mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 16:07:39 +00:00
Merge branch 'xfs-misc-fixes-for-3.19-1' into for-next
This commit is contained in:
commit
4bd47c1bf4
7 changed files with 52 additions and 48 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ xfs_init_mount_workqueues(
|
|||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue