#ifdef CONFIG_OCFS2_FS_STATS
-DEFINE_MUTEX(la_debug_mutex);
-
static int ocfs2_la_debug_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
static ssize_t ocfs2_la_debug_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
+ static DEFINE_MUTEX(la_debug_mutex);
struct ocfs2_super *osb = file->private_data;
int written, ret;
char *buf = osb->local_alloc_debug_buf;
goto bail;
}
- status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,
- &alloc_bh, 0, inode);
+ status = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1,
+ &alloc_bh, OCFS2_BH_IGNORE_CACHE);
if (status < 0) {
mlog_errno(status);
goto bail;
bail:
if (status < 0)
- if (alloc_bh)
- brelse(alloc_bh);
+ brelse(alloc_bh);
if (inode)
iput(inode);
ocfs2_commit_trans(osb, handle);
out_unlock:
- if (main_bm_bh)
- brelse(main_bm_bh);
+ brelse(main_bm_bh);
ocfs2_inode_unlock(main_bm_inode, 1);
mutex_lock(&inode->i_mutex);
- status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,
- &alloc_bh, 0, inode);
+ status = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1,
+ &alloc_bh, OCFS2_BH_IGNORE_CACHE);
if (status < 0) {
mlog_errno(status);
goto bail;
*alloc_copy = NULL;
}
- if (alloc_bh)
- brelse(alloc_bh);
+ brelse(alloc_bh);
if (inode) {
mutex_unlock(&inode->i_mutex);
out_mutex:
mutex_unlock(&main_bm_inode->i_mutex);
- if (main_bm_bh)
- brelse(main_bm_bh);
+ brelse(main_bm_bh);
iput(main_bm_inode);
return status;
}
+/* Check to see if the local alloc window is within ac->ac_max_block */
+static int ocfs2_local_alloc_in_range(struct inode *inode,
+ struct ocfs2_alloc_context *ac,
+ u32 bits_wanted)
+{
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ struct ocfs2_dinode *alloc;
+ struct ocfs2_local_alloc *la;
+ int start;
+ u64 block_off;
+
+ if (!ac->ac_max_block)
+ return 1;
+
+ alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+ la = OCFS2_LOCAL_ALLOC(alloc);
+
+ start = ocfs2_local_alloc_find_clear_bits(osb, alloc, bits_wanted);
+ if (start == -1) {
+ mlog_errno(-ENOSPC);
+ return 0;
+ }
+
+ /*
+ * Converting (bm_off + start + bits_wanted) to blocks gives us
+ * the blkno just past our actual allocation. This is perfect
+ * to compare with ac_max_block.
+ */
+ block_off = ocfs2_clusters_to_blocks(inode->i_sb,
+ le32_to_cpu(la->la_bm_off) +
+ start + bits_wanted);
+ mlog(0, "Checking %llu against %llu\n",
+ (unsigned long long)block_off,
+ (unsigned long long)ac->ac_max_block);
+ if (block_off > ac->ac_max_block)
+ return 0;
+
+ return 1;
+}
+
/*
* make sure we've got at least bits_wanted contiguous bits in the
* local alloc. You lose them when you drop i_mutex.
goto bail;
}
+ if (ac->ac_max_block)
+ mlog(0, "Calling in_range for max block %llu\n",
+ (unsigned long long)ac->ac_max_block);
+
+ if (!ocfs2_local_alloc_in_range(local_alloc_inode, ac,
+ bits_wanted)) {
+ /*
+ * The window is outside ac->ac_max_block.
+ * This errno tells the caller to keep localalloc enabled
+ * but to get the allocation from the main bitmap.
+ */
+ status = -EFBIG;
+ goto bail;
+ }
+
ac->ac_inode = local_alloc_inode;
/* We should never use localalloc from another slot */
ac->ac_alloc_slot = osb->slot_num;
if (handle)
ocfs2_commit_trans(osb, handle);
- if (main_bm_bh)
- brelse(main_bm_bh);
+ brelse(main_bm_bh);
if (main_bm_inode)
iput(main_bm_inode);