Blame view

fs/gfs2/glops.c 15.1 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
cf45b752c   Bob Peterson   [GFS2] Remove rgr...
3
   * Copyright (C) 2004-2008 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
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
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
   */
b3b94faa5   David Teigland   [GFS2] The core o...
9
10
11
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
12
  #include <linux/gfs2_ondisk.h>
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
13
  #include <linux/bio.h>
c65f7fb53   Steven Whitehouse   GFS2: Use forget_...
14
  #include <linux/posix_acl.h>
b3b94faa5   David Teigland   [GFS2] The core o...
15
16
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
17
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
18
19
20
21
22
23
  #include "bmap.h"
  #include "glock.h"
  #include "glops.h"
  #include "inode.h"
  #include "log.h"
  #include "meta_io.h"
b3b94faa5   David Teigland   [GFS2] The core o...
24
25
  #include "recovery.h"
  #include "rgrp.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
26
  #include "util.h"
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
27
  #include "trans.h"
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
28
  #include "dir.h"
b3b94faa5   David Teigland   [GFS2] The core o...
29

75549186e   Steven Whitehouse   GFS2: Fix bug-tra...
30
31
32
33
34
35
36
37
38
39
40
41
42
  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
  ",
  	       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
  ",
  	       gl->gl_name.ln_type, gl->gl_name.ln_number,
  	       gfs2_glock2aspace(gl));
  	gfs2_lm_withdraw(gl->gl_sbd, "AIL error
  ");
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
43
  /**
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
44
   * __gfs2_ail_flush - remove all buffers for a given lock from the AIL
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
45
   * @gl: the glock
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
46
   * @fsync: set when called from fsync (not all buffers will be clean)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
47
48
49
   *
   * None of the buffers should be dirty, locked, or pinned.
   */
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
50
  static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
51
52
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
53
  	struct list_head *head = &gl->gl_ail_list;
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
54
  	struct gfs2_bufdata *bd, *tmp;
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
55
  	struct buffer_head *bh;
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
56
  	const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock);
75549186e   Steven Whitehouse   GFS2: Fix bug-tra...
57
  	sector_t blocknr;
d8348de06   Steven Whitehouse   GFS2: Fix deadloc...
58

b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
59
  	gfs2_log_lock(sdp);
d6a079e82   Dave Chinner   GFS2: introduce A...
60
  	spin_lock(&sdp->sd_ail_lock);
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
61
  	list_for_each_entry_safe(bd, tmp, head, bd_ail_gl_list) {
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
62
  		bh = bd->bd_bh;
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
63
64
65
  		if (bh->b_state & b_state) {
  			if (fsync)
  				continue;
75549186e   Steven Whitehouse   GFS2: Fix bug-tra...
66
  			gfs2_ail_error(gl, bh);
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
67
68
  		}
  		blocknr = bh->b_blocknr;
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
69
  		bh->b_private = NULL;
75549186e   Steven Whitehouse   GFS2: Fix bug-tra...
70
  		gfs2_remove_from_ail(bd); /* drops ref on bh */
380f7c65a   Steven Whitehouse   GFS2: Resolve ino...
71

75549186e   Steven Whitehouse   GFS2: Fix bug-tra...
72
73
  		bd->bd_bh = NULL;
  		bd->bd_blkno = blocknr;
1ad38c437   Steven Whitehouse   [GFS2] Clean up g...
74
  		gfs2_trans_add_revoke(sdp, bd);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
75
  	}
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
76
  	BUG_ON(!fsync && atomic_read(&gl->gl_ail_count));
d6a079e82   Dave Chinner   GFS2: introduce A...
77
  	spin_unlock(&sdp->sd_ail_lock);
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
78
  	gfs2_log_unlock(sdp);
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  }
  
  
  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));
  	tr.tr_revokes = atomic_read(&gl->gl_ail_count);
  
  	if (!tr.tr_revokes)
  		return;
  
  	/* A shortened, inline version of gfs2_trans_begin() */
  	tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
  	tr.tr_ip = (unsigned long)__builtin_return_address(0);
  	INIT_LIST_HEAD(&tr.tr_list_buf);
  	gfs2_log_reserve(sdp, tr.tr_reserved);
  	BUG_ON(current->journal_info);
  	current->journal_info = &tr;
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
100
  	__gfs2_ail_flush(gl, 0);
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
101
102
103
104
  
  	gfs2_trans_end(sdp);
  	gfs2_log_flush(sdp, NULL);
  }
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
105

b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
106
  void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
dba898b02   Steven Whitehouse   GFS2: Clean up fs...
107
108
109
110
111
112
113
114
115
116
117
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  	unsigned int revokes = atomic_read(&gl->gl_ail_count);
  	int ret;
  
  	if (!revokes)
  		return;
  
  	ret = gfs2_trans_begin(sdp, 0, revokes);
  	if (ret)
  		return;
b5b24d7ae   Steven Whitehouse   GFS2: Fix AIL flu...
118
  	__gfs2_ail_flush(gl, fsync);
ddacfaf76   Steven Whitehouse   [GFS2] Move loggi...
119
120
121
  	gfs2_trans_end(sdp);
  	gfs2_log_flush(sdp, NULL);
  }
ba7f72901   Steven Whitehouse   [GFS2] Remove pag...
122
123
  
  /**
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
124
   * rgrp_go_sync - sync out the metadata for this glock
b3b94faa5   David Teigland   [GFS2] The core o...
125
   * @gl: the glock
b3b94faa5   David Teigland   [GFS2] The core o...
126
127
128
129
130
   *
   * 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.
   */
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
131
  static void rgrp_go_sync(struct gfs2_glock *gl)
b3b94faa5   David Teigland   [GFS2] The core o...
132
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
133
  	struct address_space *metamapping = gfs2_glock2aspace(gl);
8339ee543   Steven Whitehouse   GFS2: Make resour...
134
  	struct gfs2_rgrpd *rgd;
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
135
136
137
  	int error;
  
  	if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
138
  		return;
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
139
  	BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE);
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
140

6bac243f0   Steven Whitehouse   GFS2: Clean up of...
141
142
143
144
145
  	gfs2_log_flush(gl->gl_sbd, gl);
  	filemap_fdatawrite(metamapping);
  	error = filemap_fdatawait(metamapping);
          mapping_set_error(metamapping, error);
  	gfs2_ail_empty_gl(gl);
7c9ca6211   Bob Peterson   GFS2: Use rbtree ...
146

8339ee543   Steven Whitehouse   GFS2: Make resour...
147
148
149
150
151
  	spin_lock(&gl->gl_spin);
  	rgd = gl->gl_object;
  	if (rgd)
  		gfs2_free_clones(rgd);
  	spin_unlock(&gl->gl_spin);
b3b94faa5   David Teigland   [GFS2] The core o...
152
153
154
  }
  
  /**
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
155
   * rgrp_go_inval - invalidate the metadata for this glock
b3b94faa5   David Teigland   [GFS2] The core o...
156
157
158
   * @gl: the glock
   * @flags:
   *
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
159
160
161
   * We never used LM_ST_DEFERRED with resource groups, so that we
   * should always see the metadata flag set here.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
162
   */
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
163
  static void rgrp_go_inval(struct gfs2_glock *gl, int flags)
b3b94faa5   David Teigland   [GFS2] The core o...
164
  {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
165
  	struct address_space *mapping = gfs2_glock2aspace(gl);
b3b94faa5   David Teigland   [GFS2] The core o...
166

6bac243f0   Steven Whitehouse   GFS2: Clean up of...
167
168
169
  	BUG_ON(!(flags & DIO_METADATA));
  	gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
  	truncate_inode_pages(mapping, 0);
cf45b752c   Bob Peterson   [GFS2] Remove rgr...
170

6bac243f0   Steven Whitehouse   GFS2: Clean up of...
171
172
  	if (gl->gl_object) {
  		struct gfs2_rgrpd *rgd = (struct gfs2_rgrpd *)gl->gl_object;
cf45b752c   Bob Peterson   [GFS2] Remove rgr...
173
174
  		rgd->rd_flags &= ~GFS2_RDF_UPTODATE;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
175
176
177
  }
  
  /**
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
178
179
180
181
182
183
184
185
   * 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;
009d85183   Steven Whitehouse   GFS2: Metadata ad...
186
  	struct address_space *metamapping = gfs2_glock2aspace(gl);
3042a2ccd   Steven Whitehouse   [GFS2] Reorder wr...
187
  	int error;
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
188
189
  	if (ip && !S_ISREG(ip->i_inode.i_mode))
  		ip = NULL;
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
190
191
192
193
  	if (ip && test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
  		unmap_shared_mapping_range(ip->i_inode.i_mapping, 0, 0);
  	if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags))
  		return;
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
194

6bac243f0   Steven Whitehouse   GFS2: Clean up of...
195
196
197
198
199
200
201
202
203
  	BUG_ON(gl->gl_state != LM_ST_EXCLUSIVE);
  
  	gfs2_log_flush(gl->gl_sbd, gl);
  	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);
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
204
  	}
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
205
206
207
  	error = filemap_fdatawait(metamapping);
  	mapping_set_error(metamapping, error);
  	gfs2_ail_empty_gl(gl);
52fcd11c0   Steven Whitehouse   GFS2: Clear dirty...
208
209
210
211
212
213
  	/*
  	 * Writeback of the data mapping may cause the dirty flag to be set
  	 * so we have to clear it again here.
  	 */
  	smp_mb__before_clear_bit();
  	clear_bit(GLF_DIRTY, &gl->gl_flags);
b5d32bead   Steven Whitehouse   [GFS2] Tidy up gl...
214
215
216
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
217
218
219
   * inode_go_inval - prepare a inode glock to be released
   * @gl: the glock
   * @flags:
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
220
221
222
223
   * 
   * Normally we invlidate everything, but if we are moving into
   * 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.
b3b94faa5   David Teigland   [GFS2] The core o...
224
225
226
227
228
   *
   */
  
  static void inode_go_inval(struct gfs2_glock *gl, int flags)
  {
b004157ab   Steven Whitehouse   [GFS2] Fix journa...
229
  	struct gfs2_inode *ip = gl->gl_object;
b3b94faa5   David Teigland   [GFS2] The core o...
230

6bac243f0   Steven Whitehouse   GFS2: Clean up of...
231
232
233
  	gfs2_assert_withdraw(gl->gl_sbd, !atomic_read(&gl->gl_ail_count));
  
  	if (flags & DIO_METADATA) {
009d85183   Steven Whitehouse   GFS2: Metadata ad...
234
  		struct address_space *mapping = gfs2_glock2aspace(gl);
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
235
  		truncate_inode_pages(mapping, 0);
c65f7fb53   Steven Whitehouse   GFS2: Use forget_...
236
  		if (ip) {
b004157ab   Steven Whitehouse   [GFS2] Fix journa...
237
  			set_bit(GIF_INVALID, &ip->i_flags);
c65f7fb53   Steven Whitehouse   GFS2: Use forget_...
238
  			forget_all_cached_acls(&ip->i_inode);
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
239
  			gfs2_dir_hash_inval(ip);
c65f7fb53   Steven Whitehouse   GFS2: Use forget_...
240
  		}
b004157ab   Steven Whitehouse   [GFS2] Fix journa...
241
  	}
1ce533686   Benjamin Marzinski   GFS2: force a log...
242
243
  	if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) {
  		gfs2_log_flush(gl->gl_sbd, NULL);
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
244
  		gl->gl_sbd->sd_rindex_uptodate = 0;
1ce533686   Benjamin Marzinski   GFS2: force a log...
245
  	}
3cc3f710c   Steven Whitehouse   [GFS2] Use ->page...
246
  	if (ip && S_ISREG(ip->i_inode.i_mode))
b004157ab   Steven Whitehouse   [GFS2] Fix journa...
247
  		truncate_inode_pages(ip->i_inode.i_mapping, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
248
249
250
251
252
253
254
255
  }
  
  /**
   * 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
   */
97cc1025b   Steven Whitehouse   GFS2: Kill two da...
256
  static int inode_go_demote_ok(const struct gfs2_glock *gl)
b3b94faa5   David Teigland   [GFS2] The core o...
257
258
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
bc015cb84   Steven Whitehouse   GFS2: Use RCU for...
259
  	struct gfs2_holder *gh;
97cc1025b   Steven Whitehouse   GFS2: Kill two da...
260
261
  	if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
  		return 0;
bc015cb84   Steven Whitehouse   GFS2: Use RCU for...
262
263
264
265
266
267
  
  	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;
  	}
97cc1025b   Steven Whitehouse   GFS2: Kill two da...
268
  	return 1;
b3b94faa5   David Teigland   [GFS2] The core o...
269
270
271
  }
  
  /**
d4b2cf1b0   Steven Whitehouse   GFS2: Move gfs2_r...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
   * 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
bfe868486   Miklos Szeredi   filesystems: add ...
293
  			set_nlink(inode, nlink);
d4b2cf1b0   Steven Whitehouse   GFS2: Move gfs2_r...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
  	}
  }
  
  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;
  	};
  
  	ip->i_inode.i_uid = be32_to_cpu(str->di_uid);
  	ip->i_inode.i_gid = be32_to_cpu(str->di_gid);
  	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);
9964afbb7   Steven Whitehouse   GFS2: Add S_NOSEC...
334
335
  	ip->i_eattr = be64_to_cpu(str->di_eattr);
  	/* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */
d4b2cf1b0   Steven Whitehouse   GFS2: Move gfs2_r...
336
337
338
339
340
341
342
343
344
345
346
  	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);
d4b2cf1b0   Steven Whitehouse   GFS2: Move gfs2_r...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  	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;
  
  	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) {
  		brelse(dibh);
  		return -EIO;
  	}
  
  	error = gfs2_dinode_in(ip, dibh->b_data);
  	brelse(dibh);
  	clear_bit(GIF_INVALID, &ip->i_flags);
  
  	return error;
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
385
386
387
388
389
390
391
392
393
394
   * 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;
813e0c46c   Steven Whitehouse   GFS2: Fix "trunca...
395
  	struct gfs2_sbd *sdp = gl->gl_sbd;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
396
  	struct gfs2_inode *ip = gl->gl_object;
b3b94faa5   David Teigland   [GFS2] The core o...
397
  	int error = 0;
091806edd   Bob Peterson   [GFS2] filesystem...
398
  	if (!ip || (gh->gh_flags & GL_SKIP))
b3b94faa5   David Teigland   [GFS2] The core o...
399
  		return 0;
bfded27ba   Steven Whitehouse   [GFS2] Shrink gfs...
400
  	if (test_bit(GIF_INVALID, &ip->i_flags)) {
b3b94faa5   David Teigland   [GFS2] The core o...
401
402
403
  		error = gfs2_inode_refresh(ip);
  		if (error)
  			return error;
b3b94faa5   David Teigland   [GFS2] The core o...
404
  	}
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
405
  	if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) &&
b3b94faa5   David Teigland   [GFS2] The core o...
406
  	    (gl->gl_state == LM_ST_EXCLUSIVE) &&
813e0c46c   Steven Whitehouse   GFS2: Fix "trunca...
407
408
409
410
411
412
413
414
  	    (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;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
415
416
417
418
419
  
  	return error;
  }
  
  /**
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
420
421
422
423
424
425
426
427
428
429
430
431
   * inode_go_dump - print information about an inode
   * @seq: The iterator
   * @ip: the inode
   *
   * Returns: 0 on success, -ENOBUFS when we run out of space
   */
  
  static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
  {
  	const struct gfs2_inode *ip = gl->gl_object;
  	if (ip == NULL)
  		return 0;
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
432
433
  	gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu
  ",
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
434
435
  		  (unsigned long long)ip->i_no_formal_ino,
  		  (unsigned long long)ip->i_no_addr,
fa75cedc3   Steven Whitehouse   GFS2: Add more de...
436
437
  		  IF2DT(ip->i_inode.i_mode), ip->i_flags,
  		  (unsigned int)ip->i_diskflags,
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
438
  		  (unsigned long long)i_size_read(&ip->i_inode));
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
439
440
441
442
  	return 0;
  }
  
  /**
3042a2ccd   Steven Whitehouse   [GFS2] Reorder wr...
443
   * trans_go_sync - promote/demote the transaction glock
b3b94faa5   David Teigland   [GFS2] The core o...
444
445
446
447
448
   * @gl: the glock
   * @state: the requested state
   * @flags:
   *
   */
3042a2ccd   Steven Whitehouse   [GFS2] Reorder wr...
449
  static void trans_go_sync(struct gfs2_glock *gl)
b3b94faa5   David Teigland   [GFS2] The core o...
450
451
452
453
454
455
456
457
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  
  	if (gl->gl_state != LM_ST_UNLOCKED &&
  	    test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
  		gfs2_meta_syncfs(sdp);
  		gfs2_log_shutdown(sdp);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
458
459
460
461
462
463
464
  }
  
  /**
   * trans_go_xmote_bh - After promoting/demoting the transaction glock
   * @gl: the glock
   *
   */
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
465
  static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
b3b94faa5   David Teigland   [GFS2] The core o...
466
467
  {
  	struct gfs2_sbd *sdp = gl->gl_sbd;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
468
  	struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
469
  	struct gfs2_glock *j_gl = ip->i_gl;
551676226   Al Viro   [GFS2] split and ...
470
  	struct gfs2_log_header_host head;
b3b94faa5   David Teigland   [GFS2] The core o...
471
  	int error;
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
472
  	if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
1a14d3a68   Steven Whitehouse   [GFS2] Simplify g...
473
  		j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
b3b94faa5   David Teigland   [GFS2] The core o...
474
475
476
477
478
479
480
481
482
483
484
485
486
  
  		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);
  		}
  	}
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
487
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
488
489
490
  }
  
  /**
97cc1025b   Steven Whitehouse   GFS2: Kill two da...
491
492
493
494
495
496
497
498
499
500
   * trans_go_demote_ok
   * @gl: the glock
   *
   * Always returns 0
   */
  
  static int trans_go_demote_ok(const struct gfs2_glock *gl)
  {
  	return 0;
  }
b94a170e9   Benjamin Marzinski   GFS2: remove dcac...
501
502
503
504
505
506
507
508
509
  /**
   * iopen_go_callback - schedule the dcache entry for the inode to be deleted
   * @gl: the glock
   *
   * gl_spin lock is held while calling this
   */
  static void iopen_go_callback(struct gfs2_glock *gl)
  {
  	struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
001e8e8df   Steven Whitehouse   GFS2: Don't try t...
510
511
512
513
  	struct gfs2_sbd *sdp = gl->gl_sbd;
  
  	if (sdp->sd_vfs->s_flags & MS_RDONLY)
  		return;
b94a170e9   Benjamin Marzinski   GFS2: remove dcac...
514
515
  
  	if (gl->gl_demote_state == LM_ST_UNLOCKED &&
009d85183   Steven Whitehouse   GFS2: Metadata ad...
516
  	    gl->gl_state == LM_ST_SHARED && ip) {
b94a170e9   Benjamin Marzinski   GFS2: remove dcac...
517
518
519
520
521
  		gfs2_glock_hold(gl);
  		if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0)
  			gfs2_glock_put_nolock(gl);
  	}
  }
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
522
  const struct gfs2_glock_operations gfs2_meta_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
523
  	.go_type = LM_TYPE_META,
b3b94faa5   David Teigland   [GFS2] The core o...
524
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
525
  const struct gfs2_glock_operations gfs2_inode_glops = {
3042a2ccd   Steven Whitehouse   [GFS2] Reorder wr...
526
  	.go_xmote_th = inode_go_sync,
b3b94faa5   David Teigland   [GFS2] The core o...
527
528
529
  	.go_inval = inode_go_inval,
  	.go_demote_ok = inode_go_demote_ok,
  	.go_lock = inode_go_lock,
6802e3400   Steven Whitehouse   [GFS2] Clean up t...
530
  	.go_dump = inode_go_dump,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
531
  	.go_type = LM_TYPE_INODE,
009d85183   Steven Whitehouse   GFS2: Metadata ad...
532
  	.go_flags = GLOF_ASPACE,
b3b94faa5   David Teigland   [GFS2] The core o...
533
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
534
  const struct gfs2_glock_operations gfs2_rgrp_glops = {
6bac243f0   Steven Whitehouse   GFS2: Clean up of...
535
536
  	.go_xmote_th = rgrp_go_sync,
  	.go_inval = rgrp_go_inval,
7c9ca6211   Bob Peterson   GFS2: Use rbtree ...
537
538
  	.go_lock = gfs2_rgrp_go_lock,
  	.go_unlock = gfs2_rgrp_go_unlock,
090109783   Steven Whitehouse   GFS2: Improve res...
539
  	.go_dump = gfs2_rgrp_dump,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
540
  	.go_type = LM_TYPE_RGRP,
009d85183   Steven Whitehouse   GFS2: Metadata ad...
541
  	.go_flags = GLOF_ASPACE,
b3b94faa5   David Teigland   [GFS2] The core o...
542
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
543
  const struct gfs2_glock_operations gfs2_trans_glops = {
3042a2ccd   Steven Whitehouse   [GFS2] Reorder wr...
544
  	.go_xmote_th = trans_go_sync,
b3b94faa5   David Teigland   [GFS2] The core o...
545
  	.go_xmote_bh = trans_go_xmote_bh,
97cc1025b   Steven Whitehouse   GFS2: Kill two da...
546
  	.go_demote_ok = trans_go_demote_ok,
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
547
  	.go_type = LM_TYPE_NONDISK,
b3b94faa5   David Teigland   [GFS2] The core o...
548
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
549
  const struct gfs2_glock_operations gfs2_iopen_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
550
  	.go_type = LM_TYPE_IOPEN,
b94a170e9   Benjamin Marzinski   GFS2: remove dcac...
551
  	.go_callback = iopen_go_callback,
b3b94faa5   David Teigland   [GFS2] The core o...
552
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
553
  const struct gfs2_glock_operations gfs2_flock_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
554
  	.go_type = LM_TYPE_FLOCK,
b3b94faa5   David Teigland   [GFS2] The core o...
555
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
556
  const struct gfs2_glock_operations gfs2_nondisk_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
557
  	.go_type = LM_TYPE_NONDISK,
b3b94faa5   David Teigland   [GFS2] The core o...
558
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
559
  const struct gfs2_glock_operations gfs2_quota_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
560
  	.go_type = LM_TYPE_QUOTA,
b3b94faa5   David Teigland   [GFS2] The core o...
561
  };
8fb4b536e   Steven Whitehouse   [GFS2] Make glock...
562
  const struct gfs2_glock_operations gfs2_journal_glops = {
ea67eedb2   Steven Whitehouse   [GFS2] Fix end of...
563
  	.go_type = LM_TYPE_JOURNAL,
b3b94faa5   David Teigland   [GFS2] The core o...
564
  };
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
565
566
567
568
  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,
64d576ba2   Steven Whitehouse   GFS2: Add a "demo...
569
570
571
572
573
574
  	[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,
  };