aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2010-04-05 21:17:16 -0400
committerJoel Becker <joel.becker@oracle.com>2010-05-05 21:18:07 -0400
commit83f92318fa33cc084e14e64dc903e605f75884c1 (patch)
treec7466c64019fb050c69cab27b4388e3a86d58b1a
parentb07f8f24dfe54da0f074b78949044842e8df881f (diff)
ocfs2: Add dir_resv_level mount option
The default behavior for directory reservations stays the same, but we add a mount option so people can tweak the size of directory reservations according to their workloads. Signed-off-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--Documentation/filesystems/ocfs2.txt4
-rw-r--r--fs/ocfs2/dir.c6
-rw-r--r--fs/ocfs2/ocfs2.h1
-rw-r--r--fs/ocfs2/reservations.c9
-rw-r--r--fs/ocfs2/reservations.h2
-rw-r--r--fs/ocfs2/super.c23
6 files changed, 40 insertions, 5 deletions
diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt
index 32339e584a9a..1f7ae144f6d8 100644
--- a/Documentation/filesystems/ocfs2.txt
+++ b/Documentation/filesystems/ocfs2.txt
@@ -83,3 +83,7 @@ noacl (*) Disables POSIX Access Control Lists support.
83resv_level=2 (*) Set how agressive allocation reservations will be. 83resv_level=2 (*) Set how agressive allocation reservations will be.
84 Valid values are between 0 (reservations off) to 8 84 Valid values are between 0 (reservations off) to 8
85 (maximum space for reservations). 85 (maximum space for reservations).
86dir_resv_level= (*) By default, directory reservations will scale with file
87 reservations - users should rarely need to change this
88 value. If allocation reservations are turned off, this
89 option will have no effect.
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 8563f97c58af..6c9a28a2d3ae 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -2977,7 +2977,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
2977 * if we only get one now, that's enough to continue. The rest 2977 * if we only get one now, that's enough to continue. The rest
2978 * will be claimed after the conversion to extents. 2978 * will be claimed after the conversion to extents.
2979 */ 2979 */
2980 data_ac->ac_resv = &oi->ip_la_data_resv; 2980 if (ocfs2_dir_resv_allowed(osb))
2981 data_ac->ac_resv = &oi->ip_la_data_resv;
2981 ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, &len); 2982 ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, &len);
2982 if (ret) { 2983 if (ret) {
2983 mlog_errno(ret); 2984 mlog_errno(ret);
@@ -3348,7 +3349,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
3348 goto bail; 3349 goto bail;
3349 } 3350 }
3350 3351
3351 data_ac->ac_resv = &OCFS2_I(dir)->ip_la_data_resv; 3352 if (ocfs2_dir_resv_allowed(osb))
3353 data_ac->ac_resv = &OCFS2_I(dir)->ip_la_data_resv;
3352 3354
3353 credits = ocfs2_calc_extend_credits(sb, el, 1); 3355 credits = ocfs2_calc_extend_credits(sb, el, 1);
3354 } else { 3356 } else {
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 09d7aee3dabe..a388528f485c 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -356,6 +356,7 @@ struct ocfs2_super
356 struct ocfs2_reservation_map osb_la_resmap; 356 struct ocfs2_reservation_map osb_la_resmap;
357 357
358 unsigned int osb_resv_level; 358 unsigned int osb_resv_level;
359 unsigned int osb_dir_resv_level;
359 360
360 /* Next three fields are for local node slot recovery during 361 /* Next three fields are for local node slot recovery during
361 * mount. */ 362 * mount. */
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c
index 87fa35791f18..6497bcc00fa5 100644
--- a/fs/ocfs2/reservations.c
+++ b/fs/ocfs2/reservations.c
@@ -44,7 +44,11 @@ DEFINE_SPINLOCK(resv_lock);
44 44
45#define OCFS2_MIN_RESV_WINDOW_BITS 8 45#define OCFS2_MIN_RESV_WINDOW_BITS 8
46#define OCFS2_MAX_RESV_WINDOW_BITS 1024 46#define OCFS2_MAX_RESV_WINDOW_BITS 1024
47#define OCFS2_RESV_DIR_WINDOW_BITS OCFS2_MIN_RESV_WINDOW_BITS 47
48int ocfs2_dir_resv_allowed(struct ocfs2_super *osb)
49{
50 return (osb->osb_resv_level && osb->osb_dir_resv_level);
51}
48 52
49static unsigned int ocfs2_resv_window_bits(struct ocfs2_reservation_map *resmap, 53static unsigned int ocfs2_resv_window_bits(struct ocfs2_reservation_map *resmap,
50 struct ocfs2_alloc_reservation *resv) 54 struct ocfs2_alloc_reservation *resv)
@@ -56,8 +60,7 @@ static unsigned int ocfs2_resv_window_bits(struct ocfs2_reservation_map *resmap,
56 /* 8, 16, 32, 64, 128, 256, 512, 1024 */ 60 /* 8, 16, 32, 64, 128, 256, 512, 1024 */
57 bits = 4 << osb->osb_resv_level; 61 bits = 4 << osb->osb_resv_level;
58 } else { 62 } else {
59 /* For now, treat directories the same as files. */ 63 bits = 4 << osb->osb_dir_resv_level;
60 bits = 4 << osb->osb_resv_level;
61 } 64 }
62 return bits; 65 return bits;
63} 66}
diff --git a/fs/ocfs2/reservations.h b/fs/ocfs2/reservations.h
index 022aff601e15..25b0c0e31e91 100644
--- a/fs/ocfs2/reservations.h
+++ b/fs/ocfs2/reservations.h
@@ -67,6 +67,8 @@ void ocfs2_resv_init_once(struct ocfs2_alloc_reservation *resv);
67void ocfs2_resv_set_type(struct ocfs2_alloc_reservation *resv, 67void ocfs2_resv_set_type(struct ocfs2_alloc_reservation *resv,
68 unsigned int flags); 68 unsigned int flags);
69 69
70int ocfs2_dir_resv_allowed(struct ocfs2_super *osb);
71
70/** 72/**
71 * ocfs2_resv_discard() - truncate a reservation 73 * ocfs2_resv_discard() - truncate a reservation
72 * @resmap: 74 * @resmap:
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 5745682eb1c0..79d7d4cf45b1 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -96,6 +96,7 @@ struct mount_options
96 signed short slot; 96 signed short slot;
97 int localalloc_opt; 97 int localalloc_opt;
98 unsigned int resv_level; 98 unsigned int resv_level;
99 int dir_resv_level;
99 char cluster_stack[OCFS2_STACK_LABEL_LEN + 1]; 100 char cluster_stack[OCFS2_STACK_LABEL_LEN + 1];
100}; 101};
101 102
@@ -178,6 +179,7 @@ enum {
178 Opt_usrquota, 179 Opt_usrquota,
179 Opt_grpquota, 180 Opt_grpquota,
180 Opt_resv_level, 181 Opt_resv_level,
182 Opt_dir_resv_level,
181 Opt_err, 183 Opt_err,
182}; 184};
183 185
@@ -205,6 +207,7 @@ static const match_table_t tokens = {
205 {Opt_usrquota, "usrquota"}, 207 {Opt_usrquota, "usrquota"},
206 {Opt_grpquota, "grpquota"}, 208 {Opt_grpquota, "grpquota"},
207 {Opt_resv_level, "resv_level=%u"}, 209 {Opt_resv_level, "resv_level=%u"},
210 {Opt_dir_resv_level, "dir_resv_level=%u"},
208 {Opt_err, NULL} 211 {Opt_err, NULL}
209}; 212};
210 213
@@ -1034,6 +1037,11 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
1034 1037
1035 ocfs2_la_set_sizes(osb, parsed_options.localalloc_opt); 1038 ocfs2_la_set_sizes(osb, parsed_options.localalloc_opt);
1036 osb->osb_resv_level = parsed_options.resv_level; 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;
1037 1045
1038 status = ocfs2_verify_userspace_stack(osb, &parsed_options); 1046 status = ocfs2_verify_userspace_stack(osb, &parsed_options);
1039 if (status) 1047 if (status)
@@ -1295,6 +1303,7 @@ static int ocfs2_parse_options(struct super_block *sb,
1295 mopt->localalloc_opt = -1; 1303 mopt->localalloc_opt = -1;
1296 mopt->cluster_stack[0] = '\0'; 1304 mopt->cluster_stack[0] = '\0';
1297 mopt->resv_level = OCFS2_DEFAULT_RESV_LEVEL; 1305 mopt->resv_level = OCFS2_DEFAULT_RESV_LEVEL;
1306 mopt->dir_resv_level = -1;
1298 1307
1299 if (!options) { 1308 if (!options) {
1300 status = 1; 1309 status = 1;
@@ -1449,6 +1458,17 @@ static int ocfs2_parse_options(struct super_block *sb,
1449 option < OCFS2_MAX_RESV_LEVEL) 1458 option < OCFS2_MAX_RESV_LEVEL)
1450 mopt->resv_level = option; 1459 mopt->resv_level = option;
1451 break; 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;
1452 default: 1472 default:
1453 mlog(ML_ERROR, 1473 mlog(ML_ERROR,
1454 "Unrecognized mount option \"%s\" " 1474 "Unrecognized mount option \"%s\" "
@@ -1533,6 +1553,9 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1533 if (osb->osb_resv_level != OCFS2_DEFAULT_RESV_LEVEL) 1553 if (osb->osb_resv_level != OCFS2_DEFAULT_RESV_LEVEL)
1534 seq_printf(s, ",resv_level=%d", osb->osb_resv_level); 1554 seq_printf(s, ",resv_level=%d", osb->osb_resv_level);
1535 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
1536 return 0; 1559 return 0;
1537} 1560}
1538 1561