diff options
Diffstat (limited to 'fs/xfs/xfs_vfsops.c')
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 159 |
1 files changed, 94 insertions, 65 deletions
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 65c561201cb8..11f5ea29a038 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #include "xfs_acl.h" | 51 | #include "xfs_acl.h" |
52 | #include "xfs_attr.h" | 52 | #include "xfs_attr.h" |
53 | #include "xfs_clnt.h" | 53 | #include "xfs_clnt.h" |
54 | #include "xfs_mru_cache.h" | ||
55 | #include "xfs_filestream.h" | ||
54 | #include "xfs_fsops.h" | 56 | #include "xfs_fsops.h" |
55 | 57 | ||
56 | STATIC int xfs_sync(bhv_desc_t *, int, cred_t *); | 58 | STATIC int xfs_sync(bhv_desc_t *, int, cred_t *); |
@@ -81,6 +83,8 @@ xfs_init(void) | |||
81 | xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); | 83 | xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); |
82 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); | 84 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); |
83 | xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); | 85 | xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); |
86 | xfs_mru_cache_init(); | ||
87 | xfs_filestream_init(); | ||
84 | 88 | ||
85 | /* | 89 | /* |
86 | * The size of the zone allocated buf log item is the maximum | 90 | * The size of the zone allocated buf log item is the maximum |
@@ -164,6 +168,8 @@ xfs_cleanup(void) | |||
164 | xfs_cleanup_procfs(); | 168 | xfs_cleanup_procfs(); |
165 | xfs_sysctl_unregister(); | 169 | xfs_sysctl_unregister(); |
166 | xfs_refcache_destroy(); | 170 | xfs_refcache_destroy(); |
171 | xfs_filestream_uninit(); | ||
172 | xfs_mru_cache_uninit(); | ||
167 | xfs_acl_zone_destroy(xfs_acl_zone); | 173 | xfs_acl_zone_destroy(xfs_acl_zone); |
168 | 174 | ||
169 | #ifdef XFS_DIR2_TRACE | 175 | #ifdef XFS_DIR2_TRACE |
@@ -320,6 +326,9 @@ xfs_start_flags( | |||
320 | else | 326 | else |
321 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 327 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
322 | 328 | ||
329 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
330 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
331 | |||
323 | return 0; | 332 | return 0; |
324 | } | 333 | } |
325 | 334 | ||
@@ -518,6 +527,9 @@ xfs_mount( | |||
518 | if (mp->m_flags & XFS_MOUNT_BARRIER) | 527 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
519 | xfs_mountfs_check_barriers(mp); | 528 | xfs_mountfs_check_barriers(mp); |
520 | 529 | ||
530 | if ((error = xfs_filestream_mount(mp))) | ||
531 | goto error2; | ||
532 | |||
521 | error = XFS_IOINIT(vfsp, args, flags); | 533 | error = XFS_IOINIT(vfsp, args, flags); |
522 | if (error) | 534 | if (error) |
523 | goto error2; | 535 | goto error2; |
@@ -575,6 +587,13 @@ xfs_unmount( | |||
575 | */ | 587 | */ |
576 | xfs_refcache_purge_mp(mp); | 588 | xfs_refcache_purge_mp(mp); |
577 | 589 | ||
590 | /* | ||
591 | * Blow away any referenced inode in the filestreams cache. | ||
592 | * This can and will cause log traffic as inodes go inactive | ||
593 | * here. | ||
594 | */ | ||
595 | xfs_filestream_unmount(mp); | ||
596 | |||
578 | XFS_bflush(mp->m_ddev_targp); | 597 | XFS_bflush(mp->m_ddev_targp); |
579 | error = xfs_unmount_flush(mp, 0); | 598 | error = xfs_unmount_flush(mp, 0); |
580 | if (error) | 599 | if (error) |
@@ -640,7 +659,7 @@ xfs_quiesce_fs( | |||
640 | * we can write the unmount record. | 659 | * we can write the unmount record. |
641 | */ | 660 | */ |
642 | do { | 661 | do { |
643 | xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, NULL); | 662 | xfs_syncsub(mp, SYNC_INODE_QUIESCE, NULL); |
644 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | 663 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); |
645 | if (!pincount) { | 664 | if (!pincount) { |
646 | delay(50); | 665 | delay(50); |
@@ -651,6 +670,30 @@ xfs_quiesce_fs( | |||
651 | return 0; | 670 | return 0; |
652 | } | 671 | } |
653 | 672 | ||
673 | /* | ||
674 | * Second stage of a quiesce. The data is already synced, now we have to take | ||
675 | * care of the metadata. New transactions are already blocked, so we need to | ||
676 | * wait for any remaining transactions to drain out before proceding. | ||
677 | */ | ||
678 | STATIC void | ||
679 | xfs_attr_quiesce( | ||
680 | xfs_mount_t *mp) | ||
681 | { | ||
682 | /* wait for all modifications to complete */ | ||
683 | while (atomic_read(&mp->m_active_trans) > 0) | ||
684 | delay(100); | ||
685 | |||
686 | /* flush inodes and push all remaining buffers out to disk */ | ||
687 | xfs_quiesce_fs(mp); | ||
688 | |||
689 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
690 | |||
691 | /* Push the superblock and write an unmount record */ | ||
692 | xfs_log_sbcount(mp, 1); | ||
693 | xfs_log_unmount_write(mp); | ||
694 | xfs_unmountfs_writesb(mp); | ||
695 | } | ||
696 | |||
654 | STATIC int | 697 | STATIC int |
655 | xfs_mntupdate( | 698 | xfs_mntupdate( |
656 | bhv_desc_t *bdp, | 699 | bhv_desc_t *bdp, |
@@ -670,10 +713,9 @@ xfs_mntupdate( | |||
670 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 713 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
671 | } | 714 | } |
672 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ | 715 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ |
673 | bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL); | 716 | xfs_filestream_flush(mp); |
674 | xfs_quiesce_fs(mp); | 717 | bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); |
675 | xfs_log_unmount_write(mp); | 718 | xfs_attr_quiesce(mp); |
676 | xfs_unmountfs_writesb(mp); | ||
677 | vfsp->vfs_flag |= VFS_RDONLY; | 719 | vfsp->vfs_flag |= VFS_RDONLY; |
678 | } | 720 | } |
679 | return 0; | 721 | return 0; |
@@ -887,6 +929,9 @@ xfs_sync( | |||
887 | { | 929 | { |
888 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 930 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
889 | 931 | ||
932 | if (flags & SYNC_IOWAIT) | ||
933 | xfs_filestream_flush(mp); | ||
934 | |||
890 | return xfs_syncsub(mp, flags, NULL); | 935 | return xfs_syncsub(mp, flags, NULL); |
891 | } | 936 | } |
892 | 937 | ||
@@ -1128,58 +1173,41 @@ xfs_sync_inodes( | |||
1128 | * in the inode list. | 1173 | * in the inode list. |
1129 | */ | 1174 | */ |
1130 | 1175 | ||
1131 | if ((flags & SYNC_CLOSE) && (vp != NULL)) { | 1176 | /* |
1132 | /* | 1177 | * If we have to flush data or wait for I/O completion |
1133 | * This is the shutdown case. We just need to | 1178 | * we need to drop the ilock that we currently hold. |
1134 | * flush and invalidate all the pages associated | 1179 | * If we need to drop the lock, insert a marker if we |
1135 | * with the inode. Drop the inode lock since | 1180 | * have not already done so. |
1136 | * we can't hold it across calls to the buffer | 1181 | */ |
1137 | * cache. | 1182 | if ((flags & (SYNC_CLOSE|SYNC_IOWAIT)) || |
1138 | * | 1183 | ((flags & SYNC_DELWRI) && VN_DIRTY(vp))) { |
1139 | * We don't set the VREMAPPING bit in the vnode | 1184 | if (mount_locked) { |
1140 | * here, because we don't hold the vnode lock | 1185 | IPOINTER_INSERT(ip, mp); |
1141 | * exclusively. It doesn't really matter, though, | ||
1142 | * because we only come here when we're shutting | ||
1143 | * down anyway. | ||
1144 | */ | ||
1145 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1146 | |||
1147 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
1148 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); | ||
1149 | } else { | ||
1150 | error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF); | ||
1151 | } | 1186 | } |
1187 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1152 | 1188 | ||
1153 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1189 | if (flags & SYNC_CLOSE) { |
1154 | 1190 | /* Shutdown case. Flush and invalidate. */ | |
1155 | } else if ((flags & SYNC_DELWRI) && (vp != NULL)) { | 1191 | if (XFS_FORCED_SHUTDOWN(mp)) |
1156 | if (VN_DIRTY(vp)) { | 1192 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); |
1157 | /* We need to have dropped the lock here, | 1193 | else |
1158 | * so insert a marker if we have not already | 1194 | error = bhv_vop_flushinval_pages(vp, 0, |
1159 | * done so. | 1195 | -1, FI_REMAPF); |
1160 | */ | 1196 | } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { |
1161 | if (mount_locked) { | ||
1162 | IPOINTER_INSERT(ip, mp); | ||
1163 | } | ||
1164 | |||
1165 | /* | ||
1166 | * Drop the inode lock since we can't hold it | ||
1167 | * across calls to the buffer cache. | ||
1168 | */ | ||
1169 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1170 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, | 1197 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, |
1171 | -1, fflag, FI_NONE); | 1198 | -1, fflag, FI_NONE); |
1172 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
1173 | } | 1199 | } |
1174 | 1200 | ||
1201 | /* | ||
1202 | * When freezing, we need to wait ensure all I/O (including direct | ||
1203 | * I/O) is complete to ensure no further data modification can take | ||
1204 | * place after this point | ||
1205 | */ | ||
1206 | if (flags & SYNC_IOWAIT) | ||
1207 | vn_iowait(vp); | ||
1208 | |||
1209 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
1175 | } | 1210 | } |
1176 | /* | ||
1177 | * When freezing, we need to wait ensure all I/O (including direct | ||
1178 | * I/O) is complete to ensure no further data modification can take | ||
1179 | * place after this point | ||
1180 | */ | ||
1181 | if (flags & SYNC_IOWAIT) | ||
1182 | vn_iowait(vp); | ||
1183 | 1211 | ||
1184 | if (flags & SYNC_BDFLUSH) { | 1212 | if (flags & SYNC_BDFLUSH) { |
1185 | if ((flags & SYNC_ATTR) && | 1213 | if ((flags & SYNC_ATTR) && |
@@ -1514,6 +1542,15 @@ xfs_syncsub( | |||
1514 | } | 1542 | } |
1515 | 1543 | ||
1516 | /* | 1544 | /* |
1545 | * If asked, update the disk superblock with incore counter values if we | ||
1546 | * are using non-persistent counters so that they don't get too far out | ||
1547 | * of sync if we crash or get a forced shutdown. We don't want to force | ||
1548 | * this to disk, just get a transaction into the iclogs.... | ||
1549 | */ | ||
1550 | if (flags & SYNC_SUPER) | ||
1551 | xfs_log_sbcount(mp, 0); | ||
1552 | |||
1553 | /* | ||
1517 | * Now check to see if the log needs a "dummy" transaction. | 1554 | * Now check to see if the log needs a "dummy" transaction. |
1518 | */ | 1555 | */ |
1519 | 1556 | ||
@@ -1645,6 +1682,7 @@ xfs_vget( | |||
1645 | * in stat(). */ | 1682 | * in stat(). */ |
1646 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | 1683 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ |
1647 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 1684 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
1685 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | ||
1648 | 1686 | ||
1649 | STATIC unsigned long | 1687 | STATIC unsigned long |
1650 | suffix_strtoul(char *s, char **endp, unsigned int base) | 1688 | suffix_strtoul(char *s, char **endp, unsigned int base) |
@@ -1831,6 +1869,8 @@ xfs_parseargs( | |||
1831 | args->flags |= XFSMNT_ATTR2; | 1869 | args->flags |= XFSMNT_ATTR2; |
1832 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 1870 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { |
1833 | args->flags &= ~XFSMNT_ATTR2; | 1871 | args->flags &= ~XFSMNT_ATTR2; |
1872 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | ||
1873 | args->flags2 |= XFSMNT2_FILESTREAMS; | ||
1834 | } else if (!strcmp(this_char, "osyncisdsync")) { | 1874 | } else if (!strcmp(this_char, "osyncisdsync")) { |
1835 | /* no-op, this is now the default */ | 1875 | /* no-op, this is now the default */ |
1836 | cmn_err(CE_WARN, | 1876 | cmn_err(CE_WARN, |
@@ -1959,9 +1999,9 @@ xfs_showargs( | |||
1959 | } | 1999 | } |
1960 | 2000 | ||
1961 | /* | 2001 | /* |
1962 | * Second stage of a freeze. The data is already frozen, now we have to take | 2002 | * Second stage of a freeze. The data is already frozen so we only |
1963 | * care of the metadata. New transactions are already blocked, so we need to | 2003 | * need to take care of themetadata. Once that's done write a dummy |
1964 | * wait for any remaining transactions to drain out before proceding. | 2004 | * record to dirty the log in case of a crash while frozen. |
1965 | */ | 2005 | */ |
1966 | STATIC void | 2006 | STATIC void |
1967 | xfs_freeze( | 2007 | xfs_freeze( |
@@ -1969,18 +2009,7 @@ xfs_freeze( | |||
1969 | { | 2009 | { |
1970 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 2010 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
1971 | 2011 | ||
1972 | /* wait for all modifications to complete */ | 2012 | xfs_attr_quiesce(mp); |
1973 | while (atomic_read(&mp->m_active_trans) > 0) | ||
1974 | delay(100); | ||
1975 | |||
1976 | /* flush inodes and push all remaining buffers out to disk */ | ||
1977 | xfs_quiesce_fs(mp); | ||
1978 | |||
1979 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
1980 | |||
1981 | /* Push the superblock and write an unmount record */ | ||
1982 | xfs_log_unmount_write(mp); | ||
1983 | xfs_unmountfs_writesb(mp); | ||
1984 | xfs_fs_log_dummy(mp); | 2013 | xfs_fs_log_dummy(mp); |
1985 | } | 2014 | } |
1986 | 2015 | ||