All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@sgi.com>
To: torvalds@transmeta.com
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH] stale bdev reference in quotactl
Date: Wed, 15 Jan 2003 22:42:48 -0500	[thread overview]
Message-ID: <20030115224248.A8753@sgi.com> (raw)

sys_quotacl tries to do a get_super on a struct block_device * to which
it doesn't hold a reference (nor does it actually have to be non-NULL).

As lookup bdev by name is a rather common operation I splitted out a new
helper, lookup_bdev() that does this out of open_bdev_excl and switched
quota.c to use it.  lookup_bdev() holds a proper reference that needs
to be dropped by bdput(), and it's well documented.


--- 1.121/fs/block_dev.c	Tue Jan  7 23:52:26 2003
+++ edited/fs/block_dev.c	Wed Jan 15 20:51:33 2003
@@ -799,24 +799,20 @@
 }
 
 /**
- * open_bdev_excl  -  open a block device by name and set it up for use
+ * lookup_bdev  - lookup a struct block_device by name
  *
  * @path:	special file representing the block device
- * @flags:	%MS_RDONLY for opening read-only
- * @kind:	usage (same as the 4th paramter to blkdev_get)
- * @holder:	owner for exclusion
  *
- * Open the blockdevice described by the special file at @path, claim it
- * for the @holder and properly set it up for @kind usage.
+ * Get a reference to the blockdevice at @path in the current
+ * namespace if possible and return it.  Return ERR_PTR(error)
+ * otherwise.
  */
-struct block_device *open_bdev_excl(const char *path, int flags,
-				    int kind, void *holder)
+struct block_device *lookup_bdev(const char *path)
 {
-	struct inode *inode;
 	struct block_device *bdev;
+	struct inode *inode;
 	struct nameidata nd;
-	mode_t mode = FMODE_READ;
-	int error = 0;
+	int error;
 
 	if (!path || !*path)
 		return ERR_PTR(-EINVAL);
@@ -828,17 +824,44 @@
 	inode = nd.dentry->d_inode;
 	error = -ENOTBLK;
 	if (!S_ISBLK(inode->i_mode))
-		goto path_release;
+		goto fail;
 	error = -EACCES;
 	if (nd.mnt->mnt_flags & MNT_NODEV)
-		goto path_release;
+		goto fail;
 	error = bd_acquire(inode);
 	if (error)
-		goto path_release;
+		goto fail;
 	bdev = inode->i_bdev;
 
-	/* Done with lookups */
+out:
 	path_release(&nd);
+	return bdev;
+fail:
+	bdev = ERR_PTR(error);
+	goto out;
+}
+
+/**
+ * open_bdev_excl  -  open a block device by name and set it up for use
+ *
+ * @path:	special file representing the block device
+ * @flags:	%MS_RDONLY for opening read-only
+ * @kind:	usage (same as the 4th paramter to blkdev_get)
+ * @holder:	owner for exclusion
+ *
+ * Open the blockdevice described by the special file at @path, claim it
+ * for the @holder and properly set it up for @kind usage.
+ */
+struct block_device *open_bdev_excl(const char *path, int flags,
+				    int kind, void *holder)
+{
+	struct block_device *bdev;
+	mode_t mode = FMODE_READ;
+	int error = 0;
+
+	bdev = lookup_bdev(path);
+	if (IS_ERR(bdev))
+		return bdev;
 
 	if (!(flags & MS_RDONLY))
 		mode |= FMODE_WRITE;
@@ -856,10 +879,6 @@
 	
 blkdev_put:
 	blkdev_put(bdev, BDEV_FS);
-	return ERR_PTR(error);
-
-path_release:
-	path_release(&nd);
 	return ERR_PTR(error);
 }
 
--- 1.10/fs/quota.c	Wed Jan  1 03:44:36 2003
+++ edited/fs/quota.c	Wed Jan 15 20:51:33 2003
@@ -102,35 +102,6 @@
 	return security_quotactl (cmd, type, id, sb);
 }
 
-/* Resolve device pathname to superblock */
-static struct super_block *resolve_dev(const char *path)
-{
-	int ret;
-	mode_t mode;
-	struct nameidata nd;
-	struct block_device *bdev;
-	struct super_block *sb;
-
-	ret = user_path_walk(path, &nd);
-	if (ret)
-		goto out;
-
-	bdev = nd.dentry->d_inode->i_bdev;
-	mode = nd.dentry->d_inode->i_mode;
-	path_release(&nd);
-
-	ret = -ENOTBLK;
-	if (!S_ISBLK(mode))
-		goto out;
-	ret = -ENODEV;
-	sb = get_super(bdev);
-	if (!sb)
-		goto out;
-	return sb;
-out:
-	return ERR_PTR(ret);
-}
-
 /* Copy parameters and call proper function */
 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
 {
@@ -249,21 +220,24 @@
 {
 	uint cmds, type;
 	struct super_block *sb = NULL;
-	int ret = -EINVAL;
+	struct block_device *bdev;
+	int ret = -ENODEV;
 
 	cmds = cmd >> SUBCMDSHIFT;
 	type = cmd & SUBCMDMASK;
 
-	if (IS_ERR(sb = resolve_dev(special))) {
-		ret = PTR_ERR(sb);
-		sb = NULL;
-		goto out;
-	}
-	if ((ret = check_quotactl_valid(sb, type, cmds, id)) < 0)
-		goto out;
-	ret = do_quotactl(sb, type, cmds, id, addr);
-out:
-	if (sb)
+	bdev = lookup_bdev(special);
+	if (IS_ERR(bdev))
+		return PTR_ERR(bdev);
+	sb = get_super(bdev);
+	bdput(bdev);
+
+	if (sb) {
+		ret = check_quotactl_valid(sb, type, cmds, id);
+		if (ret >= 0)
+			ret = do_quotactl(sb, type, cmds, id, addr);
 		drop_super(sb);
+	}
+
 	return ret;
 }
--- 1.210/include/linux/fs.h	Wed Jan  8 21:37:23 2003
+++ edited/include/linux/fs.h	Wed Jan 15 20:51:33 2003
@@ -1103,6 +1100,7 @@
 {
 	return __bdevname(bdev->bd_dev);
 }
+extern struct block_device *lookup_bdev(const char *);
 extern struct block_device *open_bdev_excl(const char *, int, int, void *);
 extern void close_bdev_excl(struct block_device *, int);
 

                 reply	other threads:[~2003-01-16  3:42 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030115224248.A8753@sgi.com \
    --to=hch@sgi.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.