ROMFS: Fix up an error in iget removal
authorDavid Howells <dhowells@redhat.com>
Thu, 20 Mar 2008 00:00:50 +0000 (17:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Mar 2008 01:53:36 +0000 (18:53 -0700)
Fix up an error in iget removal in which romfs_lookup() making a successful
call to romfs_iget() continues through the negative/error handling (previously
the successful case jumped around the negative/error handling case):

 (1) inode is initialised to NULL at the top of the function, eliminating the
     need for specific negative-inode handling.  This means the positive
     success handling now flows straight through.

 (2) Rename the labels to be clearer about what they mean.

Also make romfs_lookup()'s result variable of type long so as to avoid
32-bit/64-bit conversions with PTR_ERR() and friends.

Based upon a report and patch from Adam Richter.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: "Adam J. Richter" <adam@yggdrasil.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/romfs/inode.c

index 00b6f0a..3f13d49 100644 (file)
@@ -340,8 +340,9 @@ static struct dentry *
 romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 {
        unsigned long offset, maxoff;
-       int fslen, res;
-       struct inode *inode;
+       long res;
+       int fslen;
+       struct inode *inode = NULL;
        char fsname[ROMFS_MAXFN];       /* XXX dynamic? */
        struct romfs_inode ri;
        const char *name;               /* got from dentry */
@@ -351,7 +352,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        offset = dir->i_ino & ROMFH_MASK;
        lock_kernel();
        if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
-               goto out;
+               goto error;
 
        maxoff = romfs_maxsize(dir->i_sb);
        offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
@@ -364,9 +365,9 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 
        for(;;) {
                if (!offset || offset >= maxoff)
-                       goto out0;
+                       goto success; /* negative success */
                if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
-                       goto out;
+                       goto error;
 
                /* try to match the first 16 bytes of name */
                fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE);
@@ -397,23 +398,14 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
        inode = romfs_iget(dir->i_sb, offset);
        if (IS_ERR(inode)) {
                res = PTR_ERR(inode);
-               goto out;
+               goto error;
        }
 
-       /*
-        * it's a bit funky, _lookup needs to return an error code
-        * (negative) or a NULL, both as a dentry.  ENOENT should not
-        * be returned, instead we need to create a negative dentry by
-        * d_add(dentry, NULL); and return 0 as no error.
-        * (Although as I see, it only matters on writable file
-        * systems).
-        */
-
-out0:  inode = NULL;
+success:
+       d_add(dentry, inode);
        res = 0;
-       d_add (dentry, inode);
-
-out:   unlock_kernel();
+error:
+       unlock_kernel();
        return ERR_PTR(res);
 }