From cf2bc809403ae48a4a2bb5cc551d2ec35f2e4a47 Mon Sep 17 00:00:00 2001 From: Joel Becker Date: Tue, 18 Aug 2009 13:52:38 -0700 Subject: ocfs2: Teach ocfs2_xa_loc how to do its own journal work We're going to want to make sure our buffers get accessed and dirtied correctly. So have the xa_loc do the work. This includes storing the inode on ocfs2_xa_loc. Signed-off-by: Joel Becker --- fs/ocfs2/xattr.c | 115 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 29 deletions(-) (limited to 'fs/ocfs2/xattr.c') diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e0d0fa2..fbec116 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -142,6 +142,13 @@ struct ocfs2_xattr_search { struct ocfs2_xa_loc; struct ocfs2_xa_loc_operations { /* + * Journal functions + */ + int (*xlo_journal_access)(handle_t *handle, struct ocfs2_xa_loc *loc, + int type); + void (*xlo_journal_dirty)(handle_t *handle, struct ocfs2_xa_loc *loc); + + /* * Return a pointer to the appropriate buffer in loc->xl_storage * at the given offset from loc->xl_header. */ @@ -186,6 +193,9 @@ struct ocfs2_xa_loc_operations { * tracking the on-disk structure. */ struct ocfs2_xa_loc { + /* This xattr belongs to this inode */ + struct inode *xl_inode; + /* The ocfs2_xattr_header inside the on-disk storage. Not NULL. */ struct ocfs2_xattr_header *xl_header; @@ -1540,6 +1550,17 @@ static int ocfs2_xa_check_space_helper(int needed_space, int free_start, return 0; } +static int ocfs2_xa_journal_access(handle_t *handle, struct ocfs2_xa_loc *loc, + int type) +{ + return loc->xl_ops->xlo_journal_access(handle, loc, type); +} + +static void ocfs2_xa_journal_dirty(handle_t *handle, struct ocfs2_xa_loc *loc) +{ + loc->xl_ops->xlo_journal_dirty(handle, loc); +} + /* Give a pointer into the storage for the given offset */ static void *ocfs2_xa_offset_pointer(struct ocfs2_xa_loc *loc, int offset) { @@ -1629,6 +1650,29 @@ static void ocfs2_xa_fill_value_buf(struct ocfs2_xa_loc *loc, name_size); } +static int ocfs2_xa_block_journal_access(handle_t *handle, + struct ocfs2_xa_loc *loc, int type) +{ + struct buffer_head *bh = loc->xl_storage; + ocfs2_journal_access_func access; + + if (loc->xl_size == (bh->b_size - + offsetof(struct ocfs2_xattr_block, + xb_attrs.xb_header))) + access = ocfs2_journal_access_xb; + else + access = ocfs2_journal_access_di; + return access(handle, INODE_CACHE(loc->xl_inode), bh, type); +} + +static void ocfs2_xa_block_journal_dirty(handle_t *handle, + struct ocfs2_xa_loc *loc) +{ + struct buffer_head *bh = loc->xl_storage; + + ocfs2_journal_dirty(handle, bh); +} + static void *ocfs2_xa_block_offset_pointer(struct ocfs2_xa_loc *loc, int offset) { @@ -1755,6 +1799,8 @@ static void ocfs2_xa_block_fill_value_buf(struct ocfs2_xa_loc *loc, * storage and unindexed ocfs2_xattr_blocks. */ static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = { + .xlo_journal_access = ocfs2_xa_block_journal_access, + .xlo_journal_dirty = ocfs2_xa_block_journal_dirty, .xlo_offset_pointer = ocfs2_xa_block_offset_pointer, .xlo_check_space = ocfs2_xa_block_check_space, .xlo_can_reuse = ocfs2_xa_block_can_reuse, @@ -1765,6 +1811,22 @@ static const struct ocfs2_xa_loc_operations ocfs2_xa_block_loc_ops = { .xlo_fill_value_buf = ocfs2_xa_block_fill_value_buf, }; +static int ocfs2_xa_bucket_journal_access(handle_t *handle, + struct ocfs2_xa_loc *loc, int type) +{ + struct ocfs2_xattr_bucket *bucket = loc->xl_storage; + + return ocfs2_xattr_bucket_journal_access(handle, bucket, type); +} + +static void ocfs2_xa_bucket_journal_dirty(handle_t *handle, + struct ocfs2_xa_loc *loc) +{ + struct ocfs2_xattr_bucket *bucket = loc->xl_storage; + + ocfs2_xattr_bucket_journal_dirty(handle, bucket); +} + static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc, int offset) { @@ -1772,8 +1834,8 @@ static void *ocfs2_xa_bucket_offset_pointer(struct ocfs2_xa_loc *loc, int block, block_offset; /* The header is at the front of the bucket */ - block = offset >> bucket->bu_inode->i_sb->s_blocksize_bits; - block_offset = offset % bucket->bu_inode->i_sb->s_blocksize; + block = offset >> loc->xl_inode->i_sb->s_blocksize_bits; + block_offset = offset % loc->xl_inode->i_sb->s_blocksize; return bucket_block(bucket, block) + block_offset; } @@ -1813,8 +1875,7 @@ static int ocfs2_xa_bucket_check_space(struct ocfs2_xa_loc *loc, int free_start = ocfs2_xa_get_free_start(loc); int needed_space = ocfs2_xi_entry_usage(xi); int size = namevalue_size_xi(xi); - struct ocfs2_xattr_bucket *bucket = loc->xl_storage; - struct super_block *sb = bucket->bu_inode->i_sb; + struct super_block *sb = loc->xl_inode->i_sb; /* * Bucket storage does not reclaim name+value pairs it cannot @@ -1896,8 +1957,7 @@ static void ocfs2_xa_bucket_add_namevalue(struct ocfs2_xa_loc *loc, int size) { int free_start = ocfs2_xa_get_free_start(loc); struct ocfs2_xattr_header *xh = loc->xl_header; - struct ocfs2_xattr_bucket *bucket = loc->xl_storage; - struct super_block *sb = bucket->bu_inode->i_sb; + struct super_block *sb = loc->xl_inode->i_sb; int nameval_offset; free_start = ocfs2_bucket_align_free_start(sb, free_start, size); @@ -1912,7 +1972,7 @@ static void ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc *loc, struct ocfs2_xattr_value_buf *vb) { struct ocfs2_xattr_bucket *bucket = loc->xl_storage; - struct super_block *sb = bucket->bu_inode->i_sb; + struct super_block *sb = loc->xl_inode->i_sb; int nameval_offset = le16_to_cpu(loc->xl_entry->xe_name_offset); int size = namevalue_size_xe(loc->xl_entry); int block_offset = nameval_offset >> sb->s_blocksize_bits; @@ -1929,6 +1989,8 @@ static void ocfs2_xa_bucket_fill_value_buf(struct ocfs2_xa_loc *loc, /* Operations for xattrs stored in buckets. */ static const struct ocfs2_xa_loc_operations ocfs2_xa_bucket_loc_ops = { + .xlo_journal_access = ocfs2_xa_bucket_journal_access, + .xlo_journal_dirty = ocfs2_xa_bucket_journal_dirty, .xlo_offset_pointer = ocfs2_xa_bucket_offset_pointer, .xlo_check_space = ocfs2_xa_bucket_check_space, .xlo_can_reuse = ocfs2_xa_bucket_can_reuse, @@ -2049,6 +2111,7 @@ static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc, { struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; + loc->xl_inode = inode; loc->xl_ops = &ocfs2_xa_block_loc_ops; loc->xl_storage = bh; loc->xl_entry = entry; @@ -2065,6 +2128,7 @@ static void ocfs2_init_dinode_xa_loc(struct ocfs2_xa_loc *loc, } static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc, + struct inode *inode, struct buffer_head *bh, struct ocfs2_xattr_entry *entry) { @@ -2073,6 +2137,7 @@ static void ocfs2_init_xattr_block_xa_loc(struct ocfs2_xa_loc *loc, BUG_ON(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED); + loc->xl_inode = inode; loc->xl_ops = &ocfs2_xa_block_loc_ops; loc->xl_storage = bh; loc->xl_header = &(xb->xb_attrs.xb_header); @@ -2085,6 +2150,7 @@ static void ocfs2_init_xattr_bucket_xa_loc(struct ocfs2_xa_loc *loc, struct ocfs2_xattr_bucket *bucket, struct ocfs2_xattr_entry *entry) { + loc->xl_inode = bucket->bu_inode; loc->xl_ops = &ocfs2_xa_bucket_loc_ops; loc->xl_storage = bucket; loc->xl_header = bucket_xh(bucket); @@ -2226,21 +2292,18 @@ static int ocfs2_xattr_set_entry(struct inode *inode, goto out; } - if (!(flag & OCFS2_INLINE_XATTR_FL)) { - ret = vb.vb_access(handle, INODE_CACHE(inode), vb.vb_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto out; - } - } - if (xs->xattr_bh == xs->inode_bh) ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh, xs->not_found ? NULL : xs->here); else - ocfs2_init_xattr_block_xa_loc(&loc, xs->xattr_bh, + ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh, xs->not_found ? NULL : xs->here); + ret = ocfs2_xa_journal_access(handle, &loc, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + mlog_errno(ret); + goto out; + } /* * Prepare our entry and insert the inline value. This will @@ -2258,13 +2321,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, ocfs2_xa_store_inline_value(&loc, xi); xs->here = loc.xl_entry; - if (!(flag & OCFS2_INLINE_XATTR_FL)) { - ret = ocfs2_journal_dirty(handle, xs->xattr_bh); - if (ret < 0) { - mlog_errno(ret); - goto out; - } - } + ocfs2_xa_journal_dirty(handle, &loc); if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) && (flag & OCFS2_INLINE_XATTR_FL)) { @@ -5325,15 +5382,15 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, } } - ret = ocfs2_xattr_bucket_journal_access(handle, xs->bucket, - OCFS2_JOURNAL_ACCESS_WRITE); + ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket, + xs->not_found ? NULL : xs->here); + ret = ocfs2_xa_journal_access(handle, &loc, + OCFS2_JOURNAL_ACCESS_WRITE); if (ret < 0) { mlog_errno(ret); goto out; } - ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket, - xs->not_found ? NULL : xs->here); ret = ocfs2_xa_prepare_entry(&loc, xi, name_hash); if (ret) { if (ret != -ENOSPC) @@ -5345,7 +5402,7 @@ static int ocfs2_xattr_set_entry_in_bucket(struct inode *inode, ocfs2_xa_store_inline_value(&loc, xi); xs->here = loc.xl_entry; - ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket); + ocfs2_xa_journal_dirty(handle, &loc); out: return ret; -- cgit v1.1