Commit 3f82ff55168e92859119bf348e9e0bd6714d2fea

Authored by Ryusuke Konishi
Committed by Al Viro
1 parent 33c8e57c86

nilfs2: get rid of sget use for checking if current mount is present

This stops using sget() for checking if an r/w-mount or an r/o-mount
exists on the device.  This elimination uses a back pointer to the
current mount added to nilfs object.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 2 changed files with 35 additions and 60 deletions Side-by-side Diff

... ... @@ -67,8 +67,6 @@
67 67  
68 68 static void nilfs_write_super(struct super_block *sb);
69 69 static int nilfs_remount(struct super_block *sb, int *flags, char *data);
70   -static int test_exclusive_mount(struct file_system_type *fs_type,
71   - struct block_device *bdev, int flags);
72 70  
73 71 /**
74 72 * nilfs_error() - report failure condition on a filesystem
... ... @@ -329,6 +327,10 @@
329 327 nilfs_commit_super(sbi, 1);
330 328 up_write(&nilfs->ns_sem);
331 329 }
  330 + down_write(&nilfs->ns_sem);
  331 + if (nilfs->ns_current == sbi)
  332 + nilfs->ns_current = NULL;
  333 + up_write(&nilfs->ns_sem);
332 334  
333 335 nilfs_detach_checkpoint(sbi);
334 336 put_nilfs(sbi->s_nilfs);
... ... @@ -880,6 +882,11 @@
880 882 goto failed_root;
881 883 }
882 884  
  885 + down_write(&nilfs->ns_sem);
  886 + if (!nilfs_test_opt(sbi, SNAPSHOT))
  887 + nilfs->ns_current = sbi;
  888 + up_write(&nilfs->ns_sem);
  889 +
883 890 return 0;
884 891  
885 892 failed_root:
886 893  
887 894  
888 895  
... ... @@ -958,14 +965,16 @@
958 965 * by fsck since we originally mounted the partition.)
959 966 */
960 967 down(&sb->s_bdev->bd_mount_sem);
961   - /* Check existing RW-mount */
962   - if (test_exclusive_mount(sb->s_type, sb->s_bdev, 0)) {
  968 + down_read(&nilfs->ns_sem);
  969 + if (nilfs->ns_current && nilfs->ns_current != sbi) {
963 970 printk(KERN_WARNING "NILFS (device %s): couldn't "
964   - "remount because a RW-mount exists.\n",
  971 + "remount because an RW-mount exists.\n",
965 972 sb->s_id);
  973 + up_read(&nilfs->ns_sem);
966 974 err = -EBUSY;
967 975 goto rw_remount_failed;
968 976 }
  977 + up_read(&nilfs->ns_sem);
969 978 if (sbi->s_snapshot_cno != nilfs_last_cno(nilfs)) {
970 979 printk(KERN_WARNING "NILFS (device %s): couldn't "
971 980 "remount because the current RO-mount is not "
... ... @@ -984,6 +993,7 @@
984 993  
985 994 down_write(&nilfs->ns_sem);
986 995 nilfs_setup_super(sbi);
  996 + nilfs->ns_current = sbi;
987 997 up_write(&nilfs->ns_sem);
988 998  
989 999 up(&sb->s_bdev->bd_mount_sem);
... ... @@ -1118,10 +1128,23 @@
1118 1128 }
1119 1129  
1120 1130 down(&sd.bdev->bd_mount_sem);
1121   - if (!sd.cno &&
1122   - (err = test_exclusive_mount(fs_type, sd.bdev, flags ^ MS_RDONLY))) {
1123   - err = (err < 0) ? : -EBUSY;
1124   - goto failed_unlock;
  1131 +
  1132 + if (!sd.cno) {
  1133 + /*
  1134 + * Check if an exclusive mount exists or not.
  1135 + * Snapshot mounts coexist with a current mount
  1136 + * (i.e. rw-mount or ro-mount), whereas rw-mount and
  1137 + * ro-mount are mutually exclusive.
  1138 + */
  1139 + down_read(&nilfs->ns_sem);
  1140 + if (nilfs->ns_current &&
  1141 + ((nilfs->ns_current->s_super->s_flags ^ flags)
  1142 + & MS_RDONLY)) {
  1143 + up_read(&nilfs->ns_sem);
  1144 + err = -EBUSY;
  1145 + goto failed_unlock;
  1146 + }
  1147 + up_read(&nilfs->ns_sem);
1125 1148 }
1126 1149  
1127 1150 /*
... ... @@ -1180,57 +1203,6 @@
1180 1203 * put_nilfs() and unlocking bd_mount_sem need the block device.
1181 1204 */
1182 1205 return err;
1183   -}
1184   -
1185   -static int nilfs_test_bdev_super3(struct super_block *s, void *data)
1186   -{
1187   - struct nilfs_super_data *sd = data;
1188   - int ret;
1189   -
1190   - if (s->s_bdev != sd->bdev)
1191   - return 0;
1192   - if (down_read_trylock(&s->s_umount)) {
1193   - ret = (s->s_flags & MS_RDONLY) && s->s_root &&
1194   - nilfs_test_opt(NILFS_SB(s), SNAPSHOT);
1195   - up_read(&s->s_umount);
1196   - if (ret)
1197   - return 0; /* ignore snapshot mounts */
1198   - }
1199   - return !((sd->flags ^ s->s_flags) & MS_RDONLY);
1200   -}
1201   -
1202   -static int __false_bdev_super(struct super_block *s, void *data)
1203   -{
1204   -#if 0 /* XXX: workaround for lock debug. This is not good idea */
1205   - up_write(&s->s_umount);
1206   -#endif
1207   - return -EFAULT;
1208   -}
1209   -
1210   -/**
1211   - * test_exclusive_mount - check whether an exclusive RW/RO mount exists or not.
1212   - * fs_type: filesystem type
1213   - * bdev: block device
1214   - * flag: 0 (check rw-mount) or MS_RDONLY (check ro-mount)
1215   - * res: pointer to an integer to store result
1216   - *
1217   - * This function must be called within a section protected by bd_mount_mutex.
1218   - */
1219   -static int test_exclusive_mount(struct file_system_type *fs_type,
1220   - struct block_device *bdev, int flags)
1221   -{
1222   - struct super_block *s;
1223   - struct nilfs_super_data sd = { .flags = flags, .bdev = bdev };
1224   -
1225   - s = sget(fs_type, nilfs_test_bdev_super3, __false_bdev_super, &sd);
1226   - if (IS_ERR(s)) {
1227   - if (PTR_ERR(s) != -EFAULT)
1228   - return PTR_ERR(s);
1229   - return 0; /* Not found */
1230   - }
1231   - up_write(&s->s_umount);
1232   - deactivate_super(s);
1233   - return 1; /* Found */
1234 1206 }
1235 1207  
1236 1208 struct file_system_type nilfs_fs_type = {
fs/nilfs2/the_nilfs.h
... ... @@ -50,6 +50,7 @@
50 50 * @ns_sem: semaphore for shared states
51 51 * @ns_writer_mutex: mutex protecting ns_writer attach/detach
52 52 * @ns_writer_refcount: number of referrers on ns_writer
  53 + * @ns_current: back pointer to current mount
53 54 * @ns_sbh: buffer heads of on-disk super blocks
54 55 * @ns_sbp: pointers to super block data
55 56 * @ns_sbwtime: previous write time of super blocks
... ... @@ -97,6 +98,8 @@
97 98 struct rw_semaphore ns_sem;
98 99 struct mutex ns_writer_mutex;
99 100 atomic_t ns_writer_refcount;
  101 +
  102 + struct nilfs_sb_info *ns_current;
100 103  
101 104 /*
102 105 * used for