Merge branch 'xfs-coccinelle-cleanups' into xfs-misc-fixes-for-3.19-2
authorDave Chinner <david@fromorbit.com>
Wed, 3 Dec 2014 22:18:21 +0000 (09:18 +1100)
committerDave Chinner <david@fromorbit.com>
Wed, 3 Dec 2014 22:18:21 +0000 (09:18 +1100)
fs/xfs/xfs_buf.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_qm_syscalls.c
fs/xfs/xfs_super.c

index 24b4ebea0d4d114c924838c3d50614920c0a923d..d083889535a21af28838bbc891e9eabfae834da0 100644 (file)
@@ -44,8 +44,6 @@
 
 static kmem_zone_t *xfs_buf_zone;
 
-static struct workqueue_struct *xfslogd_workqueue;
-
 #ifdef XFS_BUF_LOCK_TRACKING
 # define XB_SET_OWNER(bp)      ((bp)->b_last_holder = current->pid)
 # define XB_CLEAR_OWNER(bp)    ((bp)->b_last_holder = -1)
@@ -463,7 +461,7 @@ _xfs_buf_find(
         * have to check that the buffer falls within the filesystem bounds.
         */
        eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
-       if (blkno >= eofs) {
+       if (blkno < 0 || blkno >= eofs) {
                /*
                 * XXX (dgc): we should really be returning -EFSCORRUPTED here,
                 * but none of the higher level infrastructure supports
@@ -1053,7 +1051,7 @@ xfs_buf_ioend_async(
        struct xfs_buf  *bp)
 {
        INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work);
-       queue_work(xfslogd_workqueue, &bp->b_iodone_work);
+       queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work);
 }
 
 void
@@ -1882,15 +1880,8 @@ xfs_buf_init(void)
        if (!xfs_buf_zone)
                goto out;
 
-       xfslogd_workqueue = alloc_workqueue("xfslogd",
-                               WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZABLE, 1);
-       if (!xfslogd_workqueue)
-               goto out_free_buf_zone;
-
        return 0;
 
- out_free_buf_zone:
-       kmem_zone_destroy(xfs_buf_zone);
  out:
        return -ENOMEM;
 }
@@ -1898,6 +1889,5 @@ xfs_buf_init(void)
 void
 xfs_buf_terminate(void)
 {
-       destroy_workqueue(xfslogd_workqueue);
        kmem_zone_destroy(xfs_buf_zone);
 }
index 8ed049d1e3327fd61b1a6f1c7d1e0fea0bba77cd..2ffb80267e374a0cf50d7264859ebc8b37863037 100644 (file)
@@ -1082,7 +1082,7 @@ xfs_create(
        struct xfs_dquot        *udqp = NULL;
        struct xfs_dquot        *gdqp = NULL;
        struct xfs_dquot        *pdqp = NULL;
-       struct xfs_trans_res    tres;
+       struct xfs_trans_res    *tres;
        uint                    resblks;
 
        trace_xfs_create(dp, name);
@@ -1105,13 +1105,11 @@ xfs_create(
        if (is_dir) {
                rdev = 0;
                resblks = XFS_MKDIR_SPACE_RES(mp, name->len);
-               tres.tr_logres = M_RES(mp)->tr_mkdir.tr_logres;
-               tres.tr_logcount = XFS_MKDIR_LOG_COUNT;
+               tres = &M_RES(mp)->tr_mkdir;
                tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR);
        } else {
                resblks = XFS_CREATE_SPACE_RES(mp, name->len);
-               tres.tr_logres = M_RES(mp)->tr_create.tr_logres;
-               tres.tr_logcount = XFS_CREATE_LOG_COUNT;
+               tres = &M_RES(mp)->tr_create;
                tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE);
        }
 
@@ -1123,17 +1121,16 @@ xfs_create(
         * the case we'll drop the one we have and get a more
         * appropriate transaction later.
         */
-       tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-       error = xfs_trans_reserve(tp, &tres, resblks, 0);
+       error = xfs_trans_reserve(tp, tres, resblks, 0);
        if (error == -ENOSPC) {
                /* flush outstanding delalloc blocks and retry */
                xfs_flush_inodes(mp);
-               error = xfs_trans_reserve(tp, &tres, resblks, 0);
+               error = xfs_trans_reserve(tp, tres, resblks, 0);
        }
        if (error == -ENOSPC) {
                /* No space at all so try a "no-allocation" reservation */
                resblks = 0;
-               error = xfs_trans_reserve(tp, &tres, 0, 0);
+               error = xfs_trans_reserve(tp, tres, 0, 0);
        }
        if (error) {
                cancel_flags = 0;
index fe88ef67f93acb9bbcbf4fbee7c06747b3c8155e..e810e9df91b76bfa7949d3e0c425b2f2afe93aa8 100644 (file)
@@ -1031,7 +1031,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
        struct xlog     *log = mp->m_log;
        int             needed = 0;
 
-       if (!xfs_fs_writable(mp))
+       if (!xfs_fs_writable(mp, SB_FREEZE_WRITE))
                return 0;
 
        if (!xlog_cil_empty(log))
index 51435dbce9c4efd2407be2c12ddd58d86324bce8..13d1170891015796ed3c3cb2f4a8af744c14cb0f 100644 (file)
@@ -1074,11 +1074,23 @@ xfs_unmountfs(
        xfs_sysfs_del(&mp->m_kobj);
 }
 
-int
-xfs_fs_writable(xfs_mount_t *mp)
+/*
+ * Determine whether modifications can proceed. The caller specifies the minimum
+ * freeze level for which modifications should not be allowed. This allows
+ * certain operations to proceed while the freeze sequence is in progress, if
+ * necessary.
+ */
+bool
+xfs_fs_writable(
+       struct xfs_mount        *mp,
+       int                     level)
 {
-       return !(mp->m_super->s_writers.frozen || XFS_FORCED_SHUTDOWN(mp) ||
-               (mp->m_flags & XFS_MOUNT_RDONLY));
+       ASSERT(level > SB_UNFROZEN);
+       if ((mp->m_super->s_writers.frozen >= level) ||
+           XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_RDONLY))
+               return false;
+
+       return true;
 }
 
 /*
@@ -1086,9 +1098,9 @@ xfs_fs_writable(xfs_mount_t *mp)
  *
  * Sync the superblock counters to disk.
  *
- * Note this code can be called during the process of freezing, so
- * we may need to use the transaction allocator which does not
- * block when the transaction subsystem is in its frozen state.
+ * Note this code can be called during the process of freezing, so we use the
+ * transaction allocator that does not block when the transaction subsystem is
+ * in its frozen state.
  */
 int
 xfs_log_sbcount(xfs_mount_t *mp)
@@ -1096,7 +1108,8 @@ xfs_log_sbcount(xfs_mount_t *mp)
        xfs_trans_t     *tp;
        int             error;
 
-       if (!xfs_fs_writable(mp))
+       /* allow this to proceed during the freeze sequence... */
+       if (!xfs_fs_writable(mp, SB_FREEZE_COMPLETE))
                return 0;
 
        xfs_icsb_sync_counters(mp, 0);
index b0447c86e7e24e5e21c7b8a3ff28103d89583382..01fb28f5ae1c2e77153641e92caa0de5515c2d49 100644 (file)
@@ -168,6 +168,7 @@ typedef struct xfs_mount {
                                                /* low free space thresholds */
        struct xfs_kobj         m_kobj;
 
+       struct workqueue_struct *m_buf_workqueue;
        struct workqueue_struct *m_data_workqueue;
        struct workqueue_struct *m_unwritten_workqueue;
        struct workqueue_struct *m_cil_workqueue;
@@ -384,7 +385,7 @@ extern int  xfs_mount_log_sb(xfs_mount_t *, __int64_t);
 extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
 extern int     xfs_readsb(xfs_mount_t *, int);
 extern void    xfs_freesb(xfs_mount_t *);
-extern int     xfs_fs_writable(xfs_mount_t *);
+extern bool    xfs_fs_writable(struct xfs_mount *mp, int level);
 extern int     xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
 
 extern int     xfs_dev_is_read_only(struct xfs_mount *, char *);
index 80f2d77d929a87797b67269880b1c04907b9f402..d1e0ab7a5d126708cb5e01e594339c8d9f21ecc4 100644 (file)
@@ -784,19 +784,21 @@ xfs_qm_log_quotaoff(
 {
        xfs_trans_t            *tp;
        int                     error;
-       xfs_qoff_logitem_t     *qoffi=NULL;
-       uint                    oldsbqflag=0;
+       xfs_qoff_logitem_t     *qoffi;
+
+       *qoffstartp = NULL;
 
        tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);
        error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);
-       if (error)
-               goto error0;
+       if (error) {
+               xfs_trans_cancel(tp, 0);
+               goto out;
+       }
 
        qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
        xfs_trans_log_quotaoff_item(tp, qoffi);
 
        spin_lock(&mp->m_sb_lock);
-       oldsbqflag = mp->m_sb.sb_qflags;
        mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
        spin_unlock(&mp->m_sb_lock);
 
@@ -809,19 +811,11 @@ xfs_qm_log_quotaoff(
         */
        xfs_trans_set_sync(tp);
        error = xfs_trans_commit(tp, 0);
+       if (error)
+               goto out;
 
-error0:
-       if (error) {
-               xfs_trans_cancel(tp, 0);
-               /*
-                * No one else is modifying sb_qflags, so this is OK.
-                * We still hold the quotaofflock.
-                */
-               spin_lock(&mp->m_sb_lock);
-               mp->m_sb.sb_qflags = oldsbqflag;
-               spin_unlock(&mp->m_sb_lock);
-       }
        *qoffstartp = qoffi;
+out:
        return error;
 }
 
index 95745be3ab473d3a74e64b21a9a5f702e7b19557..a0f58d933261292e4bbe04f3aeeaae5fa8f6f2fb 100644 (file)
@@ -841,10 +841,16 @@ STATIC int
 xfs_init_mount_workqueues(
        struct xfs_mount        *mp)
 {
+       mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
+                       WQ_MEM_RECLAIM|WQ_HIGHPRI|WQ_FREEZABLE, 1,
+                       mp->m_fsname);
+       if (!mp->m_buf_workqueue)
+               goto out;
+
        mp->m_data_workqueue = alloc_workqueue("xfs-data/%s",
                        WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
        if (!mp->m_data_workqueue)
-               goto out;
+               goto out_destroy_buf;
 
        mp->m_unwritten_workqueue = alloc_workqueue("xfs-conv/%s",
                        WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname);
@@ -883,6 +889,8 @@ out_destroy_unwritten:
        destroy_workqueue(mp->m_unwritten_workqueue);
 out_destroy_data_iodone_queue:
        destroy_workqueue(mp->m_data_workqueue);
+out_destroy_buf:
+       destroy_workqueue(mp->m_buf_workqueue);
 out:
        return -ENOMEM;
 }
@@ -897,6 +905,7 @@ xfs_destroy_mount_workqueues(
        destroy_workqueue(mp->m_cil_workqueue);
        destroy_workqueue(mp->m_data_workqueue);
        destroy_workqueue(mp->m_unwritten_workqueue);
+       destroy_workqueue(mp->m_buf_workqueue);
 }
 
 /*