Blame view
fs/gfs2/glops.c
16.2 KB
b3b94faa5 [GFS2] The core o... |
1 2 |
/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
cf45b752c [GFS2] Remove rgr... |
3 |
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
b3b94faa5 [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 [GFS2] Update cop... |
7 |
* of the GNU General Public License version 2. |
b3b94faa5 [GFS2] The core o... |
8 |
*/ |
b3b94faa5 [GFS2] The core o... |
9 10 11 |
#include <linux/spinlock.h> #include <linux/completion.h> #include <linux/buffer_head.h> |
5c676f6d3 [GFS2] Macros rem... |
12 |
#include <linux/gfs2_ondisk.h> |
6802e3400 [GFS2] Clean up t... |
13 |
#include <linux/bio.h> |
c65f7fb53 GFS2: Use forget_... |
14 |
#include <linux/posix_acl.h> |
f39814f60 gfs2: Invalid sec... |
15 |
#include <linux/security.h> |
b3b94faa5 [GFS2] The core o... |
16 17 |
#include "gfs2.h" |
5c676f6d3 [GFS2] Macros rem... |
18 |
#include "incore.h" |
b3b94faa5 [GFS2] The core o... |
19 20 21 22 23 24 |
#include "bmap.h" #include "glock.h" #include "glops.h" #include "inode.h" #include "log.h" #include "meta_io.h" |
b3b94faa5 [GFS2] The core o... |
25 26 |
#include "recovery.h" #include "rgrp.h" |
5c676f6d3 [GFS2] Macros rem... |
27 |
#include "util.h" |
ddacfaf76 [GFS2] Move loggi... |
28 |
#include "trans.h" |
17d539f04 GFS2: Cache dir h... |
29 |
#include "dir.h" |
b3b94faa5 [GFS2] The core o... |
30 |
|
2e60d7683 GFS2: update free... |
31 |
struct workqueue_struct *gfs2_freeze_wq; |
75549186e GFS2: Fix bug-tra... |
32 33 |
static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh) { |
15562c439 GFS2: Move glock ... |
34 35 36 37 |
fs_err(gl->gl_name.ln_sbd, "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page " "state 0x%lx ", |
75549186e GFS2: Fix bug-tra... |
38 39 |
bh, (unsigned long long)bh->b_blocknr, bh->b_state, bh->b_page->mapping, bh->b_page->flags); |
15562c439 GFS2: Move glock ... |
40 41 |
fs_err(gl->gl_name.ln_sbd, "AIL glock %u:%llu mapping %p ", |
75549186e GFS2: Fix bug-tra... |
42 43 |
gl->gl_name.ln_type, gl->gl_name.ln_number, gfs2_glock2aspace(gl)); |
15562c439 GFS2: Move glock ... |
44 45 |
gfs2_lm_withdraw(gl->gl_name.ln_sbd, "AIL error "); |
75549186e GFS2: Fix bug-tra... |
46 |
} |
ddacfaf76 [GFS2] Move loggi... |
47 |
/** |
dba898b02 GFS2: Clean up fs... |
48 |
* __gfs2_ail_flush - remove all buffers for a given lock from the AIL |
ddacfaf76 [GFS2] Move loggi... |
49 |
* @gl: the glock |
b5b24d7ae GFS2: Fix AIL flu... |
50 |
* @fsync: set when called from fsync (not all buffers will be clean) |
ddacfaf76 [GFS2] Move loggi... |
51 52 53 |
* * None of the buffers should be dirty, locked, or pinned. */ |
1bc333f4c GFS2: don't overr... |
54 55 |
static void __gfs2_ail_flush(struct gfs2_glock *gl, bool fsync, unsigned int nr_revokes) |
ddacfaf76 [GFS2] Move loggi... |
56 |
{ |
15562c439 GFS2: Move glock ... |
57 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
ddacfaf76 [GFS2] Move loggi... |
58 |
struct list_head *head = &gl->gl_ail_list; |
b5b24d7ae GFS2: Fix AIL flu... |
59 |
struct gfs2_bufdata *bd, *tmp; |
ddacfaf76 [GFS2] Move loggi... |
60 |
struct buffer_head *bh; |
b5b24d7ae GFS2: Fix AIL flu... |
61 |
const unsigned long b_state = (1UL << BH_Dirty)|(1UL << BH_Pinned)|(1UL << BH_Lock); |
d8348de06 GFS2: Fix deadloc... |
62 |
|
b5b24d7ae GFS2: Fix AIL flu... |
63 |
gfs2_log_lock(sdp); |
d6a079e82 GFS2: introduce A... |
64 |
spin_lock(&sdp->sd_ail_lock); |
1bc333f4c GFS2: don't overr... |
65 66 67 |
list_for_each_entry_safe_reverse(bd, tmp, head, bd_ail_gl_list) { if (nr_revokes == 0) break; |
ddacfaf76 [GFS2] Move loggi... |
68 |
bh = bd->bd_bh; |
b5b24d7ae GFS2: Fix AIL flu... |
69 70 71 |
if (bh->b_state & b_state) { if (fsync) continue; |
75549186e GFS2: Fix bug-tra... |
72 |
gfs2_ail_error(gl, bh); |
b5b24d7ae GFS2: Fix AIL flu... |
73 |
} |
1ad38c437 [GFS2] Clean up g... |
74 |
gfs2_trans_add_revoke(sdp, bd); |
1bc333f4c GFS2: don't overr... |
75 |
nr_revokes--; |
ddacfaf76 [GFS2] Move loggi... |
76 |
} |
8eae1ca00 GFS2: Review bug ... |
77 |
GLOCK_BUG_ON(gl, !fsync && atomic_read(&gl->gl_ail_count)); |
d6a079e82 GFS2: introduce A... |
78 |
spin_unlock(&sdp->sd_ail_lock); |
b5b24d7ae GFS2: Fix AIL flu... |
79 |
gfs2_log_unlock(sdp); |
dba898b02 GFS2: Clean up fs... |
80 81 82 83 84 |
} static void gfs2_ail_empty_gl(struct gfs2_glock *gl) { |
15562c439 GFS2: Move glock ... |
85 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
dba898b02 GFS2: Clean up fs... |
86 87 88 |
struct gfs2_trans tr; memset(&tr, 0, sizeof(tr)); |
d69a3c656 GFS2: Move log bu... |
89 90 |
INIT_LIST_HEAD(&tr.tr_buf); INIT_LIST_HEAD(&tr.tr_databuf); |
dba898b02 GFS2: Clean up fs... |
91 92 93 94 |
tr.tr_revokes = atomic_read(&gl->gl_ail_count); if (!tr.tr_revokes) return; |
24972557b GFS2: remove tran... |
95 96 97 |
/* A shortened, inline version of gfs2_trans_begin() * tr->alloced is not set since the transaction structure is * on the stack */ |
dba898b02 GFS2: Clean up fs... |
98 |
tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64)); |
d29c0afe4 GFS2: use _RET_IP... |
99 |
tr.tr_ip = _RET_IP_; |
2e60d7683 GFS2: update free... |
100 |
if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) |
24972557b GFS2: remove tran... |
101 |
return; |
8eae1ca00 GFS2: Review bug ... |
102 |
WARN_ON_ONCE(current->journal_info); |
dba898b02 GFS2: Clean up fs... |
103 |
current->journal_info = &tr; |
1bc333f4c GFS2: don't overr... |
104 |
__gfs2_ail_flush(gl, 0, tr.tr_revokes); |
dba898b02 GFS2: Clean up fs... |
105 106 |
gfs2_trans_end(sdp); |
24972557b GFS2: remove tran... |
107 |
gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
dba898b02 GFS2: Clean up fs... |
108 |
} |
ddacfaf76 [GFS2] Move loggi... |
109 |
|
b5b24d7ae GFS2: Fix AIL flu... |
110 |
void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) |
dba898b02 GFS2: Clean up fs... |
111 |
{ |
15562c439 GFS2: Move glock ... |
112 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
dba898b02 GFS2: Clean up fs... |
113 |
unsigned int revokes = atomic_read(&gl->gl_ail_count); |
1bc333f4c GFS2: don't overr... |
114 |
unsigned int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); |
dba898b02 GFS2: Clean up fs... |
115 116 117 118 |
int ret; if (!revokes) return; |
1bc333f4c GFS2: don't overr... |
119 120 121 122 |
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); |
dba898b02 GFS2: Clean up fs... |
123 124 |
if (ret) return; |
1bc333f4c GFS2: don't overr... |
125 |
__gfs2_ail_flush(gl, fsync, max_revokes); |
ddacfaf76 [GFS2] Move loggi... |
126 |
gfs2_trans_end(sdp); |
24972557b GFS2: remove tran... |
127 |
gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); |
ddacfaf76 [GFS2] Move loggi... |
128 |
} |
ba7f72901 [GFS2] Remove pag... |
129 130 |
/** |
6bac243f0 GFS2: Clean up of... |
131 |
* rgrp_go_sync - sync out the metadata for this glock |
b3b94faa5 [GFS2] The core o... |
132 |
* @gl: the glock |
b3b94faa5 [GFS2] The core o... |
133 134 135 136 137 |
* * 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 GFS2: Clean up of... |
138 |
static void rgrp_go_sync(struct gfs2_glock *gl) |
b3b94faa5 [GFS2] The core o... |
139 |
{ |
15562c439 GFS2: Move glock ... |
140 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
70d4ee94b GFS2: Use only a ... |
141 |
struct address_space *mapping = &sdp->sd_aspace; |
8339ee543 GFS2: Make resour... |
142 |
struct gfs2_rgrpd *rgd; |
6bac243f0 GFS2: Clean up of... |
143 |
int error; |
f3dd16491 gfs2: Remove gl_s... |
144 |
spin_lock(&gl->gl_lockref.lock); |
39b0f1e92 GFS2: Don't brels... |
145 146 147 |
rgd = gl->gl_object; if (rgd) gfs2_rgrp_brelse(rgd); |
f3dd16491 gfs2: Remove gl_s... |
148 |
spin_unlock(&gl->gl_lockref.lock); |
39b0f1e92 GFS2: Don't brels... |
149 |
|
6bac243f0 GFS2: Clean up of... |
150 |
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) |
b5d32bead [GFS2] Tidy up gl... |
151 |
return; |
8eae1ca00 GFS2: Review bug ... |
152 |
GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); |
b5d32bead [GFS2] Tidy up gl... |
153 |
|
24972557b GFS2: remove tran... |
154 |
gfs2_log_flush(sdp, gl, NORMAL_FLUSH); |
70d4ee94b GFS2: Use only a ... |
155 156 157 |
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); |
6bac243f0 GFS2: Clean up of... |
158 |
gfs2_ail_empty_gl(gl); |
7c9ca6211 GFS2: Use rbtree ... |
159 |
|
f3dd16491 gfs2: Remove gl_s... |
160 |
spin_lock(&gl->gl_lockref.lock); |
8339ee543 GFS2: Make resour... |
161 162 163 |
rgd = gl->gl_object; if (rgd) gfs2_free_clones(rgd); |
f3dd16491 gfs2: Remove gl_s... |
164 |
spin_unlock(&gl->gl_lockref.lock); |
b3b94faa5 [GFS2] The core o... |
165 166 167 |
} /** |
6bac243f0 GFS2: Clean up of... |
168 |
* rgrp_go_inval - invalidate the metadata for this glock |
b3b94faa5 [GFS2] The core o... |
169 170 171 |
* @gl: the glock * @flags: * |
6bac243f0 GFS2: Clean up of... |
172 173 174 |
* We never used LM_ST_DEFERRED with resource groups, so that we * should always see the metadata flag set here. * |
b3b94faa5 [GFS2] The core o... |
175 |
*/ |
6bac243f0 GFS2: Clean up of... |
176 |
static void rgrp_go_inval(struct gfs2_glock *gl, int flags) |
b3b94faa5 [GFS2] The core o... |
177 |
{ |
15562c439 GFS2: Move glock ... |
178 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
70d4ee94b GFS2: Use only a ... |
179 |
struct address_space *mapping = &sdp->sd_aspace; |
39b0f1e92 GFS2: Don't brels... |
180 181 182 183 |
struct gfs2_rgrpd *rgd = gl->gl_object; if (rgd) gfs2_rgrp_brelse(rgd); |
b3b94faa5 [GFS2] The core o... |
184 |
|
8eae1ca00 GFS2: Review bug ... |
185 |
WARN_ON_ONCE(!(flags & DIO_METADATA)); |
70d4ee94b GFS2: Use only a ... |
186 |
gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
7005c3e4a GFS2: Use range b... |
187 |
truncate_inode_pages_range(mapping, gl->gl_vm.start, gl->gl_vm.end); |
cf45b752c [GFS2] Remove rgr... |
188 |
|
39b0f1e92 GFS2: Don't brels... |
189 |
if (rgd) |
cf45b752c [GFS2] Remove rgr... |
190 |
rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
b3b94faa5 [GFS2] The core o... |
191 192 193 |
} /** |
b5d32bead [GFS2] Tidy up gl... |
194 195 196 197 198 199 200 201 |
* 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 GFS2: Metadata ad... |
202 |
struct address_space *metamapping = gfs2_glock2aspace(gl); |
3042a2ccd [GFS2] Reorder wr... |
203 |
int error; |
b5d32bead [GFS2] Tidy up gl... |
204 205 |
if (ip && !S_ISREG(ip->i_inode.i_mode)) ip = NULL; |
582d2f7ae GFS2: Wait for as... |
206 207 208 209 210 |
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); } |
6bac243f0 GFS2: Clean up of... |
211 212 |
if (!test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) return; |
b5d32bead [GFS2] Tidy up gl... |
213 |
|
8eae1ca00 GFS2: Review bug ... |
214 |
GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); |
6bac243f0 GFS2: Clean up of... |
215 |
|
15562c439 GFS2: Move glock ... |
216 |
gfs2_log_flush(gl->gl_name.ln_sbd, gl, NORMAL_FLUSH); |
6bac243f0 GFS2: Clean up of... |
217 218 219 220 221 222 |
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 [GFS2] Tidy up gl... |
223 |
} |
6bac243f0 GFS2: Clean up of... |
224 225 226 |
error = filemap_fdatawait(metamapping); mapping_set_error(metamapping, error); gfs2_ail_empty_gl(gl); |
52fcd11c0 GFS2: Clear dirty... |
227 228 229 230 |
/* * Writeback of the data mapping may cause the dirty flag to be set * so we have to clear it again here. */ |
4e857c58e arch: Mass conver... |
231 |
smp_mb__before_atomic(); |
52fcd11c0 GFS2: Clear dirty... |
232 |
clear_bit(GLF_DIRTY, &gl->gl_flags); |
b5d32bead [GFS2] Tidy up gl... |
233 234 235 |
} /** |
b3b94faa5 [GFS2] The core o... |
236 237 238 |
* inode_go_inval - prepare a inode glock to be released * @gl: the glock * @flags: |
6b49d1d9c GFS2: memcontrol:... |
239 240 |
* * Normally we invalidate everything, but if we are moving into |
6bac243f0 GFS2: Clean up of... |
241 242 |
* 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 [GFS2] The core o... |
243 244 245 246 247 |
* */ static void inode_go_inval(struct gfs2_glock *gl, int flags) { |
b004157ab [GFS2] Fix journa... |
248 |
struct gfs2_inode *ip = gl->gl_object; |
b3b94faa5 [GFS2] The core o... |
249 |
|
15562c439 GFS2: Move glock ... |
250 |
gfs2_assert_withdraw(gl->gl_name.ln_sbd, !atomic_read(&gl->gl_ail_count)); |
6bac243f0 GFS2: Clean up of... |
251 252 |
if (flags & DIO_METADATA) { |
009d85183 GFS2: Metadata ad... |
253 |
struct address_space *mapping = gfs2_glock2aspace(gl); |
6bac243f0 GFS2: Clean up of... |
254 |
truncate_inode_pages(mapping, 0); |
c65f7fb53 GFS2: Use forget_... |
255 |
if (ip) { |
b004157ab [GFS2] Fix journa... |
256 |
set_bit(GIF_INVALID, &ip->i_flags); |
c65f7fb53 GFS2: Use forget_... |
257 |
forget_all_cached_acls(&ip->i_inode); |
f39814f60 gfs2: Invalid sec... |
258 |
security_inode_invalidate_secctx(&ip->i_inode); |
17d539f04 GFS2: Cache dir h... |
259 |
gfs2_dir_hash_inval(ip); |
c65f7fb53 GFS2: Use forget_... |
260 |
} |
b004157ab [GFS2] Fix journa... |
261 |
} |
15562c439 GFS2: Move glock ... |
262 263 264 |
if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) { gfs2_log_flush(gl->gl_name.ln_sbd, NULL, NORMAL_FLUSH); gl->gl_name.ln_sbd->sd_rindex_uptodate = 0; |
1ce533686 GFS2: force a log... |
265 |
} |
3cc3f710c [GFS2] Use ->page... |
266 |
if (ip && S_ISREG(ip->i_inode.i_mode)) |
b004157ab [GFS2] Fix journa... |
267 |
truncate_inode_pages(ip->i_inode.i_mapping, 0); |
b3b94faa5 [GFS2] The core o... |
268 269 270 271 272 273 274 275 |
} /** * 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 GFS2: Kill two da... |
276 |
static int inode_go_demote_ok(const struct gfs2_glock *gl) |
b3b94faa5 [GFS2] The core o... |
277 |
{ |
15562c439 GFS2: Move glock ... |
278 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
bc015cb84 GFS2: Use RCU for... |
279 |
|
97cc1025b GFS2: Kill two da... |
280 281 |
if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) return 0; |
bc015cb84 GFS2: Use RCU for... |
282 |
|
97cc1025b GFS2: Kill two da... |
283 |
return 1; |
b3b94faa5 [GFS2] The core o... |
284 285 286 |
} /** |
d4b2cf1b0 GFS2: Move gfs2_r... |
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
* 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 filesystems: add ... |
308 |
set_nlink(inode, nlink); |
d4b2cf1b0 GFS2: Move gfs2_r... |
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
} } 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; }; |
d05464264 gfs2: Convert uid... |
330 331 |
i_uid_write(&ip->i_inode, be32_to_cpu(str->di_uid)); i_gid_write(&ip->i_inode, be32_to_cpu(str->di_gid)); |
d4b2cf1b0 GFS2: Move gfs2_r... |
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
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 GFS2: Add S_NOSEC... |
348 349 |
ip->i_eattr = be64_to_cpu(str->di_eattr); /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ |
d4b2cf1b0 GFS2: Move gfs2_r... |
350 351 352 353 354 355 356 357 358 359 360 |
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 GFS2: Move gfs2_r... |
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; |
d4b2cf1b0 GFS2: Move gfs2_r... |
385 386 387 388 389 390 391 392 |
error = gfs2_dinode_in(ip, dibh->b_data); brelse(dibh); clear_bit(GIF_INVALID, &ip->i_flags); return error; } /** |
b3b94faa5 [GFS2] The core o... |
393 394 395 396 397 398 399 400 401 402 |
* 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; |
15562c439 GFS2: Move glock ... |
403 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
5c676f6d3 [GFS2] Macros rem... |
404 |
struct gfs2_inode *ip = gl->gl_object; |
b3b94faa5 [GFS2] The core o... |
405 |
int error = 0; |
091806edd [GFS2] filesystem... |
406 |
if (!ip || (gh->gh_flags & GL_SKIP)) |
b3b94faa5 [GFS2] The core o... |
407 |
return 0; |
bfded27ba [GFS2] Shrink gfs... |
408 |
if (test_bit(GIF_INVALID, &ip->i_flags)) { |
b3b94faa5 [GFS2] The core o... |
409 410 411 |
error = gfs2_inode_refresh(ip); if (error) return error; |
b3b94faa5 [GFS2] The core o... |
412 |
} |
582d2f7ae GFS2: Wait for as... |
413 414 |
if (gh->gh_state != LM_ST_DEFERRED) inode_dio_wait(&ip->i_inode); |
383f01fbf GFS2: Banish stru... |
415 |
if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && |
b3b94faa5 [GFS2] The core o... |
416 |
(gl->gl_state == LM_ST_EXCLUSIVE) && |
813e0c46c GFS2: Fix "trunca... |
417 418 419 420 421 422 423 424 |
(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 [GFS2] The core o... |
425 426 427 428 429 |
return error; } /** |
6802e3400 [GFS2] Clean up t... |
430 431 432 433 |
* inode_go_dump - print information about an inode * @seq: The iterator * @ip: the inode * |
6802e3400 [GFS2] Clean up t... |
434 |
*/ |
ac3beb6a5 GFS2: Don't use E... |
435 |
static void inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) |
6802e3400 [GFS2] Clean up t... |
436 437 438 |
{ const struct gfs2_inode *ip = gl->gl_object; if (ip == NULL) |
ac3beb6a5 GFS2: Don't use E... |
439 |
return; |
a2e0f7993 GFS2: Remove i_di... |
440 441 |
gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu ", |
6802e3400 [GFS2] Clean up t... |
442 443 |
(unsigned long long)ip->i_no_formal_ino, (unsigned long long)ip->i_no_addr, |
fa75cedc3 GFS2: Add more de... |
444 445 |
IF2DT(ip->i_inode.i_mode), ip->i_flags, (unsigned int)ip->i_diskflags, |
a2e0f7993 GFS2: Remove i_di... |
446 |
(unsigned long long)i_size_read(&ip->i_inode)); |
6802e3400 [GFS2] Clean up t... |
447 448 449 |
} /** |
24972557b GFS2: remove tran... |
450 |
* freeze_go_sync - promote/demote the freeze glock |
b3b94faa5 [GFS2] The core o... |
451 452 453 454 455 |
* @gl: the glock * @state: the requested state * @flags: * */ |
24972557b GFS2: remove tran... |
456 |
static void freeze_go_sync(struct gfs2_glock *gl) |
b3b94faa5 [GFS2] The core o... |
457 |
{ |
2e60d7683 GFS2: update free... |
458 |
int error = 0; |
15562c439 GFS2: Move glock ... |
459 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
b3b94faa5 [GFS2] The core o... |
460 |
|
24972557b GFS2: remove tran... |
461 |
if (gl->gl_state == LM_ST_SHARED && |
b3b94faa5 [GFS2] The core o... |
462 |
test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
2e60d7683 GFS2: update free... |
463 464 465 466 467 468 469 470 471 |
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 ", error); gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); gfs2_log_flush(sdp, NULL, FREEZE_FLUSH); |
b3b94faa5 [GFS2] The core o... |
472 |
} |
b3b94faa5 [GFS2] The core o... |
473 474 475 |
} /** |
24972557b GFS2: remove tran... |
476 |
* freeze_go_xmote_bh - After promoting/demoting the freeze glock |
b3b94faa5 [GFS2] The core o... |
477 478 479 |
* @gl: the glock * */ |
24972557b GFS2: remove tran... |
480 |
static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) |
b3b94faa5 [GFS2] The core o... |
481 |
{ |
15562c439 GFS2: Move glock ... |
482 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
feaa7bba0 [GFS2] Fix unlink... |
483 |
struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
5c676f6d3 [GFS2] Macros rem... |
484 |
struct gfs2_glock *j_gl = ip->i_gl; |
551676226 [GFS2] split and ... |
485 |
struct gfs2_log_header_host head; |
b3b94faa5 [GFS2] The core o... |
486 |
int error; |
6802e3400 [GFS2] Clean up t... |
487 |
if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
1a14d3a68 [GFS2] Simplify g... |
488 |
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
b3b94faa5 [GFS2] The core o... |
489 490 491 492 493 494 495 496 497 498 499 500 501 |
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 [GFS2] Clean up t... |
502 |
return 0; |
b3b94faa5 [GFS2] The core o... |
503 504 505 |
} /** |
97cc1025b GFS2: Kill two da... |
506 507 508 509 510 |
* trans_go_demote_ok * @gl: the glock * * Always returns 0 */ |
24972557b GFS2: remove tran... |
511 |
static int freeze_go_demote_ok(const struct gfs2_glock *gl) |
97cc1025b GFS2: Kill two da... |
512 513 514 |
{ return 0; } |
b94a170e9 GFS2: remove dcac... |
515 516 517 518 |
/** * iopen_go_callback - schedule the dcache entry for the inode to be deleted * @gl: the glock * |
f3dd16491 gfs2: Remove gl_s... |
519 |
* gl_lockref.lock lock is held while calling this |
b94a170e9 GFS2: remove dcac... |
520 |
*/ |
81ffbf654 GFS2: Add origin ... |
521 |
static void iopen_go_callback(struct gfs2_glock *gl, bool remote) |
b94a170e9 GFS2: remove dcac... |
522 523 |
{ struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; |
15562c439 GFS2: Move glock ... |
524 |
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
001e8e8df GFS2: Don't try t... |
525 |
|
81ffbf654 GFS2: Add origin ... |
526 |
if (!remote || (sdp->sd_vfs->s_flags & MS_RDONLY)) |
001e8e8df GFS2: Don't try t... |
527 |
return; |
b94a170e9 GFS2: remove dcac... |
528 529 |
if (gl->gl_demote_state == LM_ST_UNLOCKED && |
009d85183 GFS2: Metadata ad... |
530 |
gl->gl_state == LM_ST_SHARED && ip) { |
e66cf1610 GFS2: Use lockref... |
531 |
gl->gl_lockref.count++; |
b94a170e9 GFS2: remove dcac... |
532 |
if (queue_work(gfs2_delete_workqueue, &gl->gl_delete) == 0) |
e66cf1610 GFS2: Use lockref... |
533 |
gl->gl_lockref.count--; |
b94a170e9 GFS2: remove dcac... |
534 535 |
} } |
8fb4b536e [GFS2] Make glock... |
536 |
const struct gfs2_glock_operations gfs2_meta_glops = { |
ea67eedb2 [GFS2] Fix end of... |
537 |
.go_type = LM_TYPE_META, |
b3b94faa5 [GFS2] The core o... |
538 |
}; |
8fb4b536e [GFS2] Make glock... |
539 |
const struct gfs2_glock_operations gfs2_inode_glops = { |
06dfc3064 GFS2: Rename glop... |
540 |
.go_sync = inode_go_sync, |
b3b94faa5 [GFS2] The core o... |
541 542 543 |
.go_inval = inode_go_inval, .go_demote_ok = inode_go_demote_ok, .go_lock = inode_go_lock, |
6802e3400 [GFS2] Clean up t... |
544 |
.go_dump = inode_go_dump, |
ea67eedb2 [GFS2] Fix end of... |
545 |
.go_type = LM_TYPE_INODE, |
e7ccaf5fe GFS2: Don't add a... |
546 |
.go_flags = GLOF_ASPACE | GLOF_LRU, |
b3b94faa5 [GFS2] The core o... |
547 |
}; |
8fb4b536e [GFS2] Make glock... |
548 |
const struct gfs2_glock_operations gfs2_rgrp_glops = { |
06dfc3064 GFS2: Rename glop... |
549 |
.go_sync = rgrp_go_sync, |
6bac243f0 GFS2: Clean up of... |
550 |
.go_inval = rgrp_go_inval, |
7c9ca6211 GFS2: Use rbtree ... |
551 552 |
.go_lock = gfs2_rgrp_go_lock, .go_unlock = gfs2_rgrp_go_unlock, |
090109783 GFS2: Improve res... |
553 |
.go_dump = gfs2_rgrp_dump, |
ea67eedb2 [GFS2] Fix end of... |
554 |
.go_type = LM_TYPE_RGRP, |
70d4ee94b GFS2: Use only a ... |
555 |
.go_flags = GLOF_LVB, |
b3b94faa5 [GFS2] The core o... |
556 |
}; |
24972557b GFS2: remove tran... |
557 558 559 560 |
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, |
ea67eedb2 [GFS2] Fix end of... |
561 |
.go_type = LM_TYPE_NONDISK, |
b3b94faa5 [GFS2] The core o... |
562 |
}; |
8fb4b536e [GFS2] Make glock... |
563 |
const struct gfs2_glock_operations gfs2_iopen_glops = { |
ea67eedb2 [GFS2] Fix end of... |
564 |
.go_type = LM_TYPE_IOPEN, |
b94a170e9 GFS2: remove dcac... |
565 |
.go_callback = iopen_go_callback, |
e7ccaf5fe GFS2: Don't add a... |
566 |
.go_flags = GLOF_LRU, |
b3b94faa5 [GFS2] The core o... |
567 |
}; |
8fb4b536e [GFS2] Make glock... |
568 |
const struct gfs2_glock_operations gfs2_flock_glops = { |
ea67eedb2 [GFS2] Fix end of... |
569 |
.go_type = LM_TYPE_FLOCK, |
e7ccaf5fe GFS2: Don't add a... |
570 |
.go_flags = GLOF_LRU, |
b3b94faa5 [GFS2] The core o... |
571 |
}; |
8fb4b536e [GFS2] Make glock... |
572 |
const struct gfs2_glock_operations gfs2_nondisk_glops = { |
ea67eedb2 [GFS2] Fix end of... |
573 |
.go_type = LM_TYPE_NONDISK, |
b3b94faa5 [GFS2] The core o... |
574 |
}; |
8fb4b536e [GFS2] Make glock... |
575 |
const struct gfs2_glock_operations gfs2_quota_glops = { |
ea67eedb2 [GFS2] Fix end of... |
576 |
.go_type = LM_TYPE_QUOTA, |
e7ccaf5fe GFS2: Don't add a... |
577 |
.go_flags = GLOF_LVB | GLOF_LRU, |
b3b94faa5 [GFS2] The core o... |
578 |
}; |
8fb4b536e [GFS2] Make glock... |
579 |
const struct gfs2_glock_operations gfs2_journal_glops = { |
ea67eedb2 [GFS2] Fix end of... |
580 |
.go_type = LM_TYPE_JOURNAL, |
b3b94faa5 [GFS2] The core o... |
581 |
}; |
64d576ba2 GFS2: Add a "demo... |
582 583 584 585 |
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 GFS2: Add a "demo... |
586 587 588 589 590 591 |
[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, }; |