aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfsfh.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 739dd3c5c3b2..6ca2d24fc216 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -323,7 +323,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
323 * 323 *
324 */ 324 */
325 325
326 u8 version = 1; 326 u8 version;
327 u8 fsid_type = 0; 327 u8 fsid_type = 0;
328 struct inode * inode = dentry->d_inode; 328 struct inode * inode = dentry->d_inode;
329 struct dentry *parent = dentry->d_parent; 329 struct dentry *parent = dentry->d_parent;
@@ -341,15 +341,59 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
341 * the reference filehandle (if it is in the same export) 341 * the reference filehandle (if it is in the same export)
342 * or the export options. 342 * or the export options.
343 */ 343 */
344 retry:
345 version = 1;
344 if (ref_fh && ref_fh->fh_export == exp) { 346 if (ref_fh && ref_fh->fh_export == exp) {
345 version = ref_fh->fh_handle.fh_version; 347 version = ref_fh->fh_handle.fh_version;
346 if (version == 0xca) 348 fsid_type = ref_fh->fh_handle.fh_fsid_type;
349
350 if (ref_fh == fhp)
351 fh_put(ref_fh);
352 ref_fh = NULL;
353
354 switch (version) {
355 case 0xca:
347 fsid_type = FSID_DEV; 356 fsid_type = FSID_DEV;
348 else 357 break;
349 fsid_type = ref_fh->fh_handle.fh_fsid_type; 358 case 1:
350 /* We know this version/type works for this export 359 break;
351 * so there is no need for further checks. 360 default:
361 goto retry;
362 }
363
364 /* Need to check that this type works for this
365 * export point. As the fsid -> filesystem mapping
366 * was guided by user-space, there is no guarantee
367 * that the filesystem actually supports that fsid
368 * type. If it doesn't we loop around again without
369 * ref_fh set.
352 */ 370 */
371 switch(fsid_type) {
372 case FSID_DEV:
373 if (!old_valid_dev(ex_dev))
374 goto retry;
375 /* FALL THROUGH */
376 case FSID_MAJOR_MINOR:
377 case FSID_ENCODE_DEV:
378 if (!(exp->ex_dentry->d_inode->i_sb->s_type->fs_flags
379 & FS_REQUIRES_DEV))
380 goto retry;
381 break;
382 case FSID_NUM:
383 if (! (exp->ex_flags & NFSEXP_FSID))
384 goto retry;
385 break;
386 case FSID_UUID8:
387 case FSID_UUID16:
388 if (!root_export)
389 goto retry;
390 /* fall through */
391 case FSID_UUID4_INUM:
392 case FSID_UUID16_INUM:
393 if (exp->ex_uuid == NULL)
394 goto retry;
395 break;
396 }
353 } else if (exp->ex_uuid) { 397 } else if (exp->ex_uuid) {
354 if (fhp->fh_maxsize >= 64) { 398 if (fhp->fh_maxsize >= 64) {
355 if (root_export) 399 if (root_export)