From cb9471a5f73c69858d9dd35ea90b86476e65e4ca Mon Sep 17 00:00:00 2001 From: Coly Li Date: Mon, 26 Apr 2010 22:37:05 +0800 Subject: [PATCH 27/30] dx_dirs: stop iteration of dir trailer initialization for I/O error Callback dir_trailer_func() may encounter malloc or I/O error, these errors can not return to its caller directly. This patch add a member 'errcode_t err' to struct trailer_ctxt, which can catch the error. By this fix, dir_trailer_func() can return OCFS2_EXTENT_ERROR to stop dir iteration immediately and can return the REAL error as well. Thanks to Tao Ma catches this error. Signed-off-by: Coly Li Cc: Mark Fasheh Cc: Tao Ma --- libocfs2/dir_indexed.c | 37 +++++++++++++++++++++++++++++-------- 1 files changed, 29 insertions(+), 8 deletions(-) diff --git a/libocfs2/dir_indexed.c b/libocfs2/dir_indexed.c index 9cae3d0..5f3db95 100644 --- a/libocfs2/dir_indexed.c +++ b/libocfs2/dir_indexed.c @@ -121,6 +121,7 @@ int ocfs2_find_max_rec_len(ocfs2_filesys *fs, char *buf) struct trailer_ctxt { struct ocfs2_dx_root_block *dx_root; struct ocfs2_dinode *di; + errcode_t err; }; /* make sure the space for trailer is reserved */ @@ -170,8 +171,8 @@ static int dir_trailer_func(ocfs2_filesys *fs, struct ocfs2_dinode *di = ctxt->di; struct ocfs2_dx_root_block *dx_root = ctxt->dx_root; struct ocfs2_dir_block_trailer *trailer; - int max_rec_len = 0; - errcode_t ret = 0; + int max_rec_len = 0, ret = 0; + errcode_t err; char *blk = NULL; ret = ocfs2_malloc_block(fs->fs_io, &blk); @@ -180,12 +181,20 @@ static int dir_trailer_func(ocfs2_filesys *fs, /* here we don't trust trailer, cannot use * ocfs2_read_dir_block() */ - ret = ocfs2_read_blocks(fs, blkno, 1, blk); - if (ret) + err = ocfs2_read_blocks(fs, blkno, 1, blk); + if (err) { + ctxt->err = err; + ret = OCFS2_EXTENT_ERROR; goto out; - ret = ocfs2_check_dir_trailer_space(fs, di, blkno, blk); - if (ret) + } + + err = ocfs2_check_dir_trailer_space(fs, di, blkno, blk); + if (err) { + ctxt->err = err; + ret = OCFS2_EXTENT_ERROR; goto out; + } + ocfs2_init_dir_trailer(fs, di, blkno, blk); max_rec_len = ocfs2_find_max_rec_len(fs, blk); trailer = ocfs2_dir_trailer_from_block(fs, blk); @@ -198,7 +207,12 @@ static int dir_trailer_func(ocfs2_filesys *fs, /* comput trailer->db_check here, after writes out, * trailer is trustable */ - ret = ocfs2_write_dir_block(fs, di, blkno, blk); + err = ocfs2_write_dir_block(fs, di, blkno, blk); + if (err) { + ctxt->err = err; + ret = OCFS2_EXTENT_ERROR; + } + out: if (blk) ocfs2_free(&blk); @@ -219,9 +233,16 @@ static errcode_t ocfs2_init_dir_trailers(ocfs2_filesys *fs, ctxt.di = di; ctxt.dx_root = dx_root; - + ctxt.err = 0; ret = ocfs2_block_iterate_inode(fs, di, 0, dir_trailer_func, &ctxt); + + /* callback dir_trailer_func() may have error which can not + * return to its caller directly. If dir_trailer_func() sets + * error in ctxt.err, we should take this REAL error other + * than the value returned by ocfs2_block_iterate_inode(). */ + if (ctxt.err) + ret = ctxt.err; out: return ret; } -- 1.7.0.2