gfs2: Move delete workqueue into super block
Move the global delete workqueue into struct gfs2_sbd so that we can flush / drain it without interfering with other filesystems. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
Родитель
3056dc4655
Коммит
0247f4e959
|
@ -67,7 +67,6 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state,
|
||||||
|
|
||||||
static struct dentry *gfs2_root;
|
static struct dentry *gfs2_root;
|
||||||
static struct workqueue_struct *glock_workqueue;
|
static struct workqueue_struct *glock_workqueue;
|
||||||
struct workqueue_struct *gfs2_delete_workqueue;
|
|
||||||
static LIST_HEAD(lru_list);
|
static LIST_HEAD(lru_list);
|
||||||
static atomic_t lru_count = ATOMIC_INIT(0);
|
static atomic_t lru_count = ATOMIC_INIT(0);
|
||||||
static DEFINE_SPINLOCK(lru_lock);
|
static DEFINE_SPINLOCK(lru_lock);
|
||||||
|
@ -2060,7 +2059,9 @@ static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
|
||||||
|
|
||||||
bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
|
bool gfs2_queue_delete_work(struct gfs2_glock *gl, unsigned long delay)
|
||||||
{
|
{
|
||||||
return queue_delayed_work(gfs2_delete_workqueue,
|
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||||
|
|
||||||
|
return queue_delayed_work(sdp->sd_delete_wq,
|
||||||
&gl->gl_delete, delay);
|
&gl->gl_delete, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2073,8 +2074,10 @@ void gfs2_cancel_delete_work(struct gfs2_glock *gl)
|
||||||
static void flush_delete_work(struct gfs2_glock *gl)
|
static void flush_delete_work(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
if (gl->gl_name.ln_type == LM_TYPE_IOPEN) {
|
if (gl->gl_name.ln_type == LM_TYPE_IOPEN) {
|
||||||
|
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
|
||||||
|
|
||||||
if (cancel_delayed_work(&gl->gl_delete)) {
|
if (cancel_delayed_work(&gl->gl_delete)) {
|
||||||
queue_delayed_work(gfs2_delete_workqueue,
|
queue_delayed_work(sdp->sd_delete_wq,
|
||||||
&gl->gl_delete, 0);
|
&gl->gl_delete, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2083,7 +2086,7 @@ static void flush_delete_work(struct gfs2_glock *gl)
|
||||||
void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
|
void gfs2_flush_delete_work(struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
glock_hash_walk(flush_delete_work, sdp);
|
glock_hash_walk(flush_delete_work, sdp);
|
||||||
flush_workqueue(gfs2_delete_workqueue);
|
flush_workqueue(sdp->sd_delete_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2444,18 +2447,9 @@ int __init gfs2_glock_init(void)
|
||||||
rhashtable_destroy(&gl_hash_table);
|
rhashtable_destroy(&gl_hash_table);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
gfs2_delete_workqueue = alloc_workqueue("delete_workqueue",
|
|
||||||
WQ_MEM_RECLAIM | WQ_FREEZABLE,
|
|
||||||
0);
|
|
||||||
if (!gfs2_delete_workqueue) {
|
|
||||||
destroy_workqueue(glock_workqueue);
|
|
||||||
rhashtable_destroy(&gl_hash_table);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = register_shrinker(&glock_shrinker, "gfs2-glock");
|
ret = register_shrinker(&glock_shrinker, "gfs2-glock");
|
||||||
if (ret) {
|
if (ret) {
|
||||||
destroy_workqueue(gfs2_delete_workqueue);
|
|
||||||
destroy_workqueue(glock_workqueue);
|
destroy_workqueue(glock_workqueue);
|
||||||
rhashtable_destroy(&gl_hash_table);
|
rhashtable_destroy(&gl_hash_table);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2472,7 +2466,6 @@ void gfs2_glock_exit(void)
|
||||||
unregister_shrinker(&glock_shrinker);
|
unregister_shrinker(&glock_shrinker);
|
||||||
rhashtable_destroy(&gl_hash_table);
|
rhashtable_destroy(&gl_hash_table);
|
||||||
destroy_workqueue(glock_workqueue);
|
destroy_workqueue(glock_workqueue);
|
||||||
destroy_workqueue(gfs2_delete_workqueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)
|
static void gfs2_glock_iter_next(struct gfs2_glock_iter *gi, loff_t n)
|
||||||
|
|
|
@ -144,7 +144,6 @@ struct gfs2_glock_aspace {
|
||||||
struct address_space mapping;
|
struct address_space mapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct workqueue_struct *gfs2_delete_workqueue;
|
|
||||||
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
|
static inline struct gfs2_holder *gfs2_glock_is_locked_by_me(struct gfs2_glock *gl)
|
||||||
{
|
{
|
||||||
struct gfs2_holder *gh;
|
struct gfs2_holder *gh;
|
||||||
|
|
|
@ -770,6 +770,10 @@ struct gfs2_sbd {
|
||||||
|
|
||||||
struct completion sd_journal_ready;
|
struct completion sd_journal_ready;
|
||||||
|
|
||||||
|
/* Workqueue stuff */
|
||||||
|
|
||||||
|
struct workqueue_struct *sd_delete_wq;
|
||||||
|
|
||||||
/* Daemon stuff */
|
/* Daemon stuff */
|
||||||
|
|
||||||
struct task_struct *sd_logd_process;
|
struct task_struct *sd_logd_process;
|
||||||
|
|
|
@ -1197,9 +1197,15 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||||
|
|
||||||
snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name);
|
snprintf(sdp->sd_fsname, sizeof(sdp->sd_fsname), "%s", sdp->sd_table_name);
|
||||||
|
|
||||||
|
sdp->sd_delete_wq = alloc_workqueue("gfs2-delete/%s",
|
||||||
|
WQ_MEM_RECLAIM | WQ_FREEZABLE, 0, sdp->sd_fsname);
|
||||||
|
error = -ENOMEM;
|
||||||
|
if (!sdp->sd_delete_wq)
|
||||||
|
goto fail_free;
|
||||||
|
|
||||||
error = gfs2_sys_fs_add(sdp);
|
error = gfs2_sys_fs_add(sdp);
|
||||||
if (error)
|
if (error)
|
||||||
goto fail_free;
|
goto fail_delete_wq;
|
||||||
|
|
||||||
gfs2_create_debugfs_file(sdp);
|
gfs2_create_debugfs_file(sdp);
|
||||||
|
|
||||||
|
@ -1309,6 +1315,8 @@ fail_lm:
|
||||||
fail_debug:
|
fail_debug:
|
||||||
gfs2_delete_debugfs_file(sdp);
|
gfs2_delete_debugfs_file(sdp);
|
||||||
gfs2_sys_fs_del(sdp);
|
gfs2_sys_fs_del(sdp);
|
||||||
|
fail_delete_wq:
|
||||||
|
destroy_workqueue(sdp->sd_delete_wq);
|
||||||
fail_free:
|
fail_free:
|
||||||
free_sbd(sdp);
|
free_sbd(sdp);
|
||||||
sb->s_fs_info = NULL;
|
sb->s_fs_info = NULL;
|
||||||
|
|
|
@ -630,6 +630,8 @@ restart:
|
||||||
/* Unmount the locking protocol */
|
/* Unmount the locking protocol */
|
||||||
gfs2_lm_unmount(sdp);
|
gfs2_lm_unmount(sdp);
|
||||||
|
|
||||||
|
destroy_workqueue(sdp->sd_delete_wq);
|
||||||
|
|
||||||
/* At this point, we're through participating in the lockspace */
|
/* At this point, we're through participating in the lockspace */
|
||||||
gfs2_sys_fs_del(sdp);
|
gfs2_sys_fs_del(sdp);
|
||||||
free_sbd(sdp);
|
free_sbd(sdp);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче