diff options
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 793 |
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 | ||
61 | int | 61 | int __init |
62 | xfs_init(void) | 62 | xfs_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 | ||
155 | void | 150 | void __exit |
156 | xfs_cleanup(void) | 151 | xfs_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 | */ |
697 | STATIC void | 684 | void |
698 | xfs_attr_quiesce( | 685 | xfs_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 | */ | ||
830 | int | ||
831 | xfs_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 | */ | ||
850 | int | ||
851 | xfs_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 | */ | ||
1634 | int | ||
1635 | xfs_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 | |||
1732 | STATIC unsigned long | ||
1733 | suffix_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 | |||
1755 | int | ||
1756 | xfs_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 | |||
2020 | done: | ||
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 | |||
2028 | int | ||
2029 | xfs_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 | */ | ||
2119 | void | ||
2120 | xfs_freeze( | ||
2121 | xfs_mount_t *mp) | ||
2122 | { | ||
2123 | xfs_attr_quiesce(mp); | ||
2124 | xfs_fs_log_dummy(mp); | ||
2125 | } | ||