aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-07-18 03:12:36 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:59:28 -0400
commit62a877e35d5085c65936ed3194d1bbaf84f419e1 (patch)
tree76f16d460d8eec4f1d39bb533167e591bb6113c6
parentdeeb5912db12e8b7ccf3f4b1afaad60bc29abed9 (diff)
[XFS] fix mount option parsing in remount
Remount currently happily accept any option thrown at it, although the only filesystem specific option it actually handles is barrier/nobarrier. And it actually doesn't handle these correctly either because it only uses the value it parsed when we're doing a ro->rw transition. In addition to that there's also a bad bug in xfs_parseargs which doesn't touch the actual option in the mount point except for a single one, XFS_MOUNT_SMALL_INUMS and thus forced any filesystem that's every remounted in some way to not support 64bit inodes with no way to recover unless unmounted. This patch changes xfs_fs_remount to use it's own linux/parser.h based options parse instead of xfs_parseargs and reject all options except for barrier/nobarrier and to the right thing in general. Eventually I'd like to have a single big option table used for mount aswell but that can wait for a while. SGI-PV: 983964 SGI-Modid: xfs-linux-melb:xfs-kern:31382a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c72
1 files changed, 54 insertions, 18 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index fcb4931902ac..b40086680047 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -66,6 +66,7 @@
66#include <linux/writeback.h> 66#include <linux/writeback.h>
67#include <linux/kthread.h> 67#include <linux/kthread.h>
68#include <linux/freezer.h> 68#include <linux/freezer.h>
69#include <linux/parser.h>
69 70
70static struct quotactl_ops xfs_quotactl_operations; 71static struct quotactl_ops xfs_quotactl_operations;
71static struct super_operations xfs_super_operations; 72static struct super_operations xfs_super_operations;
@@ -147,6 +148,23 @@ xfs_args_allocate(
147#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */ 148#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
148#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */ 149#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
149 150
151/*
152 * Table driven mount option parser.
153 *
154 * Currently only used for remount, but it will be used for mount
155 * in the future, too.
156 */
157enum {
158 Opt_barrier, Opt_nobarrier, Opt_err
159};
160
161static match_table_t tokens = {
162 {Opt_barrier, "barrier"},
163 {Opt_nobarrier, "nobarrier"},
164 {Opt_err, NULL}
165};
166
167
150STATIC unsigned long 168STATIC unsigned long
151suffix_strtoul(char *s, char **endp, unsigned int base) 169suffix_strtoul(char *s, char **endp, unsigned int base)
152{ 170{
@@ -1364,36 +1382,54 @@ xfs_fs_remount(
1364 char *options) 1382 char *options)
1365{ 1383{
1366 struct xfs_mount *mp = XFS_M(sb); 1384 struct xfs_mount *mp = XFS_M(sb);
1367 struct xfs_mount_args *args; 1385 substring_t args[MAX_OPT_ARGS];
1368 int error; 1386 char *p;
1369 1387
1370 args = xfs_args_allocate(sb, 0); 1388 while ((p = strsep(&options, ",")) != NULL) {
1371 if (!args) 1389 int token;
1372 return -ENOMEM;
1373 1390
1374 error = xfs_parseargs(mp, options, args, 1); 1391 if (!*p)
1375 if (error) 1392 continue;
1376 goto out_free_args;
1377 1393
1378 if (!(*flags & MS_RDONLY)) { /* rw/ro -> rw */ 1394 token = match_token(p, tokens, args);
1379 if (mp->m_flags & XFS_MOUNT_RDONLY) 1395 switch (token) {
1380 mp->m_flags &= ~XFS_MOUNT_RDONLY; 1396 case Opt_barrier:
1381 if (args->flags & XFSMNT_BARRIER) {
1382 mp->m_flags |= XFS_MOUNT_BARRIER; 1397 mp->m_flags |= XFS_MOUNT_BARRIER;
1383 xfs_mountfs_check_barriers(mp); 1398
1384 } else { 1399 /*
1400 * Test if barriers are actually working if we can,
1401 * else delay this check until the filesystem is
1402 * marked writeable.
1403 */
1404 if (!(mp->m_flags & XFS_MOUNT_RDONLY))
1405 xfs_mountfs_check_barriers(mp);
1406 break;
1407 case Opt_nobarrier:
1385 mp->m_flags &= ~XFS_MOUNT_BARRIER; 1408 mp->m_flags &= ~XFS_MOUNT_BARRIER;
1409 break;
1410 default:
1411 printk(KERN_INFO
1412 "XFS: mount option \"%s\" not supported for remount\n", p);
1413 return -EINVAL;
1386 } 1414 }
1387 } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */ 1415 }
1416
1417 /* rw/ro -> rw */
1418 if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
1419 mp->m_flags &= ~XFS_MOUNT_RDONLY;
1420 if (mp->m_flags & XFS_MOUNT_BARRIER)
1421 xfs_mountfs_check_barriers(mp);
1422 }
1423
1424 /* rw -> ro */
1425 if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
1388 xfs_filestream_flush(mp); 1426 xfs_filestream_flush(mp);
1389 xfs_sync(mp, SYNC_DATA_QUIESCE); 1427 xfs_sync(mp, SYNC_DATA_QUIESCE);
1390 xfs_attr_quiesce(mp); 1428 xfs_attr_quiesce(mp);
1391 mp->m_flags |= XFS_MOUNT_RDONLY; 1429 mp->m_flags |= XFS_MOUNT_RDONLY;
1392 } 1430 }
1393 1431
1394 out_free_args: 1432 return 0;
1395 kfree(args);
1396 return -error;
1397} 1433}
1398 1434
1399/* 1435/*