lops.c 18.5 KB
Newer Older
D
David Teigland 已提交
1 2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
D
David Teigland 已提交
4 5 6
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
D
David Teigland 已提交
8 9 10 11 12 13 14
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
15
#include <linux/gfs2_ondisk.h>
D
David Teigland 已提交
16 17

#include "gfs2.h"
18
#include "incore.h"
19
#include "inode.h"
D
David Teigland 已提交
20 21 22 23 24 25 26
#include "glock.h"
#include "log.h"
#include "lops.h"
#include "meta_io.h"
#include "recovery.h"
#include "rgrp.h"
#include "trans.h"
27
#include "util.h"
D
David Teigland 已提交
28

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/**
 * gfs2_pin - Pin a buffer in memory
 * @sdp: The superblock
 * @bh: The buffer to be pinned
 *
 * The log lock must be held when calling this function
 */
static void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh)
{
	struct gfs2_bufdata *bd;

	gfs2_assert_withdraw(sdp, test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags));

	clear_buffer_dirty(bh);
	if (test_set_buffer_pinned(bh))
		gfs2_assert_withdraw(sdp, 0);
	if (!buffer_uptodate(bh))
		gfs2_io_error_bh(sdp, bh);
	bd = bh->b_private;
	/* If this buffer is in the AIL and it has already been written
	 * to in-place disk block, remove it from the AIL.
	 */
	if (bd->bd_ail)
		list_move(&bd->bd_ail_st_list, &bd->bd_ail->ai_ail2_list);
	get_bh(bh);
}

/**
 * gfs2_unpin - Unpin a buffer
 * @sdp: the filesystem the buffer belongs to
 * @bh: The buffer to unpin
 * @ai:
 *
 */

static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh,
		       struct gfs2_ail *ai)
{
	struct gfs2_bufdata *bd = bh->b_private;

	gfs2_assert_withdraw(sdp, buffer_uptodate(bh));

	if (!buffer_pinned(bh))
		gfs2_assert_withdraw(sdp, 0);

	lock_buffer(bh);
	mark_buffer_dirty(bh);
	clear_buffer_pinned(bh);

	gfs2_log_lock(sdp);
	if (bd->bd_ail) {
		list_del(&bd->bd_ail_st_list);
		brelse(bh);
	} else {
		struct gfs2_glock *gl = bd->bd_gl;
		list_add(&bd->bd_ail_gl_list, &gl->gl_ail_list);
		atomic_inc(&gl->gl_ail_count);
	}
	bd->bd_ail = ai;
	list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list);
89
	clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
90 91 92 93
	gfs2_log_unlock(sdp);
	unlock_buffer(bh);
}

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126

static inline struct gfs2_log_descriptor *bh_log_desc(struct buffer_head *bh)
{
	return (struct gfs2_log_descriptor *)bh->b_data;
}

static inline __be64 *bh_log_ptr(struct buffer_head *bh)
{
	struct gfs2_log_descriptor *ld = bh_log_desc(bh);
	return (__force __be64 *)(ld + 1);
}

static inline __be64 *bh_ptr_end(struct buffer_head *bh)
{
	return (__force __be64 *)(bh->b_data + bh->b_size);
}


static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
{
	struct buffer_head *bh = gfs2_log_get_buf(sdp);
	struct gfs2_log_descriptor *ld = bh_log_desc(bh);
	ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
	ld->ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD);
	ld->ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD);
	ld->ld_type = cpu_to_be32(ld_type);
	ld->ld_length = 0;
	ld->ld_data1 = 0;
	ld->ld_data2 = 0;
	memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved));
	return bh;
}

D
David Teigland 已提交
127 128 129 130 131
static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
	struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
	struct gfs2_trans *tr;

132
	lock_buffer(bd->bd_bh);
133
	gfs2_log_lock(sdp);
134 135
	if (!list_empty(&bd->bd_list_tr))
		goto out;
136
	tr = current->journal_info;
D
David Teigland 已提交
137 138 139 140
	tr->tr_touched = 1;
	tr->tr_num_buf++;
	list_add(&bd->bd_list_tr, &tr->tr_list_buf);
	if (!list_empty(&le->le_list))
141
		goto out;
142 143
	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
D
David Teigland 已提交
144
	gfs2_meta_check(sdp, bd->bd_bh);
145
	gfs2_pin(sdp, bd->bd_bh);
D
David Teigland 已提交
146 147 148
	sdp->sd_log_num_buf++;
	list_add(&le->le_list, &sdp->sd_log_le_buf);
	tr->tr_num_buf_new++;
149 150 151
out:
	gfs2_log_unlock(sdp);
	unlock_buffer(bd->bd_bh);
D
David Teigland 已提交
152 153 154 155 156 157 158
}

static void buf_lo_before_commit(struct gfs2_sbd *sdp)
{
	struct buffer_head *bh;
	struct gfs2_log_descriptor *ld;
	struct gfs2_bufdata *bd1 = NULL, *bd2;
159
	unsigned int total;
D
David Teigland 已提交
160 161 162 163 164
	unsigned int limit;
	unsigned int num;
	unsigned n;
	__be64 *ptr;

165
	limit = buf_limit(sdp);
D
David Teigland 已提交
166 167
	/* for 4k blocks, limit = 503 */

168 169
	gfs2_log_lock(sdp);
	total = sdp->sd_log_num_buf;
D
David Teigland 已提交
170 171 172 173 174
	bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list);
	while(total) {
		num = total;
		if (total > limit)
			num = limit;
175
		gfs2_log_unlock(sdp);
176
		bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_METADATA);
177
		gfs2_log_lock(sdp);
178 179
		ld = bh_log_desc(bh);
		ptr = bh_log_ptr(bh);
D
David Teigland 已提交
180 181 182 183
		ld->ld_length = cpu_to_be32(num + 1);
		ld->ld_data1 = cpu_to_be32(num);

		n = 0;
184 185
		list_for_each_entry_continue(bd1, &sdp->sd_log_le_buf,
					     bd_le.le_list) {
D
David Teigland 已提交
186 187 188 189 190
			*ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr);
			if (++n >= num)
				break;
		}

191
		gfs2_log_unlock(sdp);
192
		submit_bh(WRITE, bh);
193
		gfs2_log_lock(sdp);
D
David Teigland 已提交
194 195

		n = 0;
196 197
		list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf,
					     bd_le.le_list) {
198
			get_bh(bd2->bd_bh);
199
			gfs2_log_unlock(sdp);
200
			lock_buffer(bd2->bd_bh);
D
David Teigland 已提交
201
			bh = gfs2_log_fake_buf(sdp, bd2->bd_bh);
202
			submit_bh(WRITE, bh);
203
			gfs2_log_lock(sdp);
D
David Teigland 已提交
204 205 206 207
			if (++n >= num)
				break;
		}

208
		BUG_ON(total < num);
D
David Teigland 已提交
209 210
		total -= num;
	}
211
	gfs2_log_unlock(sdp);
D
David Teigland 已提交
212 213 214 215 216 217 218 219 220 221 222 223
}

static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
{
	struct list_head *head = &sdp->sd_log_le_buf;
	struct gfs2_bufdata *bd;

	while (!list_empty(head)) {
		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
		list_del_init(&bd->bd_le.le_list);
		sdp->sd_log_num_buf--;

224
		gfs2_unpin(sdp, bd->bd_bh, ai);
D
David Teigland 已提交
225 226 227 228 229
	}
	gfs2_assert_warn(sdp, !sdp->sd_log_num_buf);
}

static void buf_lo_before_scan(struct gfs2_jdesc *jd,
A
Al Viro 已提交
230
			       struct gfs2_log_header_host *head, int pass)
D
David Teigland 已提交
231
{
232
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
233 234 235 236 237 238 239 240 241 242 243 244

	if (pass != 0)
		return;

	sdp->sd_found_blocks = 0;
	sdp->sd_replayed_blocks = 0;
}

static int buf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
				struct gfs2_log_descriptor *ld, __be64 *ptr,
				int pass)
{
245 246
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
247
	struct gfs2_glock *gl = ip->i_gl;
D
David Teigland 已提交
248 249
	unsigned int blks = be32_to_cpu(ld->ld_data1);
	struct buffer_head *bh_log, *bh_ip;
250
	u64 blkno;
D
David Teigland 已提交
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
	int error = 0;

	if (pass != 1 || be32_to_cpu(ld->ld_type) != GFS2_LOG_DESC_METADATA)
		return 0;

	gfs2_replay_incr_blk(sdp, &start);

	for (; blks; gfs2_replay_incr_blk(sdp, &start), blks--) {
		blkno = be64_to_cpu(*ptr++);

		sdp->sd_found_blocks++;

		if (gfs2_revoke_check(sdp, blkno, start))
			continue;

		error = gfs2_replay_read_block(jd, start, &bh_log);
S
Steven Whitehouse 已提交
267 268
		if (error)
			return error;
D
David Teigland 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291

		bh_ip = gfs2_meta_new(gl, blkno);
		memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size);

		if (gfs2_meta_check(sdp, bh_ip))
			error = -EIO;
		else
			mark_buffer_dirty(bh_ip);

		brelse(bh_log);
		brelse(bh_ip);

		if (error)
			break;

		sdp->sd_replayed_blocks++;
	}

	return error;
}

static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
292 293
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
294 295

	if (error) {
S
Steven Whitehouse 已提交
296
		gfs2_meta_sync(ip->i_gl);
D
David Teigland 已提交
297 298 299 300 301
		return;
	}
	if (pass != 1)
		return;

S
Steven Whitehouse 已提交
302
	gfs2_meta_sync(ip->i_gl);
D
David Teigland 已提交
303 304 305 306 307 308 309 310 311

	fs_info(sdp, "jid=%u: Replayed %u of %u blocks\n",
	        jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks);
}

static void revoke_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
	struct gfs2_trans *tr;

312
	tr = current->journal_info;
D
David Teigland 已提交
313 314 315 316 317 318 319 320 321 322 323 324 325
	tr->tr_touched = 1;
	tr->tr_num_revoke++;
	sdp->sd_log_num_revoke++;
	list_add(&le->le_list, &sdp->sd_log_le_revoke);
}

static void revoke_lo_before_commit(struct gfs2_sbd *sdp)
{
	struct gfs2_log_descriptor *ld;
	struct gfs2_meta_header *mh;
	struct buffer_head *bh;
	unsigned int offset;
	struct list_head *head = &sdp->sd_log_le_revoke;
326
	struct gfs2_bufdata *bd;
D
David Teigland 已提交
327 328 329 330

	if (!sdp->sd_log_num_revoke)
		return;

331 332
	bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE);
	ld = bh_log_desc(bh);
333
	ld->ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp->sd_log_num_revoke,
334
						    sizeof(u64)));
D
David Teigland 已提交
335 336 337 338
	ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);
	offset = sizeof(struct gfs2_log_descriptor);

	while (!list_empty(head)) {
339 340
		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
		list_del_init(&bd->bd_le.le_list);
D
David Teigland 已提交
341 342
		sdp->sd_log_num_revoke--;

343
		if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
344
			submit_bh(WRITE, bh);
D
David Teigland 已提交
345 346 347 348

			bh = gfs2_log_get_buf(sdp);
			mh = (struct gfs2_meta_header *)bh->b_data;
			mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
349 350
			mh->mh_type = cpu_to_be32(GFS2_METATYPE_LB);
			mh->mh_format = cpu_to_be32(GFS2_FORMAT_LB);
D
David Teigland 已提交
351 352 353
			offset = sizeof(struct gfs2_meta_header);
		}

354
		*(__be64 *)(bh->b_data + offset) = cpu_to_be64(bd->bd_blkno);
355
		kmem_cache_free(gfs2_bufdata_cachep, bd);
D
David Teigland 已提交
356

357
		offset += sizeof(u64);
D
David Teigland 已提交
358 359 360
	}
	gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);

361
	submit_bh(WRITE, bh);
D
David Teigland 已提交
362 363 364
}

static void revoke_lo_before_scan(struct gfs2_jdesc *jd,
A
Al Viro 已提交
365
				  struct gfs2_log_header_host *head, int pass)
D
David Teigland 已提交
366
{
367
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
368 369 370 371 372 373 374 375 376 377 378 379

	if (pass != 0)
		return;

	sdp->sd_found_revokes = 0;
	sdp->sd_replay_tail = head->lh_tail;
}

static int revoke_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
				   struct gfs2_log_descriptor *ld, __be64 *ptr,
				   int pass)
{
380
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
381 382 383 384
	unsigned int blks = be32_to_cpu(ld->ld_length);
	unsigned int revokes = be32_to_cpu(ld->ld_data1);
	struct buffer_head *bh;
	unsigned int offset;
385
	u64 blkno;
D
David Teigland 已提交
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
	int first = 1;
	int error;

	if (pass != 0 || be32_to_cpu(ld->ld_type) != GFS2_LOG_DESC_REVOKE)
		return 0;

	offset = sizeof(struct gfs2_log_descriptor);

	for (; blks; gfs2_replay_incr_blk(sdp, &start), blks--) {
		error = gfs2_replay_read_block(jd, start, &bh);
		if (error)
			return error;

		if (!first)
			gfs2_metatype_check(sdp, bh, GFS2_METATYPE_LB);

402
		while (offset + sizeof(u64) <= sdp->sd_sb.sb_bsize) {
D
David Teigland 已提交
403 404 405
			blkno = be64_to_cpu(*(__be64 *)(bh->b_data + offset));

			error = gfs2_revoke_add(sdp, blkno, start);
B
Bob Peterson 已提交
406 407
			if (error < 0) {
				brelse(bh);
D
David Teigland 已提交
408
				return error;
B
Bob Peterson 已提交
409
			}
D
David Teigland 已提交
410 411 412 413 414
			else if (error)
				sdp->sd_found_revokes++;

			if (!--revokes)
				break;
415
			offset += sizeof(u64);
D
David Teigland 已提交
416 417 418 419 420 421 422 423 424 425 426 427
		}

		brelse(bh);
		offset = sizeof(struct gfs2_meta_header);
		first = 0;
	}

	return 0;
}

static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
428
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445

	if (error) {
		gfs2_revoke_clean(sdp);
		return;
	}
	if (pass != 1)
		return;

	fs_info(sdp, "jid=%u: Found %u revoke tags\n",
	        jd->jd_jid, sdp->sd_found_revokes);

	gfs2_revoke_clean(sdp);
}

static void rg_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
	struct gfs2_rgrpd *rgd;
446
	struct gfs2_trans *tr = current->journal_info;
D
David Teigland 已提交
447

448
	tr->tr_touched = 1;
D
David Teigland 已提交
449 450 451 452

	rgd = container_of(le, struct gfs2_rgrpd, rd_le);

	gfs2_log_lock(sdp);
453 454 455 456 457
	if (!list_empty(&le->le_list)){
		gfs2_log_unlock(sdp);
		return;
	}
	gfs2_rgrp_bh_hold(rgd);
D
David Teigland 已提交
458 459
	sdp->sd_log_num_rg++;
	list_add(&le->le_list, &sdp->sd_log_le_rg);
460
	gfs2_log_unlock(sdp);
D
David Teigland 已提交
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
}

static void rg_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
{
	struct list_head *head = &sdp->sd_log_le_rg;
	struct gfs2_rgrpd *rgd;

	while (!list_empty(head)) {
		rgd = list_entry(head->next, struct gfs2_rgrpd, rd_le.le_list);
		list_del_init(&rgd->rd_le.le_list);
		sdp->sd_log_num_rg--;

		gfs2_rgrp_repolish_clones(rgd);
		gfs2_rgrp_bh_put(rgd);
	}
	gfs2_assert_warn(sdp, !sdp->sd_log_num_rg);
}

479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
/**
 * databuf_lo_add - Add a databuf to the transaction.
 *
 * This is used in two distinct cases:
 * i) In ordered write mode
 *    We put the data buffer on a list so that we can ensure that its
 *    synced to disk at the right time
 * ii) In journaled data mode
 *    We need to journal the data block in the same way as metadata in
 *    the functions above. The difference is that here we have a tag
 *    which is two __be64's being the block number (as per meta data)
 *    and a flag which says whether the data block needs escaping or
 *    not. This means we need a new log entry for each 251 or so data
 *    blocks, which isn't an enormous overhead but twice as much as
 *    for normal metadata blocks.
 */
D
David Teigland 已提交
495 496
static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
497
	struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
498
	struct gfs2_trans *tr = current->journal_info;
499
	struct address_space *mapping = bd->bd_bh->b_page->mapping;
500
	struct gfs2_inode *ip = GFS2_I(mapping->host);
D
David Teigland 已提交
501

502
	lock_buffer(bd->bd_bh);
503
	gfs2_log_lock(sdp);
504 505 506 507 508 509 510 511
	if (tr) {
		if (!list_empty(&bd->bd_list_tr))
			goto out;
		tr->tr_touched = 1;
		if (gfs2_is_jdata(ip)) {
			tr->tr_num_buf++;
			list_add(&bd->bd_list_tr, &tr->tr_list_buf);
		}
512
	}
513
	if (!list_empty(&le->le_list))
514
		goto out;
515

516 517
	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
518 519 520
	if (gfs2_is_jdata(ip)) {
		gfs2_pin(sdp, bd->bd_bh);
		tr->tr_num_databuf_new++;
521 522 523 524
		sdp->sd_log_num_databuf++;
		list_add(&le->le_list, &sdp->sd_log_le_databuf);
	} else {
		list_add(&le->le_list, &sdp->sd_log_le_ordered);
525 526
	}
out:
D
David Teigland 已提交
527
	gfs2_log_unlock(sdp);
528
	unlock_buffer(bd->bd_bh);
D
David Teigland 已提交
529 530
}

531
static void gfs2_check_magic(struct buffer_head *bh)
532 533 534 535
{
	void *kaddr;
	__be32 *ptr;

536 537
	clear_buffer_escaped(bh);
	kaddr = kmap_atomic(bh->b_page, KM_USER0);
538 539
	ptr = kaddr + bh_offset(bh);
	if (*ptr == cpu_to_be32(GFS2_MAGIC))
540
		set_buffer_escaped(bh);
541
	kunmap_atomic(kaddr, KM_USER0);
542 543
}

544 545 546
static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh,
			      struct list_head *list, struct list_head *done,
			      unsigned int n)
D
David Teigland 已提交
547
{
548
	struct buffer_head *bh1;
549
	struct gfs2_log_descriptor *ld;
550 551
	struct gfs2_bufdata *bd;
	__be64 *ptr;
552

553 554
	if (!bh)
		return;
D
David Teigland 已提交
555

556 557 558
	ld = bh_log_desc(bh);
	ld->ld_length = cpu_to_be32(n + 1);
	ld->ld_data1 = cpu_to_be32(n);
D
David Teigland 已提交
559

560 561 562 563
	ptr = bh_log_ptr(bh);
	
	get_bh(bh);
	submit_bh(WRITE, bh);
564
	gfs2_log_lock(sdp);
565 566 567 568 569 570 571
	while(!list_empty(list)) {
		bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list);
		list_move_tail(&bd->bd_le.le_list, done);
		get_bh(bd->bd_bh);
		while (be64_to_cpu(*ptr) != bd->bd_bh->b_blocknr) {
			gfs2_log_incr_head(sdp);
			ptr += 2;
572
		}
573
		gfs2_log_unlock(sdp);
574 575 576 577 578 579 580 581 582 583 584 585 586 587
		lock_buffer(bd->bd_bh);
		if (buffer_escaped(bd->bd_bh)) {
			void *kaddr;
			bh1 = gfs2_log_get_buf(sdp);
			kaddr = kmap_atomic(bd->bd_bh->b_page, KM_USER0);
			memcpy(bh1->b_data, kaddr + bh_offset(bd->bd_bh),
			       bh1->b_size);
			kunmap_atomic(kaddr, KM_USER0);
			*(__be32 *)bh1->b_data = 0;
			clear_buffer_escaped(bd->bd_bh);
			unlock_buffer(bd->bd_bh);
			brelse(bd->bd_bh);
		} else {
			bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh);
588
		}
589
		submit_bh(WRITE, bh1);
590
		gfs2_log_lock(sdp);
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
		ptr += 2;
	}
	gfs2_log_unlock(sdp);
	brelse(bh);
}

/**
 * databuf_lo_before_commit - Scan the data buffers, writing as we go
 *
 */

static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
{
	struct gfs2_bufdata *bd = NULL;
	struct buffer_head *bh = NULL;
	unsigned int n = 0;
	__be64 *ptr = NULL, *end = NULL;
	LIST_HEAD(processed);
	LIST_HEAD(in_progress);

	gfs2_log_lock(sdp);
	while (!list_empty(&sdp->sd_log_le_databuf)) {
		if (ptr == end) {
614
			gfs2_log_unlock(sdp);
615 616 617 618 619
			gfs2_write_blocks(sdp, bh, &in_progress, &processed, n);
			n = 0;
			bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_JDATA);
			ptr = bh_log_ptr(bh);
			end = bh_ptr_end(bh) - 1;
620
			gfs2_log_lock(sdp);
621
			continue;
622
		}
623 624 625 626 627 628
		bd = list_entry(sdp->sd_log_le_databuf.next, struct gfs2_bufdata, bd_le.le_list);
		list_move_tail(&bd->bd_le.le_list, &in_progress);
		gfs2_check_magic(bd->bd_bh);
		*ptr++ = cpu_to_be64(bd->bd_bh->b_blocknr);
		*ptr++ = cpu_to_be64(buffer_escaped(bh) ? 1 : 0);
		n++;
D
David Teigland 已提交
629
	}
630
	gfs2_log_unlock(sdp);
631 632 633 634
	gfs2_write_blocks(sdp, bh, &in_progress, &processed, n);
	gfs2_log_lock(sdp);
	list_splice(&processed, &sdp->sd_log_le_databuf);
	gfs2_log_unlock(sdp);
635 636 637 638 639 640
}

static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
				    struct gfs2_log_descriptor *ld,
				    __be64 *ptr, int pass)
{
641 642
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
643
	struct gfs2_glock *gl = ip->i_gl;
644 645
	unsigned int blks = be32_to_cpu(ld->ld_data1);
	struct buffer_head *bh_log, *bh_ip;
646 647
	u64 blkno;
	u64 esc;
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691
	int error = 0;

	if (pass != 1 || be32_to_cpu(ld->ld_type) != GFS2_LOG_DESC_JDATA)
		return 0;

	gfs2_replay_incr_blk(sdp, &start);
	for (; blks; gfs2_replay_incr_blk(sdp, &start), blks--) {
		blkno = be64_to_cpu(*ptr++);
		esc = be64_to_cpu(*ptr++);

		sdp->sd_found_blocks++;

		if (gfs2_revoke_check(sdp, blkno, start))
			continue;

		error = gfs2_replay_read_block(jd, start, &bh_log);
		if (error)
			return error;

		bh_ip = gfs2_meta_new(gl, blkno);
		memcpy(bh_ip->b_data, bh_log->b_data, bh_log->b_size);

		/* Unescape */
		if (esc) {
			__be32 *eptr = (__be32 *)bh_ip->b_data;
			*eptr = cpu_to_be32(GFS2_MAGIC);
		}
		mark_buffer_dirty(bh_ip);

		brelse(bh_log);
		brelse(bh_ip);
		if (error)
			break;

		sdp->sd_replayed_blocks++;
	}

	return error;
}

/* FIXME: sort out accounting for log blocks etc. */

static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass)
{
692 693
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
694 695

	if (error) {
S
Steven Whitehouse 已提交
696
		gfs2_meta_sync(ip->i_gl);
697 698 699 700 701 702
		return;
	}
	if (pass != 1)
		return;

	/* data sync? */
S
Steven Whitehouse 已提交
703
	gfs2_meta_sync(ip->i_gl);
704 705 706 707 708 709 710 711 712 713 714 715

	fs_info(sdp, "jid=%u: Replayed %u of %u data blocks\n",
		jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks);
}

static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
{
	struct list_head *head = &sdp->sd_log_le_databuf;
	struct gfs2_bufdata *bd;

	while (!list_empty(head)) {
		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
S
Steven Whitehouse 已提交
716
		list_del_init(&bd->bd_le.le_list);
717 718 719
		sdp->sd_log_num_databuf--;
		gfs2_unpin(sdp, bd->bd_bh, ai);
	}
D
David Teigland 已提交
720 721 722
	gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf);
}

723

724
const struct gfs2_log_operations gfs2_buf_lops = {
D
David Teigland 已提交
725 726 727 728 729 730
	.lo_add = buf_lo_add,
	.lo_before_commit = buf_lo_before_commit,
	.lo_after_commit = buf_lo_after_commit,
	.lo_before_scan = buf_lo_before_scan,
	.lo_scan_elements = buf_lo_scan_elements,
	.lo_after_scan = buf_lo_after_scan,
731
	.lo_name = "buf",
D
David Teigland 已提交
732 733
};

734
const struct gfs2_log_operations gfs2_revoke_lops = {
D
David Teigland 已提交
735 736 737 738 739
	.lo_add = revoke_lo_add,
	.lo_before_commit = revoke_lo_before_commit,
	.lo_before_scan = revoke_lo_before_scan,
	.lo_scan_elements = revoke_lo_scan_elements,
	.lo_after_scan = revoke_lo_after_scan,
740
	.lo_name = "revoke",
D
David Teigland 已提交
741 742
};

743
const struct gfs2_log_operations gfs2_rg_lops = {
D
David Teigland 已提交
744 745
	.lo_add = rg_lo_add,
	.lo_after_commit = rg_lo_after_commit,
746
	.lo_name = "rg",
D
David Teigland 已提交
747 748
};

749
const struct gfs2_log_operations gfs2_databuf_lops = {
D
David Teigland 已提交
750 751
	.lo_add = databuf_lo_add,
	.lo_before_commit = databuf_lo_before_commit,
752 753 754
	.lo_after_commit = databuf_lo_after_commit,
	.lo_scan_elements = databuf_lo_scan_elements,
	.lo_after_scan = databuf_lo_after_scan,
755
	.lo_name = "databuf",
D
David Teigland 已提交
756 757
};

758
const struct gfs2_log_operations *gfs2_log_ops[] = {
759
	&gfs2_databuf_lops,
D
David Teigland 已提交
760 761
	&gfs2_buf_lops,
	&gfs2_rg_lops,
762
	&gfs2_revoke_lops,
763
	NULL,
D
David Teigland 已提交
764 765
};