diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-05-16 16:53:28 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-07-10 23:40:48 -0400 |
commit | 275a5d24bf56b2d9dd4644c54a56366b89a028f1 (patch) | |
tree | 2c429fc9480ef292b8cfdc81be05f3ff2b2c02a5 /fs | |
parent | 75180df2ed467866ada839fe73cf7cc7d75c0a22 (diff) |
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>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/super.c | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 1b555cd41e3b..a2b1af89ca1a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1317,7 +1317,9 @@ static int nfs_compare_super(struct super_block *sb, void *data) | |||
1317 | { | 1317 | { |
1318 | struct nfs_server *server = data, *old = NFS_SB(sb); | 1318 | struct nfs_server *server = data, *old = NFS_SB(sb); |
1319 | 1319 | ||
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) | ||
1321 | return 0; | 1323 | return 0; |
1322 | /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */ | 1324 | /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */ |
1323 | if (old->flags & NFS_MOUNT_UNSHARED) | 1325 | if (old->flags & NFS_MOUNT_UNSHARED) |
@@ -1327,6 +1329,39 @@ static int nfs_compare_super(struct super_block *sb, void *data) | |||
1327 | return 1; | 1329 | return 1; |
1328 | } | 1330 | } |
1329 | 1331 | ||
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 | |||
1330 | static int nfs_get_sb(struct file_system_type *fs_type, | 1365 | static int nfs_get_sb(struct file_system_type *fs_type, |
1331 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) | 1366 | int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt) |
1332 | { | 1367 | { |
@@ -1361,8 +1396,11 @@ static int nfs_get_sb(struct file_system_type *fs_type, | |||
1361 | } | 1396 | } |
1362 | 1397 | ||
1363 | if (s->s_fs_info != server) { | 1398 | if (s->s_fs_info != server) { |
1399 | error = nfs_compare_mount_options(s, server, flags); | ||
1364 | nfs_free_server(server); | 1400 | nfs_free_server(server); |
1365 | server = NULL; | 1401 | server = NULL; |
1402 | if (error < 0) | ||
1403 | goto error_splat_super; | ||
1366 | } | 1404 | } |
1367 | 1405 | ||
1368 | if (!s->s_root) { | 1406 | if (!s->s_root) { |
@@ -1442,8 +1480,11 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, | |||
1442 | } | 1480 | } |
1443 | 1481 | ||
1444 | if (s->s_fs_info != server) { | 1482 | if (s->s_fs_info != server) { |
1483 | error = nfs_compare_mount_options(s, server, flags); | ||
1445 | nfs_free_server(server); | 1484 | nfs_free_server(server); |
1446 | server = NULL; | 1485 | server = NULL; |
1486 | if (error < 0) | ||
1487 | goto error_splat_super; | ||
1447 | } | 1488 | } |
1448 | 1489 | ||
1449 | if (!s->s_root) { | 1490 | if (!s->s_root) { |