diff options
author | Theodore Ts'o <tytso@mit.edu> | 2012-03-03 23:20:47 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-03-03 23:20:47 -0500 |
commit | 26092bf52478d23f872c6531e9e3ea9bde2c66c1 (patch) | |
tree | e32c3dce5d4d82087da6306dc7f4effd3d8c4d31 /fs/ext4 | |
parent | 72578c33c4977941a5094f1d7011c8e1f5c43552 (diff) |
ext4: use a table-driven handler for mount options
By using a table-drive approach, we shave about 100 lines of code from
ext4, and make the code a bit more regular and factored out. This
will also make it possible in a future patch to use this table for
displaying the mount options that were specified in /proc/mounts.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 570 |
1 files changed, 234 insertions, 336 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b5f2e6816ec3..61a65ee2c905 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1509,371 +1509,269 @@ static int clear_qf_name(struct super_block *sb, int qtype) | |||
1509 | } | 1509 | } |
1510 | #endif | 1510 | #endif |
1511 | 1511 | ||
1512 | static int parse_options(char *options, struct super_block *sb, | 1512 | #define MOPT_SET 0x0001 |
1513 | unsigned long *journal_devnum, | 1513 | #define MOPT_CLEAR 0x0002 |
1514 | unsigned int *journal_ioprio, | 1514 | #define MOPT_NOSUPPORT 0x0004 |
1515 | int is_remount) | 1515 | #define MOPT_EXPLICIT 0x0008 |
1516 | { | 1516 | #define MOPT_CLEAR_ERR 0x0010 |
1517 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1517 | #define MOPT_GTE0 0x0020 |
1518 | char *p; | ||
1519 | substring_t args[MAX_OPT_ARGS]; | ||
1520 | int data_opt = 0; | ||
1521 | int option; | ||
1522 | #ifdef CONFIG_QUOTA | 1518 | #ifdef CONFIG_QUOTA |
1523 | int qfmt; | 1519 | #define MOPT_Q 0 |
1520 | #define MOPT_QFMT 0x0040 | ||
1521 | #else | ||
1522 | #define MOPT_Q MOPT_NOSUPPORT | ||
1523 | #define MOPT_QFMT MOPT_NOSUPPORT | ||
1524 | #endif | 1524 | #endif |
1525 | 1525 | #define MOPT_DATAJ 0x0080 | |
1526 | if (!options) | 1526 | |
1527 | return 1; | 1527 | static const struct mount_opts { |
1528 | 1528 | int token; | |
1529 | while ((p = strsep(&options, ",")) != NULL) { | 1529 | int mount_opt; |
1530 | int token; | 1530 | int flags; |
1531 | if (!*p) | 1531 | } ext4_mount_opts[] = { |
1532 | continue; | 1532 | {Opt_minix_df, EXT4_MOUNT_MINIX_DF, MOPT_SET}, |
1533 | 1533 | {Opt_bsd_df, EXT4_MOUNT_MINIX_DF, MOPT_CLEAR}, | |
1534 | /* | 1534 | {Opt_grpid, EXT4_MOUNT_GRPID, MOPT_SET}, |
1535 | * Initialize args struct so we know whether arg was | 1535 | {Opt_nogrpid, EXT4_MOUNT_GRPID, MOPT_CLEAR}, |
1536 | * found; some options take optional arguments. | 1536 | {Opt_mblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_SET}, |
1537 | */ | 1537 | {Opt_nomblk_io_submit, EXT4_MOUNT_MBLK_IO_SUBMIT, MOPT_CLEAR}, |
1538 | args[0].to = args[0].from = NULL; | 1538 | {Opt_block_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_SET}, |
1539 | token = match_token(p, tokens, args); | 1539 | {Opt_noblock_validity, EXT4_MOUNT_BLOCK_VALIDITY, MOPT_CLEAR}, |
1540 | switch (token) { | 1540 | {Opt_dioread_nolock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_SET}, |
1541 | case Opt_bsd_df: | 1541 | {Opt_dioread_lock, EXT4_MOUNT_DIOREAD_NOLOCK, MOPT_CLEAR}, |
1542 | clear_opt(sb, MINIX_DF); | 1542 | {Opt_discard, EXT4_MOUNT_DISCARD, MOPT_SET}, |
1543 | break; | 1543 | {Opt_nodiscard, EXT4_MOUNT_DISCARD, MOPT_CLEAR}, |
1544 | case Opt_minix_df: | 1544 | {Opt_delalloc, EXT4_MOUNT_DELALLOC, MOPT_SET | MOPT_EXPLICIT}, |
1545 | set_opt(sb, MINIX_DF); | 1545 | {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, MOPT_CLEAR | MOPT_EXPLICIT}, |
1546 | break; | 1546 | {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, MOPT_SET}, |
1547 | case Opt_grpid: | 1547 | {Opt_journal_async_commit, (EXT4_MOUNT_JOURNAL_ASYNC_COMMIT | |
1548 | set_opt(sb, GRPID); | 1548 | EXT4_MOUNT_JOURNAL_CHECKSUM), MOPT_SET}, |
1549 | break; | 1549 | {Opt_noload, EXT4_MOUNT_NOLOAD, MOPT_SET}, |
1550 | case Opt_nogrpid: | 1550 | {Opt_err_panic, EXT4_MOUNT_ERRORS_PANIC, MOPT_SET | MOPT_CLEAR_ERR}, |
1551 | clear_opt(sb, GRPID); | 1551 | {Opt_err_ro, EXT4_MOUNT_ERRORS_RO, MOPT_SET | MOPT_CLEAR_ERR}, |
1552 | break; | 1552 | {Opt_err_cont, EXT4_MOUNT_ERRORS_CONT, MOPT_SET | MOPT_CLEAR_ERR}, |
1553 | case Opt_resuid: | 1553 | {Opt_data_err_abort, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_SET}, |
1554 | if (match_int(&args[0], &option)) | 1554 | {Opt_data_err_ignore, EXT4_MOUNT_DATA_ERR_ABORT, MOPT_CLEAR}, |
1555 | return 0; | 1555 | {Opt_barrier, EXT4_MOUNT_BARRIER, MOPT_SET}, |
1556 | sbi->s_resuid = option; | 1556 | {Opt_nobarrier, EXT4_MOUNT_BARRIER, MOPT_CLEAR}, |
1557 | break; | 1557 | {Opt_noauto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_SET}, |
1558 | case Opt_resgid: | 1558 | {Opt_auto_da_alloc, EXT4_MOUNT_NO_AUTO_DA_ALLOC, MOPT_CLEAR}, |
1559 | if (match_int(&args[0], &option)) | 1559 | {Opt_noinit_itable, EXT4_MOUNT_INIT_INODE_TABLE, MOPT_CLEAR}, |
1560 | return 0; | 1560 | {Opt_commit, 0, MOPT_GTE0}, |
1561 | sbi->s_resgid = option; | 1561 | {Opt_max_batch_time, 0, MOPT_GTE0}, |
1562 | break; | 1562 | {Opt_min_batch_time, 0, MOPT_GTE0}, |
1563 | case Opt_sb: | 1563 | {Opt_inode_readahead_blks, 0, MOPT_GTE0}, |
1564 | /* handled by get_sb_block() instead of here */ | 1564 | {Opt_init_itable, 0, MOPT_GTE0}, |
1565 | /* *sb_block = match_int(&args[0]); */ | 1565 | {Opt_stripe, 0, MOPT_GTE0}, |
1566 | break; | 1566 | {Opt_data_journal, EXT4_MOUNT_JOURNAL_DATA, MOPT_DATAJ}, |
1567 | case Opt_err_panic: | 1567 | {Opt_data_ordered, EXT4_MOUNT_ORDERED_DATA, MOPT_DATAJ}, |
1568 | clear_opt(sb, ERRORS_MASK); | 1568 | {Opt_data_writeback, EXT4_MOUNT_WRITEBACK_DATA, MOPT_DATAJ}, |
1569 | set_opt(sb, ERRORS_PANIC); | ||
1570 | break; | ||
1571 | case Opt_err_ro: | ||
1572 | clear_opt(sb, ERRORS_MASK); | ||
1573 | set_opt(sb, ERRORS_RO); | ||
1574 | break; | ||
1575 | case Opt_err_cont: | ||
1576 | clear_opt(sb, ERRORS_MASK); | ||
1577 | set_opt(sb, ERRORS_CONT); | ||
1578 | break; | ||
1579 | case Opt_nouid32: | ||
1580 | set_opt(sb, NO_UID32); | ||
1581 | break; | ||
1582 | case Opt_debug: | ||
1583 | set_opt(sb, DEBUG); | ||
1584 | break; | ||
1585 | case Opt_removed: | ||
1586 | ext4_msg(sb, KERN_WARNING, | ||
1587 | "Ignoring deprecated %s option", p); | ||
1588 | break; | ||
1589 | #ifdef CONFIG_EXT4_FS_XATTR | 1569 | #ifdef CONFIG_EXT4_FS_XATTR |
1590 | case Opt_user_xattr: | 1570 | {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, |
1591 | set_opt(sb, XATTR_USER); | 1571 | {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, |
1592 | break; | ||
1593 | case Opt_nouser_xattr: | ||
1594 | clear_opt(sb, XATTR_USER); | ||
1595 | break; | ||
1596 | #else | 1572 | #else |
1597 | case Opt_user_xattr: | 1573 | {Opt_user_xattr, 0, MOPT_NOSUPPORT}, |
1598 | case Opt_nouser_xattr: | 1574 | {Opt_nouser_xattr, 0, MOPT_NOSUPPORT}, |
1599 | ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported"); | ||
1600 | break; | ||
1601 | #endif | 1575 | #endif |
1602 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 1576 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
1603 | case Opt_acl: | 1577 | {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, |
1604 | set_opt(sb, POSIX_ACL); | 1578 | {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, |
1605 | break; | ||
1606 | case Opt_noacl: | ||
1607 | clear_opt(sb, POSIX_ACL); | ||
1608 | break; | ||
1609 | #else | 1579 | #else |
1610 | case Opt_acl: | 1580 | {Opt_acl, 0, MOPT_NOSUPPORT}, |
1611 | case Opt_noacl: | 1581 | {Opt_noacl, 0, MOPT_NOSUPPORT}, |
1612 | ext4_msg(sb, KERN_ERR, "(no)acl options not supported"); | ||
1613 | break; | ||
1614 | #endif | 1582 | #endif |
1615 | case Opt_journal_dev: | 1583 | {Opt_nouid32, EXT4_MOUNT_NO_UID32, MOPT_SET}, |
1616 | if (is_remount) { | 1584 | {Opt_debug, EXT4_MOUNT_DEBUG, MOPT_SET}, |
1585 | {Opt_quota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, MOPT_SET | MOPT_Q}, | ||
1586 | {Opt_usrquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA, | ||
1587 | MOPT_SET | MOPT_Q}, | ||
1588 | {Opt_grpquota, EXT4_MOUNT_QUOTA | EXT4_MOUNT_GRPQUOTA, | ||
1589 | MOPT_SET | MOPT_Q}, | ||
1590 | {Opt_noquota, (EXT4_MOUNT_QUOTA | EXT4_MOUNT_USRQUOTA | | ||
1591 | EXT4_MOUNT_GRPQUOTA), MOPT_CLEAR | MOPT_Q}, | ||
1592 | {Opt_usrjquota, 0, MOPT_Q}, | ||
1593 | {Opt_grpjquota, 0, MOPT_Q}, | ||
1594 | {Opt_offusrjquota, 0, MOPT_Q}, | ||
1595 | {Opt_offgrpjquota, 0, MOPT_Q}, | ||
1596 | {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT}, | ||
1597 | {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT}, | ||
1598 | {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, | ||
1599 | {Opt_err, 0, 0} | ||
1600 | }; | ||
1601 | |||
1602 | static int handle_mount_opt(struct super_block *sb, char *opt, int token, | ||
1603 | substring_t *args, unsigned long *journal_devnum, | ||
1604 | unsigned int *journal_ioprio, int is_remount) | ||
1605 | { | ||
1606 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1607 | const struct mount_opts *m; | ||
1608 | int arg = 0; | ||
1609 | |||
1610 | if (args->from && match_int(args, &arg)) | ||
1611 | return -1; | ||
1612 | switch (token) { | ||
1613 | case Opt_sb: | ||
1614 | return 1; /* handled by get_sb_block() */ | ||
1615 | case Opt_removed: | ||
1616 | ext4_msg(sb, KERN_WARNING, | ||
1617 | "Ignoring removed %s option", opt); | ||
1618 | return 1; | ||
1619 | case Opt_resuid: | ||
1620 | sbi->s_resuid = arg; | ||
1621 | return 1; | ||
1622 | case Opt_resgid: | ||
1623 | sbi->s_resgid = arg; | ||
1624 | return 1; | ||
1625 | case Opt_abort: | ||
1626 | sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; | ||
1627 | return 1; | ||
1628 | case Opt_i_version: | ||
1629 | sb->s_flags |= MS_I_VERSION; | ||
1630 | return 1; | ||
1631 | case Opt_journal_dev: | ||
1632 | if (is_remount) { | ||
1633 | ext4_msg(sb, KERN_ERR, | ||
1634 | "Cannot specify journal on remount"); | ||
1635 | return -1; | ||
1636 | } | ||
1637 | *journal_devnum = arg; | ||
1638 | return 1; | ||
1639 | case Opt_journal_ioprio: | ||
1640 | if (arg < 0 || arg > 7) | ||
1641 | return -1; | ||
1642 | *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg); | ||
1643 | return 1; | ||
1644 | } | ||
1645 | |||
1646 | for (m = ext4_mount_opts; m->token != Opt_err; m++) { | ||
1647 | if (token != m->token) | ||
1648 | continue; | ||
1649 | if (args->from && (m->flags & MOPT_GTE0) && (arg < 0)) | ||
1650 | return -1; | ||
1651 | if (m->flags & MOPT_EXPLICIT) | ||
1652 | set_opt2(sb, EXPLICIT_DELALLOC); | ||
1653 | if (m->flags & MOPT_CLEAR_ERR) | ||
1654 | clear_opt(sb, ERRORS_MASK); | ||
1655 | if (token == Opt_noquota && sb_any_quota_loaded(sb)) { | ||
1656 | ext4_msg(sb, KERN_ERR, "Cannot change quota " | ||
1657 | "options when quota turned on"); | ||
1658 | return -1; | ||
1659 | } | ||
1660 | |||
1661 | if (m->flags & MOPT_NOSUPPORT) { | ||
1662 | ext4_msg(sb, KERN_ERR, "%s option not supported", opt); | ||
1663 | } else if (token == Opt_commit) { | ||
1664 | if (arg == 0) | ||
1665 | arg = JBD2_DEFAULT_MAX_COMMIT_AGE; | ||
1666 | sbi->s_commit_interval = HZ * arg; | ||
1667 | } else if (token == Opt_max_batch_time) { | ||
1668 | if (arg == 0) | ||
1669 | arg = EXT4_DEF_MAX_BATCH_TIME; | ||
1670 | sbi->s_max_batch_time = arg; | ||
1671 | } else if (token == Opt_min_batch_time) { | ||
1672 | sbi->s_min_batch_time = arg; | ||
1673 | } else if (token == Opt_inode_readahead_blks) { | ||
1674 | if (arg > (1 << 30)) | ||
1675 | return -1; | ||
1676 | if (arg && !is_power_of_2(arg)) { | ||
1617 | ext4_msg(sb, KERN_ERR, | 1677 | ext4_msg(sb, KERN_ERR, |
1618 | "Cannot specify journal on remount"); | 1678 | "EXT4-fs: inode_readahead_blks" |
1619 | return 0; | 1679 | " must be a power of 2"); |
1680 | return -1; | ||
1620 | } | 1681 | } |
1621 | if (match_int(&args[0], &option)) | 1682 | sbi->s_inode_readahead_blks = arg; |
1622 | return 0; | 1683 | } else if (token == Opt_init_itable) { |
1623 | *journal_devnum = option; | 1684 | set_opt(sb, INIT_INODE_TABLE); |
1624 | break; | 1685 | if (!args->from) |
1625 | case Opt_journal_checksum: | 1686 | arg = EXT4_DEF_LI_WAIT_MULT; |
1626 | set_opt(sb, JOURNAL_CHECKSUM); | 1687 | sbi->s_li_wait_mult = arg; |
1627 | break; | 1688 | } else if (token == Opt_stripe) { |
1628 | case Opt_journal_async_commit: | 1689 | sbi->s_stripe = arg; |
1629 | set_opt(sb, JOURNAL_ASYNC_COMMIT); | 1690 | } else if (m->flags & MOPT_DATAJ) { |
1630 | set_opt(sb, JOURNAL_CHECKSUM); | ||
1631 | break; | ||
1632 | case Opt_noload: | ||
1633 | set_opt(sb, NOLOAD); | ||
1634 | break; | ||
1635 | case Opt_commit: | ||
1636 | if (match_int(&args[0], &option)) | ||
1637 | return 0; | ||
1638 | if (option < 0) | ||
1639 | return 0; | ||
1640 | if (option == 0) | ||
1641 | option = JBD2_DEFAULT_MAX_COMMIT_AGE; | ||
1642 | sbi->s_commit_interval = HZ * option; | ||
1643 | break; | ||
1644 | case Opt_max_batch_time: | ||
1645 | if (match_int(&args[0], &option)) | ||
1646 | return 0; | ||
1647 | if (option < 0) | ||
1648 | return 0; | ||
1649 | if (option == 0) | ||
1650 | option = EXT4_DEF_MAX_BATCH_TIME; | ||
1651 | sbi->s_max_batch_time = option; | ||
1652 | break; | ||
1653 | case Opt_min_batch_time: | ||
1654 | if (match_int(&args[0], &option)) | ||
1655 | return 0; | ||
1656 | if (option < 0) | ||
1657 | return 0; | ||
1658 | sbi->s_min_batch_time = option; | ||
1659 | break; | ||
1660 | case Opt_data_journal: | ||
1661 | data_opt = EXT4_MOUNT_JOURNAL_DATA; | ||
1662 | goto datacheck; | ||
1663 | case Opt_data_ordered: | ||
1664 | data_opt = EXT4_MOUNT_ORDERED_DATA; | ||
1665 | goto datacheck; | ||
1666 | case Opt_data_writeback: | ||
1667 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; | ||
1668 | datacheck: | ||
1669 | if (is_remount) { | 1691 | if (is_remount) { |
1670 | if (!sbi->s_journal) | 1692 | if (!sbi->s_journal) |
1671 | ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); | 1693 | ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); |
1672 | else if (test_opt(sb, DATA_FLAGS) != data_opt) { | 1694 | else if (test_opt(sb, DATA_FLAGS) != |
1695 | m->mount_opt) { | ||
1673 | ext4_msg(sb, KERN_ERR, | 1696 | ext4_msg(sb, KERN_ERR, |
1674 | "Cannot change data mode on remount"); | 1697 | "Cannot change data mode on remount"); |
1675 | return 0; | 1698 | return -1; |
1676 | } | 1699 | } |
1677 | } else { | 1700 | } else { |
1678 | clear_opt(sb, DATA_FLAGS); | 1701 | clear_opt(sb, DATA_FLAGS); |
1679 | sbi->s_mount_opt |= data_opt; | 1702 | sbi->s_mount_opt |= m->mount_opt; |
1680 | } | 1703 | } |
1681 | break; | ||
1682 | case Opt_data_err_abort: | ||
1683 | set_opt(sb, DATA_ERR_ABORT); | ||
1684 | break; | ||
1685 | case Opt_data_err_ignore: | ||
1686 | clear_opt(sb, DATA_ERR_ABORT); | ||
1687 | break; | ||
1688 | #ifdef CONFIG_QUOTA | 1704 | #ifdef CONFIG_QUOTA |
1689 | case Opt_usrjquota: | 1705 | } else if (token == Opt_usrjquota) { |
1690 | if (!set_qf_name(sb, USRQUOTA, &args[0])) | 1706 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1691 | return 0; | 1707 | return -1; |
1692 | break; | 1708 | } else if (token == Opt_grpjquota) { |
1693 | case Opt_grpjquota: | ||
1694 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) | 1709 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1695 | return 0; | 1710 | return -1; |
1696 | break; | 1711 | } else if (token == Opt_offusrjquota) { |
1697 | case Opt_offusrjquota: | ||
1698 | if (!clear_qf_name(sb, USRQUOTA)) | 1712 | if (!clear_qf_name(sb, USRQUOTA)) |
1699 | return 0; | 1713 | return -1; |
1700 | break; | 1714 | } else if (token == Opt_offgrpjquota) { |
1701 | case Opt_offgrpjquota: | ||
1702 | if (!clear_qf_name(sb, GRPQUOTA)) | 1715 | if (!clear_qf_name(sb, GRPQUOTA)) |
1703 | return 0; | 1716 | return -1; |
1704 | break; | 1717 | } else if (m->flags & MOPT_QFMT) { |
1705 | |||
1706 | case Opt_jqfmt_vfsold: | ||
1707 | qfmt = QFMT_VFS_OLD; | ||
1708 | goto set_qf_format; | ||
1709 | case Opt_jqfmt_vfsv0: | ||
1710 | qfmt = QFMT_VFS_V0; | ||
1711 | goto set_qf_format; | ||
1712 | case Opt_jqfmt_vfsv1: | ||
1713 | qfmt = QFMT_VFS_V1; | ||
1714 | set_qf_format: | ||
1715 | if (sb_any_quota_loaded(sb) && | 1718 | if (sb_any_quota_loaded(sb) && |
1716 | sbi->s_jquota_fmt != qfmt) { | 1719 | sbi->s_jquota_fmt != m->mount_opt) { |
1717 | ext4_msg(sb, KERN_ERR, "Cannot change " | 1720 | ext4_msg(sb, KERN_ERR, "Cannot " |
1718 | "journaled quota options when " | 1721 | "change journaled quota options " |
1719 | "quota turned on"); | 1722 | "when quota turned on"); |
1720 | return 0; | 1723 | return -1; |
1721 | } | 1724 | } |
1722 | sbi->s_jquota_fmt = qfmt; | 1725 | sbi->s_jquota_fmt = m->mount_opt; |
1723 | break; | ||
1724 | case Opt_quota: | ||
1725 | case Opt_usrquota: | ||
1726 | set_opt(sb, QUOTA); | ||
1727 | set_opt(sb, USRQUOTA); | ||
1728 | break; | ||
1729 | case Opt_grpquota: | ||
1730 | set_opt(sb, QUOTA); | ||
1731 | set_opt(sb, GRPQUOTA); | ||
1732 | break; | ||
1733 | case Opt_noquota: | ||
1734 | if (sb_any_quota_loaded(sb)) { | ||
1735 | ext4_msg(sb, KERN_ERR, "Cannot change quota " | ||
1736 | "options when quota turned on"); | ||
1737 | return 0; | ||
1738 | } | ||
1739 | clear_opt(sb, QUOTA); | ||
1740 | clear_opt(sb, USRQUOTA); | ||
1741 | clear_opt(sb, GRPQUOTA); | ||
1742 | break; | ||
1743 | #else | ||
1744 | case Opt_quota: | ||
1745 | case Opt_usrquota: | ||
1746 | case Opt_grpquota: | ||
1747 | ext4_msg(sb, KERN_ERR, | ||
1748 | "quota options not supported"); | ||
1749 | break; | ||
1750 | case Opt_usrjquota: | ||
1751 | case Opt_grpjquota: | ||
1752 | case Opt_offusrjquota: | ||
1753 | case Opt_offgrpjquota: | ||
1754 | case Opt_jqfmt_vfsold: | ||
1755 | case Opt_jqfmt_vfsv0: | ||
1756 | case Opt_jqfmt_vfsv1: | ||
1757 | ext4_msg(sb, KERN_ERR, | ||
1758 | "journaled quota options not supported"); | ||
1759 | break; | ||
1760 | case Opt_noquota: | ||
1761 | break; | ||
1762 | #endif | 1726 | #endif |
1763 | case Opt_abort: | 1727 | } else { |
1764 | sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; | 1728 | if (!args->from) |
1765 | break; | 1729 | arg = 1; |
1766 | case Opt_nobarrier: | 1730 | if (m->flags & MOPT_CLEAR) |
1767 | clear_opt(sb, BARRIER); | 1731 | arg = !arg; |
1768 | break; | 1732 | else if (unlikely(!(m->flags & MOPT_SET))) { |
1769 | case Opt_barrier: | 1733 | ext4_msg(sb, KERN_WARNING, |
1770 | if (args[0].from) { | 1734 | "buggy handling of option %s", opt); |
1771 | if (match_int(&args[0], &option)) | 1735 | WARN_ON(1); |
1772 | return 0; | 1736 | return -1; |
1773 | } else | ||
1774 | option = 1; /* No argument, default to 1 */ | ||
1775 | if (option) | ||
1776 | set_opt(sb, BARRIER); | ||
1777 | else | ||
1778 | clear_opt(sb, BARRIER); | ||
1779 | break; | ||
1780 | case Opt_i_version: | ||
1781 | sb->s_flags |= MS_I_VERSION; | ||
1782 | break; | ||
1783 | case Opt_nodelalloc: | ||
1784 | clear_opt(sb, DELALLOC); | ||
1785 | clear_opt2(sb, EXPLICIT_DELALLOC); | ||
1786 | break; | ||
1787 | case Opt_mblk_io_submit: | ||
1788 | set_opt(sb, MBLK_IO_SUBMIT); | ||
1789 | break; | ||
1790 | case Opt_nomblk_io_submit: | ||
1791 | clear_opt(sb, MBLK_IO_SUBMIT); | ||
1792 | break; | ||
1793 | case Opt_stripe: | ||
1794 | if (match_int(&args[0], &option)) | ||
1795 | return 0; | ||
1796 | if (option < 0) | ||
1797 | return 0; | ||
1798 | sbi->s_stripe = option; | ||
1799 | break; | ||
1800 | case Opt_delalloc: | ||
1801 | set_opt(sb, DELALLOC); | ||
1802 | set_opt2(sb, EXPLICIT_DELALLOC); | ||
1803 | break; | ||
1804 | case Opt_block_validity: | ||
1805 | set_opt(sb, BLOCK_VALIDITY); | ||
1806 | break; | ||
1807 | case Opt_noblock_validity: | ||
1808 | clear_opt(sb, BLOCK_VALIDITY); | ||
1809 | break; | ||
1810 | case Opt_inode_readahead_blks: | ||
1811 | if (match_int(&args[0], &option)) | ||
1812 | return 0; | ||
1813 | if (option < 0 || option > (1 << 30)) | ||
1814 | return 0; | ||
1815 | if (option && !is_power_of_2(option)) { | ||
1816 | ext4_msg(sb, KERN_ERR, | ||
1817 | "EXT4-fs: inode_readahead_blks" | ||
1818 | " must be a power of 2"); | ||
1819 | return 0; | ||
1820 | } | 1737 | } |
1821 | sbi->s_inode_readahead_blks = option; | 1738 | if (arg != 0) |
1822 | break; | 1739 | sbi->s_mount_opt |= m->mount_opt; |
1823 | case Opt_journal_ioprio: | ||
1824 | if (match_int(&args[0], &option)) | ||
1825 | return 0; | ||
1826 | if (option < 0 || option > 7) | ||
1827 | break; | ||
1828 | *journal_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, | ||
1829 | option); | ||
1830 | break; | ||
1831 | case Opt_noauto_da_alloc: | ||
1832 | set_opt(sb, NO_AUTO_DA_ALLOC); | ||
1833 | break; | ||
1834 | case Opt_auto_da_alloc: | ||
1835 | if (args[0].from) { | ||
1836 | if (match_int(&args[0], &option)) | ||
1837 | return 0; | ||
1838 | } else | ||
1839 | option = 1; /* No argument, default to 1 */ | ||
1840 | if (option) | ||
1841 | clear_opt(sb, NO_AUTO_DA_ALLOC); | ||
1842 | else | 1740 | else |
1843 | set_opt(sb,NO_AUTO_DA_ALLOC); | 1741 | sbi->s_mount_opt &= ~m->mount_opt; |
1844 | break; | ||
1845 | case Opt_discard: | ||
1846 | set_opt(sb, DISCARD); | ||
1847 | break; | ||
1848 | case Opt_nodiscard: | ||
1849 | clear_opt(sb, DISCARD); | ||
1850 | break; | ||
1851 | case Opt_dioread_nolock: | ||
1852 | set_opt(sb, DIOREAD_NOLOCK); | ||
1853 | break; | ||
1854 | case Opt_dioread_lock: | ||
1855 | clear_opt(sb, DIOREAD_NOLOCK); | ||
1856 | break; | ||
1857 | case Opt_init_itable: | ||
1858 | set_opt(sb, INIT_INODE_TABLE); | ||
1859 | if (args[0].from) { | ||
1860 | if (match_int(&args[0], &option)) | ||
1861 | return 0; | ||
1862 | } else | ||
1863 | option = EXT4_DEF_LI_WAIT_MULT; | ||
1864 | if (option < 0) | ||
1865 | return 0; | ||
1866 | sbi->s_li_wait_mult = option; | ||
1867 | break; | ||
1868 | case Opt_noinit_itable: | ||
1869 | clear_opt(sb, INIT_INODE_TABLE); | ||
1870 | break; | ||
1871 | default: | ||
1872 | ext4_msg(sb, KERN_ERR, | ||
1873 | "Unrecognized mount option \"%s\" " | ||
1874 | "or missing value", p); | ||
1875 | return 0; | ||
1876 | } | 1742 | } |
1743 | return 1; | ||
1744 | } | ||
1745 | ext4_msg(sb, KERN_ERR, "Unrecognized mount option \"%s\" " | ||
1746 | "or missing value", opt); | ||
1747 | return -1; | ||
1748 | } | ||
1749 | |||
1750 | static int parse_options(char *options, struct super_block *sb, | ||
1751 | unsigned long *journal_devnum, | ||
1752 | unsigned int *journal_ioprio, | ||
1753 | int is_remount) | ||
1754 | { | ||
1755 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1756 | char *p; | ||
1757 | substring_t args[MAX_OPT_ARGS]; | ||
1758 | int token; | ||
1759 | |||
1760 | if (!options) | ||
1761 | return 1; | ||
1762 | |||
1763 | while ((p = strsep(&options, ",")) != NULL) { | ||
1764 | if (!*p) | ||
1765 | continue; | ||
1766 | /* | ||
1767 | * Initialize args struct so we know whether arg was | ||
1768 | * found; some options take optional arguments. | ||
1769 | */ | ||
1770 | args[0].to = args[0].from = 0; | ||
1771 | token = match_token(p, tokens, args); | ||
1772 | if (handle_mount_opt(sb, p, token, args, journal_devnum, | ||
1773 | journal_ioprio, is_remount) < 0) | ||
1774 | return 0; | ||
1877 | } | 1775 | } |
1878 | #ifdef CONFIG_QUOTA | 1776 | #ifdef CONFIG_QUOTA |
1879 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1777 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |