aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <david@fromorbit.com>2014-11-27 22:52:02 -0500
committerDave Chinner <david@fromorbit.com>2014-11-27 22:52:02 -0500
commit4bd47c1bf4a64225a855ed77e259eeb37944ba33 (patch)
tree79aed8aaf3b04595d55762421d25d7ea2a5a5318 /fs/xfs
parent002758992693ae63c04122603ea9261a0a58d728 (diff)
parentdb52d09ecbf85c54e263a9d1ebfb615a9b2b3ba6 (diff)
Merge branch 'xfs-misc-fixes-for-3.19-1' into for-next
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_buf.c14
-rw-r--r--fs/xfs/xfs_inode.c15
-rw-r--r--fs/xfs/xfs_log.c2
-rw-r--r--fs/xfs/xfs_mount.c29
-rw-r--r--fs/xfs/xfs_mount.h3
-rw-r--r--fs/xfs/xfs_qm_syscalls.c26
-rw-r--r--fs/xfs/xfs_super.c11
7 files changed, 52 insertions, 48 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 24b4ebea0d4d..d083889535a2 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -44,8 +44,6 @@
44 44
45static kmem_zone_t *xfs_buf_zone; 45static kmem_zone_t *xfs_buf_zone;
46 46
47static struct workqueue_struct *xfslogd_workqueue;
48
49#ifdef XFS_BUF_LOCK_TRACKING 47#ifdef XFS_BUF_LOCK_TRACKING
50# define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid) 48# define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid)
51# define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1) 49# define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1)
@@ -463,7 +461,7 @@ _xfs_buf_find(
463 * have to check that the buffer falls within the filesystem bounds. 461 * have to check that the buffer falls within the filesystem bounds.
464 */ 462 */
465 eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks); 463 eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
466 if (blkno >= eofs) { 464 if (blkno < 0 || blkno >= eofs) {
467 /* 465 /*
468 * XXX (dgc): we should really be returning -EFSCORRUPTED here, 466 * XXX (dgc): we should really be returning -EFSCORRUPTED here,
469 * but none of the higher level infrastructure supports 467 * but none of the higher level infrastructure supports
@@ -1053,7 +1051,7 @@ xfs_buf_ioend_async(
1053 struct xfs_buf *bp) 1051 struct xfs_buf *bp)
1054{ 1052{
1055 INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work); 1053 INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work);
1056 queue_work(xfslogd_workqueue, &bp->b_iodone_work); 1054 queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work);
1057} 1055}
1058 1056
1059void 1057void
@@ -1882,15 +1880,8 @@ xfs_buf_init(void)
1882 if (!xfs_buf_zone) 1880 if (!xfs_buf_zone)
1883 goto out; 1881 goto out;
1884 1882
1885 xfslogd_workqueue = alloc_workqueue("xfslogd",
1886 WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZABLE, 1);
1887 if (!xfslogd_workqueue)
1888 goto out_free_buf_zone;
1889
1890 return 0; 1883 return 0;
1891 1884
1892 out_free_buf_zone:
1893 kmem_zone_destroy(xfs_buf_zone);
1894 out: 1885 out:
1895 return -ENOMEM; 1886 return -ENOMEM;
1896} 1887}
@@ -1898,6 +1889,5 @@ xfs_buf_init(void)
1898void 1889void
1899xfs_buf_terminate(void) 1890xfs_buf_terminate(void)
1900{ 1891{
1901 destroy_workqueue(xfslogd_workqueue);
1902 kmem_zone_destroy(xfs_buf_zone); 1892 kmem_zone_destroy(xfs_buf_zone);
1903} 1893}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 8ed049d1e332..2ffb80267e37 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1082,7 +1082,7 @@ xfs_create(
1082 struct xfs_dquot *udqp = NULL; 1082 struct xfs_dquot *udqp = NULL;
1083 struct xfs_dquot *gdqp = NULL; 1083 struct xfs_dquot *gdqp = NULL;
1084 struct xfs_dquot *pdqp = NULL; 1084 struct xfs_dquot *pdqp = NULL;
1085 struct xfs_trans_res tres; 1085 struct xfs_trans_res *tres;
1086 uint resblks; 1086 uint resblks;
1087 1087
1088 trace_xfs_create(dp, name); 1088 trace_xfs_create(dp, name);
@@ -1105,13 +1105,11 @@ xfs_create(
1105 if (is_dir) { 1105 if (is_dir) {
1106 rdev = 0; 1106 rdev = 0;
1107 resblks = XFS_MKDIR_SPACE_RES(mp, name->len); 1107 resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
1108 tres.tr_logres = M_RES(mp)->tr_mkdir.tr_logres; 1108 tres = &M_RES(mp)->tr_mkdir;
1109 tres.tr_logcount = XFS_MKDIR_LOG_COUNT;
1110 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); 1109 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
1111 } else { 1110 } else {
1112 resblks = XFS_CREATE_SPACE_RES(mp, name->len); 1111 resblks = XFS_CREATE_SPACE_RES(mp, name->len);
1113 tres.tr_logres = M_RES(mp)->tr_create.tr_logres; 1112 tres = &M_RES(mp)->tr_create;
1114 tres.tr_logcount = XFS_CREATE_LOG_COUNT;
1115 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); 1113 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
1116 } 1114 }
1117 1115
@@ -1123,17 +1121,16 @@ xfs_create(
1123 * the case we'll drop the one we have and get a more 1121 * the case we'll drop the one we have and get a more
1124 * appropriate transaction later. 1122 * appropriate transaction later.
1125 */ 1123 */
1126 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; 1124 error = xfs_trans_reserve(tp, tres, resblks, 0);
1127 error = xfs_trans_reserve(tp, &tres, resblks, 0);
1128 if (error == -ENOSPC) { 1125 if (error == -ENOSPC) {
1129 /* flush outstanding delalloc blocks and retry */ 1126 /* flush outstanding delalloc blocks and retry */
1130 xfs_flush_inodes(mp); 1127 xfs_flush_inodes(mp);
1131 error = xfs_trans_reserve(tp, &tres, resblks, 0); 1128 error = xfs_trans_reserve(tp, tres, resblks, 0);
1132 } 1129 }
1133 if (error == -ENOSPC) { 1130 if (error == -ENOSPC) {
1134 /* No space at all so try a "no-allocation" reservation */ 1131 /* No space at all so try a "no-allocation" reservation */
1135 resblks = 0; 1132 resblks = 0;
1136 error = xfs_trans_reserve(tp, &tres, 0, 0); 1133 error = xfs_trans_reserve(tp, tres, 0, 0);
1137 } 1134 }
1138 if (error) { 1135 if (error) {
1139 cancel_flags = 0; 1136 cancel_flags = 0;
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index fe88ef67f93a..e810e9df91b7 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1031,7 +1031,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
1031 struct xlog *log = mp->m_log; 1031 struct xlog *log = mp->m_log;
1032 int needed = 0; 1032 int needed = 0;
1033 1033
1034 if (!xfs_fs_writable(mp)) 1034 if (!xfs_fs_writable(mp, SB_FREEZE_WRITE))
1035 return 0; 1035 return 0;
1036 1036
1037 if (!xlog_cil_empty(log)) 1037 if (!xlog_cil_empty(log))
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 51435dbce9c4..13d117089101 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1074,11 +1074,23 @@ xfs_unmountfs(
1074 xfs_sysfs_del(&mp->m_kobj); 1074 xfs_sysfs_del(&mp->m_kobj);
1075} 1075}
1076 1076
1077int 1077/*
1078xfs_fs_writable(xfs_mount_t *mp) 1078 * Determine whether modifications can proceed. The caller specifies the minimum
1079 * freeze level for which modifications should not be allowed. This allows
1080 * certain operations to proceed while the freeze sequence is in progress, if
1081 * necessary.
1082 */
1083bool
1084xfs_fs_writable(
1085 struct xfs_mount *mp,
1086 int level)
1079{ 1087{
1080 return !(mp->m_super->s_writers.frozen || XFS_FORCED_SHUTDOWN(mp) || 1088 ASSERT(level > SB_UNFROZEN);
1081 (mp->m_flags & XFS_MOUNT_RDONLY)); 1089 if ((mp->m_super->s_writers.frozen >= level) ||
1090 XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_RDONLY))
1091 return false;
1092
1093 return true;
1082} 1094}
1083 1095
1084/* 1096/*
@@ -1086,9 +1098,9 @@ xfs_fs_writable(xfs_mount_t *mp)
1086 * 1098 *
1087 * Sync the superblock counters to disk. 1099 * Sync the superblock counters to disk.
1088 * 1100 *
1089 * Note this code can be called during the process of freezing, so 1101 * Note this code can be called during the process of freezing, so we use the
1090 * we may need to use the transaction allocator which does not 1102 * transaction allocator that does not block when the transaction subsystem is
1091 * block when the transaction subsystem is in its frozen state. 1103 * in its frozen state.
1092 */ 1104 */
1093int 1105int
1094xfs_log_sbcount(xfs_mount_t *mp) 1106xfs_log_sbcount(xfs_mount_t *mp)
@@ -1096,7 +1108,8 @@ xfs_log_sbcount(xfs_mount_t *mp)
1096 xfs_trans_t *tp; 1108 xfs_trans_t *tp;
1097 int error; 1109 int error;
1098 1110
1099 if (!xfs_fs_writable(mp)) 1111 /* allow this to proceed during the freeze sequence... */
1112 if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
1100 return 0; 1113 return 0;
1101 1114
1102 xfs_icsb_sync_counters(mp, 0); 1115 xfs_icsb_sync_counters(mp, 0);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index b0447c86e7e2..01fb28f5ae1c 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -168,6 +168,7 @@ typedef struct xfs_mount {
168 /* low free space thresholds */ 168 /* low free space thresholds */
169 struct xfs_kobj m_kobj; 169 struct xfs_kobj m_kobj;
170 170
171 struct workqueue_struct *m_buf_workqueue;
171 struct workqueue_struct *m_data_workqueue; 172 struct workqueue_struct *m_data_workqueue;
172 struct workqueue_struct *m_unwritten_workqueue; 173 struct workqueue_struct *m_unwritten_workqueue;
173 struct workqueue_struct *m_cil_workqueue; 174 struct workqueue_struct *m_cil_workqueue;
@@ -384,7 +385,7 @@ extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t);
384extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 385extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
385extern int xfs_readsb(xfs_mount_t *, int); 386extern int xfs_readsb(xfs_mount_t *, int);
386extern void xfs_freesb(xfs_mount_t *); 387extern void xfs_freesb(xfs_mount_t *);
387extern int xfs_fs_writable(xfs_mount_t *); 388extern bool xfs_fs_writable(struct xfs_mount *mp, int level);
388extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); 389extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
389 390
390extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 391extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 80f2d77d929a..d1e0ab7a5d12 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -784,19 +784,21 @@ xfs_qm_log_quotaoff(
784{ 784{
785 xfs_trans_t *tp; 785 xfs_trans_t *tp;
786 int error; 786 int error;
787 xfs_qoff_logitem_t *qoffi=NULL; 787 xfs_qoff_logitem_t *qoffi;
788 uint oldsbqflag=0; 788
789 *qoffstartp = NULL;
789 790
790 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF); 791 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);
791 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0); 792 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);
792 if (error) 793 if (error) {
793 goto error0; 794 xfs_trans_cancel(tp, 0);
795 goto out;
796 }
794 797
795 qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); 798 qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
796 xfs_trans_log_quotaoff_item(tp, qoffi); 799 xfs_trans_log_quotaoff_item(tp, qoffi);
797 800
798 spin_lock(&mp->m_sb_lock); 801 spin_lock(&mp->m_sb_lock);
799 oldsbqflag = mp->m_sb.sb_qflags;
800 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 802 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
801 spin_unlock(&mp->m_sb_lock); 803 spin_unlock(&mp->m_sb_lock);
802 804
@@ -809,19 +811,11 @@ xfs_qm_log_quotaoff(
809 */ 811 */
810 xfs_trans_set_sync(tp); 812 xfs_trans_set_sync(tp);
811 error = xfs_trans_commit(tp, 0); 813 error = xfs_trans_commit(tp, 0);
814 if (error)
815 goto out;
812 816
813error0:
814 if (error) {
815 xfs_trans_cancel(tp, 0);
816 /*
817 * No one else is modifying sb_qflags, so this is OK.
818 * We still hold the quotaofflock.
819 */
820 spin_lock(&mp->m_sb_lock);
821 mp->m_sb.sb_qflags = oldsbqflag;
822 spin_unlock(&mp->m_sb_lock);
823 }
824 *qoffstartp = qoffi; 817 *qoffstartp = qoffi;
818out:
825 return error; 819 return error;
826} 820}
827 821
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 9f622feda6a4..03e3cc242902 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -842,10 +842,16 @@ STATIC int
842xfs_init_mount_workqueues( 842xfs_init_mount_workqueues(
843 struct xfs_mount *mp) 843 struct xfs_mount *mp)
844{ 844{
845 mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
846 WQ_MEM_RECLAIM|WQ_HIGHPRI|WQ_FREEZABLE, 1,
847 mp->m_fsname);
848 if (!mp->m_buf_workqueue)
849 goto out;
850
845 mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", 851 mp->m_data_workqueue = alloc_workqueue("xfs-data/%s",
846 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 852 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
847 if (!mp->m_data_workqueue) 853 if (!mp->m_data_workqueue)
848 goto out; 854 goto out_destroy_buf;
849 855
850 mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", 856 mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s",
851 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 857 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
@@ -884,6 +890,8 @@ out_destroy_unwritten:
884 destroy_workqueue(mp->m_unwritten_workqueue); 890 destroy_workqueue(mp->m_unwritten_workqueue);
885out_destroy_data_iodone_queue: 891out_destroy_data_iodone_queue:
886 destroy_workqueue(mp->m_data_workqueue); 892 destroy_workqueue(mp->m_data_workqueue);
893out_destroy_buf:
894 destroy_workqueue(mp->m_buf_workqueue);
887out: 895out:
888 return -ENOMEM; 896 return -ENOMEM;
889} 897}
@@ -898,6 +906,7 @@ xfs_destroy_mount_workqueues(
898 destroy_workqueue(mp->m_cil_workqueue); 906 destroy_workqueue(mp->m_cil_workqueue);
899 destroy_workqueue(mp->m_data_workqueue); 907 destroy_workqueue(mp->m_data_workqueue);
900 destroy_workqueue(mp->m_unwritten_workqueue); 908 destroy_workqueue(mp->m_unwritten_workqueue);
909 destroy_workqueue(mp->m_buf_workqueue);
901} 910}
902 911
903/* 912/*