Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
Two bugfixes in XFS for 3.3: one fix passes KMEM_SLEEP to kmem_realloc
instead of 0, and the other resolves a possible deadlock in xfs quotas.

* 'for-linus' of git://oss.sgi.com/xfs/xfs:
  xfs: use a normal shrinker for the dquot freelist
  xfs: pass KM_SLEEP flag to kmem_realloc() in xlog_recover_add_to_cnt_trans()
  • Loading branch information
Linus Torvalds committed Feb 13, 2012
2 parents b14a299 + 04da0c8 commit 19be13c
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 283 deletions.
6 changes: 0 additions & 6 deletions fs/xfs/kmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,4 @@ kmem_zone_destroy(kmem_zone_t *zone)
extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast);
extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast);

static inline int
kmem_shake_allow(gfp_t gfp_mask)
{
return ((gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS));
}

#endif /* __XFS_SUPPORT_KMEM_H__ */
103 changes: 26 additions & 77 deletions fs/xfs/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,82 +62,6 @@ int xfs_dqerror_mod = 33;

static struct lock_class_key xfs_dquot_other_class;

/*
* Allocate and initialize a dquot. We don't always allocate fresh memory;
* we try to reclaim a free dquot if the number of incore dquots are above
* a threshold.
* The only field inside the core that gets initialized at this point
* is the d_id field. The idea is to fill in the entire q_core
* when we read in the on disk dquot.
*/
STATIC xfs_dquot_t *
xfs_qm_dqinit(
xfs_mount_t *mp,
xfs_dqid_t id,
uint type)
{
xfs_dquot_t *dqp;
boolean_t brandnewdquot;

brandnewdquot = xfs_qm_dqalloc_incore(&dqp);
dqp->dq_flags = type;
dqp->q_core.d_id = cpu_to_be32(id);
dqp->q_mount = mp;

/*
* No need to re-initialize these if this is a reclaimed dquot.
*/
if (brandnewdquot) {
INIT_LIST_HEAD(&dqp->q_freelist);
mutex_init(&dqp->q_qlock);
init_waitqueue_head(&dqp->q_pinwait);

/*
* Because we want to use a counting completion, complete
* the flush completion once to allow a single access to
* the flush completion without blocking.
*/
init_completion(&dqp->q_flush);
complete(&dqp->q_flush);

trace_xfs_dqinit(dqp);
} else {
/*
* Only the q_core portion was zeroed in dqreclaim_one().
* So, we need to reset others.
*/
dqp->q_nrefs = 0;
dqp->q_blkno = 0;
INIT_LIST_HEAD(&dqp->q_mplist);
INIT_LIST_HEAD(&dqp->q_hashlist);
dqp->q_bufoffset = 0;
dqp->q_fileoffset = 0;
dqp->q_transp = NULL;
dqp->q_gdquot = NULL;
dqp->q_res_bcount = 0;
dqp->q_res_icount = 0;
dqp->q_res_rtbcount = 0;
atomic_set(&dqp->q_pincount, 0);
dqp->q_hash = NULL;
ASSERT(list_empty(&dqp->q_freelist));

trace_xfs_dqreuse(dqp);
}

/*
* In either case we need to make sure group quotas have a different
* lock class than user quotas, to make sure lockdep knows we can
* locks of one of each at the same time.
*/
if (!(type & XFS_DQ_USER))
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);

/*
* log item gets initialized later
*/
return (dqp);
}

/*
* This is called to free all the memory associated with a dquot
*/
Expand Down Expand Up @@ -567,7 +491,32 @@ xfs_qm_dqread(
int error;
int cancelflags = 0;

dqp = xfs_qm_dqinit(mp, id, type);

dqp = kmem_zone_zalloc(xfs_Gqm->qm_dqzone, KM_SLEEP);

dqp->dq_flags = type;
dqp->q_core.d_id = cpu_to_be32(id);
dqp->q_mount = mp;
INIT_LIST_HEAD(&dqp->q_freelist);
mutex_init(&dqp->q_qlock);
init_waitqueue_head(&dqp->q_pinwait);

/*
* Because we want to use a counting completion, complete
* the flush completion once to allow a single access to
* the flush completion without blocking.
*/
init_completion(&dqp->q_flush);
complete(&dqp->q_flush);

/*
* Make sure group quotas have a different lock class than user
* quotas.
*/
if (!(type & XFS_DQ_USER))
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class);

atomic_inc(&xfs_Gqm->qm_totaldquots);

trace_xfs_dqread(dqp);

Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/xfs_log_recover.c
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,7 @@ xlog_recover_add_to_cont_trans(
old_ptr = item->ri_buf[item->ri_cnt-1].i_addr;
old_len = item->ri_buf[item->ri_cnt-1].i_len;

ptr = kmem_realloc(old_ptr, len+old_len, old_len, 0u);
ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP);
memcpy(&ptr[old_len], dp, len); /* d, s, l */
item->ri_buf[item->ri_cnt-1].i_len += len;
item->ri_buf[item->ri_cnt-1].i_addr = ptr;
Expand Down
Loading

0 comments on commit 19be13c

Please sign in to comment.