> On Aug 26, 2021, at 12:28 AM, NeilBrown <neilb@xxxxxxx> wrote: > > > File-handles not in the "new" or "version 1" format have not been handed > out for new mounts since Linux 2.4 which was released 20 years ago. > I think it is safe to say that no such file handles are still in use, > and that we can drop support for them. > > This patch also moves the nfsfh.h from the include/uapi directory into > fs/nfsd. I can find no evidence of it being used anywhere outside the > kernel. Certainly nfs-utils and wireshark do not use it. > > fh_base and fh_pad are occasionally used to refer to the whole > filehandle. These are replaced with "fh_raw" which is hopefully more > meaningful. > > Signed-off-by: NeilBrown <neilb@xxxxxxx> > --- > > I found > https://www.spinics.net/lists/linux-nfs/msg43280.html > "Re: [PATCH] nfsd: clean up fh_auth usage" > from 2014 where moving nfsfh.h out of uapi was considered but not > actioned. Christoph said he would "do some research if the > uapi <linux/nfsd/*.h> headers are used anywhere at all". I can find no > report on the result of that research. My own research turned up > nothing. > > Thanks, > NeilBrown Hi Neil- I have no philosophical objection to this clean up, but I'm concerned a bit about timing. It's a large patch, and 5.15 should be opening on Sunday. I would prefer this to go into 5.16, if that's OK with you? > fs/nfsd/lockd.c | 2 +- > fs/nfsd/nfs3xdr.c | 4 +- > fs/nfsd/nfs4callback.c | 2 +- > fs/nfsd/nfs4proc.c | 2 +- > fs/nfsd/nfs4state.c | 4 +- > fs/nfsd/nfs4xdr.c | 4 +- > fs/nfsd/nfsctl.c | 6 +- > fs/nfsd/nfsfh.c | 177 +++++++++++--------------------- > fs/nfsd/nfsfh.h | 55 +++++++++- > fs/nfsd/nfsxdr.c | 4 +- > include/uapi/linux/nfsd/nfsfh.h | 116 --------------------- > 11 files changed, 126 insertions(+), 250 deletions(-) > delete mode 100644 include/uapi/linux/nfsd/nfsfh.h > > diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c > index 3f5b3d7b62b7..74d1630e7994 100644 > --- a/fs/nfsd/lockd.c > +++ b/fs/nfsd/lockd.c > @@ -33,7 +33,7 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) > /* must initialize before using! but maxsize doesn't matter */ > fh_init(&fh,0); > fh.fh_handle.fh_size = f->size; > - memcpy((char*)&fh.fh_handle.fh_base, f->data, f->size); > + memcpy((char*)&fh.fh_handle.fh_raw, f->data, f->size); > fh.fh_export = NULL; > > nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); > diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c > index 0a5ebc52e6a9..3d37923afb06 100644 > --- a/fs/nfsd/nfs3xdr.c > +++ b/fs/nfsd/nfs3xdr.c > @@ -92,7 +92,7 @@ svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp) > return false; > fh_init(fhp, NFS3_FHSIZE); > fhp->fh_handle.fh_size = size; > - memcpy(&fhp->fh_handle.fh_base, p, size); > + memcpy(&fhp->fh_handle.fh_raw, p, size); > > return true; > } > @@ -131,7 +131,7 @@ svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp) > *p++ = cpu_to_be32(size); > if (size) > p[XDR_QUADLEN(size) - 1] = 0; > - memcpy(p, &fhp->fh_handle.fh_base, size); > + memcpy(p, &fhp->fh_handle.fh_raw, size); > > return true; > } > diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c > index 0f8b10f363e7..11f8715d92d6 100644 > --- a/fs/nfsd/nfs4callback.c > +++ b/fs/nfsd/nfs4callback.c > @@ -121,7 +121,7 @@ static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh) > > BUG_ON(length > NFS4_FHSIZE); > p = xdr_reserve_space(xdr, 4 + length); > - xdr_encode_opaque(p, &fh->fh_base, length); > + xdr_encode_opaque(p, &fh->fh_raw, length); > } > > /* > diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c > index 486c5dba4b65..4872b9519a72 100644 > --- a/fs/nfsd/nfs4proc.c > +++ b/fs/nfsd/nfs4proc.c > @@ -519,7 +519,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, > > fh_put(&cstate->current_fh); > cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; > - memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, > + memcpy(&cstate->current_fh.fh_handle.fh_raw, putfh->pf_fhval, > putfh->pf_fhlen); > ret = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS); > #ifdef CONFIG_NFSD_V4_2_INTER_SSC > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > index fa67ecd5fe63..d66b4be99063 100644 > --- a/fs/nfsd/nfs4state.c > +++ b/fs/nfsd/nfs4state.c > @@ -1010,7 +1010,7 @@ static int delegation_blocked(struct knfsd_fh *fh) > } > spin_unlock(&blocked_delegations_lock); > } > - hash = jhash(&fh->fh_base, fh->fh_size, 0); > + hash = jhash(&fh->fh_raw, fh->fh_size, 0); > if (test_bit(hash&255, bd->set[0]) && > test_bit((hash>>8)&255, bd->set[0]) && > test_bit((hash>>16)&255, bd->set[0])) > @@ -1029,7 +1029,7 @@ static void block_delegations(struct knfsd_fh *fh) > u32 hash; > struct bloom_pair *bd = &blocked_delegations; > > - hash = jhash(&fh->fh_base, fh->fh_size, 0); > + hash = jhash(&fh->fh_raw, fh->fh_size, 0); > > spin_lock(&blocked_delegations_lock); > __set_bit(hash&255, bd->set[bd->new]); > diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c > index 7abeccb975b2..a54b2845473b 100644 > --- a/fs/nfsd/nfs4xdr.c > +++ b/fs/nfsd/nfs4xdr.c > @@ -3110,7 +3110,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, > p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4); > if (!p) > goto out_resource; > - p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, > + p = xdr_encode_opaque(p, &fhp->fh_handle.fh_raw, > fhp->fh_handle.fh_size); > } > if (bmval0 & FATTR4_WORD0_FILEID) { > @@ -3667,7 +3667,7 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh > p = xdr_reserve_space(xdr, len + 4); > if (!p) > return nfserr_resource; > - p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len); > + p = xdr_encode_opaque(p, &fhp->fh_handle.fh_raw, len); > return 0; > } > > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c > index c2c3d9077dc5..449b57e5e328 100644 > --- a/fs/nfsd/nfsctl.c > +++ b/fs/nfsd/nfsctl.c > @@ -395,12 +395,12 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) > auth_domain_put(dom); > if (len) > return len; > - > + > mesg = buf; > len = SIMPLE_TRANSACTION_LIMIT; > - qword_addhex(&mesg, &len, (char*)&fh.fh_base, fh.fh_size); > + qword_addhex(&mesg, &len, (char*)&fh.fh_raw, fh.fh_size); > mesg[-1] = '\n'; > - return mesg - buf; > + return mesg - buf; > } > > /* > diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c > index c475d2271f9c..7695c0f1eefe 100644 > --- a/fs/nfsd/nfsfh.c > +++ b/fs/nfsd/nfsfh.c > @@ -154,11 +154,12 @@ static inline __be32 check_pseudo_root(struct svc_rqst *rqstp, > static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) > { > struct knfsd_fh *fh = &fhp->fh_handle; > - struct fid *fid = NULL, sfid; > + struct fid *fid = NULL; > struct svc_export *exp; > struct dentry *dentry; > int fileid_type; > int data_left = fh->fh_size/4; > + int len; > __be32 error; > > error = nfserr_stale; > @@ -167,48 +168,35 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) > if (rqstp->rq_vers == 4 && fh->fh_size == 0) > return nfserr_nofilehandle; > > - if (fh->fh_version == 1) { > - int len; > - > - if (--data_left < 0) > - return error; > - if (fh->fh_auth_type != 0) > - return error; > - len = key_len(fh->fh_fsid_type) / 4; > - if (len == 0) > - return error; > - if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { > - /* deprecated, convert to type 3 */ > - len = key_len(FSID_ENCODE_DEV)/4; > - fh->fh_fsid_type = FSID_ENCODE_DEV; > - /* > - * struct knfsd_fh uses host-endian fields, which are > - * sometimes used to hold net-endian values. This > - * confuses sparse, so we must use __force here to > - * keep it from complaining. > - */ > - fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]), > - ntohl((__force __be32)fh->fh_fsid[1]))); > - fh->fh_fsid[1] = fh->fh_fsid[2]; > - } > - data_left -= len; > - if (data_left < 0) > - return error; > - exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid); > - fid = (struct fid *)(fh->fh_fsid + len); > - } else { > - __u32 tfh[2]; > - dev_t xdev; > - ino_t xino; > - > - if (fh->fh_size != NFS_FHSIZE) > - return error; > - /* assume old filehandle format */ > - xdev = old_decode_dev(fh->ofh_xdev); > - xino = u32_to_ino_t(fh->ofh_xino); > - mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL); > - exp = rqst_exp_find(rqstp, FSID_DEV, tfh); > + if (fh->fh_version != 1) > + return error; > + > + if (--data_left < 0) > + return error; > + if (fh->fh_auth_type != 0) > + return error; > + len = key_len(fh->fh_fsid_type) / 4; > + if (len == 0) > + return error; > + if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { > + /* deprecated, convert to type 3 */ > + len = key_len(FSID_ENCODE_DEV)/4; > + fh->fh_fsid_type = FSID_ENCODE_DEV; > + /* > + * struct knfsd_fh uses host-endian fields, which are > + * sometimes used to hold net-endian values. This > + * confuses sparse, so we must use __force here to > + * keep it from complaining. > + */ > + fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]), > + ntohl((__force __be32)fh->fh_fsid[1]))); > + fh->fh_fsid[1] = fh->fh_fsid[2]; > } > + data_left -= len; > + if (data_left < 0) > + return error; > + exp = rqst_exp_find(rqstp, fh->fh_fsid_type, fh->fh_fsid); > + fid = (struct fid *)(fh->fh_fsid + len); > > error = nfserr_stale; > if (IS_ERR(exp)) { > @@ -253,18 +241,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) > if (rqstp->rq_vers > 2) > error = nfserr_badhandle; > > - if (fh->fh_version != 1) { > - sfid.i32.ino = fh->ofh_ino; > - sfid.i32.gen = fh->ofh_generation; > - sfid.i32.parent_ino = fh->ofh_dirino; > - fid = &sfid; > - data_left = 3; > - if (fh->ofh_dirino == 0) > - fileid_type = FILEID_INO32_GEN; > - else > - fileid_type = FILEID_INO32_GEN_PARENT; > - } else > - fileid_type = fh->fh_fileid_type; > + fileid_type = fh->fh_fileid_type; > > if (fileid_type == FILEID_ROOT) > dentry = dget(exp->ex_path.dentry); > @@ -452,20 +429,6 @@ static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, > } > } > > -/* > - * for composing old style file handles > - */ > -static inline void _fh_update_old(struct dentry *dentry, > - struct svc_export *exp, > - struct knfsd_fh *fh) > -{ > - fh->ofh_ino = ino_t_to_u32(d_inode(dentry)->i_ino); > - fh->ofh_generation = d_inode(dentry)->i_generation; > - if (d_is_dir(dentry) || > - (exp->ex_flags & NFSEXP_NOSUBTREECHECK)) > - fh->ofh_dirino = 0; > -} > - > static bool is_root_export(struct svc_export *exp) > { > return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root; > @@ -600,35 +563,21 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, > fhp->fh_dentry = dget(dentry); /* our internal copy */ > fhp->fh_export = exp_get(exp); > > - if (fhp->fh_handle.fh_version == 0xca) { > - /* old style filehandle please */ > - memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE); > - fhp->fh_handle.fh_size = NFS_FHSIZE; > - fhp->fh_handle.ofh_dcookie = 0xfeebbaca; > - fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev); > - fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev; > - fhp->fh_handle.ofh_xino = > - ino_t_to_u32(d_inode(exp->ex_path.dentry)->i_ino); > - fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry)); > - if (inode) > - _fh_update_old(dentry, exp, &fhp->fh_handle); > - } else { > - fhp->fh_handle.fh_size = > - key_len(fhp->fh_handle.fh_fsid_type) + 4; > - fhp->fh_handle.fh_auth_type = 0; > - > - mk_fsid(fhp->fh_handle.fh_fsid_type, > - fhp->fh_handle.fh_fsid, > - ex_dev, > - d_inode(exp->ex_path.dentry)->i_ino, > - exp->ex_fsid, exp->ex_uuid); > - > - if (inode) > - _fh_update(fhp, exp, dentry); > - if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { > - fh_put(fhp); > - return nfserr_opnotsupp; > - } > + fhp->fh_handle.fh_size = > + key_len(fhp->fh_handle.fh_fsid_type) + 4; > + fhp->fh_handle.fh_auth_type = 0; > + > + mk_fsid(fhp->fh_handle.fh_fsid_type, > + fhp->fh_handle.fh_fsid, > + ex_dev, > + d_inode(exp->ex_path.dentry)->i_ino, > + exp->ex_fsid, exp->ex_uuid); > + > + if (inode) > + _fh_update(fhp, exp, dentry); > + if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { > + fh_put(fhp); > + return nfserr_opnotsupp; > } > > return 0; > @@ -649,23 +598,19 @@ fh_update(struct svc_fh *fhp) > dentry = fhp->fh_dentry; > if (d_really_is_negative(dentry)) > goto out_negative; > - if (fhp->fh_handle.fh_version != 1) { > - _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); > - } else { > - if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) > - return 0; > + if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) > + return 0; > > - _fh_update(fhp, fhp->fh_export, dentry); > - if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) > - return nfserr_opnotsupp; > - } > + _fh_update(fhp, fhp->fh_export, dentry); > + if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) > + return nfserr_opnotsupp; > return 0; > out_bad: > printk(KERN_ERR "fh_update: fh not verified!\n"); > return nfserr_serverfault; > out_negative: > printk(KERN_ERR "fh_update: %pd2 still negative!\n", > - dentry); > + dentry); > return nfserr_serverfault; > } > > @@ -702,12 +647,12 @@ char * SVCFH_fmt(struct svc_fh *fhp) > static char buf[80]; > sprintf(buf, "%d: %08x %08x %08x %08x %08x %08x", > fh->fh_size, > - fh->fh_base.fh_pad[0], > - fh->fh_base.fh_pad[1], > - fh->fh_base.fh_pad[2], > - fh->fh_base.fh_pad[3], > - fh->fh_base.fh_pad[4], > - fh->fh_base.fh_pad[5]); > + fh->fh_raw[0], > + fh->fh_raw[1], > + fh->fh_raw[2], > + fh->fh_raw[3], > + fh->fh_raw[4], > + fh->fh_raw[5]); > return buf; > } > > diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h > index 6106697adc04..f36234c474dc 100644 > --- a/fs/nfsd/nfsfh.h > +++ b/fs/nfsd/nfsfh.h > @@ -10,9 +10,56 @@ > > #include <linux/crc32.h> > #include <linux/sunrpc/svc.h> > -#include <uapi/linux/nfsd/nfsfh.h> > #include <linux/iversion.h> > #include <linux/exportfs.h> > +#include <linux/nfs4.h> > + > +/* > + * The file handle starts with a sequence of four-byte words. > + * The first word contains a version number (1) and three descriptor bytes > + * that tell how the remaining 3 variable length fields should be handled. > + * These three bytes are auth_type, fsid_type and fileid_type. > + * > + * All four-byte values are in host-byte-order. > + * > + * The auth_type field is deprecated and must be set to 0. > + * > + * The fsid_type identifies how the filesystem (or export point) is > + * encoded. > + * Current values: > + * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number > + * NOTE: we cannot use the kdev_t device id value, because kdev_t.h > + * says we mustn't. We must break it up and reassemble. > + * 1 - 4 byte user specified identifier > + * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED > + * 3 - 4 byte device id, encoded for user-space, 4 byte inode number > + * 4 - 4 byte inode number and 4 byte uuid > + * 5 - 8 byte uuid > + * 6 - 16 byte uuid > + * 7 - 8 byte inode number and 16 byte uuid > + * > + * The fileid_type identified how the file within the filesystem is encoded. > + * The values for this field are filesystem specific, exccept that > + * filesystems must not use the values '0' or '0xff'. 'See enum fid_type' > + * in include/linux/exportfs.h for currently registered values. > + */ > + > +struct knfsd_fh { > + unsigned int fh_size; /* > + * Points to the current size while > + * building a new file handle. > + */ > + union { > + __u32 fh_raw[NFS4_FHSIZE/4]; > + struct { > + __u8 fh_version; /* == 1 */ > + __u8 fh_auth_type; /* deprecated */ > + __u8 fh_fsid_type; > + __u8 fh_fileid_type; > + __u32 fh_fsid[]; /* flexible-array member */ > + }; > + }; > +}; > > static inline __u32 ino_t_to_u32(ino_t ino) > { > @@ -188,7 +235,7 @@ static inline void > fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src) > { > dst->fh_size = src->fh_size; > - memcpy(&dst->fh_base, &src->fh_base, src->fh_size); > + memcpy(&dst->fh_raw, &src->fh_raw, src->fh_size); > } > > static __inline__ struct svc_fh * > @@ -203,7 +250,7 @@ static inline bool fh_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) > { > if (fh1->fh_size != fh2->fh_size) > return false; > - if (memcmp(fh1->fh_base.fh_pad, fh2->fh_base.fh_pad, fh1->fh_size) != 0) > + if (memcmp(fh1->fh_raw, fh2->fh_raw, fh1->fh_size) != 0) > return false; > return true; > } > @@ -227,7 +274,7 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) > */ > static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh) > { > - return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size); > + return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_raw, fh->fh_size); > } > #else > static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh) > diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c > index a06c05fe3b42..082449c7d0db 100644 > --- a/fs/nfsd/nfsxdr.c > +++ b/fs/nfsd/nfsxdr.c > @@ -64,7 +64,7 @@ svcxdr_decode_fhandle(struct xdr_stream *xdr, struct svc_fh *fhp) > if (!p) > return false; > fh_init(fhp, NFS_FHSIZE); > - memcpy(&fhp->fh_handle.fh_base, p, NFS_FHSIZE); > + memcpy(&fhp->fh_handle.fh_raw, p, NFS_FHSIZE); > fhp->fh_handle.fh_size = NFS_FHSIZE; > > return true; > @@ -78,7 +78,7 @@ svcxdr_encode_fhandle(struct xdr_stream *xdr, const struct svc_fh *fhp) > p = xdr_reserve_space(xdr, NFS_FHSIZE); > if (!p) > return false; > - memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); > + memcpy(p, &fhp->fh_handle.fh_raw, NFS_FHSIZE); > > return true; > } > diff --git a/include/uapi/linux/nfsd/nfsfh.h b/include/uapi/linux/nfsd/nfsfh.h > deleted file mode 100644 > index 427294dd56a1..000000000000 > --- a/include/uapi/linux/nfsd/nfsfh.h > +++ /dev/null > @@ -1,116 +0,0 @@ > -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ > -/* > - * This file describes the layout of the file handles as passed > - * over the wire. > - * > - * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@xxxxxxxxxxxx> > - */ > - > -#ifndef _UAPI_LINUX_NFSD_FH_H > -#define _UAPI_LINUX_NFSD_FH_H > - > -#include <linux/types.h> > -#include <linux/nfs.h> > -#include <linux/nfs2.h> > -#include <linux/nfs3.h> > -#include <linux/nfs4.h> > - > -/* > - * This is the old "dentry style" Linux NFSv2 file handle. > - * > - * The xino and xdev fields are currently used to transport the > - * ino/dev of the exported inode. > - */ > -struct nfs_fhbase_old { > - __u32 fb_dcookie; /* dentry cookie - always 0xfeebbaca */ > - __u32 fb_ino; /* our inode number */ > - __u32 fb_dirino; /* dir inode number, 0 for directories */ > - __u32 fb_dev; /* our device */ > - __u32 fb_xdev; > - __u32 fb_xino; > - __u32 fb_generation; > -}; > - > -/* > - * This is the new flexible, extensible style NFSv2/v3/v4 file handle. > - * by Neil Brown <neilb@xxxxxxxxxxxxxxx> - March 2000 > - * > - * The file handle starts with a sequence of four-byte words. > - * The first word contains a version number (1) and three descriptor bytes > - * that tell how the remaining 3 variable length fields should be handled. > - * These three bytes are auth_type, fsid_type and fileid_type. > - * > - * All four-byte values are in host-byte-order. > - * > - * The auth_type field is deprecated and must be set to 0. > - * > - * The fsid_type identifies how the filesystem (or export point) is > - * encoded. > - * Current values: > - * 0 - 4 byte device id (ms-2-bytes major, ls-2-bytes minor), 4byte inode number > - * NOTE: we cannot use the kdev_t device id value, because kdev_t.h > - * says we mustn't. We must break it up and reassemble. > - * 1 - 4 byte user specified identifier > - * 2 - 4 byte major, 4 byte minor, 4 byte inode number - DEPRECATED > - * 3 - 4 byte device id, encoded for user-space, 4 byte inode number > - * 4 - 4 byte inode number and 4 byte uuid > - * 5 - 8 byte uuid > - * 6 - 16 byte uuid > - * 7 - 8 byte inode number and 16 byte uuid > - * > - * The fileid_type identified how the file within the filesystem is encoded. > - * The values for this field are filesystem specific, exccept that > - * filesystems must not use the values '0' or '0xff'. 'See enum fid_type' > - * in include/linux/exportfs.h for currently registered values. > - */ > -struct nfs_fhbase_new { > - union { > - struct { > - __u8 fb_version_aux; /* == 1, even => nfs_fhbase_old */ > - __u8 fb_auth_type_aux; > - __u8 fb_fsid_type_aux; > - __u8 fb_fileid_type_aux; > - __u32 fb_auth[1]; > - /* __u32 fb_fsid[0]; floating */ > - /* __u32 fb_fileid[0]; floating */ > - }; > - struct { > - __u8 fb_version; /* == 1, even => nfs_fhbase_old */ > - __u8 fb_auth_type; > - __u8 fb_fsid_type; > - __u8 fb_fileid_type; > - __u32 fb_auth_flex[]; /* flexible-array member */ > - }; > - }; > -}; > - > -struct knfsd_fh { > - unsigned int fh_size; /* significant for NFSv3. > - * Points to the current size while building > - * a new file handle > - */ > - union { > - struct nfs_fhbase_old fh_old; > - __u32 fh_pad[NFS4_FHSIZE/4]; > - struct nfs_fhbase_new fh_new; > - } fh_base; > -}; > - > -#define ofh_dcookie fh_base.fh_old.fb_dcookie > -#define ofh_ino fh_base.fh_old.fb_ino > -#define ofh_dirino fh_base.fh_old.fb_dirino > -#define ofh_dev fh_base.fh_old.fb_dev > -#define ofh_xdev fh_base.fh_old.fb_xdev > -#define ofh_xino fh_base.fh_old.fb_xino > -#define ofh_generation fh_base.fh_old.fb_generation > - > -#define fh_version fh_base.fh_new.fb_version > -#define fh_fsid_type fh_base.fh_new.fb_fsid_type > -#define fh_auth_type fh_base.fh_new.fb_auth_type > -#define fh_fileid_type fh_base.fh_new.fb_fileid_type > -#define fh_fsid fh_base.fh_new.fb_auth_flex > - > -/* Do not use, provided for userspace compatiblity. */ > -#define fh_auth fh_base.fh_new.fb_auth > - > -#endif /* _UAPI_LINUX_NFSD_FH_H */ > -- > 2.32.0 > > -- Chuck Lever