aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/xattr.c
diff options
context:
space:
mode:
authorTheodore Y. Ts'o <tytso@mit.edu>2004-06-17 17:58:40 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-17 17:58:40 -0700
commit5c4ad014d46133915101b001b217debb21ac2e39 (patch)
tree94d748b4cf4553c30c994b24dd1e6b4853645274 /fs/ext3/xattr.c
parent248af7e2e8c8a365bcebb6b181808b6e4a6264f1 (diff)
downloadhistory-5c4ad014d46133915101b001b217debb21ac2e39.tar.gz
[PATCH] Ext3: Retry allocation after transaction commit (v2)
Here is a reworked version of my patch to ext3 to retry certain filesystem operations after an ENOSPC error. The ext3_should_retry_alloc() function will not wait on the currently running transaction if there is a currently active handle; hence this should avoid deadlocks in the Lustre use case. The patch is versus BK-recent. I've also included a simple, reliable test case which demonstrates the problem this patch is intended to fix. (Note that BK-recent is not sufficient to address this test case, and waiting on the commiting transaction in ext3_new_block is also not sufficient. Been there, tried that, didn't work. We need to do the full-bore retry from the top level. The ext3_should_retry_alloc() will only wait on the committing transaction if there is an active handle; hence Lustre will probably also need to use ext3_should_retry_alloc() if it wants to reliably avoid this particular problem.) #!/bin/sh # # TEST_DIR=/tmp IMAGE=$TEST_DIR/retry.img MNTPT=$TEST_DIR/retry.mnt TEST_SRC=/usr/projects/e2fsprogs/e2fsprogs/build MKE2FS_OPTS="" IMAGE_SIZE=8192 umount $MNTPT dd if=/dev/zero of=$IMAGE bs=4k count=$IMAGE_SIZE mke2fs -j -F $MKE2FS_OPTS $IMAGE function test_log () { echo $* logger -p local4.notice $* } mkdir -p $MNTPT mount -o loop -t ext3 $IMAGE $MNTPT test_log Retry test: BEGIN for i in `seq 1 3` do test_log "Retry test: Loop $i" echo 2 > /proc/sys/fs/jbd-debug while ! mkdir -p $MNTPT/foo/bar do test_log "Retry test: mkdir failed" sleep 1 done echo 0 > /proc/sys/fs/jbd-debug cp -r $TEST_SRC $MNTPT/foo/bar 2> /dev/null rm -rf $MNTPT/* done umount $MNTPT test_log "Retry test: END" akpm@osdl.org Rework the code to make it a formal JBD API entry point. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext3/xattr.c')
-rw-r--r--fs/ext3/xattr.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 97b74fed688d20..e818beec46a5a4 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -875,8 +875,9 @@ ext3_xattr_set(struct inode *inode, int name_index, const char *name,
const void *value, size_t value_len, int flags)
{
handle_t *handle;
- int error;
+ int error, retries = 0;
+retry:
handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
if (IS_ERR(handle)) {
error = PTR_ERR(handle);
@@ -886,6 +887,9 @@ ext3_xattr_set(struct inode *inode, int name_index, const char *name,
error = ext3_xattr_set_handle(handle, inode, name_index, name,
value, value_len, flags);
error2 = ext3_journal_stop(handle);
+ if (error == -ENOSPC &&
+ ext3_should_retry_alloc(inode->i_sb, &retries))
+ goto retry;
if (error == 0)
error = error2;
}