lops.c 18.7 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>
S
Steven Whitehouse 已提交
16 17
#include <linux/bio.h>
#include <linux/fs.h>
D
David Teigland 已提交
18 19

#include "gfs2.h"
20
#include "incore.h"
21
#include "inode.h"
D
David Teigland 已提交
22 23 24 25 26 27 28
#include "glock.h"
#include "log.h"
#include "lops.h"
#include "meta_io.h"
#include "recovery.h"
#include "rgrp.h"
#include "trans.h"
29
#include "util.h"
S
Steven Whitehouse 已提交
30
#include "trace_gfs2.h"
D
David Teigland 已提交
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
/**
 * 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);
S
Steven Whitehouse 已提交
57
	trace_gfs2_pin(bd, 1);
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 89 90 91 92
}

/**
 * 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);
93
	clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
S
Steven Whitehouse 已提交
94
	trace_gfs2_pin(bd, 0);
95 96 97 98
	gfs2_log_unlock(sdp);
	unlock_buffer(bh);
}

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 127 128 129 130 131

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 已提交
132 133 134 135 136
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;

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

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;
164
	unsigned int total;
D
David Teigland 已提交
165 166 167 168 169
	unsigned int limit;
	unsigned int num;
	unsigned n;
	__be64 *ptr;

170
	limit = buf_limit(sdp);
D
David Teigland 已提交
171 172
	/* for 4k blocks, limit = 503 */

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

		n = 0;
189 190
		list_for_each_entry_continue(bd1, &sdp->sd_log_le_buf,
					     bd_le.le_list) {
D
David Teigland 已提交
191 192 193 194 195
			*ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr);
			if (++n >= num)
				break;
		}

196
		gfs2_log_unlock(sdp);
S
Steven Whitehouse 已提交
197
		submit_bh(WRITE_SYNC_PLUG, bh);
198
		gfs2_log_lock(sdp);
D
David Teigland 已提交
199 200

		n = 0;
201 202
		list_for_each_entry_continue(bd2, &sdp->sd_log_le_buf,
					     bd_le.le_list) {
203
			get_bh(bd2->bd_bh);
204
			gfs2_log_unlock(sdp);
205
			lock_buffer(bd2->bd_bh);
D
David Teigland 已提交
206
			bh = gfs2_log_fake_buf(sdp, bd2->bd_bh);
S
Steven Whitehouse 已提交
207
			submit_bh(WRITE_SYNC_PLUG, bh);
208
			gfs2_log_lock(sdp);
D
David Teigland 已提交
209 210 211 212
			if (++n >= num)
				break;
		}

213
		BUG_ON(total < num);
D
David Teigland 已提交
214 215
		total -= num;
	}
216
	gfs2_log_unlock(sdp);
D
David Teigland 已提交
217 218 219 220 221 222 223 224 225 226 227 228
}

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--;

229
		gfs2_unpin(sdp, bd->bd_bh, ai);
D
David Teigland 已提交
230 231 232 233 234
	}
	gfs2_assert_warn(sdp, !sdp->sd_log_num_buf);
}

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

	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)
{
250 251
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
252
	struct gfs2_glock *gl = ip->i_gl;
D
David Teigland 已提交
253 254
	unsigned int blks = be32_to_cpu(ld->ld_data1);
	struct buffer_head *bh_log, *bh_ip;
255
	u64 blkno;
D
David Teigland 已提交
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
	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 已提交
272 273
		if (error)
			return error;
D
David Teigland 已提交
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296

		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)
{
297 298
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
299 300

	if (error) {
S
Steven Whitehouse 已提交
301
		gfs2_meta_sync(ip->i_gl);
D
David Teigland 已提交
302 303 304 305 306
		return;
	}
	if (pass != 1)
		return;

S
Steven Whitehouse 已提交
307
	gfs2_meta_sync(ip->i_gl);
D
David Teigland 已提交
308 309 310 311 312 313 314 315 316

	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;

317
	tr = current->journal_info;
D
David Teigland 已提交
318 319 320 321 322 323 324 325 326 327 328 329 330
	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;
331
	struct gfs2_bufdata *bd;
D
David Teigland 已提交
332 333 334 335

	if (!sdp->sd_log_num_revoke)
		return;

336 337
	bh = gfs2_get_log_desc(sdp, GFS2_LOG_DESC_REVOKE);
	ld = bh_log_desc(bh);
338
	ld->ld_length = cpu_to_be32(gfs2_struct2blk(sdp, sdp->sd_log_num_revoke,
339
						    sizeof(u64)));
D
David Teigland 已提交
340 341 342 343
	ld->ld_data1 = cpu_to_be32(sdp->sd_log_num_revoke);
	offset = sizeof(struct gfs2_log_descriptor);

	while (!list_empty(head)) {
344 345
		bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
		list_del_init(&bd->bd_le.le_list);
D
David Teigland 已提交
346 347
		sdp->sd_log_num_revoke--;

348
		if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) {
S
Steven Whitehouse 已提交
349
			submit_bh(WRITE_SYNC_PLUG, bh);
D
David Teigland 已提交
350 351 352 353

			bh = gfs2_log_get_buf(sdp);
			mh = (struct gfs2_meta_header *)bh->b_data;
			mh->mh_magic = cpu_to_be32(GFS2_MAGIC);
354 355
			mh->mh_type = cpu_to_be32(GFS2_METATYPE_LB);
			mh->mh_format = cpu_to_be32(GFS2_FORMAT_LB);
D
David Teigland 已提交
356 357 358
			offset = sizeof(struct gfs2_meta_header);
		}

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

362
		offset += sizeof(u64);
D
David Teigland 已提交
363 364 365
	}
	gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);

S
Steven Whitehouse 已提交
366
	submit_bh(WRITE_SYNC_PLUG, bh);
D
David Teigland 已提交
367 368 369
}

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

	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)
{
385
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
386 387 388 389
	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;
390
	u64 blkno;
D
David Teigland 已提交
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
	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);

407
		while (offset + sizeof(u64) <= sdp->sd_sb.sb_bsize) {
D
David Teigland 已提交
408 409 410
			blkno = be64_to_cpu(*(__be64 *)(bh->b_data + offset));

			error = gfs2_revoke_add(sdp, blkno, start);
B
Bob Peterson 已提交
411 412
			if (error < 0) {
				brelse(bh);
D
David Teigland 已提交
413
				return error;
B
Bob Peterson 已提交
414
			}
D
David Teigland 已提交
415 416 417 418 419
			else if (error)
				sdp->sd_found_revokes++;

			if (!--revokes)
				break;
420
			offset += sizeof(u64);
D
David Teigland 已提交
421 422 423 424 425 426 427 428 429 430 431 432
		}

		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)
{
433
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
D
David Teigland 已提交
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450

	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;
451
	struct gfs2_trans *tr = current->journal_info;
D
David Teigland 已提交
452

453
	tr->tr_touched = 1;
D
David Teigland 已提交
454 455 456 457

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

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

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);
}

484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499
/**
 * 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 已提交
500 501
static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
{
502
	struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
503
	struct gfs2_trans *tr = current->journal_info;
504
	struct address_space *mapping = bd->bd_bh->b_page->mapping;
505
	struct gfs2_inode *ip = GFS2_I(mapping->host);
D
David Teigland 已提交
506

507
	lock_buffer(bd->bd_bh);
508
	gfs2_log_lock(sdp);
509 510 511 512 513 514 515 516
	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);
		}
517
	}
518
	if (!list_empty(&le->le_list))
519
		goto out;
520

521 522
	set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags);
	set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
523 524 525
	if (gfs2_is_jdata(ip)) {
		gfs2_pin(sdp, bd->bd_bh);
		tr->tr_num_databuf_new++;
526 527 528 529
		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);
530 531
	}
out:
D
David Teigland 已提交
532
	gfs2_log_unlock(sdp);
533
	unlock_buffer(bd->bd_bh);
D
David Teigland 已提交
534 535
}

536
static void gfs2_check_magic(struct buffer_head *bh)
537 538 539 540
{
	void *kaddr;
	__be32 *ptr;

541 542
	clear_buffer_escaped(bh);
	kaddr = kmap_atomic(bh->b_page, KM_USER0);
543 544
	ptr = kaddr + bh_offset(bh);
	if (*ptr == cpu_to_be32(GFS2_MAGIC))
545
		set_buffer_escaped(bh);
546
	kunmap_atomic(kaddr, KM_USER0);
547 548
}

549 550 551
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 已提交
552
{
553
	struct buffer_head *bh1;
554
	struct gfs2_log_descriptor *ld;
555 556
	struct gfs2_bufdata *bd;
	__be64 *ptr;
557

558 559
	if (!bh)
		return;
D
David Teigland 已提交
560

561 562 563
	ld = bh_log_desc(bh);
	ld->ld_length = cpu_to_be32(n + 1);
	ld->ld_data1 = cpu_to_be32(n);
D
David Teigland 已提交
564

565 566 567
	ptr = bh_log_ptr(bh);
	
	get_bh(bh);
S
Steven Whitehouse 已提交
568
	submit_bh(WRITE_SYNC_PLUG, bh);
569
	gfs2_log_lock(sdp);
570 571 572 573 574 575 576
	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;
577
		}
578
		gfs2_log_unlock(sdp);
579 580 581 582 583 584 585 586 587 588 589 590 591 592
		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);
593
		}
S
Steven Whitehouse 已提交
594
		submit_bh(WRITE_SYNC_PLUG, bh1);
595
		gfs2_log_lock(sdp);
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
		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) {
619
			gfs2_log_unlock(sdp);
620 621 622 623 624
			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;
625
			gfs2_log_lock(sdp);
626
			continue;
627
		}
628 629 630 631 632 633
		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 已提交
634
	}
635
	gfs2_log_unlock(sdp);
636 637 638 639
	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);
640 641 642 643 644 645
}

static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
				    struct gfs2_log_descriptor *ld,
				    __be64 *ptr, int pass)
{
646 647
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
648
	struct gfs2_glock *gl = ip->i_gl;
649 650
	unsigned int blks = be32_to_cpu(ld->ld_data1);
	struct buffer_head *bh_log, *bh_ip;
651 652
	u64 blkno;
	u64 esc;
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 692 693 694 695 696
	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)
{
697 698
	struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
	struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
699 700

	if (error) {
S
Steven Whitehouse 已提交
701
		gfs2_meta_sync(ip->i_gl);
702 703 704 705 706 707
		return;
	}
	if (pass != 1)
		return;

	/* data sync? */
S
Steven Whitehouse 已提交
708
	gfs2_meta_sync(ip->i_gl);
709 710 711 712 713 714 715 716 717 718 719 720

	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 已提交
721
		list_del_init(&bd->bd_le.le_list);
722 723 724
		sdp->sd_log_num_databuf--;
		gfs2_unpin(sdp, bd->bd_bh, ai);
	}
D
David Teigland 已提交
725 726 727
	gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf);
}

728

729
const struct gfs2_log_operations gfs2_buf_lops = {
D
David Teigland 已提交
730 731 732 733 734 735
	.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,
736
	.lo_name = "buf",
D
David Teigland 已提交
737 738
};

739
const struct gfs2_log_operations gfs2_revoke_lops = {
D
David Teigland 已提交
740 741 742 743 744
	.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,
745
	.lo_name = "revoke",
D
David Teigland 已提交
746 747
};

748
const struct gfs2_log_operations gfs2_rg_lops = {
D
David Teigland 已提交
749 750
	.lo_add = rg_lo_add,
	.lo_after_commit = rg_lo_after_commit,
751
	.lo_name = "rg",
D
David Teigland 已提交
752 753
};

754
const struct gfs2_log_operations gfs2_databuf_lops = {
D
David Teigland 已提交
755 756
	.lo_add = databuf_lo_add,
	.lo_before_commit = databuf_lo_before_commit,
757 758 759
	.lo_after_commit = databuf_lo_after_commit,
	.lo_scan_elements = databuf_lo_scan_elements,
	.lo_after_scan = databuf_lo_after_scan,
760
	.lo_name = "databuf",
D
David Teigland 已提交
761 762
};

763
const struct gfs2_log_operations *gfs2_log_ops[] = {
764
	&gfs2_databuf_lops,
D
David Teigland 已提交
765 766
	&gfs2_buf_lops,
	&gfs2_rg_lops,
767
	&gfs2_revoke_lops,
768
	NULL,
D
David Teigland 已提交
769 770
};