aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-05-19 21:30:59 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:21 -0400
commitf8f15e42b408edce6ca9e9d8bd0d0e2078a39efd (patch)
treef54b232eff9f335f4dae890cf0fa72eead07b585 /fs
parente48ad3160e5c5f5b952c7a7ed814f6f289a60100 (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')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c360
-rw-r--r--fs/xfs/xfs_vfsops.c369
-rw-r--r--fs/xfs/xfs_vfsops.h2
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 */
1373STATIC int
1374xfs_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 */
1499STATIC int
1500xfs_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 */
1369STATIC int 1598STATIC int
1370xfs_fs_fill_super( 1599xfs_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
1441fail_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
1449fail_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
1468fail_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 */
198STATIC int
199xfs_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 */
324STATIC int
325xfs_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 */
425int
426xfs_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
545error2:
546 if (mp->m_sb_bp)
547 xfs_freesb(mp);
548error1:
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);
554error0:
555 xfs_unmountfs_close(mp, credp);
556 xfs_qmops_put(mp);
557 xfs_dmops_put(mp);
558 return error;
559}
560
561STATIC void 192STATIC void
562xfs_quiesce_fs( 193xfs_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;
8struct xfs_mount; 8struct xfs_mount;
9struct xfs_mount_args; 9struct xfs_mount_args;
10 10
11int xfs_mount(struct xfs_mount *mp, struct xfs_mount_args *args,
12 struct cred *credp);
13int xfs_sync(struct xfs_mount *mp, int flags); 11int xfs_sync(struct xfs_mount *mp, int flags);
14void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname, 12void xfs_do_force_shutdown(struct xfs_mount *mp, int flags, char *fname,
15 int lnnum); 13 int lnnum);