lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Wed, 14 Apr 2021 21:47:36 +0800 From: Zhang Yi <yi.zhang@...wei.com> To: <linux-ext4@...r.kernel.org> CC: <linux-fsdevel@...r.kernel.org>, <tytso@....edu>, <adilger.kernel@...ger.ca>, <jack@...e.cz>, <yi.zhang@...wei.com>, <yukuai3@...wei.com> Subject: [RFC PATCH v2 6/7] fs: introduce a usage count into the superblock Commit <87d8fe1ee6b8> ("add releasepage hooks to block devices which can be used by file systems") introduce a hook that used by ext4 filesystem to release journal buffers, but it doesn't add corresponding concurrency protection that ->bdev_try_to_free_page() could be raced by umount filesystem concurrently. This patch add a usage count on superblock that filesystem can use it to prevent above race and make invoke ->bdev_try_to_free_page() safe. Signed-off-by: Zhang Yi <yi.zhang@...wei.com> --- include/linux/fs.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index ec8f3ddf4a6a..3c6a5c08c2df 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -41,6 +41,7 @@ #include <linux/stddef.h> #include <linux/mount.h> #include <linux/cred.h> +#include <linux/percpu-refcount.h> #include <asm/byteorder.h> #include <uapi/linux/fs.h> @@ -1547,6 +1548,13 @@ struct super_block { spinlock_t s_inode_wblist_lock; struct list_head s_inodes_wb; /* writeback inodes */ + + /* + * Count users who are using the super_block, used to protect + * umount filesystem concurrently with others. + */ + struct percpu_ref s_usage_counter; + wait_queue_head_t s_usage_waitq; } __randomize_layout; /* Helper functions so that in most cases filesystems will @@ -1765,6 +1773,27 @@ static inline bool sb_start_intwrite_trylock(struct super_block *sb) bool inode_owner_or_capable(struct user_namespace *mnt_userns, const struct inode *inode); +static inline void sb_usage_counter_release(struct percpu_ref *ref) +{ + struct super_block *sb; + + sb = container_of(ref, struct super_block, s_usage_counter); + wake_up(&sb->s_usage_waitq); +} + +static inline int sb_usage_counter_init(struct super_block *sb) +{ + init_waitqueue_head(&sb->s_usage_waitq); + return percpu_ref_init(&sb->s_usage_counter, sb_usage_counter_release, + 0, GFP_KERNEL); +} + +static inline void sb_usage_counter_wait(struct super_block *sb) +{ + percpu_ref_kill(&sb->s_usage_counter); + wait_event(sb->s_usage_waitq, percpu_ref_is_zero(&sb->s_usage_counter)); +} + /* * VFS helper functions.. */ -- 2.25.4
Powered by blists - more mailing lists