Skip to content

Commit b94a170

Browse files
bmarzinsswhiteho
authored andcommitted
GFS2: remove dcache entries for remote deleted inodes
When a file is deleted from a gfs2 filesystem on one node, a dcache entry for it may still exist on other nodes in the cluster. If this happens, gfs2 will be unable to free this file on disk. Because of this, it's possible to have a gfs2 filesystem with no files on it and no free space. With this patch, when a node receives a callback notifying it that the file is being deleted on another node, it schedules a new workqueue thread to remove the file's dcache entry. Signed-off-by: Benjamin Marzinski <[email protected]> Signed-off-by: Steven Whitehouse <[email protected]>
1 parent 6b94617 commit b94a170

File tree

5 files changed

+65
-5
lines changed

5 files changed

+65
-5
lines changed

fs/gfs2/glock.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int
6363
static DECLARE_RWSEM(gfs2_umount_flush_sem);
6464
static struct dentry *gfs2_root;
6565
static struct workqueue_struct *glock_workqueue;
66+
struct workqueue_struct *gfs2_delete_workqueue;
6667
static LIST_HEAD(lru_list);
6768
static atomic_t lru_count = ATOMIC_INIT(0);
6869
static DEFINE_SPINLOCK(lru_lock);
@@ -167,7 +168,7 @@ static void glock_free(struct gfs2_glock *gl)
167168
*
168169
*/
169170

170-
static void gfs2_glock_hold(struct gfs2_glock *gl)
171+
void gfs2_glock_hold(struct gfs2_glock *gl)
171172
{
172173
GLOCK_BUG_ON(gl, atomic_read(&gl->gl_ref) == 0);
173174
atomic_inc(&gl->gl_ref);
@@ -222,7 +223,7 @@ static void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl)
222223
* to the glock, in addition to the one it is dropping.
223224
*/
224225

225-
static void gfs2_glock_put_nolock(struct gfs2_glock *gl)
226+
void gfs2_glock_put_nolock(struct gfs2_glock *gl)
226227
{
227228
if (atomic_dec_and_test(&gl->gl_ref))
228229
GLOCK_BUG_ON(gl, 1);
@@ -679,6 +680,29 @@ __acquires(&gl->gl_spin)
679680
goto out;
680681
}
681682

683+
static void delete_work_func(struct work_struct *work)
684+
{
685+
struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete);
686+
struct gfs2_sbd *sdp = gl->gl_sbd;
687+
struct gfs2_inode *ip = NULL;
688+
struct inode *inode;
689+
u64 no_addr = 0;
690+
691+
spin_lock(&gl->gl_spin);
692+
ip = (struct gfs2_inode *)gl->gl_object;
693+
if (ip)
694+
no_addr = ip->i_no_addr;
695+
spin_unlock(&gl->gl_spin);
696+
if (ip) {
697+
inode = gfs2_ilookup(sdp->sd_vfs, no_addr);
698+
if (inode) {
699+
d_prune_aliases(inode);
700+
iput(inode);
701+
}
702+
}
703+
gfs2_glock_put(gl);
704+
}
705+
682706
static void glock_work_func(struct work_struct *work)
683707
{
684708
unsigned long delay = 0;
@@ -757,6 +781,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
757781
gl->gl_sbd = sdp;
758782
gl->gl_aspace = NULL;
759783
INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
784+
INIT_WORK(&gl->gl_delete, delete_work_func);
760785

761786
/* If this glock protects actual on-disk data or metadata blocks,
762787
create a VFS inode to manage the pages/buffers holding them. */
@@ -898,6 +923,8 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
898923
gl->gl_demote_state != state) {
899924
gl->gl_demote_state = LM_ST_UNLOCKED;
900925
}
926+
if (gl->gl_ops->go_callback)
927+
gl->gl_ops->go_callback(gl);
901928
trace_gfs2_demote_rq(gl);
902929
}
903930

@@ -1344,14 +1371,14 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
13441371
spin_unlock(&lru_lock);
13451372
spin_lock(&gl->gl_spin);
13461373
may_demote = demote_ok(gl);
1347-
spin_unlock(&gl->gl_spin);
1348-
clear_bit(GLF_LOCK, &gl->gl_flags);
13491374
if (may_demote) {
13501375
handle_callback(gl, LM_ST_UNLOCKED, 0);
13511376
nr--;
13521377
}
13531378
if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
1354-
gfs2_glock_put(gl);
1379+
gfs2_glock_put_nolock(gl);
1380+
spin_unlock(&gl->gl_spin);
1381+
clear_bit(GLF_LOCK, &gl->gl_flags);
13551382
spin_lock(&lru_lock);
13561383
continue;
13571384
}
@@ -1738,6 +1765,11 @@ int __init gfs2_glock_init(void)
17381765
glock_workqueue = create_workqueue("glock_workqueue");
17391766
if (IS_ERR(glock_workqueue))
17401767
return PTR_ERR(glock_workqueue);
1768+
gfs2_delete_workqueue = create_workqueue("delete_workqueue");
1769+
if (IS_ERR(gfs2_delete_workqueue)) {
1770+
destroy_workqueue(glock_workqueue);
1771+
return PTR_ERR(gfs2_delete_workqueue);
1772+
}
17411773

17421774
register_shrinker(&glock_shrinker);
17431775

@@ -1748,6 +1780,7 @@ void gfs2_glock_exit(void)
17481780
{
17491781
unregister_shrinker(&glock_shrinker);
17501782
destroy_workqueue(glock_workqueue);
1783+
destroy_workqueue(gfs2_delete_workqueue);
17511784
}
17521785

17531786
static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)

fs/gfs2/glock.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ struct lm_lockops {
143143

144144
#define GLR_TRYFAILED 13
145145

146+
extern struct workqueue_struct *gfs2_delete_workqueue;
146147
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
147148
{
148149
struct gfs2_holder *gh;
@@ -191,6 +192,8 @@ static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
191192
int gfs2_glock_get(struct gfs2_sbd *sdp,
192193
u64 number, const struct gfs2_glock_operations *glops,
193194
int create, struct gfs2_glock **glp);
195+
void gfs2_glock_hold(struct gfs2_glock *gl);
196+
void gfs2_glock_put_nolock(struct gfs2_glock *gl);
194197
int gfs2_glock_put(struct gfs2_glock *gl);
195198
void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
196199
struct gfs2_holder *gh);

fs/gfs2/glops.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ static void trans_go_sync(struct gfs2_glock *gl)
323323

324324
if (gl->gl_state != LM_ST_UNLOCKED &&
325325
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
326+
flush_workqueue(gfs2_delete_workqueue);
326327
gfs2_meta_syncfs(sdp);
327328
gfs2_log_shutdown(sdp);
328329
}
@@ -372,6 +373,25 @@ static int trans_go_demote_ok(const struct gfs2_glock *gl)
372373
return 0;
373374
}
374375

376+
/**
377+
* iopen_go_callback - schedule the dcache entry for the inode to be deleted
378+
* @gl: the glock
379+
*
380+
* gl_spin lock is held while calling this
381+
*/
382+
static void iopen_go_callback(struct gfs2_glock *gl)
383+
{
384+
struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
385+
386+
if (gl->gl_demote_state == LM_ST_UNLOCKED &&
387+
gl->gl_state == LM_ST_SHARED &&
388+
ip && test_bit(GIF_USER, &ip->i_flags)) {
389+
gfs2_glock_hold(gl);
390+
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
391+
gfs2_glock_put_nolock(gl);
392+
}
393+
}
394+
375395
const struct gfs2_glock_operations gfs2_meta_glops = {
376396
.go_type = LM_TYPE_META,
377397
};
@@ -406,6 +426,7 @@ const struct gfs2_glock_operations gfs2_trans_glops = {
406426

407427
const struct gfs2_glock_operations gfs2_iopen_glops = {
408428
.go_type = LM_TYPE_IOPEN,
429+
.go_callback = iopen_go_callback,
409430
};
410431

411432
const struct gfs2_glock_operations gfs2_flock_glops = {

fs/gfs2/incore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ struct gfs2_glock_operations {
159159
int (*go_lock) (struct gfs2_holder *gh);
160160
void (*go_unlock) (struct gfs2_holder *gh);
161161
int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl);
162+
void (*go_callback) (struct gfs2_glock *gl);
162163
const int go_type;
163164
const unsigned long go_min_hold_time;
164165
};
@@ -228,6 +229,7 @@ struct gfs2_glock {
228229
struct list_head gl_ail_list;
229230
atomic_t gl_ail_count;
230231
struct delayed_work gl_work;
232+
struct work_struct gl_delete;
231233
};
232234

233235
#define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */

fs/gfs2/super.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
691691
struct gfs2_holder t_gh;
692692
int error;
693693

694+
flush_workqueue(gfs2_delete_workqueue);
694695
gfs2_quota_sync(sdp);
695696
gfs2_statfs_sync(sdp);
696697

0 commit comments

Comments
 (0)