aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 12:19:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 12:19:22 -0400
commit49d99a2f9c4d033cc3965958a1397b1fad573dd3 (patch)
treecda1849d49d40d2f25773e86605c55bc6745cf1f /fs/xfs/xfs_super.c
parent1c3ddfe5ab886c4dc0443535e95ad8e41c41d0e5 (diff)
parentf074211f6041305b645669464343d504f4e6a290 (diff)
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Pull XFS updates from Ben Myers: "Scalability improvements for dquots, log grant code cleanups, plus bugfixes and cleanups large and small" Fix up various trivial conflicts that were due to some of the earlier patches already having been integrated into v3.3 as bugfixes, and then there were development patches on top of those. Easily merged by just taking the newer version from the pulled branch. * 'for-linus' of git://oss.sgi.com/xfs/xfs: (45 commits) xfs: fallback to vmalloc for large buffers in xfs_getbmap xfs: fallback to vmalloc for large buffers in xfs_attrmulti_attr_get xfs: remove remaining scraps of struct xfs_iomap xfs: fix inode lookup race xfs: clean up minor sparse warnings xfs: remove the global xfs_Gqm structure xfs: remove the per-filesystem list of dquots xfs: use per-filesystem radix trees for dquot lookup xfs: per-filesystem dquot LRU lists xfs: use common code for quota statistics xfs: reimplement fdatasync support xfs: split in-core and on-disk inode log item fields xfs: make xfs_inode_item_size idempotent xfs: log timestamp updates xfs: log file size updates at I/O completion time xfs: log file size updates as part of unwritten extent conversion xfs: do not require an ioend for new EOF calculation xfs: use per-filesystem I/O completion workqueues quota: make Q_XQUOTASYNC a noop xfs: include reservations in quota reporting ...
Diffstat (limited to 'fs/xfs/xfs_super.c')
-rw-r--r--fs/xfs/xfs_super.c164
1 files changed, 85 insertions, 79 deletions
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index baf40e378d35..912442cf0f82 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -324,10 +324,9 @@ xfs_parseargs(
324 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { 324 } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
325 mp->m_flags |= XFS_MOUNT_FILESTREAMS; 325 mp->m_flags |= XFS_MOUNT_FILESTREAMS;
326 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) { 326 } else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
327 mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE | 327 mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
328 XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE | 328 mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
329 XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE | 329 mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
330 XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD);
331 } else if (!strcmp(this_char, MNTOPT_QUOTA) || 330 } else if (!strcmp(this_char, MNTOPT_QUOTA) ||
332 !strcmp(this_char, MNTOPT_UQUOTA) || 331 !strcmp(this_char, MNTOPT_UQUOTA) ||
333 !strcmp(this_char, MNTOPT_USRQUOTA)) { 332 !strcmp(this_char, MNTOPT_USRQUOTA)) {
@@ -760,6 +759,36 @@ xfs_setup_devices(
760 return 0; 759 return 0;
761} 760}
762 761
762STATIC int
763xfs_init_mount_workqueues(
764 struct xfs_mount *mp)
765{
766 mp->m_data_workqueue = alloc_workqueue("xfs-data/%s",
767 WQ_MEM_RECLAIM, 0, mp->m_fsname);
768 if (!mp->m_data_workqueue)
769 goto out;
770
771 mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s",
772 WQ_MEM_RECLAIM, 0, mp->m_fsname);
773 if (!mp->m_unwritten_workqueue)
774 goto out_destroy_data_iodone_queue;
775
776 return 0;
777
778out_destroy_data_iodone_queue:
779 destroy_workqueue(mp->m_data_workqueue);
780out:
781 return -ENOMEM;
782}
783
784STATIC void
785xfs_destroy_mount_workqueues(
786 struct xfs_mount *mp)
787{
788 destroy_workqueue(mp->m_data_workqueue);
789 destroy_workqueue(mp->m_unwritten_workqueue);
790}
791
763/* Catch misguided souls that try to use this interface on XFS */ 792/* Catch misguided souls that try to use this interface on XFS */
764STATIC struct inode * 793STATIC struct inode *
765xfs_fs_alloc_inode( 794xfs_fs_alloc_inode(
@@ -834,91 +863,58 @@ xfs_fs_inode_init_once(
834} 863}
835 864
836/* 865/*
837 * Dirty the XFS inode when mark_inode_dirty_sync() is called so that 866 * This is called by the VFS when dirtying inode metadata. This can happen
838 * we catch unlogged VFS level updates to the inode. 867 * for a few reasons, but we only care about timestamp updates, given that
868 * we handled the rest ourselves. In theory no other calls should happen,
869 * but for example generic_write_end() keeps dirtying the inode after
870 * updating i_size. Thus we check that the flags are exactly I_DIRTY_SYNC,
871 * and skip this call otherwise.
839 * 872 *
840 * We need the barrier() to maintain correct ordering between unlogged 873 * We'll hopefull get a different method just for updating timestamps soon,
841 * updates and the transaction commit code that clears the i_update_core 874 * at which point this hack can go away, and maybe we'll also get real
842 * field. This requires all updates to be completed before marking the 875 * error handling here.
843 * inode dirty.
844 */ 876 */
845STATIC void 877STATIC void
846xfs_fs_dirty_inode( 878xfs_fs_dirty_inode(
847 struct inode *inode,
848 int flags)
849{
850 barrier();
851 XFS_I(inode)->i_update_core = 1;
852}
853
854STATIC int
855xfs_fs_write_inode(
856 struct inode *inode, 879 struct inode *inode,
857 struct writeback_control *wbc) 880 int flags)
858{ 881{
859 struct xfs_inode *ip = XFS_I(inode); 882 struct xfs_inode *ip = XFS_I(inode);
860 struct xfs_mount *mp = ip->i_mount; 883 struct xfs_mount *mp = ip->i_mount;
861 int error = EAGAIN; 884 struct xfs_trans *tp;
862 885 int error;
863 trace_xfs_write_inode(ip);
864
865 if (XFS_FORCED_SHUTDOWN(mp))
866 return -XFS_ERROR(EIO);
867
868 if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) {
869 /*
870 * Make sure the inode has made it it into the log. Instead
871 * of forcing it all the way to stable storage using a
872 * synchronous transaction we let the log force inside the
873 * ->sync_fs call do that for thus, which reduces the number
874 * of synchronous log forces dramatically.
875 */
876 error = xfs_log_dirty_inode(ip, NULL, 0);
877 if (error)
878 goto out;
879 return 0;
880 } else {
881 if (!ip->i_update_core)
882 return 0;
883 886
884 /* 887 if (flags != I_DIRTY_SYNC)
885 * We make this non-blocking if the inode is contended, return 888 return;
886 * EAGAIN to indicate to the caller that they did not succeed.
887 * This prevents the flush path from blocking on inodes inside
888 * another operation right now, they get caught later by
889 * xfs_sync.
890 */
891 if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
892 goto out;
893 889
894 if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip)) 890 trace_xfs_dirty_inode(ip);
895 goto out_unlock;
896 891
897 /* 892 tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
898 * Now we have the flush lock and the inode is not pinned, we 893 error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0);
899 * can check if the inode is really clean as we know that 894 if (error) {
900 * there are no pending transaction completions, it is not 895 xfs_trans_cancel(tp, 0);
901 * waiting on the delayed write queue and there is no IO in 896 goto trouble;
902 * progress.
903 */
904 if (xfs_inode_clean(ip)) {
905 xfs_ifunlock(ip);
906 error = 0;
907 goto out_unlock;
908 }
909 error = xfs_iflush(ip, SYNC_TRYLOCK);
910 } 897 }
911 898 xfs_ilock(ip, XFS_ILOCK_EXCL);
912 out_unlock:
913 xfs_iunlock(ip, XFS_ILOCK_SHARED);
914 out:
915 /* 899 /*
916 * if we failed to write out the inode then mark 900 * Grab all the latest timestamps from the Linux inode.
917 * it dirty again so we'll try again later.
918 */ 901 */
902 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
903 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
904 ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec;
905 ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec;
906 ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
907 ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec;
908
909 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
910 xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
911 error = xfs_trans_commit(tp, 0);
919 if (error) 912 if (error)
920 xfs_mark_inode_dirty_sync(ip); 913 goto trouble;
921 return -error; 914 return;
915
916trouble:
917 xfs_warn(mp, "failed to update timestamps for inode 0x%llx", ip->i_ino);
922} 918}
923 919
924STATIC void 920STATIC void
@@ -983,6 +979,7 @@ xfs_fs_put_super(
983 xfs_unmountfs(mp); 979 xfs_unmountfs(mp);
984 xfs_freesb(mp); 980 xfs_freesb(mp);
985 xfs_icsb_destroy_counters(mp); 981 xfs_icsb_destroy_counters(mp);
982 xfs_destroy_mount_workqueues(mp);
986 xfs_close_devices(mp); 983 xfs_close_devices(mp);
987 xfs_free_fsname(mp); 984 xfs_free_fsname(mp);
988 kfree(mp); 985 kfree(mp);
@@ -1309,10 +1306,14 @@ xfs_fs_fill_super(
1309 if (error) 1306 if (error)
1310 goto out_free_fsname; 1307 goto out_free_fsname;
1311 1308
1312 error = xfs_icsb_init_counters(mp); 1309 error = xfs_init_mount_workqueues(mp);
1313 if (error) 1310 if (error)
1314 goto out_close_devices; 1311 goto out_close_devices;
1315 1312
1313 error = xfs_icsb_init_counters(mp);
1314 if (error)
1315 goto out_destroy_workqueues;
1316
1316 error = xfs_readsb(mp, flags); 1317 error = xfs_readsb(mp, flags);
1317 if (error) 1318 if (error)
1318 goto out_destroy_counters; 1319 goto out_destroy_counters;
@@ -1376,6 +1377,8 @@ xfs_fs_fill_super(
1376 xfs_freesb(mp); 1377 xfs_freesb(mp);
1377 out_destroy_counters: 1378 out_destroy_counters:
1378 xfs_icsb_destroy_counters(mp); 1379 xfs_icsb_destroy_counters(mp);
1380out_destroy_workqueues:
1381 xfs_destroy_mount_workqueues(mp);
1379 out_close_devices: 1382 out_close_devices:
1380 xfs_close_devices(mp); 1383 xfs_close_devices(mp);
1381 out_free_fsname: 1384 out_free_fsname:
@@ -1429,7 +1432,6 @@ static const struct super_operations xfs_super_operations = {
1429 .alloc_inode = xfs_fs_alloc_inode, 1432 .alloc_inode = xfs_fs_alloc_inode,
1430 .destroy_inode = xfs_fs_destroy_inode, 1433 .destroy_inode = xfs_fs_destroy_inode,
1431 .dirty_inode = xfs_fs_dirty_inode, 1434 .dirty_inode = xfs_fs_dirty_inode,
1432 .write_inode = xfs_fs_write_inode,
1433 .evict_inode = xfs_fs_evict_inode, 1435 .evict_inode = xfs_fs_evict_inode,
1434 .put_super = xfs_fs_put_super, 1436 .put_super = xfs_fs_put_super,
1435 .sync_fs = xfs_fs_sync_fs, 1437 .sync_fs = xfs_fs_sync_fs,
@@ -1651,13 +1653,17 @@ init_xfs_fs(void)
1651 if (error) 1653 if (error)
1652 goto out_cleanup_procfs; 1654 goto out_cleanup_procfs;
1653 1655
1654 vfs_initquota(); 1656 error = xfs_qm_init();
1657 if (error)
1658 goto out_sysctl_unregister;
1655 1659
1656 error = register_filesystem(&xfs_fs_type); 1660 error = register_filesystem(&xfs_fs_type);
1657 if (error) 1661 if (error)
1658 goto out_sysctl_unregister; 1662 goto out_qm_exit;
1659 return 0; 1663 return 0;
1660 1664
1665 out_qm_exit:
1666 xfs_qm_exit();
1661 out_sysctl_unregister: 1667 out_sysctl_unregister:
1662 xfs_sysctl_unregister(); 1668 xfs_sysctl_unregister();
1663 out_cleanup_procfs: 1669 out_cleanup_procfs:
@@ -1679,7 +1685,7 @@ init_xfs_fs(void)
1679STATIC void __exit 1685STATIC void __exit
1680exit_xfs_fs(void) 1686exit_xfs_fs(void)
1681{ 1687{
1682 vfs_exitquota(); 1688 xfs_qm_exit();
1683 unregister_filesystem(&xfs_fs_type); 1689 unregister_filesystem(&xfs_fs_type);
1684 xfs_sysctl_unregister(); 1690 xfs_sysctl_unregister();
1685 xfs_cleanup_procfs(); 1691 xfs_cleanup_procfs();