From: Li Lingfeng <lilingfeng3@xxxxxxxxxx> 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). If the 'ro' parameter is used in two consecutive mount commands, only the first execution will create a new vfsmount, and the kernel will return EBUSY on the second execution. However, if a remount command with the 'ro' parameter is executed between the two mount commands, both mount commands will create new vfsmounts. The superblock generated after the first mount command does not have the 'ro' flag, and the read-only status of the file system is implemented by checking the read-only flag of the vfsmount. After executing the remount command, the 'ro' flag will be added to the superblock. When the second mount command is executed, the comparison result between the superblock with the 'ro' flag and the fs_context without the flag in the nfs_compare_mount_options() function will be different, resulting in the creation of a new vfsmount. This problem can be reproduced by performing the following operations: mount -t nfs -o ro,vers=4.0 192.168.240.250:/sdb /mnt/sdb mount -t nfs -o remount,ro,vers=4.0 192.168.240.250:/sdb /mnt/sdb mount -t nfs -o ro,vers=4.0 192.168.240.250:/sdb /mnt/sdb Two vfsmounts are generated: [root@localhost ~]# mount | grep nfs 192.168.240.250:/sdb on /mnt/sdb type nfs4 (ro,relatime,vers=4.0, rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2, sec=sys,clientaddr=192.168.240.251,local_lock=none,addr=192.168.240.250) 192.168.240.250:/sdb on /mnt/sdb type nfs4 (ro,relatime,vers=4.0, rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2, sec=sys,clientaddr=192.168.240.251,local_lock=none,addr=192.168.240.250) Fix this by setting sb_flags to second superblock. Signed-off-by: Li Lingfeng <lilingfeng3@xxxxxxxxxx> --- fs/nfs/namespace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index 887aeacedebd..8b3d75af60d4 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c @@ -158,7 +158,7 @@ struct vfsmount *nfs_d_automount(struct path *path, unsigned int sb_flags) /* Open a new filesystem context, transferring parameters from the * parent superblock, including the network namespace. */ - fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry, 0); + fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry, sb_flags); if (IS_ERR(fc)) return ERR_CAST(fc); -- 2.39.2