ROMFS: Fix up an error in iget removal
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>
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 00b6f0a5..3f13d49 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -340,8 +340,9 @@
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 @@
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 @@
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 @@
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);
}