glops.c 16.1 KB
Newer Older
David Teigland's avatar
David Teigland committed
1
2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
David Teigland's avatar
David Teigland committed
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.
David Teigland's avatar
David Teigland committed
8
9
10
11
12
 */

#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
13
#include <linux/gfs2_ondisk.h>
14
#include <linux/bio.h>
15
#include <linux/posix_acl.h>
David Teigland's avatar
David Teigland committed
16
17

#include "gfs2.h"
18
#include "incore.h"
David Teigland's avatar
David Teigland committed
19
20
21
22
23
24
25
26
#include "bmap.h"
#include "glock.h"
#include "glops.h"
#include "inode.h"
#include "log.h"
#include "meta_io.h"
#include "recovery.h"
#include "rgrp.h"
27
#include "util.h"
28
#include "trans.h"
29
#include "dir.h"
David Teigland's avatar
David Teigland committed
30

31
32
struct workqueue_struct *gfs2_freeze_wq;

33
34
35
36
37
38
39
40
41
42
43
static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
{
	fs_err(gl->gl_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page state 0x%lx\n",
	       bh, (unsigned long long)bh->b_blocknr, bh->b_state,
	       bh->b_page->mapping, bh->b_page->flags);
	fs_err(gl->gl_sbd, "AIL glock %u:%llu mapping %p\n",
	       gl->gl_name.ln_type, gl->gl_name.ln_number,
	       gfs2_glock2aspace(gl));
	gfs2_lm_withdraw(gl->gl_sbd, "AIL error\n");
}

44
/**
Steven Whitehouse's avatar
Steven Whitehouse committed
45
 * __gfs2_ail_flush - remove all buffers for a given lock from the AIL
46
 * @gl: the glock
47
 * @fsync: set when called from fsync (not all buffers will be clean)
48
49
50
51
 *
 * None of the buffers should be dirty, locked, or pinned.
 */

52
53
static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync,
			     unsigned int nr_revokes)
54
55
56
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct list_head *head = &gl->gl_ail_list;
57
	struct gfs2_bufdata *bd, *tmp;
58
	struct buffer_head *bh;
59
	const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock);
60

61
	gfs2_log_lock(sdp);
Dave Chinner's avatar
Dave Chinner committed
62
	spin_lock(&sdp->sd_ail_lock);
63
64
65
	list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) {
		if (nr_revokes == 0)
			break;
66
		bh = bd->bd_bh;
67
68
69
		if (bh->b_state & b_state) {
			if (fsync)
				continue;
70
			gfs2_ail_error(gl, bh);
71
		}
72
		gfs2_trans_add_revoke(sdp, bd);
73
		nr_revokes--;
74
	}
75
	GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count));
Dave Chinner's avatar
Dave Chinner committed
76
	spin_unlock(&sdp->sd_ail_lock);
77
	gfs2_log_unlock(sdp);
Steven Whitehouse's avatar
Steven Whitehouse committed
78
79
80
81
82
83
84
85
86
}


static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct gfs2_trans tr;

	memset(&tr, 0, sizeof(tr));
87
88
	INIT_LIST_HEAD(&tr.tr_buf);
	INIT_LIST_HEAD(&tr.tr_databuf);
Steven Whitehouse's avatar
Steven Whitehouse committed
89
90
91
92
93
	tr.tr_revokes = atomic_read(&gl->gl_ail_count);

	if (!tr.tr_revokes)
		return;

94
95
96
	/* A shortened, inline version of gfs2_trans_begin()
         * tr->alloced is not set since the transaction structure is
         * on the stack */
Steven Whitehouse's avatar
Steven Whitehouse committed
97
	tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
98
	tr.tr_ip = _RET_IP_;
99
	if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0)
100
		return;
101
	WARN_ON_ONCE(current->journal_info);
Steven Whitehouse's avatar
Steven Whitehouse committed
102
103
	current->journal_info = &tr;

104
	__gfs2_ail_flush(gl, 0, tr.tr_revokes);
Steven Whitehouse's avatar
Steven Whitehouse committed
105
106

	gfs2_trans_end(sdp);
107
	gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
Steven Whitehouse's avatar
Steven Whitehouse committed
108
}
109

110
void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
Steven Whitehouse's avatar
Steven Whitehouse committed
111
112
113
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
	unsigned int revokes = atomic_read(&gl->gl_ail_count);
114
	unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64);
Steven Whitehouse's avatar
Steven Whitehouse committed
115
116
117
118
119
	int ret;

	if (!revokes)
		return;

120
121
122
123
	while (revokes > max_revokes)
		max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64);

	ret = gfs2_trans_begin(sdp, 0, max_revokes);
Steven Whitehouse's avatar
Steven Whitehouse committed
124
125
	if (ret)
		return;
126
	__gfs2_ail_flush(gl, fsync, max_revokes);
127
	gfs2_trans_end(sdp);
128
	gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
129
}
Steven Whitehouse's avatar
Steven Whitehouse committed
130
131

/**
Steven Whitehouse's avatar
Steven Whitehouse committed
132
 * rgrp_go_sync - sync out the metadata for this glock
David Teigland's avatar
David Teigland committed
133
134
135
136
137
138
139
 * @gl: the glock
 *
 * Called when demoting or unlocking an EX glock.  We must flush
 * to disk all dirty buffers/pages relating to this glock, and must not
 * not return to caller to demote/unlock the glock until I/O is complete.
 */

Steven Whitehouse's avatar
Steven Whitehouse committed
140
static void rgrp_go_sync(struct gfs2_glock *gl)
David Teigland's avatar
David Teigland committed
141
{
142
143
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct address_space *mapping = &sdp->sd_aspace;
144
	struct gfs2_rgrpd *rgd;
Steven Whitehouse's avatar
Steven Whitehouse committed
145
146
	int error;

147
148
149
150
151
152
	spin_lock(&gl->gl_spin);
	rgd = gl->gl_object;
	if (rgd)
		gfs2_rgrp_brelse(rgd);
	spin_unlock(&gl->gl_spin);

Steven Whitehouse's avatar
Steven Whitehouse committed
153
	if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
Steven Whitehouse's avatar
Steven Whitehouse committed
154
		return;
155
	GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
Steven Whitehouse's avatar
Steven Whitehouse committed
156

157
	gfs2_log_flush(sdp, gl, NORMAL_FLUSH);
158
159
160
	filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
	error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
	mapping_set_error(mapping, error);
Steven Whitehouse's avatar
Steven Whitehouse committed
161
	gfs2_ail_empty_gl(gl);
162

163
164
165
166
167
	spin_lock(&gl->gl_spin);
	rgd = gl->gl_object;
	if (rgd)
		gfs2_free_clones(rgd);
	spin_unlock(&gl->gl_spin);
David Teigland's avatar
David Teigland committed
168
169
170
}

/**
Steven Whitehouse's avatar
Steven Whitehouse committed
171
 * rgrp_go_inval - invalidate the metadata for this glock
David Teigland's avatar
David Teigland committed
172
173
174
 * @gl: the glock
 * @flags:
 *
Steven Whitehouse's avatar
Steven Whitehouse committed
175
176
177
 * We never used LM_ST_DEFERRED with resource groups, so that we
 * should always see the metadata flag set here.
 *
David Teigland's avatar
David Teigland committed
178
179
 */

Steven Whitehouse's avatar
Steven Whitehouse committed
180
static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
David Teigland's avatar
David Teigland committed
181
{
182
183
	struct gfs2_sbd *sdp = gl->gl_sbd;
	struct address_space *mapping = &sdp->sd_aspace;
184
185
186
187
	struct gfs2_rgrpd *rgd = gl->gl_object;

	if (rgd)
		gfs2_rgrp_brelse(rgd);
David Teigland's avatar
David Teigland committed
188

189
	WARN_ON_ONCE(!(flags & DIO_METADATA));
190
	gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
191
	truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
192

193
	if (rgd)
194
		rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
David Teigland's avatar
David Teigland committed
195
196
}

Steven Whitehouse's avatar
Steven Whitehouse committed
197
198
199
200
201
202
203
204
205
/**
 * inode_go_sync - Sync the dirty data and/or metadata for an inode glock
 * @gl: the glock protecting the inode
 *
 */

static void inode_go_sync(struct gfs2_glock *gl)
{
	struct gfs2_inode *ip = gl->gl_object;
206
	struct address_space *metamapping = gfs2_glock2aspace(gl);
207
208
	int error;

Steven Whitehouse's avatar
Steven Whitehouse committed
209
210
	if (ip && !S_ISREG(ip->i_inode.i_mode))
		ip = NULL;
211
212
213
214
215
	if (ip) {
		if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
			unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0);
		inode_dio_wait(&ip->i_inode);
	}
Steven Whitehouse's avatar
Steven Whitehouse committed
216
217
	if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
		return;
Steven Whitehouse's avatar
Steven Whitehouse committed
218

219
	GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
Steven Whitehouse's avatar
Steven Whitehouse committed
220

221
	gfs2_log_flush(gl->gl_sbd, gl, NORMAL_FLUSH);
Steven Whitehouse's avatar
Steven Whitehouse committed
222
223
224
225
226
227
	filemap_fdatawrite(metamapping);
	if (ip) {
		struct address_space *mapping = ip->i_inode.i_mapping;
		filemap_fdatawrite(mapping);
		error = filemap_fdatawait(mapping);
		mapping_set_error(mapping, error);
Steven Whitehouse's avatar
Steven Whitehouse committed
228
	}
Steven Whitehouse's avatar
Steven Whitehouse committed
229
230
231
	error = filemap_fdatawait(metamapping);
	mapping_set_error(metamapping, error);
	gfs2_ail_empty_gl(gl);
232
233
234
235
	/*
	 * Writeback of the data mapping may cause the dirty flag to be set
	 * so we have to clear it again here.
	 */
236
	smp_mb__before_atomic();
237
	clear_bit(GLF_DIRTY, &gl->gl_flags);
Steven Whitehouse's avatar
Steven Whitehouse committed
238
239
}

David Teigland's avatar
David Teigland committed
240
241
242
243
/**
 * inode_go_inval - prepare a inode glock to be released
 * @gl: the glock
 * @flags:
244
245
 *
 * Normally we invalidate everything, but if we are moving into
Steven Whitehouse's avatar
Steven Whitehouse committed
246
247
 * LM_ST_DEFERRED from LM_ST_SHARED or LM_ST_EXCLUSIVE then we
 * can keep hold of the metadata, since it won't have changed.
David Teigland's avatar
David Teigland committed
248
249
250
251
252
 *
 */

static void inode_go_inval(struct gfs2_glock *gl, int flags)
{
253
	struct gfs2_inode *ip = gl->gl_object;
David Teigland's avatar
David Teigland committed
254

Steven Whitehouse's avatar
Steven Whitehouse committed
255
256
257
	gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));

	if (flags & DIO_METADATA) {
258
		struct address_space *mapping = gfs2_glock2aspace(gl);
Steven Whitehouse's avatar
Steven Whitehouse committed
259
		truncate_inode_pages(mapping, 0);
260
		if (ip) {
261
			set_bit(GIF_INVALID, &ip->i_flags);
262
			forget_all_cached_acls(&ip->i_inode);
263
			gfs2_dir_hash_inval(ip);
264
		}
265
266
	}

267
	if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) {
268
		gfs2_log_flush(gl->gl_sbd, NULL, NORMAL_FLUSH);
Steven Whitehouse's avatar
Steven Whitehouse committed
269
		gl->gl_sbd->sd_rindex_uptodate = 0;
270
	}
271
	if (ip && S_ISREG(ip->i_inode.i_mode))
272
		truncate_inode_pages(ip->i_inode.i_mapping, 0);
David Teigland's avatar
David Teigland committed
273
274
275
276
277
278
279
280
281
}

/**
 * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock
 * @gl: the glock
 *
 * Returns: 1 if it's ok
 */

282
static int inode_go_demote_ok(const struct gfs2_glock *gl)
David Teigland's avatar
David Teigland committed
283
284
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
285
286
	struct gfs2_holder *gh;

287
288
	if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
		return 0;
289
290
291
292
293
294
295

	if (!list_empty(&gl->gl_holders)) {
		gh = list_entry(gl->gl_holders.next, struct gfs2_holder, gh_list);
		if (gh->gh_list.next != &gl->gl_holders)
			return 0;
	}

296
	return 1;
David Teigland's avatar
David Teigland committed
297
298
}

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/**
 * gfs2_set_nlink - Set the inode's link count based on on-disk info
 * @inode: The inode in question
 * @nlink: The link count
 *
 * If the link count has hit zero, it must never be raised, whatever the
 * on-disk inode might say. When new struct inodes are created the link
 * count is set to 1, so that we can safely use this test even when reading
 * in on disk information for the first time.
 */

static void gfs2_set_nlink(struct inode *inode, u32 nlink)
{
	/*
	 * We will need to review setting the nlink count here in the
	 * light of the forthcoming ro bind mount work. This is a reminder
	 * to do that.
	 */
	if ((inode->i_nlink != nlink) && (inode->i_nlink != 0)) {
		if (nlink == 0)
			clear_nlink(inode);
		else
Miklos Szeredi's avatar
Miklos Szeredi committed
321
			set_nlink(inode, nlink);
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
	}
}

static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
{
	const struct gfs2_dinode *str = buf;
	struct timespec atime;
	u16 height, depth;

	if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
		goto corrupt;
	ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
	ip->i_inode.i_mode = be32_to_cpu(str->di_mode);
	ip->i_inode.i_rdev = 0;
	switch (ip->i_inode.i_mode & S_IFMT) {
	case S_IFBLK:
	case S_IFCHR:
		ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
					   be32_to_cpu(str->di_minor));
		break;
	};

344
345
	i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid));
	i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid));
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
	gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
	i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
	gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
	atime.tv_sec = be64_to_cpu(str->di_atime);
	atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
	if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0)
		ip->i_inode.i_atime = atime;
	ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
	ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
	ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
	ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);

	ip->i_goal = be64_to_cpu(str->di_goal_meta);
	ip->i_generation = be64_to_cpu(str->di_generation);

	ip->i_diskflags = be32_to_cpu(str->di_flags);
Steven Whitehouse's avatar
Steven Whitehouse committed
362
363
	ip->i_eattr = be64_to_cpu(str->di_eattr);
	/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
	gfs2_set_inode_flags(&ip->i_inode);
	height = be16_to_cpu(str->di_height);
	if (unlikely(height > GFS2_MAX_META_HEIGHT))
		goto corrupt;
	ip->i_height = (u8)height;

	depth = be16_to_cpu(str->di_depth);
	if (unlikely(depth > GFS2_DIR_MAX_DEPTH))
		goto corrupt;
	ip->i_depth = (u8)depth;
	ip->i_entries = be32_to_cpu(str->di_entries);

	if (S_ISREG(ip->i_inode.i_mode))
		gfs2_set_aops(&ip->i_inode);

	return 0;
corrupt:
	gfs2_consist_inode(ip);
	return -EIO;
}

/**
 * gfs2_inode_refresh - Refresh the incore copy of the dinode
 * @ip: The GFS2 inode
 *
 * Returns: errno
 */

int gfs2_inode_refresh(struct gfs2_inode *ip)
{
	struct buffer_head *dibh;
	int error;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		return error;

	error = gfs2_dinode_in(ip, dibh->b_data);
	brelse(dibh);
	clear_bit(GIF_INVALID, &ip->i_flags);

	return error;
}

David Teigland's avatar
David Teigland committed
408
409
410
411
412
413
414
415
416
417
418
/**
 * inode_go_lock - operation done after an inode lock is locked by a process
 * @gl: the glock
 * @flags:
 *
 * Returns: errno
 */

static int inode_go_lock(struct gfs2_holder *gh)
{
	struct gfs2_glock *gl = gh->gh_gl;
419
	struct gfs2_sbd *sdp = gl->gl_sbd;
420
	struct gfs2_inode *ip = gl->gl_object;
David Teigland's avatar
David Teigland committed
421
422
	int error = 0;

423
	if (!ip || (gh->gh_flags & GL_SKIP))
David Teigland's avatar
David Teigland committed
424
425
		return 0;

426
	if (test_bit(GIF_INVALID, &ip->i_flags)) {
David Teigland's avatar
David Teigland committed
427
428
429
430
431
		error = gfs2_inode_refresh(ip);
		if (error)
			return error;
	}

432
433
434
	if (gh->gh_state != LM_ST_DEFERRED)
		inode_dio_wait(&ip->i_inode);

435
	if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) &&
David Teigland's avatar
David Teigland committed
436
	    (gl->gl_state == LM_ST_EXCLUSIVE) &&
437
438
439
440
441
442
443
444
	    (gh->gh_state == LM_ST_EXCLUSIVE)) {
		spin_lock(&sdp->sd_trunc_lock);
		if (list_empty(&ip->i_trunc_list))
			list_add(&sdp->sd_trunc_list, &ip->i_trunc_list);
		spin_unlock(&sdp->sd_trunc_lock);
		wake_up(&sdp->sd_quota_wait);
		return 1;
	}
David Teigland's avatar
David Teigland committed
445
446
447
448

	return error;
}

449
450
451
452
453
454
455
/**
 * inode_go_dump - print information about an inode
 * @seq: The iterator
 * @ip: the inode
 *
 */

456
static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
457
458
459
{
	const struct gfs2_inode *ip = gl->gl_object;
	if (ip == NULL)
460
		return;
Steven Whitehouse's avatar
Steven Whitehouse committed
461
	gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n",
462
463
		  (unsigned long long)ip->i_no_formal_ino,
		  (unsigned long long)ip->i_no_addr,
464
465
		  IF2DT(ip->i_inode.i_mode), ip->i_flags,
		  (unsigned int)ip->i_diskflags,
Steven Whitehouse's avatar
Steven Whitehouse committed
466
		  (unsigned long long)i_size_read(&ip->i_inode));
467
468
}

David Teigland's avatar
David Teigland committed
469
/**
470
 * freeze_go_sync - promote/demote the freeze glock
David Teigland's avatar
David Teigland committed
471
472
473
474
475
476
 * @gl: the glock
 * @state: the requested state
 * @flags:
 *
 */

477
static void freeze_go_sync(struct gfs2_glock *gl)
David Teigland's avatar
David Teigland committed
478
{
479
	int error = 0;
David Teigland's avatar
David Teigland committed
480
481
	struct gfs2_sbd *sdp = gl->gl_sbd;

482
	if (gl->gl_state == LM_ST_SHARED &&
David Teigland's avatar
David Teigland committed
483
	    test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
484
485
486
487
488
489
490
491
		atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE);
		error = freeze_super(sdp->sd_vfs);
		if (error) {
			printk(KERN_INFO "GFS2: couldn't freeze filesystem: %d\n", error);
			gfs2_assert_withdraw(sdp, 0);
		}
		queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work);
		gfs2_log_flush(sdp, NULL, FREEZE_FLUSH);
David Teigland's avatar
David Teigland committed
492
493
494
495
	}
}

/**
496
 * freeze_go_xmote_bh - After promoting/demoting the freeze glock
David Teigland's avatar
David Teigland committed
497
498
499
500
 * @gl: the glock
 *
 */

501
static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
David Teigland's avatar
David Teigland committed
502
503
{
	struct gfs2_sbd *sdp = gl->gl_sbd;
504
	struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
505
	struct gfs2_glock *j_gl = ip->i_gl;
506
	struct gfs2_log_header_host head;
David Teigland's avatar
David Teigland committed
507
508
	int error;

509
	if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
510
		j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
David Teigland's avatar
David Teigland committed
511
512
513
514
515
516
517
518
519
520
521
522
523

		error = gfs2_find_jhead(sdp->sd_jdesc, &head);
		if (error)
			gfs2_consist(sdp);
		if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT))
			gfs2_consist(sdp);

		/*  Initialize some head of the log stuff  */
		if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) {
			sdp->sd_log_sequence = head.lh_sequence + 1;
			gfs2_log_pointers_init(sdp, head.lh_blkno);
		}
	}
524
	return 0;
David Teigland's avatar
David Teigland committed
525
526
}

527
528
529
530
531
532
533
/**
 * trans_go_demote_ok
 * @gl: the glock
 *
 * Always returns 0
 */

534
static int freeze_go_demote_ok(const struct gfs2_glock *gl)
535
536
537
538
{
	return 0;
}

539
540
541
542
543
544
/**
 * iopen_go_callback - schedule the dcache entry for the inode to be deleted
 * @gl: the glock
 *
 * gl_spin lock is held while calling this
 */
545
static void iopen_go_callback(struct gfs2_glock *gl, bool remote)
546
547
{
	struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
548
549
	struct gfs2_sbd *sdp = gl->gl_sbd;

550
	if (!remote || (sdp->sd_vfs->s_flags & MS_RDONLY))
551
		return;
552
553

	if (gl->gl_demote_state == LM_ST_UNLOCKED &&
554
	    gl->gl_state == LM_ST_SHARED && ip) {
555
		gl->gl_lockref.count++;
556
		if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
557
			gl->gl_lockref.count--;
558
559
560
	}
}

561
const struct gfs2_glock_operations gfs2_meta_glops = {
562
	.go_type = LM_TYPE_META,
David Teigland's avatar
David Teigland committed
563
564
};

565
const struct gfs2_glock_operations gfs2_inode_glops = {
566
	.go_sync = inode_go_sync,
David Teigland's avatar
David Teigland committed
567
568
569
	.go_inval = inode_go_inval,
	.go_demote_ok = inode_go_demote_ok,
	.go_lock = inode_go_lock,
570
	.go_dump = inode_go_dump,
571
	.go_type = LM_TYPE_INODE,
572
	.go_flags = GLOF_ASPACE | GLOF_LRU,
David Teigland's avatar
David Teigland committed
573
574
};

575
const struct gfs2_glock_operations gfs2_rgrp_glops = {
576
	.go_sync = rgrp_go_sync,
Steven Whitehouse's avatar
Steven Whitehouse committed
577
	.go_inval = rgrp_go_inval,
578
579
	.go_lock = gfs2_rgrp_go_lock,
	.go_unlock = gfs2_rgrp_go_unlock,
580
	.go_dump = gfs2_rgrp_dump,
581
	.go_type = LM_TYPE_RGRP,
582
	.go_flags = GLOF_LVB,
David Teigland's avatar
David Teigland committed
583
584
};

585
586
587
588
const struct gfs2_glock_operations gfs2_freeze_glops = {
	.go_sync = freeze_go_sync,
	.go_xmote_bh = freeze_go_xmote_bh,
	.go_demote_ok = freeze_go_demote_ok,
589
	.go_type = LM_TYPE_NONDISK,
David Teigland's avatar
David Teigland committed
590
591
};

592
const struct gfs2_glock_operations gfs2_iopen_glops = {
593
	.go_type = LM_TYPE_IOPEN,
594
	.go_callback = iopen_go_callback,
595
	.go_flags = GLOF_LRU,
David Teigland's avatar
David Teigland committed
596
597
};

598
const struct gfs2_glock_operations gfs2_flock_glops = {
599
	.go_type = LM_TYPE_FLOCK,
600
	.go_flags = GLOF_LRU,
David Teigland's avatar
David Teigland committed
601
602
};

603
const struct gfs2_glock_operations gfs2_nondisk_glops = {
604
	.go_type = LM_TYPE_NONDISK,
David Teigland's avatar
David Teigland committed
605
606
};

607
const struct gfs2_glock_operations gfs2_quota_glops = {
608
	.go_type = LM_TYPE_QUOTA,
609
	.go_flags = GLOF_LVB | GLOF_LRU,
David Teigland's avatar
David Teigland committed
610
611
};

612
const struct gfs2_glock_operations gfs2_journal_glops = {
613
	.go_type = LM_TYPE_JOURNAL,
David Teigland's avatar
David Teigland committed
614
615
};

616
617
618
619
620
621
622
623
624
625
626
const struct gfs2_glock_operations *gfs2_glops_list[] = {
	[LM_TYPE_META] = &gfs2_meta_glops,
	[LM_TYPE_INODE] = &gfs2_inode_glops,
	[LM_TYPE_RGRP] = &gfs2_rgrp_glops,
	[LM_TYPE_IOPEN] = &gfs2_iopen_glops,
	[LM_TYPE_FLOCK] = &gfs2_flock_glops,
	[LM_TYPE_NONDISK] = &gfs2_nondisk_glops,
	[LM_TYPE_QUOTA] = &gfs2_quota_glops,
	[LM_TYPE_JOURNAL] = &gfs2_journal_glops,
};