Commit 3d23985d6cfa7908e46fd0c62a2ee84faffe4d8b

Authored by Al Viro
1 parent 6cc9c1d2c1

switch fat to ->s_d_op, close exportfs races there

don't bother with lock_super() in fat_fill_super() callers, while
we are at it - there won't be any concurrency anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 4 changed files with 25 additions and 45 deletions Side-by-side Diff

... ... @@ -319,7 +319,8 @@
319 319 struct msdos_dir_entry *de, loff_t i_pos);
320 320 extern int fat_sync_inode(struct inode *inode);
321 321 extern int fat_fill_super(struct super_block *sb, void *data, int silent,
322   - const struct inode_operations *fs_dir_inode_ops, int isvfat);
  322 + const struct inode_operations *fs_dir_inode_ops,
  323 + int isvfat, void (*setup)(struct super_block *));
323 324  
324 325 extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
325 326 struct inode *i2);
... ... @@ -703,7 +703,6 @@
703 703 struct fid *fid, int fh_len, int fh_type)
704 704 {
705 705 struct inode *inode = NULL;
706   - struct dentry *result;
707 706 u32 *fh = fid->raw;
708 707  
709 708 if (fh_len < 5 || fh_type != 3)
... ... @@ -748,10 +747,7 @@
748 747 * the fat_iget lookup again. If that fails, then we are totally out
749 748 * of luck. But all that is for another day
750 749 */
751   - result = d_obtain_alias(inode);
752   - if (!IS_ERR(result))
753   - d_set_d_op(result, sb->s_root->d_op);
754   - return result;
  750 + return d_obtain_alias(inode);
755 751 }
756 752  
757 753 static int
... ... @@ -799,8 +795,6 @@
799 795 brelse(bh);
800 796  
801 797 parent = d_obtain_alias(inode);
802   - if (!IS_ERR(parent))
803   - d_set_d_op(parent, sb->s_root->d_op);
804 798 out:
805 799 unlock_super(sb);
806 800  
... ... @@ -1244,7 +1238,8 @@
1244 1238 * Read the super block of an MS-DOS FS.
1245 1239 */
1246 1240 int fat_fill_super(struct super_block *sb, void *data, int silent,
1247   - const struct inode_operations *fs_dir_inode_ops, int isvfat)
  1241 + const struct inode_operations *fs_dir_inode_ops, int isvfat,
  1242 + void (*setup)(struct super_block *))
1248 1243 {
1249 1244 struct inode *root_inode = NULL, *fat_inode = NULL;
1250 1245 struct buffer_head *bh;
... ... @@ -1279,6 +1274,8 @@
1279 1274 error = parse_options(data, isvfat, silent, &debug, &sbi->options);
1280 1275 if (error)
1281 1276 goto out_fail;
  1277 +
  1278 + setup(sb); /* flavour-specific stuff that needs options */
1282 1279  
1283 1280 error = -EIO;
1284 1281 sb_min_blocksize(sb, 512);
fs/fat/namei_msdos.c
... ... @@ -227,11 +227,7 @@
227 227 }
228 228 out:
229 229 unlock_super(sb);
230   - d_set_d_op(dentry, &msdos_dentry_operations);
231   - dentry = d_splice_alias(inode, dentry);
232   - if (dentry)
233   - d_set_d_op(dentry, &msdos_dentry_operations);
234   - return dentry;
  230 + return d_splice_alias(inode, dentry);
235 231  
236 232 error:
237 233 unlock_super(sb);
238 234  
239 235  
... ... @@ -661,21 +657,16 @@
661 657 .getattr = fat_getattr,
662 658 };
663 659  
664   -static int msdos_fill_super(struct super_block *sb, void *data, int silent)
  660 +static void setup(struct super_block *sb)
665 661 {
666   - int res;
667   -
668   - lock_super(sb);
669   - res = fat_fill_super(sb, data, silent, &msdos_dir_inode_operations, 0);
670   - if (res) {
671   - unlock_super(sb);
672   - return res;
673   - }
674   -
  662 + sb->s_d_op = &msdos_dentry_operations;
675 663 sb->s_flags |= MS_NOATIME;
676   - d_set_d_op(sb->s_root, &msdos_dentry_operations);
677   - unlock_super(sb);
678   - return 0;
  664 +}
  665 +
  666 +static int msdos_fill_super(struct super_block *sb, void *data, int silent)
  667 +{
  668 + return fat_fill_super(sb, data, silent, &msdos_dir_inode_operations,
  669 + 0, setup);
679 670 }
680 671  
681 672 static struct dentry *msdos_mount(struct file_system_type *fs_type,
... ... @@ -772,13 +772,10 @@
772 772  
773 773 out:
774 774 unlock_super(sb);
775   - d_set_d_op(dentry, sb->s_root->d_op);
776 775 dentry->d_time = dentry->d_parent->d_inode->i_version;
777 776 dentry = d_splice_alias(inode, dentry);
778   - if (dentry) {
779   - d_set_d_op(dentry, sb->s_root->d_op);
  777 + if (dentry)
780 778 dentry->d_time = dentry->d_parent->d_inode->i_version;
781   - }
782 779 return dentry;
783 780  
784 781 error:
785 782  
786 783  
787 784  
788 785  
... ... @@ -1066,24 +1063,18 @@
1066 1063 .getattr = fat_getattr,
1067 1064 };
1068 1065  
1069   -static int vfat_fill_super(struct super_block *sb, void *data, int silent)
  1066 +static void setup(struct super_block *sb)
1070 1067 {
1071   - int res;
1072   -
1073   - lock_super(sb);
1074   - res = fat_fill_super(sb, data, silent, &vfat_dir_inode_operations, 1);
1075   - if (res) {
1076   - unlock_super(sb);
1077   - return res;
1078   - }
1079   -
1080 1068 if (MSDOS_SB(sb)->options.name_check != 's')
1081   - d_set_d_op(sb->s_root, &vfat_ci_dentry_ops);
  1069 + sb->s_d_op = &vfat_ci_dentry_ops;
1082 1070 else
1083   - d_set_d_op(sb->s_root, &vfat_dentry_ops);
  1071 + sb->s_d_op = &vfat_dentry_ops;
  1072 +}
1084 1073  
1085   - unlock_super(sb);
1086   - return 0;
  1074 +static int vfat_fill_super(struct super_block *sb, void *data, int silent)
  1075 +{
  1076 + return fat_fill_super(sb, data, silent, &vfat_dir_inode_operations,
  1077 + 1, setup);
1087 1078 }
1088 1079  
1089 1080 static struct dentry *vfat_mount(struct file_system_type *fs_type,