[PATCH OLK-5.10] cachefiles: Fix non-taking of sb_writers around set/removexattr

From: David Howells <dhowells@redhat.com> stable inclusion from stable-v6.6.54 commit 81b048b9484bf8b3c0ad6e901a6b79fb941173b0 category: bugfix bugzilla: 190608 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- [ Upstream commit 80887f31672970abae3aaa9cf62ac72a124e7c89 ] Unlike other vfs_xxxx() calls, vfs_setxattr() and vfs_removexattr() don't take the sb_writers lock, so the caller should do it for them. Fix cachefiles to do this. Fixes: 9ae326a69004 ("CacheFiles: A cache that backs onto a mounted filesystem") Signed-off-by: David Howells <dhowells@redhat.com> cc: Christian Brauner <brauner@kernel.org> cc: Gao Xiang <xiang@kernel.org> cc: netfs@lists.linux.dev cc: linux-erofs@lists.ozlabs.org cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/20240814203850.2240469-3-dhowells@redhat.com/ # v2 Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> Conflicts: fs/cachefiles/internal.h fs/cachefiles/bind.c fs/cachefiles/xattr.c [The code has changed and relevant adaptations have been made.] Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- fs/cachefiles/bind.c | 2 +- fs/cachefiles/internal.h | 3 +- fs/cachefiles/xattr.c | 69 +++++++++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index 3a88bef9ed4b..8c84bfcde991 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -206,7 +206,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) fsdef->dentry = cachedir; fsdef->fscache.cookie = NULL; - ret = cachefiles_check_object_type(fsdef); + ret = cachefiles_check_object_type(fsdef, cache); if (ret < 0) goto error_unsupported; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 97c4b4c639b4..96d96926017e 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -368,7 +368,8 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache, /* * xattr.c */ -extern int cachefiles_check_object_type(struct cachefiles_object *object); +extern int cachefiles_check_object_type(struct cachefiles_object *object, + struct cachefiles_cache *cache); extern int cachefiles_set_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata); extern int cachefiles_update_object_xattr(struct cachefiles_object *object, diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c index 4aadace026d2..bac55fc7359e 100644 --- a/fs/cachefiles/xattr.c +++ b/fs/cachefiles/xattr.c @@ -45,7 +45,8 @@ static int cachefiles_check_new_obj_xattr(struct cachefiles_object *object); * check the type label on an object * - done using xattrs */ -int cachefiles_check_object_type(struct cachefiles_object *object) +int cachefiles_check_object_type(struct cachefiles_object *object, + struct cachefiles_cache *cache) { struct dentry *dentry = object->dentry; char type[3], xtype[3]; @@ -62,8 +63,12 @@ int cachefiles_check_object_type(struct cachefiles_object *object) _enter("%p{%s}", object, type); /* attempt to install a type label directly */ - ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2, - XATTR_CREATE); + ret = mnt_want_write(cache->mnt); + if (ret == 0) { + ret = vfs_setxattr(dentry, cachefiles_xattr_cache, type, 2, + XATTR_CREATE); + mnt_drop_write(cache->mnt); + } if (ret == 0) { _debug("SET"); /* we succeeded */ goto error; @@ -123,6 +128,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct dentry *dentry = object->dentry; + struct cachefiles_cache *cache; int ret; ASSERT(dentry); @@ -132,15 +138,22 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object, /* attempt to install the cache metadata directly */ _debug("SET #%u", auxdata->len); + cache = container_of(object->fscache.cache, + struct cachefiles_cache, cache); + clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); - if (data_new_version(object->fscache.cookie)) - ret = cachefiles_set_new_obj_xattr(object); - else if (volume_new_version(object->fscache.cookie)) - ret = cachefiles_set_new_vol_xattr(object); - else - ret = vfs_setxattr(dentry, cachefiles_xattr_cache, - &auxdata->type, auxdata->len, - XATTR_CREATE); + ret = mnt_want_write(cache->mnt); + if (ret == 0) { + if (data_new_version(object->fscache.cookie)) + ret = cachefiles_set_new_obj_xattr(object); + else if (volume_new_version(object->fscache.cookie)) + ret = cachefiles_set_new_vol_xattr(object); + else + ret = vfs_setxattr(dentry, cachefiles_xattr_cache, + &auxdata->type, auxdata->len, + XATTR_CREATE); + mnt_drop_write(cache->mnt); + } if (ret < 0 && ret != -ENOMEM) cachefiles_io_error_obj( object, @@ -157,6 +170,7 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct dentry *dentry = object->dentry; + struct cachefiles_cache *cache; int ret; if (!dentry) @@ -167,10 +181,17 @@ int cachefiles_update_object_xattr(struct cachefiles_object *object, /* attempt to install the cache metadata directly */ _debug("SET #%u", auxdata->len); + cache = container_of(object->fscache.cache, + struct cachefiles_cache, cache); + clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags); - ret = vfs_setxattr(dentry, cachefiles_xattr_cache, - &auxdata->type, auxdata->len, - XATTR_REPLACE); + ret = mnt_want_write(cache->mnt); + if (ret == 0) { + ret = vfs_setxattr(dentry, cachefiles_xattr_cache, + &auxdata->type, auxdata->len, + XATTR_REPLACE); + mnt_drop_write(cache->mnt); + } if (ret < 0 && ret != -ENOMEM) cachefiles_io_error_obj( object, @@ -222,6 +243,7 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object, struct cachefiles_xattr *auxdata) { struct cachefiles_xattr *auxbuf; + struct cachefiles_cache *cache; unsigned int len = sizeof(struct cachefiles_xattr) + 512; struct dentry *dentry = object->dentry; int ret; @@ -279,10 +301,17 @@ int cachefiles_check_old_object_xattr(struct cachefiles_object *object, BUG(); } + cache = container_of(object->fscache.cache, + struct cachefiles_cache, cache); + /* update the current label */ - ret = vfs_setxattr(dentry, cachefiles_xattr_cache, - &auxdata->type, auxdata->len, - XATTR_REPLACE); + ret = mnt_want_write(cache->mnt); + if (ret == 0) { + ret = vfs_setxattr(dentry, cachefiles_xattr_cache, + &auxdata->type, auxdata->len, + XATTR_REPLACE); + mnt_drop_write(cache->mnt); + } if (ret < 0) { cachefiles_io_error_obj(object, "Can't update xattr on %lu" @@ -364,7 +393,11 @@ int cachefiles_remove_object_xattr(struct cachefiles_cache *cache, { int ret; - ret = vfs_removexattr(dentry, cachefiles_xattr_cache); + ret = mnt_want_write(cache->mnt); + if (ret == 0) { + ret = vfs_removexattr(dentry, cachefiles_xattr_cache); + mnt_drop_write(cache->mnt); + } if (ret < 0) { if (ret == -ENOENT || ret == -ENODATA) ret = 0; -- 2.39.2

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... 失败原因:同步源码仓代码到fork仓失败 建议解决方法:请稍等,机器人会在下一次任务重新执行 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... Failed Reason: sync origin kernel's codes to the fork repository failed Suggest Solution: please wait, the bot will retry in the next interval

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... 失败原因:同步源码仓代码到fork仓失败 建议解决方法:请稍等,机器人会在下一次任务重新执行 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... Failed Reason: sync origin kernel's codes to the fork repository failed Suggest Solution: please wait, the bot will retry in the next interval

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... 失败原因:同步源码仓代码到fork仓失败 建议解决方法:请稍等,机器人会在下一次任务重新执行 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... Failed Reason: sync origin kernel's codes to the fork repository failed Suggest Solution: please wait, the bot will retry in the next interval

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... 失败原因:同步源码仓代码到fork仓失败 建议解决方法:请稍等,机器人会在下一次任务重新执行 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... Failed Reason: sync origin kernel's codes to the fork repository failed Suggest Solution: please wait, the bot will retry in the next interval

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,转换为PR失败! 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... 失败原因:同步源码仓代码到fork仓失败 建议解决方法:请稍等,机器人会在下一次任务重新执行 FeedBack: The patch(es) which you have sent to kernel@openeuler.org has been converted to PR failed! Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/FNV... Failed Reason: sync origin kernel's codes to the fork repository failed Suggest Solution: please wait, the bot will retry in the next interval
participants (2)
-
patchwork bot
-
Zizhi Wo