aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/ops_fstype.c135
-rw-r--r--fs/gfs2/super.c16
-rw-r--r--fs/gfs2/super.h2
3 files changed, 127 insertions, 26 deletions
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 52fb6c048981..e5ee06231ae5 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -1114,7 +1114,7 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
1114 * Returns: errno 1114 * Returns: errno
1115 */ 1115 */
1116 1116
1117static int fill_super(struct super_block *sb, void *data, int silent) 1117static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent)
1118{ 1118{
1119 struct gfs2_sbd *sdp; 1119 struct gfs2_sbd *sdp;
1120 struct gfs2_holder mount_gh; 1120 struct gfs2_holder mount_gh;
@@ -1125,17 +1125,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
1125 printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n"); 1125 printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
1126 return -ENOMEM; 1126 return -ENOMEM;
1127 } 1127 }
1128 1128 sdp->sd_args = *args;
1129 sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
1130 sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
1131 sdp->sd_args.ar_commit = 60;
1132 sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT;
1133
1134 error = gfs2_mount_args(sdp, &sdp->sd_args, data);
1135 if (error) {
1136 printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
1137 goto fail;
1138 }
1139 1129
1140 if (sdp->sd_args.ar_spectator) { 1130 if (sdp->sd_args.ar_spectator) {
1141 sb->s_flags |= MS_RDONLY; 1131 sb->s_flags |= MS_RDONLY;
@@ -1243,18 +1233,125 @@ fail:
1243 return error; 1233 return error;
1244} 1234}
1245 1235
1246static int gfs2_get_sb(struct file_system_type *fs_type, int flags, 1236static int set_gfs2_super(struct super_block *s, void *data)
1247 const char *dev_name, void *data, struct vfsmount *mnt)
1248{ 1237{
1249 return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); 1238 s->s_bdev = data;
1239 s->s_dev = s->s_bdev->bd_dev;
1240
1241 /*
1242 * We set the bdi here to the queue backing, file systems can
1243 * overwrite this in ->fill_super()
1244 */
1245 s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
1246 return 0;
1250} 1247}
1251 1248
1252static int test_meta_super(struct super_block *s, void *ptr) 1249static int test_gfs2_super(struct super_block *s, void *ptr)
1253{ 1250{
1254 struct block_device *bdev = ptr; 1251 struct block_device *bdev = ptr;
1255 return (bdev == s->s_bdev); 1252 return (bdev == s->s_bdev);
1256} 1253}
1257 1254
1255/**
1256 * gfs2_get_sb - Get the GFS2 superblock
1257 * @fs_type: The GFS2 filesystem type
1258 * @flags: Mount flags
1259 * @dev_name: The name of the device
1260 * @data: The mount arguments
1261 * @mnt: The vfsmnt for this mount
1262 *
1263 * Q. Why not use get_sb_bdev() ?
1264 * A. We need to select one of two root directories to mount, independent
1265 * of whether this is the initial, or subsequent, mount of this sb
1266 *
1267 * Returns: 0 or -ve on error
1268 */
1269
1270static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
1271 const char *dev_name, void *data, struct vfsmount *mnt)
1272{
1273 struct block_device *bdev;
1274 struct super_block *s;
1275 fmode_t mode = FMODE_READ;
1276 int error;
1277 struct gfs2_args args;
1278 struct gfs2_sbd *sdp;
1279
1280 if (!(flags & MS_RDONLY))
1281 mode |= FMODE_WRITE;
1282
1283 bdev = open_bdev_exclusive(dev_name, mode, fs_type);
1284 if (IS_ERR(bdev))
1285 return PTR_ERR(bdev);
1286
1287 /*
1288 * once the super is inserted into the list by sget, s_umount
1289 * will protect the lockfs code from trying to start a snapshot
1290 * while we are mounting
1291 */
1292 mutex_lock(&bdev->bd_fsfreeze_mutex);
1293 if (bdev->bd_fsfreeze_count > 0) {
1294 mutex_unlock(&bdev->bd_fsfreeze_mutex);
1295 error = -EBUSY;
1296 goto error_bdev;
1297 }
1298 s = sget(fs_type, test_gfs2_super, set_gfs2_super, bdev);
1299 mutex_unlock(&bdev->bd_fsfreeze_mutex);
1300 error = PTR_ERR(s);
1301 if (IS_ERR(s))
1302 goto error_bdev;
1303
1304 memset(&args, 0, sizeof(args));
1305 args.ar_quota = GFS2_QUOTA_DEFAULT;
1306 args.ar_data = GFS2_DATA_DEFAULT;
1307 args.ar_commit = 60;
1308 args.ar_errors = GFS2_ERRORS_DEFAULT;
1309
1310 error = gfs2_mount_args(&args, data);
1311 if (error) {
1312 printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
1313 if (s->s_root)
1314 goto error_super;
1315 deactivate_locked_super(s);
1316 return error;
1317 }
1318
1319 if (s->s_root) {
1320 error = -EBUSY;
1321 if ((flags ^ s->s_flags) & MS_RDONLY)
1322 goto error_super;
1323 close_bdev_exclusive(bdev, mode);
1324 } else {
1325 char b[BDEVNAME_SIZE];
1326
1327 s->s_flags = flags;
1328 s->s_mode = mode;
1329 strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
1330 sb_set_blocksize(s, block_size(bdev));
1331 error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
1332 if (error) {
1333 deactivate_locked_super(s);
1334 return error;
1335 }
1336 s->s_flags |= MS_ACTIVE;
1337 bdev->bd_super = s;
1338 }
1339
1340 sdp = s->s_fs_info;
1341 mnt->mnt_sb = s;
1342 if (args.ar_meta)
1343 mnt->mnt_root = dget(sdp->sd_master_dir);
1344 else
1345 mnt->mnt_root = dget(sdp->sd_root_dir);
1346 return 0;
1347
1348error_super:
1349 deactivate_locked_super(s);
1350error_bdev:
1351 close_bdev_exclusive(bdev, mode);
1352 return error;
1353}
1354
1258static int set_meta_super(struct super_block *s, void *ptr) 1355static int set_meta_super(struct super_block *s, void *ptr)
1259{ 1356{
1260 return -EINVAL; 1357 return -EINVAL;
@@ -1274,13 +1371,17 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
1274 dev_name, error); 1371 dev_name, error);
1275 return error; 1372 return error;
1276 } 1373 }
1277 s = sget(&gfs2_fs_type, test_meta_super, set_meta_super, 1374 s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
1278 path.dentry->d_inode->i_sb->s_bdev); 1375 path.dentry->d_inode->i_sb->s_bdev);
1279 path_put(&path); 1376 path_put(&path);
1280 if (IS_ERR(s)) { 1377 if (IS_ERR(s)) {
1281 printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); 1378 printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
1282 return PTR_ERR(s); 1379 return PTR_ERR(s);
1283 } 1380 }
1381 if ((flags ^ s->s_flags) & MS_RDONLY) {
1382 deactivate_locked_super(s);
1383 return -EBUSY;
1384 }
1284 sdp = s->s_fs_info; 1385 sdp = s->s_fs_info;
1285 mnt->mnt_sb = s; 1386 mnt->mnt_sb = s;
1286 mnt->mnt_root = dget(sdp->sd_master_dir); 1387 mnt->mnt_root = dget(sdp->sd_master_dir);
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 0ec3ec672de1..42e5458703f0 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -106,13 +106,13 @@ static const match_table_t tokens = {
106 106
107/** 107/**
108 * gfs2_mount_args - Parse mount options 108 * gfs2_mount_args - Parse mount options
109 * @sdp: 109 * @args: The structure into which the parsed options will be written
110 * @data: 110 * @options: The options to parse
111 * 111 *
112 * Return: errno 112 * Return: errno
113 */ 113 */
114 114
115int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) 115int gfs2_mount_args(struct gfs2_args *args, char *options)
116{ 116{
117 char *o; 117 char *o;
118 int token; 118 int token;
@@ -157,7 +157,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
157 break; 157 break;
158 case Opt_debug: 158 case Opt_debug:
159 if (args->ar_errors == GFS2_ERRORS_PANIC) { 159 if (args->ar_errors == GFS2_ERRORS_PANIC) {
160 fs_info(sdp, "-o debug and -o errors=panic " 160 printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
161 "are mutually exclusive.\n"); 161 "are mutually exclusive.\n");
162 return -EINVAL; 162 return -EINVAL;
163 } 163 }
@@ -210,7 +210,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
210 case Opt_commit: 210 case Opt_commit:
211 rv = match_int(&tmp[0], &args->ar_commit); 211 rv = match_int(&tmp[0], &args->ar_commit);
212 if (rv || args->ar_commit <= 0) { 212 if (rv || args->ar_commit <= 0) {
213 fs_info(sdp, "commit mount option requires a positive numeric argument\n"); 213 printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
214 return rv ? rv : -EINVAL; 214 return rv ? rv : -EINVAL;
215 } 215 }
216 break; 216 break;
@@ -219,7 +219,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
219 break; 219 break;
220 case Opt_err_panic: 220 case Opt_err_panic:
221 if (args->ar_debug) { 221 if (args->ar_debug) {
222 fs_info(sdp, "-o debug and -o errors=panic " 222 printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
223 "are mutually exclusive.\n"); 223 "are mutually exclusive.\n");
224 return -EINVAL; 224 return -EINVAL;
225 } 225 }
@@ -227,7 +227,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
227 break; 227 break;
228 case Opt_error: 228 case Opt_error:
229 default: 229 default:
230 fs_info(sdp, "invalid mount option: %s\n", o); 230 printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
231 return -EINVAL; 231 return -EINVAL;
232 } 232 }
233 } 233 }
@@ -1062,7 +1062,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
1062 spin_lock(&gt->gt_spin); 1062 spin_lock(&gt->gt_spin);
1063 args.ar_commit = gt->gt_log_flush_secs; 1063 args.ar_commit = gt->gt_log_flush_secs;
1064 spin_unlock(&gt->gt_spin); 1064 spin_unlock(&gt->gt_spin);
1065 error = gfs2_mount_args(sdp, &args, data); 1065 error = gfs2_mount_args(&args, data);
1066 if (error) 1066 if (error)
1067 return error; 1067 return error;
1068 1068
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h
index 235db3682885..ed962ea68c3a 100644
--- a/fs/gfs2/super.h
+++ b/fs/gfs2/super.h
@@ -27,7 +27,7 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
27 27
28extern void gfs2_jindex_free(struct gfs2_sbd *sdp); 28extern void gfs2_jindex_free(struct gfs2_sbd *sdp);
29 29
30extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data); 30extern int gfs2_mount_args(struct gfs2_args *args, char *data);
31 31
32extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); 32extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
33extern int gfs2_jdesc_check(struct gfs2_jdesc *jd); 33extern int gfs2_jdesc_check(struct gfs2_jdesc *jd);