|
@@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
|
|
|
dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
|
|
|
|
|
|
if (!fhp->fh_dentry) {
|
|
|
- __u32 *datap=NULL;
|
|
|
- __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
|
|
|
+ struct fid *fid = NULL, sfid;
|
|
|
int fileid_type;
|
|
|
int data_left = fh->fh_size/4;
|
|
|
|
|
@@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
|
|
|
|
|
|
if (fh->fh_version == 1) {
|
|
|
int len;
|
|
|
- datap = fh->fh_auth;
|
|
|
if (--data_left<0) goto out;
|
|
|
switch (fh->fh_auth_type) {
|
|
|
case 0: break;
|
|
@@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
|
|
|
fh->fh_fsid[1] = fh->fh_fsid[2];
|
|
|
}
|
|
|
if ((data_left -= len)<0) goto out;
|
|
|
- exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap);
|
|
|
- datap += len;
|
|
|
+ exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
|
|
|
+ fh->fh_auth);
|
|
|
+ fid = (struct fid *)(fh->fh_auth + len);
|
|
|
} else {
|
|
|
+ __u32 tfh[2];
|
|
|
dev_t xdev;
|
|
|
ino_t xino;
|
|
|
if (fh->fh_size != NFS_FHSIZE)
|
|
@@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
|
|
|
error = nfserr_badhandle;
|
|
|
|
|
|
if (fh->fh_version != 1) {
|
|
|
- tfh[0] = fh->ofh_ino;
|
|
|
- tfh[1] = fh->ofh_generation;
|
|
|
- tfh[2] = fh->ofh_dirino;
|
|
|
- datap = tfh;
|
|
|
+ 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 = 1;
|
|
|
+ fileid_type = FILEID_INO32_GEN;
|
|
|
else
|
|
|
- fileid_type = 2;
|
|
|
+ fileid_type = FILEID_INO32_GEN_PARENT;
|
|
|
} else
|
|
|
fileid_type = fh->fh_fileid_type;
|
|
|
|
|
|
- if (fileid_type == 0)
|
|
|
+ if (fileid_type == FILEID_ROOT)
|
|
|
dentry = dget(exp->ex_dentry);
|
|
|
else {
|
|
|
- dentry = exportfs_decode_fh(exp->ex_mnt, datap,
|
|
|
+ dentry = exportfs_decode_fh(exp->ex_mnt, fid,
|
|
|
data_left, fileid_type,
|
|
|
nfsd_acceptable, exp);
|
|
|
}
|
|
@@ -286,16 +286,21 @@ out:
|
|
|
* an inode. In this case a call to fh_update should be made
|
|
|
* before the fh goes out on the wire ...
|
|
|
*/
|
|
|
-static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
|
|
|
- __u32 *datap, int *maxsize)
|
|
|
+static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
|
|
|
+ struct dentry *dentry)
|
|
|
{
|
|
|
- if (dentry == exp->ex_dentry) {
|
|
|
- *maxsize = 0;
|
|
|
- return 0;
|
|
|
- }
|
|
|
+ if (dentry != exp->ex_dentry) {
|
|
|
+ struct fid *fid = (struct fid *)
|
|
|
+ (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
|
|
|
+ int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
|
|
|
+ int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
|
|
|
|
|
|
- return exportfs_encode_fh(dentry, datap, maxsize,
|
|
|
- !(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
|
|
|
+ fhp->fh_handle.fh_fileid_type =
|
|
|
+ exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
|
|
|
+ fhp->fh_handle.fh_size += maxsize * 4;
|
|
|
+ } else {
|
|
|
+ fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
|
|
|
datap += len/4;
|
|
|
fhp->fh_handle.fh_size = 4 + len;
|
|
|
|
|
|
- if (inode) {
|
|
|
- int size = (fhp->fh_maxsize-len-4)/4;
|
|
|
- fhp->fh_handle.fh_fileid_type =
|
|
|
- _fh_update(dentry, exp, datap, &size);
|
|
|
- fhp->fh_handle.fh_size += size*4;
|
|
|
- }
|
|
|
+ if (inode)
|
|
|
+ _fh_update(fhp, exp, dentry);
|
|
|
if (fhp->fh_handle.fh_fileid_type == 255)
|
|
|
return nfserr_opnotsupp;
|
|
|
}
|
|
@@ -479,7 +480,6 @@ __be32
|
|
|
fh_update(struct svc_fh *fhp)
|
|
|
{
|
|
|
struct dentry *dentry;
|
|
|
- __u32 *datap;
|
|
|
|
|
|
if (!fhp->fh_dentry)
|
|
|
goto out_bad;
|
|
@@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp)
|
|
|
if (fhp->fh_handle.fh_version != 1) {
|
|
|
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
|
|
|
} else {
|
|
|
- int size;
|
|
|
- if (fhp->fh_handle.fh_fileid_type != 0)
|
|
|
+ if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
|
|
|
goto out;
|
|
|
- datap = fhp->fh_handle.fh_auth+
|
|
|
- fhp->fh_handle.fh_size/4 -1;
|
|
|
- size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
|
|
|
- fhp->fh_handle.fh_fileid_type =
|
|
|
- _fh_update(dentry, fhp->fh_export, datap, &size);
|
|
|
- fhp->fh_handle.fh_size += size*4;
|
|
|
+
|
|
|
+ _fh_update(fhp, fhp->fh_export, dentry);
|
|
|
if (fhp->fh_handle.fh_fileid_type == 255)
|
|
|
return nfserr_opnotsupp;
|
|
|
}
|