Home | History | Annotate | Download | only in nfsd
      1 /*
      2  * include/linux/nfsd/nfsfh.h
      3  *
      4  * This file describes the layout of the file handles as passed
      5  * over the wire.
      6  *
      7  * Earlier versions of knfsd used to sign file handles using keyed MD5
      8  * or SHA. I've removed this code, because it doesn't give you more
      9  * security than blocking external access to port 2049 on your firewall.
     10  *
     11  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir (at) monad.swb.de>
     12  */
     13 
     14 #ifndef _LINUX_NFSD_FH_H
     15 #define _LINUX_NFSD_FH_H
     16 
     17 #include <asm/types.h>
     18 #ifdef __KERNEL__
     19 # include <linux/types.h>
     20 # include <linux/string.h>
     21 # include <linux/fs.h>
     22 #endif
     23 #include <linux/nfsd/const.h>
     24 #include <linux/nfsd/debug.h>
     25 
     26 /*
     27  * This is the old "dentry style" Linux NFSv2 file handle.
     28  *
     29  * The xino and xdev fields are currently used to transport the
     30  * ino/dev of the exported inode.
     31  */
     32 struct nfs_fhbase_old {
     33 	__u32		fb_dcookie;	/* dentry cookie - always 0xfeebbaca */
     34 	__u32		fb_ino;		/* our inode number */
     35 	__u32		fb_dirino;	/* dir inode number, 0 for directories */
     36 	__u32		fb_dev;		/* our device */
     37 	__u32		fb_xdev;
     38 	__u32		fb_xino;
     39 	__u32		fb_generation;
     40 };
     41 
     42 /*
     43  * This is the new flexible, extensible style NFSv2/v3 file handle.
     44  * by Neil Brown <neilb (at) cse.unsw.edu.au> - March 2000
     45  *
     46  * The file handle is seens as a list of 4byte words.
     47  * The first word contains a version number (1) and four descriptor bytes
     48  * that tell how the remaining 3 variable length fields should be handled.
     49  * These three bytes are auth_type, fsid_type and fileid_type.
     50  *
     51  * All 4byte values are in host-byte-order.
     52  *
     53  * The auth_type field specifies how the filehandle can be authenticated
     54  * This might allow a file to be confirmed to be in a writable part of a
     55  * filetree without checking the path from it upto the root.
     56  * Current values:
     57  *     0  - No authentication.  fb_auth is 0 bytes long
     58  * Possible future values:
     59  *     1  - 4 bytes taken from MD5 hash of the remainer of the file handle
     60  *          prefixed by a secret and with the important export flags.
     61  *
     62  * The fsid_type identifies how the filesystem (or export point) is
     63  *    encoded.
     64  *  Current values:
     65  *     0  - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number
     66  *        NOTE: we cannot use the kdev_t device id value, because kdev_t.h
     67  *              says we mustn't.  We must break it up and reassemble.
     68  *     1  - 4 byte user specified identifier
     69  *     2  - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED
     70  *     3  - 4 byte device id, encoded for user-space, 4 byte inode number
     71  *
     72  * The fileid_type identified how the file within the filesystem is encoded.
     73  * This is (will be) passed to, and set by, the underlying filesystem if it supports
     74  * filehandle operations.  The filesystem must not use the value '0' or '0xff' and may
     75  * only use the values 1 and 2 as defined below:
     76  *  Current values:
     77  *    0   - The root, or export point, of the filesystem.  fb_fileid is 0 bytes.
     78  *    1   - 32bit inode number, 32 bit generation number.
     79  *    2   - 32bit inode number, 32 bit generation number, 32 bit parent directory inode number.
     80  *
     81  */
     82 struct nfs_fhbase_new {
     83 	__u8		fb_version;	/* == 1, even => nfs_fhbase_old */
     84 	__u8		fb_auth_type;
     85 	__u8		fb_fsid_type;
     86 	__u8		fb_fileid_type;
     87 	__u32		fb_auth[1];
     88 /*	__u32		fb_fsid[0]; floating */
     89 /*	__u32		fb_fileid[0]; floating */
     90 };
     91 
     92 struct knfsd_fh {
     93 	unsigned int	fh_size;	/* significant for NFSv3.
     94 					 * Points to the current size while building
     95 					 * a new file handle
     96 					 */
     97 	union {
     98 		struct nfs_fhbase_old	fh_old;
     99 		__u32			fh_pad[NFS4_FHSIZE/4];
    100 		struct nfs_fhbase_new	fh_new;
    101 	} fh_base;
    102 };
    103 
    104 #define ofh_dcookie		fh_base.fh_old.fb_dcookie
    105 #define ofh_ino			fh_base.fh_old.fb_ino
    106 #define ofh_dirino		fh_base.fh_old.fb_dirino
    107 #define ofh_dev			fh_base.fh_old.fb_dev
    108 #define ofh_xdev		fh_base.fh_old.fb_xdev
    109 #define ofh_xino		fh_base.fh_old.fb_xino
    110 #define ofh_generation		fh_base.fh_old.fb_generation
    111 
    112 #define	fh_version		fh_base.fh_new.fb_version
    113 #define	fh_fsid_type		fh_base.fh_new.fb_fsid_type
    114 #define	fh_auth_type		fh_base.fh_new.fb_auth_type
    115 #define	fh_fileid_type		fh_base.fh_new.fb_fileid_type
    116 #define	fh_auth			fh_base.fh_new.fb_auth
    117 #define	fh_fsid			fh_base.fh_new.fb_auth
    118 
    119 #ifdef __KERNEL__
    120 
    121 static inline __u32 ino_t_to_u32(ino_t ino)
    122 {
    123 	return (__u32) ino;
    124 }
    125 
    126 static inline ino_t u32_to_ino_t(__u32 uino)
    127 {
    128 	return (ino_t) uino;
    129 }
    130 
    131 /*
    132  * This is the internal representation of an NFS handle used in knfsd.
    133  * pre_mtime/post_version will be used to support wcc_attr's in NFSv3.
    134  */
    135 typedef struct svc_fh {
    136 	struct knfsd_fh		fh_handle;	/* FH data */
    137 	struct dentry *		fh_dentry;	/* validated dentry */
    138 	struct svc_export *	fh_export;	/* export pointer */
    139 	int			fh_maxsize;	/* max size for fh_handle */
    140 
    141 	unsigned char		fh_locked;	/* inode locked by us */
    142 
    143 #ifdef CONFIG_NFSD_V3
    144 	unsigned char		fh_post_saved;	/* post-op attrs saved */
    145 	unsigned char		fh_pre_saved;	/* pre-op attrs saved */
    146 
    147 	/* Pre-op attributes saved during fh_lock */
    148 	__u64			fh_pre_size;	/* size before operation */
    149 	struct timespec		fh_pre_mtime;	/* mtime before oper */
    150 	struct timespec		fh_pre_ctime;	/* ctime before oper */
    151 
    152 	/* Post-op attributes saved in fh_unlock */
    153 	umode_t			fh_post_mode;	/* i_mode */
    154 	nlink_t			fh_post_nlink;	/* i_nlink */
    155 	uid_t			fh_post_uid;	/* i_uid */
    156 	gid_t			fh_post_gid;	/* i_gid */
    157 	__u64			fh_post_size;	/* i_size */
    158 	unsigned long		fh_post_blocks; /* i_blocks */
    159 	unsigned long		fh_post_blksize;/* i_blksize */
    160 	__u32			fh_post_rdev[2];/* i_rdev */
    161 	struct timespec		fh_post_atime;	/* i_atime */
    162 	struct timespec		fh_post_mtime;	/* i_mtime */
    163 	struct timespec		fh_post_ctime;	/* i_ctime */
    164 #endif /* CONFIG_NFSD_V3 */
    165 
    166 } svc_fh;
    167 
    168 static inline void mk_fsid_v0(u32 *fsidv, dev_t dev, ino_t ino)
    169 {
    170 	fsidv[0] = htonl((MAJOR(dev)<<16) |
    171 			MINOR(dev));
    172 	fsidv[1] = ino_t_to_u32(ino);
    173 }
    174 
    175 static inline void mk_fsid_v1(u32 *fsidv, u32 fsid)
    176 {
    177 	fsidv[0] = fsid;
    178 }
    179 
    180 static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino)
    181 {
    182 	fsidv[0] = htonl(MAJOR(dev));
    183 	fsidv[1] = htonl(MINOR(dev));
    184 	fsidv[2] = ino_t_to_u32(ino);
    185 }
    186 
    187 static inline void mk_fsid_v3(u32 *fsidv, dev_t dev, ino_t ino)
    188 {
    189 	fsidv[0] = new_encode_dev(dev);
    190 	fsidv[1] = ino_t_to_u32(ino);
    191 }
    192 
    193 static inline int key_len(int type)
    194 {
    195 	switch(type) {
    196 	case 0: return 8;
    197 	case 1: return 4;
    198 	case 2: return 12;
    199 	case 3: return 8;
    200 	default: return 0;
    201 	}
    202 }
    203 
    204 /*
    205  * Shorthand for dprintk()'s
    206  */
    207 extern char * SVCFH_fmt(struct svc_fh *fhp);
    208 
    209 /*
    210  * Function prototypes
    211  */
    212 u32	fh_verify(struct svc_rqst *, struct svc_fh *, int, int);
    213 int	fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *);
    214 int	fh_update(struct svc_fh *);
    215 void	fh_put(struct svc_fh *);
    216 
    217 static __inline__ struct svc_fh *
    218 fh_copy(struct svc_fh *dst, struct svc_fh *src)
    219 {
    220 	if (src->fh_dentry || src->fh_locked) {
    221 		struct dentry *dentry = src->fh_dentry;
    222 		printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n",
    223 			dentry->d_parent->d_name.name, dentry->d_name.name);
    224 	}
    225 
    226 	*dst = *src;
    227 	return dst;
    228 }
    229 
    230 static __inline__ struct svc_fh *
    231 fh_init(struct svc_fh *fhp, int maxsize)
    232 {
    233 	memset(fhp, 0, sizeof(*fhp));
    234 	fhp->fh_maxsize = maxsize;
    235 	return fhp;
    236 }
    237 
    238 #ifdef CONFIG_NFSD_V3
    239 /*
    240  * Fill in the pre_op attr for the wcc data
    241  */
    242 static inline void
    243 fill_pre_wcc(struct svc_fh *fhp)
    244 {
    245 	struct inode    *inode;
    246 
    247 	inode = fhp->fh_dentry->d_inode;
    248 	if (!fhp->fh_pre_saved) {
    249 		fhp->fh_pre_mtime = inode->i_mtime;
    250 		fhp->fh_pre_ctime = inode->i_ctime;
    251 			fhp->fh_pre_size  = inode->i_size;
    252 			fhp->fh_pre_saved = 1;
    253 	}
    254 }
    255 
    256 /*
    257  * Fill in the post_op attr for the wcc data
    258  */
    259 static inline void
    260 fill_post_wcc(struct svc_fh *fhp)
    261 {
    262 	struct inode    *inode = fhp->fh_dentry->d_inode;
    263 
    264 	if (fhp->fh_post_saved)
    265 		printk("nfsd: inode locked twice during operation.\n");
    266 
    267 	fhp->fh_post_mode       = inode->i_mode;
    268 	fhp->fh_post_nlink      = inode->i_nlink;
    269 	fhp->fh_post_uid	= inode->i_uid;
    270 	fhp->fh_post_gid	= inode->i_gid;
    271 	fhp->fh_post_size       = inode->i_size;
    272 	if (inode->i_blksize) {
    273 		fhp->fh_post_blksize    = inode->i_blksize;
    274 		fhp->fh_post_blocks     = inode->i_blocks;
    275 	} else {
    276 		fhp->fh_post_blksize    = BLOCK_SIZE;
    277 		/* how much do we care for accuracy with MinixFS? */
    278 		fhp->fh_post_blocks     = (inode->i_size+511) >> 9;
    279 	}
    280 	fhp->fh_post_rdev[0]    = htonl((u32)imajor(inode));
    281 	fhp->fh_post_rdev[1]    = htonl((u32)iminor(inode));
    282 	fhp->fh_post_atime      = inode->i_atime;
    283 	fhp->fh_post_mtime      = inode->i_mtime;
    284 	fhp->fh_post_ctime      = inode->i_ctime;
    285 	fhp->fh_post_saved      = 1;
    286 }
    287 #else
    288 #define	fill_pre_wcc(ignored)
    289 #define fill_post_wcc(notused)
    290 #endif /* CONFIG_NFSD_V3 */
    291 
    292 
    293 /*
    294  * Lock a file handle/inode
    295  * NOTE: both fh_lock and fh_unlock are done "by hand" in
    296  * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once
    297  * so, any changes here should be reflected there.
    298  */
    299 static inline void
    300 fh_lock(struct svc_fh *fhp)
    301 {
    302 	struct dentry	*dentry = fhp->fh_dentry;
    303 	struct inode	*inode;
    304 
    305 	dfprintk(FILEOP, "nfsd: fh_lock(%s) locked = %d\n",
    306 			SVCFH_fmt(fhp), fhp->fh_locked);
    307 
    308 	if (!fhp->fh_dentry) {
    309 		printk(KERN_ERR "fh_lock: fh not verified!\n");
    310 		return;
    311 	}
    312 	if (fhp->fh_locked) {
    313 		printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
    314 			dentry->d_parent->d_name.name, dentry->d_name.name);
    315 		return;
    316 	}
    317 
    318 	inode = dentry->d_inode;
    319 	mutex_lock(&inode->i_mutex);
    320 	fill_pre_wcc(fhp);
    321 	fhp->fh_locked = 1;
    322 }
    323 
    324 /*
    325  * Unlock a file handle/inode
    326  */
    327 static inline void
    328 fh_unlock(struct svc_fh *fhp)
    329 {
    330 	if (!fhp->fh_dentry)
    331 		printk(KERN_ERR "fh_unlock: fh not verified!\n");
    332 
    333 	if (fhp->fh_locked) {
    334 		fill_post_wcc(fhp);
    335 		mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex);
    336 		fhp->fh_locked = 0;
    337 	}
    338 }
    339 #endif /* __KERNEL__ */
    340 
    341 
    342 #endif /* _LINUX_NFSD_FH_H */
    343