On Thu, 2005-10-20 at 12:24 -0400, Charles P. Wright wrote: > I'll take a bite of the apple. I've committed your diff to the latest > snapshot.
Here's another patch on top of what you already applied. it attempts to wrap ever function that calls branchget/put within a read_lock/read_unlock pair. look it over, I'm not so sure that I got the lock ordering right (vis a vis w/ dentry locking). Is there any other functions that depend on the sb branch structure not changing that would have to be wrapped?
diff -rNu unionfs-20051020-1229/commonfops.c unionfs-20051020-1229.new/commonfops.c --- unionfs-20051020-1229/commonfops.c 2005-10-20 12:29:42.000000000 -0400 +++ unionfs-20051020-1229.new/commonfops.c 2005-10-20 14:30:44.000000000 -0400 @@ -28,11 +28,9 @@ { struct putmap *putmap; - unionfs_read_lock(sb); - if (generation == atomic_read(&stopd(sb)->usi_generation)) { branchput(sb, index); - goto out; + return; } ASSERT(stopd(sb)->usi_firstputmap <= generation); @@ -51,9 +49,6 @@ fist_dprint(8, "Freeing putmap %d.\n", generation); KFREE(putmap); } - - out: - unionfs_read_unlock(sb); } char *get_random_name(int size, unsigned char *name) @@ -182,14 +177,16 @@ dentry = file->f_dentry; lock_dentry(dentry); PASSERT(dentry); + sb = dentry->d_sb; + PASSERT(sb); + unionfs_read_lock(sb); + if (!unionfs_d_revalidate(dentry, 0) && !d_deleted(dentry)) { err = -ESTALE; goto out; } fist_print_dentry("file revalidate in", dentry); - sb = dentry->d_sb; - PASSERT(sb); sbgen = atomic_read(&stopd(sb)->usi_generation); dgen = atomic_read(&dtopd(dentry)->udi_generation); fgen = atomic_read(&ftopd(file)->ufi_generation); @@ -349,9 +346,7 @@ bend = fbend(file); for (bindex = bstart; bindex <= bend; bindex++) { if (ftohf_index(file, bindex)) { - unionfs_read_lock(dentry->d_sb); branchput(dentry->d_sb, bindex); - unionfs_read_unlock(dentry->d_sb); fput(ftohf_index(file, bindex)); set_ftohf_index(file, bindex, NULL); } @@ -363,6 +358,7 @@ out: fist_print_dentry("file revalidate out", dentry); unlock_dentry(dentry); + unionfs_read_unlock(dentry->d_sb); print_exit_status(err); return err; } @@ -411,6 +407,9 @@ lock_dentry(dentry); locked = 1; + //need this to ensure branchget/put are in same generation + unionfs_read_lock(inode->i_sb); + bstart = fbstart(file) = dbstart(dentry); bend = fbend(file) = dbend(dentry); @@ -512,6 +511,9 @@ if (locked) unlock_dentry(dentry); + + unionfs_read_unlock(inode->i_sb); + print_exit_status(err); return err; } @@ -537,7 +539,9 @@ if (hidden_file) { fput(hidden_file); + unionfs_read_lock(inode->i_sb); branchput_gen(fgen, inode->i_sb, bindex); + unionfs_read_unlock(inode->i_sb); } } KFREE(ftohf_ptr(file)); diff -rNu unionfs-20051020-1229/copyup.c unionfs-20051020-1229.new/copyup.c --- unionfs-20051020-1229/copyup.c 2005-10-20 12:29:42.000000000 -0400 +++ unionfs-20051020-1229.new/copyup.c 2005-10-20 14:32:18.000000000 -0400 @@ -226,6 +226,8 @@ sb = dir->i_sb; + unionfs_read_lock(sb); + if ((err = is_robranch_super(sb, new_bindex))) goto out; @@ -422,6 +424,8 @@ } } + unionfs_read_unlock(sb); + fist_print_dentry("OUT: copyup_dentry", dentry); fist_print_inode("OUT: copyup_dentry", dentry->d_inode); diff -rNu unionfs-20051020-1229/dirhelper.c unionfs-20051020-1229.new/dirhelper.c --- unionfs-20051020-1229/dirhelper.c 2005-10-20 12:29:42.000000000 -0400 +++ unionfs-20051020-1229.new/dirhelper.c 2005-10-20 14:32:44.000000000 -0400 @@ -175,6 +175,8 @@ sb = dentry->d_sb; + unionfs_read_lock(sb); + ASSERT(S_ISDIR(dentry->d_inode->i_mode)); if ((err = unionfs_partial_lookup(dentry))) @@ -245,6 +247,8 @@ KFREE(buf); } + unionfs_read_unlock(sb); + print_exit_status(err); return err; }
_______________________________________________ unionfs mailing list unionfs@mail.fsl.cs.sunysb.edu http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs