diff options
author | Dave Chinner <david@fromorbit.com> | 2014-11-27 22:52:02 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-11-27 22:52:02 -0500 |
commit | 4bd47c1bf4a64225a855ed77e259eeb37944ba33 (patch) | |
tree | 79aed8aaf3b04595d55762421d25d7ea2a5a5318 /fs/xfs | |
parent | 002758992693ae63c04122603ea9261a0a58d728 (diff) | |
parent | db52d09ecbf85c54e263a9d1ebfb615a9b2b3ba6 (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.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 15 | ||||
-rw-r--r-- | fs/xfs/xfs_log.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 29 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_syscalls.c | 26 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 11 |
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 | ||
45 | static kmem_zone_t *xfs_buf_zone; | 45 | static kmem_zone_t *xfs_buf_zone; |
46 | 46 | ||
47 | static 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 | ||
1059 | void | 1057 | void |
@@ -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) | |||
1898 | void | 1889 | void |
1899 | xfs_buf_terminate(void) | 1890 | xfs_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 | ||
1077 | int | 1077 | /* |
1078 | xfs_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 | */ | ||
1083 | bool | ||
1084 | xfs_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 | */ |
1093 | int | 1105 | int |
1094 | xfs_log_sbcount(xfs_mount_t *mp) | 1106 | xfs_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); | |||
384 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); | 385 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); |
385 | extern int xfs_readsb(xfs_mount_t *, int); | 386 | extern int xfs_readsb(xfs_mount_t *, int); |
386 | extern void xfs_freesb(xfs_mount_t *); | 387 | extern void xfs_freesb(xfs_mount_t *); |
387 | extern int xfs_fs_writable(xfs_mount_t *); | 388 | extern bool xfs_fs_writable(struct xfs_mount *mp, int level); |
388 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); | 389 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); |
389 | 390 | ||
390 | extern int xfs_dev_is_read_only(struct xfs_mount *, char *); | 391 | extern 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 | ||
813 | error0: | ||
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; |
818 | out: | ||
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 | |||
842 | xfs_init_mount_workqueues( | 842 | xfs_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); |
885 | out_destroy_data_iodone_queue: | 891 | out_destroy_data_iodone_queue: |
886 | destroy_workqueue(mp->m_data_workqueue); | 892 | destroy_workqueue(mp->m_data_workqueue); |
893 | out_destroy_buf: | ||
894 | destroy_workqueue(mp->m_buf_workqueue); | ||
887 | out: | 895 | out: |
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 | /* |