lkml.org 
[lkml]   [2003]   [Jan]   [16]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateThu, 16 Jan 2003 14:00:15 +0300
FromOleg Drokin <>
Subject[2.4] VFS locking problem during concurrent link/unlink
Hello!

   Debugging reiserfs problem that can be demonstrated with script created by
   Zygo Blaxell, I started to wonder if the problem presented is indeed reiserfs
   fault and not VFS.
   Though the Zygo claims script only produces problems on reiserfs, I am trying
   it now myself on ext2 (which will take some time).

   Debugging shows that reiserfs_link is sometimes called for inodes whose
   i_nlink is zero (and all corresponding data is deleted already).
   So my current guess of what's going on is this:

   process 1                      process 2
   sys_unlink("a/b")		  sys_link("a/b", "c/d");
   down(inode of ("a"));	  down(inode of "c");

   lock_kernel()
   reiserfs_unlink("a/b")
     decreases i_nlink of a/b to zero
     and removes name "b" from "a"
   unlock_kernel()
   d_delete("a/b")
(*)
				   lock_kernel()
				   reiserfs_link()
					at this point we do usual stuff,
					but inode's n_nlink is zero and
					file data already removed which
				        indicates reiserfs_delete_inode()
					was already called at (*)
				   unlock_kernel()

   So my question is "Is it really ok that sys_link/vfs_link does not
   take semaphore on parent dir of original path?", or should we
   actually put a workaround in reiserfs code to avoid such a situation?

Bye,
    Oleg
PS: Here's the script:
#!/bin/bash

# Create an empty filesystem:

mkreiserfs -f -f /dev/hdb2
mount /dev/hdb2 /data1 -t reiserfs

cd /data1

# Script used to control the load average.  Note that as written the loops
# below will keep spawning new processes, so we need some way to throttle
# them.  Change the '-lt 10' to another number to change the number
# of processes.

cat <<'LC' > loadcheck && chmod 755 loadcheck
#!/bin/sh
read av1 av5 av15 rest < /proc/loadavg
echo -n "Load Average: $av1 ... "
av1=${av1%.*}
if [ $av1 -lt 10 ]; then
        echo OK
        exit 0
else
        echo "Whoa, Nellie!"
        exit 1
fi
LC
# Create directories used by test
mkdir foo bar
mkdir foo/etc foo/usr foo/var
# Start up some rsyncs.  I use /etc, /usr, and /var because there's a
# good mixture of files with some hardlinks between them, and on a normal
# Linux system some of them change from time to time.

while sleep 1m; do
        ./loadcheck || continue;
        for x in usr etc var; do
                rsync -avxHS --delete /$x/. foo/$x/. &
        done;
done &
# Start up some cp -al's and rm -rf's.  Note there are two concurrent
# sets of 'cp's and two concurrent sets of 'rm's, and each of those
# has different instances of 'cp' and 'rm' running at different times.
for x in  1 2; do
        while sleep 1m; do
                ./loadcheck || continue;
                cp -al foo bar/`date +%s` &
        done &
        while sleep 1m; do
                ./loadcheck || continue;
                for x in bar/*; do
                        rm -rf $x;
                        sleep 1m;
                done &
        done &
done &


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 12:32    [from the cache]
©2003-2008