diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfsfh.c | 67 |
1 files changed, 31 insertions, 36 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 7011d62acfc8..4f712e970584 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
115 | dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); | 115 | dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); |
116 | 116 | ||
117 | if (!fhp->fh_dentry) { | 117 | if (!fhp->fh_dentry) { |
118 | __u32 *datap=NULL; | 118 | struct fid *fid = NULL, sfid; |
119 | __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */ | ||
120 | int fileid_type; | 119 | int fileid_type; |
121 | int data_left = fh->fh_size/4; | 120 | int data_left = fh->fh_size/4; |
122 | 121 | ||
@@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
128 | 127 | ||
129 | if (fh->fh_version == 1) { | 128 | if (fh->fh_version == 1) { |
130 | int len; | 129 | int len; |
131 | datap = fh->fh_auth; | ||
132 | if (--data_left<0) goto out; | 130 | if (--data_left<0) goto out; |
133 | switch (fh->fh_auth_type) { | 131 | switch (fh->fh_auth_type) { |
134 | case 0: break; | 132 | case 0: break; |
@@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
144 | fh->fh_fsid[1] = fh->fh_fsid[2]; | 142 | fh->fh_fsid[1] = fh->fh_fsid[2]; |
145 | } | 143 | } |
146 | if ((data_left -= len)<0) goto out; | 144 | if ((data_left -= len)<0) goto out; |
147 | exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap); | 145 | exp = rqst_exp_find(rqstp, fh->fh_fsid_type, |
148 | datap += len; | 146 | fh->fh_auth); |
147 | fid = (struct fid *)(fh->fh_auth + len); | ||
149 | } else { | 148 | } else { |
149 | __u32 tfh[2]; | ||
150 | dev_t xdev; | 150 | dev_t xdev; |
151 | ino_t xino; | 151 | ino_t xino; |
152 | if (fh->fh_size != NFS_FHSIZE) | 152 | if (fh->fh_size != NFS_FHSIZE) |
@@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
190 | error = nfserr_badhandle; | 190 | error = nfserr_badhandle; |
191 | 191 | ||
192 | if (fh->fh_version != 1) { | 192 | if (fh->fh_version != 1) { |
193 | tfh[0] = fh->ofh_ino; | 193 | sfid.i32.ino = fh->ofh_ino; |
194 | tfh[1] = fh->ofh_generation; | 194 | sfid.i32.gen = fh->ofh_generation; |
195 | tfh[2] = fh->ofh_dirino; | 195 | sfid.i32.parent_ino = fh->ofh_dirino; |
196 | datap = tfh; | 196 | fid = &sfid; |
197 | data_left = 3; | 197 | data_left = 3; |
198 | if (fh->ofh_dirino == 0) | 198 | if (fh->ofh_dirino == 0) |
199 | fileid_type = 1; | 199 | fileid_type = FILEID_INO32_GEN; |
200 | else | 200 | else |
201 | fileid_type = 2; | 201 | fileid_type = FILEID_INO32_GEN_PARENT; |
202 | } else | 202 | } else |
203 | fileid_type = fh->fh_fileid_type; | 203 | fileid_type = fh->fh_fileid_type; |
204 | 204 | ||
205 | if (fileid_type == 0) | 205 | if (fileid_type == FILEID_ROOT) |
206 | dentry = dget(exp->ex_dentry); | 206 | dentry = dget(exp->ex_dentry); |
207 | else { | 207 | else { |
208 | dentry = exportfs_decode_fh(exp->ex_mnt, datap, | 208 | dentry = exportfs_decode_fh(exp->ex_mnt, fid, |
209 | data_left, fileid_type, | 209 | data_left, fileid_type, |
210 | nfsd_acceptable, exp); | 210 | nfsd_acceptable, exp); |
211 | } | 211 | } |
@@ -286,16 +286,21 @@ out: | |||
286 | * an inode. In this case a call to fh_update should be made | 286 | * an inode. In this case a call to fh_update should be made |
287 | * before the fh goes out on the wire ... | 287 | * before the fh goes out on the wire ... |
288 | */ | 288 | */ |
289 | static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, | 289 | static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, |
290 | __u32 *datap, int *maxsize) | 290 | struct dentry *dentry) |
291 | { | 291 | { |
292 | if (dentry == exp->ex_dentry) { | 292 | if (dentry != exp->ex_dentry) { |
293 | *maxsize = 0; | 293 | struct fid *fid = (struct fid *) |
294 | return 0; | 294 | (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1); |
295 | } | 295 | int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; |
296 | int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK); | ||
296 | 297 | ||
297 | return exportfs_encode_fh(dentry, datap, maxsize, | 298 | fhp->fh_handle.fh_fileid_type = |
298 | !(exp->ex_flags & NFSEXP_NOSUBTREECHECK)); | 299 | exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck); |
300 | fhp->fh_handle.fh_size += maxsize * 4; | ||
301 | } else { | ||
302 | fhp->fh_handle.fh_fileid_type = FILEID_ROOT; | ||
303 | } | ||
299 | } | 304 | } |
300 | 305 | ||
301 | /* | 306 | /* |
@@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, | |||
457 | datap += len/4; | 462 | datap += len/4; |
458 | fhp->fh_handle.fh_size = 4 + len; | 463 | fhp->fh_handle.fh_size = 4 + len; |
459 | 464 | ||
460 | if (inode) { | 465 | if (inode) |
461 | int size = (fhp->fh_maxsize-len-4)/4; | 466 | _fh_update(fhp, exp, dentry); |
462 | fhp->fh_handle.fh_fileid_type = | ||
463 | _fh_update(dentry, exp, datap, &size); | ||
464 | fhp->fh_handle.fh_size += size*4; | ||
465 | } | ||
466 | if (fhp->fh_handle.fh_fileid_type == 255) | 467 | if (fhp->fh_handle.fh_fileid_type == 255) |
467 | return nfserr_opnotsupp; | 468 | return nfserr_opnotsupp; |
468 | } | 469 | } |
@@ -479,7 +480,6 @@ __be32 | |||
479 | fh_update(struct svc_fh *fhp) | 480 | fh_update(struct svc_fh *fhp) |
480 | { | 481 | { |
481 | struct dentry *dentry; | 482 | struct dentry *dentry; |
482 | __u32 *datap; | ||
483 | 483 | ||
484 | if (!fhp->fh_dentry) | 484 | if (!fhp->fh_dentry) |
485 | goto out_bad; | 485 | goto out_bad; |
@@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp) | |||
490 | if (fhp->fh_handle.fh_version != 1) { | 490 | if (fhp->fh_handle.fh_version != 1) { |
491 | _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); | 491 | _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); |
492 | } else { | 492 | } else { |
493 | int size; | 493 | if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) |
494 | if (fhp->fh_handle.fh_fileid_type != 0) | ||
495 | goto out; | 494 | goto out; |
496 | datap = fhp->fh_handle.fh_auth+ | 495 | |
497 | fhp->fh_handle.fh_size/4 -1; | 496 | _fh_update(fhp, fhp->fh_export, dentry); |
498 | size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; | ||
499 | fhp->fh_handle.fh_fileid_type = | ||
500 | _fh_update(dentry, fhp->fh_export, datap, &size); | ||
501 | fhp->fh_handle.fh_size += size*4; | ||
502 | if (fhp->fh_handle.fh_fileid_type == 255) | 497 | if (fhp->fh_handle.fh_fileid_type == 255) |
503 | return nfserr_opnotsupp; | 498 | return nfserr_opnotsupp; |
504 | } | 499 | } |