diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-08-01 08:57:10 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:55:08 -0400 |
commit | 8fbbfd214c853102b614f4705c1904ed14f5a808 (patch) | |
tree | b33cb7ee7392d64f99124588ef6af7c0d0bc7e9d /fs/gfs2/glock.c | |
parent | ca5a939b33166a9f5a2556e6c4ec031524852ba2 (diff) |
[GFS2] Reduce number of gfs2_scand processes to one
We only need a single gfs2_scand process rather than the one
per filesystem which we had previously. As a result the parameter
determining the frequency of gfs2_scand runs becomes a module
parameter rather than a mount parameter as it was before.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r-- | fs/gfs2/glock.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 0054b7df714a..559937c710fc 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/kthread.h> | ||
29 | #include <linux/freezer.h> | ||
28 | 30 | ||
29 | #include "gfs2.h" | 31 | #include "gfs2.h" |
30 | #include "incore.h" | 32 | #include "incore.h" |
@@ -58,6 +60,8 @@ static void gfs2_glock_xmote_th(struct gfs2_glock *gl, struct gfs2_holder *gh); | |||
58 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); | 60 | static void gfs2_glock_drop_th(struct gfs2_glock *gl); |
59 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 61 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
60 | static struct dentry *gfs2_root; | 62 | static struct dentry *gfs2_root; |
63 | static struct task_struct *scand_process; | ||
64 | static unsigned int scand_secs = 5; | ||
61 | 65 | ||
62 | #define GFS2_GL_HASH_SHIFT 15 | 66 | #define GFS2_GL_HASH_SHIFT 15 |
63 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) | 67 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) |
@@ -1627,7 +1631,7 @@ static int examine_bucket(glock_examiner examiner, struct gfs2_sbd *sdp, | |||
1627 | goto out; | 1631 | goto out; |
1628 | gl = list_entry(head->first, struct gfs2_glock, gl_list); | 1632 | gl = list_entry(head->first, struct gfs2_glock, gl_list); |
1629 | while(1) { | 1633 | while(1) { |
1630 | if (gl->gl_sbd == sdp) { | 1634 | if (!sdp || gl->gl_sbd == sdp) { |
1631 | gfs2_glock_hold(gl); | 1635 | gfs2_glock_hold(gl); |
1632 | read_unlock(gl_lock_addr(hash)); | 1636 | read_unlock(gl_lock_addr(hash)); |
1633 | if (prev) | 1637 | if (prev) |
@@ -1645,6 +1649,7 @@ out: | |||
1645 | read_unlock(gl_lock_addr(hash)); | 1649 | read_unlock(gl_lock_addr(hash)); |
1646 | if (prev) | 1650 | if (prev) |
1647 | gfs2_glock_put(prev); | 1651 | gfs2_glock_put(prev); |
1652 | cond_resched(); | ||
1648 | return has_entries; | 1653 | return has_entries; |
1649 | } | 1654 | } |
1650 | 1655 | ||
@@ -1673,20 +1678,6 @@ out_schedule: | |||
1673 | } | 1678 | } |
1674 | 1679 | ||
1675 | /** | 1680 | /** |
1676 | * gfs2_scand_internal - Look for glocks and inodes to toss from memory | ||
1677 | * @sdp: the filesystem | ||
1678 | * | ||
1679 | */ | ||
1680 | |||
1681 | void gfs2_scand_internal(struct gfs2_sbd *sdp) | ||
1682 | { | ||
1683 | unsigned int x; | ||
1684 | |||
1685 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) | ||
1686 | examine_bucket(scan_glock, sdp, x); | ||
1687 | } | ||
1688 | |||
1689 | /** | ||
1690 | * clear_glock - look at a glock and see if we can free it from glock cache | 1681 | * clear_glock - look at a glock and see if we can free it from glock cache |
1691 | * @gl: the glock to look at | 1682 | * @gl: the glock to look at |
1692 | * | 1683 | * |
@@ -1973,6 +1964,35 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp) | |||
1973 | return error; | 1964 | return error; |
1974 | } | 1965 | } |
1975 | 1966 | ||
1967 | /** | ||
1968 | * gfs2_scand - Look for cached glocks and inodes to toss from memory | ||
1969 | * @sdp: Pointer to GFS2 superblock | ||
1970 | * | ||
1971 | * One of these daemons runs, finding candidates to add to sd_reclaim_list. | ||
1972 | * See gfs2_glockd() | ||
1973 | */ | ||
1974 | |||
1975 | static int gfs2_scand(void *data) | ||
1976 | { | ||
1977 | unsigned x; | ||
1978 | unsigned delay; | ||
1979 | |||
1980 | while (!kthread_should_stop()) { | ||
1981 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) | ||
1982 | examine_bucket(scan_glock, NULL, x); | ||
1983 | if (freezing(current)) | ||
1984 | refrigerator(); | ||
1985 | delay = scand_secs; | ||
1986 | if (delay < 1) | ||
1987 | delay = 1; | ||
1988 | schedule_timeout_interruptible(delay * HZ); | ||
1989 | } | ||
1990 | |||
1991 | return 0; | ||
1992 | } | ||
1993 | |||
1994 | |||
1995 | |||
1976 | int __init gfs2_glock_init(void) | 1996 | int __init gfs2_glock_init(void) |
1977 | { | 1997 | { |
1978 | unsigned i; | 1998 | unsigned i; |
@@ -1984,9 +2004,22 @@ int __init gfs2_glock_init(void) | |||
1984 | rwlock_init(&gl_hash_locks[i]); | 2004 | rwlock_init(&gl_hash_locks[i]); |
1985 | } | 2005 | } |
1986 | #endif | 2006 | #endif |
2007 | |||
2008 | scand_process = kthread_run(gfs2_scand, NULL, "gfs2_scand"); | ||
2009 | if (IS_ERR(scand_process)) | ||
2010 | return PTR_ERR(scand_process); | ||
2011 | |||
1987 | return 0; | 2012 | return 0; |
1988 | } | 2013 | } |
1989 | 2014 | ||
2015 | void gfs2_glock_exit(void) | ||
2016 | { | ||
2017 | kthread_stop(scand_process); | ||
2018 | } | ||
2019 | |||
2020 | module_param(scand_secs, uint, S_IRUGO|S_IWUSR); | ||
2021 | MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs"); | ||
2022 | |||
1990 | static int gfs2_glock_iter_next(struct glock_iter *gi) | 2023 | static int gfs2_glock_iter_next(struct glock_iter *gi) |
1991 | { | 2024 | { |
1992 | struct gfs2_glock *gl; | 2025 | struct gfs2_glock *gl; |