Skip to content

Commit 275a5d2

Browse files
Trond MyklebustTrond Myklebust
authored andcommitted
NFS: Error when mounting the same filesystem with different options
Unless the user sets the NFS_MOUNT_NOSHAREDCACHE mount flag, we should return EBUSY if the filesystem is already mounted on a superblock that has set conflicting mount options. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
1 parent 75180df commit 275a5d2

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

fs/nfs/super.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,9 @@ static int nfs_compare_super(struct super_block *sb, void *data)
13171317
{
13181318
struct nfs_server *server = data, *old = NFS_SB(sb);
13191319

1320-
if (old->nfs_client != server->nfs_client)
1320+
if (memcmp(&old->nfs_client->cl_addr,
1321+
&server->nfs_client->cl_addr,
1322+
sizeof(old->nfs_client->cl_addr)) != 0)
13211323
return 0;
13221324
/* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
13231325
if (old->flags & NFS_MOUNT_UNSHARED)
@@ -1327,6 +1329,39 @@ static int nfs_compare_super(struct super_block *sb, void *data)
13271329
return 1;
13281330
}
13291331

1332+
#define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
1333+
1334+
static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
1335+
{
1336+
const struct nfs_server *a = s->s_fs_info;
1337+
const struct rpc_clnt *clnt_a = a->client;
1338+
const struct rpc_clnt *clnt_b = b->client;
1339+
1340+
if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK))
1341+
goto Ebusy;
1342+
if (a->nfs_client != b->nfs_client)
1343+
goto Ebusy;
1344+
if (a->flags != b->flags)
1345+
goto Ebusy;
1346+
if (a->wsize != b->wsize)
1347+
goto Ebusy;
1348+
if (a->rsize != b->rsize)
1349+
goto Ebusy;
1350+
if (a->acregmin != b->acregmin)
1351+
goto Ebusy;
1352+
if (a->acregmax != b->acregmax)
1353+
goto Ebusy;
1354+
if (a->acdirmin != b->acdirmin)
1355+
goto Ebusy;
1356+
if (a->acdirmax != b->acdirmax)
1357+
goto Ebusy;
1358+
if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
1359+
goto Ebusy;
1360+
return 0;
1361+
Ebusy:
1362+
return -EBUSY;
1363+
}
1364+
13301365
static int nfs_get_sb(struct file_system_type *fs_type,
13311366
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
13321367
{
@@ -1361,8 +1396,11 @@ static int nfs_get_sb(struct file_system_type *fs_type,
13611396
}
13621397

13631398
if (s->s_fs_info != server) {
1399+
error = nfs_compare_mount_options(s, server, flags);
13641400
nfs_free_server(server);
13651401
server = NULL;
1402+
if (error < 0)
1403+
goto error_splat_super;
13661404
}
13671405

13681406
if (!s->s_root) {
@@ -1442,8 +1480,11 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
14421480
}
14431481

14441482
if (s->s_fs_info != server) {
1483+
error = nfs_compare_mount_options(s, server, flags);
14451484
nfs_free_server(server);
14461485
server = NULL;
1486+
if (error < 0)
1487+
goto error_splat_super;
14471488
}
14481489

14491490
if (!s->s_root) {

0 commit comments

Comments
 (0)