ocfs2: Take the inode out of the metadata read/write paths.

We are really passing the inode into the ocfs2_read/write_blocks()
functions to get at the metadata cache.  This commit passes the cache
directly into the metadata block functions, divorcing them from the
inode.

Signed-off-by: Joel Becker <joel.becker@oracle.com>
This commit is contained in:
Joel Becker 2009-02-10 20:00:41 -08:00
parent 6e5a3d7538
commit 8cb471e8f8
20 changed files with 156 additions and 134 deletions

View file

@ -859,7 +859,7 @@ int ocfs2_read_extent_block(struct inode *inode, u64 eb_blkno,
int rc; int rc;
struct buffer_head *tmp = *bh; struct buffer_head *tmp = *bh;
rc = ocfs2_read_block(inode, eb_blkno, &tmp, rc = ocfs2_read_block(INODE_CACHE(inode), eb_blkno, &tmp,
ocfs2_validate_extent_block); ocfs2_validate_extent_block);
/* If ocfs2_read_block() got us a new bh, pass it up. */ /* If ocfs2_read_block() got us a new bh, pass it up. */
@ -949,7 +949,8 @@ static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb,
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
ocfs2_set_new_buffer_uptodate(inode, bhs[i]); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode),
bhs[i]);
status = ocfs2_journal_access_eb(handle, inode, bhs[i], status = ocfs2_journal_access_eb(handle, inode, bhs[i],
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -2559,7 +2560,7 @@ static void ocfs2_unlink_path(struct inode *inode, handle_t *handle,
le16_to_cpu(el->l_next_free_rec)); le16_to_cpu(el->l_next_free_rec));
ocfs2_journal_dirty(handle, bh); ocfs2_journal_dirty(handle, bh);
ocfs2_remove_from_cache(inode, bh); ocfs2_remove_from_cache(INODE_CACHE(inode), bh);
continue; continue;
} }
@ -2572,7 +2573,7 @@ static void ocfs2_unlink_path(struct inode *inode, handle_t *handle,
if (ret) if (ret)
mlog_errno(ret); mlog_errno(ret);
ocfs2_remove_from_cache(inode, bh); ocfs2_remove_from_cache(INODE_CACHE(inode), bh);
} }
} }
@ -6010,7 +6011,7 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
tl->tl_used = 0; tl->tl_used = 0;
ocfs2_compute_meta_ecc(osb->sb, tl_bh->b_data, &di->i_check); ocfs2_compute_meta_ecc(osb->sb, tl_bh->b_data, &di->i_check);
status = ocfs2_write_block(osb, tl_bh, tl_inode); status = ocfs2_write_block(osb, tl_bh, INODE_CACHE(tl_inode));
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
@ -6719,7 +6720,7 @@ delete:
mlog(0, "deleting this extent block.\n"); mlog(0, "deleting this extent block.\n");
ocfs2_remove_from_cache(inode, bh); ocfs2_remove_from_cache(INODE_CACHE(inode), bh);
BUG_ON(ocfs2_rec_clusters(el, &el->l_recs[0])); BUG_ON(ocfs2_rec_clusters(el, &el->l_recs[0]));
BUG_ON(le32_to_cpu(el->l_recs[0].e_cpos)); BUG_ON(le32_to_cpu(el->l_recs[0].e_cpos));

View file

@ -52,12 +52,12 @@ enum ocfs2_state_bits {
BUFFER_FNS(NeedsValidate, needs_validate); BUFFER_FNS(NeedsValidate, needs_validate);
int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
struct inode *inode) struct ocfs2_caching_info *ci)
{ {
int ret = 0; int ret = 0;
mlog_entry("(bh->b_blocknr = %llu, inode=%p)\n", mlog_entry("(bh->b_blocknr = %llu, ci=%p)\n",
(unsigned long long)bh->b_blocknr, inode); (unsigned long long)bh->b_blocknr, ci);
BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO); BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
BUG_ON(buffer_jbd(bh)); BUG_ON(buffer_jbd(bh));
@ -70,7 +70,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
goto out; goto out;
} }
mutex_lock(&OCFS2_I(inode)->ip_io_mutex); ocfs2_metadata_cache_io_lock(ci);
lock_buffer(bh); lock_buffer(bh);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
@ -85,7 +85,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
wait_on_buffer(bh); wait_on_buffer(bh);
if (buffer_uptodate(bh)) { if (buffer_uptodate(bh)) {
ocfs2_set_buffer_uptodate(inode, bh); ocfs2_set_buffer_uptodate(ci, bh);
} else { } else {
/* We don't need to remove the clustered uptodate /* We don't need to remove the clustered uptodate
* information for this bh as it's not marked locally * information for this bh as it's not marked locally
@ -94,7 +94,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
put_bh(bh); put_bh(bh);
} }
mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); ocfs2_metadata_cache_io_unlock(ci);
out: out:
mlog_exit(ret); mlog_exit(ret);
return ret; return ret;
@ -177,7 +177,7 @@ bail:
return status; return status;
} }
int ocfs2_read_blocks(struct inode *inode, u64 block, int nr, int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
struct buffer_head *bhs[], int flags, struct buffer_head *bhs[], int flags,
int (*validate)(struct super_block *sb, int (*validate)(struct super_block *sb,
struct buffer_head *bh)) struct buffer_head *bh))
@ -185,11 +185,12 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
int status = 0; int status = 0;
int i, ignore_cache = 0; int i, ignore_cache = 0;
struct buffer_head *bh; struct buffer_head *bh;
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
mlog_entry("(inode=%p, block=(%llu), nr=(%d), flags=%d)\n", mlog_entry("(ci=%p, block=(%llu), nr=(%d), flags=%d)\n",
inode, (unsigned long long)block, nr, flags); ci, (unsigned long long)block, nr, flags);
BUG_ON(!inode); BUG_ON(!ci);
BUG_ON((flags & OCFS2_BH_READAHEAD) && BUG_ON((flags & OCFS2_BH_READAHEAD) &&
(flags & OCFS2_BH_IGNORE_CACHE)); (flags & OCFS2_BH_IGNORE_CACHE));
@ -212,12 +213,12 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
goto bail; goto bail;
} }
mutex_lock(&OCFS2_I(inode)->ip_io_mutex); ocfs2_metadata_cache_io_lock(ci);
for (i = 0 ; i < nr ; i++) { for (i = 0 ; i < nr ; i++) {
if (bhs[i] == NULL) { if (bhs[i] == NULL) {
bhs[i] = sb_getblk(inode->i_sb, block++); bhs[i] = sb_getblk(sb, block++);
if (bhs[i] == NULL) { if (bhs[i] == NULL) {
mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); ocfs2_metadata_cache_io_unlock(ci);
status = -EIO; status = -EIO;
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
@ -250,11 +251,11 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
* before our is-it-in-flight check. * before our is-it-in-flight check.
*/ */
if (!ignore_cache && !ocfs2_buffer_uptodate(inode, bh)) { if (!ignore_cache && !ocfs2_buffer_uptodate(ci, bh)) {
mlog(ML_UPTODATE, mlog(ML_UPTODATE,
"bh (%llu), inode %llu not uptodate\n", "bh (%llu), owner %llu not uptodate\n",
(unsigned long long)bh->b_blocknr, (unsigned long long)bh->b_blocknr,
(unsigned long long)OCFS2_I(inode)->ip_blkno); (unsigned long long)ocfs2_metadata_cache_owner(ci));
/* We're using ignore_cache here to say /* We're using ignore_cache here to say
* "go to disk" */ * "go to disk" */
ignore_cache = 1; ignore_cache = 1;
@ -283,7 +284,7 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
* previously submitted request than we are * previously submitted request than we are
* done here. */ * done here. */
if ((flags & OCFS2_BH_READAHEAD) if ((flags & OCFS2_BH_READAHEAD)
&& ocfs2_buffer_read_ahead(inode, bh)) && ocfs2_buffer_read_ahead(ci, bh))
continue; continue;
lock_buffer(bh); lock_buffer(bh);
@ -305,7 +306,7 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
* buffer lock. */ * buffer lock. */
if (!(flags & OCFS2_BH_IGNORE_CACHE) if (!(flags & OCFS2_BH_IGNORE_CACHE)
&& !(flags & OCFS2_BH_READAHEAD) && !(flags & OCFS2_BH_READAHEAD)
&& ocfs2_buffer_uptodate(inode, bh)) { && ocfs2_buffer_uptodate(ci, bh)) {
unlock_buffer(bh); unlock_buffer(bh);
continue; continue;
} }
@ -327,7 +328,7 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
if (!(flags & OCFS2_BH_READAHEAD)) { if (!(flags & OCFS2_BH_READAHEAD)) {
/* We know this can't have changed as we hold the /* We know this can't have changed as we hold the
* inode sem. Avoid doing any work on the bh if the * owner sem. Avoid doing any work on the bh if the
* journal has it. */ * journal has it. */
if (!buffer_jbd(bh)) if (!buffer_jbd(bh))
wait_on_buffer(bh); wait_on_buffer(bh);
@ -351,7 +352,7 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
* that better not have changed */ * that better not have changed */
BUG_ON(buffer_jbd(bh)); BUG_ON(buffer_jbd(bh));
clear_buffer_needs_validate(bh); clear_buffer_needs_validate(bh);
status = validate(inode->i_sb, bh); status = validate(sb, bh);
if (status) { if (status) {
put_bh(bh); put_bh(bh);
bhs[i] = NULL; bhs[i] = NULL;
@ -363,9 +364,9 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
/* Always set the buffer in the cache, even if it was /* Always set the buffer in the cache, even if it was
* a forced read, or read-ahead which hasn't yet * a forced read, or read-ahead which hasn't yet
* completed. */ * completed. */
ocfs2_set_buffer_uptodate(inode, bh); ocfs2_set_buffer_uptodate(ci, bh);
} }
mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); ocfs2_metadata_cache_io_unlock(ci);
mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n", mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n",
(unsigned long long)block, nr, (unsigned long long)block, nr,
@ -399,7 +400,7 @@ static void ocfs2_check_super_or_backup(struct super_block *sb,
/* /*
* Write super block and backups doesn't need to collaborate with journal, * Write super block and backups doesn't need to collaborate with journal,
* so we don't need to lock ip_io_mutex and inode doesn't need to bea passed * so we don't need to lock ip_io_mutex and ci doesn't need to bea passed
* into this function. * into this function.
*/ */
int ocfs2_write_super_or_backup(struct ocfs2_super *osb, int ocfs2_write_super_or_backup(struct ocfs2_super *osb,

View file

@ -33,7 +33,7 @@ void ocfs2_end_buffer_io_sync(struct buffer_head *bh,
int ocfs2_write_block(struct ocfs2_super *osb, int ocfs2_write_block(struct ocfs2_super *osb,
struct buffer_head *bh, struct buffer_head *bh,
struct inode *inode); struct ocfs2_caching_info *ci);
int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
unsigned int nr, struct buffer_head *bhs[]); unsigned int nr, struct buffer_head *bhs[]);
@ -44,7 +44,7 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
* be set even for a READAHEAD call, as it marks the buffer for later * be set even for a READAHEAD call, as it marks the buffer for later
* validation. * validation.
*/ */
int ocfs2_read_blocks(struct inode *inode, u64 block, int nr, int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
struct buffer_head *bhs[], int flags, struct buffer_head *bhs[], int flags,
int (*validate)(struct super_block *sb, int (*validate)(struct super_block *sb,
struct buffer_head *bh)); struct buffer_head *bh));
@ -55,7 +55,7 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
#define OCFS2_BH_IGNORE_CACHE 1 #define OCFS2_BH_IGNORE_CACHE 1
#define OCFS2_BH_READAHEAD 8 #define OCFS2_BH_READAHEAD 8
static inline int ocfs2_read_block(struct inode *inode, u64 off, static inline int ocfs2_read_block(struct ocfs2_caching_info *ci, u64 off,
struct buffer_head **bh, struct buffer_head **bh,
int (*validate)(struct super_block *sb, int (*validate)(struct super_block *sb,
struct buffer_head *bh)) struct buffer_head *bh))
@ -68,7 +68,7 @@ static inline int ocfs2_read_block(struct inode *inode, u64 off,
goto bail; goto bail;
} }
status = ocfs2_read_blocks(inode, off, 1, bh, 0, validate); status = ocfs2_read_blocks(ci, off, 1, bh, 0, validate);
bail: bail:
return status; return status;

View file

@ -564,7 +564,8 @@ static int ocfs2_read_dir_block_direct(struct inode *dir, u64 phys,
int ret; int ret;
struct buffer_head *tmp = *bh; struct buffer_head *tmp = *bh;
ret = ocfs2_read_block(dir, phys, &tmp, ocfs2_validate_dir_block); ret = ocfs2_read_block(INODE_CACHE(dir), phys, &tmp,
ocfs2_validate_dir_block);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
@ -622,7 +623,8 @@ static int ocfs2_read_dx_root(struct inode *dir, struct ocfs2_dinode *di,
u64 blkno = le64_to_cpu(di->i_dx_root); u64 blkno = le64_to_cpu(di->i_dx_root);
struct buffer_head *tmp = *dx_root_bh; struct buffer_head *tmp = *dx_root_bh;
ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_root); ret = ocfs2_read_block(INODE_CACHE(dir), blkno, &tmp,
ocfs2_validate_dx_root);
/* If ocfs2_read_block() got us a new bh, pass it up. */ /* If ocfs2_read_block() got us a new bh, pass it up. */
if (!ret && !*dx_root_bh) if (!ret && !*dx_root_bh)
@ -662,7 +664,8 @@ static int ocfs2_read_dx_leaf(struct inode *dir, u64 blkno,
int ret; int ret;
struct buffer_head *tmp = *dx_leaf_bh; struct buffer_head *tmp = *dx_leaf_bh;
ret = ocfs2_read_block(dir, blkno, &tmp, ocfs2_validate_dx_leaf); ret = ocfs2_read_block(INODE_CACHE(dir), blkno, &tmp,
ocfs2_validate_dx_leaf);
/* If ocfs2_read_block() got us a new bh, pass it up. */ /* If ocfs2_read_block() got us a new bh, pass it up. */
if (!ret && !*dx_leaf_bh) if (!ret && !*dx_leaf_bh)
@ -680,7 +683,7 @@ static int ocfs2_read_dx_leaves(struct inode *dir, u64 start, int num,
{ {
int ret; int ret;
ret = ocfs2_read_blocks(dir, start, num, dx_leaf_bhs, 0, ret = ocfs2_read_blocks(INODE_CACHE(dir), start, num, dx_leaf_bhs, 0,
ocfs2_validate_dx_leaf); ocfs2_validate_dx_leaf);
if (ret) if (ret)
mlog_errno(ret); mlog_errno(ret);
@ -2332,7 +2335,7 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
goto bail; goto bail;
} }
ocfs2_set_new_buffer_uptodate(inode, new_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
status = ocfs2_journal_access_db(handle, inode, new_bh, status = ocfs2_journal_access_db(handle, inode, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -2418,7 +2421,7 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
ocfs2_set_new_buffer_uptodate(dir, dx_root_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(dir), dx_root_bh);
ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh, ret = ocfs2_journal_access_dr(handle, dir, dx_root_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -2495,7 +2498,7 @@ static int ocfs2_dx_dir_format_cluster(struct ocfs2_super *osb,
} }
dx_leaves[i] = bh; dx_leaves[i] = bh;
ocfs2_set_new_buffer_uptodate(dir, bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(dir), bh);
ret = ocfs2_journal_access_dl(handle, dir, bh, ret = ocfs2_journal_access_dl(handle, dir, bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -3005,7 +3008,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
goto out_commit; goto out_commit;
} }
ocfs2_set_new_buffer_uptodate(dir, dirdata_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(dir), dirdata_bh);
ret = ocfs2_journal_access_db(handle, dir, dirdata_bh, ret = ocfs2_journal_access_db(handle, dir, dirdata_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -3387,7 +3390,7 @@ do_extend:
goto bail; goto bail;
} }
ocfs2_set_new_buffer_uptodate(dir, new_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(dir), new_bh);
status = ocfs2_journal_access_db(handle, dir, new_bh, status = ocfs2_journal_access_db(handle, dir, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -4565,7 +4568,7 @@ remove_index:
goto out; goto out;
} }
ocfs2_remove_from_cache(dir, dx_root_bh); ocfs2_remove_from_cache(INODE_CACHE(dir), dx_root_bh);
out: out:
ocfs2_schedule_truncate_log_flush(osb, 1); ocfs2_schedule_truncate_log_flush(osb, 1);
ocfs2_run_deallocs(osb, &dealloc); ocfs2_run_deallocs(osb, &dealloc);

View file

@ -2127,7 +2127,7 @@ static int ocfs2_inode_lock_update(struct inode *inode,
/* This will discard any caching information we might have had /* This will discard any caching information we might have had
* for the inode metadata. */ * for the inode metadata. */
ocfs2_metadata_cache_purge(inode); ocfs2_metadata_cache_purge(INODE_CACHE(inode));
ocfs2_extent_map_trunc(inode, 0); ocfs2_extent_map_trunc(inode, 0);

View file

@ -862,8 +862,8 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
BUG_ON(bhs[done + i]->b_blocknr != (p_block + i)); BUG_ON(bhs[done + i]->b_blocknr != (p_block + i));
} }
rc = ocfs2_read_blocks(inode, p_block, count, bhs + done, rc = ocfs2_read_blocks(INODE_CACHE(inode), p_block, count,
flags, validate); bhs + done, flags, validate);
if (rc) { if (rc) {
mlog_errno(rc); mlog_errno(rc);
break; break;

View file

@ -662,7 +662,7 @@ static int ocfs2_remove_inode(struct inode *inode,
goto bail_commit; goto bail_commit;
} }
ocfs2_remove_from_cache(inode, di_bh); ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh);
vfs_dq_free_inode(inode); vfs_dq_free_inode(inode);
status = ocfs2_free_dinode(handle, inode_alloc_inode, status = ocfs2_free_dinode(handle, inode_alloc_inode,
@ -1112,14 +1112,14 @@ void ocfs2_clear_inode(struct inode *inode)
ocfs2_lock_res_free(&oi->ip_inode_lockres); ocfs2_lock_res_free(&oi->ip_inode_lockres);
ocfs2_lock_res_free(&oi->ip_open_lockres); ocfs2_lock_res_free(&oi->ip_open_lockres);
ocfs2_metadata_cache_purge(inode); ocfs2_metadata_cache_purge(INODE_CACHE(inode));
mlog_bug_on_msg(oi->ip_metadata_cache.ci_num_cached, mlog_bug_on_msg(INODE_CACHE(inode)->ci_num_cached,
"Clear inode of %llu, inode has %u cache items\n", "Clear inode of %llu, inode has %u cache items\n",
(unsigned long long)oi->ip_blkno, oi->ip_metadata_cache.ci_num_cached); (unsigned long long)oi->ip_blkno,
INODE_CACHE(inode)->ci_num_cached);
mlog_bug_on_msg(!(oi->ip_metadata_cache.ci_flags & mlog_bug_on_msg(!(INODE_CACHE(inode)->ci_flags & OCFS2_CACHE_FL_INLINE),
OCFS2_CACHE_FL_INLINE),
"Clear inode of %llu, inode has a bad flag\n", "Clear inode of %llu, inode has a bad flag\n",
(unsigned long long)oi->ip_blkno); (unsigned long long)oi->ip_blkno);
@ -1381,8 +1381,8 @@ int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
int rc; int rc;
struct buffer_head *tmp = *bh; struct buffer_head *tmp = *bh;
rc = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, &tmp, rc = ocfs2_read_blocks(INODE_CACHE(inode), OCFS2_I(inode)->ip_blkno,
flags, ocfs2_validate_inode_block); 1, &tmp, flags, ocfs2_validate_inode_block);
/* If ocfs2_read_blocks() got us a new bh, pass it up. */ /* If ocfs2_read_blocks() got us a new bh, pass it up. */
if (!rc && !*bh) if (!rc && !*bh)
@ -1408,6 +1408,13 @@ static u64 ocfs2_inode_cache_owner(struct ocfs2_caching_info *ci)
return oi->ip_blkno; return oi->ip_blkno;
} }
static struct super_block *ocfs2_inode_cache_get_super(struct ocfs2_caching_info *ci)
{
struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
return oi->vfs_inode.i_sb;
}
static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci) static void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci)
{ {
struct ocfs2_inode_info *oi = cache_info_to_inode(ci); struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
@ -1438,6 +1445,7 @@ static void ocfs2_inode_cache_io_unlock(struct ocfs2_caching_info *ci)
const struct ocfs2_caching_operations ocfs2_inode_caching_ops = { const struct ocfs2_caching_operations ocfs2_inode_caching_ops = {
.co_owner = ocfs2_inode_cache_owner, .co_owner = ocfs2_inode_cache_owner,
.co_get_super = ocfs2_inode_cache_get_super,
.co_cache_lock = ocfs2_inode_cache_lock, .co_cache_lock = ocfs2_inode_cache_lock,
.co_cache_unlock = ocfs2_inode_cache_unlock, .co_cache_unlock = ocfs2_inode_cache_unlock,
.co_io_lock = ocfs2_inode_cache_io_lock, .co_io_lock = ocfs2_inode_cache_io_lock,

View file

@ -120,6 +120,11 @@ extern struct kmem_cache *ocfs2_inode_cache;
extern const struct address_space_operations ocfs2_aops; extern const struct address_space_operations ocfs2_aops;
extern const struct ocfs2_caching_operations ocfs2_inode_caching_ops; extern const struct ocfs2_caching_operations ocfs2_inode_caching_ops;
static inline struct ocfs2_caching_info *INODE_CACHE(struct inode *inode)
{
return &OCFS2_I(inode)->ip_metadata_cache;
}
void ocfs2_clear_inode(struct inode *inode); void ocfs2_clear_inode(struct inode *inode);
void ocfs2_delete_inode(struct inode *inode); void ocfs2_delete_inode(struct inode *inode);
void ocfs2_drop_inode(struct inode *inode); void ocfs2_drop_inode(struct inode *inode);

View file

@ -898,7 +898,7 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
ocfs2_bump_recovery_generation(fe); ocfs2_bump_recovery_generation(fe);
ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check); ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
status = ocfs2_write_block(osb, bh, journal->j_inode); status = ocfs2_write_block(osb, bh, INODE_CACHE(journal->j_inode));
if (status < 0) if (status < 0)
mlog_errno(status); mlog_errno(status);
@ -1642,7 +1642,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
ocfs2_get_recovery_generation(fe); ocfs2_get_recovery_generation(fe);
ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check); ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
status = ocfs2_write_block(osb, bh, inode); status = ocfs2_write_block(osb, bh, INODE_CACHE(inode));
if (status < 0) if (status < 0)
mlog_errno(status); mlog_errno(status);

View file

@ -392,7 +392,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
ocfs2_clear_local_alloc(alloc); ocfs2_clear_local_alloc(alloc);
ocfs2_compute_meta_ecc(osb->sb, alloc_bh->b_data, &alloc->i_check); ocfs2_compute_meta_ecc(osb->sb, alloc_bh->b_data, &alloc->i_check);
status = ocfs2_write_block(osb, alloc_bh, inode); status = ocfs2_write_block(osb, alloc_bh, INODE_CACHE(inode));
if (status < 0) if (status < 0)
mlog_errno(status); mlog_errno(status);

View file

@ -507,7 +507,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
mlog_errno(status); mlog_errno(status);
goto leave; goto leave;
} }
ocfs2_set_new_buffer_uptodate(inode, *new_fe_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), *new_fe_bh);
status = ocfs2_journal_access_di(handle, inode, *new_fe_bh, status = ocfs2_journal_access_di(handle, inode, *new_fe_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -1527,7 +1527,8 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
ocfs2_set_new_buffer_uptodate(inode, bhs[virtual]); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode),
bhs[virtual]);
status = ocfs2_journal_access(handle, inode, bhs[virtual], status = ocfs2_journal_access(handle, inode, bhs[virtual],
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);

View file

@ -253,7 +253,7 @@ ssize_t ocfs2_quota_write(struct super_block *sb, int type,
flush_dcache_page(bh->b_page); flush_dcache_page(bh->b_page);
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
unlock_buffer(bh); unlock_buffer(bh);
ocfs2_set_buffer_uptodate(gqinode, bh); ocfs2_set_buffer_uptodate(INODE_CACHE(gqinode), bh);
err = ocfs2_journal_access_dq(handle, gqinode, bh, ja_type); err = ocfs2_journal_access_dq(handle, gqinode, bh, ja_type);
if (err < 0) { if (err < 0) {
brelse(bh); brelse(bh);

View file

@ -993,7 +993,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
goto out_trans; goto out_trans;
} }
dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data; dchunk = (struct ocfs2_local_disk_chunk *)bh->b_data;
ocfs2_set_new_buffer_uptodate(lqinode, bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
status = ocfs2_journal_access_dq(handle, lqinode, bh, status = ocfs2_journal_access_dq(handle, lqinode, bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
if (status < 0) { if (status < 0) {
@ -1027,7 +1027,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
mlog_errno(status); mlog_errno(status);
goto out_trans; goto out_trans;
} }
ocfs2_set_new_buffer_uptodate(lqinode, dbh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), dbh);
status = ocfs2_journal_access_dq(handle, lqinode, dbh, status = ocfs2_journal_access_dq(handle, lqinode, dbh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
if (status < 0) { if (status < 0) {
@ -1131,7 +1131,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
mlog_errno(status); mlog_errno(status);
goto out; goto out;
} }
ocfs2_set_new_buffer_uptodate(lqinode, bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(lqinode), bh);
/* Local quota info, chunk header and the new block we initialize */ /* Local quota info, chunk header and the new block we initialize */
handle = ocfs2_start_trans(OCFS2_SB(sb), handle = ocfs2_start_trans(OCFS2_SB(sb),

View file

@ -514,7 +514,7 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
goto out_unlock; goto out_unlock;
} }
ocfs2_set_new_buffer_uptodate(inode, group_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), group_bh);
ret = ocfs2_verify_group_and_input(main_bm_inode, fe, input, group_bh); ret = ocfs2_verify_group_and_input(main_bm_inode, fe, input, group_bh);
if (ret) { if (ret) {

View file

@ -150,8 +150,8 @@ int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
* be !NULL. Thus, ocfs2_read_blocks() will ignore blocknr. If * be !NULL. Thus, ocfs2_read_blocks() will ignore blocknr. If
* this is not true, the read of -1 (UINT64_MAX) will fail. * this is not true, the read of -1 (UINT64_MAX) will fail.
*/ */
ret = ocfs2_read_blocks(si->si_inode, -1, si->si_blocks, si->si_bh, ret = ocfs2_read_blocks(INODE_CACHE(si->si_inode), -1, si->si_blocks,
OCFS2_BH_IGNORE_CACHE, NULL); si->si_bh, OCFS2_BH_IGNORE_CACHE, NULL);
if (ret == 0) { if (ret == 0) {
spin_lock(&osb->osb_lock); spin_lock(&osb->osb_lock);
ocfs2_update_slot_info(si); ocfs2_update_slot_info(si);
@ -213,7 +213,7 @@ static int ocfs2_update_disk_slot(struct ocfs2_super *osb,
ocfs2_update_disk_slot_old(si, slot_num, &bh); ocfs2_update_disk_slot_old(si, slot_num, &bh);
spin_unlock(&osb->osb_lock); spin_unlock(&osb->osb_lock);
status = ocfs2_write_block(osb, bh, si->si_inode); status = ocfs2_write_block(osb, bh, INODE_CACHE(si->si_inode));
if (status < 0) if (status < 0)
mlog_errno(status); mlog_errno(status);
@ -404,8 +404,8 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb,
(unsigned long long)blkno); (unsigned long long)blkno);
bh = NULL; /* Acquire a fresh bh */ bh = NULL; /* Acquire a fresh bh */
status = ocfs2_read_blocks(si->si_inode, blkno, 1, &bh, status = ocfs2_read_blocks(INODE_CACHE(si->si_inode), blkno,
OCFS2_BH_IGNORE_CACHE, NULL); 1, &bh, OCFS2_BH_IGNORE_CACHE, NULL);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;

View file

@ -310,7 +310,7 @@ int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
int rc; int rc;
struct buffer_head *tmp = *bh; struct buffer_head *tmp = *bh;
rc = ocfs2_read_block(inode, gd_blkno, &tmp, rc = ocfs2_read_block(INODE_CACHE(inode), gd_blkno, &tmp,
ocfs2_validate_group_descriptor); ocfs2_validate_group_descriptor);
if (rc) if (rc)
goto out; goto out;
@ -476,7 +476,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
ocfs2_set_new_buffer_uptodate(alloc_inode, bg_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(alloc_inode), bg_bh);
status = ocfs2_block_group_fill(handle, status = ocfs2_block_group_fill(handle,
alloc_inode, alloc_inode,

View file

@ -1683,7 +1683,7 @@ static void ocfs2_inode_init_once(void *data)
ocfs2_lock_res_init_once(&oi->ip_inode_lockres); ocfs2_lock_res_init_once(&oi->ip_inode_lockres);
ocfs2_lock_res_init_once(&oi->ip_open_lockres); ocfs2_lock_res_init_once(&oi->ip_open_lockres);
ocfs2_metadata_cache_init(&oi->ip_metadata_cache, ocfs2_metadata_cache_init(INODE_CACHE(&oi->vfs_inode),
&ocfs2_inode_caching_ops); &ocfs2_inode_caching_ops);
inode_init_once(&oi->vfs_inode); inode_init_once(&oi->vfs_inode);

View file

@ -75,13 +75,20 @@ struct ocfs2_meta_cache_item {
static struct kmem_cache *ocfs2_uptodate_cachep = NULL; static struct kmem_cache *ocfs2_uptodate_cachep = NULL;
static u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci) u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci)
{ {
BUG_ON(!ci || !ci->ci_ops); BUG_ON(!ci || !ci->ci_ops);
return ci->ci_ops->co_owner(ci); return ci->ci_ops->co_owner(ci);
} }
struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci)
{
BUG_ON(!ci || !ci->ci_ops);
return ci->ci_ops->co_get_super(ci);
}
static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci) static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci)
{ {
BUG_ON(!ci || !ci->ci_ops); BUG_ON(!ci || !ci->ci_ops);
@ -96,14 +103,14 @@ static void ocfs2_metadata_cache_unlock(struct ocfs2_caching_info *ci)
ci->ci_ops->co_cache_unlock(ci); ci->ci_ops->co_cache_unlock(ci);
} }
static void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci) void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci)
{ {
BUG_ON(!ci || !ci->ci_ops); BUG_ON(!ci || !ci->ci_ops);
ci->ci_ops->co_io_lock(ci); ci->ci_ops->co_io_lock(ci);
} }
static void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci) void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci)
{ {
BUG_ON(!ci || !ci->ci_ops); BUG_ON(!ci || !ci->ci_ops);
@ -149,11 +156,9 @@ static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
* This function is a few more lines longer than necessary due to some * This function is a few more lines longer than necessary due to some
* accounting done here, but I think it's worth tracking down those * accounting done here, but I think it's worth tracking down those
* bugs sooner -- Mark */ * bugs sooner -- Mark */
void ocfs2_metadata_cache_purge(struct inode *inode) void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
{ {
struct ocfs2_inode_info *oi = OCFS2_I(inode);
unsigned int tree, to_purge, purged; unsigned int tree, to_purge, purged;
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
struct rb_root root = RB_ROOT; struct rb_root root = RB_ROOT;
BUG_ON(!ci || !ci->ci_ops); BUG_ON(!ci || !ci->ci_ops);
@ -223,12 +228,11 @@ ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
return NULL; return NULL;
} }
static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi, static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
int index = -1; int index = -1;
struct ocfs2_meta_cache_item *item = NULL; struct ocfs2_meta_cache_item *item = NULL;
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
ocfs2_metadata_cache_lock(ci); ocfs2_metadata_cache_lock(ci);
@ -238,11 +242,9 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
!!(ci->ci_flags & OCFS2_CACHE_FL_INLINE)); !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
index = ocfs2_search_cache_array(&oi->ip_metadata_cache, index = ocfs2_search_cache_array(ci, bh->b_blocknr);
bh->b_blocknr);
else else
item = ocfs2_search_cache_tree(&oi->ip_metadata_cache, item = ocfs2_search_cache_tree(ci, bh->b_blocknr);
bh->b_blocknr);
ocfs2_metadata_cache_unlock(ci); ocfs2_metadata_cache_unlock(ci);
@ -256,7 +258,7 @@ static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
* *
* This can be called under lock_buffer() * This can be called under lock_buffer()
*/ */
int ocfs2_buffer_uptodate(struct inode *inode, int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
/* Doesn't matter if the bh is in our cache or not -- if it's /* Doesn't matter if the bh is in our cache or not -- if it's
@ -272,17 +274,17 @@ int ocfs2_buffer_uptodate(struct inode *inode,
/* Ok, locally the buffer is marked as up to date, now search /* Ok, locally the buffer is marked as up to date, now search
* our cache to see if we can trust that. */ * our cache to see if we can trust that. */
return ocfs2_buffer_cached(OCFS2_I(inode), bh); return ocfs2_buffer_cached(ci, bh);
} }
/* /*
* Determine whether a buffer is currently out on a read-ahead request. * Determine whether a buffer is currently out on a read-ahead request.
* ci_io_sem should be held to serialize submitters with the logic here. * ci_io_sem should be held to serialize submitters with the logic here.
*/ */
int ocfs2_buffer_read_ahead(struct inode *inode, int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
return buffer_locked(bh) && ocfs2_buffer_cached(OCFS2_I(inode), bh); return buffer_locked(bh) && ocfs2_buffer_cached(ci, bh);
} }
/* Requires ip_lock */ /* Requires ip_lock */
@ -335,8 +337,7 @@ static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
} }
/* co_cache_lock() must be held */ /* co_cache_lock() must be held */
static inline int ocfs2_insert_can_use_array(struct ocfs2_inode_info *oi, static inline int ocfs2_insert_can_use_array(struct ocfs2_caching_info *ci)
struct ocfs2_caching_info *ci)
{ {
return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) && return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) &&
(ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY); (ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY);
@ -347,11 +348,10 @@ static inline int ocfs2_insert_can_use_array(struct ocfs2_inode_info *oi,
* when to free in case of error. * when to free in case of error.
* *
* The co_cache_lock() must be held. */ * The co_cache_lock() must be held. */
static void ocfs2_expand_cache(struct ocfs2_inode_info *oi, static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
struct ocfs2_meta_cache_item **tree) struct ocfs2_meta_cache_item **tree)
{ {
int i; int i;
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY, mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY,
"Owner %llu, num cached = %u, should be %u\n", "Owner %llu, num cached = %u, should be %u\n",
@ -383,12 +383,11 @@ static void ocfs2_expand_cache(struct ocfs2_inode_info *oi,
/* Slow path function - memory allocation is necessary. See the /* Slow path function - memory allocation is necessary. See the
* comment above ocfs2_set_buffer_uptodate for more information. */ * comment above ocfs2_set_buffer_uptodate for more information. */
static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi, static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
sector_t block, sector_t block,
int expand_tree) int expand_tree)
{ {
int i; int i;
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
struct ocfs2_meta_cache_item *new = NULL; struct ocfs2_meta_cache_item *new = NULL;
struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] = struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
{ NULL, }; { NULL, };
@ -420,7 +419,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi,
} }
ocfs2_metadata_cache_lock(ci); ocfs2_metadata_cache_lock(ci);
if (ocfs2_insert_can_use_array(oi, ci)) { if (ocfs2_insert_can_use_array(ci)) {
mlog(0, "Someone cleared the tree underneath us\n"); mlog(0, "Someone cleared the tree underneath us\n");
/* Ok, items were removed from the cache in between /* Ok, items were removed from the cache in between
* locks. Detect this and revert back to the fast path */ * locks. Detect this and revert back to the fast path */
@ -430,7 +429,7 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi,
} }
if (expand_tree) if (expand_tree)
ocfs2_expand_cache(oi, tree); ocfs2_expand_cache(ci, tree);
__ocfs2_insert_cache_tree(ci, new); __ocfs2_insert_cache_tree(ci, new);
ocfs2_metadata_cache_unlock(ci); ocfs2_metadata_cache_unlock(ci);
@ -468,16 +467,14 @@ out_free:
* Readahead buffers can be passed in here before the I/O request is * Readahead buffers can be passed in here before the I/O request is
* completed. * completed.
*/ */
void ocfs2_set_buffer_uptodate(struct inode *inode, void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
int expand; int expand;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
/* The block may very well exist in our cache already, so avoid /* The block may very well exist in our cache already, so avoid
* doing any more work in that case. */ * doing any more work in that case. */
if (ocfs2_buffer_cached(oi, bh)) if (ocfs2_buffer_cached(ci, bh))
return; return;
mlog(0, "Owner %llu, inserting block %llu\n", mlog(0, "Owner %llu, inserting block %llu\n",
@ -487,7 +484,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
/* No need to recheck under spinlock - insertion is guarded by /* No need to recheck under spinlock - insertion is guarded by
* co_io_lock() */ * co_io_lock() */
ocfs2_metadata_cache_lock(ci); ocfs2_metadata_cache_lock(ci);
if (ocfs2_insert_can_use_array(oi, ci)) { if (ocfs2_insert_can_use_array(ci)) {
/* Fast case - it's an array and there's a free /* Fast case - it's an array and there's a free
* spot. */ * spot. */
ocfs2_append_cache_array(ci, bh->b_blocknr); ocfs2_append_cache_array(ci, bh->b_blocknr);
@ -502,25 +499,22 @@ void ocfs2_set_buffer_uptodate(struct inode *inode,
} }
ocfs2_metadata_cache_unlock(ci); ocfs2_metadata_cache_unlock(ci);
__ocfs2_set_buffer_uptodate(oi, bh->b_blocknr, expand); __ocfs2_set_buffer_uptodate(ci, bh->b_blocknr, expand);
} }
/* Called against a newly allocated buffer. Most likely nobody should /* Called against a newly allocated buffer. Most likely nobody should
* be able to read this sort of metadata while it's still being * be able to read this sort of metadata while it's still being
* allocated, but this is careful to take co_io_lock() anyway. */ * allocated, but this is careful to take co_io_lock() anyway. */
void ocfs2_set_new_buffer_uptodate(struct inode *inode, void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
/* This should definitely *not* exist in our cache */ /* This should definitely *not* exist in our cache */
BUG_ON(ocfs2_buffer_cached(oi, bh)); BUG_ON(ocfs2_buffer_cached(ci, bh));
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
ocfs2_metadata_cache_io_lock(ci); ocfs2_metadata_cache_io_lock(ci);
ocfs2_set_buffer_uptodate(inode, bh); ocfs2_set_buffer_uptodate(ci, bh);
ocfs2_metadata_cache_io_unlock(ci); ocfs2_metadata_cache_io_unlock(ci);
} }
@ -559,13 +553,11 @@ static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
ci->ci_num_cached--; ci->ci_num_cached--;
} }
static void ocfs2_remove_block_from_cache(struct inode *inode, static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
sector_t block) sector_t block)
{ {
int index; int index;
struct ocfs2_meta_cache_item *item = NULL; struct ocfs2_meta_cache_item *item = NULL;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
ocfs2_metadata_cache_lock(ci); ocfs2_metadata_cache_lock(ci);
mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n", mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n",
@ -593,23 +585,24 @@ static void ocfs2_remove_block_from_cache(struct inode *inode,
* bother reverting things to an inlined array in the case of a remove * bother reverting things to an inlined array in the case of a remove
* which moves us back under the limit. * which moves us back under the limit.
*/ */
void ocfs2_remove_from_cache(struct inode *inode, void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
struct buffer_head *bh) struct buffer_head *bh)
{ {
sector_t block = bh->b_blocknr; sector_t block = bh->b_blocknr;
ocfs2_remove_block_from_cache(inode, block); ocfs2_remove_block_from_cache(ci, block);
} }
/* Called when we remove xattr clusters from an inode. */ /* Called when we remove xattr clusters from an inode. */
void ocfs2_remove_xattr_clusters_from_cache(struct inode *inode, void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
sector_t block, sector_t block,
u32 c_len) u32 c_len)
{ {
unsigned int i, b_len = ocfs2_clusters_to_blocks(inode->i_sb, 1) * c_len; struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
unsigned int i, b_len = ocfs2_clusters_to_blocks(sb, 1) * c_len;
for (i = 0; i < b_len; i++, block++) for (i = 0; i < b_len; i++, block++)
ocfs2_remove_block_from_cache(inode, block); ocfs2_remove_block_from_cache(ci, block);
} }
int __init init_ocfs2_uptodate_cache(void) int __init init_ocfs2_uptodate_cache(void)

View file

@ -38,6 +38,8 @@ struct ocfs2_caching_operations {
*/ */
u64 (*co_owner)(struct ocfs2_caching_info *ci); u64 (*co_owner)(struct ocfs2_caching_info *ci);
/* The superblock is needed during I/O. */
struct super_block *(*co_get_super)(struct ocfs2_caching_info *ci);
/* /*
* Lock and unlock the caching data. These will not sleep, and * Lock and unlock the caching data. These will not sleep, and
* should probably be spinlocks. * should probably be spinlocks.
@ -58,20 +60,25 @@ void exit_ocfs2_uptodate_cache(void);
void ocfs2_metadata_cache_init(struct ocfs2_caching_info *ci, void ocfs2_metadata_cache_init(struct ocfs2_caching_info *ci,
const struct ocfs2_caching_operations *ops); const struct ocfs2_caching_operations *ops);
void ocfs2_metadata_cache_purge(struct inode *inode); void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci);
int ocfs2_buffer_uptodate(struct inode *inode, u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci);
struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci);
void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci);
void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci);
int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh); struct buffer_head *bh);
void ocfs2_set_buffer_uptodate(struct inode *inode, void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh); struct buffer_head *bh);
void ocfs2_set_new_buffer_uptodate(struct inode *inode, void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
struct buffer_head *bh); struct buffer_head *bh);
void ocfs2_remove_from_cache(struct inode *inode, void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
struct buffer_head *bh); struct buffer_head *bh);
void ocfs2_remove_xattr_clusters_from_cache(struct inode *inode, void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
sector_t block, sector_t block,
u32 c_len); u32 c_len);
int ocfs2_buffer_read_ahead(struct inode *inode, int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
struct buffer_head *bh); struct buffer_head *bh);
#endif /* OCFS2_UPTODATE_H */ #endif /* OCFS2_UPTODATE_H */

View file

@ -254,9 +254,9 @@ static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
break; break;
} }
if (!ocfs2_buffer_uptodate(bucket->bu_inode, if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode),
bucket->bu_bhs[i])) bucket->bu_bhs[i]))
ocfs2_set_new_buffer_uptodate(bucket->bu_inode, ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode),
bucket->bu_bhs[i]); bucket->bu_bhs[i]);
} }
@ -271,7 +271,7 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
{ {
int rc; int rc;
rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno, rc = ocfs2_read_blocks(INODE_CACHE(bucket->bu_inode), xb_blkno,
bucket->bu_blocks, bucket->bu_bhs, 0, bucket->bu_blocks, bucket->bu_bhs, 0,
NULL); NULL);
if (!rc) { if (!rc) {
@ -399,7 +399,7 @@ static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno,
int rc; int rc;
struct buffer_head *tmp = *bh; struct buffer_head *tmp = *bh;
rc = ocfs2_read_block(inode, xb_blkno, &tmp, rc = ocfs2_read_block(INODE_CACHE(inode), xb_blkno, &tmp,
ocfs2_validate_xattr_block); ocfs2_validate_xattr_block);
/* If ocfs2_read_block() got us a new bh, pass it up. */ /* If ocfs2_read_block() got us a new bh, pass it up. */
@ -724,8 +724,8 @@ static int ocfs2_xattr_shrink_size(struct inode *inode,
} }
block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
ocfs2_remove_xattr_clusters_from_cache(inode, block, ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode),
alloc_size); block, alloc_size);
cpos += alloc_size; cpos += alloc_size;
trunc_len -= alloc_size; trunc_len -= alloc_size;
} }
@ -970,7 +970,8 @@ static int ocfs2_xattr_get_value_outside(struct inode *inode,
blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
/* Copy ocfs2_xattr_value */ /* Copy ocfs2_xattr_value */
for (i = 0; i < num_clusters * bpc; i++, blkno++) { for (i = 0; i < num_clusters * bpc; i++, blkno++) {
ret = ocfs2_read_block(inode, blkno, &bh, NULL); ret = ocfs2_read_block(INODE_CACHE(inode), blkno,
&bh, NULL);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
@ -1208,7 +1209,8 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
for (i = 0; i < num_clusters * bpc; i++, blkno++) { for (i = 0; i < num_clusters * bpc; i++, blkno++) {
ret = ocfs2_read_block(inode, blkno, &bh, NULL); ret = ocfs2_read_block(INODE_CACHE(inode), blkno,
&bh, NULL);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
@ -2121,7 +2123,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
} }
new_bh = sb_getblk(inode->i_sb, first_blkno); new_bh = sb_getblk(inode->i_sb, first_blkno);
ocfs2_set_new_buffer_uptodate(inode, new_bh); ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
ret = ocfs2_journal_access_xb(handle, inode, new_bh, ret = ocfs2_journal_access_xb(handle, inode, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE); OCFS2_JOURNAL_ACCESS_CREATE);
@ -4845,7 +4847,8 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n", mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n",
cpos, len, (unsigned long long)blkno); cpos, len, (unsigned long long)blkno);
ocfs2_remove_xattr_clusters_from_cache(inode, blkno, len); ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), blkno,
len);
ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac); ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac);
if (ret) { if (ret) {