linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: linux-fsdevel@vger.kernel.org
Cc: linux-mtd@lists.infradead.org, Jan Kara <jack@suse.com>,
	Richard Weinberger <richard@nod.at>,
	kernel@pengutronix.de, Sascha Hauer <s.hauer@pengutronix.de>
Subject: [PATCH 04/11] fs, quota: introduce wait_super_thawed() to wait until a superblock is thawed
Date: Wed, 14 Aug 2019 14:18:27 +0200	[thread overview]
Message-ID: <20190814121834.13983-5-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20190814121834.13983-1-s.hauer@pengutronix.de>

quota uses three different functions to get a superblock from a
block_device. Instead, retrieve the superblock always with get_super()
and introduce wait_super_thawed() which is then used to wait until the
superblock is thawed. This way the code can better be shared with the
code introduced in the next step: We want to add quota support for
filesystems without a block_device, so here functions around a
block_device can't be used.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/quota/quota.c   | 30 +++++++++++++++----
 fs/super.c         | 72 +++++++++++++++++-----------------------------
 include/linux/fs.h |  4 +--
 3 files changed, 52 insertions(+), 54 deletions(-)

diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index cb13fb76dbee..64a212576a72 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -791,6 +791,16 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
 	struct block_device *bdev;
 	struct super_block *sb;
 	struct filename *tmp = getname(special);
+	bool thawed = false, exclusive;
+	int ret;
+
+	if (quotactl_cmd_onoff(cmd)) {
+		thawed = true;
+		exclusive = true;
+	} else if (quotactl_cmd_write(cmd)) {
+		thawed = true;
+		exclusive = false;
+	}
 
 	if (IS_ERR(tmp))
 		return ERR_CAST(tmp);
@@ -798,16 +808,24 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
 	putname(tmp);
 	if (IS_ERR(bdev))
 		return ERR_CAST(bdev);
-	if (quotactl_cmd_onoff(cmd))
-		sb = get_super_exclusive_thawed(bdev);
-	else if (quotactl_cmd_write(cmd))
-		sb = get_super_thawed(bdev);
-	else
-		sb = get_super(bdev);
+
 	bdput(bdev);
+
+	sb = get_super(bdev);
 	if (!sb)
 		return ERR_PTR(-ENODEV);
 
+	if (thawed) {
+		ret = wait_super_thawed(sb, exclusive);
+		if (ret) {
+			if (exclusive)
+				drop_super_exclusive(sb);
+			else
+				drop_super(sb);
+			return ERR_PTR(ret);
+		}
+	}
+
 	return sb;
 #else
 	return ERR_PTR(-ENODEV);
diff --git a/fs/super.c b/fs/super.c
index f85d1ea194ae..13380ffcbd8d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -783,61 +783,41 @@ struct super_block *get_super(struct block_device *bdev)
 }
 EXPORT_SYMBOL(get_super);
 
-static struct super_block *__get_super_thawed(struct block_device *bdev,
-					      bool excl)
+/**
+ *	wait_super_thawed - wait for a superblock being thawed
+ *	@sb: superblock to wait for
+ *	@excl: if true, get s_umount semaphore exclusively
+ *
+ * Wait until the superblock is thawed. s_umount semaphore must be released on
+ * entry and will be held when returning.
+ */
+int wait_super_thawed(struct super_block *sb, bool excl)
 {
-	struct super_block *s = __get_super(bdev, excl);
-	if (!s)
-		return NULL;
+	up_read(&sb->s_umount);
 
 	while (1) {
-		if (s->s_writers.frozen == SB_UNFROZEN)
-			return s;
-
-		if (!excl)
-			up_read(&s->s_umount);
+		if (excl)
+			down_write(&sb->s_umount);
 		else
-			up_write(&s->s_umount);
+			down_read(&sb->s_umount);
 
-		wait_event(s->s_writers.wait_unfrozen,
-			   s->s_writers.frozen == SB_UNFROZEN);
+		/* still alive? */
+		if (!sb->s_root || !(sb->s_flags & SB_BORN))
+			return -ENODEV;
 
-		if (!excl)
-			down_read(&sb->s_umount);
-		else
-			down_write(&sb->s_umount);
-	}
-}
+		if (sb->s_writers.frozen == SB_UNFROZEN)
+			return 0;
 
-/**
- *	get_super_thawed - get thawed superblock of a device
- *	@bdev: device to get the superblock for
- *
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device. The superblock is returned once it is thawed
- *	(or immediately if it was not frozen). %NULL is returned if no match
- *	is found.
- */
-struct super_block *get_super_thawed(struct block_device *bdev)
-{
-	return __get_super_thawed(bdev, false);
-}
-EXPORT_SYMBOL(get_super_thawed);
+		if (excl)
+			up_write(&sb->s_umount);
+		else
+			up_read(&sb->s_umount);
 
-/**
- *	get_super_exclusive_thawed - get thawed superblock of a device
- *	@bdev: device to get the superblock for
- *
- *	Scans the superblock list and finds the superblock of the file system
- *	mounted on the device. The superblock is returned once it is thawed
- *	(or immediately if it was not frozen) and s_umount semaphore is held
- *	in exclusive mode. %NULL is returned if no match is found.
- */
-struct super_block *get_super_exclusive_thawed(struct block_device *bdev)
-{
-	return __get_super_thawed(bdev, true);
+		wait_event(sb->s_writers.wait_unfrozen,
+			   sb->s_writers.frozen == SB_UNFROZEN);
+	}
 }
-EXPORT_SYMBOL(get_super_exclusive_thawed);
+EXPORT_SYMBOL(wait_super_thawed);
 
 /**
  * get_active_super - get an active reference to the superblock of a device
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 997a530ff4e9..59d9ea62942a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3220,9 +3220,9 @@ extern struct file_system_type *get_filesystem(struct file_system_type *fs);
 extern void put_filesystem(struct file_system_type *fs);
 extern struct file_system_type *get_fs_type(const char *name);
 extern struct super_block *get_super(struct block_device *);
-extern struct super_block *get_super_thawed(struct block_device *);
-extern struct super_block *get_super_exclusive_thawed(struct block_device *bdev);
+extern int wait_super_thawed(struct super_block *sb, bool excl);
 extern struct super_block *get_active_super(struct block_device *bdev);
+extern int super_wait_thawed(struct super_block *sb, bool excl);
 extern void drop_super(struct super_block *sb);
 extern void drop_super_exclusive(struct super_block *sb);
 extern void iterate_supers(void (*)(struct super_block *, void *), void *);
-- 
2.20.1


  parent reply	other threads:[~2019-08-14 12:18 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-14 12:18 [PATCH 00/11] Add quota support to UBIFS Sascha Hauer
2019-08-14 12:18 ` [PATCH 01/11] quota: Make inode optional Sascha Hauer
2019-08-14 12:18 ` [PATCH 02/11] quota: Only module_put the format when existing Sascha Hauer
2019-08-15 11:18   ` Jan Kara
2019-08-16 11:49     ` Sascha Hauer
2019-08-14 12:18 ` [PATCH 03/11] fs: move __get_super() out of loop Sascha Hauer
2019-08-14 23:32   ` Al Viro
2019-08-14 12:18 ` Sascha Hauer [this message]
2019-08-14 23:35   ` [PATCH 04/11] fs, quota: introduce wait_super_thawed() to wait until a superblock is thawed Al Viro
2019-08-14 12:18 ` [PATCH 05/11] quota: Allow to pass quotactl a mountpoint Sascha Hauer
2019-08-14 22:42   ` kbuild test robot
2019-08-14 23:33   ` kbuild test robot
2019-08-14 23:36   ` Al Viro
2019-08-14 23:39     ` Al Viro
2019-08-14 23:51       ` Al Viro
2019-08-15  9:53         ` Jan Kara
2019-08-15  7:46       ` Sascha Hauer
2019-08-14 12:18 ` [PATCH 06/11] ubifs: move checks and preparation into setflags() Sascha Hauer
2019-08-14 12:18 ` [PATCH 07/11] ubifs: Add support for FS_IOC_FS[SG]ETXATTR ioctls Sascha Hauer
2019-08-14 14:11   ` Mainz, Roland
2019-08-15  7:31     ` Sascha Hauer
2019-08-14 12:18 ` [PATCH 08/11] ubifs: do not ubifs_inode() on potentially NULL pointer Sascha Hauer
2019-08-14 12:18 ` [PATCH 09/11] ubifs: Add support for project id Sascha Hauer
2019-08-14 12:18 ` [PATCH 10/11] ubifs: export get_znode Sascha Hauer
2019-08-14 12:18 ` [PATCH 11/11] ubifs: Add quota support Sascha Hauer
2019-08-15 11:17   ` Jan Kara

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=20190814121834.13983-5-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=jack@suse.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).