aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glops.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/gfs2/glops.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r--fs/gfs2/glops.c214
1 files changed, 178 insertions, 36 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 49f97d3bb690..2cca29316bd6 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -28,18 +28,45 @@
28#include "trans.h" 28#include "trans.h"
29 29
30/** 30/**
31 * ail_empty_gl - remove all buffers for a given lock from the AIL 31 * __gfs2_ail_flush - remove all buffers for a given lock from the AIL
32 * @gl: the glock 32 * @gl: the glock
33 * 33 *
34 * None of the buffers should be dirty, locked, or pinned. 34 * None of the buffers should be dirty, locked, or pinned.
35 */ 35 */
36 36
37static void gfs2_ail_empty_gl(struct gfs2_glock *gl) 37static void __gfs2_ail_flush(struct gfs2_glock *gl)
38{ 38{
39 struct gfs2_sbd *sdp = gl->gl_sbd; 39 struct gfs2_sbd *sdp = gl->gl_sbd;
40 struct list_head *head = &gl->gl_ail_list; 40 struct list_head *head = &gl->gl_ail_list;
41 struct gfs2_bufdata *bd; 41 struct gfs2_bufdata *bd;
42 struct buffer_head *bh; 42 struct buffer_head *bh;
43
44 spin_lock(&sdp->sd_ail_lock);
45 while (!list_empty(head)) {
46 bd = list_entry(head->next, struct gfs2_bufdata,
47 bd_ail_gl_list);
48 bh = bd->bd_bh;
49 gfs2_remove_from_ail(bd);
50 bd->bd_bh = NULL;
51 bh->b_private = NULL;
52 spin_unlock(&sdp->sd_ail_lock);
53
54 bd->bd_blkno = bh->b_blocknr;
55 gfs2_log_lock(sdp);
56 gfs2_assert_withdraw(sdp, !buffer_busy(bh));
57 gfs2_trans_add_revoke(sdp, bd);
58 gfs2_log_unlock(sdp);
59
60 spin_lock(&sdp->sd_ail_lock);
61 }
62 gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
63 spin_unlock(&sdp->sd_ail_lock);
64}
65
66
67static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
68{
69 struct gfs2_sbd *sdp = gl->gl_sbd;
43 struct gfs2_trans tr; 70 struct gfs2_trans tr;
44 71
45 memset(&tr, 0, sizeof(tr)); 72 memset(&tr, 0, sizeof(tr));
@@ -56,25 +83,29 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl)
56 BUG_ON(current->journal_info); 83 BUG_ON(current->journal_info);
57 current->journal_info = &tr; 84 current->journal_info = &tr;
58 85
59 gfs2_log_lock(sdp); 86 __gfs2_ail_flush(gl);
60 while (!list_empty(head)) {
61 bd = list_entry(head->next, struct gfs2_bufdata,
62 bd_ail_gl_list);
63 bh = bd->bd_bh;
64 gfs2_remove_from_ail(bd);
65 bd->bd_bh = NULL;
66 bh->b_private = NULL;
67 bd->bd_blkno = bh->b_blocknr;
68 gfs2_assert_withdraw(sdp, !buffer_busy(bh));
69 gfs2_trans_add_revoke(sdp, bd);
70 }
71 gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count));
72 gfs2_log_unlock(sdp);
73 87
74 gfs2_trans_end(sdp); 88 gfs2_trans_end(sdp);
75 gfs2_log_flush(sdp, NULL); 89 gfs2_log_flush(sdp, NULL);
76} 90}
77 91
92void gfs2_ail_flush(struct gfs2_glock *gl)
93{
94 struct gfs2_sbd *sdp = gl->gl_sbd;
95 unsigned int revokes = atomic_read(&gl->gl_ail_count);
96 int ret;
97
98 if (!revokes)
99 return;
100
101 ret = gfs2_trans_begin(sdp, 0, revokes);
102 if (ret)
103 return;
104 __gfs2_ail_flush(gl);
105 gfs2_trans_end(sdp);
106 gfs2_log_flush(sdp, NULL);
107}
108
78/** 109/**
79 * rgrp_go_sync - sync out the metadata for this glock 110 * rgrp_go_sync - sync out the metadata for this glock
80 * @gl: the glock 111 * @gl: the glock
@@ -190,8 +221,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
190 } 221 }
191 } 222 }
192 223
193 if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) 224 if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) {
225 gfs2_log_flush(gl->gl_sbd, NULL);
194 gl->gl_sbd->sd_rindex_uptodate = 0; 226 gl->gl_sbd->sd_rindex_uptodate = 0;
227 }
195 if (ip && S_ISREG(ip->i_inode.i_mode)) 228 if (ip && S_ISREG(ip->i_inode.i_mode))
196 truncate_inode_pages(ip->i_inode.i_mapping, 0); 229 truncate_inode_pages(ip->i_inode.i_mapping, 0);
197} 230}
@@ -206,12 +239,134 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
206static int inode_go_demote_ok(const struct gfs2_glock *gl) 239static int inode_go_demote_ok(const struct gfs2_glock *gl)
207{ 240{
208 struct gfs2_sbd *sdp = gl->gl_sbd; 241 struct gfs2_sbd *sdp = gl->gl_sbd;
242 struct gfs2_holder *gh;
243
209 if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) 244 if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object)
210 return 0; 245 return 0;
246
247 if (!list_empty(&gl->gl_holders)) {
248 gh = list_entry(gl->gl_holders.next, struct gfs2_holder, gh_list);
249 if (gh->gh_list.next != &gl->gl_holders)
250 return 0;
251 }
252
211 return 1; 253 return 1;
212} 254}
213 255
214/** 256/**
257 * gfs2_set_nlink - Set the inode's link count based on on-disk info
258 * @inode: The inode in question
259 * @nlink: The link count
260 *
261 * If the link count has hit zero, it must never be raised, whatever the
262 * on-disk inode might say. When new struct inodes are created the link
263 * count is set to 1, so that we can safely use this test even when reading
264 * in on disk information for the first time.
265 */
266
267static void gfs2_set_nlink(struct inode *inode, u32 nlink)
268{
269 /*
270 * We will need to review setting the nlink count here in the
271 * light of the forthcoming ro bind mount work. This is a reminder
272 * to do that.
273 */
274 if ((inode->i_nlink != nlink) && (inode->i_nlink != 0)) {
275 if (nlink == 0)
276 clear_nlink(inode);
277 else
278 inode->i_nlink = nlink;
279 }
280}
281
282static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
283{
284 const struct gfs2_dinode *str = buf;
285 struct timespec atime;
286 u16 height, depth;
287
288 if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)))
289 goto corrupt;
290 ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino);
291 ip->i_inode.i_mode = be32_to_cpu(str->di_mode);
292 ip->i_inode.i_rdev = 0;
293 switch (ip->i_inode.i_mode & S_IFMT) {
294 case S_IFBLK:
295 case S_IFCHR:
296 ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major),
297 be32_to_cpu(str->di_minor));
298 break;
299 };
300
301 ip->i_inode.i_uid = be32_to_cpu(str->di_uid);
302 ip->i_inode.i_gid = be32_to_cpu(str->di_gid);
303 gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
304 i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
305 gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
306 atime.tv_sec = be64_to_cpu(str->di_atime);
307 atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
308 if (timespec_compare(&ip->i_inode.i_atime, &atime) < 0)
309 ip->i_inode.i_atime = atime;
310 ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime);
311 ip->i_inode.i_mtime.tv_nsec = be32_to_cpu(str->di_mtime_nsec);
312 ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime);
313 ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec);
314
315 ip->i_goal = be64_to_cpu(str->di_goal_meta);
316 ip->i_generation = be64_to_cpu(str->di_generation);
317
318 ip->i_diskflags = be32_to_cpu(str->di_flags);
319 gfs2_set_inode_flags(&ip->i_inode);
320 height = be16_to_cpu(str->di_height);
321 if (unlikely(height > GFS2_MAX_META_HEIGHT))
322 goto corrupt;
323 ip->i_height = (u8)height;
324
325 depth = be16_to_cpu(str->di_depth);
326 if (unlikely(depth > GFS2_DIR_MAX_DEPTH))
327 goto corrupt;
328 ip->i_depth = (u8)depth;
329 ip->i_entries = be32_to_cpu(str->di_entries);
330
331 ip->i_eattr = be64_to_cpu(str->di_eattr);
332 if (S_ISREG(ip->i_inode.i_mode))
333 gfs2_set_aops(&ip->i_inode);
334
335 return 0;
336corrupt:
337 gfs2_consist_inode(ip);
338 return -EIO;
339}
340
341/**
342 * gfs2_inode_refresh - Refresh the incore copy of the dinode
343 * @ip: The GFS2 inode
344 *
345 * Returns: errno
346 */
347
348int gfs2_inode_refresh(struct gfs2_inode *ip)
349{
350 struct buffer_head *dibh;
351 int error;
352
353 error = gfs2_meta_inode_buffer(ip, &dibh);
354 if (error)
355 return error;
356
357 if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), dibh, GFS2_METATYPE_DI)) {
358 brelse(dibh);
359 return -EIO;
360 }
361
362 error = gfs2_dinode_in(ip, dibh->b_data);
363 brelse(dibh);
364 clear_bit(GIF_INVALID, &ip->i_flags);
365
366 return error;
367}
368
369/**
215 * inode_go_lock - operation done after an inode lock is locked by a process 370 * inode_go_lock - operation done after an inode lock is locked by a process
216 * @gl: the glock 371 * @gl: the glock
217 * @flags: 372 * @flags:
@@ -262,30 +417,16 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl)
262 const struct gfs2_inode *ip = gl->gl_object; 417 const struct gfs2_inode *ip = gl->gl_object;
263 if (ip == NULL) 418 if (ip == NULL)
264 return 0; 419 return 0;
265 gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu/%llu\n", 420 gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu\n",
266 (unsigned long long)ip->i_no_formal_ino, 421 (unsigned long long)ip->i_no_formal_ino,
267 (unsigned long long)ip->i_no_addr, 422 (unsigned long long)ip->i_no_addr,
268 IF2DT(ip->i_inode.i_mode), ip->i_flags, 423 IF2DT(ip->i_inode.i_mode), ip->i_flags,
269 (unsigned int)ip->i_diskflags, 424 (unsigned int)ip->i_diskflags,
270 (unsigned long long)ip->i_inode.i_size, 425 (unsigned long long)i_size_read(&ip->i_inode));
271 (unsigned long long)ip->i_disksize);
272 return 0; 426 return 0;
273} 427}
274 428
275/** 429/**
276 * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock
277 * @gl: the glock
278 *
279 * Returns: 1 if it's ok
280 */
281
282static int rgrp_go_demote_ok(const struct gfs2_glock *gl)
283{
284 const struct address_space *mapping = (const struct address_space *)(gl + 1);
285 return !mapping->nrpages;
286}
287
288/**
289 * rgrp_go_lock - operation done after an rgrp lock is locked by 430 * rgrp_go_lock - operation done after an rgrp lock is locked by
290 * a first holder on this node. 431 * a first holder on this node.
291 * @gl: the glock 432 * @gl: the glock
@@ -326,7 +467,6 @@ static void trans_go_sync(struct gfs2_glock *gl)
326 467
327 if (gl->gl_state != LM_ST_UNLOCKED && 468 if (gl->gl_state != LM_ST_UNLOCKED &&
328 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { 469 test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
329 flush_workqueue(gfs2_delete_workqueue);
330 gfs2_meta_syncfs(sdp); 470 gfs2_meta_syncfs(sdp);
331 gfs2_log_shutdown(sdp); 471 gfs2_log_shutdown(sdp);
332 } 472 }
@@ -385,6 +525,10 @@ static int trans_go_demote_ok(const struct gfs2_glock *gl)
385static void iopen_go_callback(struct gfs2_glock *gl) 525static void iopen_go_callback(struct gfs2_glock *gl)
386{ 526{
387 struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; 527 struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object;
528 struct gfs2_sbd *sdp = gl->gl_sbd;
529
530 if (sdp->sd_vfs->s_flags & MS_RDONLY)
531 return;
388 532
389 if (gl->gl_demote_state == LM_ST_UNLOCKED && 533 if (gl->gl_demote_state == LM_ST_UNLOCKED &&
390 gl->gl_state == LM_ST_SHARED && ip) { 534 gl->gl_state == LM_ST_SHARED && ip) {
@@ -412,7 +556,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = {
412const struct gfs2_glock_operations gfs2_rgrp_glops = { 556const struct gfs2_glock_operations gfs2_rgrp_glops = {
413 .go_xmote_th = rgrp_go_sync, 557 .go_xmote_th = rgrp_go_sync,
414 .go_inval = rgrp_go_inval, 558 .go_inval = rgrp_go_inval,
415 .go_demote_ok = rgrp_go_demote_ok,
416 .go_lock = rgrp_go_lock, 559 .go_lock = rgrp_go_lock,
417 .go_unlock = rgrp_go_unlock, 560 .go_unlock = rgrp_go_unlock,
418 .go_dump = gfs2_rgrp_dump, 561 .go_dump = gfs2_rgrp_dump,
@@ -453,7 +596,6 @@ const struct gfs2_glock_operations *gfs2_glops_list[] = {
453 [LM_TYPE_META] = &gfs2_meta_glops, 596 [LM_TYPE_META] = &gfs2_meta_glops,
454 [LM_TYPE_INODE] = &gfs2_inode_glops, 597 [LM_TYPE_INODE] = &gfs2_inode_glops,
455 [LM_TYPE_RGRP] = &gfs2_rgrp_glops, 598 [LM_TYPE_RGRP] = &gfs2_rgrp_glops,
456 [LM_TYPE_NONDISK] = &gfs2_trans_glops,
457 [LM_TYPE_IOPEN] = &gfs2_iopen_glops, 599 [LM_TYPE_IOPEN] = &gfs2_iopen_glops,
458 [LM_TYPE_FLOCK] = &gfs2_flock_glops, 600 [LM_TYPE_FLOCK] = &gfs2_flock_glops,
459 [LM_TYPE_NONDISK] = &gfs2_nondisk_glops, 601 [LM_TYPE_NONDISK] = &gfs2_nondisk_glops,