From: Miklos Szeredi Date: Fri, 9 Jul 2004 08:58:32 +0000 (+0000) Subject: attribute caching fix X-Git-Tag: fuse_1_3~1 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=fbbb47a3081ff829ca728a66250169c373b961da;p=qemu-gpiodev%2Flibfuse.git attribute caching fix --- diff --git a/ChangeLog b/ChangeLog index 0476313..dee4a83 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-07-08 Miklos Szeredi + + * When performing create or remove operation, refresh the parent's + attributes on next revalidate, as i_nlink (and maybe size/time) + could be inacurate. + 2004-07-06 Miklos Szeredi * Make RELEASE method synchronous. This fixes an abort in libfuse diff --git a/kernel/dir.c b/kernel/dir.c index e6bf28c..9a88a23 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -145,6 +145,17 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, return 0; } +static void uncache_dir(struct inode *dir) +{ + struct dentry *entry = d_find_alias(dir); + if (!entry) + dir->i_nlink = 0; + else { + entry->d_time = jiffies - FUSE_REVALIDATE_TIME - 1; + dput(entry); + } +} + /* create needs to return a positive entry, so this is actually an mknod+lookup */ static int _fuse_mknod(struct inode *dir, struct dentry *entry, int mode, @@ -188,6 +199,7 @@ static int _fuse_mknod(struct inode *dir, struct dentry *entry, int mode, } d_instantiate(entry, inode); + uncache_dir(dir); return 0; } @@ -208,6 +220,7 @@ static int lookup_new_entry(struct inode *dir, struct dentry *entry) return err ? err : -ENOENT; } d_instantiate(entry, inode); + uncache_dir(dir); return 0; } @@ -286,6 +299,8 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) err = fuse_do_getattr(entry->d_inode); if(err == -ENOENT) entry->d_inode->i_nlink = 0; + + uncache_dir(dir); return 0; } return err; @@ -294,8 +309,10 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) static int fuse_rmdir(struct inode *dir, struct dentry *entry) { int err = fuse_remove(dir, entry, FUSE_RMDIR); - if(!err) + if(!err) { entry->d_inode->i_nlink = 0; + uncache_dir(dir); + } return err; } @@ -321,6 +338,12 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, in.args[2].value = newent->d_name.name; request_send(fc, &in, &out); + if (!out.h.error) { + uncache_dir(olddir); + if (olddir != newdir) + uncache_dir(newdir); + } + return out.h.error; }