diff options
-rw-r--r-- | fs/ocfs2/ocfs2.h | 1 | ||||
-rw-r--r-- | fs/ocfs2/slot_map.c | 12 | ||||
-rw-r--r-- | fs/ocfs2/super.c | 23 |
3 files changed, 31 insertions, 5 deletions
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index a860633e833f..648ef8e45eaa 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -219,6 +219,7 @@ struct ocfs2_super | |||
219 | u16 max_slots; | 219 | u16 max_slots; |
220 | s16 node_num; | 220 | s16 node_num; |
221 | s16 slot_num; | 221 | s16 slot_num; |
222 | s16 preferred_slot; | ||
222 | int s_sectsize_bits; | 223 | int s_sectsize_bits; |
223 | int s_clustersize; | 224 | int s_clustersize; |
224 | int s_clustersize_bits; | 225 | int s_clustersize_bits; |
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index d8b79067dc14..af4882b62cfa 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c | |||
@@ -121,17 +121,25 @@ static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si, | |||
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | 123 | ||
124 | static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si) | 124 | static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si, s16 preferred) |
125 | { | 125 | { |
126 | int i; | 126 | int i; |
127 | s16 ret = OCFS2_INVALID_SLOT; | 127 | s16 ret = OCFS2_INVALID_SLOT; |
128 | 128 | ||
129 | if (preferred >= 0 && preferred < si->si_num_slots) { | ||
130 | if (OCFS2_INVALID_SLOT == si->si_global_node_nums[preferred]) { | ||
131 | ret = preferred; | ||
132 | goto out; | ||
133 | } | ||
134 | } | ||
135 | |||
129 | for(i = 0; i < si->si_num_slots; i++) { | 136 | for(i = 0; i < si->si_num_slots; i++) { |
130 | if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) { | 137 | if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) { |
131 | ret = (s16) i; | 138 | ret = (s16) i; |
132 | break; | 139 | break; |
133 | } | 140 | } |
134 | } | 141 | } |
142 | out: | ||
135 | return ret; | 143 | return ret; |
136 | } | 144 | } |
137 | 145 | ||
@@ -248,7 +256,7 @@ int ocfs2_find_slot(struct ocfs2_super *osb) | |||
248 | if (slot == OCFS2_INVALID_SLOT) { | 256 | if (slot == OCFS2_INVALID_SLOT) { |
249 | /* if no slot yet, then just take 1st available | 257 | /* if no slot yet, then just take 1st available |
250 | * one. */ | 258 | * one. */ |
251 | slot = __ocfs2_find_empty_slot(si); | 259 | slot = __ocfs2_find_empty_slot(si, osb->preferred_slot); |
252 | if (slot == OCFS2_INVALID_SLOT) { | 260 | if (slot == OCFS2_INVALID_SLOT) { |
253 | spin_unlock(&si->si_lock); | 261 | spin_unlock(&si->si_lock); |
254 | mlog(ML_ERROR, "no free slots available!\n"); | 262 | mlog(ML_ERROR, "no free slots available!\n"); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 86b559c7dce9..f07718a7552b 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -82,7 +82,8 @@ MODULE_AUTHOR("Oracle"); | |||
82 | MODULE_LICENSE("GPL"); | 82 | MODULE_LICENSE("GPL"); |
83 | 83 | ||
84 | static int ocfs2_parse_options(struct super_block *sb, char *options, | 84 | static int ocfs2_parse_options(struct super_block *sb, char *options, |
85 | unsigned long *mount_opt, int is_remount); | 85 | unsigned long *mount_opt, s16 *slot, |
86 | int is_remount); | ||
86 | static void ocfs2_put_super(struct super_block *sb); | 87 | static void ocfs2_put_super(struct super_block *sb); |
87 | static int ocfs2_mount_volume(struct super_block *sb); | 88 | static int ocfs2_mount_volume(struct super_block *sb); |
88 | static int ocfs2_remount(struct super_block *sb, int *flags, char *data); | 89 | static int ocfs2_remount(struct super_block *sb, int *flags, char *data); |
@@ -140,6 +141,7 @@ enum { | |||
140 | Opt_data_ordered, | 141 | Opt_data_ordered, |
141 | Opt_data_writeback, | 142 | Opt_data_writeback, |
142 | Opt_atime_quantum, | 143 | Opt_atime_quantum, |
144 | Opt_slot, | ||
143 | Opt_err, | 145 | Opt_err, |
144 | }; | 146 | }; |
145 | 147 | ||
@@ -154,6 +156,7 @@ static match_table_t tokens = { | |||
154 | {Opt_data_ordered, "data=ordered"}, | 156 | {Opt_data_ordered, "data=ordered"}, |
155 | {Opt_data_writeback, "data=writeback"}, | 157 | {Opt_data_writeback, "data=writeback"}, |
156 | {Opt_atime_quantum, "atime_quantum=%u"}, | 158 | {Opt_atime_quantum, "atime_quantum=%u"}, |
159 | {Opt_slot, "preferred_slot=%u"}, | ||
157 | {Opt_err, NULL} | 160 | {Opt_err, NULL} |
158 | }; | 161 | }; |
159 | 162 | ||
@@ -355,9 +358,10 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data) | |||
355 | int incompat_features; | 358 | int incompat_features; |
356 | int ret = 0; | 359 | int ret = 0; |
357 | unsigned long parsed_options; | 360 | unsigned long parsed_options; |
361 | s16 slot; | ||
358 | struct ocfs2_super *osb = OCFS2_SB(sb); | 362 | struct ocfs2_super *osb = OCFS2_SB(sb); |
359 | 363 | ||
360 | if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) { | 364 | if (!ocfs2_parse_options(sb, data, &parsed_options, &slot, 1)) { |
361 | ret = -EINVAL; | 365 | ret = -EINVAL; |
362 | goto out; | 366 | goto out; |
363 | } | 367 | } |
@@ -534,6 +538,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
534 | struct dentry *root; | 538 | struct dentry *root; |
535 | int status, sector_size; | 539 | int status, sector_size; |
536 | unsigned long parsed_opt; | 540 | unsigned long parsed_opt; |
541 | s16 slot; | ||
537 | struct inode *inode = NULL; | 542 | struct inode *inode = NULL; |
538 | struct ocfs2_super *osb = NULL; | 543 | struct ocfs2_super *osb = NULL; |
539 | struct buffer_head *bh = NULL; | 544 | struct buffer_head *bh = NULL; |
@@ -541,7 +546,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
541 | 546 | ||
542 | mlog_entry("%p, %p, %i", sb, data, silent); | 547 | mlog_entry("%p, %p, %i", sb, data, silent); |
543 | 548 | ||
544 | if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) { | 549 | if (!ocfs2_parse_options(sb, data, &parsed_opt, &slot, 0)) { |
545 | status = -EINVAL; | 550 | status = -EINVAL; |
546 | goto read_super_error; | 551 | goto read_super_error; |
547 | } | 552 | } |
@@ -571,6 +576,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) | |||
571 | brelse(bh); | 576 | brelse(bh); |
572 | bh = NULL; | 577 | bh = NULL; |
573 | osb->s_mount_opt = parsed_opt; | 578 | osb->s_mount_opt = parsed_opt; |
579 | osb->preferred_slot = slot; | ||
574 | 580 | ||
575 | sb->s_magic = OCFS2_SUPER_MAGIC; | 581 | sb->s_magic = OCFS2_SUPER_MAGIC; |
576 | 582 | ||
@@ -713,6 +719,7 @@ static struct file_system_type ocfs2_fs_type = { | |||
713 | static int ocfs2_parse_options(struct super_block *sb, | 719 | static int ocfs2_parse_options(struct super_block *sb, |
714 | char *options, | 720 | char *options, |
715 | unsigned long *mount_opt, | 721 | unsigned long *mount_opt, |
722 | s16 *slot, | ||
716 | int is_remount) | 723 | int is_remount) |
717 | { | 724 | { |
718 | int status; | 725 | int status; |
@@ -722,6 +729,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
722 | options ? options : "(none)"); | 729 | options ? options : "(none)"); |
723 | 730 | ||
724 | *mount_opt = 0; | 731 | *mount_opt = 0; |
732 | *slot = OCFS2_INVALID_SLOT; | ||
725 | 733 | ||
726 | if (!options) { | 734 | if (!options) { |
727 | status = 1; | 735 | status = 1; |
@@ -782,6 +790,15 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
782 | else | 790 | else |
783 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | 791 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; |
784 | break; | 792 | break; |
793 | case Opt_slot: | ||
794 | option = 0; | ||
795 | if (match_int(&args[0], &option)) { | ||
796 | status = 0; | ||
797 | goto bail; | ||
798 | } | ||
799 | if (option) | ||
800 | *slot = (s16)option; | ||
801 | break; | ||
785 | default: | 802 | default: |
786 | mlog(ML_ERROR, | 803 | mlog(ML_ERROR, |
787 | "Unrecognized mount option \"%s\" " | 804 | "Unrecognized mount option \"%s\" " |