diff options
Diffstat (limited to 'fs/ocfs2/super.c')
-rw-r--r-- | fs/ocfs2/super.c | 88 |
1 files changed, 80 insertions, 8 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index dee03197a494..1c2c39f6f0b6 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 | ||
@@ -1028,8 +1034,14 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
1028 | osb->s_atime_quantum = parsed_options.atime_quantum; | 1034 | osb->s_atime_quantum = parsed_options.atime_quantum; |
1029 | osb->preferred_slot = parsed_options.slot; | 1035 | osb->preferred_slot = parsed_options.slot; |
1030 | osb->osb_commit_interval = parsed_options.commit_interval; | 1036 | osb->osb_commit_interval = parsed_options.commit_interval; |
1031 | osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt); | 1037 | |
1032 | osb->local_alloc_bits = osb->local_alloc_default_bits; | 1038 | ocfs2_la_set_sizes(osb, parsed_options.localalloc_opt); |
1039 | osb->osb_resv_level = parsed_options.resv_level; | ||
1040 | osb->osb_dir_resv_level = parsed_options.resv_level; | ||
1041 | if (parsed_options.dir_resv_level == -1) | ||
1042 | osb->osb_dir_resv_level = parsed_options.resv_level; | ||
1043 | else | ||
1044 | osb->osb_dir_resv_level = parsed_options.dir_resv_level; | ||
1033 | 1045 | ||
1034 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); | 1046 | status = ocfs2_verify_userspace_stack(osb, &parsed_options); |
1035 | if (status) | 1047 | if (status) |
@@ -1285,11 +1297,13 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1285 | options ? options : "(none)"); | 1297 | options ? options : "(none)"); |
1286 | 1298 | ||
1287 | mopt->commit_interval = 0; | 1299 | mopt->commit_interval = 0; |
1288 | mopt->mount_opt = 0; | 1300 | mopt->mount_opt = OCFS2_MOUNT_NOINTR; |
1289 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | 1301 | mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; |
1290 | mopt->slot = OCFS2_INVALID_SLOT; | 1302 | mopt->slot = OCFS2_INVALID_SLOT; |
1291 | mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE; | 1303 | mopt->localalloc_opt = -1; |
1292 | mopt->cluster_stack[0] = '\0'; | 1304 | mopt->cluster_stack[0] = '\0'; |
1305 | mopt->resv_level = OCFS2_DEFAULT_RESV_LEVEL; | ||
1306 | mopt->dir_resv_level = -1; | ||
1293 | 1307 | ||
1294 | if (!options) { | 1308 | if (!options) { |
1295 | status = 1; | 1309 | status = 1; |
@@ -1380,7 +1394,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1380 | status = 0; | 1394 | status = 0; |
1381 | goto bail; | 1395 | goto bail; |
1382 | } | 1396 | } |
1383 | if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8)) | 1397 | if (option >= 0) |
1384 | mopt->localalloc_opt = option; | 1398 | mopt->localalloc_opt = option; |
1385 | break; | 1399 | break; |
1386 | case Opt_localflocks: | 1400 | case Opt_localflocks: |
@@ -1433,6 +1447,28 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
1433 | mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; | 1447 | mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL; |
1434 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; | 1448 | mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL; |
1435 | break; | 1449 | break; |
1450 | case Opt_resv_level: | ||
1451 | if (is_remount) | ||
1452 | break; | ||
1453 | if (match_int(&args[0], &option)) { | ||
1454 | status = 0; | ||
1455 | goto bail; | ||
1456 | } | ||
1457 | if (option >= OCFS2_MIN_RESV_LEVEL && | ||
1458 | option < OCFS2_MAX_RESV_LEVEL) | ||
1459 | mopt->resv_level = option; | ||
1460 | break; | ||
1461 | case Opt_dir_resv_level: | ||
1462 | if (is_remount) | ||
1463 | break; | ||
1464 | if (match_int(&args[0], &option)) { | ||
1465 | status = 0; | ||
1466 | goto bail; | ||
1467 | } | ||
1468 | if (option >= OCFS2_MIN_RESV_LEVEL && | ||
1469 | option < OCFS2_MAX_RESV_LEVEL) | ||
1470 | mopt->dir_resv_level = option; | ||
1471 | break; | ||
1436 | default: | 1472 | default: |
1437 | mlog(ML_ERROR, | 1473 | mlog(ML_ERROR, |
1438 | "Unrecognized mount option \"%s\" " | 1474 | "Unrecognized mount option \"%s\" " |
@@ -1487,7 +1523,7 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1487 | (unsigned) (osb->osb_commit_interval / HZ)); | 1523 | (unsigned) (osb->osb_commit_interval / HZ)); |
1488 | 1524 | ||
1489 | local_alloc_megs = osb->local_alloc_bits >> (20 - osb->s_clustersize_bits); | 1525 | local_alloc_megs = osb->local_alloc_bits >> (20 - osb->s_clustersize_bits); |
1490 | if (local_alloc_megs != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE) | 1526 | if (local_alloc_megs != ocfs2_la_default_mb(osb)) |
1491 | seq_printf(s, ",localalloc=%d", local_alloc_megs); | 1527 | seq_printf(s, ",localalloc=%d", local_alloc_megs); |
1492 | 1528 | ||
1493 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) | 1529 | if (opts & OCFS2_MOUNT_LOCALFLOCKS) |
@@ -1514,6 +1550,12 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1514 | else | 1550 | else |
1515 | seq_printf(s, ",noacl"); | 1551 | seq_printf(s, ",noacl"); |
1516 | 1552 | ||
1553 | if (osb->osb_resv_level != OCFS2_DEFAULT_RESV_LEVEL) | ||
1554 | seq_printf(s, ",resv_level=%d", osb->osb_resv_level); | ||
1555 | |||
1556 | if (osb->osb_dir_resv_level != osb->osb_resv_level) | ||
1557 | seq_printf(s, ",dir_resv_level=%d", osb->osb_resv_level); | ||
1558 | |||
1517 | return 0; | 1559 | return 0; |
1518 | } | 1560 | } |
1519 | 1561 | ||
@@ -1688,6 +1730,8 @@ static void ocfs2_inode_init_once(void *data) | |||
1688 | oi->ip_blkno = 0ULL; | 1730 | oi->ip_blkno = 0ULL; |
1689 | oi->ip_clusters = 0; | 1731 | oi->ip_clusters = 0; |
1690 | 1732 | ||
1733 | ocfs2_resv_init_once(&oi->ip_la_data_resv); | ||
1734 | |||
1691 | ocfs2_lock_res_init_once(&oi->ip_rw_lockres); | 1735 | ocfs2_lock_res_init_once(&oi->ip_rw_lockres); |
1692 | ocfs2_lock_res_init_once(&oi->ip_inode_lockres); | 1736 | ocfs2_lock_res_init_once(&oi->ip_inode_lockres); |
1693 | ocfs2_lock_res_init_once(&oi->ip_open_lockres); | 1737 | ocfs2_lock_res_init_once(&oi->ip_open_lockres); |
@@ -2042,6 +2086,12 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2042 | 2086 | ||
2043 | init_waitqueue_head(&osb->osb_mount_event); | 2087 | init_waitqueue_head(&osb->osb_mount_event); |
2044 | 2088 | ||
2089 | status = ocfs2_resmap_init(osb, &osb->osb_la_resmap); | ||
2090 | if (status) { | ||
2091 | mlog_errno(status); | ||
2092 | goto bail; | ||
2093 | } | ||
2094 | |||
2045 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); | 2095 | osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL); |
2046 | if (!osb->vol_label) { | 2096 | if (!osb->vol_label) { |
2047 | mlog(ML_ERROR, "unable to alloc vol label\n"); | 2097 | mlog(ML_ERROR, "unable to alloc vol label\n"); |
@@ -2224,9 +2274,11 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
2224 | } | 2274 | } |
2225 | 2275 | ||
2226 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; | 2276 | osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; |
2277 | osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters; | ||
2227 | iput(inode); | 2278 | iput(inode); |
2228 | 2279 | ||
2229 | osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8; | 2280 | osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0, |
2281 | osb->s_feature_incompat) * 8; | ||
2230 | 2282 | ||
2231 | status = ocfs2_init_slot_info(osb); | 2283 | status = ocfs2_init_slot_info(osb); |
2232 | if (status < 0) { | 2284 | if (status < 0) { |
@@ -2509,5 +2561,25 @@ void __ocfs2_abort(struct super_block* sb, | |||
2509 | ocfs2_handle_error(sb); | 2561 | ocfs2_handle_error(sb); |
2510 | } | 2562 | } |
2511 | 2563 | ||
2564 | /* | ||
2565 | * Void signal blockers, because in-kernel sigprocmask() only fails | ||
2566 | * when SIG_* is wrong. | ||
2567 | */ | ||
2568 | void ocfs2_block_signals(sigset_t *oldset) | ||
2569 | { | ||
2570 | int rc; | ||
2571 | sigset_t blocked; | ||
2572 | |||
2573 | sigfillset(&blocked); | ||
2574 | rc = sigprocmask(SIG_BLOCK, &blocked, oldset); | ||
2575 | BUG_ON(rc); | ||
2576 | } | ||
2577 | |||
2578 | void ocfs2_unblock_signals(sigset_t *oldset) | ||
2579 | { | ||
2580 | int rc = sigprocmask(SIG_SETMASK, oldset, NULL); | ||
2581 | BUG_ON(rc); | ||
2582 | } | ||
2583 | |||
2512 | module_init(ocfs2_init); | 2584 | module_init(ocfs2_init); |
2513 | module_exit(ocfs2_exit); | 2585 | module_exit(ocfs2_exit); |