Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'xfs-misc-fixes-for-3.19-1' into for-next

+52 -48
+2 -12
fs/xfs/xfs_buf.c
··· 44 44 45 45 static kmem_zone_t *xfs_buf_zone; 46 46 47 - static struct workqueue_struct *xfslogd_workqueue; 48 - 49 47 #ifdef XFS_BUF_LOCK_TRACKING 50 48 # define XB_SET_OWNER(bp) ((bp)->b_last_holder = current->pid) 51 49 # define XB_CLEAR_OWNER(bp) ((bp)->b_last_holder = -1) ··· 461 463 * have to check that the buffer falls within the filesystem bounds. 462 464 */ 463 465 eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks); 464 - if (blkno >= eofs) { 466 + if (blkno < 0 || blkno >= eofs) { 465 467 /* 466 468 * XXX (dgc): we should really be returning -EFSCORRUPTED here, 467 469 * but none of the higher level infrastructure supports ··· 1051 1053 struct xfs_buf *bp) 1052 1054 { 1053 1055 INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work); 1054 - queue_work(xfslogd_workqueue, &bp->b_iodone_work); 1056 + queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work); 1055 1057 } 1056 1058 1057 1059 void ··· 1880 1882 if (!xfs_buf_zone) 1881 1883 goto out; 1882 1884 1883 - xfslogd_workqueue = alloc_workqueue("xfslogd", 1884 - WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZABLE, 1); 1885 - if (!xfslogd_workqueue) 1886 - goto out_free_buf_zone; 1887 - 1888 1885 return 0; 1889 1886 1890 - out_free_buf_zone: 1891 - kmem_zone_destroy(xfs_buf_zone); 1892 1887 out: 1893 1888 return -ENOMEM; 1894 1889 } ··· 1889 1898 void 1890 1899 xfs_buf_terminate(void) 1891 1900 { 1892 - destroy_workqueue(xfslogd_workqueue); 1893 1901 kmem_zone_destroy(xfs_buf_zone); 1894 1902 }
+6 -9
fs/xfs/xfs_inode.c
··· 1082 1082 struct xfs_dquot *udqp = NULL; 1083 1083 struct xfs_dquot *gdqp = NULL; 1084 1084 struct xfs_dquot *pdqp = NULL; 1085 - struct xfs_trans_res tres; 1085 + struct xfs_trans_res *tres; 1086 1086 uint resblks; 1087 1087 1088 1088 trace_xfs_create(dp, name); ··· 1105 1105 if (is_dir) { 1106 1106 rdev = 0; 1107 1107 resblks = XFS_MKDIR_SPACE_RES(mp, name->len); 1108 - tres.tr_logres = M_RES(mp)->tr_mkdir.tr_logres; 1109 - tres.tr_logcount = XFS_MKDIR_LOG_COUNT; 1108 + tres = &M_RES(mp)->tr_mkdir; 1110 1109 tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); 1111 1110 } else { 1112 1111 resblks = XFS_CREATE_SPACE_RES(mp, name->len); 1113 - tres.tr_logres = M_RES(mp)->tr_create.tr_logres; 1114 - tres.tr_logcount = XFS_CREATE_LOG_COUNT; 1112 + tres = &M_RES(mp)->tr_create; 1115 1113 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); 1116 1114 } 1117 1115 ··· 1121 1123 * the case we'll drop the one we have and get a more 1122 1124 * appropriate transaction later. 1123 1125 */ 1124 - tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; 1125 - error = xfs_trans_reserve(tp, &tres, resblks, 0); 1126 + error = xfs_trans_reserve(tp, tres, resblks, 0); 1126 1127 if (error == -ENOSPC) { 1127 1128 /* flush outstanding delalloc blocks and retry */ 1128 1129 xfs_flush_inodes(mp); 1129 - error = xfs_trans_reserve(tp, &tres, resblks, 0); 1130 + error = xfs_trans_reserve(tp, tres, resblks, 0); 1130 1131 } 1131 1132 if (error == -ENOSPC) { 1132 1133 /* No space at all so try a "no-allocation" reservation */ 1133 1134 resblks = 0; 1134 - error = xfs_trans_reserve(tp, &tres, 0, 0); 1135 + error = xfs_trans_reserve(tp, tres, 0, 0); 1135 1136 } 1136 1137 if (error) { 1137 1138 cancel_flags = 0;
+1 -1
fs/xfs/xfs_log.c
··· 1031 1031 struct xlog *log = mp->m_log; 1032 1032 int needed = 0; 1033 1033 1034 - if (!xfs_fs_writable(mp)) 1034 + if (!xfs_fs_writable(mp, SB_FREEZE_WRITE)) 1035 1035 return 0; 1036 1036 1037 1037 if (!xlog_cil_empty(log))
+21 -8
fs/xfs/xfs_mount.c
··· 1074 1074 xfs_sysfs_del(&mp->m_kobj); 1075 1075 } 1076 1076 1077 - int 1078 - xfs_fs_writable(xfs_mount_t *mp) 1077 + /* 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) || 1081 - (mp->m_flags & XFS_MOUNT_RDONLY)); 1088 + ASSERT(level > SB_UNFROZEN); 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 /* ··· 1098 1086 * 1099 1087 * Sync the superblock counters to disk. 1100 1088 * 1101 - * Note this code can be called during the process of freezing, so 1102 - * we may need to use the transaction allocator which does not 1103 - * block when the transaction subsystem is in its frozen state. 1089 + * Note this code can be called during the process of freezing, so we use the 1090 + * transaction allocator that does not block when the transaction subsystem is 1091 + * in its frozen state. 1104 1092 */ 1105 1093 int 1106 1094 xfs_log_sbcount(xfs_mount_t *mp) ··· 1108 1096 xfs_trans_t *tp; 1109 1097 int error; 1110 1098 1111 - if (!xfs_fs_writable(mp)) 1099 + /* allow this to proceed during the freeze sequence... */ 1100 + if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE)) 1112 1101 return 0; 1113 1102 1114 1103 xfs_icsb_sync_counters(mp, 0);
+2 -1
fs/xfs/xfs_mount.h
··· 168 168 /* low free space thresholds */ 169 169 struct xfs_kobj m_kobj; 170 170 171 + struct workqueue_struct *m_buf_workqueue; 171 172 struct workqueue_struct *m_data_workqueue; 172 173 struct workqueue_struct *m_unwritten_workqueue; 173 174 struct workqueue_struct *m_cil_workqueue; ··· 385 384 extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 386 385 extern int xfs_readsb(xfs_mount_t *, int); 387 386 extern void xfs_freesb(xfs_mount_t *); 388 - extern int xfs_fs_writable(xfs_mount_t *); 387 + extern bool xfs_fs_writable(struct xfs_mount *mp, int level); 389 388 extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); 390 389 391 390 extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
+10 -16
fs/xfs/xfs_qm_syscalls.c
··· 784 784 { 785 785 xfs_trans_t *tp; 786 786 int error; 787 - xfs_qoff_logitem_t *qoffi=NULL; 788 - uint oldsbqflag=0; 787 + xfs_qoff_logitem_t *qoffi; 788 + 789 + *qoffstartp = NULL; 789 790 790 791 tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF); 791 792 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0); 792 - if (error) 793 - goto error0; 793 + if (error) { 794 + xfs_trans_cancel(tp, 0); 795 + goto out; 796 + } 794 797 795 798 qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); 796 799 xfs_trans_log_quotaoff_item(tp, qoffi); 797 800 798 801 spin_lock(&mp->m_sb_lock); 799 - oldsbqflag = mp->m_sb.sb_qflags; 800 802 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 801 803 spin_unlock(&mp->m_sb_lock); 802 804 ··· 811 809 */ 812 810 xfs_trans_set_sync(tp); 813 811 error = xfs_trans_commit(tp, 0); 812 + if (error) 813 + goto out; 814 814 815 - error0: 816 - if (error) { 817 - xfs_trans_cancel(tp, 0); 818 - /* 819 - * No one else is modifying sb_qflags, so this is OK. 820 - * We still hold the quotaofflock. 821 - */ 822 - spin_lock(&mp->m_sb_lock); 823 - mp->m_sb.sb_qflags = oldsbqflag; 824 - spin_unlock(&mp->m_sb_lock); 825 - } 826 815 *qoffstartp = qoffi; 816 + out: 827 817 return error; 828 818 } 829 819
+10 -1
fs/xfs/xfs_super.c
··· 842 842 xfs_init_mount_workqueues( 843 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 851 mp->m_data_workqueue = alloc_workqueue("xfs-data/%s", 846 852 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); 847 853 if (!mp->m_data_workqueue) 848 - goto out; 854 + goto out_destroy_buf; 849 855 850 856 mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s", 851 857 WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); ··· 890 884 destroy_workqueue(mp->m_unwritten_workqueue); 891 885 out_destroy_data_iodone_queue: 892 886 destroy_workqueue(mp->m_data_workqueue); 887 + out_destroy_buf: 888 + destroy_workqueue(mp->m_buf_workqueue); 893 889 out: 894 890 return -ENOMEM; 895 891 } ··· 906 898 destroy_workqueue(mp->m_cil_workqueue); 907 899 destroy_workqueue(mp->m_data_workqueue); 908 900 destroy_workqueue(mp->m_unwritten_workqueue); 901 + destroy_workqueue(mp->m_buf_workqueue); 909 902 } 910 903 911 904 /*