[PATCH] fuse: locking fix for nlookup
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 17 Oct 2006 07:10:08 +0000 (00:10 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 17 Oct 2006 15:18:45 +0000 (08:18 -0700)
An inode could be returned by independent parallel lookups, in this case an
update of the lookup counter could be lost resulting in a memory leak in
userspace.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/fuse/dir.c
fs/fuse/inode.c

index a8f65c11aa2c499d9455e3b84a5566e64099fd5e..7ecfe95795cda9a37b410188b715f948fc8140aa 100644 (file)
@@ -163,7 +163,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                                fuse_send_forget(fc, req, outarg.nodeid, 1);
                                return 0;
                        }
+                       spin_lock(&fc->lock);
                        fi->nlookup ++;
+                       spin_unlock(&fc->lock);
                }
                fuse_put_request(fc, req);
                if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
index 8e106163aaed7e4c52c4fb6950208dd72f4be434..e9114237f31f28b10b45ef9bf189b2c39f044381 100644 (file)
@@ -195,7 +195,9 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
        }
 
        fi = get_fuse_inode(inode);
+       spin_lock(&fc->lock);
        fi->nlookup ++;
+       spin_unlock(&fc->lock);
        fuse_change_attributes(inode, attr);
        return inode;
 }