aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfsfh.c83
1 files changed, 45 insertions, 38 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 8847f3fbfc1e..78d8ebf162ca 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -397,6 +397,40 @@ static inline void _fh_update_old(struct dentry *dentry,
397 fh->ofh_dirino = 0; 397 fh->ofh_dirino = 0;
398} 398}
399 399
400static bool is_root_export(struct svc_export *exp)
401{
402 return exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root;
403}
404
405static struct super_block *exp_sb(struct svc_export *exp)
406{
407 return exp->ex_path.dentry->d_inode->i_sb;
408}
409
410static bool fsid_type_ok_for_exp(u8 fsid_type, struct svc_export *exp)
411{
412 switch (fsid_type) {
413 case FSID_DEV:
414 if (!old_valid_dev(exp_sb(exp)->s_dev))
415 return 0;
416 /* FALL THROUGH */
417 case FSID_MAJOR_MINOR:
418 case FSID_ENCODE_DEV:
419 return exp_sb(exp)->s_type->fs_flags & FS_REQUIRES_DEV;
420 case FSID_NUM:
421 return exp->ex_flags & NFSEXP_FSID;
422 case FSID_UUID8:
423 case FSID_UUID16:
424 if (!is_root_export(exp))
425 return 0;
426 /* fall through */
427 case FSID_UUID4_INUM:
428 case FSID_UUID16_INUM:
429 return exp->ex_uuid != NULL;
430 }
431 return 1;
432}
433
400__be32 434__be32
401fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, 435fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
402 struct svc_fh *ref_fh) 436 struct svc_fh *ref_fh)
@@ -414,8 +448,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
414 struct inode * inode = dentry->d_inode; 448 struct inode * inode = dentry->d_inode;
415 struct dentry *parent = dentry->d_parent; 449 struct dentry *parent = dentry->d_parent;
416 __u32 *datap; 450 __u32 *datap;
417 dev_t ex_dev = exp->ex_path.dentry->d_inode->i_sb->s_dev; 451 dev_t ex_dev = exp_sb(exp)->s_dev;
418 int root_export = (exp->ex_path.dentry == exp->ex_path.dentry->d_sb->s_root);
419 452
420 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n", 453 dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
421 MAJOR(ex_dev), MINOR(ex_dev), 454 MAJOR(ex_dev), MINOR(ex_dev),
@@ -447,49 +480,24 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
447 goto retry; 480 goto retry;
448 } 481 }
449 482
450 /* Need to check that this type works for this 483 /*
451 * export point. As the fsid -> filesystem mapping 484 * As the fsid -> filesystem mapping was guided by
452 * was guided by user-space, there is no guarantee 485 * user-space, there is no guarantee that the filesystem
453 * that the filesystem actually supports that fsid 486 * actually supports that fsid type. If it doesn't we
454 * type. If it doesn't we loop around again without 487 * loop around again without ref_fh set.
455 * ref_fh set.
456 */ 488 */
457 switch(fsid_type) { 489 if (!fsid_type_ok_for_exp(fsid_type, exp))
458 case FSID_DEV: 490 goto retry;
459 if (!old_valid_dev(ex_dev))
460 goto retry;
461 /* FALL THROUGH */
462 case FSID_MAJOR_MINOR:
463 case FSID_ENCODE_DEV:
464 if (!(exp->ex_path.dentry->d_inode->i_sb->s_type->fs_flags
465 & FS_REQUIRES_DEV))
466 goto retry;
467 break;
468 case FSID_NUM:
469 if (! (exp->ex_flags & NFSEXP_FSID))
470 goto retry;
471 break;
472 case FSID_UUID8:
473 case FSID_UUID16:
474 if (!root_export)
475 goto retry;
476 /* fall through */
477 case FSID_UUID4_INUM:
478 case FSID_UUID16_INUM:
479 if (exp->ex_uuid == NULL)
480 goto retry;
481 break;
482 }
483 } else if (exp->ex_flags & NFSEXP_FSID) { 491 } else if (exp->ex_flags & NFSEXP_FSID) {
484 fsid_type = FSID_NUM; 492 fsid_type = FSID_NUM;
485 } else if (exp->ex_uuid) { 493 } else if (exp->ex_uuid) {
486 if (fhp->fh_maxsize >= 64) { 494 if (fhp->fh_maxsize >= 64) {
487 if (root_export) 495 if (is_root_export(exp))
488 fsid_type = FSID_UUID16; 496 fsid_type = FSID_UUID16;
489 else 497 else
490 fsid_type = FSID_UUID16_INUM; 498 fsid_type = FSID_UUID16_INUM;
491 } else { 499 } else {
492 if (root_export) 500 if (is_root_export(exp))
493 fsid_type = FSID_UUID8; 501 fsid_type = FSID_UUID8;
494 else 502 else
495 fsid_type = FSID_UUID4_INUM; 503 fsid_type = FSID_UUID4_INUM;
@@ -639,8 +647,7 @@ enum fsid_source fsid_source(struct svc_fh *fhp)
639 case FSID_DEV: 647 case FSID_DEV:
640 case FSID_ENCODE_DEV: 648 case FSID_ENCODE_DEV:
641 case FSID_MAJOR_MINOR: 649 case FSID_MAJOR_MINOR:
642 if (fhp->fh_export->ex_path.dentry->d_inode->i_sb->s_type->fs_flags 650 if (exp_sb(fhp->fh_export)->s_type->fs_flags & FS_REQUIRES_DEV)
643 & FS_REQUIRES_DEV)
644 return FSIDSOURCE_DEV; 651 return FSIDSOURCE_DEV;
645 break; 652 break;
646 case FSID_NUM: 653 case FSID_NUM: