int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, handle_t *handle, struct ocfs2_alloc_context *ac, u32 bits_wanted, u32 *bit_off, u32 *num_bits) { int status, start; struct inode *local_alloc_inode; void *bitmap; struct ocfs2_dinode *alloc; struct ocfs2_local_alloc *la; mlog_entry_void(); BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); local_alloc_inode = ac->ac_inode; 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) { /* TODO: Shouldn't we just BUG here? */ status = -ENOSPC; mlog_errno(status); goto bail; } bitmap = la->la_bitmap; *bit_off = le32_to_cpu(la->la_bm_off) + start; /* local alloc is always contiguous by nature -- we never * delete bits from it! */ *num_bits = bits_wanted; status = ocfs2_journal_access_di(handle, INODE_CACHE(local_alloc_inode), osb->local_alloc_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto bail; } while(bits_wanted--) ocfs2_set_bit(start++, bitmap); le32_add_cpu(&alloc->id1.bitmap1.i_used, *num_bits); status = ocfs2_journal_dirty(handle, osb->local_alloc_bh); if (status < 0) { mlog_errno(status); goto bail; } status = 0; bail: mlog_exit(status); return status; }
int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, handle_t *handle, struct ocfs2_alloc_context *ac, u32 bits_wanted, u32 *bit_off, u32 *num_bits) { int status, start; struct inode *local_alloc_inode; void *bitmap; struct ocfs2_dinode *alloc; struct ocfs2_local_alloc *la; BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); local_alloc_inode = ac->ac_inode; 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, ac->ac_resv); if (start == -1) { /* TODO: Shouldn't we just BUG here? */ status = -ENOSPC; mlog_errno(status); goto bail; } bitmap = la->la_bitmap; *bit_off = le32_to_cpu(la->la_bm_off) + start; *num_bits = bits_wanted; status = ocfs2_journal_access_di(handle, INODE_CACHE(local_alloc_inode), osb->local_alloc_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto bail; } ocfs2_resmap_claimed_bits(&osb->osb_la_resmap, ac->ac_resv, start, bits_wanted); while(bits_wanted--) ocfs2_set_bit(start++, bitmap); le32_add_cpu(&alloc->id1.bitmap1.i_used, *num_bits); ocfs2_journal_dirty(handle, osb->local_alloc_bh); bail: if (status) mlog_errno(status); 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; }