Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+11 −19
Original line number Diff line number Diff line
@@ -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;
	res = 0;
success:
	d_add(dentry, inode);

out:	unlock_kernel();
	res = 0;
error:
	unlock_kernel();
	return ERR_PTR(res);
}