I've given up on trying to fix the putmap code for now, this patch
builds on my previous patch, basically removes all
putmap/branchget/branchput code. and seems very stable (able to
complete my postmark while branching every 60s torture test that
everything for a long time has failed on).
this includes my previous patch fixing up the locking.
obviously if you want to remove branches from an active union, this
isn't the best thing for one to use.
On Thu, 2006-01-19 at 15:24 -0500, Shaya Potter wrote:
> one thing to note about this patch.
>
> Without it, branching/heavy use seem to deadlock the machine.
>
> With it, it runs much longer (many times completing the postmark), but
> I'm able to get a repeated "Unable to handle kernel paging request" in
> the branchman code, which from my previous message seems to indicate
> that unionfs is corrupting some of its internal data structures somehow.
>
> On Thu, 2006-01-19 at 14:05 -0500, Shaya Potter wrote:
> > this patch changes the use of the read/write lock to force serialization
> > on the branch table.
> >
> > basically, any entry point that can change it (ioctl for adding/changing
> > mode/inc) is taken with write, while every other fs entry point (lookup,
> > read, write....) is taken with read. basically to force the fs not to
> > be in use when a branching operation is taking place.
> >
> > thoughts?
> >
> > it also does one other thing, makes all (I believe) the
> > branchget/branchputs follow this model.
> >
> > 1. branchget before open().
> >
> > 2. branchput after fput().
> > _______________________________________________
> > unionfs mailing list
> > [email protected]
> > http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs
>
> _______________________________________________
> unionfs mailing list
> [email protected]
> http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs
diff -rNu unionfs-20060117-2031/branchman.c unionfs-20060117-2031.branching/branchman.c
--- unionfs-20060117-2031/branchman.c 2006-01-19 13:31:33.000000000 -0500
+++ unionfs-20060117-2031.branching/branchman.c 2006-01-19 15:55:46.000000000 -0500
@@ -21,105 +21,6 @@
#include "unionfs.h"
-static void fixputmaps(struct super_block *sb)
-{
- struct unionfs_sb_info *spd;
- struct putmap *cur;
- int gen;
- int i;
-
- print_entry_location();
-
- spd = stopd(sb);
- cur = spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap];
-
- for (gen = 0; gen < spd->usi_lastputmap - spd->usi_firstputmap; gen++) {
- if (!spd->usi_putmaps[gen])
- continue;
- for (i = 0; i <= spd->usi_putmaps[gen]->bend; i++)
- spd->usi_putmaps[gen]->map[i] =
- cur->map[spd->usi_putmaps[gen]->map[i]];
- }
-
- print_exit_location();
-}
-
-static int newputmap(struct super_block *sb)
-{
- struct unionfs_sb_info *spd;
- struct putmap *newmap;
- int count = 0;
- int i;
-
- print_entry_location();
-
- spd = stopd(sb);
-
- i = sizeof(int) * (sbend(sb) + 1);
- newmap = KMALLOC(sizeof(struct putmap) + i, GFP_KERNEL);
- if (!newmap) {
- print_exit_status(-ENOMEM);
- return -ENOMEM;
- }
-
- if (!spd->usi_firstputmap) {
- spd->usi_firstputmap = 1;
- spd->usi_lastputmap = 1;
-
- spd->usi_putmaps = KMALLOC(sizeof(struct putmap *), GFP_KERNEL);
- if (!spd->usi_putmaps) {
- KFREE(newmap);
- print_exit_status(-ENOMEM);
- return -ENOMEM;
- }
- } else {
- struct putmap **newlist;
- int newfirst = spd->usi_firstputmap;
-
- while (!spd->usi_putmaps[newfirst - spd->usi_firstputmap] &&
- newfirst <= spd->usi_lastputmap) {
- newfirst++;
- }
-
- newlist =
- KMALLOC(sizeof(struct putmap *) *
- (1 + spd->usi_lastputmap - newfirst), GFP_KERNEL);
- if (!newlist) {
- KFREE(newmap);
- print_exit_status(-ENOMEM);
- return -ENOMEM;
- }
-
- for (i = newfirst; i <= spd->usi_lastputmap; i++) {
- newlist[i - newfirst] =
- spd->usi_putmaps[i - spd->usi_firstputmap];
- }
-
- KFREE(spd->usi_putmaps);
- spd->usi_putmaps = newlist;
- spd->usi_firstputmap = newfirst;
- spd->usi_lastputmap++;
- }
-
- newmap->bend = sbend(sb);
- for (i = 0; i <= sbend(sb); i++) {
- count += branch_count(sb, i);
- newmap->map[i] = i;
- }
- for (i = spd->usi_firstputmap; i < spd->usi_lastputmap; i++) {
- struct putmap *cur;
- cur = spd->usi_putmaps[i - spd->usi_firstputmap];
- if (!cur)
- continue;
- count -= atomic_read(&cur->count);
- }
- atomic_set(&newmap->count, count);
- spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap] = newmap;
-
- print_exit_status(0);
- return 0;
-}
-
int unionfs_ioctl_branchcount(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -158,18 +59,12 @@
sb = file->f_dentry->d_sb;
- unionfs_write_lock(sb);
- if ((err = newputmap(sb)))
- goto out;
-
atomic_inc(&stopd(sb)->usi_generation);
err = atomic_read(&stopd(sb)->usi_generation);
atomic_set(&dtopd(sb->s_root)->udi_generation, err);
atomic_set(&itopd(sb->s_root->d_inode)->uii_generation, err);
- out:
- unionfs_write_unlock(sb);
print_exit_status(err);
return err;
}
@@ -235,7 +130,6 @@
goto out;
}
- unionfs_write_lock(inode->i_sb);
lock_dentry(inode->i_sb->s_root);
root = inode->i_sb->s_root;
@@ -253,9 +147,6 @@
|| (addargs->ab_branch > (sbend(inode->i_sb) + 1)))
goto out;
- if ((err = newputmap(inode->i_sb)))
- goto out;
-
stopd(inode->i_sb)->b_end++;
dtopd(inode->i_sb->s_root)->udi_bcount++;
set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1);
@@ -308,7 +199,6 @@
struct super_block *hs;
struct dentry *hd;
struct inode *hi;
- int pmindex;
count = branch_count(inode->i_sb, i);
perms = branchperms(inode->i_sb, i);
@@ -317,11 +207,6 @@
hd = dtohd_index(inode->i_sb->s_root, i);
hi = itohi_index(inode->i_sb->s_root->d_inode, i);
- /* Update the newest putmap, so it is correct for later. */
- pmindex = stopd(inode->i_sb)->usi_lastputmap;
- pmindex -= stopd(inode->i_sb)->usi_firstputmap;
- stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j;
-
if (j >= UNIONFS_INLINE_OBJECTS) {
j -= UNIONFS_INLINE_OBJECTS;
atomic_set(&(new_counts[j]), count);
@@ -376,11 +261,8 @@
atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen);
atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen);
- fixputmaps(inode->i_sb);
-
out:
unlock_dentry(inode->i_sb->s_root);
- unionfs_write_unlock(inode->i_sb);
KFREE(new_hidden_mnt);
KFREE(new_udi_dentry);
@@ -406,7 +288,7 @@
struct dentry *root_dentry;
struct inode *root_inode;
int err = 0;
- int pmindex, i, gen;
+ int i, gen;
print_entry("branch = %lu ", arg);
lock_dentry(sb->s_root);
@@ -421,12 +303,6 @@
if (branch_count(sb, arg))
goto out;
- if ((err = newputmap(sb)))
- goto out;
-
- pmindex = stopd(sb)->usi_lastputmap;
- pmindex -= stopd(sb)->usi_firstputmap;
-
atomic_inc(&stopd(sb)->usi_generation);
gen = atomic_read(&stopd(sb)->usi_generation);
@@ -449,7 +325,6 @@
set_dtohd_index(root_dentry, i,
dtohd_index(root_dentry, i + 1));
set_itohi_index(root_inode, i, itohi_index(root_inode, i + 1));
- stopd(sb)->usi_putmaps[pmindex]->map[i + 1] = i;
}
set_dtohd_index(root_dentry, sbend(sb), NULL);
@@ -465,14 +340,6 @@
atomic_set(&dtopd(root_dentry)->udi_generation, gen);
atomic_set(&itopd(root_inode)->uii_generation, gen);
- fixputmaps(sb);
-
- /* This doesn't open a file, so we might have to free the map here. */
- if (atomic_read(&stopd(sb)->usi_putmaps[pmindex]->count) == 0) {
- KFREE(stopd(sb)->usi_putmaps[pmindex]);
- stopd(sb)->usi_putmaps[pmindex] = NULL;
- }
-
out:
unlock_dentry(sb->s_root);
print_exit_status(err);
@@ -489,12 +356,8 @@
print_entry_location();
- unionfs_write_lock(inode->i_sb);
lock_dentry(inode->i_sb->s_root);
- if ((err = newputmap(inode->i_sb)))
- goto out;
-
err = -ENOMEM;
rdwrargs = KMALLOC(sizeof(struct unionfs_rdwrbranch_args), GFP_KERNEL);
if (!rdwrargs)
@@ -526,7 +389,6 @@
out:
unlock_dentry(inode->i_sb->s_root);
- unionfs_write_unlock(inode->i_sb);
KFREE(rdwrargs);
print_exit_status(err);
diff -rNu unionfs-20060117-2031/commonfops.c unionfs-20060117-2031.branching/commonfops.c
--- unionfs-20060117-2031/commonfops.c 2006-01-18 19:14:16.000000000 -0500
+++ unionfs-20060117-2031.branching/commonfops.c 2006-01-19 15:54:44.000000000 -0500
@@ -21,36 +21,6 @@
#include "unionfs.h"
-/* We only need this function here, but it could get promoted to unionfs.h, if
- * other things need a generation specific branch putting function. */
-static inline void branchput_gen(int generation, struct super_block *sb,
- int index)
-{
- struct putmap *putmap;
-
- if (generation == atomic_read(&stopd(sb)->usi_generation)) {
- branchput(sb, index);
- return;
- }
-
- BUG_ON(stopd(sb)->usi_firstputmap > generation);
- BUG_ON(stopd(sb)->usi_lastputmap < generation);
-
- putmap =
- stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap];
- BUG_ON(index < 0);
- BUG_ON(putmap == NULL);
- BUG_ON(index > putmap->bend);
- BUG_ON(putmap->map[index] < 0);
- branchput(sb, putmap->map[index]);
- if (atomic_dec_and_test(&putmap->count)) {
- stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap]
- = NULL;
- fist_dprint(8, "Freeing putmap %d.\n", generation);
- KFREE(putmap);
- }
-}
-
static char *get_random_name(int size, unsigned char *name)
{
int i;
@@ -174,7 +144,6 @@
dentry = file->f_dentry;
lock_dentry(dentry);
sb = dentry->d_sb;
- unionfs_read_lock(sb);
if (!unionfs_d_revalidate(dentry, NULL) && !d_deleted(dentry)) {
err = -ESTALE;
goto out;
@@ -198,7 +167,6 @@
bend = fbend(file);
for (bindex = bstart; bindex <= bend; bindex++) {
if (ftohf_index(file, bindex)) {
- branchput_gen(fgen, dentry->d_sb, bindex);
fput(ftohf_index(file, bindex));
}
}
@@ -233,7 +201,6 @@
DGET(hidden_dentry);
mntget(stohiddenmnt_index(sb, bindex));
- branchget(sb, bindex);
hidden_file =
DENTRY_OPEN(hidden_dentry,
@@ -278,7 +245,6 @@
DGET(hidden_dentry);
mntget(stohiddenmnt_index(sb, bstart));
- branchget(sb, bstart);
hidden_file =
DENTRY_OPEN(hidden_dentry,
stohiddenmnt_index(sb, bstart),
@@ -333,7 +299,6 @@
bend = fbend(file);
for (bindex = bstart; bindex <= bend; bindex++) {
if (ftohf_index(file, bindex)) {
- branchput(dentry->d_sb, bindex);
fput(ftohf_index(file, bindex));
set_ftohf_index(file, bindex, NULL);
}
@@ -345,7 +310,6 @@
out:
fist_print_dentry("file revalidate out", dentry);
unlock_dentry(dentry);
- unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -361,6 +325,7 @@
int locked = 0;
print_entry_location();
+ unionfs_read_lock(inode->i_sb);
ftopd_lhs(file) = KZALLOC(sizeof(struct unionfs_file_info), GFP_KERNEL);
if (!ftopd(file)) {
@@ -389,7 +354,6 @@
dentry = file->f_dentry;
fist_dprint(8, "dentry to open is %p\n", dentry);
lock_dentry(dentry);
- unionfs_read_lock(inode->i_sb);
locked = 1;
bstart = fbstart(file) = dbstart(dentry);
@@ -419,9 +383,6 @@
}
set_ftohf_index(file, bindex, hidden_file);
- /* The branchget goes after the open, because otherwise
- * we would miss the reference on release. */
- branchget(inode->i_sb, bindex);
}
} else {
/* open a file */
@@ -467,25 +428,19 @@
goto out;
} else {
set_ftohf(file, hidden_file);
- branchget(inode->i_sb, bstart);
}
}
out:
/* freeing the allocated resources, and fput the opened files */
if (err < 0 && ftopd(file)) {
- if (!locked)
- unionfs_read_lock(file->f_dentry->d_sb);
for (bindex = bstart; bindex <= bend; bindex++) {
hidden_file = ftohf_index(file, bindex);
if (hidden_file) {
- branchput(file->f_dentry->d_sb, bindex);
/* fput calls dput for hidden_dentry */
fput(hidden_file);
}
}
- if (!locked)
- unionfs_read_unlock(file->f_dentry->d_sb);
KFREE(ftohf_ptr(file));
KFREE(ftopd(file));
}
@@ -494,8 +449,8 @@
if (locked) {
unlock_dentry(dentry);
- unionfs_read_unlock(inode->i_sb);
}
+ unionfs_read_unlock(inode->i_sb);
print_exit_status(err);
return err;
}
@@ -508,6 +463,7 @@
int fgen;
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
fist_checkinode(inode, "unionfs_release");
@@ -521,9 +477,6 @@
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));
@@ -546,6 +499,8 @@
fist_checkinode(inode, "post unionfs_release");
+ unionfs_read_unlock(file->f_dentry->d_sb);
+
print_exit_status(err);
return err;
}
@@ -560,9 +515,22 @@
long err = 0; /* don't fail by default */
struct file *hidden_file = NULL;
int val;
+ int read_lock = 0;
print_entry_location();
+ switch (cmd) {
+ case FIST_IOCTL_SET_DEBUG_VALUE:
+ case UNIONFS_IOCTL_INCGEN:
+ case UNIONFS_IOCTL_ADDBRANCH:
+ case UNIONFS_IOCTL_RDWRBRANCH:
+ unionfs_write_lock(file->f_dentry->d_sb);
+ break;
+ default:
+ unionfs_read_lock(file->f_dentry->d_sb);
+ read_lock = 1;
+ }
+
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -661,6 +629,11 @@
} /* end of outer switch statement */
out:
+ if (read_lock)
+ unionfs_read_unlock(file->f_dentry->d_sb);
+ else {
+ unionfs_write_unlock(file->f_dentry->d_sb);
+ }
print_exit_status((int)err);
return err;
}
@@ -673,6 +646,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
if (!atomic_dec_and_test
@@ -704,6 +679,7 @@
out_lock:
unlock_dentry(file->f_dentry);
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/copyup.c unionfs-20060117-2031.branching/copyup.c
--- unionfs-20060117-2031/copyup.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/copyup.c 2006-01-19 15:55:01.000000000 -0500
@@ -219,8 +219,6 @@
sb = dir->i_sb;
- unionfs_read_lock(sb);
-
if ((err = is_robranch_super(sb, new_bindex)))
goto out;
@@ -303,7 +301,6 @@
/* We actually copyup the file here. */
if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) {
mntget(stohiddenmnt_index(sb, old_bindex));
- branchget(sb, old_bindex);
got_branch_input = old_bindex;
input_file =
DENTRY_OPEN(old_hidden_dentry,
@@ -320,7 +317,6 @@
/* copy the new file */
DGET(new_hidden_dentry);
mntget(stohiddenmnt_index(sb, new_bindex));
- branchget(sb, new_bindex);
got_branch_output = new_bindex;
output_file =
DENTRY_OPEN(new_hidden_dentry,
@@ -401,10 +397,6 @@
DPUT(old_hidden_dentry);
}
- /* in any case, we have to branchput */
- if (got_branch_input >= 0)
- branchput(sb, got_branch_input);
-
if (output_file) {
if (copyup_file && !err) {
*copyup_file = output_file;
@@ -412,12 +404,9 @@
if (!err) {
fput(output_file);
}
- branchput(sb, got_branch_output);
}
}
- unionfs_read_unlock(sb);
-
fist_print_dentry("OUT: copyup_dentry", dentry);
fist_print_inode("OUT: copyup_dentry", dentry->d_inode);
diff -rNu unionfs-20060117-2031/dentry.c unionfs-20060117-2031.branching/dentry.c
--- unionfs-20060117-2031/dentry.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/dentry.c 2006-01-19 15:48:10.000000000 -0500
@@ -22,8 +22,10 @@
#include "unionfs.h"
/* declarations added for "sparse" */
-extern int unionfs_d_revalidate_wrap(struct dentry *dentry,
+extern int unionfs_d_revalidate_lockd(struct dentry *dentry,
struct nameidata *nd);
+extern int unionfs_d_revalidate_wrap(struct dentry *dentry,
+ struct nameidata *nd);
extern void unionfs_d_release(struct dentry *dentry);
extern void unionfs_d_iput(struct dentry *dentry, struct inode *inode);
@@ -38,7 +40,6 @@
int bindex, bstart, bend;
int sbgen, dgen;
int positive = 0;
- int locked = 0;
int restart = 0;
print_util_entry_location();
@@ -66,24 +67,20 @@
struct dentry *result;
int pdgen;
- unionfs_read_lock(dentry->d_sb);
- locked = 1;
-
/* The root entry should always be valid */
BUG_ON(IS_ROOT(dentry));
/* We can't work correctly if our parent isn't valid. */
pdgen = atomic_read(&dtopd(dentry->d_parent)->udi_generation);
if (!restart && (pdgen != sbgen)) {
- unionfs_read_unlock(dentry->d_sb);
- locked = 0;
/* We must be locked before our parent. */
- if (!
- (dentry->d_parent->d_op->
- d_revalidate(dentry->d_parent, nd))) {
+ lock_dentry(dentry->d_parent);
+ if (!unionfs_d_revalidate(dentry->d_parent, nd)) {
+ unlock_dentry(dentry->d_parent);
invalid = 1;
goto out;
}
+ unlock_dentry(dentry->d_parent);
restart = 1;
goto restart;
}
@@ -166,8 +163,6 @@
fist_copy_attr_all(dentry->d_inode, dtohd(dentry)->d_inode);
out:
- if (locked)
- unionfs_read_unlock(dentry->d_sb);
if (invalid)
err = 0;
fist_print_dentry("revalidate out", dentry);
@@ -180,11 +175,13 @@
int err;
print_entry_location();
- lock_dentry(dentry);
+ unionfs_read_lock(dentry->d_sb);
+ lock_dentry(dentry);
err = unionfs_d_revalidate(dentry, nd);
-
unlock_dentry(dentry);
+
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/dirfops.c unionfs-20060117-2031.branching/dirfops.c
--- unionfs-20060117-2031/dirfops.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/dirfops.c 2006-01-19 15:48:10.000000000 -0500
@@ -106,6 +106,8 @@
fist_print_file("In unionfs_readdir()", file);
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -206,6 +208,7 @@
}
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
fist_checkinode(inode, "post unionfs_readdir");
print_exit_status(err);
return err;
@@ -230,6 +233,8 @@
print_entry(" file=%p, offset=0x%llx, origin = %d", file, offset,
origin);
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -294,6 +299,7 @@
}
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status((int)err);
return err;
}
diff -rNu unionfs-20060117-2031/dirhelper.c unionfs-20060117-2031.branching/dirhelper.c
--- unionfs-20060117-2031/dirhelper.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/dirhelper.c 2006-01-19 15:55:17.000000000 -0500
@@ -168,8 +168,6 @@
sb = dentry->d_sb;
- unionfs_read_lock(sb);
-
BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
if ((err = unionfs_partial_lookup(dentry)))
@@ -206,17 +204,15 @@
DGET(hidden_dentry);
mntget(stohiddenmnt_index(sb, bindex));
- branchget(sb, bindex);
hidden_file =
DENTRY_OPEN(hidden_dentry, stohiddenmnt_index(sb, bindex),
O_RDONLY);
if (IS_ERR(hidden_file)) {
err = PTR_ERR(hidden_file);
DPUT(hidden_dentry);
- branchput(sb, bindex);
goto out;
}
-
+
do {
buf->filldir_called = 0;
buf->rdstate->uds_bindex = bindex;
@@ -228,7 +224,6 @@
/* fput calls dput for hidden_dentry */
fput(hidden_file);
- branchput(sb, bindex);
if (err < 0)
goto out;
@@ -243,8 +238,6 @@
KFREE(buf);
}
- unionfs_read_unlock(sb);
-
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/file.c unionfs-20060117-2031.branching/file.c
--- unionfs-20060117-2031/file.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/file.c 2006-01-19 15:48:10.000000000 -0500
@@ -40,6 +40,8 @@
fist_dprint(6, "unionfs_llseek: file=%p, offset=0x%llx, origin=%d\n",
file, offset, origin);
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -65,6 +67,7 @@
file->f_version++;
}
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status((int)err);
return err;
}
@@ -78,6 +81,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -99,6 +104,7 @@
sizeof(struct file_ra_state));
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
fist_print_file("leaving read()", file);
print_exit_status(err);
return err;
@@ -113,6 +119,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 0)))
goto out;
@@ -126,6 +134,7 @@
target);
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -144,6 +153,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -180,6 +191,7 @@
inode->i_size = pos;
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -200,6 +212,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if (unionfs_file_revalidate(file, 0)) {
/* We should pretend an error happend. */
mask = POLLERR | POLLIN | POLLOUT;
@@ -214,6 +228,7 @@
mask = hidden_file->f_op->poll(hidden_file, wait);
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(mask);
return mask;
}
@@ -227,6 +242,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
/* This might could be deferred to mmap's writepage. */
willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
if ((err = unionfs_file_revalidate(file, willwrite)))
@@ -244,6 +261,7 @@
fput(file); /* no need to keep extra ref on ours */
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -255,6 +273,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -270,6 +290,7 @@
up(&hidden_file->f_dentry->d_inode->i_sem);
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -281,6 +302,8 @@
print_entry_location();
+ unionfs_read_lock(file->f_dentry->d_sb);
+
if ((err = unionfs_file_revalidate(file, 1)))
goto out;
@@ -290,6 +313,7 @@
err = hidden_file->f_op->fasync(fd, hidden_file, flag);
out:
+ unionfs_read_unlock(file->f_dentry->d_sb);
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/fistdev.mk unionfs-20060117-2031.branching/fistdev.mk
--- unionfs-20060117-2031/fistdev.mk 1969-12-31 19:00:00.000000000 -0500
+++ unionfs-20060117-2031.branching/fistdev.mk 2006-01-19 15:48:10.000000000 -0500
@@ -0,0 +1 @@
+EXTRACFLAGS=-DUNIONFS_NDEBUG
diff -rNu unionfs-20060117-2031/inode.c unionfs-20060117-2031.branching/inode.c
--- unionfs-20060117-2031/inode.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/inode.c 2006-01-19 15:48:10.000000000 -0500
@@ -45,6 +45,8 @@
char *name = NULL;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
+
lock_dentry(dentry);
fist_print_dentry("IN unionfs_create", dentry);
@@ -194,6 +196,7 @@
fist_print_dentry("OUT unionfs_create :", dentry);
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -201,8 +204,15 @@
struct dentry *unionfs_lookup(struct inode *parent, struct dentry *dentry,
struct nameidata *nd)
{
- /* The locking is done by unionfs_lookup_backend. */
- return unionfs_lookup_backend(dentry, INTERPOSE_LOOKUP);
+ struct dentry * ret;
+ unionfs_read_lock(dentry->d_sb);
+ /* The dentry locking is done by unionfs_lookup_backend. */
+
+ ret = unionfs_lookup_backend(dentry, INTERPOSE_LOOKUP);
+
+ unionfs_read_unlock(dentry->d_sb);
+
+ return ret;
}
static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
@@ -216,6 +226,8 @@
char *name = NULL;
print_entry_location();
+ unionfs_read_lock(new_dentry->d_sb);
+
double_lock_dentry(new_dentry, old_dentry);
hidden_new_dentry = dtohd(new_dentry);
@@ -327,6 +339,8 @@
unlock_dentry(new_dentry);
unlock_dentry(old_dentry);
+ unionfs_read_unlock(new_dentry->d_sb);
+
print_exit_status(err);
return err;
}
@@ -343,6 +357,9 @@
char *name = NULL;
print_entry_location();
+
+ unionfs_read_lock(dentry->d_sb);
+
lock_dentry(dentry);
fist_print_dentry("IN unionfs_symlink", dentry);
@@ -453,6 +470,9 @@
KFREE(name);
fist_print_dentry("OUT unionfs_symlink :", dentry);
unlock_dentry(dentry);
+
+ unionfs_read_unlock(dentry->d_sb);
+
print_exit_status(err);
return err;
}
@@ -469,6 +489,7 @@
gid_t saved_gid = current->fsgid;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
fist_print_dentry("IN unionfs_mkdir", dentry);
bstart = dbstart(dentry);
@@ -605,6 +626,7 @@
fist_print_dentry("OUT unionfs_mkdir :", dentry);
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -620,6 +642,7 @@
int whiteout_unlinked = 0;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
fist_print_dentry("IN unionfs_mknod", dentry);
bstart = dbstart(dentry);
@@ -718,6 +741,7 @@
fist_print_dentry("OUT unionfs_mknod :", dentry);
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -728,6 +752,7 @@
struct dentry *hidden_dentry;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
hidden_dentry = dtohd(dentry);
fist_print_dentry("unionfs_readlink IN", dentry);
@@ -745,6 +770,7 @@
out:
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -762,6 +788,8 @@
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
+
/* This is freed by the put_link method assuming a successful call. */
buf = (char *)KMALLOC(len, GFP_KERNEL);
if (!buf) {
@@ -784,6 +812,7 @@
err = 0;
out:
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
return err;
@@ -867,6 +896,7 @@
int is_file = 0;
print_entry_location();
+ unionfs_read_lock(inode->i_sb);
bstart = ibstart(inode);
bend = ibend(inode);
@@ -908,6 +938,7 @@
}
out:
+ unionfs_read_unlock(inode->i_sb);
print_exit_status(err);
return err;
}
@@ -923,6 +954,7 @@
int copyup = 0;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
bstart = dbstart(dentry);
bend = dbend(dentry);
@@ -972,6 +1004,7 @@
out:
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
fist_checkinode(inode, "post unionfs_setattr");
print_exit_status(err);
return err;
diff -rNu unionfs-20060117-2031/rename.c unionfs-20060117-2031.branching/rename.c
--- unionfs-20060117-2031/rename.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/rename.c 2006-01-19 15:48:10.000000000 -0500
@@ -757,6 +757,8 @@
print_entry_location();
+ unionfs_read_lock(new_dentry->d_sb);
+
double_lock_dentry(old_dentry, new_dentry);
fist_checkinode(old_dir, "unionfs_rename-old_dir");
@@ -822,6 +824,7 @@
unlock_dentry(new_dentry);
unlock_dentry(old_dentry);
+ unionfs_read_unlock(new_dentry->d_sb);
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/super.c unionfs-20060117-2031.branching/super.c
--- unionfs-20060117-2031/super.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/super.c 2006-01-19 15:54:25.000000000 -0500
@@ -135,7 +135,6 @@
KFREE(stohiddenmnt_ptr(sb));
KFREE(spd->usi_sbcount_p);
KFREE(spd->usi_branchperms_p);
- KFREE(spd->usi_putmaps);
KFREE(spd);
stopd_lhs(sb) = NULL;
}
@@ -152,6 +151,7 @@
int bindex, bindex1, bstart, bend;
print_entry_location();
+
memset(buf, 0, sizeof(struct kstatfs));
buf->f_type = UNIONFS_SUPER_MAGIC;
@@ -223,6 +223,7 @@
memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t));
memset(&buf->f_spare, 0, sizeof(buf->f_spare));
+
print_exit_status(err);
return err;
}
@@ -232,6 +233,8 @@
unsigned long *uldata = (unsigned long *)data;
int err;
+ unionfs_write_lock(sb);
+
uldata++;
switch (*uldata) {
@@ -242,6 +245,7 @@
err = -ENOTTY;
}
+ unionfs_write_unlock(sb);
return err;
}
@@ -289,7 +293,11 @@
hidden_inode = itohi_index(inode, bindex);
if (!hidden_inode)
continue;
- iput(hidden_inode);
+ if (hidden_inode->i_sb) {
+ iput(hidden_inode);
+ } else {
+ printk("SHAYA: hidden_inode->i_sb is NULL!\n");
+ }
}
}
// XXX: why this assertion fails?
@@ -317,6 +325,7 @@
memset(&c->info, 0, sizeof(c->info));
c->vfs_inode.i_version = 1;
+
print_exit_pointer(&c->vfs_inode);
return &c->vfs_inode;
}
@@ -373,7 +382,11 @@
/* Called when we have a dirty inode, right here we only throw out
* parts of our readdir list that are too old.
*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
static int unionfs_write_inode(struct inode *inode, int sync)
+#else
+static void unionfs_write_inode(struct inode *inode, int sync)
+#endif
{
struct list_head *pos, *n;
struct unionfs_dir_state *rdstate;
@@ -393,7 +406,9 @@
spin_unlock(&itopd(inode)->uii_rdlock);
print_exit_location();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
return 0;
+#endif
}
/*
diff -rNu unionfs-20060117-2031/unionfs.h unionfs-20060117-2031.branching/unionfs.h
--- unionfs-20060117-2031/unionfs.h 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/unionfs.h 2006-01-19 15:48:10.000000000 -0500
@@ -44,7 +44,7 @@
#include <linux/dcache.h>
#include <linux/poll.h>
-#if (!defined(UNIONFS_UNSUPPORTED)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+#if (!defined(UNIONFS_UNSUPPORTED)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8))
#warning You are compiling Unionfs on an unsupported kernel version.
#warning To compile Unionfs, you will need to define UNIONFS_UNSUPPORTED.
#warning Try adding: EXTRACFLAGS=-DUNIONFS_UNSUPPORTED to fistdev.mk
diff -rNu unionfs-20060117-2031/unlink.c unionfs-20060117-2031.branching/unlink.c
--- unionfs-20060117-2031/unlink.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/unlink.c 2006-01-19 15:48:10.000000000 -0500
@@ -202,6 +202,7 @@
int err = 0;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
fist_print_dentry("IN unionfs_unlink", dentry);
@@ -215,6 +216,7 @@
d_drop(dentry);
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -342,6 +344,7 @@
struct unionfs_dir_state *namelist = NULL;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
fist_print_dentry("IN unionfs_rmdir: ", dentry);
@@ -397,6 +400,7 @@
free_rdstate(namelist);
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
diff -rNu unionfs-20060117-2031/xattr.c unionfs-20060117-2031.branching/xattr.c
--- unionfs-20060117-2031/xattr.c 2006-01-17 20:31:48.000000000 -0500
+++ unionfs-20060117-2031.branching/xattr.c 2006-01-19 15:48:10.000000000 -0500
@@ -65,6 +65,8 @@
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
+
lock_dentry(dentry);
hidden_dentry = dtohd(dentry);
@@ -89,6 +91,7 @@
}
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -105,6 +108,8 @@
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
+
lock_dentry(dentry);
hidden_dentry = dtohd(dentry);
@@ -121,6 +126,7 @@
}
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -135,6 +141,7 @@
char *encoded_name;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
hidden_dentry = dtohd(dentry);
@@ -153,6 +160,7 @@
}
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
@@ -167,6 +175,7 @@
char *encoded_list = NULL;
print_entry_location();
+ unionfs_read_lock(dentry->d_sb);
lock_dentry(dentry);
hidden_dentry = dtohd(dentry);
@@ -183,6 +192,7 @@
}
unlock_dentry(dentry);
+ unionfs_read_unlock(dentry->d_sb);
print_exit_status(err);
return err;
}
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs