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
next prev 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).