From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] GFS2: remove dcache entries for remote deleted inodes
Date: Fri, 24 Jul 2009 12:17:13 +0100 [thread overview]
Message-ID: <1248434233.4675.42.camel@localhost.localdomain> (raw)
In-Reply-To: <20090723235234.GD15326@ether.msp.redhat.com>
Hi,
Now in the -nmw git tree. Also I've rebased since there have been a few
patches hit upstream which affect GFS2 in the mean time. Thanks,
Steve.
On Thu, 2009-07-23 at 18:52 -0500, Benjamin Marzinski wrote:
> 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 <bmarzins@redhat.com>
> ---
> fs/gfs2/glock.c | 43 ++++++++++++++++++++++++++++++++++++++-----
> fs/gfs2/glock.h | 3 +++
> fs/gfs2/glops.c | 21 +++++++++++++++++++++
> fs/gfs2/incore.h | 2 ++
> fs/gfs2/super.c | 1 +
> 5 files changed, 65 insertions(+), 5 deletions(-)
>
> Index: gfs2-2.6-nmw/fs/gfs2/glock.c
> ===================================================================
> --- gfs2-2.6-nmw.orig/fs/gfs2/glock.c
> +++ gfs2-2.6-nmw/fs/gfs2/glock.c
> @@ -63,6 +63,7 @@ static void do_xmote(struct gfs2_glock *
> static DECLARE_RWSEM(gfs2_umount_flush_sem);
> static struct dentry *gfs2_root;
> static struct workqueue_struct *glock_workqueue;
> +struct workqueue_struct *gfs2_delete_workqueue;
> static LIST_HEAD(lru_list);
> static atomic_t lru_count = ATOMIC_INIT(0);
> static DEFINE_SPINLOCK(lru_lock);
> @@ -167,7 +168,7 @@ static void glock_free(struct gfs2_glock
> *
> */
>
> -static void gfs2_glock_hold(struct gfs2_glock *gl)
> +void gfs2_glock_hold(struct gfs2_glock *gl)
> {
> GLOCK_BUG_ON(gl, atomic_read(&gl->gl_ref) == 0);
> atomic_inc(&gl->gl_ref);
> @@ -222,7 +223,7 @@ static void gfs2_glock_schedule_for_recl
> * to the glock, in addition to the one it is dropping.
> */
>
> -static void gfs2_glock_put_nolock(struct gfs2_glock *gl)
> +void gfs2_glock_put_nolock(struct gfs2_glock *gl)
> {
> if (atomic_dec_and_test(&gl->gl_ref))
> GLOCK_BUG_ON(gl, 1);
> @@ -679,6 +680,29 @@ out_unlock:
> goto out;
> }
>
> +static void delete_work_func(struct work_struct *work)
> +{
> + struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_delete);
> + struct gfs2_sbd *sdp = gl->gl_sbd;
> + struct gfs2_inode *ip = NULL;
> + struct inode *inode;
> + u64 no_addr = 0;
> +
> + spin_lock(&gl->gl_spin);
> + ip = (struct gfs2_inode *)gl->gl_object;
> + if (ip)
> + no_addr = ip->i_no_addr;
> + spin_unlock(&gl->gl_spin);
> + if (ip) {
> + inode = gfs2_ilookup(sdp->sd_vfs, no_addr);
> + if (inode) {
> + d_prune_aliases(inode);
> + iput(inode);
> + }
> + }
> + gfs2_glock_put(gl);
> +}
> +
> static void glock_work_func(struct work_struct *work)
> {
> unsigned long delay = 0;
> @@ -757,6 +781,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp,
> gl->gl_sbd = sdp;
> gl->gl_aspace = NULL;
> INIT_DELAYED_WORK(&gl->gl_work, glock_work_func);
> + INIT_WORK(&gl->gl_delete, delete_work_func);
>
> /* If this glock protects actual on-disk data or metadata blocks,
> create a VFS inode to manage the pages/buffers holding them. */
> @@ -898,6 +923,8 @@ static void handle_callback(struct gfs2_
> gl->gl_demote_state != state) {
> gl->gl_demote_state = LM_ST_UNLOCKED;
> }
> + if (gl->gl_ops->go_callback)
> + gl->gl_ops->go_callback(gl);
> trace_gfs2_demote_rq(gl);
> }
>
> @@ -1344,14 +1371,14 @@ static int gfs2_shrink_glock_memory(int
> spin_unlock(&lru_lock);
> spin_lock(&gl->gl_spin);
> may_demote = demote_ok(gl);
> - spin_unlock(&gl->gl_spin);
> - clear_bit(GLF_LOCK, &gl->gl_flags);
> if (may_demote) {
> handle_callback(gl, LM_ST_UNLOCKED, 0);
> nr--;
> }
> if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
> - gfs2_glock_put(gl);
> + gfs2_glock_put_nolock(gl);
> + spin_unlock(&gl->gl_spin);
> + clear_bit(GLF_LOCK, &gl->gl_flags);
> spin_lock(&lru_lock);
> continue;
> }
> @@ -1738,6 +1765,11 @@ int __init gfs2_glock_init(void)
> glock_workqueue = create_workqueue("glock_workqueue");
> if (IS_ERR(glock_workqueue))
> return PTR_ERR(glock_workqueue);
> + gfs2_delete_workqueue = create_workqueue("delete_workqueue");
> + if (IS_ERR(gfs2_delete_workqueue)) {
> + destroy_workqueue(glock_workqueue);
> + return PTR_ERR(gfs2_delete_workqueue);
> + }
>
> register_shrinker(&glock_shrinker);
>
> @@ -1748,6 +1780,7 @@ void gfs2_glock_exit(void)
> {
> unregister_shrinker(&glock_shrinker);
> destroy_workqueue(glock_workqueue);
> + destroy_workqueue(gfs2_delete_workqueue);
> }
>
> static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi)
> Index: gfs2-2.6-nmw/fs/gfs2/incore.h
> ===================================================================
> --- gfs2-2.6-nmw.orig/fs/gfs2/incore.h
> +++ gfs2-2.6-nmw/fs/gfs2/incore.h
> @@ -159,6 +159,7 @@ struct gfs2_glock_operations {
> int (*go_lock) (struct gfs2_holder *gh);
> void (*go_unlock) (struct gfs2_holder *gh);
> int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl);
> + void (*go_callback) (struct gfs2_glock *gl);
> const int go_type;
> const unsigned long go_min_hold_time;
> };
> @@ -228,6 +229,7 @@ struct gfs2_glock {
> struct list_head gl_ail_list;
> atomic_t gl_ail_count;
> struct delayed_work gl_work;
> + struct work_struct gl_delete;
> };
>
> #define GFS2_MIN_LVB_SIZE 32 /* Min size of LVB that gfs2 supports */
> Index: gfs2-2.6-nmw/fs/gfs2/glops.c
> ===================================================================
> --- gfs2-2.6-nmw.orig/fs/gfs2/glops.c
> +++ gfs2-2.6-nmw/fs/gfs2/glops.c
> @@ -323,6 +323,7 @@ static void trans_go_sync(struct gfs2_gl
>
> if (gl->gl_state != LM_ST_UNLOCKED &&
> test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
> + flush_workqueue(gfs2_delete_workqueue);
> gfs2_meta_syncfs(sdp);
> gfs2_log_shutdown(sdp);
> }
> @@ -372,6 +373,25 @@ static int trans_go_demote_ok(const stru
> return 0;
> }
>
> +/**
> + * iopen_go_callback - schedule the dcache entry for the inode to be deleted
> + * @gl: the glock
> + *
> + * gl_spin lock is held while calling this
> + */
> +static void iopen_go_callback(struct gfs2_glock *gl)
> +{
> + struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
> +
> + if (gl->gl_demote_state == LM_ST_UNLOCKED &&
> + gl->gl_state == LM_ST_SHARED &&
> + ip && test_bit(GIF_USER, &ip->i_flags)) {
> + gfs2_glock_hold(gl);
> + if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
> + gfs2_glock_put_nolock(gl);
> + }
> +}
> +
> const struct gfs2_glock_operations gfs2_meta_glops = {
> .go_type = LM_TYPE_META,
> };
> @@ -406,6 +426,7 @@ const struct gfs2_glock_operations gfs2_
>
> const struct gfs2_glock_operations gfs2_iopen_glops = {
> .go_type = LM_TYPE_IOPEN,
> + .go_callback = iopen_go_callback,
> };
>
> const struct gfs2_glock_operations gfs2_flock_glops = {
> Index: gfs2-2.6-nmw/fs/gfs2/glock.h
> ===================================================================
> --- gfs2-2.6-nmw.orig/fs/gfs2/glock.h
> +++ gfs2-2.6-nmw/fs/gfs2/glock.h
> @@ -143,6 +143,7 @@ struct lm_lockops {
>
> #define GLR_TRYFAILED 13
>
> +extern struct workqueue_struct *gfs2_delete_workqueue;
> static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
> {
> struct gfs2_holder *gh;
> @@ -191,6 +192,8 @@ static inline int gfs2_glock_is_blocking
> int gfs2_glock_get(struct gfs2_sbd *sdp,
> u64 number, const struct gfs2_glock_operations *glops,
> int create, struct gfs2_glock **glp);
> +void gfs2_glock_hold(struct gfs2_glock *gl);
> +void gfs2_glock_put_nolock(struct gfs2_glock *gl);
> int gfs2_glock_put(struct gfs2_glock *gl);
> void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags,
> struct gfs2_holder *gh);
> Index: gfs2-2.6-nmw/fs/gfs2/super.c
> ===================================================================
> --- gfs2-2.6-nmw.orig/fs/gfs2/super.c
> +++ gfs2-2.6-nmw/fs/gfs2/super.c
> @@ -691,6 +691,7 @@ static int gfs2_make_fs_ro(struct gfs2_s
> struct gfs2_holder t_gh;
> int error;
>
> + flush_workqueue(gfs2_delete_workqueue);
> gfs2_quota_sync(sdp);
> gfs2_statfs_sync(sdp);
>
>
prev parent reply other threads:[~2009-07-24 11:17 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-23 23:52 [Cluster-devel] GFS2: remove dcache entries for remote deleted inodes Benjamin Marzinski
2009-07-24 11:17 ` Steven Whitehouse [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1248434233.4675.42.camel@localhost.localdomain \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox