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

This commit is contained in:
Dave Chinner 2014-11-28 14:52:02 +11:00
commit 4bd47c1bf4
7 changed files with 52 additions and 48 deletions

View 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);
}

View 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;

View 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))

View 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);

View 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 *);

View 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;
}

View file

@ -842,10 +842,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);
@ -884,6 +890,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;
}
@ -898,6 +906,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);
}
/*