summaryrefslogtreecommitdiff
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-04-18 17:29:05 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-04-18 17:29:05 -0700
commitdbfad21422f8d2c0866185b3e449c4a6ebaec4e2 (patch)
treea30de27f59ddce92ba9b950d5bb1b20ff23191b4 /fs/fuse/dir.c
parent743e89ebc0215900040b1c2d1563d70a22ac2cb0 (diff)
parentc628ee67fb15a0d8d48351aa2e487c5f14779785 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: use flexible array in fuse.h fuse: allow nanosecond granularity fuse: O_DIRECT support for files fuse: fix nlink after unlink
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r--fs/fuse/dir.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 206632887bb..df5ac048dc7 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -387,9 +387,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
if (fc->no_create)
return -ENOSYS;
- if (flags & O_DIRECT)
- return -EINVAL;
-
forget = fuse_alloc_forget();
if (!forget)
return -ENOMEM;
@@ -644,13 +641,12 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
fuse_put_request(fc, req);
if (!err) {
struct inode *inode = entry->d_inode;
+ struct fuse_inode *fi = get_fuse_inode(inode);
- /*
- * Set nlink to zero so the inode can be cleared, if the inode
- * does have more links this will be discovered at the next
- * lookup/getattr.
- */
- clear_nlink(inode);
+ spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
+ drop_nlink(inode);
+ spin_unlock(&fc->lock);
fuse_invalidate_attr(inode);
fuse_invalidate_attr(dir);
fuse_invalidate_entry_cache(entry);
@@ -762,8 +758,17 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
will reflect changes in the backing inode (link count,
etc.)
*/
- if (!err || err == -EINTR)
+ if (!err) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+
+ spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
+ inc_nlink(inode);
+ spin_unlock(&fc->lock);
+ fuse_invalidate_attr(inode);
+ } else if (err == -EINTR) {
fuse_invalidate_attr(inode);
+ }
return err;
}