summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/glock.c10
-rw-r--r--fs/gfs2/glock.h2
-rw-r--r--fs/gfs2/super.c30
3 files changed, 39 insertions, 3 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 11d48b964047..5ad757f0ce60 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -171,7 +171,7 @@ void gfs2_glock_free(struct gfs2_glock *gl)
171 * 171 *
172 */ 172 */
173 173
174static void gfs2_glock_hold(struct gfs2_glock *gl) 174void gfs2_glock_hold(struct gfs2_glock *gl)
175{ 175{
176 GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref)); 176 GLOCK_BUG_ON(gl, __lockref_is_dead(&gl->gl_lockref));
177 lockref_get(&gl->gl_lockref); 177 lockref_get(&gl->gl_lockref);
@@ -264,6 +264,14 @@ static void __gfs2_glock_put(struct gfs2_glock *gl)
264 sdp->sd_lockstruct.ls_ops->lm_put_lock(gl); 264 sdp->sd_lockstruct.ls_ops->lm_put_lock(gl);
265} 265}
266 266
267/*
268 * Cause the glock to be put in work queue context.
269 */
270void gfs2_glock_queue_put(struct gfs2_glock *gl)
271{
272 gfs2_glock_queue_work(gl, 0);
273}
274
267/** 275/**
268 * gfs2_glock_put() - Decrement reference count on glock 276 * gfs2_glock_put() - Decrement reference count on glock
269 * @gl: The glock to put 277 * @gl: The glock to put
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 526d2123f758..5e12220cc0c2 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -182,7 +182,9 @@ static inline struct address_space *gfs2_glock2aspace(struct gfs2_glock *gl)
182extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, 182extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
183 const struct gfs2_glock_operations *glops, 183 const struct gfs2_glock_operations *glops,
184 int create, struct gfs2_glock **glp); 184 int create, struct gfs2_glock **glp);
185extern void gfs2_glock_hold(struct gfs2_glock *gl);
185extern void gfs2_glock_put(struct gfs2_glock *gl); 186extern void gfs2_glock_put(struct gfs2_glock *gl);
187extern void gfs2_glock_queue_put(struct gfs2_glock *gl);
186extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, 188extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state,
187 u16 flags, struct gfs2_holder *gh); 189 u16 flags, struct gfs2_holder *gh);
188extern void gfs2_holder_reinit(unsigned int state, u16 flags, 190extern void gfs2_holder_reinit(unsigned int state, u16 flags,
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 6c39bb1ec100..4089dbe617a6 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1502,6 +1502,22 @@ out_qs:
1502} 1502}
1503 1503
1504/** 1504/**
1505 * gfs2_glock_put_eventually
1506 * @gl: The glock to put
1507 *
1508 * When under memory pressure, trigger a deferred glock put to make sure we
1509 * won't call into DLM and deadlock. Otherwise, put the glock directly.
1510 */
1511
1512static void gfs2_glock_put_eventually(struct gfs2_glock *gl)
1513{
1514 if (current->flags & PF_MEMALLOC)
1515 gfs2_glock_queue_put(gl);
1516 else
1517 gfs2_glock_put(gl);
1518}
1519
1520/**
1505 * gfs2_evict_inode - Remove an inode from cache 1521 * gfs2_evict_inode - Remove an inode from cache
1506 * @inode: The inode to evict 1522 * @inode: The inode to evict
1507 * 1523 *
@@ -1564,6 +1580,12 @@ static void gfs2_evict_inode(struct inode *inode)
1564 goto out_truncate; 1580 goto out_truncate;
1565 } 1581 }
1566 1582
1583 /*
1584 * The inode may have been recreated in the meantime.
1585 */
1586 if (inode->i_nlink)
1587 goto out_truncate;
1588
1567alloc_failed: 1589alloc_failed:
1568 if (gfs2_holder_initialized(&ip->i_iopen_gh) && 1590 if (gfs2_holder_initialized(&ip->i_iopen_gh) &&
1569 test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { 1591 test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) {
@@ -1653,12 +1675,16 @@ out:
1653 glock_clear_object(ip->i_gl, ip); 1675 glock_clear_object(ip->i_gl, ip);
1654 wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE); 1676 wait_on_bit_io(&ip->i_flags, GIF_GLOP_PENDING, TASK_UNINTERRUPTIBLE);
1655 gfs2_glock_add_to_lru(ip->i_gl); 1677 gfs2_glock_add_to_lru(ip->i_gl);
1656 gfs2_glock_put(ip->i_gl); 1678 gfs2_glock_put_eventually(ip->i_gl);
1657 ip->i_gl = NULL; 1679 ip->i_gl = NULL;
1658 if (gfs2_holder_initialized(&ip->i_iopen_gh)) { 1680 if (gfs2_holder_initialized(&ip->i_iopen_gh)) {
1659 glock_clear_object(ip->i_iopen_gh.gh_gl, ip); 1681 struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
1682
1683 glock_clear_object(gl, ip);
1660 ip->i_iopen_gh.gh_flags |= GL_NOCACHE; 1684 ip->i_iopen_gh.gh_flags |= GL_NOCACHE;
1685 gfs2_glock_hold(gl);
1661 gfs2_glock_dq_uninit(&ip->i_iopen_gh); 1686 gfs2_glock_dq_uninit(&ip->i_iopen_gh);
1687 gfs2_glock_put_eventually(gl);
1662 } 1688 }
1663} 1689}
1664 1690