aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_vfsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r--fs/xfs/xfs_vfsops.c793
1 files changed, 29 insertions, 764 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a1544597bcd3..413587f02155 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -58,17 +58,12 @@
58#include "xfs_vfsops.h" 58#include "xfs_vfsops.h"
59 59
60 60
61int 61int __init
62xfs_init(void) 62xfs_init(void)
63{ 63{
64 extern kmem_zone_t *xfs_bmap_free_item_zone;
65 extern kmem_zone_t *xfs_btree_cur_zone;
66 extern kmem_zone_t *xfs_trans_zone;
67 extern kmem_zone_t *xfs_buf_item_zone;
68 extern kmem_zone_t *xfs_dabuf_zone;
69#ifdef XFS_DABUF_DEBUG 64#ifdef XFS_DABUF_DEBUG
70 extern lock_t xfs_dabuf_global_lock; 65 extern spinlock_t xfs_dabuf_global_lock;
71 spinlock_init(&xfs_dabuf_global_lock, "xfsda"); 66 spin_lock_init(&xfs_dabuf_global_lock);
72#endif 67#endif
73 68
74 /* 69 /*
@@ -152,18 +147,12 @@ xfs_init(void)
152 return 0; 147 return 0;
153} 148}
154 149
155void 150void __exit
156xfs_cleanup(void) 151xfs_cleanup(void)
157{ 152{
158 extern kmem_zone_t *xfs_bmap_free_item_zone;
159 extern kmem_zone_t *xfs_btree_cur_zone;
160 extern kmem_zone_t *xfs_inode_zone; 153 extern kmem_zone_t *xfs_inode_zone;
161 extern kmem_zone_t *xfs_trans_zone;
162 extern kmem_zone_t *xfs_da_state_zone;
163 extern kmem_zone_t *xfs_dabuf_zone;
164 extern kmem_zone_t *xfs_efd_zone; 154 extern kmem_zone_t *xfs_efd_zone;
165 extern kmem_zone_t *xfs_efi_zone; 155 extern kmem_zone_t *xfs_efi_zone;
166 extern kmem_zone_t *xfs_buf_item_zone;
167 extern kmem_zone_t *xfs_icluster_zone; 156 extern kmem_zone_t *xfs_icluster_zone;
168 157
169 xfs_cleanup_procfs(); 158 xfs_cleanup_procfs();
@@ -449,8 +438,6 @@ xfs_mount(
449 if (error) 438 if (error)
450 return error; 439 return error;
451 440
452 mp->m_io_ops = xfs_iocore_xfs;
453
454 if (args->flags & XFSMNT_QUIET) 441 if (args->flags & XFSMNT_QUIET)
455 flags |= XFS_MFSI_QUIET; 442 flags |= XFS_MFSI_QUIET;
456 443
@@ -544,7 +531,7 @@ xfs_mount(
544 if ((error = xfs_filestream_mount(mp))) 531 if ((error = xfs_filestream_mount(mp)))
545 goto error2; 532 goto error2;
546 533
547 error = XFS_IOINIT(mp, args, flags); 534 error = xfs_mountfs(mp, flags);
548 if (error) 535 if (error)
549 goto error2; 536 goto error2;
550 537
@@ -694,7 +681,7 @@ xfs_quiesce_fs(
694 * care of the metadata. New transactions are already blocked, so we need to 681 * care of the metadata. New transactions are already blocked, so we need to
695 * wait for any remaining transactions to drain out before proceding. 682 * wait for any remaining transactions to drain out before proceding.
696 */ 683 */
697STATIC void 684void
698xfs_attr_quiesce( 685xfs_attr_quiesce(
699 xfs_mount_t *mp) 686 xfs_mount_t *mp)
700{ 687{
@@ -821,80 +808,6 @@ fscorrupt_out2:
821} 808}
822 809
823/* 810/*
824 * xfs_root extracts the root vnode from a vfs.
825 *
826 * vfsp -- the vfs struct for the desired file system
827 * vpp -- address of the caller's vnode pointer which should be
828 * set to the desired fs root vnode
829 */
830int
831xfs_root(
832 xfs_mount_t *mp,
833 bhv_vnode_t **vpp)
834{
835 bhv_vnode_t *vp;
836
837 vp = XFS_ITOV(mp->m_rootip);
838 VN_HOLD(vp);
839 *vpp = vp;
840 return 0;
841}
842
843/*
844 * xfs_statvfs
845 *
846 * Fill in the statvfs structure for the given file system. We use
847 * the superblock lock in the mount structure to ensure a consistent
848 * snapshot of the counters returned.
849 */
850int
851xfs_statvfs(
852 xfs_mount_t *mp,
853 bhv_statvfs_t *statp,
854 bhv_vnode_t *vp)
855{
856 __uint64_t fakeinos;
857 xfs_extlen_t lsize;
858 xfs_sb_t *sbp;
859 unsigned long s;
860
861 sbp = &(mp->m_sb);
862
863 statp->f_type = XFS_SB_MAGIC;
864
865 xfs_icsb_sync_counters_flags(mp, XFS_ICSB_LAZY_COUNT);
866 s = XFS_SB_LOCK(mp);
867 statp->f_bsize = sbp->sb_blocksize;
868 lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
869 statp->f_blocks = sbp->sb_dblocks - lsize;
870 statp->f_bfree = statp->f_bavail =
871 sbp->sb_fdblocks - XFS_ALLOC_SET_ASIDE(mp);
872 fakeinos = statp->f_bfree << sbp->sb_inopblog;
873#if XFS_BIG_INUMS
874 fakeinos += mp->m_inoadd;
875#endif
876 statp->f_files =
877 MIN(sbp->sb_icount + fakeinos, (__uint64_t)XFS_MAXINUMBER);
878 if (mp->m_maxicount)
879#if XFS_BIG_INUMS
880 if (!mp->m_inoadd)
881#endif
882 statp->f_files = min_t(typeof(statp->f_files),
883 statp->f_files,
884 mp->m_maxicount);
885 statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree);
886 XFS_SB_UNLOCK(mp, s);
887
888 xfs_statvfs_fsid(statp, mp);
889 statp->f_namelen = MAXNAMELEN - 1;
890
891 if (vp)
892 XFS_QM_DQSTATVFS(xfs_vtoi(vp), statp);
893 return 0;
894}
895
896
897/*
898 * xfs_sync flushes any pending I/O to file system vfsp. 811 * xfs_sync flushes any pending I/O to file system vfsp.
899 * 812 *
900 * This routine is called by vfs_sync() to make sure that things make it 813 * This routine is called by vfs_sync() to make sure that things make it
@@ -981,8 +894,6 @@ xfs_sync_inodes(
981 int *bypassed) 894 int *bypassed)
982{ 895{
983 xfs_inode_t *ip = NULL; 896 xfs_inode_t *ip = NULL;
984 xfs_inode_t *ip_next;
985 xfs_buf_t *bp;
986 bhv_vnode_t *vp = NULL; 897 bhv_vnode_t *vp = NULL;
987 int error; 898 int error;
988 int last_error; 899 int last_error;
@@ -992,7 +903,6 @@ xfs_sync_inodes(
992 boolean_t mount_locked; 903 boolean_t mount_locked;
993 boolean_t vnode_refed; 904 boolean_t vnode_refed;
994 int preempt; 905 int preempt;
995 xfs_dinode_t *dip;
996 xfs_iptr_t *ipointer; 906 xfs_iptr_t *ipointer;
997#ifdef DEBUG 907#ifdef DEBUG
998 boolean_t ipointer_in = B_FALSE; 908 boolean_t ipointer_in = B_FALSE;
@@ -1045,6 +955,8 @@ xfs_sync_inodes(
1045 955
1046#define XFS_PREEMPT_MASK 0x7f 956#define XFS_PREEMPT_MASK 0x7f
1047 957
958 ASSERT(!(flags & SYNC_BDFLUSH));
959
1048 if (bypassed) 960 if (bypassed)
1049 *bypassed = 0; 961 *bypassed = 0;
1050 if (mp->m_flags & XFS_MOUNT_RDONLY) 962 if (mp->m_flags & XFS_MOUNT_RDONLY)
@@ -1057,7 +969,7 @@ xfs_sync_inodes(
1057 ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP); 969 ipointer = (xfs_iptr_t *)kmem_zalloc(sizeof(xfs_iptr_t), KM_SLEEP);
1058 970
1059 fflag = XFS_B_ASYNC; /* default is don't wait */ 971 fflag = XFS_B_ASYNC; /* default is don't wait */
1060 if (flags & (SYNC_BDFLUSH | SYNC_DELWRI)) 972 if (flags & SYNC_DELWRI)
1061 fflag = XFS_B_DELWRI; 973 fflag = XFS_B_DELWRI;
1062 if (flags & SYNC_WAIT) 974 if (flags & SYNC_WAIT)
1063 fflag = 0; /* synchronous overrides all */ 975 fflag = 0; /* synchronous overrides all */
@@ -1147,24 +1059,6 @@ xfs_sync_inodes(
1147 } 1059 }
1148 1060
1149 /* 1061 /*
1150 * If this is just vfs_sync() or pflushd() calling
1151 * then we can skip inodes for which it looks like
1152 * there is nothing to do. Since we don't have the
1153 * inode locked this is racy, but these are periodic
1154 * calls so it doesn't matter. For the others we want
1155 * to know for sure, so we at least try to lock them.
1156 */
1157 if (flags & SYNC_BDFLUSH) {
1158 if (((ip->i_itemp == NULL) ||
1159 !(ip->i_itemp->ili_format.ilf_fields &
1160 XFS_ILOG_ALL)) &&
1161 (ip->i_update_core == 0)) {
1162 ip = ip->i_mnext;
1163 continue;
1164 }
1165 }
1166
1167 /*
1168 * Try to lock without sleeping. We're out of order with 1062 * Try to lock without sleeping. We're out of order with
1169 * the inode list lock here, so if we fail we need to drop 1063 * the inode list lock here, so if we fail we need to drop
1170 * the mount lock and try again. If we're called from 1064 * the mount lock and try again. If we're called from
@@ -1181,7 +1075,7 @@ xfs_sync_inodes(
1181 * it. 1075 * it.
1182 */ 1076 */
1183 if (xfs_ilock_nowait(ip, lock_flags) == 0) { 1077 if (xfs_ilock_nowait(ip, lock_flags) == 0) {
1184 if ((flags & SYNC_BDFLUSH) || (vp == NULL)) { 1078 if (vp == NULL) {
1185 ip = ip->i_mnext; 1079 ip = ip->i_mnext;
1186 continue; 1080 continue;
1187 } 1081 }
@@ -1242,160 +1136,27 @@ xfs_sync_inodes(
1242 xfs_ilock(ip, XFS_ILOCK_SHARED); 1136 xfs_ilock(ip, XFS_ILOCK_SHARED);
1243 } 1137 }
1244 1138
1245 if (flags & SYNC_BDFLUSH) { 1139 if ((flags & SYNC_ATTR) &&
1246 if ((flags & SYNC_ATTR) && 1140 (ip->i_update_core ||
1247 ((ip->i_update_core) || 1141 (ip->i_itemp && ip->i_itemp->ili_format.ilf_fields))) {
1248 ((ip->i_itemp != NULL) && 1142 if (mount_locked)
1249 (ip->i_itemp->ili_format.ilf_fields != 0)))) { 1143 IPOINTER_INSERT(ip, mp);
1250
1251 /* Insert marker and drop lock if not already
1252 * done.
1253 */
1254 if (mount_locked) {
1255 IPOINTER_INSERT(ip, mp);
1256 }
1257
1258 /*
1259 * We don't want the periodic flushing of the
1260 * inodes by vfs_sync() to interfere with
1261 * I/O to the file, especially read I/O
1262 * where it is only the access time stamp
1263 * that is being flushed out. To prevent
1264 * long periods where we have both inode
1265 * locks held shared here while reading the
1266 * inode's buffer in from disk, we drop the
1267 * inode lock while reading in the inode
1268 * buffer. We have to release the buffer
1269 * and reacquire the inode lock so that they
1270 * are acquired in the proper order (inode
1271 * locks first). The buffer will go at the
1272 * end of the lru chain, though, so we can
1273 * expect it to still be there when we go
1274 * for it again in xfs_iflush().
1275 */
1276 if ((xfs_ipincount(ip) == 0) &&
1277 xfs_iflock_nowait(ip)) {
1278
1279 xfs_ifunlock(ip);
1280 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1281
1282 error = xfs_itobp(mp, NULL, ip,
1283 &dip, &bp, 0, 0);
1284 if (!error) {
1285 xfs_buf_relse(bp);
1286 } else {
1287 /* Bailing out, remove the
1288 * marker and free it.
1289 */
1290 XFS_MOUNT_ILOCK(mp);
1291 IPOINTER_REMOVE(ip, mp);
1292 XFS_MOUNT_IUNLOCK(mp);
1293
1294 ASSERT(!(lock_flags &
1295 XFS_IOLOCK_SHARED));
1296
1297 kmem_free(ipointer,
1298 sizeof(xfs_iptr_t));
1299 return (0);
1300 }
1301
1302 /*
1303 * Since we dropped the inode lock,
1304 * the inode may have been reclaimed.
1305 * Therefore, we reacquire the mount
1306 * lock and check to see if we were the
1307 * inode reclaimed. If this happened
1308 * then the ipointer marker will no
1309 * longer point back at us. In this
1310 * case, move ip along to the inode
1311 * after the marker, remove the marker
1312 * and continue.
1313 */
1314 XFS_MOUNT_ILOCK(mp);
1315 mount_locked = B_TRUE;
1316
1317 if (ip != ipointer->ip_mprev) {
1318 IPOINTER_REMOVE(ip, mp);
1319
1320 ASSERT(!vnode_refed);
1321 ASSERT(!(lock_flags &
1322 XFS_IOLOCK_SHARED));
1323 continue;
1324 }
1325
1326 ASSERT(ip->i_mount == mp);
1327
1328 if (xfs_ilock_nowait(ip,
1329 XFS_ILOCK_SHARED) == 0) {
1330 ASSERT(ip->i_mount == mp);
1331 /*
1332 * We failed to reacquire
1333 * the inode lock without
1334 * sleeping, so just skip
1335 * the inode for now. We
1336 * clear the ILOCK bit from
1337 * the lock_flags so that we
1338 * won't try to drop a lock
1339 * we don't hold below.
1340 */
1341 lock_flags &= ~XFS_ILOCK_SHARED;
1342 IPOINTER_REMOVE(ip_next, mp);
1343 } else if ((xfs_ipincount(ip) == 0) &&
1344 xfs_iflock_nowait(ip)) {
1345 ASSERT(ip->i_mount == mp);
1346 /*
1347 * Since this is vfs_sync()
1348 * calling we only flush the
1349 * inode out if we can lock
1350 * it without sleeping and
1351 * it is not pinned. Drop
1352 * the mount lock here so
1353 * that we don't hold it for
1354 * too long. We already have
1355 * a marker in the list here.
1356 */
1357 XFS_MOUNT_IUNLOCK(mp);
1358 mount_locked = B_FALSE;
1359 error = xfs_iflush(ip,
1360 XFS_IFLUSH_DELWRI);
1361 } else {
1362 ASSERT(ip->i_mount == mp);
1363 IPOINTER_REMOVE(ip_next, mp);
1364 }
1365 }
1366
1367 }
1368 1144
1369 } else { 1145 if (flags & SYNC_WAIT) {
1370 if ((flags & SYNC_ATTR) && 1146 xfs_iflock(ip);
1371 ((ip->i_update_core) || 1147 error = xfs_iflush(ip, XFS_IFLUSH_SYNC);
1372 ((ip->i_itemp != NULL) &&
1373 (ip->i_itemp->ili_format.ilf_fields != 0)))) {
1374 if (mount_locked) {
1375 IPOINTER_INSERT(ip, mp);
1376 }
1377 1148
1378 if (flags & SYNC_WAIT) { 1149 /*
1379 xfs_iflock(ip); 1150 * If we can't acquire the flush lock, then the inode
1380 error = xfs_iflush(ip, 1151 * is already being flushed so don't bother waiting.
1381 XFS_IFLUSH_SYNC); 1152 *
1382 } else { 1153 * If we can lock it then do a delwri flush so we can
1383 /* 1154 * combine multiple inode flushes in each disk write.
1384 * If we can't acquire the flush 1155 */
1385 * lock, then the inode is already 1156 } else if (xfs_iflock_nowait(ip)) {
1386 * being flushed so don't bother 1157 error = xfs_iflush(ip, XFS_IFLUSH_DELWRI);
1387 * waiting. If we can lock it then 1158 } else if (bypassed) {
1388 * do a delwri flush so we can 1159 (*bypassed)++;
1389 * combine multiple inode flushes
1390 * in each disk write.
1391 */
1392 if (xfs_iflock_nowait(ip)) {
1393 error = xfs_iflush(ip,
1394 XFS_IFLUSH_DELWRI);
1395 }
1396 else if (bypassed)
1397 (*bypassed)++;
1398 }
1399 } 1160 }
1400 } 1161 }
1401 1162
@@ -1627,499 +1388,3 @@ xfs_syncsub(
1627 1388
1628 return XFS_ERROR(last_error); 1389 return XFS_ERROR(last_error);
1629} 1390}
1630
1631/*
1632 * xfs_vget - called by DMAPI and NFSD to get vnode from file handle
1633 */
1634int
1635xfs_vget(
1636 xfs_mount_t *mp,
1637 bhv_vnode_t **vpp,
1638 xfs_fid_t *xfid)
1639{
1640 xfs_inode_t *ip;
1641 int error;
1642 xfs_ino_t ino;
1643 unsigned int igen;
1644
1645 /*
1646 * Invalid. Since handles can be created in user space and passed in
1647 * via gethandle(), this is not cause for a panic.
1648 */
1649 if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len))
1650 return XFS_ERROR(EINVAL);
1651
1652 ino = xfid->fid_ino;
1653 igen = xfid->fid_gen;
1654
1655 /*
1656 * NFS can sometimes send requests for ino 0. Fail them gracefully.
1657 */
1658 if (ino == 0)
1659 return XFS_ERROR(ESTALE);
1660
1661 error = xfs_iget(mp, NULL, ino, 0, XFS_ILOCK_SHARED, &ip, 0);
1662 if (error) {
1663 *vpp = NULL;
1664 return error;
1665 }
1666
1667 if (ip == NULL) {
1668 *vpp = NULL;
1669 return XFS_ERROR(EIO);
1670 }
1671
1672 if (ip->i_d.di_mode == 0 || ip->i_d.di_gen != igen) {
1673 xfs_iput_new(ip, XFS_ILOCK_SHARED);
1674 *vpp = NULL;
1675 return XFS_ERROR(ENOENT);
1676 }
1677
1678 *vpp = XFS_ITOV(ip);
1679 xfs_iunlock(ip, XFS_ILOCK_SHARED);
1680 return 0;
1681}
1682
1683
1684#define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */
1685#define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */
1686#define MNTOPT_LOGDEV "logdev" /* log device */
1687#define MNTOPT_RTDEV "rtdev" /* realtime I/O device */
1688#define MNTOPT_BIOSIZE "biosize" /* log2 of preferred buffered io size */
1689#define MNTOPT_WSYNC "wsync" /* safe-mode nfs compatible mount */
1690#define MNTOPT_INO64 "ino64" /* force inodes into 64-bit range */
1691#define MNTOPT_NOALIGN "noalign" /* turn off stripe alignment */
1692#define MNTOPT_SWALLOC "swalloc" /* turn on stripe width allocation */
1693#define MNTOPT_SUNIT "sunit" /* data volume stripe unit */
1694#define MNTOPT_SWIDTH "swidth" /* data volume stripe width */
1695#define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */
1696#define MNTOPT_MTPT "mtpt" /* filesystem mount point */
1697#define MNTOPT_GRPID "grpid" /* group-ID from parent directory */
1698#define MNTOPT_NOGRPID "nogrpid" /* group-ID from current process */
1699#define MNTOPT_BSDGROUPS "bsdgroups" /* group-ID from parent directory */
1700#define MNTOPT_SYSVGROUPS "sysvgroups" /* group-ID from current process */
1701#define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */
1702#define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */
1703#define MNTOPT_BARRIER "barrier" /* use writer barriers for log write and
1704 * unwritten extent conversion */
1705#define MNTOPT_NOBARRIER "nobarrier" /* .. disable */
1706#define MNTOPT_OSYNCISOSYNC "osyncisosync" /* o_sync is REALLY o_sync */
1707#define MNTOPT_64BITINODE "inode64" /* inodes can be allocated anywhere */
1708#define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */
1709#define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */
1710#define MNTOPT_LARGEIO "largeio" /* report large I/O sizes in stat() */
1711#define MNTOPT_NOLARGEIO "nolargeio" /* do not report large I/O sizes
1712 * in stat(). */
1713#define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */
1714#define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */
1715#define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */
1716#define MNTOPT_QUOTA "quota" /* disk quotas (user) */
1717#define MNTOPT_NOQUOTA "noquota" /* no quotas */
1718#define MNTOPT_USRQUOTA "usrquota" /* user quota enabled */
1719#define MNTOPT_GRPQUOTA "grpquota" /* group quota enabled */
1720#define MNTOPT_PRJQUOTA "prjquota" /* project quota enabled */
1721#define MNTOPT_UQUOTA "uquota" /* user quota (IRIX variant) */
1722#define MNTOPT_GQUOTA "gquota" /* group quota (IRIX variant) */
1723#define MNTOPT_PQUOTA "pquota" /* project quota (IRIX variant) */
1724#define MNTOPT_UQUOTANOENF "uqnoenforce"/* user quota limit enforcement */
1725#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
1726#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
1727#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
1728#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
1729#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
1730#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
1731
1732STATIC unsigned long
1733suffix_strtoul(char *s, char **endp, unsigned int base)
1734{
1735 int last, shift_left_factor = 0;
1736 char *value = s;
1737
1738 last = strlen(value) - 1;
1739 if (value[last] == 'K' || value[last] == 'k') {
1740 shift_left_factor = 10;
1741 value[last] = '\0';
1742 }
1743 if (value[last] == 'M' || value[last] == 'm') {
1744 shift_left_factor = 20;
1745 value[last] = '\0';
1746 }
1747 if (value[last] == 'G' || value[last] == 'g') {
1748 shift_left_factor = 30;
1749 value[last] = '\0';
1750 }
1751
1752 return simple_strtoul((const char *)s, endp, base) << shift_left_factor;
1753}
1754
1755int
1756xfs_parseargs(
1757 struct xfs_mount *mp,
1758 char *options,
1759 struct xfs_mount_args *args,
1760 int update)
1761{
1762 char *this_char, *value, *eov;
1763 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1764 int iosize;
1765 int ikeep = 0;
1766
1767 args->flags |= XFSMNT_BARRIER;
1768 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1769
1770 if (!options)
1771 goto done;
1772
1773 iosize = dsunit = dswidth = vol_dsunit = vol_dswidth = 0;
1774
1775 while ((this_char = strsep(&options, ",")) != NULL) {
1776 if (!*this_char)
1777 continue;
1778 if ((value = strchr(this_char, '=')) != NULL)
1779 *value++ = 0;
1780
1781 if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
1782 if (!value || !*value) {
1783 cmn_err(CE_WARN,
1784 "XFS: %s option requires an argument",
1785 this_char);
1786 return EINVAL;
1787 }
1788 args->logbufs = simple_strtoul(value, &eov, 10);
1789 } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
1790 if (!value || !*value) {
1791 cmn_err(CE_WARN,
1792 "XFS: %s option requires an argument",
1793 this_char);
1794 return EINVAL;
1795 }
1796 args->logbufsize = suffix_strtoul(value, &eov, 10);
1797 } else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
1798 if (!value || !*value) {
1799 cmn_err(CE_WARN,
1800 "XFS: %s option requires an argument",
1801 this_char);
1802 return EINVAL;
1803 }
1804 strncpy(args->logname, value, MAXNAMELEN);
1805 } else if (!strcmp(this_char, MNTOPT_MTPT)) {
1806 if (!value || !*value) {
1807 cmn_err(CE_WARN,
1808 "XFS: %s option requires an argument",
1809 this_char);
1810 return EINVAL;
1811 }
1812 strncpy(args->mtpt, value, MAXNAMELEN);
1813 } else if (!strcmp(this_char, MNTOPT_RTDEV)) {
1814 if (!value || !*value) {
1815 cmn_err(CE_WARN,
1816 "XFS: %s option requires an argument",
1817 this_char);
1818 return EINVAL;
1819 }
1820 strncpy(args->rtname, value, MAXNAMELEN);
1821 } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
1822 if (!value || !*value) {
1823 cmn_err(CE_WARN,
1824 "XFS: %s option requires an argument",
1825 this_char);
1826 return EINVAL;
1827 }
1828 iosize = simple_strtoul(value, &eov, 10);
1829 args->flags |= XFSMNT_IOSIZE;
1830 args->iosizelog = (uint8_t) iosize;
1831 } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
1832 if (!value || !*value) {
1833 cmn_err(CE_WARN,
1834 "XFS: %s option requires an argument",
1835 this_char);
1836 return EINVAL;
1837 }
1838 iosize = suffix_strtoul(value, &eov, 10);
1839 args->flags |= XFSMNT_IOSIZE;
1840 args->iosizelog = ffs(iosize) - 1;
1841 } else if (!strcmp(this_char, MNTOPT_GRPID) ||
1842 !strcmp(this_char, MNTOPT_BSDGROUPS)) {
1843 mp->m_flags |= XFS_MOUNT_GRPID;
1844 } else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
1845 !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
1846 mp->m_flags &= ~XFS_MOUNT_GRPID;
1847 } else if (!strcmp(this_char, MNTOPT_WSYNC)) {
1848 args->flags |= XFSMNT_WSYNC;
1849 } else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
1850 args->flags |= XFSMNT_OSYNCISOSYNC;
1851 } else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
1852 args->flags |= XFSMNT_NORECOVERY;
1853 } else if (!strcmp(this_char, MNTOPT_INO64)) {
1854 args->flags |= XFSMNT_INO64;
1855#if !XFS_BIG_INUMS
1856 cmn_err(CE_WARN,
1857 "XFS: %s option not allowed on this system",
1858 this_char);
1859 return EINVAL;
1860#endif
1861 } else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
1862 args->flags |= XFSMNT_NOALIGN;
1863 } else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
1864 args->flags |= XFSMNT_SWALLOC;
1865 } else if (!strcmp(this_char, MNTOPT_SUNIT)) {
1866 if (!value || !*value) {
1867 cmn_err(CE_WARN,
1868 "XFS: %s option requires an argument",
1869 this_char);
1870 return EINVAL;
1871 }
1872 dsunit = simple_strtoul(value, &eov, 10);
1873 } else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
1874 if (!value || !*value) {
1875 cmn_err(CE_WARN,
1876 "XFS: %s option requires an argument",
1877 this_char);
1878 return EINVAL;
1879 }
1880 dswidth = simple_strtoul(value, &eov, 10);
1881 } else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
1882 args->flags &= ~XFSMNT_32BITINODES;
1883#if !XFS_BIG_INUMS
1884 cmn_err(CE_WARN,
1885 "XFS: %s option not allowed on this system",
1886 this_char);
1887 return EINVAL;
1888#endif
1889 } else if (!strcmp(this_char, MNTOPT_NOUUID)) {
1890 args->flags |= XFSMNT_NOUUID;
1891 } else if (!strcmp(this_char, MNTOPT_BARRIER)) {
1892 args->flags |= XFSMNT_BARRIER;
1893 } else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
1894 args->flags &= ~XFSMNT_BARRIER;
1895 } else if (!strcmp(this_char, MNTOPT_IKEEP)) {
1896 ikeep = 1;
1897 args->flags &= ~XFSMNT_IDELETE;
1898 } else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
1899 args->flags |= XFSMNT_IDELETE;
1900 } else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
1901 args->flags2 &= ~XFSMNT2_COMPAT_IOSIZE;
1902 } else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
1903 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1904 } else if (!strcmp(this_char, MNTOPT_ATTR2)) {
1905 args->flags |= XFSMNT_ATTR2;
1906 } else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
1907 args->flags &= ~XFSMNT_ATTR2;
1908 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
1909 args->flags2 |= XFSMNT2_FILESTREAMS;
1910 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
1911 args->flags &= ~(XFSMNT_UQUOTAENF|XFSMNT_UQUOTA);
1912 args->flags &= ~(XFSMNT_GQUOTAENF|XFSMNT_GQUOTA);
1913 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
1914 !strcmp(this_char, MNTOPT_UQUOTA) ||
1915 !strcmp(this_char, MNTOPT_USRQUOTA)) {
1916 args->flags |= XFSMNT_UQUOTA | XFSMNT_UQUOTAENF;
1917 } else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
1918 !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
1919 args->flags |= XFSMNT_UQUOTA;
1920 args->flags &= ~XFSMNT_UQUOTAENF;
1921 } else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
1922 !strcmp(this_char, MNTOPT_PRJQUOTA)) {
1923 args->flags |= XFSMNT_PQUOTA | XFSMNT_PQUOTAENF;
1924 } else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
1925 args->flags |= XFSMNT_PQUOTA;
1926 args->flags &= ~XFSMNT_PQUOTAENF;
1927 } else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
1928 !strcmp(this_char, MNTOPT_GRPQUOTA)) {
1929 args->flags |= XFSMNT_GQUOTA | XFSMNT_GQUOTAENF;
1930 } else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
1931 args->flags |= XFSMNT_GQUOTA;
1932 args->flags &= ~XFSMNT_GQUOTAENF;
1933 } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
1934 args->flags |= XFSMNT_DMAPI;
1935 } else if (!strcmp(this_char, MNTOPT_XDSM)) {
1936 args->flags |= XFSMNT_DMAPI;
1937 } else if (!strcmp(this_char, MNTOPT_DMI)) {
1938 args->flags |= XFSMNT_DMAPI;
1939 } else if (!strcmp(this_char, "ihashsize")) {
1940 cmn_err(CE_WARN,
1941 "XFS: ihashsize no longer used, option is deprecated.");
1942 } else if (!strcmp(this_char, "osyncisdsync")) {
1943 /* no-op, this is now the default */
1944 cmn_err(CE_WARN,
1945 "XFS: osyncisdsync is now the default, option is deprecated.");
1946 } else if (!strcmp(this_char, "irixsgid")) {
1947 cmn_err(CE_WARN,
1948 "XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
1949 } else {
1950 cmn_err(CE_WARN,
1951 "XFS: unknown mount option [%s].", this_char);
1952 return EINVAL;
1953 }
1954 }
1955
1956 if (args->flags & XFSMNT_NORECOVERY) {
1957 if ((mp->m_flags & XFS_MOUNT_RDONLY) == 0) {
1958 cmn_err(CE_WARN,
1959 "XFS: no-recovery mounts must be read-only.");
1960 return EINVAL;
1961 }
1962 }
1963
1964 if ((args->flags & XFSMNT_NOALIGN) && (dsunit || dswidth)) {
1965 cmn_err(CE_WARN,
1966 "XFS: sunit and swidth options incompatible with the noalign option");
1967 return EINVAL;
1968 }
1969
1970 if ((args->flags & XFSMNT_GQUOTA) && (args->flags & XFSMNT_PQUOTA)) {
1971 cmn_err(CE_WARN,
1972 "XFS: cannot mount with both project and group quota");
1973 return EINVAL;
1974 }
1975
1976 if ((args->flags & XFSMNT_DMAPI) && *args->mtpt == '\0') {
1977 printk("XFS: %s option needs the mount point option as well\n",
1978 MNTOPT_DMAPI);
1979 return EINVAL;
1980 }
1981
1982 if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
1983 cmn_err(CE_WARN,
1984 "XFS: sunit and swidth must be specified together");
1985 return EINVAL;
1986 }
1987
1988 if (dsunit && (dswidth % dsunit != 0)) {
1989 cmn_err(CE_WARN,
1990 "XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
1991 dswidth, dsunit);
1992 return EINVAL;
1993 }
1994
1995 /*
1996 * Applications using DMI filesystems often expect the
1997 * inode generation number to be monotonically increasing.
1998 * If we delete inode chunks we break this assumption, so
1999 * keep unused inode chunks on disk for DMI filesystems
2000 * until we come up with a better solution.
2001 * Note that if "ikeep" or "noikeep" mount options are
2002 * supplied, then they are honored.
2003 */
2004 if (!(args->flags & XFSMNT_DMAPI) && !ikeep)
2005 args->flags |= XFSMNT_IDELETE;
2006
2007 if ((args->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
2008 if (dsunit) {
2009 args->sunit = dsunit;
2010 args->flags |= XFSMNT_RETERR;
2011 } else {
2012 args->sunit = vol_dsunit;
2013 }
2014 dswidth ? (args->swidth = dswidth) :
2015 (args->swidth = vol_dswidth);
2016 } else {
2017 args->sunit = args->swidth = 0;
2018 }
2019
2020done:
2021 if (args->flags & XFSMNT_32BITINODES)
2022 mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
2023 if (args->flags2)
2024 args->flags |= XFSMNT_FLAGS2;
2025 return 0;
2026}
2027
2028int
2029xfs_showargs(
2030 struct xfs_mount *mp,
2031 struct seq_file *m)
2032{
2033 static struct proc_xfs_info {
2034 int flag;
2035 char *str;
2036 } xfs_info[] = {
2037 /* the few simple ones we can get from the mount struct */
2038 { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC },
2039 { XFS_MOUNT_INO64, "," MNTOPT_INO64 },
2040 { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN },
2041 { XFS_MOUNT_SWALLOC, "," MNTOPT_SWALLOC },
2042 { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID },
2043 { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY },
2044 { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
2045 { 0, NULL }
2046 };
2047 struct proc_xfs_info *xfs_infop;
2048
2049 for (xfs_infop = xfs_info; xfs_infop->flag; xfs_infop++) {
2050 if (mp->m_flags & xfs_infop->flag)
2051 seq_puts(m, xfs_infop->str);
2052 }
2053
2054 if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)
2055 seq_printf(m, "," MNTOPT_ALLOCSIZE "=%dk",
2056 (int)(1 << mp->m_writeio_log) >> 10);
2057
2058 if (mp->m_logbufs > 0)
2059 seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs);
2060 if (mp->m_logbsize > 0)
2061 seq_printf(m, "," MNTOPT_LOGBSIZE "=%dk", mp->m_logbsize >> 10);
2062
2063 if (mp->m_logname)
2064 seq_printf(m, "," MNTOPT_LOGDEV "=%s", mp->m_logname);
2065 if (mp->m_rtname)
2066 seq_printf(m, "," MNTOPT_RTDEV "=%s", mp->m_rtname);
2067
2068 if (mp->m_dalign > 0)
2069 seq_printf(m, "," MNTOPT_SUNIT "=%d",
2070 (int)XFS_FSB_TO_BB(mp, mp->m_dalign));
2071 if (mp->m_swidth > 0)
2072 seq_printf(m, "," MNTOPT_SWIDTH "=%d",
2073 (int)XFS_FSB_TO_BB(mp, mp->m_swidth));
2074
2075 if (!(mp->m_flags & XFS_MOUNT_IDELETE))
2076 seq_printf(m, "," MNTOPT_IKEEP);
2077 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
2078 seq_printf(m, "," MNTOPT_LARGEIO);
2079
2080 if (!(mp->m_flags & XFS_MOUNT_SMALL_INUMS))
2081 seq_printf(m, "," MNTOPT_64BITINODE);
2082 if (mp->m_flags & XFS_MOUNT_GRPID)
2083 seq_printf(m, "," MNTOPT_GRPID);
2084
2085 if (mp->m_qflags & XFS_UQUOTA_ACCT) {
2086 if (mp->m_qflags & XFS_UQUOTA_ENFD)
2087 seq_puts(m, "," MNTOPT_USRQUOTA);
2088 else
2089 seq_puts(m, "," MNTOPT_UQUOTANOENF);
2090 }
2091
2092 if (mp->m_qflags & XFS_PQUOTA_ACCT) {
2093 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2094 seq_puts(m, "," MNTOPT_PRJQUOTA);
2095 else
2096 seq_puts(m, "," MNTOPT_PQUOTANOENF);
2097 }
2098
2099 if (mp->m_qflags & XFS_GQUOTA_ACCT) {
2100 if (mp->m_qflags & XFS_OQUOTA_ENFD)
2101 seq_puts(m, "," MNTOPT_GRPQUOTA);
2102 else
2103 seq_puts(m, "," MNTOPT_GQUOTANOENF);
2104 }
2105
2106 if (!(mp->m_qflags & XFS_ALL_QUOTA_ACCT))
2107 seq_puts(m, "," MNTOPT_NOQUOTA);
2108
2109 if (mp->m_flags & XFS_MOUNT_DMAPI)
2110 seq_puts(m, "," MNTOPT_DMAPI);
2111 return 0;
2112}
2113
2114/*
2115 * Second stage of a freeze. The data is already frozen so we only
2116 * need to take care of themetadata. Once that's done write a dummy
2117 * record to dirty the log in case of a crash while frozen.
2118 */
2119void
2120xfs_freeze(
2121 xfs_mount_t *mp)
2122{
2123 xfs_attr_quiesce(mp);
2124 xfs_fs_log_dummy(mp);
2125}