Skip to content

Commit

Permalink
ocfs2: Use metadata-specific ocfs2_journal_access_*() functions.
Browse files Browse the repository at this point in the history
The per-metadata-type ocfs2_journal_access_*() functions hook up jbd2
commit triggers and allow us to compute metadata ecc right before the
buffers are written out.  This commit provides ecc for inodes, extent
blocks, group descriptors, and quota blocks.  It is not safe to use
extened attributes and metaecc at the same time yet.

The ocfs2_extent_tree and ocfs2_path abstractions in alloc.c both hide
the type of block at their root.  Before, it didn't matter, but now the
root block must use the appropriate ocfs2_journal_access_*() function.
To keep this abstract, the structures now have a pointer to the matching
journal_access function and a wrapper call to call it.

A few places use naked ocfs2_write_block() calls instead of adding the
blocks to the journal.  We make sure to calculate their checksum and ecc
before the write.

Since we pass around the journal_access functions.  Let's typedef them
in ocfs2.h.

Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
  • Loading branch information
Joel Becker authored and Mark Fasheh committed Jan 5, 2009
1 parent ffdd7a5 commit 13723d0
Show file tree
Hide file tree
Showing 15 changed files with 280 additions and 206 deletions.
233 changes: 137 additions & 96 deletions fs/ocfs2/alloc.c

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion fs/ocfs2/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
*
* ocfs2_extent_tree contains info for the root of the b-tree, it must have a
* root ocfs2_extent_list and a root_bh so that they can be used in the b-tree
* functions.
* functions. With metadata ecc, we now call different journal_access
* functions for each type of metadata, so it must have the
* root_journal_access function.
* ocfs2_extent_tree_operations abstract the normal operations we do for
* the root of extent b-tree.
*/
Expand All @@ -54,6 +56,7 @@ struct ocfs2_extent_tree {
struct ocfs2_extent_tree_operations *et_ops;
struct buffer_head *et_root_bh;
struct ocfs2_extent_list *et_root_el;
ocfs2_journal_access_func et_root_journal_access;
void *et_object;
unsigned int et_max_leaf_clusters;
};
Expand Down
8 changes: 4 additions & 4 deletions fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1512,8 +1512,8 @@ static int ocfs2_write_begin_inline(struct address_space *mapping,
goto out;
}

ret = ocfs2_journal_access(handle, inode, wc->w_di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
ret = ocfs2_journal_access_di(handle, inode, wc->w_di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) {
ocfs2_commit_trans(osb, handle);

Expand Down Expand Up @@ -1740,8 +1740,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
* We don't want this to fail in ocfs2_write_end(), so do it
* here.
*/
ret = ocfs2_journal_access(handle, inode, wc->w_di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
ret = ocfs2_journal_access_di(handle, inode, wc->w_di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) {
mlog_errno(ret);
goto out_quota;
Expand Down
48 changes: 31 additions & 17 deletions fs/ocfs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,14 +378,18 @@ int ocfs2_update_entry(struct inode *dir, handle_t *handle,
struct inode *new_entry_inode)
{
int ret;
ocfs2_journal_access_func access = ocfs2_journal_access_db;

/*
* The same code works fine for both inline-data and extent
* based directories, so no need to split this up.
* based directories, so no need to split this up. The only
* difference is the journal_access function.
*/

ret = ocfs2_journal_access(handle, dir, de_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
access = ocfs2_journal_access_di;

ret = access(handle, dir, de_bh, OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) {
mlog_errno(ret);
goto out;
Expand All @@ -407,9 +411,13 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
{
struct ocfs2_dir_entry *de, *pde;
int i, status = -ENOENT;
ocfs2_journal_access_func access = ocfs2_journal_access_db;

mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);

if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
access = ocfs2_journal_access_di;

i = 0;
pde = NULL;
de = (struct ocfs2_dir_entry *) first_de;
Expand All @@ -420,8 +428,8 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
goto bail;
}
if (de == de_del) {
status = ocfs2_journal_access(handle, dir, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = access(handle, dir, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
status = -EIO;
mlog_errno(status);
Expand Down Expand Up @@ -581,8 +589,14 @@ int __ocfs2_add_entry(handle_t *handle,
goto bail;
}

status = ocfs2_journal_access(handle, dir, insert_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (insert_bh == parent_fe_bh)
status = ocfs2_journal_access_di(handle, dir,
insert_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
else
status = ocfs2_journal_access_db(handle, dir,
insert_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
/* By now the buffer is marked for journaling */
offset += le16_to_cpu(de->rec_len);
if (le64_to_cpu(de->inode)) {
Expand Down Expand Up @@ -1081,8 +1095,8 @@ static int ocfs2_fill_new_dir_id(struct ocfs2_super *osb,
struct ocfs2_inline_data *data = &di->id2.i_data;
unsigned int size = le16_to_cpu(data->id_count);

ret = ocfs2_journal_access(handle, inode, di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
ret = ocfs2_journal_access_di(handle, inode, di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) {
mlog_errno(ret);
goto out;
Expand Down Expand Up @@ -1129,8 +1143,8 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,

ocfs2_set_new_buffer_uptodate(inode, new_bh);

status = ocfs2_journal_access(handle, inode, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
status = ocfs2_journal_access_db(handle, inode, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
if (status < 0) {
mlog_errno(status);
goto bail;
Expand Down Expand Up @@ -1292,8 +1306,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,

ocfs2_set_new_buffer_uptodate(dir, dirdata_bh);

ret = ocfs2_journal_access(handle, dir, dirdata_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
ret = ocfs2_journal_access_db(handle, dir, dirdata_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
if (ret) {
mlog_errno(ret);
goto out_commit;
Expand All @@ -1319,8 +1333,8 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
* We let the later dirent insert modify c/mtime - to the user
* the data hasn't changed.
*/
ret = ocfs2_journal_access(handle, dir, di_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
ret = ocfs2_journal_access_di(handle, dir, di_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
if (ret) {
mlog_errno(ret);
goto out_commit;
Expand Down Expand Up @@ -1583,8 +1597,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,

ocfs2_set_new_buffer_uptodate(dir, new_bh);

status = ocfs2_journal_access(handle, dir, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
status = ocfs2_journal_access_db(handle, dir, new_bh,
OCFS2_JOURNAL_ACCESS_CREATE);
if (status < 0) {
mlog_errno(status);
goto bail;
Expand Down
16 changes: 8 additions & 8 deletions fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ int ocfs2_update_inode_atime(struct inode *inode,
goto out;
}

ret = ocfs2_journal_access(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
ret = ocfs2_journal_access_di(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret) {
mlog_errno(ret);
goto out_commit;
Expand Down Expand Up @@ -353,8 +353,8 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
goto out;
}

status = ocfs2_journal_access(handle, inode, fe_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, inode, fe_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto out_commit;
Expand Down Expand Up @@ -590,8 +590,8 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
/* reserve a write to the file entry early on - that we if we
* run out of credits in the allocation path, we can still
* update i_size. */
status = ocfs2_journal_access(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto leave;
Expand Down Expand Up @@ -1121,8 +1121,8 @@ static int __ocfs2_write_remove_suid(struct inode *inode,
goto out;
}

ret = ocfs2_journal_access(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
ret = ocfs2_journal_access_di(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret < 0) {
mlog_errno(ret);
goto out_trans;
Expand Down
17 changes: 10 additions & 7 deletions fs/ocfs2/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,8 +537,8 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
goto out;
}

status = ocfs2_journal_access(handle, inode, fe_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, inode, fe_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto out;
Expand Down Expand Up @@ -621,8 +621,8 @@ static int ocfs2_remove_inode(struct inode *inode,
}

/* set the inodes dtime */
status = ocfs2_journal_access(handle, inode, di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, inode, di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto bail_commit;
Expand Down Expand Up @@ -1190,8 +1190,8 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
mlog_entry("(inode %llu)\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno);

status = ocfs2_journal_access(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto leave;
Expand Down Expand Up @@ -1277,8 +1277,11 @@ int ocfs2_validate_inode_block(struct super_block *sb,
* local to this block.
*/
rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check);
if (rc)
if (rc) {
mlog(ML_ERROR, "Checksum failed for dinode %llu\n",
(unsigned long long)bh->b_blocknr);
goto bail;
}

/*
* Errors after here are fatal.
Expand Down
2 changes: 2 additions & 0 deletions fs/ocfs2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
if (replayed)
ocfs2_bump_recovery_generation(fe);

ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
status = ocfs2_write_block(osb, bh, journal->j_inode);
if (status < 0)
mlog_errno(status);
Expand Down Expand Up @@ -1486,6 +1487,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
osb->slot_recovery_generations[slot_num] =
ocfs2_get_recovery_generation(fe);

ocfs2_compute_meta_ecc(osb->sb, bh->b_data, &fe->i_check);
status = ocfs2_write_block(osb, bh, inode);
if (status < 0)
mlog_errno(status);
Expand Down
3 changes: 2 additions & 1 deletion fs/ocfs2/journal.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks);
#define OCFS2_JOURNAL_ACCESS_WRITE 1
#define OCFS2_JOURNAL_ACCESS_UNDO 2


/* ocfs2_inode */
int ocfs2_journal_access_di(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type);
struct buffer_head *bh, int type);
/* ocfs2_extent_block */
int ocfs2_journal_access_eb(handle_t *handle, struct inode *inode,
struct buffer_head *bh, int type);
Expand Down
18 changes: 10 additions & 8 deletions fs/ocfs2/localalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ocfs2.h"

#include "alloc.h"
#include "blockcheck.h"
#include "dlmglue.h"
#include "inode.h"
#include "journal.h"
Expand Down Expand Up @@ -382,8 +383,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
}
memcpy(alloc_copy, alloc, bh->b_size);

status = ocfs2_journal_access(handle, local_alloc_inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, local_alloc_inode, bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto out_commit;
Expand Down Expand Up @@ -476,6 +477,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
alloc = (struct ocfs2_dinode *) alloc_bh->b_data;
ocfs2_clear_local_alloc(alloc);

ocfs2_compute_meta_ecc(osb->sb, alloc_bh->b_data, &alloc->i_check);
status = ocfs2_write_block(osb, alloc_bh, inode);
if (status < 0)
mlog_errno(status);
Expand Down Expand Up @@ -762,9 +764,9 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
* delete bits from it! */
*num_bits = bits_wanted;

status = ocfs2_journal_access(handle, local_alloc_inode,
osb->local_alloc_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, local_alloc_inode,
osb->local_alloc_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto bail;
Expand Down Expand Up @@ -1240,9 +1242,9 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
}
memcpy(alloc_copy, alloc, osb->local_alloc_bh->b_size);

status = ocfs2_journal_access(handle, local_alloc_inode,
osb->local_alloc_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
status = ocfs2_journal_access_di(handle, local_alloc_inode,
osb->local_alloc_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
mlog_errno(status);
goto bail;
Expand Down
Loading

0 comments on commit 13723d0

Please sign in to comment.