diff options
author | Theodore Y. Ts'o <tytso@mit.edu> | 2004-06-17 17:58:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-17 17:58:40 -0700 |
commit | 5c4ad014d46133915101b001b217debb21ac2e39 (patch) | |
tree | 94d748b4cf4553c30c994b24dd1e6b4853645274 /fs/ext3/xattr.c | |
parent | 248af7e2e8c8a365bcebb6b181808b6e4a6264f1 (diff) | |
download | history-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.c | 6 |
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; } |