diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2004-07-09 08:58:32 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2004-07-09 08:58:32 +0000 |
commit | fbbb47a3081ff829ca728a66250169c373b961da (patch) | |
tree | dbdbe015f1a72682578f743248f2677b11160974 | |
parent | 9b53489a21e8c3ab45c43bcb7c62e0ee25898281 (diff) | |
download | fuse-fbbb47a3081ff829ca728a66250169c373b961da.tar.gz |
attribute caching fix
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | kernel/dir.c | 25 |
2 files changed, 30 insertions, 1 deletions
@@ -1,3 +1,9 @@ +2004-07-08 Miklos Szeredi <miklos@szeredi.hu> + + * 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 <miklos@szeredi.hu> * 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; } |