diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-05-19 21:30:59 -0400 |
---|---|---|
committer | Niv Sardi <xaiki@debian.org> | 2008-07-28 02:58:21 -0400 |
commit | f8f15e42b408edce6ca9e9d8bd0d0e2078a39efd (patch) | |
tree | f54b232eff9f335f4dae890cf0fa72eead07b585 | |
parent | e48ad3160e5c5f5b952c7a7ed814f6f289a60100 (diff) |
[XFS] merge xfs_mount into xfs_fs_fill_super
xfs_mount is already pretty linux-specific so merge it into
xfs_fs_fill_super to allow for a more structured mount code in the next
patches. xfs_start_flags and xfs_finish_flags also move to xfs_super.c.
SGI-PV: 981951
SGI-Modid: xfs-linux-melb:xfs-kern:31189a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 360 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 369 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.h | 2 |
3 files changed, 355 insertions, 376 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 28132e643953..4b6ddf88d44e 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1366,6 +1366,235 @@ xfs_fs_setxquota( | |||
1366 | Q_XSETPQLIM), id, (caddr_t)fdq); | 1366 | Q_XSETPQLIM), id, (caddr_t)fdq); |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | /* | ||
1370 | * This function fills in xfs_mount_t fields based on mount args. | ||
1371 | * Note: the superblock has _not_ yet been read in. | ||
1372 | */ | ||
1373 | STATIC int | ||
1374 | xfs_start_flags( | ||
1375 | struct xfs_mount_args *ap, | ||
1376 | struct xfs_mount *mp) | ||
1377 | { | ||
1378 | /* Values are in BBs */ | ||
1379 | if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
1380 | /* | ||
1381 | * At this point the superblock has not been read | ||
1382 | * in, therefore we do not know the block size. | ||
1383 | * Before the mount call ends we will convert | ||
1384 | * these to FSBs. | ||
1385 | */ | ||
1386 | mp->m_dalign = ap->sunit; | ||
1387 | mp->m_swidth = ap->swidth; | ||
1388 | } | ||
1389 | |||
1390 | if (ap->logbufs != -1 && | ||
1391 | ap->logbufs != 0 && | ||
1392 | (ap->logbufs < XLOG_MIN_ICLOGS || | ||
1393 | ap->logbufs > XLOG_MAX_ICLOGS)) { | ||
1394 | cmn_err(CE_WARN, | ||
1395 | "XFS: invalid logbufs value: %d [not %d-%d]", | ||
1396 | ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | ||
1397 | return XFS_ERROR(EINVAL); | ||
1398 | } | ||
1399 | mp->m_logbufs = ap->logbufs; | ||
1400 | if (ap->logbufsize != -1 && | ||
1401 | ap->logbufsize != 0 && | ||
1402 | (ap->logbufsize < XLOG_MIN_RECORD_BSIZE || | ||
1403 | ap->logbufsize > XLOG_MAX_RECORD_BSIZE || | ||
1404 | !is_power_of_2(ap->logbufsize))) { | ||
1405 | cmn_err(CE_WARN, | ||
1406 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | ||
1407 | ap->logbufsize); | ||
1408 | return XFS_ERROR(EINVAL); | ||
1409 | } | ||
1410 | mp->m_logbsize = ap->logbufsize; | ||
1411 | mp->m_fsname_len = strlen(ap->fsname) + 1; | ||
1412 | mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); | ||
1413 | strcpy(mp->m_fsname, ap->fsname); | ||
1414 | if (ap->rtname[0]) { | ||
1415 | mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP); | ||
1416 | strcpy(mp->m_rtname, ap->rtname); | ||
1417 | } | ||
1418 | if (ap->logname[0]) { | ||
1419 | mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP); | ||
1420 | strcpy(mp->m_logname, ap->logname); | ||
1421 | } | ||
1422 | |||
1423 | if (ap->flags & XFSMNT_WSYNC) | ||
1424 | mp->m_flags |= XFS_MOUNT_WSYNC; | ||
1425 | #if XFS_BIG_INUMS | ||
1426 | if (ap->flags & XFSMNT_INO64) { | ||
1427 | mp->m_flags |= XFS_MOUNT_INO64; | ||
1428 | mp->m_inoadd = XFS_INO64_OFFSET; | ||
1429 | } | ||
1430 | #endif | ||
1431 | if (ap->flags & XFSMNT_RETERR) | ||
1432 | mp->m_flags |= XFS_MOUNT_RETERR; | ||
1433 | if (ap->flags & XFSMNT_NOALIGN) | ||
1434 | mp->m_flags |= XFS_MOUNT_NOALIGN; | ||
1435 | if (ap->flags & XFSMNT_SWALLOC) | ||
1436 | mp->m_flags |= XFS_MOUNT_SWALLOC; | ||
1437 | if (ap->flags & XFSMNT_OSYNCISOSYNC) | ||
1438 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; | ||
1439 | if (ap->flags & XFSMNT_32BITINODES) | ||
1440 | mp->m_flags |= XFS_MOUNT_32BITINODES; | ||
1441 | |||
1442 | if (ap->flags & XFSMNT_IOSIZE) { | ||
1443 | if (ap->iosizelog > XFS_MAX_IO_LOG || | ||
1444 | ap->iosizelog < XFS_MIN_IO_LOG) { | ||
1445 | cmn_err(CE_WARN, | ||
1446 | "XFS: invalid log iosize: %d [not %d-%d]", | ||
1447 | ap->iosizelog, XFS_MIN_IO_LOG, | ||
1448 | XFS_MAX_IO_LOG); | ||
1449 | return XFS_ERROR(EINVAL); | ||
1450 | } | ||
1451 | |||
1452 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | ||
1453 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | ||
1454 | } | ||
1455 | |||
1456 | if (ap->flags & XFSMNT_IKEEP) | ||
1457 | mp->m_flags |= XFS_MOUNT_IKEEP; | ||
1458 | if (ap->flags & XFSMNT_DIRSYNC) | ||
1459 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | ||
1460 | if (ap->flags & XFSMNT_ATTR2) | ||
1461 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
1462 | if (ap->flags & XFSMNT_NOATTR2) | ||
1463 | mp->m_flags |= XFS_MOUNT_NOATTR2; | ||
1464 | |||
1465 | if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) | ||
1466 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | ||
1467 | |||
1468 | /* | ||
1469 | * no recovery flag requires a read-only mount | ||
1470 | */ | ||
1471 | if (ap->flags & XFSMNT_NORECOVERY) { | ||
1472 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { | ||
1473 | cmn_err(CE_WARN, | ||
1474 | "XFS: tried to mount a FS read-write without recovery!"); | ||
1475 | return XFS_ERROR(EINVAL); | ||
1476 | } | ||
1477 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | ||
1478 | } | ||
1479 | |||
1480 | if (ap->flags & XFSMNT_NOUUID) | ||
1481 | mp->m_flags |= XFS_MOUNT_NOUUID; | ||
1482 | if (ap->flags & XFSMNT_BARRIER) | ||
1483 | mp->m_flags |= XFS_MOUNT_BARRIER; | ||
1484 | else | ||
1485 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
1486 | |||
1487 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
1488 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
1489 | |||
1490 | if (ap->flags & XFSMNT_DMAPI) | ||
1491 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | * This function fills in xfs_mount_t fields based on mount args. | ||
1497 | * Note: the superblock _has_ now been read in. | ||
1498 | */ | ||
1499 | STATIC int | ||
1500 | xfs_finish_flags( | ||
1501 | struct xfs_mount_args *ap, | ||
1502 | struct xfs_mount *mp) | ||
1503 | { | ||
1504 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | ||
1505 | |||
1506 | /* Fail a mount where the logbuf is smaller then the log stripe */ | ||
1507 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | ||
1508 | if ((ap->logbufsize <= 0) && | ||
1509 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { | ||
1510 | mp->m_logbsize = mp->m_sb.sb_logsunit; | ||
1511 | } else if (ap->logbufsize > 0 && | ||
1512 | ap->logbufsize < mp->m_sb.sb_logsunit) { | ||
1513 | cmn_err(CE_WARN, | ||
1514 | "XFS: logbuf size must be greater than or equal to log stripe size"); | ||
1515 | return XFS_ERROR(EINVAL); | ||
1516 | } | ||
1517 | } else { | ||
1518 | /* Fail a mount if the logbuf is larger than 32K */ | ||
1519 | if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) { | ||
1520 | cmn_err(CE_WARN, | ||
1521 | "XFS: logbuf size for version 1 logs must be 16K or 32K"); | ||
1522 | return XFS_ERROR(EINVAL); | ||
1523 | } | ||
1524 | } | ||
1525 | |||
1526 | /* | ||
1527 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly | ||
1528 | * told by noattr2 to turn it off | ||
1529 | */ | ||
1530 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | ||
1531 | !(ap->flags & XFSMNT_NOATTR2)) | ||
1532 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
1533 | |||
1534 | /* | ||
1535 | * prohibit r/w mounts of read-only filesystems | ||
1536 | */ | ||
1537 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { | ||
1538 | cmn_err(CE_WARN, | ||
1539 | "XFS: cannot mount a read-only filesystem as read-write"); | ||
1540 | return XFS_ERROR(EROFS); | ||
1541 | } | ||
1542 | |||
1543 | /* | ||
1544 | * check for shared mount. | ||
1545 | */ | ||
1546 | if (ap->flags & XFSMNT_SHARED) { | ||
1547 | if (!xfs_sb_version_hasshared(&mp->m_sb)) | ||
1548 | return XFS_ERROR(EINVAL); | ||
1549 | |||
1550 | /* | ||
1551 | * For IRIX 6.5, shared mounts must have the shared | ||
1552 | * version bit set, have the persistent readonly | ||
1553 | * field set, must be version 0 and can only be mounted | ||
1554 | * read-only. | ||
1555 | */ | ||
1556 | if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) || | ||
1557 | (mp->m_sb.sb_shared_vn != 0)) | ||
1558 | return XFS_ERROR(EINVAL); | ||
1559 | |||
1560 | mp->m_flags |= XFS_MOUNT_SHARED; | ||
1561 | |||
1562 | /* | ||
1563 | * Shared XFS V0 can't deal with DMI. Return EINVAL. | ||
1564 | */ | ||
1565 | if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) | ||
1566 | return XFS_ERROR(EINVAL); | ||
1567 | } | ||
1568 | |||
1569 | if (ap->flags & XFSMNT_UQUOTA) { | ||
1570 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
1571 | if (ap->flags & XFSMNT_UQUOTAENF) | ||
1572 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
1573 | } | ||
1574 | |||
1575 | if (ap->flags & XFSMNT_GQUOTA) { | ||
1576 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
1577 | if (ap->flags & XFSMNT_GQUOTAENF) | ||
1578 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
1579 | } else if (ap->flags & XFSMNT_PQUOTA) { | ||
1580 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
1581 | if (ap->flags & XFSMNT_PQUOTAENF) | ||
1582 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
1583 | } | ||
1584 | |||
1585 | return 0; | ||
1586 | } | ||
1587 | |||
1588 | /* | ||
1589 | * The file system configurations are: | ||
1590 | * (1) device (partition) with data and internal log | ||
1591 | * (2) logical volume with data and log subvolumes. | ||
1592 | * (3) logical volume with data, log, and realtime subvolumes. | ||
1593 | * | ||
1594 | * We only have to handle opening the log and realtime volumes here if | ||
1595 | * they are present. The data subvolume has already been opened by | ||
1596 | * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. | ||
1597 | */ | ||
1369 | STATIC int | 1598 | STATIC int |
1370 | xfs_fs_fill_super( | 1599 | xfs_fs_fill_super( |
1371 | struct super_block *sb, | 1600 | struct super_block *sb, |
@@ -1375,7 +1604,9 @@ xfs_fs_fill_super( | |||
1375 | struct inode *root; | 1604 | struct inode *root; |
1376 | struct xfs_mount *mp = NULL; | 1605 | struct xfs_mount *mp = NULL; |
1377 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); | 1606 | struct xfs_mount_args *args = xfs_args_allocate(sb, silent); |
1378 | int error; | 1607 | struct block_device *ddev = sb->s_bdev; |
1608 | struct block_device *logdev = NULL, *rtdev = NULL; | ||
1609 | int flags = 0, error; | ||
1379 | 1610 | ||
1380 | mp = xfs_mount_init(); | 1611 | mp = xfs_mount_init(); |
1381 | 1612 | ||
@@ -1398,10 +1629,114 @@ xfs_fs_fill_super( | |||
1398 | sb->s_qcop = &xfs_quotactl_operations; | 1629 | sb->s_qcop = &xfs_quotactl_operations; |
1399 | sb->s_op = &xfs_super_operations; | 1630 | sb->s_op = &xfs_super_operations; |
1400 | 1631 | ||
1401 | error = xfs_mount(mp, args, NULL); | 1632 | error = xfs_dmops_get(mp, args); |
1633 | if (error) | ||
1634 | goto fail_vfsop; | ||
1635 | error = xfs_qmops_get(mp, args); | ||
1402 | if (error) | 1636 | if (error) |
1403 | goto fail_vfsop; | 1637 | goto fail_vfsop; |
1404 | 1638 | ||
1639 | if (args->flags & XFSMNT_QUIET) | ||
1640 | flags |= XFS_MFSI_QUIET; | ||
1641 | |||
1642 | /* | ||
1643 | * Open real time and log devices - order is important. | ||
1644 | */ | ||
1645 | if (args->logname[0]) { | ||
1646 | error = xfs_blkdev_get(mp, args->logname, &logdev); | ||
1647 | if (error) | ||
1648 | goto fail_vfsop; | ||
1649 | } | ||
1650 | if (args->rtname[0]) { | ||
1651 | error = xfs_blkdev_get(mp, args->rtname, &rtdev); | ||
1652 | if (error) { | ||
1653 | xfs_blkdev_put(logdev); | ||
1654 | goto fail_vfsop; | ||
1655 | } | ||
1656 | |||
1657 | if (rtdev == ddev || rtdev == logdev) { | ||
1658 | cmn_err(CE_WARN, | ||
1659 | "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev."); | ||
1660 | xfs_blkdev_put(logdev); | ||
1661 | xfs_blkdev_put(rtdev); | ||
1662 | error = EINVAL; | ||
1663 | goto fail_vfsop; | ||
1664 | } | ||
1665 | } | ||
1666 | |||
1667 | /* | ||
1668 | * Setup xfs_mount buffer target pointers | ||
1669 | */ | ||
1670 | error = ENOMEM; | ||
1671 | mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0); | ||
1672 | if (!mp->m_ddev_targp) { | ||
1673 | xfs_blkdev_put(logdev); | ||
1674 | xfs_blkdev_put(rtdev); | ||
1675 | goto fail_vfsop; | ||
1676 | } | ||
1677 | if (rtdev) { | ||
1678 | mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); | ||
1679 | if (!mp->m_rtdev_targp) { | ||
1680 | xfs_blkdev_put(logdev); | ||
1681 | xfs_blkdev_put(rtdev); | ||
1682 | goto error0; | ||
1683 | } | ||
1684 | } | ||
1685 | mp->m_logdev_targp = (logdev && logdev != ddev) ? | ||
1686 | xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; | ||
1687 | if (!mp->m_logdev_targp) { | ||
1688 | xfs_blkdev_put(logdev); | ||
1689 | xfs_blkdev_put(rtdev); | ||
1690 | goto error0; | ||
1691 | } | ||
1692 | |||
1693 | /* | ||
1694 | * Setup flags based on mount(2) options and then the superblock | ||
1695 | */ | ||
1696 | error = xfs_start_flags(args, mp); | ||
1697 | if (error) | ||
1698 | goto error1; | ||
1699 | error = xfs_readsb(mp, flags); | ||
1700 | if (error) | ||
1701 | goto error1; | ||
1702 | error = xfs_finish_flags(args, mp); | ||
1703 | if (error) | ||
1704 | goto error2; | ||
1705 | |||
1706 | /* | ||
1707 | * Setup xfs_mount buffer target pointers based on superblock | ||
1708 | */ | ||
1709 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, | ||
1710 | mp->m_sb.sb_sectsize); | ||
1711 | if (!error && logdev && logdev != ddev) { | ||
1712 | unsigned int log_sector_size = BBSIZE; | ||
1713 | |||
1714 | if (xfs_sb_version_hassector(&mp->m_sb)) | ||
1715 | log_sector_size = mp->m_sb.sb_logsectsize; | ||
1716 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | ||
1717 | mp->m_sb.sb_blocksize, | ||
1718 | log_sector_size); | ||
1719 | } | ||
1720 | if (!error && rtdev) | ||
1721 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, | ||
1722 | mp->m_sb.sb_blocksize, | ||
1723 | mp->m_sb.sb_sectsize); | ||
1724 | if (error) | ||
1725 | goto error2; | ||
1726 | |||
1727 | if (mp->m_flags & XFS_MOUNT_BARRIER) | ||
1728 | xfs_mountfs_check_barriers(mp); | ||
1729 | |||
1730 | error = xfs_filestream_mount(mp); | ||
1731 | if (error) | ||
1732 | goto error2; | ||
1733 | |||
1734 | error = xfs_mountfs(mp, flags); | ||
1735 | if (error) | ||
1736 | goto error2; | ||
1737 | |||
1738 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); | ||
1739 | |||
1405 | sb->s_dirt = 1; | 1740 | sb->s_dirt = 1; |
1406 | sb->s_magic = XFS_SB_MAGIC; | 1741 | sb->s_magic = XFS_SB_MAGIC; |
1407 | sb->s_blocksize = mp->m_sb.sb_blocksize; | 1742 | sb->s_blocksize = mp->m_sb.sb_blocksize; |
@@ -1438,7 +1773,22 @@ xfs_fs_fill_super( | |||
1438 | kmem_free(args); | 1773 | kmem_free(args); |
1439 | return 0; | 1774 | return 0; |
1440 | 1775 | ||
1441 | fail_vnrele: | 1776 | error2: |
1777 | if (mp->m_sb_bp) | ||
1778 | xfs_freesb(mp); | ||
1779 | error1: | ||
1780 | xfs_binval(mp->m_ddev_targp); | ||
1781 | if (logdev && logdev != ddev) | ||
1782 | xfs_binval(mp->m_logdev_targp); | ||
1783 | if (rtdev) | ||
1784 | xfs_binval(mp->m_rtdev_targp); | ||
1785 | error0: | ||
1786 | xfs_unmountfs_close(mp, NULL); | ||
1787 | xfs_qmops_put(mp); | ||
1788 | xfs_dmops_put(mp); | ||
1789 | goto fail_vfsop; | ||
1790 | |||
1791 | fail_vnrele: | ||
1442 | if (sb->s_root) { | 1792 | if (sb->s_root) { |
1443 | dput(sb->s_root); | 1793 | dput(sb->s_root); |
1444 | sb->s_root = NULL; | 1794 | sb->s_root = NULL; |
@@ -1446,7 +1796,7 @@ fail_vnrele: | |||
1446 | iput(root); | 1796 | iput(root); |
1447 | } | 1797 | } |
1448 | 1798 | ||
1449 | fail_unmount: | 1799 | fail_unmount: |
1450 | /* | 1800 | /* |
1451 | * Blow away any referenced inode in the filestreams cache. | 1801 | * Blow away any referenced inode in the filestreams cache. |
1452 | * This can and will cause log traffic as inodes go inactive | 1802 | * This can and will cause log traffic as inodes go inactive |
@@ -1465,7 +1815,7 @@ fail_unmount: | |||
1465 | xfs_dmops_put(mp); | 1815 | xfs_dmops_put(mp); |
1466 | kmem_free(mp); | 1816 | kmem_free(mp); |
1467 | 1817 | ||
1468 | fail_vfsop: | 1818 | fail_vfsop: |
1469 | kmem_free(args); | 1819 | kmem_free(args); |
1470 | return -error; | 1820 | return -error; |
1471 | } | 1821 | } |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index bc34f90e7eea..8b5a3376c2f7 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -189,375 +189,6 @@ xfs_cleanup(void) | |||
189 | kmem_zone_destroy(xfs_log_ticket_zone); | 189 | kmem_zone_destroy(xfs_log_ticket_zone); |
190 | } | 190 | } |
191 | 191 | ||
192 | /* | ||
193 | * xfs_start_flags | ||
194 | * | ||
195 | * This function fills in xfs_mount_t fields based on mount args. | ||
196 | * Note: the superblock has _not_ yet been read in. | ||
197 | */ | ||
198 | STATIC int | ||
199 | xfs_start_flags( | ||
200 | struct xfs_mount_args *ap, | ||
201 | struct xfs_mount *mp) | ||
202 | { | ||
203 | /* Values are in BBs */ | ||
204 | if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) { | ||
205 | /* | ||
206 | * At this point the superblock has not been read | ||
207 | * in, therefore we do not know the block size. | ||
208 | * Before the mount call ends we will convert | ||
209 | * these to FSBs. | ||
210 | */ | ||
211 | mp->m_dalign = ap->sunit; | ||
212 | mp->m_swidth = ap->swidth; | ||
213 | } | ||
214 | |||
215 | if (ap->logbufs != -1 && | ||
216 | ap->logbufs != 0 && | ||
217 | (ap->logbufs < XLOG_MIN_ICLOGS || | ||
218 | ap->logbufs > XLOG_MAX_ICLOGS)) { | ||
219 | cmn_err(CE_WARN, | ||
220 | "XFS: invalid logbufs value: %d [not %d-%d]", | ||
221 | ap->logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS); | ||
222 | return XFS_ERROR(EINVAL); | ||
223 | } | ||
224 | mp->m_logbufs = ap->logbufs; | ||
225 | if (ap->logbufsize != -1 && | ||
226 | ap->logbufsize != 0 && | ||
227 | (ap->logbufsize < XLOG_MIN_RECORD_BSIZE || | ||
228 | ap->logbufsize > XLOG_MAX_RECORD_BSIZE || | ||
229 | !is_power_of_2(ap->logbufsize))) { | ||
230 | cmn_err(CE_WARN, | ||
231 | "XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]", | ||
232 | ap->logbufsize); | ||
233 | return XFS_ERROR(EINVAL); | ||
234 | } | ||
235 | mp->m_logbsize = ap->logbufsize; | ||
236 | mp->m_fsname_len = strlen(ap->fsname) + 1; | ||
237 | mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP); | ||
238 | strcpy(mp->m_fsname, ap->fsname); | ||
239 | if (ap->rtname[0]) { | ||
240 | mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP); | ||
241 | strcpy(mp->m_rtname, ap->rtname); | ||
242 | } | ||
243 | if (ap->logname[0]) { | ||
244 | mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP); | ||
245 | strcpy(mp->m_logname, ap->logname); | ||
246 | } | ||
247 | |||
248 | if (ap->flags & XFSMNT_WSYNC) | ||
249 | mp->m_flags |= XFS_MOUNT_WSYNC; | ||
250 | #if XFS_BIG_INUMS | ||
251 | if (ap->flags & XFSMNT_INO64) { | ||
252 | mp->m_flags |= XFS_MOUNT_INO64; | ||
253 | mp->m_inoadd = XFS_INO64_OFFSET; | ||
254 | } | ||
255 | #endif | ||
256 | if (ap->flags & XFSMNT_RETERR) | ||
257 | mp->m_flags |= XFS_MOUNT_RETERR; | ||
258 | if (ap->flags & XFSMNT_NOALIGN) | ||
259 | mp->m_flags |= XFS_MOUNT_NOALIGN; | ||
260 | if (ap->flags & XFSMNT_SWALLOC) | ||
261 | mp->m_flags |= XFS_MOUNT_SWALLOC; | ||
262 | if (ap->flags & XFSMNT_OSYNCISOSYNC) | ||
263 | mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC; | ||
264 | if (ap->flags & XFSMNT_32BITINODES) | ||
265 | mp->m_flags |= XFS_MOUNT_32BITINODES; | ||
266 | |||
267 | if (ap->flags & XFSMNT_IOSIZE) { | ||
268 | if (ap->iosizelog > XFS_MAX_IO_LOG || | ||
269 | ap->iosizelog < XFS_MIN_IO_LOG) { | ||
270 | cmn_err(CE_WARN, | ||
271 | "XFS: invalid log iosize: %d [not %d-%d]", | ||
272 | ap->iosizelog, XFS_MIN_IO_LOG, | ||
273 | XFS_MAX_IO_LOG); | ||
274 | return XFS_ERROR(EINVAL); | ||
275 | } | ||
276 | |||
277 | mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE; | ||
278 | mp->m_readio_log = mp->m_writeio_log = ap->iosizelog; | ||
279 | } | ||
280 | |||
281 | if (ap->flags & XFSMNT_IKEEP) | ||
282 | mp->m_flags |= XFS_MOUNT_IKEEP; | ||
283 | if (ap->flags & XFSMNT_DIRSYNC) | ||
284 | mp->m_flags |= XFS_MOUNT_DIRSYNC; | ||
285 | if (ap->flags & XFSMNT_ATTR2) | ||
286 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
287 | if (ap->flags & XFSMNT_NOATTR2) | ||
288 | mp->m_flags |= XFS_MOUNT_NOATTR2; | ||
289 | |||
290 | if (ap->flags2 & XFSMNT2_COMPAT_IOSIZE) | ||
291 | mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE; | ||
292 | |||
293 | /* | ||
294 | * no recovery flag requires a read-only mount | ||
295 | */ | ||
296 | if (ap->flags & XFSMNT_NORECOVERY) { | ||
297 | if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { | ||
298 | cmn_err(CE_WARN, | ||
299 | "XFS: tried to mount a FS read-write without recovery!"); | ||
300 | return XFS_ERROR(EINVAL); | ||
301 | } | ||
302 | mp->m_flags |= XFS_MOUNT_NORECOVERY; | ||
303 | } | ||
304 | |||
305 | if (ap->flags & XFSMNT_NOUUID) | ||
306 | mp->m_flags |= XFS_MOUNT_NOUUID; | ||
307 | if (ap->flags & XFSMNT_BARRIER) | ||
308 | mp->m_flags |= XFS_MOUNT_BARRIER; | ||
309 | else | ||
310 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
311 | |||
312 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
313 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
314 | |||
315 | if (ap->flags & XFSMNT_DMAPI) | ||
316 | mp->m_flags |= XFS_MOUNT_DMAPI; | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | /* | ||
321 | * This function fills in xfs_mount_t fields based on mount args. | ||
322 | * Note: the superblock _has_ now been read in. | ||
323 | */ | ||
324 | STATIC int | ||
325 | xfs_finish_flags( | ||
326 | struct xfs_mount_args *ap, | ||
327 | struct xfs_mount *mp) | ||
328 | { | ||
329 | int ronly = (mp->m_flags & XFS_MOUNT_RDONLY); | ||
330 | |||
331 | /* Fail a mount where the logbuf is smaller then the log stripe */ | ||
332 | if (xfs_sb_version_haslogv2(&mp->m_sb)) { | ||
333 | if ((ap->logbufsize <= 0) && | ||
334 | (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) { | ||
335 | mp->m_logbsize = mp->m_sb.sb_logsunit; | ||
336 | } else if (ap->logbufsize > 0 && | ||
337 | ap->logbufsize < mp->m_sb.sb_logsunit) { | ||
338 | cmn_err(CE_WARN, | ||
339 | "XFS: logbuf size must be greater than or equal to log stripe size"); | ||
340 | return XFS_ERROR(EINVAL); | ||
341 | } | ||
342 | } else { | ||
343 | /* Fail a mount if the logbuf is larger than 32K */ | ||
344 | if (ap->logbufsize > XLOG_BIG_RECORD_BSIZE) { | ||
345 | cmn_err(CE_WARN, | ||
346 | "XFS: logbuf size for version 1 logs must be 16K or 32K"); | ||
347 | return XFS_ERROR(EINVAL); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * mkfs'ed attr2 will turn on attr2 mount unless explicitly | ||
353 | * told by noattr2 to turn it off | ||
354 | */ | ||
355 | if (xfs_sb_version_hasattr2(&mp->m_sb) && | ||
356 | !(ap->flags & XFSMNT_NOATTR2)) | ||
357 | mp->m_flags |= XFS_MOUNT_ATTR2; | ||
358 | |||
359 | /* | ||
360 | * prohibit r/w mounts of read-only filesystems | ||
361 | */ | ||
362 | if ((mp->m_sb.sb_flags & XFS_SBF_READONLY) && !ronly) { | ||
363 | cmn_err(CE_WARN, | ||
364 | "XFS: cannot mount a read-only filesystem as read-write"); | ||
365 | return XFS_ERROR(EROFS); | ||
366 | } | ||
367 | |||
368 | /* | ||
369 | * check for shared mount. | ||
370 | */ | ||
371 | if (ap->flags & XFSMNT_SHARED) { | ||
372 | if (!xfs_sb_version_hasshared(&mp->m_sb)) | ||
373 | return XFS_ERROR(EINVAL); | ||
374 | |||
375 | /* | ||
376 | * For IRIX 6.5, shared mounts must have the shared | ||
377 | * version bit set, have the persistent readonly | ||
378 | * field set, must be version 0 and can only be mounted | ||
379 | * read-only. | ||
380 | */ | ||
381 | if (!ronly || !(mp->m_sb.sb_flags & XFS_SBF_READONLY) || | ||
382 | (mp->m_sb.sb_shared_vn != 0)) | ||
383 | return XFS_ERROR(EINVAL); | ||
384 | |||
385 | mp->m_flags |= XFS_MOUNT_SHARED; | ||
386 | |||
387 | /* | ||
388 | * Shared XFS V0 can't deal with DMI. Return EINVAL. | ||
389 | */ | ||
390 | if (mp->m_sb.sb_shared_vn == 0 && (ap->flags & XFSMNT_DMAPI)) | ||
391 | return XFS_ERROR(EINVAL); | ||
392 | } | ||
393 | |||
394 | if (ap->flags & XFSMNT_UQUOTA) { | ||
395 | mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE); | ||
396 | if (ap->flags & XFSMNT_UQUOTAENF) | ||
397 | mp->m_qflags |= XFS_UQUOTA_ENFD; | ||
398 | } | ||
399 | |||
400 | if (ap->flags & XFSMNT_GQUOTA) { | ||
401 | mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE); | ||
402 | if (ap->flags & XFSMNT_GQUOTAENF) | ||
403 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
404 | } else if (ap->flags & XFSMNT_PQUOTA) { | ||
405 | mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE); | ||
406 | if (ap->flags & XFSMNT_PQUOTAENF) | ||
407 | mp->m_qflags |= XFS_OQUOTA_ENFD; | ||
408 | } | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * xfs_mount | ||
415 | * | ||
416 | * The file system configurations are: | ||
417 | * (1) device (partition) with data and internal log | ||
418 | * (2) logical volume with data and log subvolumes. | ||
419 | * (3) logical volume with data, log, and realtime subvolumes. | ||
420 | * | ||
421 | * We only have to handle opening the log and realtime volumes here if | ||
422 | * they are present. The data subvolume has already been opened by | ||
423 | * get_sb_bdev() and is stored in vfsp->vfs_super->s_bdev. | ||
424 | */ | ||
425 | int | ||
426 | xfs_mount( | ||
427 | struct xfs_mount *mp, | ||
428 | struct xfs_mount_args *args, | ||
429 | cred_t *credp) | ||
430 | { | ||
431 | struct block_device *ddev, *logdev, *rtdev; | ||
432 | int flags = 0, error; | ||
433 | |||
434 | ddev = mp->m_super->s_bdev; | ||
435 | logdev = rtdev = NULL; | ||
436 | |||
437 | error = xfs_dmops_get(mp, args); | ||
438 | if (error) | ||
439 | return error; | ||
440 | error = xfs_qmops_get(mp, args); | ||
441 | if (error) | ||
442 | return error; | ||
443 | |||
444 | if (args->flags & XFSMNT_QUIET) | ||
445 | flags |= XFS_MFSI_QUIET; | ||
446 | |||
447 | /* | ||
448 | * Open real time and log devices - order is important. | ||
449 | */ | ||
450 | if (args->logname[0]) { | ||
451 | error = xfs_blkdev_get(mp, args->logname, &logdev); | ||
452 | if (error) | ||
453 | return error; | ||
454 | } | ||
455 | if (args->rtname[0]) { | ||
456 | error = xfs_blkdev_get(mp, args->rtname, &rtdev); | ||
457 | if (error) { | ||
458 | xfs_blkdev_put(logdev); | ||
459 | return error; | ||
460 | } | ||
461 | |||
462 | if (rtdev == ddev || rtdev == logdev) { | ||
463 | cmn_err(CE_WARN, | ||
464 | "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev."); | ||
465 | xfs_blkdev_put(logdev); | ||
466 | xfs_blkdev_put(rtdev); | ||
467 | return EINVAL; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Setup xfs_mount buffer target pointers | ||
473 | */ | ||
474 | error = ENOMEM; | ||
475 | mp->m_ddev_targp = xfs_alloc_buftarg(ddev, 0); | ||
476 | if (!mp->m_ddev_targp) { | ||
477 | xfs_blkdev_put(logdev); | ||
478 | xfs_blkdev_put(rtdev); | ||
479 | return error; | ||
480 | } | ||
481 | if (rtdev) { | ||
482 | mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev, 1); | ||
483 | if (!mp->m_rtdev_targp) { | ||
484 | xfs_blkdev_put(logdev); | ||
485 | xfs_blkdev_put(rtdev); | ||
486 | goto error0; | ||
487 | } | ||
488 | } | ||
489 | mp->m_logdev_targp = (logdev && logdev != ddev) ? | ||
490 | xfs_alloc_buftarg(logdev, 1) : mp->m_ddev_targp; | ||
491 | if (!mp->m_logdev_targp) { | ||
492 | xfs_blkdev_put(logdev); | ||
493 | xfs_blkdev_put(rtdev); | ||
494 | goto error0; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Setup flags based on mount(2) options and then the superblock | ||
499 | */ | ||
500 | error = xfs_start_flags(args, mp); | ||
501 | if (error) | ||
502 | goto error1; | ||
503 | error = xfs_readsb(mp, flags); | ||
504 | if (error) | ||
505 | goto error1; | ||
506 | error = xfs_finish_flags(args, mp); | ||
507 | if (error) | ||
508 | goto error2; | ||
509 | |||
510 | /* | ||
511 | * Setup xfs_mount buffer target pointers based on superblock | ||
512 | */ | ||
513 | error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, | ||
514 | mp->m_sb.sb_sectsize); | ||
515 | if (!error && logdev && logdev != ddev) { | ||
516 | unsigned int log_sector_size = BBSIZE; | ||
517 | |||
518 | if (xfs_sb_version_hassector(&mp->m_sb)) | ||
519 | log_sector_size = mp->m_sb.sb_logsectsize; | ||
520 | error = xfs_setsize_buftarg(mp->m_logdev_targp, | ||
521 | mp->m_sb.sb_blocksize, | ||
522 | log_sector_size); | ||
523 | } | ||
524 | if (!error && rtdev) | ||
525 | error = xfs_setsize_buftarg(mp->m_rtdev_targp, | ||
526 | mp->m_sb.sb_blocksize, | ||
527 | mp->m_sb.sb_sectsize); | ||
528 | if (error) | ||
529 | goto error2; | ||
530 | |||
531 | if (mp->m_flags & XFS_MOUNT_BARRIER) | ||
532 | xfs_mountfs_check_barriers(mp); | ||
533 | |||
534 | if ((error = xfs_filestream_mount(mp))) | ||
535 | goto error2; | ||
536 | |||
537 | error = xfs_mountfs(mp, flags); | ||
538 | if (error) | ||
539 | goto error2; | ||
540 | |||
541 | XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, args->mtpt, args->fsname); | ||
542 | |||
543 | return 0; | ||
544 | |||
545 | error2: | ||
546 | if (mp->m_sb_bp) | ||
547 | xfs_freesb(mp); | ||
548 | error1: | ||
549 | xfs_binval(mp->m_ddev_targp); | ||
550 | if (logdev && logdev != ddev) | ||
551 | xfs_binval(mp->m_logdev_targp); | ||
552 | if (rtdev) | ||
553 | xfs_binval(mp->m_rtdev_targp); | ||
554 | error0: | ||
555 | xfs_unmountfs_close(mp, credp); | ||
556 | xfs_qmops_put(mp); | ||
557 | xfs_dmops_put(mp); | ||
558 | return error; | ||
559 | } | ||
560 | |||
561 | STATIC void | 192 | STATIC void |
562 | xfs_quiesce_fs( | 193 | xfs_quiesce_fs( |
563 | xfs_mount_t *mp) | 194 | xfs_mount_t *mp) |
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h index de64bb6542df..a74b05087da4 100644 --- a/fs/xfs/xfs_vfsops.h +++ b/fs/xfs/xfs_vfsops.h | |||
@@ -8,8 +8,6 @@ struct kstatfs; | |||
8 | struct xfs_mount; | 8 | struct xfs_mount; |
9 | struct xfs_mount_args; | 9 | struct xfs_mount_args; |
10 | 10 | ||
11 | int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args, | ||
12 | struct cred *credp); | ||
13 | int xfs_sync(struct xfs_mount *mp, int flags); | 11 | int xfs_sync(struct xfs_mount *mp, int flags); |
14 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, | 12 | void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, |
15 | int lnnum); | 13 | int lnnum); |