diff options
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 107 |
1 files changed, 56 insertions, 51 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 14f47d2bfe02..dee03197a494 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include "xattr.h" | 69 | #include "xattr.h" |
70 | #include "quota.h" | 70 | #include "quota.h" |
71 | #include "refcounttree.h" | 71 | #include "refcounttree.h" |
72 | #include "suballoc.h" | ||
72 | 73 | ||
73 | #include "buffer_head_io.h" | 74 | #include "buffer_head_io.h" |
74 | 75 | ||
@@ -100,6 +101,8 @@ struct mount_options | |||
100 | static int ocfs2_parse_options(struct super_block *sb, char *options, | 101 | static int ocfs2_parse_options(struct super_block *sb, char *options, |
101 | struct mount_options *mopt, | 102 | struct mount_options *mopt, |
102 | int is_remount); | 103 | int is_remount); |
104 | static int ocfs2_check_set_options(struct super_block *sb, | ||
105 | struct mount_options *options); | ||
103 | static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt); | 106 | static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt); |
104 | static void ocfs2_put_super(struct super_block *sb); | 107 | static void ocfs2_put_super(struct super_block *sb); |
105 | static int ocfs2_mount_volume(struct super_block *sb); | 108 | static int ocfs2_mount_volume(struct super_block *sb); |
@@ -299,9 +302,12 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
299 | 302 | ||
300 | spin_lock(&osb->osb_lock); | 303 | spin_lock(&osb->osb_lock); |
301 | out += snprintf(buf + out, len - out, | 304 | out += snprintf(buf + out, len - out, |
302 | "%10s => Slot: %d NumStolen: %d\n", "Steal", | 305 | "%10s => InodeSlot: %d StolenInodes: %d, " |
306 | "MetaSlot: %d StolenMeta: %d\n", "Steal", | ||
303 | osb->s_inode_steal_slot, | 307 | osb->s_inode_steal_slot, |
304 | atomic_read(&osb->s_num_inodes_stolen)); | 308 | atomic_read(&osb->s_num_inodes_stolen), |
309 | osb->s_meta_steal_slot, | ||
310 | atomic_read(&osb->s_num_meta_stolen)); | ||
305 | spin_unlock(&osb->osb_lock); | 311 | spin_unlock(&osb->osb_lock); |
306 | 312 | ||
307 | out += snprintf(buf + out, len - out, "OrphanScan => "); | 313 | out += snprintf(buf + out, len - out, "OrphanScan => "); |
@@ -600,7 +606,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
600 | 606 | ||
601 | lock_kernel(); | 607 | lock_kernel(); |
602 | 608 | ||
603 | if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { | 609 | if (!ocfs2_parse_options(sb, data, &parsed_options, 1) || |
610 | !ocfs2_check_set_options(sb, &parsed_options)) { | ||
604 | ret = -EINVAL; | 611 | ret = -EINVAL; |
605 | goto out; | 612 | goto out; |
606 | } | 613 | } |
@@ -691,8 +698,6 @@ unlock_osb: | |||
691 | if (!ret) { | 698 | if (!ret) { |
692 | /* Only save off the new mount options in case of a successful | 699 | /* Only save off the new mount options in case of a successful |
693 | * remount. */ | 700 | * remount. */ |
694 | if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) | ||
695 | parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; | ||
696 | osb->s_mount_opt = parsed_options.mount_opt; | 701 | osb->s_mount_opt = parsed_options.mount_opt; |
697 | osb->s_atime_quantum = parsed_options.atime_quantum; | 702 | osb->s_atime_quantum = parsed_options.atime_quantum; |
698 | osb->preferred_slot = parsed_options.slot; | 703 | osb->preferred_slot = parsed_options.slot; |
@@ -701,6 +706,10 @@ unlock_osb: | |||
701 | 706 | ||
702 | if (!ocfs2_is_hard_readonly(osb)) | 707 | if (!ocfs2_is_hard_readonly(osb)) |
703 | ocfs2_set_journal_params(osb); | 708 | ocfs2_set_journal_params(osb); |
709 | |||
710 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | ||
711 | ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ? | ||
712 | MS_POSIXACL : 0); | ||
704 | } | 713 | } |
705 | out: | 714 | out: |
706 | unlock_kernel(); | 715 | unlock_kernel(); |
@@ -1011,31 +1020,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1011 | brelse(bh); | 1020 | brelse(bh); |
1012 | bh = NULL; | 1021 | bh = NULL; |
1013 | 1022 | ||
1014 | if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)) | 1023 | if (!ocfs2_check_set_options(sb, &parsed_options)) { |
1015 | parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; | 1024 | status = -EINVAL; |
1016 | 1025 | goto read_super_error; | |
1026 | } | ||
1017 | osb->s_mount_opt = parsed_options.mount_opt; | 1027 | osb->s_mount_opt = parsed_options.mount_opt; |
1018 | osb->s_atime_quantum = parsed_options.atime_quantum; | 1028 | osb->s_atime_quantum = parsed_options.atime_quantum; |
1019 | osb->preferred_slot = parsed_options.slot; | 1029 | osb->preferred_slot = parsed_options.slot; |
1020 | osb->osb_commit_interval = parsed_options.commit_interval; | 1030 | osb->osb_commit_interval = parsed_options.commit_interval; |
1021 | osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); | 1031 | osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); |
1022 | osb->local_alloc_bits = osb->local_alloc_default_bits; | 1032 | osb->local_alloc_bits = osb->local_alloc_default_bits; |
1023 | if (osb->s_mount_opt & OCFS2_MOUNT_USRQUOTA && | ||
1024 | !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1025 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | ||
1026 | status = -EINVAL; | ||
1027 | mlog(ML_ERROR, "User quotas were requested, but this " | ||
1028 | "filesystem does not have the feature enabled.\n"); | ||
1029 | goto read_super_error; | ||
1030 | } | ||
1031 | if (osb->s_mount_opt & OCFS2_MOUNT_GRPQUOTA && | ||
1032 | !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1033 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | ||
1034 | status = -EINVAL; | ||
1035 | mlog(ML_ERROR, "Group quotas were requested, but this " | ||
1036 | "filesystem does not have the feature enabled.\n"); | ||
1037 | goto read_super_error; | ||
1038 | } | ||
1039 | 1033 | ||
1040 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); | 1034 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); |
1041 | if (status) | 1035 | if (status) |
@@ -1072,7 +1066,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1072 | "file system, but write access is " | 1066 | "file system, but write access is " |
1073 | "unavailable.\n"); | 1067 | "unavailable.\n"); |
1074 | else | 1068 | else |
1075 | mlog_errno(status); | 1069 | mlog_errno(status); |
1076 | goto read_super_error; | 1070 | goto read_super_error; |
1077 | } | 1071 | } |
1078 | 1072 | ||
@@ -1245,6 +1239,40 @@ static struct file_system_type ocfs2_fs_type = { | |||
1245 | .next = NULL | 1239 | .next = NULL |
1246 | }; | 1240 | }; |
1247 | 1241 | ||
1242 | static int ocfs2_check_set_options(struct super_block *sb, | ||
1243 | struct mount_options *options) | ||
1244 | { | ||
1245 | if (options->mount_opt & OCFS2_MOUNT_USRQUOTA && | ||
1246 | !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1247 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | ||
1248 | mlog(ML_ERROR, "User quotas were requested, but this " | ||
1249 | "filesystem does not have the feature enabled.\n"); | ||
1250 | return 0; | ||
1251 | } | ||
1252 | if (options->mount_opt & OCFS2_MOUNT_GRPQUOTA && | ||
1253 | !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1254 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | ||
1255 | mlog(ML_ERROR, "Group quotas were requested, but this " | ||
1256 | "filesystem does not have the feature enabled.\n"); | ||
1257 | return 0; | ||
1258 | } | ||
1259 | if (options->mount_opt & OCFS2_MOUNT_POSIX_ACL && | ||
1260 | !OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) { | ||
1261 | mlog(ML_ERROR, "ACL support requested but extended attributes " | ||
1262 | "feature is not enabled\n"); | ||
1263 | return 0; | ||
1264 | } | ||
1265 | /* No ACL setting specified? Use XATTR feature... */ | ||
1266 | if (!(options->mount_opt & (OCFS2_MOUNT_POSIX_ACL | | ||
1267 | OCFS2_MOUNT_NO_POSIX_ACL))) { | ||
1268 | if (OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) | ||
1269 | options->mount_opt |= OCFS2_MOUNT_POSIX_ACL; | ||
1270 | else | ||
1271 | options->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; | ||
1272 | } | ||
1273 | return 1; | ||
1274 | } | ||
1275 | |||
1248 | static int ocfs2_parse_options(struct super_block *sb, | 1276 | static int ocfs2_parse_options(struct super_block *sb, |
1249 | char *options, | 1277 | char *options, |
1250 | struct mount_options *mopt, | 1278 | struct mount_options *mopt, |
@@ -1392,40 +1420,19 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1392 | mopt->mount_opt |= OCFS2_MOUNT_INODE64; | 1420 | mopt->mount_opt |= OCFS2_MOUNT_INODE64; |
1393 | break; | 1421 | break; |
1394 | case Opt_usrquota: | 1422 | case Opt_usrquota: |
1395 | /* We check only on remount, otherwise features | ||
1396 | * aren't yet initialized. */ | ||
1397 | if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1398 | OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) { | ||
1399 | mlog(ML_ERROR, "User quota requested but " | ||
1400 | "filesystem feature is not set\n"); | ||
1401 | status = 0; | ||
1402 | goto bail; | ||
1403 | } | ||
1404 | mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA; | 1423 | mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA; |
1405 | break; | 1424 | break; |
1406 | case Opt_grpquota: | 1425 | case Opt_grpquota: |
1407 | if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb, | ||
1408 | OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) { | ||
1409 | mlog(ML_ERROR, "Group quota requested but " | ||
1410 | "filesystem feature is not set\n"); | ||
1411 | status = 0; | ||
1412 | goto bail; | ||
1413 | } | ||
1414 | mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; | 1426 | mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA; |
1415 | break; | 1427 | break; |
1416 | #ifdef CONFIG_OCFS2_FS_POSIX_ACL | ||
1417 | case Opt_acl: | 1428 | case Opt_acl: |
1418 | mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; | 1429 | mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL; |
1430 | mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL; | ||
1419 | break; | 1431 | break; |
1420 | case Opt_noacl: | 1432 | case Opt_noacl: |
1433 | mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; | ||
1421 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; | 1434 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; |
1422 | break; | 1435 | break; |
1423 | #else | ||
1424 | case Opt_acl: | ||
1425 | case Opt_noacl: | ||
1426 | printk(KERN_INFO "ocfs2 (no)acl options not supported\n"); | ||
1427 | break; | ||
1428 | #endif | ||
1429 | default: | 1436 | default: |
1430 | mlog(ML_ERROR, | 1437 | mlog(ML_ERROR, |
1431 | "Unrecognized mount option \"%s\" " | 1438 | "Unrecognized mount option \"%s\" " |
@@ -1502,12 +1509,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1502 | if (opts & OCFS2_MOUNT_INODE64) | 1509 | if (opts & OCFS2_MOUNT_INODE64) |
1503 | seq_printf(s, ",inode64"); | 1510 | seq_printf(s, ",inode64"); |
1504 | 1511 | ||
1505 | #ifdef CONFIG_OCFS2_FS_POSIX_ACL | ||
1506 | if (opts & OCFS2_MOUNT_POSIX_ACL) | 1512 | if (opts & OCFS2_MOUNT_POSIX_ACL) |
1507 | seq_printf(s, ",acl"); | 1513 | seq_printf(s, ",acl"); |
1508 | else | 1514 | else |
1509 | seq_printf(s, ",noacl"); | 1515 | seq_printf(s, ",noacl"); |
1510 | #endif | ||
1511 | 1516 | ||
1512 | return 0; | 1517 | return 0; |
1513 | } | 1518 | } |
@@ -1996,7 +2001,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1996 | osb->blocked_lock_count = 0; | 2001 | osb->blocked_lock_count = 0; |
1997 | spin_lock_init(&osb->osb_lock); | 2002 | spin_lock_init(&osb->osb_lock); |
1998 | spin_lock_init(&osb->osb_xattr_lock); | 2003 | spin_lock_init(&osb->osb_xattr_lock); |
1999 | ocfs2_init_inode_steal_slot(osb); | 2004 | ocfs2_init_steal_slots(osb); |
2000 | 2005 | ||
2001 | atomic_set(&osb->alloc_stats.moves, 0); | 2006 | atomic_set(&osb->alloc_stats.moves, 0); |
2002 | atomic_set(&osb->alloc_stats.local_data, 0); | 2007 | atomic_set(&osb->alloc_stats.local_data, 0); |