aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c34
1 files changed, 6 insertions, 28 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index e6a84f7a9b71..16c14441a371 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/buffer_head.h> 14#include <linux/buffer_head.h>
15#include <linux/gfs2_ondisk.h> 15#include <linux/gfs2_ondisk.h>
16#include <linux/crc32.h>
16#include <asm/semaphore.h> 17#include <asm/semaphore.h>
17 18
18#include "gfs2.h" 19#include "gfs2.h"
@@ -24,18 +25,13 @@
24#include "lops.h" 25#include "lops.h"
25#include "meta_io.h" 26#include "meta_io.h"
26#include "util.h" 27#include "util.h"
28#include "dir.h"
27 29
28#define PULL 1 30#define PULL 1
29 31
30static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq,
31 atomic_t *a)
32{
33 wait_event(*wq, atomic_read(a) ? 0 : 1);
34}
35
36static void lock_for_trans(struct gfs2_sbd *sdp) 32static void lock_for_trans(struct gfs2_sbd *sdp)
37{ 33{
38 do_lock_wait(sdp, &sdp->sd_log_trans_wq, &sdp->sd_log_flush_count); 34 wait_event(sdp->sd_log_trans_wq, atomic_read(&sdp->sd_log_flush_count) ? 0 : 1);
39 atomic_inc(&sdp->sd_log_trans_count); 35 atomic_inc(&sdp->sd_log_trans_count);
40} 36}
41 37
@@ -49,7 +45,7 @@ static void unlock_from_trans(struct gfs2_sbd *sdp)
49static void gfs2_lock_for_flush(struct gfs2_sbd *sdp) 45static void gfs2_lock_for_flush(struct gfs2_sbd *sdp)
50{ 46{
51 atomic_inc(&sdp->sd_log_flush_count); 47 atomic_inc(&sdp->sd_log_flush_count);
52 do_lock_wait(sdp, &sdp->sd_log_flush_wq, &sdp->sd_log_trans_count); 48 wait_event(sdp->sd_log_flush_wq, atomic_read(&sdp->sd_log_trans_count) ? 0 : 1);
53} 49}
54 50
55static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp) 51static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp)
@@ -191,37 +187,19 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
191 187
192int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 188int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
193{ 189{
194 LIST_HEAD(list);
195 unsigned int try = 0; 190 unsigned int try = 0;
196 191
197 if (gfs2_assert_warn(sdp, blks) || 192 if (gfs2_assert_warn(sdp, blks) ||
198 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks)) 193 gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
199 return -EINVAL; 194 return -EINVAL;
200 195
196 mutex_lock(&sdp->sd_log_reserve_mutex);
201 for (;;) { 197 for (;;) {
202 gfs2_log_lock(sdp); 198 gfs2_log_lock(sdp);
203 if (list_empty(&list)) {
204 list_add_tail(&list, &sdp->sd_log_blks_list);
205 while (sdp->sd_log_blks_list.next != &list) {
206 DECLARE_WAITQUEUE(__wait_chan, current);
207 set_current_state(TASK_UNINTERRUPTIBLE);
208 add_wait_queue(&sdp->sd_log_blks_wait,
209 &__wait_chan);
210 gfs2_log_unlock(sdp);
211 schedule();
212 gfs2_log_lock(sdp);
213 remove_wait_queue(&sdp->sd_log_blks_wait,
214 &__wait_chan);
215 set_current_state(TASK_RUNNING);
216 }
217 }
218 /* Never give away the last block so we can
219 always pull the tail if we need to. */
220 if (sdp->sd_log_blks_free > blks) { 199 if (sdp->sd_log_blks_free > blks) {
221 sdp->sd_log_blks_free -= blks; 200 sdp->sd_log_blks_free -= blks;
222 list_del(&list);
223 gfs2_log_unlock(sdp); 201 gfs2_log_unlock(sdp);
224 wake_up(&sdp->sd_log_blks_wait); 202 mutex_unlock(&sdp->sd_log_reserve_mutex);
225 break; 203 break;
226 } 204 }
227 205