OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [gfs2/] [log.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
4
 *
5
 * This copyrighted material is made available to anyone wishing to use,
6
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
8
 */
9
 
10
#include <linux/sched.h>
11
#include <linux/slab.h>
12
#include <linux/spinlock.h>
13
#include <linux/completion.h>
14
#include <linux/buffer_head.h>
15
#include <linux/gfs2_ondisk.h>
16
#include <linux/crc32.h>
17
#include <linux/lm_interface.h>
18
#include <linux/delay.h>
19
 
20
#include "gfs2.h"
21
#include "incore.h"
22
#include "bmap.h"
23
#include "glock.h"
24
#include "log.h"
25
#include "lops.h"
26
#include "meta_io.h"
27
#include "util.h"
28
#include "dir.h"
29
 
30
#define PULL 1
31
 
32
/**
33
 * gfs2_struct2blk - compute stuff
34
 * @sdp: the filesystem
35
 * @nstruct: the number of structures
36
 * @ssize: the size of the structures
37
 *
38
 * Compute the number of log descriptor blocks needed to hold a certain number
39
 * of structures of a certain size.
40
 *
41
 * Returns: the number of blocks needed (minimum is always 1)
42
 */
43
 
44
unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct,
45
                             unsigned int ssize)
46
{
47
        unsigned int blks;
48
        unsigned int first, second;
49
 
50
        blks = 1;
51
        first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / ssize;
52
 
53
        if (nstruct > first) {
54
                second = (sdp->sd_sb.sb_bsize -
55
                          sizeof(struct gfs2_meta_header)) / ssize;
56
                blks += DIV_ROUND_UP(nstruct - first, second);
57
        }
58
 
59
        return blks;
60
}
61
 
62
/**
63
 * gfs2_remove_from_ail - Remove an entry from the ail lists, updating counters
64
 * @mapping: The associated mapping (maybe NULL)
65
 * @bd: The gfs2_bufdata to remove
66
 *
67
 * The log lock _must_ be held when calling this function
68
 *
69
 */
70
 
71
void gfs2_remove_from_ail(struct address_space *mapping, struct gfs2_bufdata *bd)
72
{
73
        bd->bd_ail = NULL;
74
        list_del_init(&bd->bd_ail_st_list);
75
        list_del_init(&bd->bd_ail_gl_list);
76
        atomic_dec(&bd->bd_gl->gl_ail_count);
77
        if (mapping)
78
                gfs2_meta_cache_flush(GFS2_I(mapping->host));
79
        brelse(bd->bd_bh);
80
}
81
 
82
/**
83
 * gfs2_ail1_start_one - Start I/O on a part of the AIL
84
 * @sdp: the filesystem
85
 * @tr: the part of the AIL
86
 *
87
 */
88
 
89
static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
90
{
91
        struct gfs2_bufdata *bd, *s;
92
        struct buffer_head *bh;
93
        int retry;
94
 
95
        BUG_ON(!spin_is_locked(&sdp->sd_log_lock));
96
 
97
        do {
98
                retry = 0;
99
 
100
                list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
101
                                                 bd_ail_st_list) {
102
                        bh = bd->bd_bh;
103
 
104
                        gfs2_assert(sdp, bd->bd_ail == ai);
105
 
106
                        if (!buffer_busy(bh)) {
107
                                if (!buffer_uptodate(bh))
108
                                        gfs2_io_error_bh(sdp, bh);
109
                                list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
110
                                continue;
111
                        }
112
 
113
                        if (!buffer_dirty(bh))
114
                                continue;
115
 
116
                        list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list);
117
 
118
                        get_bh(bh);
119
                        gfs2_log_unlock(sdp);
120
                        lock_buffer(bh);
121
                        if (test_clear_buffer_dirty(bh)) {
122
                                bh->b_end_io = end_buffer_write_sync;
123
                                submit_bh(WRITE, bh);
124
                        } else {
125
                                unlock_buffer(bh);
126
                                brelse(bh);
127
                        }
128
                        gfs2_log_lock(sdp);
129
 
130
                        retry = 1;
131
                        break;
132
                }
133
        } while (retry);
134
}
135
 
136
/**
137
 * gfs2_ail1_empty_one - Check whether or not a trans in the AIL has been synced
138
 * @sdp: the filesystem
139
 * @ai: the AIL entry
140
 *
141
 */
142
 
143
static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int flags)
144
{
145
        struct gfs2_bufdata *bd, *s;
146
        struct buffer_head *bh;
147
 
148
        list_for_each_entry_safe_reverse(bd, s, &ai->ai_ail1_list,
149
                                         bd_ail_st_list) {
150
                bh = bd->bd_bh;
151
 
152
                gfs2_assert(sdp, bd->bd_ail == ai);
153
 
154
                if (buffer_busy(bh)) {
155
                        if (flags & DIO_ALL)
156
                                continue;
157
                        else
158
                                break;
159
                }
160
 
161
                if (!buffer_uptodate(bh))
162
                        gfs2_io_error_bh(sdp, bh);
163
 
164
                list_move(&bd->bd_ail_st_list, &ai->ai_ail2_list);
165
        }
166
 
167
        return list_empty(&ai->ai_ail1_list);
168
}
169
 
170
static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags)
171
{
172
        struct list_head *head;
173
        u64 sync_gen;
174
        struct list_head *first;
175
        struct gfs2_ail *first_ai, *ai, *tmp;
176
        int done = 0;
177
 
178
        gfs2_log_lock(sdp);
179
        head = &sdp->sd_ail1_list;
180
        if (list_empty(head)) {
181
                gfs2_log_unlock(sdp);
182
                return;
183
        }
184
        sync_gen = sdp->sd_ail_sync_gen++;
185
 
186
        first = head->prev;
187
        first_ai = list_entry(first, struct gfs2_ail, ai_list);
188
        first_ai->ai_sync_gen = sync_gen;
189
        gfs2_ail1_start_one(sdp, first_ai); /* This may drop log lock */
190
 
191
        if (flags & DIO_ALL)
192
                first = NULL;
193
 
194
        while(!done) {
195
                if (first && (head->prev != first ||
196
                              gfs2_ail1_empty_one(sdp, first_ai, 0)))
197
                        break;
198
 
199
                done = 1;
200
                list_for_each_entry_safe_reverse(ai, tmp, head, ai_list) {
201
                        if (ai->ai_sync_gen >= sync_gen)
202
                                continue;
203
                        ai->ai_sync_gen = sync_gen;
204
                        gfs2_ail1_start_one(sdp, ai); /* This may drop log lock */
205
                        done = 0;
206
                        break;
207
                }
208
        }
209
 
210
        gfs2_log_unlock(sdp);
211
}
212
 
213
int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags)
214
{
215
        struct gfs2_ail *ai, *s;
216
        int ret;
217
 
218
        gfs2_log_lock(sdp);
219
 
220
        list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) {
221
                if (gfs2_ail1_empty_one(sdp, ai, flags))
222
                        list_move(&ai->ai_list, &sdp->sd_ail2_list);
223
                else if (!(flags & DIO_ALL))
224
                        break;
225
        }
226
 
227
        ret = list_empty(&sdp->sd_ail1_list);
228
 
229
        gfs2_log_unlock(sdp);
230
 
231
        return ret;
232
}
233
 
234
 
235
/**
236
 * gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced
237
 * @sdp: the filesystem
238
 * @ai: the AIL entry
239
 *
240
 */
241
 
242
static void gfs2_ail2_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
243
{
244
        struct list_head *head = &ai->ai_ail2_list;
245
        struct gfs2_bufdata *bd;
246
 
247
        while (!list_empty(head)) {
248
                bd = list_entry(head->prev, struct gfs2_bufdata,
249
                                bd_ail_st_list);
250
                gfs2_assert(sdp, bd->bd_ail == ai);
251
                gfs2_remove_from_ail(bd->bd_bh->b_page->mapping, bd);
252
        }
253
}
254
 
255
static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
256
{
257
        struct gfs2_ail *ai, *safe;
258
        unsigned int old_tail = sdp->sd_log_tail;
259
        int wrap = (new_tail < old_tail);
260
        int a, b, rm;
261
 
262
        gfs2_log_lock(sdp);
263
 
264
        list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) {
265
                a = (old_tail <= ai->ai_first);
266
                b = (ai->ai_first < new_tail);
267
                rm = (wrap) ? (a || b) : (a && b);
268
                if (!rm)
269
                        continue;
270
 
271
                gfs2_ail2_empty_one(sdp, ai);
272
                list_del(&ai->ai_list);
273
                gfs2_assert_warn(sdp, list_empty(&ai->ai_ail1_list));
274
                gfs2_assert_warn(sdp, list_empty(&ai->ai_ail2_list));
275
                kfree(ai);
276
        }
277
 
278
        gfs2_log_unlock(sdp);
279
}
280
 
281
/**
282
 * gfs2_log_reserve - Make a log reservation
283
 * @sdp: The GFS2 superblock
284
 * @blks: The number of blocks to reserve
285
 *
286
 * Note that we never give out the last few blocks of the journal. Thats
287
 * due to the fact that there is a small number of header blocks
288
 * associated with each log flush. The exact number can't be known until
289
 * flush time, so we ensure that we have just enough free blocks at all
290
 * times to avoid running out during a log flush.
291
 *
292
 * Returns: errno
293
 */
294
 
295
int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
296
{
297
        unsigned int try = 0;
298
        unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize);
299
 
300
        if (gfs2_assert_warn(sdp, blks) ||
301
            gfs2_assert_warn(sdp, blks <= sdp->sd_jdesc->jd_blocks))
302
                return -EINVAL;
303
 
304
        mutex_lock(&sdp->sd_log_reserve_mutex);
305
        gfs2_log_lock(sdp);
306
        while(sdp->sd_log_blks_free <= (blks + reserved_blks)) {
307
                gfs2_log_unlock(sdp);
308
                gfs2_ail1_empty(sdp, 0);
309
                gfs2_log_flush(sdp, NULL);
310
 
311
                if (try++)
312
                        gfs2_ail1_start(sdp, 0);
313
                gfs2_log_lock(sdp);
314
        }
315
        sdp->sd_log_blks_free -= blks;
316
        gfs2_log_unlock(sdp);
317
        mutex_unlock(&sdp->sd_log_reserve_mutex);
318
 
319
        down_read(&sdp->sd_log_flush_lock);
320
 
321
        return 0;
322
}
323
 
324
/**
325
 * gfs2_log_release - Release a given number of log blocks
326
 * @sdp: The GFS2 superblock
327
 * @blks: The number of blocks
328
 *
329
 */
330
 
331
void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
332
{
333
 
334
        gfs2_log_lock(sdp);
335
        sdp->sd_log_blks_free += blks;
336
        gfs2_assert_withdraw(sdp,
337
                             sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
338
        gfs2_log_unlock(sdp);
339
        up_read(&sdp->sd_log_flush_lock);
340
}
341
 
342
static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn)
343
{
344
        struct inode *inode = sdp->sd_jdesc->jd_inode;
345
        int error;
346
        struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
347
 
348
        bh_map.b_size = 1 << inode->i_blkbits;
349
        error = gfs2_block_map(inode, lbn, 0, &bh_map);
350
        if (error || !bh_map.b_blocknr)
351
                printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error,
352
                       (unsigned long long)bh_map.b_blocknr, lbn);
353
        gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr);
354
 
355
        return bh_map.b_blocknr;
356
}
357
 
358
/**
359
 * log_distance - Compute distance between two journal blocks
360
 * @sdp: The GFS2 superblock
361
 * @newer: The most recent journal block of the pair
362
 * @older: The older journal block of the pair
363
 *
364
 *   Compute the distance (in the journal direction) between two
365
 *   blocks in the journal
366
 *
367
 * Returns: the distance in blocks
368
 */
369
 
370
static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer,
371
                                        unsigned int older)
372
{
373
        int dist;
374
 
375
        dist = newer - older;
376
        if (dist < 0)
377
                dist += sdp->sd_jdesc->jd_blocks;
378
 
379
        return dist;
380
}
381
 
382
/**
383
 * calc_reserved - Calculate the number of blocks to reserve when
384
 *                 refunding a transaction's unused buffers.
385
 * @sdp: The GFS2 superblock
386
 *
387
 * This is complex.  We need to reserve room for all our currently used
388
 * metadata buffers (e.g. normal file I/O rewriting file time stamps) and
389
 * all our journaled data buffers for journaled files (e.g. files in the
390
 * meta_fs like rindex, or files for which chattr +j was done.)
391
 * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
392
 * will count it as free space (sd_log_blks_free) and corruption will follow.
393
 *
394
 * We can have metadata bufs and jdata bufs in the same journal.  So each
395
 * type gets its own log header, for which we need to reserve a block.
396
 * In fact, each type has the potential for needing more than one header
397
 * in cases where we have more buffers than will fit on a journal page.
398
 * Metadata journal entries take up half the space of journaled buffer entries.
399
 * Thus, metadata entries have buf_limit (502) and journaled buffers have
400
 * databuf_limit (251) before they cause a wrap around.
401
 *
402
 * Also, we need to reserve blocks for revoke journal entries and one for an
403
 * overall header for the lot.
404
 *
405
 * Returns: the number of blocks reserved
406
 */
407
static unsigned int calc_reserved(struct gfs2_sbd *sdp)
408
{
409
        unsigned int reserved = 0;
410
        unsigned int mbuf_limit, metabufhdrs_needed;
411
        unsigned int dbuf_limit, databufhdrs_needed;
412
        unsigned int revokes = 0;
413
 
414
        mbuf_limit = buf_limit(sdp);
415
        metabufhdrs_needed = (sdp->sd_log_commited_buf +
416
                              (mbuf_limit - 1)) / mbuf_limit;
417
        dbuf_limit = databuf_limit(sdp);
418
        databufhdrs_needed = (sdp->sd_log_commited_databuf +
419
                              (dbuf_limit - 1)) / dbuf_limit;
420
 
421
        if (sdp->sd_log_commited_revoke)
422
                revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
423
                                          sizeof(u64));
424
 
425
        reserved = sdp->sd_log_commited_buf + metabufhdrs_needed +
426
                sdp->sd_log_commited_databuf + databufhdrs_needed +
427
                revokes;
428
        /* One for the overall header */
429
        if (reserved)
430
                reserved++;
431
        return reserved;
432
}
433
 
434
static unsigned int current_tail(struct gfs2_sbd *sdp)
435
{
436
        struct gfs2_ail *ai;
437
        unsigned int tail;
438
 
439
        gfs2_log_lock(sdp);
440
 
441
        if (list_empty(&sdp->sd_ail1_list)) {
442
                tail = sdp->sd_log_head;
443
        } else {
444
                ai = list_entry(sdp->sd_ail1_list.prev, struct gfs2_ail, ai_list);
445
                tail = ai->ai_first;
446
        }
447
 
448
        gfs2_log_unlock(sdp);
449
 
450
        return tail;
451
}
452
 
453
void gfs2_log_incr_head(struct gfs2_sbd *sdp)
454
{
455
        if (sdp->sd_log_flush_head == sdp->sd_log_tail)
456
                BUG_ON(sdp->sd_log_flush_head != sdp->sd_log_head);
457
 
458
        if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks) {
459
                sdp->sd_log_flush_head = 0;
460
                sdp->sd_log_flush_wrapped = 1;
461
        }
462
}
463
 
464
/**
465
 * gfs2_log_write_endio - End of I/O for a log buffer
466
 * @bh: The buffer head
467
 * @uptodate: I/O Status
468
 *
469
 */
470
 
471
static void gfs2_log_write_endio(struct buffer_head *bh, int uptodate)
472
{
473
        struct gfs2_sbd *sdp = bh->b_private;
474
        bh->b_private = NULL;
475
 
476
        end_buffer_write_sync(bh, uptodate);
477
        if (atomic_dec_and_test(&sdp->sd_log_in_flight))
478
                wake_up(&sdp->sd_log_flush_wait);
479
}
480
 
481
/**
482
 * gfs2_log_get_buf - Get and initialize a buffer to use for log control data
483
 * @sdp: The GFS2 superblock
484
 *
485
 * Returns: the buffer_head
486
 */
487
 
488
struct buffer_head *gfs2_log_get_buf(struct gfs2_sbd *sdp)
489
{
490
        u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
491
        struct buffer_head *bh;
492
 
493
        bh = sb_getblk(sdp->sd_vfs, blkno);
494
        lock_buffer(bh);
495
        memset(bh->b_data, 0, bh->b_size);
496
        set_buffer_uptodate(bh);
497
        clear_buffer_dirty(bh);
498
        gfs2_log_incr_head(sdp);
499
        atomic_inc(&sdp->sd_log_in_flight);
500
        bh->b_private = sdp;
501
        bh->b_end_io = gfs2_log_write_endio;
502
 
503
        return bh;
504
}
505
 
506
/**
507
 * gfs2_fake_write_endio -
508
 * @bh: The buffer head
509
 * @uptodate: The I/O Status
510
 *
511
 */
512
 
513
static void gfs2_fake_write_endio(struct buffer_head *bh, int uptodate)
514
{
515
        struct buffer_head *real_bh = bh->b_private;
516
        struct gfs2_bufdata *bd = real_bh->b_private;
517
        struct gfs2_sbd *sdp = bd->bd_gl->gl_sbd;
518
 
519
        end_buffer_write_sync(bh, uptodate);
520
        free_buffer_head(bh);
521
        unlock_buffer(real_bh);
522
        brelse(real_bh);
523
        if (atomic_dec_and_test(&sdp->sd_log_in_flight))
524
                wake_up(&sdp->sd_log_flush_wait);
525
}
526
 
527
/**
528
 * gfs2_log_fake_buf - Build a fake buffer head to write metadata buffer to log
529
 * @sdp: the filesystem
530
 * @data: the data the buffer_head should point to
531
 *
532
 * Returns: the log buffer descriptor
533
 */
534
 
535
struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
536
                                      struct buffer_head *real)
537
{
538
        u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
539
        struct buffer_head *bh;
540
 
541
        bh = alloc_buffer_head(GFP_NOFS | __GFP_NOFAIL);
542
        atomic_set(&bh->b_count, 1);
543
        bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock);
544
        set_bh_page(bh, real->b_page, bh_offset(real));
545
        bh->b_blocknr = blkno;
546
        bh->b_size = sdp->sd_sb.sb_bsize;
547
        bh->b_bdev = sdp->sd_vfs->s_bdev;
548
        bh->b_private = real;
549
        bh->b_end_io = gfs2_fake_write_endio;
550
 
551
        gfs2_log_incr_head(sdp);
552
        atomic_inc(&sdp->sd_log_in_flight);
553
 
554
        return bh;
555
}
556
 
557
static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
558
{
559
        unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
560
 
561
        ail2_empty(sdp, new_tail);
562
 
563
        gfs2_log_lock(sdp);
564
        sdp->sd_log_blks_free += dist;
565
        gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
566
        gfs2_log_unlock(sdp);
567
 
568
        sdp->sd_log_tail = new_tail;
569
}
570
 
571
/**
572
 * log_write_header - Get and initialize a journal header buffer
573
 * @sdp: The GFS2 superblock
574
 *
575
 * Returns: the initialized log buffer descriptor
576
 */
577
 
578
static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
579
{
580
        u64 blkno = log_bmap(sdp, sdp->sd_log_flush_head);
581
        struct buffer_head *bh;
582
        struct gfs2_log_header *lh;
583
        unsigned int tail;
584
        u32 hash;
585
 
586
        bh = sb_getblk(sdp->sd_vfs, blkno);
587
        lock_buffer(bh);
588
        memset(bh->b_data, 0, bh->b_size);
589
        set_buffer_uptodate(bh);
590
        clear_buffer_dirty(bh);
591
        unlock_buffer(bh);
592
 
593
        gfs2_ail1_empty(sdp, 0);
594
        tail = current_tail(sdp);
595
 
596
        lh = (struct gfs2_log_header *)bh->b_data;
597
        memset(lh, 0, sizeof(struct gfs2_log_header));
598
        lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
599
        lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
600
        lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
601
        lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++);
602
        lh->lh_flags = cpu_to_be32(flags);
603
        lh->lh_tail = cpu_to_be32(tail);
604
        lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head);
605
        hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
606
        lh->lh_hash = cpu_to_be32(hash);
607
 
608
        set_buffer_dirty(bh);
609
        if (sync_dirty_buffer(bh))
610
                gfs2_io_error_bh(sdp, bh);
611
        brelse(bh);
612
 
613
        if (sdp->sd_log_tail != tail)
614
                log_pull_tail(sdp, tail);
615
        else
616
                gfs2_assert_withdraw(sdp, !pull);
617
 
618
        sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
619
        gfs2_log_incr_head(sdp);
620
}
621
 
622
static void log_flush_commit(struct gfs2_sbd *sdp)
623
{
624
        DEFINE_WAIT(wait);
625
 
626
        if (atomic_read(&sdp->sd_log_in_flight)) {
627
                do {
628
                        prepare_to_wait(&sdp->sd_log_flush_wait, &wait,
629
                                        TASK_UNINTERRUPTIBLE);
630
                        if (atomic_read(&sdp->sd_log_in_flight))
631
                                io_schedule();
632
                } while(atomic_read(&sdp->sd_log_in_flight));
633
                finish_wait(&sdp->sd_log_flush_wait, &wait);
634
        }
635
 
636
        log_write_header(sdp, 0, 0);
637
}
638
 
639
static void gfs2_ordered_write(struct gfs2_sbd *sdp)
640
{
641
        struct gfs2_bufdata *bd;
642
        struct buffer_head *bh;
643
        LIST_HEAD(written);
644
 
645
        gfs2_log_lock(sdp);
646
        while (!list_empty(&sdp->sd_log_le_ordered)) {
647
                bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_le.le_list);
648
                list_move(&bd->bd_le.le_list, &written);
649
                bh = bd->bd_bh;
650
                if (!buffer_dirty(bh))
651
                        continue;
652
                get_bh(bh);
653
                gfs2_log_unlock(sdp);
654
                lock_buffer(bh);
655
                if (test_clear_buffer_dirty(bh)) {
656
                        bh->b_end_io = end_buffer_write_sync;
657
                        submit_bh(WRITE, bh);
658
                } else {
659
                        unlock_buffer(bh);
660
                        brelse(bh);
661
                }
662
                gfs2_log_lock(sdp);
663
        }
664
        list_splice(&written, &sdp->sd_log_le_ordered);
665
        gfs2_log_unlock(sdp);
666
}
667
 
668
static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
669
{
670
        struct gfs2_bufdata *bd;
671
        struct buffer_head *bh;
672
 
673
        gfs2_log_lock(sdp);
674
        while (!list_empty(&sdp->sd_log_le_ordered)) {
675
                bd = list_entry(sdp->sd_log_le_ordered.prev, struct gfs2_bufdata, bd_le.le_list);
676
                bh = bd->bd_bh;
677
                if (buffer_locked(bh)) {
678
                        get_bh(bh);
679
                        gfs2_log_unlock(sdp);
680
                        wait_on_buffer(bh);
681
                        brelse(bh);
682
                        gfs2_log_lock(sdp);
683
                        continue;
684
                }
685
                list_del_init(&bd->bd_le.le_list);
686
        }
687
        gfs2_log_unlock(sdp);
688
}
689
 
690
/**
691
 * gfs2_log_flush - flush incore transaction(s)
692
 * @sdp: the filesystem
693
 * @gl: The glock structure to flush.  If NULL, flush the whole incore log
694
 *
695
 */
696
 
697
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
698
{
699
        struct gfs2_ail *ai;
700
 
701
        down_write(&sdp->sd_log_flush_lock);
702
 
703
        if (gl) {
704
                gfs2_log_lock(sdp);
705
                if (list_empty(&gl->gl_le.le_list)) {
706
                        gfs2_log_unlock(sdp);
707
                        up_write(&sdp->sd_log_flush_lock);
708
                        return;
709
                }
710
                gfs2_log_unlock(sdp);
711
        }
712
 
713
        ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL);
714
        INIT_LIST_HEAD(&ai->ai_ail1_list);
715
        INIT_LIST_HEAD(&ai->ai_ail2_list);
716
 
717
        if (sdp->sd_log_num_buf != sdp->sd_log_commited_buf) {
718
                printk(KERN_INFO "GFS2: log buf %u %u\n", sdp->sd_log_num_buf,
719
                       sdp->sd_log_commited_buf);
720
                gfs2_assert_withdraw(sdp, 0);
721
        }
722
        if (sdp->sd_log_num_databuf != sdp->sd_log_commited_databuf) {
723
                printk(KERN_INFO "GFS2: log databuf %u %u\n",
724
                       sdp->sd_log_num_databuf, sdp->sd_log_commited_databuf);
725
                gfs2_assert_withdraw(sdp, 0);
726
        }
727
        gfs2_assert_withdraw(sdp,
728
                        sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
729
 
730
        sdp->sd_log_flush_head = sdp->sd_log_head;
731
        sdp->sd_log_flush_wrapped = 0;
732
        ai->ai_first = sdp->sd_log_flush_head;
733
 
734
        gfs2_ordered_write(sdp);
735
        lops_before_commit(sdp);
736
        gfs2_ordered_wait(sdp);
737
 
738
        if (sdp->sd_log_head != sdp->sd_log_flush_head)
739
                log_flush_commit(sdp);
740
        else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
741
                gfs2_log_lock(sdp);
742
                sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */
743
                gfs2_log_unlock(sdp);
744
                log_write_header(sdp, 0, PULL);
745
        }
746
        lops_after_commit(sdp, ai);
747
 
748
        gfs2_log_lock(sdp);
749
        sdp->sd_log_head = sdp->sd_log_flush_head;
750
        sdp->sd_log_blks_reserved = 0;
751
        sdp->sd_log_commited_buf = 0;
752
        sdp->sd_log_commited_databuf = 0;
753
        sdp->sd_log_commited_revoke = 0;
754
 
755
        if (!list_empty(&ai->ai_ail1_list)) {
756
                list_add(&ai->ai_list, &sdp->sd_ail1_list);
757
                ai = NULL;
758
        }
759
        gfs2_log_unlock(sdp);
760
 
761
        sdp->sd_vfs->s_dirt = 0;
762
        up_write(&sdp->sd_log_flush_lock);
763
 
764
        kfree(ai);
765
}
766
 
767
static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
768
{
769
        unsigned int reserved;
770
        unsigned int old;
771
 
772
        gfs2_log_lock(sdp);
773
 
774
        sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm;
775
        sdp->sd_log_commited_databuf += tr->tr_num_databuf_new -
776
                tr->tr_num_databuf_rm;
777
        gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
778
                             (((int)sdp->sd_log_commited_databuf) >= 0));
779
        sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
780
        gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
781
        reserved = calc_reserved(sdp);
782
        old = sdp->sd_log_blks_free;
783
        sdp->sd_log_blks_free += tr->tr_reserved -
784
                                 (reserved - sdp->sd_log_blks_reserved);
785
 
786
        gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
787
        gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <=
788
                             sdp->sd_jdesc->jd_blocks);
789
 
790
        sdp->sd_log_blks_reserved = reserved;
791
 
792
        gfs2_log_unlock(sdp);
793
}
794
 
795
/**
796
 * gfs2_log_commit - Commit a transaction to the log
797
 * @sdp: the filesystem
798
 * @tr: the transaction
799
 *
800
 * Returns: errno
801
 */
802
 
803
void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
804
{
805
        log_refund(sdp, tr);
806
        lops_incore_commit(sdp, tr);
807
 
808
        sdp->sd_vfs->s_dirt = 1;
809
        up_read(&sdp->sd_log_flush_lock);
810
 
811
        gfs2_log_lock(sdp);
812
        if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks))
813
                wake_up_process(sdp->sd_logd_process);
814
        gfs2_log_unlock(sdp);
815
}
816
 
817
/**
818
 * gfs2_log_shutdown - write a shutdown header into a journal
819
 * @sdp: the filesystem
820
 *
821
 */
822
 
823
void gfs2_log_shutdown(struct gfs2_sbd *sdp)
824
{
825
        down_write(&sdp->sd_log_flush_lock);
826
 
827
        gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved);
828
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_gl);
829
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf);
830
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
831
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg);
832
        gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf);
833
        gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
834
 
835
        sdp->sd_log_flush_head = sdp->sd_log_head;
836
        sdp->sd_log_flush_wrapped = 0;
837
 
838
        log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT,
839
                         (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL);
840
 
841
        gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks);
842
        gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);
843
        gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list));
844
 
845
        sdp->sd_log_head = sdp->sd_log_flush_head;
846
        sdp->sd_log_tail = sdp->sd_log_head;
847
 
848
        up_write(&sdp->sd_log_flush_lock);
849
}
850
 
851
 
852
/**
853
 * gfs2_meta_syncfs - sync all the buffers in a filesystem
854
 * @sdp: the filesystem
855
 *
856
 */
857
 
858
void gfs2_meta_syncfs(struct gfs2_sbd *sdp)
859
{
860
        gfs2_log_flush(sdp, NULL);
861
        for (;;) {
862
                gfs2_ail1_start(sdp, DIO_ALL);
863
                if (gfs2_ail1_empty(sdp, DIO_ALL))
864
                        break;
865
                msleep(10);
866
        }
867
}
868
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.