it at the default (5 seconds).
                        Setting it to very large values will improve
                        performance.
+localalloc=8(*)                Allows custom localalloc size in MB. If the value is too
+                       large, the fs will silently revert it to the default.
+                       Localalloc is not enabled for local mounts.
 
 static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
                                          struct inode *local_alloc_inode);
 
-/*
- * Determine how large our local alloc window should be, in bits.
- *
- * These values (and the behavior in ocfs2_alloc_should_use_local) have
- * been chosen so that most allocations, including new block groups go
- * through local alloc.
- */
 static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb)
 {
-       BUG_ON(osb->s_clustersize_bits < 12);
+       BUG_ON(osb->s_clustersize_bits > 20);
 
-       return 2048 >> (osb->s_clustersize_bits - 12);
+       /* Size local alloc windows by the megabyte */
+       return osb->local_alloc_size << (20 - osb->s_clustersize_bits);
 }
 
 /*
 int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits)
 {
        int la_bits = ocfs2_local_alloc_window_bits(osb);
+       int ret = 0;
 
        if (osb->local_alloc_state != OCFS2_LA_ENABLED)
-               return 0;
+               goto bail;
 
        /* la_bits should be at least twice the size (in clusters) of
         * a new block group. We want to be sure block group
         * allocations go through the local alloc, so allow an
         * allocation to take up to half the bitmap. */
        if (bits > (la_bits / 2))
-               return 0;
+               goto bail;
 
-       return 1;
+       ret = 1;
+bail:
+       mlog(0, "state=%d, bits=%llu, la_bits=%d, ret=%d\n",
+            osb->local_alloc_state, (unsigned long long)bits, la_bits, ret);
+       return ret;
 }
 
 int ocfs2_load_local_alloc(struct ocfs2_super *osb)
 
        mlog_entry_void();
 
+       if (ocfs2_mount_local(osb))
+               goto bail;
+
+       if (osb->local_alloc_size == 0)
+               goto bail;
+
+       if (ocfs2_local_alloc_window_bits(osb) >= osb->bitmap_cpg) {
+               mlog(ML_NOTICE, "Requested local alloc window %d is larger "
+                    "than max possible %u. Using defaults.\n",
+                    ocfs2_local_alloc_window_bits(osb), (osb->bitmap_cpg - 1));
+               osb->local_alloc_size = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
+       }
+
        /* read the alloc off disk */
        inode = ocfs2_get_system_file_inode(osb, LOCAL_ALLOC_SYSTEM_INODE,
                                            osb->slot_num);
        if (inode)
                iput(inode);
 
+       mlog(0, "Local alloc window bits = %d\n",
+            ocfs2_local_alloc_window_bits(osb));
+
        mlog_exit(status);
        return status;
 }
                iput(local_alloc_inode);
        }
 
+       mlog(0, "bits=%d, slot=%d, ret=%d\n", bits_wanted, osb->slot_num,
+            status);
+
        mlog_exit(status);
        return status;
 }
 
        struct ocfs2_journal *journal;
        unsigned long osb_commit_interval;
 
+       int local_alloc_size;
        enum ocfs2_local_alloc_state local_alloc_state;
        struct buffer_head *local_alloc_bh;
        u64 la_last_gd;
 
 /* Journal limits (in bytes) */
 #define OCFS2_MIN_JOURNAL_SIZE         (4 * 1024 * 1024)
 
+/*
+ * Default local alloc size (in megabytes)
+ *
+ * The value chosen should be such that most allocations, including new
+ * block groups, use local alloc.
+ */
+#define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8
+
 struct ocfs2_system_inode_info {
        char    *si_name;
        int     si_iflags;
 
                if (min_clusters > (osb->bitmap_cpg - 1)) {
                        /* The only paths asking for contiguousness
                         * should know about this already. */
-                       mlog(ML_ERROR, "minimum allocation requested exceeds "
-                                      "group bitmap size!");
+                       mlog(ML_ERROR, "minimum allocation requested %u exceeds "
+                            "group bitmap size %u!\n", min_clusters,
+                            osb->bitmap_cpg);
                        status = -ENOSPC;
                        goto bail;
                }
 
        unsigned long   mount_opt;
        unsigned int    atime_quantum;
        signed short    slot;
+       unsigned int    localalloc_opt;
 };
 
 static int ocfs2_parse_options(struct super_block *sb, char *options,
        Opt_atime_quantum,
        Opt_slot,
        Opt_commit,
+       Opt_localalloc,
        Opt_err,
 };
 
        {Opt_atime_quantum, "atime_quantum=%u"},
        {Opt_slot, "preferred_slot=%u"},
        {Opt_commit, "commit=%u"},
+       {Opt_localalloc, "localalloc=%d"},
        {Opt_err, NULL}
 };
 
        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_size = parsed_options.localalloc_opt;
 
        sb->s_magic = OCFS2_SUPER_MAGIC;
 
        mopt->mount_opt = 0;
        mopt->atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
        mopt->slot = OCFS2_INVALID_SLOT;
+       mopt->localalloc_opt = OCFS2_DEFAULT_LOCAL_ALLOC_SIZE;
 
        if (!options) {
                status = 1;
                                option = JBD_DEFAULT_MAX_COMMIT_AGE;
                        mopt->commit_interval = HZ * option;
                        break;
+               case Opt_localalloc:
+                       option = 0;
+                       if (match_int(&args[0], &option)) {
+                               status = 0;
+                               goto bail;
+                       }
+                       if (option >= 0 && (option <= ocfs2_local_alloc_size(sb) * 8))
+                               mopt->localalloc_opt = option;
+                       break;
                default:
                        mlog(ML_ERROR,
                             "Unrecognized mount option \"%s\" "
                seq_printf(s, ",commit=%u",
                           (unsigned) (osb->osb_commit_interval / HZ));
 
+       if (osb->local_alloc_size != OCFS2_DEFAULT_LOCAL_ALLOC_SIZE)
+               seq_printf(s, ",localalloc=%d", osb->local_alloc_size);
+
        return 0;
 }