aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/localalloc.c42
-rw-r--r--fs/ocfs2/ocfs2.h1
-rw-r--r--fs/ocfs2/ocfs2_fs.h8
-rw-r--r--fs/ocfs2/suballoc.c5
-rw-r--r--fs/ocfs2/super.c17
5 files changed, 59 insertions, 14 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 0de0792fce7f..add1ffdc5c6c 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -75,18 +75,12 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
75static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, 75static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
76 struct inode *local_alloc_inode); 76 struct inode *local_alloc_inode);
77 77
78/*
79 * Determine how large our local alloc window should be, in bits.
80 *
81 * These values (and the behavior in ocfs2_alloc_should_use_local) have
82 * been chosen so that most allocations, including new block groups go
83 * through local alloc.
84 */
85static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb) 78static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb)
86{ 79{
87 BUG_ON(osb->s_clustersize_bits < 12); 80 BUG_ON(osb->s_clustersize_bits > 20);
88 81
89 return 2048 >> (osb->s_clustersize_bits - 12); 82 /* Size local alloc windows by the megabyte */
83 return osb->local_alloc_size << (20 - osb->s_clustersize_bits);
90} 84}
91 85
92/* 86/*
@@ -96,18 +90,23 @@ static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb)
96int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits) 90int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits)
97{ 91{
98 int la_bits = ocfs2_local_alloc_window_bits(osb); 92 int la_bits = ocfs2_local_alloc_window_bits(osb);
93 int ret = 0;
99 94
100 if (osb->local_alloc_state != OCFS2_LA_ENABLED) 95 if (osb->local_alloc_state != OCFS2_LA_ENABLED)
101 return 0; 96 goto bail;
102 97
103 /* la_bits should be at least twice the size (in clusters) of 98 /* la_bits should be at least twice the size (in clusters) of
104 * a new block group. We want to be sure block group 99 * a new block group. We want to be sure block group
105 * allocations go through the local alloc, so allow an 100 * allocations go through the local alloc, so allow an
106 * allocation to take up to half the bitmap. */ 101 * allocation to take up to half the bitmap. */
107 if (bits > (la_bits / 2)) 102 if (bits > (la_bits / 2))
108 return 0; 103 goto bail;
109 104
110 return 1; 105 ret = 1;
106bail:
107 mlog(0, "state=%d, bits=%llu, la_bits=%d, ret=%d\n",
108 osb->local_alloc_state, (unsigned long long)bits, la_bits, ret);
109 return ret;
111} 110}
112 111
113int ocfs2_load_local_alloc(struct ocfs2_super *osb) 112int ocfs2_load_local_alloc(struct ocfs2_super *osb)
@@ -121,6 +120,19 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb)
121 120
122 mlog_entry_void(); 121 mlog_entry_void();
123 122
123 if (ocfs2_mount_local(osb))
124 goto bail;
125
126 if (osb->local_alloc_size == 0)
127 goto bail;
128
129 if (ocfs2_local_alloc_window_bits(osb) >= osb->bitmap_cpg) {
130 mlog(ML_NOTICE, "Requested local alloc window %d is larger "
131 "than max possible %u. Using defaults.\n",
132 ocfs2_local_alloc_window_bits(osb), (osb->bitmap_cpg - 1));
133 osb->local_alloc_size = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
134 }
135
124 /* read the alloc off disk */ 136 /* read the alloc off disk */
125 inode = ocfs2_get_system_file_inode(osb, LOCAL_ALLOC_SYSTEM_INODE, 137 inode = ocfs2_get_system_file_inode(osb, LOCAL_ALLOC_SYSTEM_INODE,
126 osb->slot_num); 138 osb->slot_num);
@@ -181,6 +193,9 @@ bail:
181 if (inode) 193 if (inode)
182 iput(inode); 194 iput(inode);
183 195
196 mlog(0, "Local alloc window bits = %d\n",
197 ocfs2_local_alloc_window_bits(osb));
198
184 mlog_exit(status); 199 mlog_exit(status);
185 return status; 200 return status;
186} 201}
@@ -521,6 +536,9 @@ bail:
521 iput(local_alloc_inode); 536 iput(local_alloc_inode);
522 } 537 }
523 538
539 mlog(0, "bits=%d, slot=%d, ret=%d\n", bits_wanted, osb->slot_num,
540 status);
541
524 mlog_exit(status); 542 mlog_exit(status);
525 return status; 543 return status;
526} 544}
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 82802f5672a1..d12bd7036da7 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -231,6 +231,7 @@ struct ocfs2_super
231 struct ocfs2_journal *journal; 231 struct ocfs2_journal *journal;
232 unsigned long osb_commit_interval; 232 unsigned long osb_commit_interval;
233 233
234 int local_alloc_size;
234 enum ocfs2_local_alloc_state local_alloc_state; 235 enum ocfs2_local_alloc_state local_alloc_state;
235 struct buffer_head *local_alloc_bh; 236 struct buffer_head *local_alloc_bh;
236 u64 la_last_gd; 237 u64 la_last_gd;
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 425551737f1f..3633edd3982f 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -270,6 +270,14 @@ struct ocfs2_new_group_input {
270/* Journal limits (in bytes) */ 270/* Journal limits (in bytes) */
271#define OCFS2_MIN_JOURNAL_SIZE (4 * 1024 * 1024) 271#define OCFS2_MIN_JOURNAL_SIZE (4 * 1024 * 1024)
272 272
273/*
274 * Default local alloc size (in megabytes)
275 *
276 * The value chosen should be such that most allocations, including new
277 * block groups, use local alloc.
278 */
279#define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8
280
273struct ocfs2_system_inode_info { 281struct ocfs2_system_inode_info {
274 char *si_name; 282 char *si_name;
275 int si_iflags; 283 int si_iflags;
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 4391744e80f8..7e397e2c25dd 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -1516,8 +1516,9 @@ int __ocfs2_claim_clusters(struct ocfs2_super *osb,
1516 if (min_clusters > (osb->bitmap_cpg - 1)) { 1516 if (min_clusters > (osb->bitmap_cpg - 1)) {
1517 /* The only paths asking for contiguousness 1517 /* The only paths asking for contiguousness
1518 * should know about this already. */ 1518 * should know about this already. */
1519 mlog(ML_ERROR, "minimum allocation requested exceeds " 1519 mlog(ML_ERROR, "minimum allocation requested %u exceeds "
1520 "group bitmap size!"); 1520 "group bitmap size %u!\n", min_clusters,
1521 osb->bitmap_cpg);
1521 status = -ENOSPC; 1522 status = -ENOSPC;
1522 goto bail; 1523 goto bail;
1523 } 1524 }
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 8044ed97d362..1104f14c3183 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -87,6 +87,7 @@ struct mount_options
87 unsigned long mount_opt; 87 unsigned long mount_opt;
88 unsigned int atime_quantum; 88 unsigned int atime_quantum;
89 signed short slot; 89 signed short slot;
90 unsigned int localalloc_opt;
90}; 91};
91 92
92static int ocfs2_parse_options(struct super_block *sb, char *options, 93static int ocfs2_parse_options(struct super_block *sb, char *options,
@@ -151,6 +152,7 @@ enum {
151 Opt_atime_quantum, 152 Opt_atime_quantum,
152 Opt_slot, 153 Opt_slot,
153 Opt_commit, 154 Opt_commit,
155 Opt_localalloc,
154 Opt_err, 156 Opt_err,
155}; 157};
156 158
@@ -167,6 +169,7 @@ static match_table_t tokens = {
167 {Opt_atime_quantum, "atime_quantum=%u"}, 169 {Opt_atime_quantum, "atime_quantum=%u"},
168 {Opt_slot, "preferred_slot=%u"}, 170 {Opt_slot, "preferred_slot=%u"},
169 {Opt_commit, "commit=%u"}, 171 {Opt_commit, "commit=%u"},
172 {Opt_localalloc, "localalloc=%d"},
170 {Opt_err, NULL} 173 {Opt_err, NULL}
171}; 174};
172 175
@@ -602,6 +605,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
602 osb->s_atime_quantum = parsed_options.atime_quantum; 605 osb->s_atime_quantum = parsed_options.atime_quantum;
603 osb->preferred_slot = parsed_options.slot; 606 osb->preferred_slot = parsed_options.slot;
604 osb->osb_commit_interval = parsed_options.commit_interval; 607 osb->osb_commit_interval = parsed_options.commit_interval;
608 osb->local_alloc_size = parsed_options.localalloc_opt;
605 609
606 sb->s_magic = OCFS2_SUPER_MAGIC; 610 sb->s_magic = OCFS2_SUPER_MAGIC;
607 611
@@ -756,6 +760,7 @@ static int ocfs2_parse_options(struct super_block *sb,
756 mopt->mount_opt = 0; 760 mopt->mount_opt = 0;
757 mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; 761 mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
758 mopt->slot = OCFS2_INVALID_SLOT; 762 mopt->slot = OCFS2_INVALID_SLOT;
763 mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
759 764
760 if (!options) { 765 if (!options) {
761 status = 1; 766 status = 1;
@@ -834,6 +839,15 @@ static int ocfs2_parse_options(struct super_block *sb,
834 option = JBD_DEFAULT_MAX_COMMIT_AGE; 839 option = JBD_DEFAULT_MAX_COMMIT_AGE;
835 mopt->commit_interval = HZ * option; 840 mopt->commit_interval = HZ * option;
836 break; 841 break;
842 case Opt_localalloc:
843 option = 0;
844 if (match_int(&args[0], &option)) {
845 status = 0;
846 goto bail;
847 }
848 if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8))
849 mopt->localalloc_opt = option;
850 break;
837 default: 851 default:
838 mlog(ML_ERROR, 852 mlog(ML_ERROR,
839 "Unrecognized mount option \"%s\" " 853 "Unrecognized mount option \"%s\" "
@@ -886,6 +900,9 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
886 seq_printf(s, ",commit=%u", 900 seq_printf(s, ",commit=%u",
887 (unsigned) (osb->osb_commit_interval / HZ)); 901 (unsigned) (osb->osb_commit_interval / HZ));
888 902
903 if (osb->local_alloc_size != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE)
904 seq_printf(s, ",localalloc=%d", osb->local_alloc_size);
905
889 return 0; 906 return 0;
890} 907}
891 908