aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 e51991947d2..5668aa77b95 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 9e3b613d0ba..cfebc179357 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 3eea03c7853..e3f6f1844a2 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 dd83e832235..5d137063b67 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 228a4659618..0cfe44f0b6a 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 3b7f4b0e5df..1d08aeef07e 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 7e1879f1a02..59e36fd8090 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 d31e355c61f..374f50e9549 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 7f48576289c..33e96b0ce9a 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)