Commit 4ebf8984 authored by David Howells's avatar David Howells Committed by Linus Torvalds

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: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatar"Adam J. Richter" <adam@yggdrasil.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c587f0c0
...@@ -340,8 +340,9 @@ static struct dentry * ...@@ -340,8 +340,9 @@ static struct dentry *
romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{ {
unsigned long offset, maxoff; unsigned long offset, maxoff;
int fslen, res; long res;
struct inode *inode; int fslen;
struct inode *inode = NULL;
char fsname[ROMFS_MAXFN]; /* XXX dynamic? */ char fsname[ROMFS_MAXFN]; /* XXX dynamic? */
struct romfs_inode ri; struct romfs_inode ri;
const char *name; /* got from dentry */ const char *name; /* got from dentry */
...@@ -351,7 +352,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) ...@@ -351,7 +352,7 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
offset = dir->i_ino & ROMFH_MASK; offset = dir->i_ino & ROMFH_MASK;
lock_kernel(); lock_kernel();
if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
goto out; goto error;
maxoff = romfs_maxsize(dir->i_sb); maxoff = romfs_maxsize(dir->i_sb);
offset = be32_to_cpu(ri.spec) & ROMFH_MASK; offset = be32_to_cpu(ri.spec) & ROMFH_MASK;
...@@ -364,9 +365,9 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) ...@@ -364,9 +365,9 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
for(;;) { for(;;) {
if (!offset || offset >= maxoff) if (!offset || offset >= maxoff)
goto out0; goto success; /* negative success */
if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0) if (romfs_copyfrom(dir, &ri, offset, ROMFH_SIZE) <= 0)
goto out; goto error;
/* try to match the first 16 bytes of name */ /* try to match the first 16 bytes of name */
fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE); fslen = romfs_strnlen(dir, offset+ROMFH_SIZE, ROMFH_SIZE);
...@@ -397,23 +398,14 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) ...@@ -397,23 +398,14 @@ romfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
inode = romfs_iget(dir->i_sb, offset); inode = romfs_iget(dir->i_sb, offset);
if (IS_ERR(inode)) { if (IS_ERR(inode)) {
res = PTR_ERR(inode); res = PTR_ERR(inode);
goto out; goto error;
} }
/* success:
* it's a bit funky, _lookup needs to return an error code d_add(dentry, inode);
* (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;
res = 0; res = 0;
d_add (dentry, inode); error:
unlock_kernel();
out: unlock_kernel();
return ERR_PTR(res); return ERR_PTR(res);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment