Li Lingfeng (2): nfs: pass flags to second superblock nfs: ignore SB_RDONLY when mounting nfs
fs/nfs/internal.h | 2 +- fs/nfs/nfs4super.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/13879 邮件列表地址:https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/A...
FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/13879 Mailing list address: https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/A...
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB42W1
--------------------------------
During the process of mounting an NFSv4 client, two superblocks will be created in sequence. The first superblock corresponds to the root directory exported by the server, and the second superblock corresponds to the directory that will be actually mounted. The first superblock will eventually be destroyed. The flag passed from user mode will only be passed to the first superblock, resulting in the actual used superblock not carrying the flag passed from user mode(fs_context_for_submount() will set sb_flags as 0).
Since the superblock of NFS does not carry the ro tag, the file system status displayed by /proc/self/mountstats shows that NFS is always in the rw state, which may mislead users.
Pass sb_flags of the fc which carry flags passed by user to second superblock to fix it.
Fixes: 281cad46b34d ("NFS: Create a submount rpc_op") Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- fs/nfs/nfs4super.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index e7a10f5f5405..886be9cc0016 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -253,6 +253,8 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
res = nfs_follow_remote_path(root_mnt, export_path);
+ if (!IS_ERR(res)) + res->d_sb->s_flags = flags; dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n", PTR_ERR_OR_ZERO(res), IS_ERR(res) ? " [error]" : "");
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB42W1
--------------------------------
When exporting only one file system with fsid=0 on the server side, the client alternately uses the ro/rw mount options to perform the mount operation, and a new vfsmount is generated each time.
It can be reproduced as follows: [root@localhost ~]# mount /dev/sda /mnt2 [root@localhost ~]# echo "/mnt2 *(rw,no_root_squash,fsid=0)" >/etc/exports [root@localhost ~]# systemctl restart nfs-server [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o ro,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount -t nfs -o rw,vers=4 127.0.0.1:/ /mnt/sdaa [root@localhost ~]# mount | grep nfs4 127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (ro,relatime,vers=4.2,rsize=1048576,... 127.0.0.1:/ on /mnt/sdaa type nfs4 (rw,relatime,vers=4.2,rsize=1048576,... [root@localhost ~]#
We expected that after mounting with the ro option, using the rw option to mount again would return EBUSY, but the actual situation was not the case.
As shown above, when mounting for the first time, a superblock with the ro flag will be generated, and at the same time, in do_new_mount_fc --> do_add_mount, it detects that the superblock corresponding to the current target directory is inconsistent with the currently generated one (path->mnt->mnt_sb != newmnt->mnt.mnt_sb), and a new vfsmount will be generated.
When mounting with the rw option for the second time, since no matching superblock can be found in the fs_supers list, a new superblock with the rw flag will be generated again. The superblock in use (ro) is different from the newly generated superblock (rw), and a new vfsmount will be generated again.
When mounting with the ro option for the third time, the superblock (ro) is found in fs_supers, the superblock in use (rw) is different from the found superblock (ro), and a new vfsmount will be generated again.
We can switch between ro/rw through remount, and only one superblock needs to be generated, thus avoiding the problem of repeated generation of vfsmount caused by switching superblocks.
Furthermore, This can also resolve the issue described in the link.
Fixes: 275a5d24bf56 ("NFS: Error when mounting the same filesystem with different options") Link: https://lore.kernel.org/all/20240604112636.236517-3-lilingfeng@huaweicloud.c... Signed-off-by: Li Lingfeng lilingfeng3@huawei.com --- fs/nfs/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 0ce5a90640c4..ad938771813c 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -10,7 +10,7 @@ #include <linux/nfs_page.h> #include <linux/wait_bit.h>
-#define NFS_MS_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS) +#define NFS_MS_MASK (SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
extern const struct export_operations nfs_export_ops;