diff options
-rw-r--r-- | fs/gfs2/daemon.c | 53 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 4 | ||||
-rw-r--r-- | fs/gfs2/main.c | 10 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 5 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 76 | ||||
-rw-r--r-- | fs/gfs2/quota.h | 1 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 2 | ||||
-rw-r--r-- | fs/gfs2/util.c | 1 | ||||
-rw-r--r-- | fs/gfs2/util.h | 1 |
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 | |||
91 | int 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: | |||
112 | fail: | 118 | fail: |
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 | ||
121 | fail: | 123 | fail: |
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 | ||
1198 | void gfs2_quota_scan(struct gfs2_sbd *sdp) | 1200 | static 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 | ||
1277 | static 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 | |||
1285 | static 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 | |||
1305 | int 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 | "ad_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); | |||
29 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); | 29 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); |
30 | 30 | ||
31 | int gfs2_quota_init(struct gfs2_sbd *sdp); | 31 | int gfs2_quota_init(struct gfs2_sbd *sdp); |
32 | void gfs2_quota_scan(struct gfs2_sbd *sdp); | ||
33 | void gfs2_quota_cleanup(struct gfs2_sbd *sdp); | 32 | void gfs2_quota_cleanup(struct gfs2_sbd *sdp); |
34 | 33 | ||
35 | static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) | 34 | static 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); | |||
408 | TUNE_ATTR(statfs_quantum, 1); | 408 | TUNE_ATTR(statfs_quantum, 1); |
409 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); | 409 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); |
410 | TUNE_ATTR_DAEMON(logd_secs, logd_process); | 410 | TUNE_ATTR_DAEMON(logd_secs, logd_process); |
411 | TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | ||
412 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 411 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
413 | 412 | ||
414 | static struct attribute *tune_attrs[] = { | 413 | static 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; | |||
25 | struct kmem_cache *gfs2_inode_cachep __read_mostly; | 25 | struct kmem_cache *gfs2_inode_cachep __read_mostly; |
26 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; | 26 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
27 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; |
28 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; | ||
28 | 29 | ||
29 | void gfs2_assert_i(struct gfs2_sbd *sdp) | 30 | void 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; | |||
148 | extern struct kmem_cache *gfs2_inode_cachep; | 148 | extern struct kmem_cache *gfs2_inode_cachep; |
149 | extern struct kmem_cache *gfs2_bufdata_cachep; | 149 | extern struct kmem_cache *gfs2_bufdata_cachep; |
150 | extern struct kmem_cache *gfs2_rgrpd_cachep; | 150 | extern struct kmem_cache *gfs2_rgrpd_cachep; |
151 | extern struct kmem_cache *gfs2_quotad_cachep; | ||
151 | 152 | ||
152 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, | 153 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, |
153 | unsigned int *p) | 154 | unsigned int *p) |