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 /fs/xfs/linux-2.6/xfs_super.c | |
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>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_super.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 360 |
1 files changed, 355 insertions, 5 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 | } |