diff options
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 92 |
1 files changed, 84 insertions, 8 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index dee03197a494..2c26ce251cb3 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -94,7 +94,9 @@ struct mount_options | |||
94 | unsigned long mount_opt; | 94 | unsigned long mount_opt; |
95 | unsigned int atime_quantum; | 95 | unsigned int atime_quantum; |
96 | signed short slot; | 96 | signed short slot; |
97 | unsigned int localalloc_opt; | 97 | int localalloc_opt; |
98 | unsigned int resv_level; | ||
99 | int dir_resv_level; | ||
98 | char cluster_stack[OCFS2_STACK_LABEL_LEN + 1]; | 100 | char cluster_stack[OCFS2_STACK_LABEL_LEN + 1]; |
99 | }; | 101 | }; |
100 | 102 | ||
@@ -176,6 +178,8 @@ enum { | |||
176 | Opt_noacl, | 178 | Opt_noacl, |
177 | Opt_usrquota, | 179 | Opt_usrquota, |
178 | Opt_grpquota, | 180 | Opt_grpquota, |
181 | Opt_resv_level, | ||
182 | Opt_dir_resv_level, | ||
179 | Opt_err, | 183 | Opt_err, |
180 | }; | 184 | }; |
181 | 185 | ||
@@ -202,6 +206,8 @@ static const match_table_t tokens = { | |||
202 | {Opt_noacl, "noacl"}, | 206 | {Opt_noacl, "noacl"}, |
203 | {Opt_usrquota, "usrquota"}, | 207 | {Opt_usrquota, "usrquota"}, |
204 | {Opt_grpquota, "grpquota"}, | 208 | {Opt_grpquota, "grpquota"}, |
209 | {Opt_resv_level, "resv_level=%u"}, | ||
210 | {Opt_dir_resv_level, "dir_resv_level=%u"}, | ||
205 | {Opt_err, NULL} | 211 | {Opt_err, NULL} |
206 | }; | 212 | }; |
207 | 213 | ||
@@ -932,12 +938,16 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) | |||
932 | int type; | 938 | int type; |
933 | struct inode *inode; | 939 | struct inode *inode; |
934 | struct super_block *sb = osb->sb; | 940 | struct super_block *sb = osb->sb; |
941 | struct ocfs2_mem_dqinfo *oinfo; | ||
935 | 942 | ||
936 | /* We mostly ignore errors in this function because there's not much | 943 | /* We mostly ignore errors in this function because there's not much |
937 | * we can do when we see them */ | 944 | * we can do when we see them */ |
938 | for (type = 0; type < MAXQUOTAS; type++) { | 945 | for (type = 0; type < MAXQUOTAS; type++) { |
939 | if (!sb_has_quota_loaded(sb, type)) | 946 | if (!sb_has_quota_loaded(sb, type)) |
940 | continue; | 947 | continue; |
948 | /* Cancel periodic syncing before we grab dqonoff_mutex */ | ||
949 | oinfo = sb_dqinfo(sb, type)->dqi_priv; | ||
950 | cancel_delayed_work_sync(&oinfo->dqi_sync_work); | ||
941 | inode = igrab(sb->s_dquot.files[type]); | 951 | inode = igrab(sb->s_dquot.files[type]); |
942 | /* Turn off quotas. This will remove all dquot structures from | 952 | /* Turn off quotas. This will remove all dquot structures from |
943 | * memory and so they will be automatically synced to global | 953 | * memory and so they will be automatically synced to global |
@@ -1028,8 +1038,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1028 | osb->s_atime_quantum = parsed_options.atime_quantum; | 1038 | osb->s_atime_quantum = parsed_options.atime_quantum; |
1029 | osb->preferred_slot = parsed_options.slot; | 1039 | osb->preferred_slot = parsed_options.slot; |
1030 | osb->osb_commit_interval = parsed_options.commit_interval; | 1040 | osb->osb_commit_interval = parsed_options.commit_interval; |
1031 | osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); | 1041 | |
1032 | osb->local_alloc_bits = osb->local_alloc_default_bits; | 1042 | ocfs2_la_set_sizes(osb, parsed_options.localalloc_opt); |
1043 | osb->osb_resv_level = parsed_options.resv_level; | ||
1044 | osb->osb_dir_resv_level = parsed_options.resv_level; | ||
1045 | if (parsed_options.dir_resv_level == -1) | ||
1046 | osb->osb_dir_resv_level = parsed_options.resv_level; | ||
1047 | else | ||
1048 | osb->osb_dir_resv_level = parsed_options.dir_resv_level; | ||
1033 | 1049 | ||
1034 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); | 1050 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); |
1035 | if (status) | 1051 | if (status) |
@@ -1285,11 +1301,13 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1285 | options ? options : "(none)"); | 1301 | options ? options : "(none)"); |
1286 | 1302 | ||
1287 | mopt->commit_interval = 0; | 1303 | mopt->commit_interval = 0; |
1288 | mopt->mount_opt = 0; | 1304 | mopt->mount_opt = OCFS2_MOUNT_NOINTR; |
1289 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | 1305 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; |
1290 | mopt->slot = OCFS2_INVALID_SLOT; | 1306 | mopt->slot = OCFS2_INVALID_SLOT; |
1291 | mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE; | 1307 | mopt->localalloc_opt = -1; |
1292 | mopt->cluster_stack[0] = '\0'; | 1308 | mopt->cluster_stack[0] = '\0'; |
1309 | mopt->resv_level = OCFS2_DEFAULT_RESV_LEVEL; | ||
1310 | mopt->dir_resv_level = -1; | ||
1293 | 1311 | ||
1294 | if (!options) { | 1312 | if (!options) { |
1295 | status = 1; | 1313 | status = 1; |
@@ -1380,7 +1398,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1380 | status = 0; | 1398 | status = 0; |
1381 | goto bail; | 1399 | goto bail; |
1382 | } | 1400 | } |
1383 | if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8)) | 1401 | if (option >= 0) |
1384 | mopt->localalloc_opt = option; | 1402 | mopt->localalloc_opt = option; |
1385 | break; | 1403 | break; |
1386 | case Opt_localflocks: | 1404 | case Opt_localflocks: |
@@ -1433,6 +1451,28 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1433 | mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; | 1451 | mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; |
1434 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; | 1452 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; |
1435 | break; | 1453 | break; |
1454 | case Opt_resv_level: | ||
1455 | if (is_remount) | ||
1456 | break; | ||
1457 | if (match_int(&args[0], &option)) { | ||
1458 | status = 0; | ||
1459 | goto bail; | ||
1460 | } | ||
1461 | if (option >= OCFS2_MIN_RESV_LEVEL && | ||
1462 | option < OCFS2_MAX_RESV_LEVEL) | ||
1463 | mopt->resv_level = option; | ||
1464 | break; | ||
1465 | case Opt_dir_resv_level: | ||
1466 | if (is_remount) | ||
1467 | break; | ||
1468 | if (match_int(&args[0], &option)) { | ||
1469 | status = 0; | ||
1470 | goto bail; | ||
1471 | } | ||
1472 | if (option >= OCFS2_MIN_RESV_LEVEL && | ||
1473 | option < OCFS2_MAX_RESV_LEVEL) | ||
1474 | mopt->dir_resv_level = option; | ||
1475 | break; | ||
1436 | default: | 1476 | default: |
1437 | mlog(ML_ERROR, | 1477 | mlog(ML_ERROR, |
1438 | "Unrecognized mount option \"%s\" " | 1478 | "Unrecognized mount option \"%s\" " |
@@ -1487,7 +1527,7 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1487 | (unsigned) (osb->osb_commit_interval / HZ)); | 1527 | (unsigned) (osb->osb_commit_interval / HZ)); |
1488 | 1528 | ||
1489 | local_alloc_megs = osb->local_alloc_bits >> (20 - osb->s_clustersize_bits); | 1529 | local_alloc_megs = osb->local_alloc_bits >> (20 - osb->s_clustersize_bits); |
1490 | if (local_alloc_megs != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE) | 1530 | if (local_alloc_megs != ocfs2_la_default_mb(osb)) |
1491 | seq_printf(s, ",localalloc=%d", local_alloc_megs); | 1531 | seq_printf(s, ",localalloc=%d", local_alloc_megs); |
1492 | 1532 | ||
1493 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) | 1533 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) |
@@ -1514,6 +1554,12 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1514 | else | 1554 | else |
1515 | seq_printf(s, ",noacl"); | 1555 | seq_printf(s, ",noacl"); |
1516 | 1556 | ||
1557 | if (osb->osb_resv_level != OCFS2_DEFAULT_RESV_LEVEL) | ||
1558 | seq_printf(s, ",resv_level=%d", osb->osb_resv_level); | ||
1559 | |||
1560 | if (osb->osb_dir_resv_level != osb->osb_resv_level) | ||
1561 | seq_printf(s, ",dir_resv_level=%d", osb->osb_resv_level); | ||
1562 | |||
1517 | return 0; | 1563 | return 0; |
1518 | } | 1564 | } |
1519 | 1565 | ||
@@ -1688,6 +1734,8 @@ static void ocfs2_inode_init_once(void *data) | |||
1688 | oi->ip_blkno = 0ULL; | 1734 | oi->ip_blkno = 0ULL; |
1689 | oi->ip_clusters = 0; | 1735 | oi->ip_clusters = 0; |
1690 | 1736 | ||
1737 | ocfs2_resv_init_once(&oi->ip_la_data_resv); | ||
1738 | |||
1691 | ocfs2_lock_res_init_once(&oi->ip_rw_lockres); | 1739 | ocfs2_lock_res_init_once(&oi->ip_rw_lockres); |
1692 | ocfs2_lock_res_init_once(&oi->ip_inode_lockres); | 1740 | ocfs2_lock_res_init_once(&oi->ip_inode_lockres); |
1693 | ocfs2_lock_res_init_once(&oi->ip_open_lockres); | 1741 | ocfs2_lock_res_init_once(&oi->ip_open_lockres); |
@@ -2042,6 +2090,12 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2042 | 2090 | ||
2043 | init_waitqueue_head(&osb->osb_mount_event); | 2091 | init_waitqueue_head(&osb->osb_mount_event); |
2044 | 2092 | ||
2093 | status = ocfs2_resmap_init(osb, &osb->osb_la_resmap); | ||
2094 | if (status) { | ||
2095 | mlog_errno(status); | ||
2096 | goto bail; | ||
2097 | } | ||
2098 | |||
2045 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); | 2099 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); |
2046 | if (!osb->vol_label) { | 2100 | if (!osb->vol_label) { |
2047 | mlog(ML_ERROR, "unable to alloc vol label\n"); | 2101 | mlog(ML_ERROR, "unable to alloc vol label\n"); |
@@ -2224,9 +2278,11 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2224 | } | 2278 | } |
2225 | 2279 | ||
2226 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; | 2280 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; |
2281 | osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters; | ||
2227 | iput(inode); | 2282 | iput(inode); |
2228 | 2283 | ||
2229 | osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8; | 2284 | osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0, |
2285 | osb->s_feature_incompat) * 8; | ||
2230 | 2286 | ||
2231 | status = ocfs2_init_slot_info(osb); | 2287 | status = ocfs2_init_slot_info(osb); |
2232 | if (status < 0) { | 2288 | if (status < 0) { |
@@ -2509,5 +2565,25 @@ void __ocfs2_abort(struct super_block* sb, | |||
2509 | ocfs2_handle_error(sb); | 2565 | ocfs2_handle_error(sb); |
2510 | } | 2566 | } |
2511 | 2567 | ||
2568 | /* | ||
2569 | * Void signal blockers, because in-kernel sigprocmask() only fails | ||
2570 | * when SIG_* is wrong. | ||
2571 | */ | ||
2572 | void ocfs2_block_signals(sigset_t *oldset) | ||
2573 | { | ||
2574 | int rc; | ||
2575 | sigset_t blocked; | ||
2576 | |||
2577 | sigfillset(&blocked); | ||
2578 | rc = sigprocmask(SIG_BLOCK, &blocked, oldset); | ||
2579 | BUG_ON(rc); | ||
2580 | } | ||
2581 | |||
2582 | void ocfs2_unblock_signals(sigset_t *oldset) | ||
2583 | { | ||
2584 | int rc = sigprocmask(SIG_SETMASK, oldset, NULL); | ||
2585 | BUG_ON(rc); | ||
2586 | } | ||
2587 | |||
2512 | module_init(ocfs2_init); | 2588 | module_init(ocfs2_init); |
2513 | module_exit(ocfs2_exit); | 2589 | module_exit(ocfs2_exit); |