ocfs2: don't use handle for locking in allocation functions

Instead we record our state on the allocation context structure which all
callers already know about and lifetime correctly. This means the
reservation functions don't need a handle passed in any more, and we can
also take it off the alloc context.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
This commit is contained in:
Mark Fasheh 2006-10-06 18:34:35 -07:00
parent 8d5596c687
commit da5cbf2f9d
7 changed files with 75 additions and 155 deletions

View File

@ -409,13 +409,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
mlog(0, "extending dir %llu (i_size = %lld)\n",
(unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size);
handle = ocfs2_alloc_handle(osb);
if (handle == NULL) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
/* dir->i_size is always block aligned. */
spin_lock(&OCFS2_I(dir)->ip_lock);
if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
@ -428,8 +421,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
}
if (!num_free_extents) {
status = ocfs2_reserve_new_metadata(osb, handle,
fe, &meta_ac);
status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -437,7 +429,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
}
}
status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
status = ocfs2_reserve_clusters(osb, 1, &data_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -450,7 +442,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS;
}
handle = ocfs2_start_trans(osb, handle, credits);
handle = ocfs2_start_trans(osb, NULL, credits);
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;

View File

@ -463,13 +463,6 @@ restart_all:
(unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode),
fe->i_clusters, clusters_to_add);
handle = ocfs2_alloc_handle(osb);
if (handle == NULL) {
status = -ENOMEM;
mlog_errno(status);
goto leave;
}
num_free_extents = ocfs2_num_free_extents(osb,
inode,
fe);
@ -480,10 +473,7 @@ restart_all:
}
if (!num_free_extents) {
status = ocfs2_reserve_new_metadata(osb,
handle,
fe,
&meta_ac);
status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -491,10 +481,7 @@ restart_all:
}
}
status = ocfs2_reserve_clusters(osb,
handle,
clusters_to_add,
&data_ac);
status = ocfs2_reserve_clusters(osb, clusters_to_add, &data_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -509,7 +496,7 @@ restart_all:
drop_alloc_sem = 1;
credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add);
handle = ocfs2_start_trans(osb, handle, credits);
handle = ocfs2_start_trans(osb, NULL, credits);
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;

View File

@ -64,7 +64,6 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
struct buffer_head *main_bm_bh);
static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_alloc_context **ac,
struct inode **bitmap_inode,
struct buffer_head **bitmap_bh);
@ -448,7 +447,6 @@ out:
* our own in order to shift windows.
*/
int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
struct ocfs2_journal_handle *passed_handle,
u32 bits_wanted,
struct ocfs2_alloc_context *ac)
{
@ -459,9 +457,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
mlog_entry_void();
BUG_ON(!passed_handle);
BUG_ON(!ac);
BUG_ON(passed_handle->k_handle);
local_alloc_inode =
ocfs2_get_system_file_inode(osb,
@ -472,7 +468,11 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
mlog_errno(status);
goto bail;
}
ocfs2_handle_add_inode(passed_handle, local_alloc_inode);
mutex_lock(&local_alloc_inode->i_mutex);
ac->ac_inode = local_alloc_inode;
ac->ac_which = OCFS2_AC_USE_LOCAL;
if (osb->local_alloc_state != OCFS2_LA_ENABLED) {
status = -ENOSPC;
@ -511,14 +511,10 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
}
}
ac->ac_inode = igrab(local_alloc_inode);
get_bh(osb->local_alloc_bh);
ac->ac_bh = osb->local_alloc_bh;
ac->ac_which = OCFS2_AC_USE_LOCAL;
status = 0;
bail:
if (local_alloc_inode)
iput(local_alloc_inode);
mlog_exit(status);
return status;
@ -774,7 +770,6 @@ bail:
}
static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_alloc_context **ac,
struct inode **bitmap_inode,
struct buffer_head **bitmap_bh)
@ -788,7 +783,6 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
goto bail;
}
(*ac)->ac_handle = handle;
(*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb);
status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
@ -891,16 +885,8 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
mlog_entry_void();
handle = ocfs2_alloc_handle(osb);
if (!handle) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
/* This will lock the main bitmap for us. */
status = ocfs2_local_alloc_reserve_for_window(osb,
handle,
&ac,
&main_bm_inode,
&main_bm_bh);
@ -910,7 +896,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
goto bail;
}
handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS);
handle = ocfs2_start_trans(osb, NULL, OCFS2_WINDOW_MOVE_CREDITS);
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;

View File

@ -42,7 +42,6 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb,
struct ocfs2_alloc_context;
int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
struct ocfs2_journal_handle *passed_handle,
u32 bits_wanted,
struct ocfs2_alloc_context *ac);

View File

@ -334,13 +334,6 @@ static int ocfs2_mknod(struct inode *dir,
return status;
}
handle = ocfs2_alloc_handle(osb);
if (handle == NULL) {
status = -ENOMEM;
mlog_errno(status);
goto leave;
}
if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
status = -EMLINK;
goto leave;
@ -368,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir,
}
/* reserve an inode spot */
status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
status = ocfs2_reserve_new_inode(osb, &inode_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -378,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir,
/* are we making a directory? If so, reserve a cluster for his
* 1st extent. */
if (S_ISDIR(mode)) {
status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
status = ocfs2_reserve_clusters(osb, 1, &data_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -386,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir,
}
}
handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS);
handle = ocfs2_start_trans(osb, NULL, OCFS2_MKNOD_CREDITS);
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;
@ -1649,14 +1642,7 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
}
handle = ocfs2_alloc_handle(osb);
if (handle == NULL) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
status = ocfs2_reserve_new_inode(osb, &inode_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -1665,7 +1651,7 @@ static int ocfs2_symlink(struct inode *dir,
/* don't reserve bitmap space for fast symlinks. */
if (l > ocfs2_fast_symlink_chars(sb)) {
status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
status = ocfs2_reserve_clusters(osb, 1, &data_ac);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -1673,7 +1659,7 @@ static int ocfs2_symlink(struct inode *dir,
}
}
handle = ocfs2_start_trans(osb, handle, credits);
handle = ocfs2_start_trans(osb, NULL, credits);
if (IS_ERR(handle)) {
status = PTR_ERR(handle);
handle = NULL;

View File

@ -59,9 +59,6 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
struct inode *alloc_inode,
struct buffer_head *bh);
static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac);
static int ocfs2_cluster_group_search(struct inode *inode,
struct buffer_head *group_bh,
u32 bits_wanted, u32 min_bits,
@ -72,6 +69,7 @@ static int ocfs2_block_group_search(struct inode *inode,
u16 *bit_off, u16 *bits_found);
static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
@ -120,8 +118,16 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode,
void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac)
{
if (ac->ac_inode)
iput(ac->ac_inode);
struct inode *inode = ac->ac_inode;
if (inode) {
if (ac->ac_which != OCFS2_AC_USE_LOCAL)
ocfs2_meta_unlock(inode, 1);
mutex_unlock(&inode->i_mutex);
iput(inode);
}
if (ac->ac_bh)
brelse(ac->ac_bh);
kfree(ac);
@ -284,16 +290,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
mlog_entry_void();
handle = ocfs2_alloc_handle(osb);
if (!handle) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
cl = &fe->id2.i_chain;
status = ocfs2_reserve_clusters(osb,
handle,
le16_to_cpu(cl->cl_cpg),
&ac);
if (status < 0) {
@ -402,27 +400,38 @@ bail:
}
static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac)
struct ocfs2_alloc_context *ac,
int type,
u32 slot)
{
int status;
u32 bits_wanted = ac->ac_bits_wanted;
struct inode *alloc_inode = ac->ac_inode;
struct inode *alloc_inode;
struct buffer_head *bh = NULL;
struct ocfs2_journal_handle *handle = ac->ac_handle;
struct ocfs2_dinode *fe;
u32 free_bits;
mlog_entry_void();
BUG_ON(handle->k_handle);
ocfs2_handle_add_inode(handle, alloc_inode);
status = ocfs2_meta_lock(alloc_inode, handle, &bh, 1);
if (status < 0) {
mlog_errno(status);
goto bail;
alloc_inode = ocfs2_get_system_file_inode(osb, type, slot);
if (!alloc_inode) {
mlog_errno(-EINVAL);
return -EINVAL;
}
mutex_lock(&alloc_inode->i_mutex);
status = ocfs2_meta_lock(alloc_inode, NULL, &bh, 1);
if (status < 0) {
mutex_unlock(&alloc_inode->i_mutex);
iput(alloc_inode);
mlog_errno(status);
return status;
}
ac->ac_inode = alloc_inode;
fe = (struct ocfs2_dinode *) bh->b_data;
if (!OCFS2_IS_VALID_DINODE(fe)) {
OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);
@ -473,12 +482,11 @@ bail:
}
int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_dinode *fe,
struct ocfs2_alloc_context **ac)
{
int status;
struct inode *alloc_inode = NULL;
u32 slot;
*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
@ -488,28 +496,18 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
}
(*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe);
(*ac)->ac_handle = handle;
(*ac)->ac_which = OCFS2_AC_USE_META;
#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS
alloc_inode = ocfs2_get_system_file_inode(osb,
EXTENT_ALLOC_SYSTEM_INODE,
0);
slot = 0;
#else
alloc_inode = ocfs2_get_system_file_inode(osb,
EXTENT_ALLOC_SYSTEM_INODE,
osb->slot_num);
slot = osb->slot_num;
#endif
if (!alloc_inode) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
(*ac)->ac_inode = igrab(alloc_inode);
(*ac)->ac_group_search = ocfs2_block_group_search;
status = ocfs2_reserve_suballoc_bits(osb, (*ac));
status = ocfs2_reserve_suballoc_bits(osb, (*ac),
EXTENT_ALLOC_SYSTEM_INODE, slot);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -523,19 +521,14 @@ bail:
*ac = NULL;
}
if (alloc_inode)
iput(alloc_inode);
mlog_exit(status);
return status;
}
int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_alloc_context **ac)
{
int status;
struct inode *alloc_inode = NULL;
*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
@ -545,22 +538,13 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
}
(*ac)->ac_bits_wanted = 1;
(*ac)->ac_handle = handle;
(*ac)->ac_which = OCFS2_AC_USE_INODE;
alloc_inode = ocfs2_get_system_file_inode(osb,
INODE_ALLOC_SYSTEM_INODE,
osb->slot_num);
if (!alloc_inode) {
status = -ENOMEM;
mlog_errno(status);
goto bail;
}
(*ac)->ac_inode = igrab(alloc_inode);
(*ac)->ac_group_search = ocfs2_block_group_search;
status = ocfs2_reserve_suballoc_bits(osb, *ac);
status = ocfs2_reserve_suballoc_bits(osb, *ac,
INODE_ALLOC_SYSTEM_INODE,
osb->slot_num);
if (status < 0) {
if (status != -ENOSPC)
mlog_errno(status);
@ -574,9 +558,6 @@ bail:
*ac = NULL;
}
if (alloc_inode)
iput(alloc_inode);
mlog_exit(status);
return status;
}
@ -588,20 +569,17 @@ int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
{
int status;
ac->ac_inode = ocfs2_get_system_file_inode(osb,
GLOBAL_BITMAP_SYSTEM_INODE,
OCFS2_INVALID_SLOT);
if (!ac->ac_inode) {
status = -EINVAL;
mlog(ML_ERROR, "Could not get bitmap inode!\n");
goto bail;
}
ac->ac_which = OCFS2_AC_USE_MAIN;
ac->ac_group_search = ocfs2_cluster_group_search;
status = ocfs2_reserve_suballoc_bits(osb, ac);
if (status < 0 && status != -ENOSPC)
status = ocfs2_reserve_suballoc_bits(osb, ac,
GLOBAL_BITMAP_SYSTEM_INODE,
OCFS2_INVALID_SLOT);
if (status < 0 && status != -ENOSPC) {
mlog_errno(status);
goto bail;
}
bail:
return status;
}
@ -610,7 +588,6 @@ bail:
* use so we figure it out for them, but unfortunately this clutters
* things a bit. */
int ocfs2_reserve_clusters(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
struct ocfs2_alloc_context **ac)
{
@ -618,8 +595,6 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
mlog_entry_void();
BUG_ON(!handle);
*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
@ -628,12 +603,10 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
}
(*ac)->ac_bits_wanted = bits_wanted;
(*ac)->ac_handle = handle;
status = -ENOSPC;
if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {
status = ocfs2_reserve_local_alloc_bits(osb,
handle,
bits_wanted,
*ac);
if ((status < 0) && (status != -ENOSPC)) {
@ -1055,6 +1028,7 @@ out:
}
static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
@ -1067,7 +1041,6 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
struct buffer_head *group_bh = NULL;
struct ocfs2_group_desc *gd;
struct inode *alloc_inode = ac->ac_inode;
struct ocfs2_journal_handle *handle = ac->ac_handle;
ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno,
&group_bh, OCFS2_BH_CACHED, alloc_inode);
@ -1115,6 +1088,7 @@ out:
}
static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
@ -1126,7 +1100,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
u16 chain, tmp_bits;
u32 tmp_used;
u64 next_group;
struct ocfs2_journal_handle *handle = ac->ac_handle;
struct inode *alloc_inode = ac->ac_inode;
struct buffer_head *group_bh = NULL;
struct buffer_head *prev_group_bh = NULL;
@ -1272,6 +1245,7 @@ bail:
/* will give out up to bits_wanted contiguous bits. */
static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
@ -1313,8 +1287,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
* by jumping straight to the most recently used
* allocation group. This helps us mantain some
* contiguousness across allocations. */
status = ocfs2_search_one_group(ac, bits_wanted, min_bits,
bit_off, num_bits,
status = ocfs2_search_one_group(ac, handle, bits_wanted,
min_bits, bit_off, num_bits,
hint_blkno, &bits_left);
if (!status) {
/* Be careful to update *bg_blkno here as the
@ -1336,7 +1310,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
ac->ac_chain = victim;
ac->ac_allow_chain_relink = 1;
status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off,
status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, bit_off,
num_bits, bg_blkno, &bits_left);
if (!status)
goto set_hint;
@ -1360,7 +1334,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
continue;
ac->ac_chain = i;
status = ocfs2_search_chain(ac, bits_wanted, min_bits,
status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits,
bit_off, num_bits, bg_blkno,
&bits_left);
if (!status)
@ -1401,10 +1375,10 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb,
BUG_ON(!ac);
BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted));
BUG_ON(ac->ac_which != OCFS2_AC_USE_META);
BUG_ON(ac->ac_handle != handle);
status = ocfs2_claim_suballoc_bits(osb,
ac,
handle,
bits_wanted,
1,
suballoc_bit_start,
@ -1440,10 +1414,10 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb,
BUG_ON(ac->ac_bits_given != 0);
BUG_ON(ac->ac_bits_wanted != 1);
BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);
BUG_ON(ac->ac_handle != handle);
status = ocfs2_claim_suballoc_bits(osb,
ac,
handle,
1,
1,
suballoc_bit,
@ -1546,7 +1520,6 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
&& ac->ac_which != OCFS2_AC_USE_MAIN);
BUG_ON(ac->ac_handle != handle);
if (ac->ac_which == OCFS2_AC_USE_LOCAL) {
status = ocfs2_claim_local_alloc_bits(osb,
@ -1572,6 +1545,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
status = ocfs2_claim_suballoc_bits(osb,
ac,
handle,
bits_wanted,
min_clusters,
&bg_bit_off,

View File

@ -43,7 +43,6 @@ struct ocfs2_alloc_context {
#define OCFS2_AC_USE_INODE 3
#define OCFS2_AC_USE_META 4
u32 ac_which;
struct ocfs2_journal_handle *ac_handle;
/* these are used by the chain search */
u16 ac_chain;
@ -60,14 +59,11 @@ static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
}
int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_dinode *fe,
struct ocfs2_alloc_context **ac);
int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
struct ocfs2_alloc_context **ac);
int ocfs2_reserve_clusters(struct ocfs2_super *osb,
struct ocfs2_journal_handle *handle,
u32 bits_wanted,
struct ocfs2_alloc_context **ac);