aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/glock.c33
-rw-r--r--fs/gfs2/glock.h1
-rw-r--r--fs/gfs2/glops.c11
-rw-r--r--fs/gfs2/incore.h3
-rw-r--r--fs/gfs2/main.c1
-rw-r--r--fs/gfs2/ops_fstype.c2
-rw-r--r--fs/gfs2/quota.c31
7 files changed, 75 insertions, 7 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 27cb9cca9c08..4ddf3bd55dda 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -40,6 +40,7 @@
40#include "quota.h" 40#include "quota.h"
41#include "super.h" 41#include "super.h"
42#include "util.h" 42#include "util.h"
43#include "bmap.h"
43 44
44struct gfs2_gl_hash_bucket { 45struct gfs2_gl_hash_bucket {
45 struct hlist_head hb_list; 46 struct hlist_head hb_list;
@@ -289,7 +290,8 @@ static void gfs2_holder_wake(struct gfs2_holder *gh)
289 * do_promote - promote as many requests as possible on the current queue 290 * do_promote - promote as many requests as possible on the current queue
290 * @gl: The glock 291 * @gl: The glock
291 * 292 *
292 * Returns: true if there is a blocked holder at the head of the list 293 * Returns: 1 if there is a blocked holder at the head of the list, or 2
294 * if a type specific operation is underway.
293 */ 295 */
294 296
295static int do_promote(struct gfs2_glock *gl) 297static int do_promote(struct gfs2_glock *gl)
@@ -312,6 +314,8 @@ restart:
312 ret = glops->go_lock(gh); 314 ret = glops->go_lock(gh);
313 spin_lock(&gl->gl_spin); 315 spin_lock(&gl->gl_spin);
314 if (ret) { 316 if (ret) {
317 if (ret == 1)
318 return 2;
315 gh->gh_error = ret; 319 gh->gh_error = ret;
316 list_del_init(&gh->gh_list); 320 list_del_init(&gh->gh_list);
317 gfs2_holder_wake(gh); 321 gfs2_holder_wake(gh);
@@ -416,6 +420,7 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret)
416 const struct gfs2_glock_operations *glops = gl->gl_ops; 420 const struct gfs2_glock_operations *glops = gl->gl_ops;
417 struct gfs2_holder *gh; 421 struct gfs2_holder *gh;
418 unsigned state = ret & LM_OUT_ST_MASK; 422 unsigned state = ret & LM_OUT_ST_MASK;
423 int rv;
419 424
420 spin_lock(&gl->gl_spin); 425 spin_lock(&gl->gl_spin);
421 state_change(gl, state); 426 state_change(gl, state);
@@ -470,7 +475,6 @@ retry:
470 gfs2_demote_wake(gl); 475 gfs2_demote_wake(gl);
471 if (state != LM_ST_UNLOCKED) { 476 if (state != LM_ST_UNLOCKED) {
472 if (glops->go_xmote_bh) { 477 if (glops->go_xmote_bh) {
473 int rv;
474 spin_unlock(&gl->gl_spin); 478 spin_unlock(&gl->gl_spin);
475 rv = glops->go_xmote_bh(gl, gh); 479 rv = glops->go_xmote_bh(gl, gh);
476 if (rv == -EAGAIN) 480 if (rv == -EAGAIN)
@@ -481,10 +485,13 @@ retry:
481 goto out; 485 goto out;
482 } 486 }
483 } 487 }
484 do_promote(gl); 488 rv = do_promote(gl);
489 if (rv == 2)
490 goto out_locked;
485 } 491 }
486out: 492out:
487 clear_bit(GLF_LOCK, &gl->gl_flags); 493 clear_bit(GLF_LOCK, &gl->gl_flags);
494out_locked:
488 spin_unlock(&gl->gl_spin); 495 spin_unlock(&gl->gl_spin);
489 gfs2_glock_put(gl); 496 gfs2_glock_put(gl);
490} 497}
@@ -584,6 +591,7 @@ __releases(&gl->gl_spin)
584__acquires(&gl->gl_spin) 591__acquires(&gl->gl_spin)
585{ 592{
586 struct gfs2_holder *gh = NULL; 593 struct gfs2_holder *gh = NULL;
594 int ret;
587 595
588 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) 596 if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
589 return; 597 return;
@@ -602,8 +610,11 @@ __acquires(&gl->gl_spin)
602 } else { 610 } else {
603 if (test_bit(GLF_DEMOTE, &gl->gl_flags)) 611 if (test_bit(GLF_DEMOTE, &gl->gl_flags))
604 gfs2_demote_wake(gl); 612 gfs2_demote_wake(gl);
605 if (do_promote(gl) == 0) 613 ret = do_promote(gl);
614 if (ret == 0)
606 goto out; 615 goto out;
616 if (ret == 2)
617 return;
607 gh = find_first_waiter(gl); 618 gh = find_first_waiter(gl);
608 gl->gl_target = gh->gh_state; 619 gl->gl_target = gh->gh_state;
609 if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) 620 if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
@@ -1556,6 +1567,20 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp)
1556 } 1567 }
1557} 1568}
1558 1569
1570void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
1571{
1572 struct gfs2_glock *gl = ip->i_gl;
1573 int ret;
1574
1575 ret = gfs2_truncatei_resume(ip);
1576 gfs2_assert_withdraw(gl->gl_sbd, ret == 0);
1577
1578 spin_lock(&gl->gl_spin);
1579 clear_bit(GLF_LOCK, &gl->gl_flags);
1580 run_queue(gl, 1);
1581 spin_unlock(&gl->gl_spin);
1582}
1583
1559static const char *state2str(unsigned state) 1584static const char *state2str(unsigned state)
1560{ 1585{
1561 switch(state) { 1586 switch(state) {
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 695c6b193611..13a64ee6523b 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -132,6 +132,7 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data);
132void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); 132void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl);
133void gfs2_reclaim_glock(struct gfs2_sbd *sdp); 133void gfs2_reclaim_glock(struct gfs2_sbd *sdp);
134void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); 134void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
135void gfs2_glock_finish_truncate(struct gfs2_inode *ip);
135 136
136int __init gfs2_glock_init(void); 137int __init gfs2_glock_init(void);
137void gfs2_glock_exit(void); 138void gfs2_glock_exit(void);
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 68ee66552d19..8ebff8ebae20 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -227,6 +227,7 @@ static int inode_go_demote_ok(struct gfs2_glock *gl)
227static int inode_go_lock(struct gfs2_holder *gh) 227static int inode_go_lock(struct gfs2_holder *gh)
228{ 228{
229 struct gfs2_glock *gl = gh->gh_gl; 229 struct gfs2_glock *gl = gh->gh_gl;
230 struct gfs2_sbd *sdp = gl->gl_sbd;
230 struct gfs2_inode *ip = gl->gl_object; 231 struct gfs2_inode *ip = gl->gl_object;
231 int error = 0; 232 int error = 0;
232 233
@@ -241,8 +242,14 @@ static int inode_go_lock(struct gfs2_holder *gh)
241 242
242 if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && 243 if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) &&
243 (gl->gl_state == LM_ST_EXCLUSIVE) && 244 (gl->gl_state == LM_ST_EXCLUSIVE) &&
244 (gh->gh_state == LM_ST_EXCLUSIVE)) 245 (gh->gh_state == LM_ST_EXCLUSIVE)) {
245 error = gfs2_truncatei_resume(ip); 246 spin_lock(&sdp->sd_trunc_lock);
247 if (list_empty(&ip->i_trunc_list))
248 list_add(&sdp->sd_trunc_list, &ip->i_trunc_list);
249 spin_unlock(&sdp->sd_trunc_lock);
250 wake_up(&sdp->sd_quota_wait);
251 return 1;
252 }
246 253
247 return error; 254 return error;
248} 255}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index cfebc1793574..dd7d0f8f3575 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -244,6 +244,7 @@ struct gfs2_inode {
244 struct gfs2_alloc *i_alloc; 244 struct gfs2_alloc *i_alloc;
245 u64 i_goal; /* goal block for allocations */ 245 u64 i_goal; /* goal block for allocations */
246 struct rw_semaphore i_rw_mutex; 246 struct rw_semaphore i_rw_mutex;
247 struct list_head i_trunc_list;
247 u32 i_entries; 248 u32 i_entries;
248 u32 i_diskflags; 249 u32 i_diskflags;
249 u8 i_height; 250 u8 i_height;
@@ -550,6 +551,8 @@ struct gfs2_sbd {
550 spinlock_t sd_quota_spin; 551 spinlock_t sd_quota_spin;
551 struct mutex sd_quota_mutex; 552 struct mutex sd_quota_mutex;
552 wait_queue_head_t sd_quota_wait; 553 wait_queue_head_t sd_quota_wait;
554 struct list_head sd_trunc_list;
555 spinlock_t sd_trunc_lock;
553 556
554 unsigned int sd_quota_slots; 557 unsigned int sd_quota_slots;
555 unsigned int sd_quota_chunks; 558 unsigned int sd_quota_chunks;
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index e3f6f1844a21..cf39295ccb90 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -30,6 +30,7 @@ static void gfs2_init_inode_once(void *foo)
30 30
31 inode_init_once(&ip->i_inode); 31 inode_init_once(&ip->i_inode);
32 init_rwsem(&ip->i_rw_mutex); 32 init_rwsem(&ip->i_rw_mutex);
33 INIT_LIST_HEAD(&ip->i_trunc_list);
33 ip->i_alloc = NULL; 34 ip->i_alloc = NULL;
34} 35}
35 36
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 5d137063b679..a9a83804eea7 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -107,6 +107,8 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
107 spin_lock_init(&sdp->sd_quota_spin); 107 spin_lock_init(&sdp->sd_quota_spin);
108 mutex_init(&sdp->sd_quota_mutex); 108 mutex_init(&sdp->sd_quota_mutex);
109 init_waitqueue_head(&sdp->sd_quota_wait); 109 init_waitqueue_head(&sdp->sd_quota_wait);
110 INIT_LIST_HEAD(&sdp->sd_trunc_list);
111 spin_lock_init(&sdp->sd_trunc_lock);
110 112
111 spin_lock_init(&sdp->sd_log_lock); 113 spin_lock_init(&sdp->sd_log_lock);
112 114
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 0cfe44f0b6ab..b08d09696b3e 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -1296,6 +1296,25 @@ static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg,
1296 } 1296 }
1297} 1297}
1298 1298
1299static void quotad_check_trunc_list(struct gfs2_sbd *sdp)
1300{
1301 struct gfs2_inode *ip;
1302
1303 while(1) {
1304 ip = NULL;
1305 spin_lock(&sdp->sd_trunc_lock);
1306 if (!list_empty(&sdp->sd_trunc_list)) {
1307 ip = list_entry(sdp->sd_trunc_list.next,
1308 struct gfs2_inode, i_trunc_list);
1309 list_del_init(&ip->i_trunc_list);
1310 }
1311 spin_unlock(&sdp->sd_trunc_lock);
1312 if (ip == NULL)
1313 return;
1314 gfs2_glock_finish_truncate(ip);
1315 }
1316}
1317
1299/** 1318/**
1300 * gfs2_quotad - Write cached quota changes into the quota file 1319 * gfs2_quotad - Write cached quota changes into the quota file
1301 * @sdp: Pointer to GFS2 superblock 1320 * @sdp: Pointer to GFS2 superblock
@@ -1310,6 +1329,7 @@ int gfs2_quotad(void *data)
1310 unsigned long quotad_timeo = 0; 1329 unsigned long quotad_timeo = 0;
1311 unsigned long t = 0; 1330 unsigned long t = 0;
1312 DEFINE_WAIT(wait); 1331 DEFINE_WAIT(wait);
1332 int empty;
1313 1333
1314 while (!kthread_should_stop()) { 1334 while (!kthread_should_stop()) {
1315 1335
@@ -1324,12 +1344,21 @@ int gfs2_quotad(void *data)
1324 /* FIXME: This should be turned into a shrinker */ 1344 /* FIXME: This should be turned into a shrinker */
1325 gfs2_quota_scan(sdp); 1345 gfs2_quota_scan(sdp);
1326 1346
1347 /* Check for & recover partially truncated inodes */
1348 quotad_check_trunc_list(sdp);
1349
1327 if (freezing(current)) 1350 if (freezing(current))
1328 refrigerator(); 1351 refrigerator();
1329 t = min(quotad_timeo, statfs_timeo); 1352 t = min(quotad_timeo, statfs_timeo);
1330 1353
1331 prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_UNINTERRUPTIBLE); 1354 prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_UNINTERRUPTIBLE);
1332 t -= schedule_timeout(t); 1355 spin_lock(&sdp->sd_trunc_lock);
1356 empty = list_empty(&sdp->sd_trunc_list);
1357 spin_unlock(&sdp->sd_trunc_lock);
1358 if (empty)
1359 t -= schedule_timeout(t);
1360 else
1361 t = 0;
1333 finish_wait(&sdp->sd_quota_wait, &wait); 1362 finish_wait(&sdp->sd_quota_wait, &wait);
1334 } 1363 }
1335 1364