aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2008-11-17 09:25:37 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2009-01-05 02:39:05 -0500
commit37b2c8377c98acb60cf4d0126e385ef2153bded9 (patch)
tree9db50dbebc75a5e0dfde927b52dd05470cf66132
parentfa75cedc3da5923b8ea3877be9d5bc09b02e3860 (diff)
GFS2: Clean up & move gfs2_quotad
This patch is a clean up of gfs2_quotad prior to giving it an extra job to do in addition to the current portfolio of updating the quota and statfs information from time to time. As a result it has been moved into quota.c allowing one of the functions it calls to be made static. Also the clean up allows the two existing functions to have separate timeouts and also to coexist with its future role of dealing with the "truncate in progress" inode flag. The (pointless) setting of gfs2_quotad_secs is removed since we arrange to only wake up quotad when one of the two timers expires. In addition the struct gfs2_quota_data is moved into a slab cache, mainly for easier debugging. It should also be possible to use a shrinker in the future, rather than the current scheme of scanning the quota data entries from time to time. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/daemon.c53
-rw-r--r--fs/gfs2/incore.h4
-rw-r--r--fs/gfs2/main.c10
-rw-r--r--fs/gfs2/ops_fstype.c5
-rw-r--r--fs/gfs2/quota.c76
-rw-r--r--fs/gfs2/quota.h1
-rw-r--r--fs/gfs2/sys.c2
-rw-r--r--fs/gfs2/util.c1
-rw-r--r--fs/gfs2/util.h1
9 files changed, 84 insertions, 69 deletions
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c
index e51991947d2c..5668aa77b95a 100644
--- a/fs/gfs2/daemon.c
+++ b/fs/gfs2/daemon.c
@@ -23,7 +23,6 @@
23#include "daemon.h" 23#include "daemon.h"
24#include "glock.h" 24#include "glock.h"
25#include "log.h" 25#include "log.h"
26#include "quota.h"
27#include "recovery.h" 26#include "recovery.h"
28#include "super.h" 27#include "super.h"
29#include "util.h" 28#include "util.h"
@@ -82,55 +81,3 @@ int gfs2_recoverd(void *data)
82 return 0; 81 return 0;
83} 82}
84 83
85/**
86 * gfs2_quotad - Write cached quota changes into the quota file
87 * @sdp: Pointer to GFS2 superblock
88 *
89 */
90
91int gfs2_quotad(void *data)
92{
93 struct gfs2_sbd *sdp = data;
94 unsigned long t;
95 int error;
96
97 while (!kthread_should_stop()) {
98 /* Update the master statfs file */
99
100 t = sdp->sd_statfs_sync_time +
101 gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
102
103 if (time_after_eq(jiffies, t)) {
104 error = gfs2_statfs_sync(sdp);
105 if (error &&
106 error != -EROFS &&
107 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
108 fs_err(sdp, "quotad: (1) error=%d\n", error);
109 sdp->sd_statfs_sync_time = jiffies;
110 }
111
112 /* Update quota file */
113
114 t = sdp->sd_quota_sync_time +
115 gfs2_tune_get(sdp, gt_quota_quantum) * HZ;
116
117 if (time_after_eq(jiffies, t)) {
118 error = gfs2_quota_sync(sdp);
119 if (error &&
120 error != -EROFS &&
121 !test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
122 fs_err(sdp, "quotad: (2) error=%d\n", error);
123 sdp->sd_quota_sync_time = jiffies;
124 }
125
126 gfs2_quota_scan(sdp);
127
128 t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ;
129 if (freezing(current))
130 refrigerator();
131 schedule_timeout_interruptible(t);
132 }
133
134 return 0;
135}
136
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index 9e3b613d0bac..cfebc1793574 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -402,7 +402,6 @@ struct gfs2_tune {
402 402
403 unsigned int gt_recoverd_secs; 403 unsigned int gt_recoverd_secs;
404 unsigned int gt_logd_secs; 404 unsigned int gt_logd_secs;
405 unsigned int gt_quotad_secs;
406 405
407 unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ 406 unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */
408 unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ 407 unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */
@@ -509,7 +508,6 @@ struct gfs2_sbd {
509 spinlock_t sd_statfs_spin; 508 spinlock_t sd_statfs_spin;
510 struct gfs2_statfs_change_host sd_statfs_master; 509 struct gfs2_statfs_change_host sd_statfs_master;
511 struct gfs2_statfs_change_host sd_statfs_local; 510 struct gfs2_statfs_change_host sd_statfs_local;
512 unsigned long sd_statfs_sync_time;
513 511
514 /* Resource group stuff */ 512 /* Resource group stuff */
515 513
@@ -551,13 +549,13 @@ struct gfs2_sbd {
551 atomic_t sd_quota_count; 549 atomic_t sd_quota_count;
552 spinlock_t sd_quota_spin; 550 spinlock_t sd_quota_spin;
553 struct mutex sd_quota_mutex; 551 struct mutex sd_quota_mutex;
552 wait_queue_head_t sd_quota_wait;
554 553
555 unsigned int sd_quota_slots; 554 unsigned int sd_quota_slots;
556 unsigned int sd_quota_chunks; 555 unsigned int sd_quota_chunks;
557 unsigned char **sd_quota_bitmap; 556 unsigned char **sd_quota_bitmap;
558 557
559 u64 sd_quota_sync_gen; 558 u64 sd_quota_sync_gen;
560 unsigned long sd_quota_sync_time;
561 559
562 /* Log stuff */ 560 /* Log stuff */
563 561
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 3eea03c78534..e3f6f1844a21 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -93,6 +93,12 @@ static int __init init_gfs2_fs(void)
93 if (!gfs2_rgrpd_cachep) 93 if (!gfs2_rgrpd_cachep)
94 goto fail; 94 goto fail;
95 95
96 gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad",
97 sizeof(struct gfs2_quota_data),
98 0, 0, NULL);
99 if (!gfs2_quotad_cachep)
100 goto fail;
101
96 error = register_filesystem(&gfs2_fs_type); 102 error = register_filesystem(&gfs2_fs_type);
97 if (error) 103 if (error)
98 goto fail; 104 goto fail;
@@ -112,6 +118,9 @@ fail_unregister:
112fail: 118fail:
113 gfs2_glock_exit(); 119 gfs2_glock_exit();
114 120
121 if (gfs2_quotad_cachep)
122 kmem_cache_destroy(gfs2_quotad_cachep);
123
115 if (gfs2_rgrpd_cachep) 124 if (gfs2_rgrpd_cachep)
116 kmem_cache_destroy(gfs2_rgrpd_cachep); 125 kmem_cache_destroy(gfs2_rgrpd_cachep);
117 126
@@ -140,6 +149,7 @@ static void __exit exit_gfs2_fs(void)
140 unregister_filesystem(&gfs2_fs_type); 149 unregister_filesystem(&gfs2_fs_type);
141 unregister_filesystem(&gfs2meta_fs_type); 150 unregister_filesystem(&gfs2meta_fs_type);
142 151
152 kmem_cache_destroy(gfs2_quotad_cachep);
143 kmem_cache_destroy(gfs2_rgrpd_cachep); 153 kmem_cache_destroy(gfs2_rgrpd_cachep);
144 kmem_cache_destroy(gfs2_bufdata_cachep); 154 kmem_cache_destroy(gfs2_bufdata_cachep);
145 kmem_cache_destroy(gfs2_inode_cachep); 155 kmem_cache_destroy(gfs2_inode_cachep);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index dd83e8322350..5d137063b679 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -60,7 +60,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
60 gt->gt_log_flush_secs = 60; 60 gt->gt_log_flush_secs = 60;
61 gt->gt_recoverd_secs = 60; 61 gt->gt_recoverd_secs = 60;
62 gt->gt_logd_secs = 1; 62 gt->gt_logd_secs = 1;
63 gt->gt_quotad_secs = 5;
64 gt->gt_quota_simul_sync = 64; 63 gt->gt_quota_simul_sync = 64;
65 gt->gt_quota_warn_period = 10; 64 gt->gt_quota_warn_period = 10;
66 gt->gt_quota_scale_num = 1; 65 gt->gt_quota_scale_num = 1;
@@ -107,6 +106,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
107 INIT_LIST_HEAD(&sdp->sd_quota_list); 106 INIT_LIST_HEAD(&sdp->sd_quota_list);
108 spin_lock_init(&sdp->sd_quota_spin); 107 spin_lock_init(&sdp->sd_quota_spin);
109 mutex_init(&sdp->sd_quota_mutex); 108 mutex_init(&sdp->sd_quota_mutex);
109 init_waitqueue_head(&sdp->sd_quota_wait);
110 110
111 spin_lock_init(&sdp->sd_log_lock); 111 spin_lock_init(&sdp->sd_log_lock);
112 112
@@ -970,9 +970,6 @@ static int init_threads(struct gfs2_sbd *sdp, int undo)
970 } 970 }
971 sdp->sd_logd_process = p; 971 sdp->sd_logd_process = p;
972 972
973 sdp->sd_statfs_sync_time = jiffies;
974 sdp->sd_quota_sync_time = jiffies;
975
976 p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); 973 p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
977 error = IS_ERR(p); 974 error = IS_ERR(p);
978 if (error) { 975 if (error) {
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 228a46596188..0cfe44f0b6ab 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -46,6 +46,8 @@
46#include <linux/bio.h> 46#include <linux/bio.h>
47#include <linux/gfs2_ondisk.h> 47#include <linux/gfs2_ondisk.h>
48#include <linux/lm_interface.h> 48#include <linux/lm_interface.h>
49#include <linux/kthread.h>
50#include <linux/freezer.h>
49 51
50#include "gfs2.h" 52#include "gfs2.h"
51#include "incore.h" 53#include "incore.h"
@@ -94,7 +96,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
94 struct gfs2_quota_data *qd; 96 struct gfs2_quota_data *qd;
95 int error; 97 int error;
96 98
97 qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_NOFS); 99 qd = kmem_cache_zalloc(gfs2_quotad_cachep, GFP_NOFS);
98 if (!qd) 100 if (!qd)
99 return -ENOMEM; 101 return -ENOMEM;
100 102
@@ -119,7 +121,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
119 return 0; 121 return 0;
120 122
121fail: 123fail:
122 kfree(qd); 124 kmem_cache_free(gfs2_quotad_cachep, qd);
123 return error; 125 return error;
124} 126}
125 127
@@ -158,7 +160,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
158 if (qd || !create) { 160 if (qd || !create) {
159 if (new_qd) { 161 if (new_qd) {
160 gfs2_lvb_unhold(new_qd->qd_gl); 162 gfs2_lvb_unhold(new_qd->qd_gl);
161 kfree(new_qd); 163 kmem_cache_free(gfs2_quotad_cachep, new_qd);
162 } 164 }
163 *qdp = qd; 165 *qdp = qd;
164 return 0; 166 return 0;
@@ -1195,7 +1197,7 @@ fail:
1195 return error; 1197 return error;
1196} 1198}
1197 1199
1198void gfs2_quota_scan(struct gfs2_sbd *sdp) 1200static void gfs2_quota_scan(struct gfs2_sbd *sdp)
1199{ 1201{
1200 struct gfs2_quota_data *qd, *safe; 1202 struct gfs2_quota_data *qd, *safe;
1201 LIST_HEAD(dead); 1203 LIST_HEAD(dead);
@@ -1222,7 +1224,7 @@ void gfs2_quota_scan(struct gfs2_sbd *sdp)
1222 gfs2_assert_warn(sdp, !qd->qd_bh_count); 1224 gfs2_assert_warn(sdp, !qd->qd_bh_count);
1223 1225
1224 gfs2_lvb_unhold(qd->qd_gl); 1226 gfs2_lvb_unhold(qd->qd_gl);
1225 kfree(qd); 1227 kmem_cache_free(gfs2_quotad_cachep, qd);
1226 } 1228 }
1227} 1229}
1228 1230
@@ -1257,7 +1259,7 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
1257 gfs2_assert_warn(sdp, !qd->qd_bh_count); 1259 gfs2_assert_warn(sdp, !qd->qd_bh_count);
1258 1260
1259 gfs2_lvb_unhold(qd->qd_gl); 1261 gfs2_lvb_unhold(qd->qd_gl);
1260 kfree(qd); 1262 kmem_cache_free(gfs2_quotad_cachep, qd);
1261 1263
1262 spin_lock(&sdp->sd_quota_spin); 1264 spin_lock(&sdp->sd_quota_spin);
1263 } 1265 }
@@ -1272,3 +1274,65 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp)
1272 } 1274 }
1273} 1275}
1274 1276
1277static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
1278{
1279 if (error == 0 || error == -EROFS)
1280 return;
1281 if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
1282 fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error);
1283}
1284
1285static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg,
1286 int (*fxn)(struct gfs2_sbd *sdp),
1287 unsigned long t, unsigned long *timeo,
1288 unsigned int *new_timeo)
1289{
1290 if (t >= *timeo) {
1291 int error = fxn(sdp);
1292 quotad_error(sdp, msg, error);
1293 *timeo = gfs2_tune_get_i(&sdp->sd_tune, new_timeo) * HZ;
1294 } else {
1295 *timeo -= t;
1296 }
1297}
1298
1299/**
1300 * gfs2_quotad - Write cached quota changes into the quota file
1301 * @sdp: Pointer to GFS2 superblock
1302 *
1303 */
1304
1305int gfs2_quotad(void *data)
1306{
1307 struct gfs2_sbd *sdp = data;
1308 struct gfs2_tune *tune = &sdp->sd_tune;
1309 unsigned long statfs_timeo = 0;
1310 unsigned long quotad_timeo = 0;
1311 unsigned long t = 0;
1312 DEFINE_WAIT(wait);
1313
1314 while (!kthread_should_stop()) {
1315
1316 /* Update the master statfs file */
1317 quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t,
1318 &statfs_timeo, &tune->gt_statfs_quantum);
1319
1320 /* Update quota file */
1321 quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t,
1322 &quotad_timeo, &tune->gt_quota_quantum);
1323
1324 /* FIXME: This should be turned into a shrinker */
1325 gfs2_quota_scan(sdp);
1326
1327 if (freezing(current))
1328 refrigerator();
1329 t = min(quotad_timeo, statfs_timeo);
1330
1331 prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_UNINTERRUPTIBLE);
1332 t -= schedule_timeout(t);
1333 finish_wait(&sdp->sd_quota_wait, &wait);
1334 }
1335
1336 return 0;
1337}
1338
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h
index 3b7f4b0e5dfe..1d08aeef07e6 100644
--- a/fs/gfs2/quota.h
+++ b/fs/gfs2/quota.h
@@ -29,7 +29,6 @@ int gfs2_quota_sync(struct gfs2_sbd *sdp);
29int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); 29int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
30 30
31int gfs2_quota_init(struct gfs2_sbd *sdp); 31int gfs2_quota_init(struct gfs2_sbd *sdp);
32void gfs2_quota_scan(struct gfs2_sbd *sdp);
33void gfs2_quota_cleanup(struct gfs2_sbd *sdp); 32void gfs2_quota_cleanup(struct gfs2_sbd *sdp);
34 33
35static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) 34static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 7e1879f1a02c..59e36fd80903 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -408,7 +408,6 @@ TUNE_ATTR(stall_secs, 1);
408TUNE_ATTR(statfs_quantum, 1); 408TUNE_ATTR(statfs_quantum, 1);
409TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); 409TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process);
410TUNE_ATTR_DAEMON(logd_secs, logd_process); 410TUNE_ATTR_DAEMON(logd_secs, logd_process);
411TUNE_ATTR_DAEMON(quotad_secs, quotad_process);
412TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); 411TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
413 412
414static struct attribute *tune_attrs[] = { 413static struct attribute *tune_attrs[] = {
@@ -426,7 +425,6 @@ static struct attribute *tune_attrs[] = {
426 &tune_attr_statfs_quantum.attr, 425 &tune_attr_statfs_quantum.attr,
427 &tune_attr_recoverd_secs.attr, 426 &tune_attr_recoverd_secs.attr,
428 &tune_attr_logd_secs.attr, 427 &tune_attr_logd_secs.attr,
429 &tune_attr_quotad_secs.attr,
430 &tune_attr_quota_scale.attr, 428 &tune_attr_quota_scale.attr,
431 &tune_attr_new_files_jdata.attr, 429 &tune_attr_new_files_jdata.attr,
432 NULL, 430 NULL,
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index d31e355c61fb..374f50e95496 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -25,6 +25,7 @@ struct kmem_cache *gfs2_glock_cachep __read_mostly;
25struct kmem_cache *gfs2_inode_cachep __read_mostly; 25struct kmem_cache *gfs2_inode_cachep __read_mostly;
26struct kmem_cache *gfs2_bufdata_cachep __read_mostly; 26struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
27struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; 27struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
28struct kmem_cache *gfs2_quotad_cachep __read_mostly;
28 29
29void gfs2_assert_i(struct gfs2_sbd *sdp) 30void gfs2_assert_i(struct gfs2_sbd *sdp)
30{ 31{
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h
index 7f48576289c9..33e96b0ce9ab 100644
--- a/fs/gfs2/util.h
+++ b/fs/gfs2/util.h
@@ -148,6 +148,7 @@ extern struct kmem_cache *gfs2_glock_cachep;
148extern struct kmem_cache *gfs2_inode_cachep; 148extern struct kmem_cache *gfs2_inode_cachep;
149extern struct kmem_cache *gfs2_bufdata_cachep; 149extern struct kmem_cache *gfs2_bufdata_cachep;
150extern struct kmem_cache *gfs2_rgrpd_cachep; 150extern struct kmem_cache *gfs2_rgrpd_cachep;
151extern struct kmem_cache *gfs2_quotad_cachep;
151 152
152static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, 153static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt,
153 unsigned int *p) 154 unsigned int *p)