ocfs2: clean up localalloc mount option size parsing
authorMark Fasheh <mfasheh@suse.com>
Tue, 6 Apr 2010 01:17:13 +0000 (18:17 -0700)
committerJoel Becker <joel.becker@oracle.com>
Thu, 6 May 2010 01:18:06 +0000 (18:18 -0700)
This patch pulls the local alloc sizing code into localalloc.c and provides
a callout to it from ocfs2_fill_super(). Behavior is essentially unchanged
except that I correctly calculate the maximum local alloc size. The old code
in ocfs2_parse_options() calculated the max size as:

ocfs2_local_alloc_size(sb) * 8

which is correct, in bits. Unfortunately though the option passed in is in
megabytes. Ultimately, this bug made no real difference - the shrink code
would catch a too-large size and bring it down to something reasonable.
Still, it's less than efficient as-is.

Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
fs/ocfs2/localalloc.c
fs/ocfs2/localalloc.h
fs/ocfs2/ocfs2.h
fs/ocfs2/super.c

index 880e4bc827bedae1b9dbeaa3cef67ac66c3ec4e7..e39a3e7146c98d9ad93fc278bd442f7979ed6c61 100644 (file)
@@ -75,6 +75,34 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
 static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
                                          struct inode *local_alloc_inode);
 
+void ocfs2_la_set_sizes(struct ocfs2_super *osb, int requested_mb)
+{
+       struct super_block *sb = osb->sb;
+       unsigned int la_default_mb = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
+       unsigned int la_max_mb;
+
+       la_max_mb = ocfs2_clusters_to_megabytes(sb,
+                                               ocfs2_local_alloc_size(sb) * 8);
+
+       mlog(0, "requested: %dM, max: %uM, default: %uM\n",
+            requested_mb, la_max_mb, la_default_mb);
+
+       if (requested_mb == -1) {
+               /* No user request - use defaults */
+               osb->local_alloc_default_bits =
+                       ocfs2_megabytes_to_clusters(sb, la_default_mb);
+       } else if (requested_mb > la_max_mb) {
+               /* Request is too big, we give the maximum available */
+               osb->local_alloc_default_bits =
+                       ocfs2_megabytes_to_clusters(sb, la_max_mb);
+       } else {
+               osb->local_alloc_default_bits =
+                       ocfs2_megabytes_to_clusters(sb, requested_mb);
+       }
+
+       osb->local_alloc_bits = osb->local_alloc_default_bits;
+}
+
 static inline int ocfs2_la_state_enabled(struct ocfs2_super *osb)
 {
        return (osb->local_alloc_state == OCFS2_LA_THROTTLED ||
index ac5ea9f8665342013335591dffc6177c8d193727..04195c67f7c186bc840d1ae01ae214bf5c90531b 100644 (file)
@@ -30,6 +30,8 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb);
 
 void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb);
 
+void ocfs2_la_set_sizes(struct ocfs2_super *osb, int requested_mb);
+
 int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
                                     int node_num,
                                     struct ocfs2_dinode **alloc_copy);
index 9552560df6cd1ceedec23bbdc925adcca6770557..e98c954cf961cb7f025c877d2e6a1b19796c1b22 100644 (file)
@@ -768,6 +768,12 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb,
        return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits);
 }
 
+static inline unsigned int ocfs2_clusters_to_megabytes(struct super_block *sb,
+                                                      unsigned int clusters)
+{
+       return clusters >> (20 - OCFS2_SB(sb)->s_clustersize_bits);
+}
+
 static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
 {
        ext2_set_bit(bit, bitmap);
index 2a9f4c455f28dbc11c35f86ed40f3194a3e11205..fc839996d052a47b900aa226ed107425eb2369a3 100644 (file)
@@ -94,7 +94,7 @@ struct mount_options
        unsigned long   mount_opt;
        unsigned int    atime_quantum;
        signed short    slot;
-       unsigned int    localalloc_opt;
+       int             localalloc_opt;
        unsigned int    resv_level;
        char            cluster_stack[OCFS2_STACK_LABEL_LEN + 1];
 };
@@ -1031,8 +1031,8 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
        osb->s_atime_quantum = parsed_options.atime_quantum;
        osb->preferred_slot = parsed_options.slot;
        osb->osb_commit_interval = parsed_options.commit_interval;
-       osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt);
-       osb->local_alloc_bits = osb->local_alloc_default_bits;
+
+       ocfs2_la_set_sizes(osb, parsed_options.localalloc_opt);
        osb->osb_resv_level = parsed_options.resv_level;
 
        status = ocfs2_verify_userspace_stack(osb, &parsed_options);
@@ -1292,7 +1292,7 @@ static int ocfs2_parse_options(struct super_block *sb,
        mopt->mount_opt = 0;
        mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
        mopt->slot = OCFS2_INVALID_SLOT;
-       mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
+       mopt->localalloc_opt = -1;
        mopt->cluster_stack[0] = '\0';
        mopt->resv_level = OCFS2_DEFAULT_RESV_LEVEL;
 
@@ -1385,7 +1385,7 @@ static int ocfs2_parse_options(struct super_block *sb,
                                status = 0;
                                goto bail;
                        }
-                       if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8))
+                       if (option >= 0)
                                mopt->localalloc_opt = option;
                        break;
                case Opt_localflocks: