Blame view
fs/xfs/xfs_buf_item.c
35.1 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
7b7187698 [XFS] Update lice... |
2 3 |
* Copyright (c) 2000-2005 Silicon Graphics, Inc. * All Rights Reserved. |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
7b7187698 [XFS] Update lice... |
5 6 |
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
* published by the Free Software Foundation. * |
7b7187698 [XFS] Update lice... |
9 10 11 12 |
* This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
1da177e4c Linux-2.6.12-rc2 |
13 |
* |
7b7187698 [XFS] Update lice... |
14 15 16 |
* You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1da177e4c Linux-2.6.12-rc2 |
17 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include "xfs.h" |
a844f4510 [XFS] Remove xfs_... |
19 |
#include "xfs_fs.h" |
4fb6e8ade xfs: merge xfs_ag... |
20 |
#include "xfs_format.h" |
239880ef6 xfs: decouple log... |
21 22 |
#include "xfs_log_format.h" #include "xfs_trans_resv.h" |
a844f4510 [XFS] Remove xfs_... |
23 |
#include "xfs_bit.h" |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include "xfs_sb.h" |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include "xfs_mount.h" |
239880ef6 xfs: decouple log... |
26 |
#include "xfs_trans.h" |
a844f4510 [XFS] Remove xfs_... |
27 |
#include "xfs_buf_item.h" |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include "xfs_trans_priv.h" |
1da177e4c Linux-2.6.12-rc2 |
29 |
#include "xfs_error.h" |
0b1b213fc xfs: event tracin... |
30 |
#include "xfs_trace.h" |
239880ef6 xfs: decouple log... |
31 |
#include "xfs_log.h" |
0b80ae6ed xfs: Add infrastr... |
32 |
#include "xfs_inode.h" |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 |
kmem_zone_t *xfs_buf_item_zone; |
7bfa31d8e xfs: give xfs_ite... |
36 37 38 39 |
static inline struct xfs_buf_log_item *BUF_ITEM(struct xfs_log_item *lip) { return container_of(lip, struct xfs_buf_log_item, bli_item); } |
c90821a26 xfs: consume iodo... |
40 |
STATIC void xfs_buf_do_callbacks(struct xfs_buf *bp); |
1da177e4c Linux-2.6.12-rc2 |
41 |
|
166d13688 xfs: return log i... |
42 43 44 45 46 47 48 |
static inline int xfs_buf_log_format_size( struct xfs_buf_log_format *blfp) { return offsetof(struct xfs_buf_log_format, blf_data_map) + (blfp->blf_map_size * sizeof(blfp->blf_data_map[0])); } |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 52 53 54 55 56 57 58 |
/* * This returns the number of log iovecs needed to log the * given buf log item. * * It calculates this as 1 iovec for the buf log format structure * and 1 for each stretch of non-contiguous chunks to be logged. * Contiguous chunks are logged in a single iovec. * * If the XFS_BLI_STALE flag has been set, then log nothing. */ |
166d13688 xfs: return log i... |
59 |
STATIC void |
372cc85ec xfs: support disc... |
60 61 |
xfs_buf_item_size_segment( struct xfs_buf_log_item *bip, |
166d13688 xfs: return log i... |
62 63 64 |
struct xfs_buf_log_format *blfp, int *nvecs, int *nbytes) |
1da177e4c Linux-2.6.12-rc2 |
65 |
{ |
7bfa31d8e xfs: give xfs_ite... |
66 |
struct xfs_buf *bp = bip->bli_buf; |
7bfa31d8e xfs: give xfs_ite... |
67 68 |
int next_bit; int last_bit; |
1da177e4c Linux-2.6.12-rc2 |
69 |
|
372cc85ec xfs: support disc... |
70 71 |
last_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); if (last_bit == -1) |
166d13688 xfs: return log i... |
72 |
return; |
372cc85ec xfs: support disc... |
73 74 75 76 77 |
/* * initial count for a dirty buffer is 2 vectors - the format structure * and the first dirty region. */ |
166d13688 xfs: return log i... |
78 79 |
*nvecs += 2; *nbytes += xfs_buf_log_format_size(blfp) + XFS_BLF_CHUNK; |
1da177e4c Linux-2.6.12-rc2 |
80 |
|
1da177e4c Linux-2.6.12-rc2 |
81 82 83 84 85 86 87 |
while (last_bit != -1) { /* * This takes the bit number to start looking from and * returns the next set bit from there. It returns -1 * if there are no more bits set or the start bit is * beyond the end of the bitmap. */ |
372cc85ec xfs: support disc... |
88 89 |
next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, last_bit + 1); |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 93 94 95 |
/* * If we run out of bits, leave the loop, * else if we find a new set of bits bump the number of vecs, * else keep scanning the current set of bits. */ if (next_bit == -1) { |
372cc85ec xfs: support disc... |
96 |
break; |
1da177e4c Linux-2.6.12-rc2 |
97 98 |
} else if (next_bit != last_bit + 1) { last_bit = next_bit; |
166d13688 xfs: return log i... |
99 |
(*nvecs)++; |
c11554104 xfs: Clean up XFS... |
100 101 102 |
} else if (xfs_buf_offset(bp, next_bit * XFS_BLF_CHUNK) != (xfs_buf_offset(bp, last_bit * XFS_BLF_CHUNK) + XFS_BLF_CHUNK)) { |
1da177e4c Linux-2.6.12-rc2 |
103 |
last_bit = next_bit; |
166d13688 xfs: return log i... |
104 |
(*nvecs)++; |
1da177e4c Linux-2.6.12-rc2 |
105 106 107 |
} else { last_bit++; } |
166d13688 xfs: return log i... |
108 |
*nbytes += XFS_BLF_CHUNK; |
1da177e4c Linux-2.6.12-rc2 |
109 |
} |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 |
} /* |
372cc85ec xfs: support disc... |
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
* This returns the number of log iovecs needed to log the given buf log item. * * It calculates this as 1 iovec for the buf log format structure and 1 for each * stretch of non-contiguous chunks to be logged. Contiguous chunks are logged * in a single iovec. * * Discontiguous buffers need a format structure per region that that is being * logged. This makes the changes in the buffer appear to log recovery as though * they came from separate buffers, just like would occur if multiple buffers * were used instead of a single discontiguous buffer. This enables * discontiguous buffers to be in-memory constructs, completely transparent to * what ends up on disk. * * If the XFS_BLI_STALE flag has been set, then log nothing but the buf log * format structures. |
1da177e4c Linux-2.6.12-rc2 |
128 |
*/ |
166d13688 xfs: return log i... |
129 |
STATIC void |
372cc85ec xfs: support disc... |
130 |
xfs_buf_item_size( |
166d13688 xfs: return log i... |
131 132 133 |
struct xfs_log_item *lip, int *nvecs, int *nbytes) |
1da177e4c Linux-2.6.12-rc2 |
134 |
{ |
7bfa31d8e xfs: give xfs_ite... |
135 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); |
372cc85ec xfs: support disc... |
136 137 138 139 140 141 142 143 144 145 |
int i; ASSERT(atomic_read(&bip->bli_refcount) > 0); if (bip->bli_flags & XFS_BLI_STALE) { /* * The buffer is stale, so all we need to log * is the buf log format structure with the * cancel flag in it. */ trace_xfs_buf_item_size_stale(bip); |
b94381737 xfs: rename bli_f... |
146 |
ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL); |
166d13688 xfs: return log i... |
147 148 149 150 151 |
*nvecs += bip->bli_format_count; for (i = 0; i < bip->bli_format_count; i++) { *nbytes += xfs_buf_log_format_size(&bip->bli_formats[i]); } return; |
372cc85ec xfs: support disc... |
152 153 154 |
} ASSERT(bip->bli_flags & XFS_BLI_LOGGED); |
5f6bed76c xfs: Introduce an... |
155 156 157 158 159 160 161 |
if (bip->bli_flags & XFS_BLI_ORDERED) { /* * The buffer has been logged just to order it. * It is not being included in the transaction * commit, so no vectors are used at all. */ trace_xfs_buf_item_size_ordered(bip); |
166d13688 xfs: return log i... |
162 163 |
*nvecs = XFS_LOG_VEC_ORDERED; return; |
5f6bed76c xfs: Introduce an... |
164 |
} |
372cc85ec xfs: support disc... |
165 166 167 168 169 170 171 172 173 |
/* * the vector count is based on the number of buffer vectors we have * dirty bits in. This will only be greater than one when we have a * compound buffer with more than one segment dirty. Hence for compound * buffers we need to track which segment the dirty bits correspond to, * and when we move from one segment to the next increment the vector * count for the extra buf log format structure that will need to be * written. */ |
372cc85ec xfs: support disc... |
174 |
for (i = 0; i < bip->bli_format_count; i++) { |
166d13688 xfs: return log i... |
175 176 |
xfs_buf_item_size_segment(bip, &bip->bli_formats[i], nvecs, nbytes); |
372cc85ec xfs: support disc... |
177 |
} |
372cc85ec xfs: support disc... |
178 |
trace_xfs_buf_item_size(bip); |
372cc85ec xfs: support disc... |
179 |
} |
1234351cb xfs: introduce xl... |
180 |
static inline void |
7aeb72224 xfs: refactor xfs... |
181 |
xfs_buf_item_copy_iovec( |
bde7cff67 xfs: format log i... |
182 |
struct xfs_log_vec *lv, |
1234351cb xfs: introduce xl... |
183 |
struct xfs_log_iovec **vecp, |
7aeb72224 xfs: refactor xfs... |
184 185 186 187 188 189 |
struct xfs_buf *bp, uint offset, int first_bit, uint nbits) { offset += first_bit * XFS_BLF_CHUNK; |
bde7cff67 xfs: format log i... |
190 |
xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK, |
1234351cb xfs: introduce xl... |
191 192 |
xfs_buf_offset(bp, offset), nbits * XFS_BLF_CHUNK); |
7aeb72224 xfs: refactor xfs... |
193 194 195 196 197 198 199 200 201 202 203 204 205 |
} static inline bool xfs_buf_item_straddle( struct xfs_buf *bp, uint offset, int next_bit, int last_bit) { return xfs_buf_offset(bp, offset + (next_bit << XFS_BLF_SHIFT)) != (xfs_buf_offset(bp, offset + (last_bit << XFS_BLF_SHIFT)) + XFS_BLF_CHUNK); } |
1234351cb xfs: introduce xl... |
206 |
static void |
372cc85ec xfs: support disc... |
207 208 |
xfs_buf_item_format_segment( struct xfs_buf_log_item *bip, |
bde7cff67 xfs: format log i... |
209 |
struct xfs_log_vec *lv, |
1234351cb xfs: introduce xl... |
210 |
struct xfs_log_iovec **vecp, |
372cc85ec xfs: support disc... |
211 212 213 |
uint offset, struct xfs_buf_log_format *blfp) { |
7bfa31d8e xfs: give xfs_ite... |
214 |
struct xfs_buf *bp = bip->bli_buf; |
1da177e4c Linux-2.6.12-rc2 |
215 |
uint base_size; |
1da177e4c Linux-2.6.12-rc2 |
216 217 218 219 |
int first_bit; int last_bit; int next_bit; uint nbits; |
1da177e4c Linux-2.6.12-rc2 |
220 |
|
372cc85ec xfs: support disc... |
221 |
/* copy the flags across from the base format item */ |
b94381737 xfs: rename bli_f... |
222 |
blfp->blf_flags = bip->__bli_format.blf_flags; |
1da177e4c Linux-2.6.12-rc2 |
223 224 |
/* |
77c1a08fc xfs: struct xfs_b... |
225 226 227 |
* Base size is the actual size of the ondisk structure - it reflects * the actual size of the dirty bitmap rather than the size of the in * memory structure. |
1da177e4c Linux-2.6.12-rc2 |
228 |
*/ |
166d13688 xfs: return log i... |
229 |
base_size = xfs_buf_log_format_size(blfp); |
820a554f2 xfs: fix segment ... |
230 |
|
820a554f2 xfs: fix segment ... |
231 232 233 234 235 236 |
first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0); if (!(bip->bli_flags & XFS_BLI_STALE) && first_bit == -1) { /* * If the map is not be dirty in the transaction, mark * the size as zero and do not advance the vector pointer. */ |
bde7cff67 xfs: format log i... |
237 |
return; |
820a554f2 xfs: fix segment ... |
238 |
} |
bde7cff67 xfs: format log i... |
239 240 |
blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size); blfp->blf_size = 1; |
1da177e4c Linux-2.6.12-rc2 |
241 242 243 244 245 246 247 |
if (bip->bli_flags & XFS_BLI_STALE) { /* * The buffer is stale, so all we need to log * is the buf log format structure with the * cancel flag in it. */ |
0b1b213fc xfs: event tracin... |
248 |
trace_xfs_buf_item_format_stale(bip); |
372cc85ec xfs: support disc... |
249 |
ASSERT(blfp->blf_flags & XFS_BLF_CANCEL); |
bde7cff67 xfs: format log i... |
250 |
return; |
1da177e4c Linux-2.6.12-rc2 |
251 |
} |
5f6bed76c xfs: Introduce an... |
252 |
|
1da177e4c Linux-2.6.12-rc2 |
253 254 255 |
/* * Fill in an iovec for each set of contiguous chunks. */ |
1da177e4c Linux-2.6.12-rc2 |
256 257 258 259 260 261 262 263 264 |
last_bit = first_bit; nbits = 1; for (;;) { /* * This takes the bit number to start looking from and * returns the next set bit from there. It returns -1 * if there are no more bits set or the start bit is * beyond the end of the bitmap. */ |
372cc85ec xfs: support disc... |
265 266 |
next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, (uint)last_bit + 1); |
1da177e4c Linux-2.6.12-rc2 |
267 |
/* |
7aeb72224 xfs: refactor xfs... |
268 269 270 271 272 |
* If we run out of bits fill in the last iovec and get out of * the loop. Else if we start a new set of bits then fill in * the iovec for the series we were looking at and start * counting the bits in the new one. Else we're still in the * same set of bits so just keep counting and scanning. |
1da177e4c Linux-2.6.12-rc2 |
273 274 |
*/ if (next_bit == -1) { |
bde7cff67 xfs: format log i... |
275 |
xfs_buf_item_copy_iovec(lv, vecp, bp, offset, |
7aeb72224 xfs: refactor xfs... |
276 |
first_bit, nbits); |
bde7cff67 xfs: format log i... |
277 |
blfp->blf_size++; |
1da177e4c Linux-2.6.12-rc2 |
278 |
break; |
7aeb72224 xfs: refactor xfs... |
279 280 |
} else if (next_bit != last_bit + 1 || xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) { |
bde7cff67 xfs: format log i... |
281 |
xfs_buf_item_copy_iovec(lv, vecp, bp, offset, |
1234351cb xfs: introduce xl... |
282 |
first_bit, nbits); |
bde7cff67 xfs: format log i... |
283 |
blfp->blf_size++; |
1da177e4c Linux-2.6.12-rc2 |
284 285 286 287 288 289 290 291 |
first_bit = next_bit; last_bit = next_bit; nbits = 1; } else { last_bit++; nbits++; } } |
372cc85ec xfs: support disc... |
292 293 294 295 296 297 298 299 300 301 302 |
} /* * This is called to fill in the vector of log iovecs for the * given log buf item. It fills the first entry with a buf log * format structure, and the rest point to contiguous chunks * within the buffer. */ STATIC void xfs_buf_item_format( struct xfs_log_item *lip, |
bde7cff67 xfs: format log i... |
303 |
struct xfs_log_vec *lv) |
372cc85ec xfs: support disc... |
304 305 306 |
{ struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; |
bde7cff67 xfs: format log i... |
307 |
struct xfs_log_iovec *vecp = NULL; |
372cc85ec xfs: support disc... |
308 309 310 311 312 313 |
uint offset = 0; int i; ASSERT(atomic_read(&bip->bli_refcount) > 0); ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || (bip->bli_flags & XFS_BLI_STALE)); |
0d612fb57 xfs: ensure buffe... |
314 315 316 |
ASSERT((bip->bli_flags & XFS_BLI_STALE) || (xfs_blft_from_flags(&bip->__bli_format) > XFS_BLFT_UNKNOWN_BUF && xfs_blft_from_flags(&bip->__bli_format) < XFS_BLFT_MAX_BUF)); |
e9385cc6f xfs: ordered buff... |
317 318 |
ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED) || (bip->bli_flags & XFS_BLI_STALE)); |
0d612fb57 xfs: ensure buffe... |
319 |
|
372cc85ec xfs: support disc... |
320 321 322 |
/* * If it is an inode buffer, transfer the in-memory state to the |
ddf6ad014 xfs: Use inode cr... |
323 324 325 |
* format flags and clear the in-memory state. * * For buffer based inode allocation, we do not transfer |
372cc85ec xfs: support disc... |
326 327 328 |
* this state if the inode buffer allocation has not yet been committed * to the log as setting the XFS_BLI_INODE_BUF flag will prevent * correct replay of the inode allocation. |
ddf6ad014 xfs: Use inode cr... |
329 330 331 332 333 |
* * For icreate item based inode allocation, the buffers aren't written * to the journal during allocation, and hence we should always tag the * buffer as an inode buffer so that the correct unlinked list replay * occurs during recovery. |
372cc85ec xfs: support disc... |
334 335 |
*/ if (bip->bli_flags & XFS_BLI_INODE_BUF) { |
ddf6ad014 xfs: Use inode cr... |
336 337 |
if (xfs_sb_version_hascrc(&lip->li_mountp->m_sb) || !((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && |
372cc85ec xfs: support disc... |
338 |
xfs_log_item_in_current_chkpt(lip))) |
b94381737 xfs: rename bli_f... |
339 |
bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF; |
372cc85ec xfs: support disc... |
340 341 342 343 |
bip->bli_flags &= ~XFS_BLI_INODE_BUF; } for (i = 0; i < bip->bli_format_count; i++) { |
bde7cff67 xfs: format log i... |
344 |
xfs_buf_item_format_segment(bip, lv, &vecp, offset, |
1234351cb xfs: introduce xl... |
345 |
&bip->bli_formats[i]); |
a3916e528 xfs: fix broken m... |
346 |
offset += BBTOB(bp->b_maps[i].bm_len); |
372cc85ec xfs: support disc... |
347 |
} |
1da177e4c Linux-2.6.12-rc2 |
348 349 350 351 |
/* * Check to make sure everything is consistent. */ |
0b1b213fc xfs: event tracin... |
352 |
trace_xfs_buf_item_format(bip); |
1da177e4c Linux-2.6.12-rc2 |
353 354 355 |
} /* |
64fc35de6 xfs: modify buffe... |
356 |
* This is called to pin the buffer associated with the buf log item in memory |
4d16e9246 xfs: simplify buf... |
357 |
* so it cannot be written out. |
64fc35de6 xfs: modify buffe... |
358 359 360 361 362 |
* * We also always take a reference to the buffer log item here so that the bli * is held while the item is pinned in memory. This means that we can * unconditionally drop the reference count a transaction holds when the * transaction is completed. |
1da177e4c Linux-2.6.12-rc2 |
363 |
*/ |
ba0f32d46 [XFS] mark variou... |
364 |
STATIC void |
1da177e4c Linux-2.6.12-rc2 |
365 |
xfs_buf_item_pin( |
7bfa31d8e xfs: give xfs_ite... |
366 |
struct xfs_log_item *lip) |
1da177e4c Linux-2.6.12-rc2 |
367 |
{ |
7bfa31d8e xfs: give xfs_ite... |
368 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); |
1da177e4c Linux-2.6.12-rc2 |
369 |
|
1da177e4c Linux-2.6.12-rc2 |
370 371 |
ASSERT(atomic_read(&bip->bli_refcount) > 0); ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || |
5f6bed76c xfs: Introduce an... |
372 |
(bip->bli_flags & XFS_BLI_ORDERED) || |
1da177e4c Linux-2.6.12-rc2 |
373 |
(bip->bli_flags & XFS_BLI_STALE)); |
7bfa31d8e xfs: give xfs_ite... |
374 |
|
0b1b213fc xfs: event tracin... |
375 |
trace_xfs_buf_item_pin(bip); |
4d16e9246 xfs: simplify buf... |
376 377 378 |
atomic_inc(&bip->bli_refcount); atomic_inc(&bip->bli_buf->b_pin_count); |
1da177e4c Linux-2.6.12-rc2 |
379 |
} |
1da177e4c Linux-2.6.12-rc2 |
380 381 382 |
/* * This is called to unpin the buffer associated with the buf log * item which was previously pinned with a call to xfs_buf_item_pin(). |
1da177e4c Linux-2.6.12-rc2 |
383 384 385 386 |
* * Also drop the reference to the buf item for the current transaction. * If the XFS_BLI_STALE flag is set and we are the last reference, * then free up the buf log item and unlock the buffer. |
9412e3181 xfs: merge iop_un... |
387 388 389 390 391 |
* * If the remove flag is set we are called from uncommit in the * forced-shutdown path. If that is true and the reference count on * the log item is going to drop to zero we need to free the item's * descriptor in the transaction. |
1da177e4c Linux-2.6.12-rc2 |
392 |
*/ |
ba0f32d46 [XFS] mark variou... |
393 |
STATIC void |
1da177e4c Linux-2.6.12-rc2 |
394 |
xfs_buf_item_unpin( |
7bfa31d8e xfs: give xfs_ite... |
395 |
struct xfs_log_item *lip, |
9412e3181 xfs: merge iop_un... |
396 |
int remove) |
1da177e4c Linux-2.6.12-rc2 |
397 |
{ |
7bfa31d8e xfs: give xfs_ite... |
398 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); |
9412e3181 xfs: merge iop_un... |
399 |
xfs_buf_t *bp = bip->bli_buf; |
7bfa31d8e xfs: give xfs_ite... |
400 |
struct xfs_ail *ailp = lip->li_ailp; |
8e1238508 xfs: remove stale... |
401 |
int stale = bip->bli_flags & XFS_BLI_STALE; |
7bfa31d8e xfs: give xfs_ite... |
402 |
int freed; |
1da177e4c Linux-2.6.12-rc2 |
403 |
|
adadbeefb xfs: remove wrapp... |
404 |
ASSERT(bp->b_fspriv == bip); |
1da177e4c Linux-2.6.12-rc2 |
405 |
ASSERT(atomic_read(&bip->bli_refcount) > 0); |
9412e3181 xfs: merge iop_un... |
406 |
|
0b1b213fc xfs: event tracin... |
407 |
trace_xfs_buf_item_unpin(bip); |
1da177e4c Linux-2.6.12-rc2 |
408 409 |
freed = atomic_dec_and_test(&bip->bli_refcount); |
4d16e9246 xfs: simplify buf... |
410 411 412 |
if (atomic_dec_and_test(&bp->b_pin_count)) wake_up_all(&bp->b_waiters); |
7bfa31d8e xfs: give xfs_ite... |
413 |
|
1da177e4c Linux-2.6.12-rc2 |
414 415 |
if (freed && stale) { ASSERT(bip->bli_flags & XFS_BLI_STALE); |
0c842ad46 xfs: clean up buf... |
416 |
ASSERT(xfs_buf_islocked(bp)); |
5cfd28b6a xfs: remove XBF_S... |
417 |
ASSERT(bp->b_flags & XBF_STALE); |
b94381737 xfs: rename bli_f... |
418 |
ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL); |
9412e3181 xfs: merge iop_un... |
419 |
|
0b1b213fc xfs: event tracin... |
420 |
trace_xfs_buf_item_unpin_stale(bip); |
9412e3181 xfs: merge iop_un... |
421 422 |
if (remove) { /* |
e34a314c5 xfs: fix efi item... |
423 424 425 426 427 |
* If we are in a transaction context, we have to * remove the log item from the transaction as we are * about to release our reference to the buffer. If we * don't, the unlock that occurs later in * xfs_trans_uncommit() will try to reference the |
9412e3181 xfs: merge iop_un... |
428 429 |
* buffer which we no longer have a hold on. */ |
e34a314c5 xfs: fix efi item... |
430 431 |
if (lip->li_desc) xfs_trans_del_item(lip); |
9412e3181 xfs: merge iop_un... |
432 433 434 435 436 |
/* * Since the transaction no longer refers to the buffer, * the buffer should no longer refer to the transaction. */ |
bf9d9013a xfs: add a proper... |
437 |
bp->b_transp = NULL; |
9412e3181 xfs: merge iop_un... |
438 |
} |
1da177e4c Linux-2.6.12-rc2 |
439 440 |
/* * If we get called here because of an IO error, we may |
783a2f656 [XFS] Finish remo... |
441 |
* or may not have the item on the AIL. xfs_trans_ail_delete() |
1da177e4c Linux-2.6.12-rc2 |
442 |
* will take care of that situation. |
783a2f656 [XFS] Finish remo... |
443 |
* xfs_trans_ail_delete() drops the AIL lock. |
1da177e4c Linux-2.6.12-rc2 |
444 445 |
*/ if (bip->bli_flags & XFS_BLI_STALE_INODE) { |
c90821a26 xfs: consume iodo... |
446 |
xfs_buf_do_callbacks(bp); |
adadbeefb xfs: remove wrapp... |
447 |
bp->b_fspriv = NULL; |
cb669ca57 xfs: remove wrapp... |
448 |
bp->b_iodone = NULL; |
1da177e4c Linux-2.6.12-rc2 |
449 |
} else { |
783a2f656 [XFS] Finish remo... |
450 |
spin_lock(&ailp->xa_lock); |
04913fdd9 xfs: pass shutdow... |
451 |
xfs_trans_ail_delete(ailp, lip, SHUTDOWN_LOG_IO_ERROR); |
1da177e4c Linux-2.6.12-rc2 |
452 |
xfs_buf_item_relse(bp); |
adadbeefb xfs: remove wrapp... |
453 |
ASSERT(bp->b_fspriv == NULL); |
1da177e4c Linux-2.6.12-rc2 |
454 455 |
} xfs_buf_relse(bp); |
960c60af8 xfs: do not add b... |
456 |
} else if (freed && remove) { |
137fff09b xfs: fix buffer s... |
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
/* * There are currently two references to the buffer - the active * LRU reference and the buf log item. What we are about to do * here - simulate a failed IO completion - requires 3 * references. * * The LRU reference is removed by the xfs_buf_stale() call. The * buf item reference is removed by the xfs_buf_iodone() * callback that is run by xfs_buf_do_callbacks() during ioend * processing (via the bp->b_iodone callback), and then finally * the ioend processing will drop the IO reference if the buffer * is marked XBF_ASYNC. * * Hence we need to take an additional reference here so that IO * completion processing doesn't free the buffer prematurely. */ |
960c60af8 xfs: do not add b... |
473 |
xfs_buf_lock(bp); |
137fff09b xfs: fix buffer s... |
474 475 |
xfs_buf_hold(bp); bp->b_flags |= XBF_ASYNC; |
2451337dd xfs: global error... |
476 |
xfs_buf_ioerror(bp, -EIO); |
b0388bf10 xfs: remove XBF_D... |
477 |
bp->b_flags &= ~XBF_DONE; |
960c60af8 xfs: do not add b... |
478 |
xfs_buf_stale(bp); |
e8aaba9a7 xfs: xfs_buf_ioen... |
479 |
xfs_buf_ioend(bp); |
1da177e4c Linux-2.6.12-rc2 |
480 481 |
} } |
ac8809f9a xfs: abort metada... |
482 483 484 485 486 |
/* * Buffer IO error rate limiting. Limit it to no more than 10 messages per 30 * seconds so as to not spam logs too much on repeated detection of the same * buffer being bad.. */ |
02cc18764 xfs: xfs_buf_writ... |
487 |
static DEFINE_RATELIMIT_STATE(xfs_buf_write_fail_rl_state, 30 * HZ, 10); |
ac8809f9a xfs: abort metada... |
488 |
|
ba0f32d46 [XFS] mark variou... |
489 |
STATIC uint |
43ff2122e xfs: on-stack del... |
490 491 492 |
xfs_buf_item_push( struct xfs_log_item *lip, struct list_head *buffer_list) |
1da177e4c Linux-2.6.12-rc2 |
493 |
{ |
7bfa31d8e xfs: give xfs_ite... |
494 495 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; |
43ff2122e xfs: on-stack del... |
496 |
uint rval = XFS_ITEM_SUCCESS; |
1da177e4c Linux-2.6.12-rc2 |
497 |
|
811e64c71 Replace the macro... |
498 |
if (xfs_buf_ispinned(bp)) |
1da177e4c Linux-2.6.12-rc2 |
499 |
return XFS_ITEM_PINNED; |
5337fe9b1 xfs: recheck buff... |
500 501 502 503 504 505 506 507 508 509 |
if (!xfs_buf_trylock(bp)) { /* * If we have just raced with a buffer being pinned and it has * been marked stale, we could end up stalling until someone else * issues a log force to unpin the stale buffer. Check for the * race condition here so xfsaild recognizes the buffer is pinned * and queues a log force to move it along. */ if (xfs_buf_ispinned(bp)) return XFS_ITEM_PINNED; |
1da177e4c Linux-2.6.12-rc2 |
510 |
return XFS_ITEM_LOCKED; |
5337fe9b1 xfs: recheck buff... |
511 |
} |
1da177e4c Linux-2.6.12-rc2 |
512 |
|
1da177e4c Linux-2.6.12-rc2 |
513 |
ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); |
43ff2122e xfs: on-stack del... |
514 515 |
trace_xfs_buf_item_push(bip); |
ac8809f9a xfs: abort metada... |
516 517 |
/* has a previous flush failed due to IO errors? */ if ((bp->b_flags & XBF_WRITE_FAIL) && |
fdadf2676 xfs: clarify asyn... |
518 |
___ratelimit(&xfs_buf_write_fail_rl_state, "XFS: Failing async write")) { |
ac8809f9a xfs: abort metada... |
519 |
xfs_warn(bp->b_target->bt_mount, |
fdadf2676 xfs: clarify asyn... |
520 |
"Failing async write on buffer block 0x%llx. Retrying async write.", |
ac8809f9a xfs: abort metada... |
521 522 |
(long long)bp->b_bn); } |
43ff2122e xfs: on-stack del... |
523 524 525 526 |
if (!xfs_buf_delwri_queue(bp, buffer_list)) rval = XFS_ITEM_FLUSHING; xfs_buf_unlock(bp); return rval; |
1da177e4c Linux-2.6.12-rc2 |
527 528 529 |
} /* |
64fc35de6 xfs: modify buffe... |
530 531 532 |
* Release the buffer associated with the buf log item. If there is no dirty * logged data associated with the buffer recorded in the buf log item, then * free the buf log item and remove the reference to it in the buffer. |
1da177e4c Linux-2.6.12-rc2 |
533 |
* |
64fc35de6 xfs: modify buffe... |
534 535 |
* This call ignores the recursion count. It is only called when the buffer * should REALLY be unlocked, regardless of the recursion count. |
1da177e4c Linux-2.6.12-rc2 |
536 |
* |
64fc35de6 xfs: modify buffe... |
537 538 539 540 541 542 543 544 545 546 |
* We unconditionally drop the transaction's reference to the log item. If the * item was logged, then another reference was taken when it was pinned, so we * can safely drop the transaction reference now. This also allows us to avoid * potential races with the unpin code freeing the bli by not referencing the * bli after we've dropped the reference count. * * If the XFS_BLI_HOLD flag is set in the buf log item, then free the log item * if necessary but do not unlock the buffer. This is for support of * xfs_trans_bhold(). Make sure the XFS_BLI_HOLD field is cleared if we don't * free the item. |
1da177e4c Linux-2.6.12-rc2 |
547 |
*/ |
ba0f32d46 [XFS] mark variou... |
548 |
STATIC void |
1da177e4c Linux-2.6.12-rc2 |
549 |
xfs_buf_item_unlock( |
7bfa31d8e xfs: give xfs_ite... |
550 |
struct xfs_log_item *lip) |
1da177e4c Linux-2.6.12-rc2 |
551 |
{ |
7bfa31d8e xfs: give xfs_ite... |
552 553 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; |
6453c65d3 xfs: remove unnec... |
554 555 556 |
bool aborted = !!(lip->li_flags & XFS_LI_ABORTED); bool hold = !!(bip->bli_flags & XFS_BLI_HOLD); bool dirty = !!(bip->bli_flags & XFS_BLI_DIRTY); |
7bf7a193a xfs: fix compiler... |
557 |
#if defined(DEBUG) || defined(XFS_WARN) |
6453c65d3 xfs: remove unnec... |
558 |
bool ordered = !!(bip->bli_flags & XFS_BLI_ORDERED); |
7bf7a193a xfs: fix compiler... |
559 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
560 |
|
64fc35de6 xfs: modify buffe... |
561 |
/* Clear the buffer's association with this transaction. */ |
bf9d9013a xfs: add a proper... |
562 |
bp->b_transp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
563 564 |
/* |
6453c65d3 xfs: remove unnec... |
565 566 |
* The per-transaction state has been copied above so clear it from the * bli. |
1da177e4c Linux-2.6.12-rc2 |
567 |
*/ |
5f6bed76c xfs: Introduce an... |
568 |
bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED); |
64fc35de6 xfs: modify buffe... |
569 570 571 572 573 |
/* * If the buf item is marked stale, then don't do anything. We'll * unlock the buffer and free the buf item when the buffer is unpinned * for the last time. |
1da177e4c Linux-2.6.12-rc2 |
574 |
*/ |
6453c65d3 xfs: remove unnec... |
575 |
if (bip->bli_flags & XFS_BLI_STALE) { |
0b1b213fc xfs: event tracin... |
576 |
trace_xfs_buf_item_unlock_stale(bip); |
b94381737 xfs: rename bli_f... |
577 |
ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL); |
64fc35de6 xfs: modify buffe... |
578 579 |
if (!aborted) { atomic_dec(&bip->bli_refcount); |
1da177e4c Linux-2.6.12-rc2 |
580 |
return; |
64fc35de6 xfs: modify buffe... |
581 |
} |
1da177e4c Linux-2.6.12-rc2 |
582 |
} |
0b1b213fc xfs: event tracin... |
583 |
trace_xfs_buf_item_unlock(bip); |
1da177e4c Linux-2.6.12-rc2 |
584 585 |
/* |
64fc35de6 xfs: modify buffe... |
586 |
* If the buf item isn't tracking any data, free it, otherwise drop the |
3b19034d4 xfs: fix shutdown... |
587 588 589 590 |
* reference we hold to it. If we are aborting the transaction, this may * be the only reference to the buf item, so we free it anyway * regardless of whether it is dirty or not. A dirty abort implies a * shutdown, anyway. |
5f6bed76c xfs: Introduce an... |
591 |
* |
6453c65d3 xfs: remove unnec... |
592 593 |
* The bli dirty state should match whether the blf has logged segments * except for ordered buffers, where only the bli should be dirty. |
1da177e4c Linux-2.6.12-rc2 |
594 |
*/ |
6453c65d3 xfs: remove unnec... |
595 596 |
ASSERT((!ordered && dirty == xfs_buf_item_dirty_format(bip)) || (ordered && dirty && !xfs_buf_item_dirty_format(bip))); |
46f9d2eb3 xfs: aborted buf ... |
597 598 599 |
/* * Clean buffers, by definition, cannot be in the AIL. However, aborted |
3d4b4a3e3 xfs: remove bli f... |
600 601 602 603 604 605 606 607 608 |
* buffers may be in the AIL regardless of dirty state. An aborted * transaction that invalidates a buffer already in the AIL may have * marked it stale and cleared the dirty state, for example. * * Therefore if we are aborting a buffer and we've just taken the last * reference away, we have to check if it is in the AIL before freeing * it. We need to free it in this case, because an aborted transaction * has already shut the filesystem down and this is the last chance we * will have to do so. |
46f9d2eb3 xfs: aborted buf ... |
609 610 |
*/ if (atomic_dec_and_test(&bip->bli_refcount)) { |
3d4b4a3e3 xfs: remove bli f... |
611 |
if (aborted) { |
46f9d2eb3 xfs: aborted buf ... |
612 |
ASSERT(XFS_FORCED_SHUTDOWN(lip->li_mountp)); |
146e54b71 xfs: add helper t... |
613 |
xfs_trans_ail_remove(lip, SHUTDOWN_LOG_IO_ERROR); |
3b19034d4 xfs: fix shutdown... |
614 |
xfs_buf_item_relse(bp); |
6453c65d3 xfs: remove unnec... |
615 |
} else if (!dirty) |
3d4b4a3e3 xfs: remove bli f... |
616 |
xfs_buf_item_relse(bp); |
46f9d2eb3 xfs: aborted buf ... |
617 |
} |
1da177e4c Linux-2.6.12-rc2 |
618 |
|
6453c65d3 xfs: remove unnec... |
619 |
if (!hold) |
1da177e4c Linux-2.6.12-rc2 |
620 |
xfs_buf_relse(bp); |
1da177e4c Linux-2.6.12-rc2 |
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
} /* * This is called to find out where the oldest active copy of the * buf log item in the on disk log resides now that the last log * write of it completed at the given lsn. * We always re-log all the dirty data in a buffer, so usually the * latest copy in the on disk log is the only one that matters. For * those cases we simply return the given lsn. * * The one exception to this is for buffers full of newly allocated * inodes. These buffers are only relogged with the XFS_BLI_INODE_BUF * flag set, indicating that only the di_next_unlinked fields from the * inodes in the buffers will be replayed during recovery. If the * original newly allocated inode images have not yet been flushed * when the buffer is so relogged, then we need to make sure that we * keep the old images in the 'active' portion of the log. We do this * by returning the original lsn of that transaction here rather than * the current one. */ |
ba0f32d46 [XFS] mark variou... |
641 |
STATIC xfs_lsn_t |
1da177e4c Linux-2.6.12-rc2 |
642 |
xfs_buf_item_committed( |
7bfa31d8e xfs: give xfs_ite... |
643 |
struct xfs_log_item *lip, |
1da177e4c Linux-2.6.12-rc2 |
644 645 |
xfs_lsn_t lsn) { |
7bfa31d8e xfs: give xfs_ite... |
646 |
struct xfs_buf_log_item *bip = BUF_ITEM(lip); |
0b1b213fc xfs: event tracin... |
647 |
trace_xfs_buf_item_committed(bip); |
7bfa31d8e xfs: give xfs_ite... |
648 649 650 |
if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && lip->li_lsn != 0) return lip->li_lsn; return lsn; |
1da177e4c Linux-2.6.12-rc2 |
651 |
} |
ba0f32d46 [XFS] mark variou... |
652 |
STATIC void |
7bfa31d8e xfs: give xfs_ite... |
653 654 655 |
xfs_buf_item_committing( struct xfs_log_item *lip, xfs_lsn_t commit_lsn) |
1da177e4c Linux-2.6.12-rc2 |
656 657 658 659 660 661 |
{ } /* * This is the ops vector shared by all buf log items. */ |
272e42b21 xfs: constify xfs... |
662 |
static const struct xfs_item_ops xfs_buf_item_ops = { |
7bfa31d8e xfs: give xfs_ite... |
663 664 665 666 |
.iop_size = xfs_buf_item_size, .iop_format = xfs_buf_item_format, .iop_pin = xfs_buf_item_pin, .iop_unpin = xfs_buf_item_unpin, |
7bfa31d8e xfs: give xfs_ite... |
667 668 669 |
.iop_unlock = xfs_buf_item_unlock, .iop_committed = xfs_buf_item_committed, .iop_push = xfs_buf_item_push, |
7bfa31d8e xfs: give xfs_ite... |
670 |
.iop_committing = xfs_buf_item_committing |
1da177e4c Linux-2.6.12-rc2 |
671 |
}; |
372cc85ec xfs: support disc... |
672 673 674 675 676 677 678 679 680 |
STATIC int xfs_buf_item_get_format( struct xfs_buf_log_item *bip, int count) { ASSERT(bip->bli_formats == NULL); bip->bli_format_count = count; if (count == 1) { |
b94381737 xfs: rename bli_f... |
681 |
bip->bli_formats = &bip->__bli_format; |
372cc85ec xfs: support disc... |
682 683 684 685 686 687 |
return 0; } bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format), KM_SLEEP); if (!bip->bli_formats) |
2451337dd xfs: global error... |
688 |
return -ENOMEM; |
372cc85ec xfs: support disc... |
689 690 691 692 693 694 695 |
return 0; } STATIC void xfs_buf_item_free_format( struct xfs_buf_log_item *bip) { |
b94381737 xfs: rename bli_f... |
696 |
if (bip->bli_formats != &bip->__bli_format) { |
372cc85ec xfs: support disc... |
697 698 699 700 |
kmem_free(bip->bli_formats); bip->bli_formats = NULL; } } |
1da177e4c Linux-2.6.12-rc2 |
701 702 703 704 705 706 707 708 |
/* * Allocate a new buf log item to go with the given buffer. * Set the buffer's b_fsprivate field to point to the new * buf log item. If there are other item's attached to the * buffer (see xfs_buf_attach_iodone() below), then put the * buf log item at the front. */ |
f79af0b90 xfs: fix non-debu... |
709 |
int |
1da177e4c Linux-2.6.12-rc2 |
710 |
xfs_buf_item_init( |
f79af0b90 xfs: fix non-debu... |
711 712 |
struct xfs_buf *bp, struct xfs_mount *mp) |
1da177e4c Linux-2.6.12-rc2 |
713 |
{ |
f79af0b90 xfs: fix non-debu... |
714 715 |
struct xfs_log_item *lip = bp->b_fspriv; struct xfs_buf_log_item *bip; |
1da177e4c Linux-2.6.12-rc2 |
716 717 |
int chunks; int map_size; |
372cc85ec xfs: support disc... |
718 719 |
int error; int i; |
1da177e4c Linux-2.6.12-rc2 |
720 721 722 723 724 725 726 |
/* * Check to see if there is already a buf log item for * this buffer. If there is, it is guaranteed to be * the first. If we do already have one, there is * nothing to do here so return. */ |
ebad861b5 xfs: store xfs_mo... |
727 |
ASSERT(bp->b_target->bt_mount == mp); |
adadbeefb xfs: remove wrapp... |
728 |
if (lip != NULL && lip->li_type == XFS_LI_BUF) |
f79af0b90 xfs: fix non-debu... |
729 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
730 |
|
372cc85ec xfs: support disc... |
731 |
bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); |
43f5efc5b xfs: factor log i... |
732 |
xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); |
1da177e4c Linux-2.6.12-rc2 |
733 |
bip->bli_buf = bp; |
372cc85ec xfs: support disc... |
734 735 736 737 738 739 740 741 742 743 744 745 |
/* * chunks is the number of XFS_BLF_CHUNK size pieces the buffer * can be divided into. Make sure not to truncate any pieces. * map_size is the size of the bitmap needed to describe the * chunks of the buffer. * * Discontiguous buffer support follows the layout of the underlying * buffer. This makes the implementation as simple as possible. */ error = xfs_buf_item_get_format(bip, bp->b_map_count); ASSERT(error == 0); |
f79af0b90 xfs: fix non-debu... |
746 747 748 749 |
if (error) { /* to stop gcc throwing set-but-unused warnings */ kmem_zone_free(xfs_buf_item_zone, bip); return error; } |
372cc85ec xfs: support disc... |
750 751 752 753 754 755 756 757 758 759 760 |
for (i = 0; i < bip->bli_format_count; i++) { chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len), XFS_BLF_CHUNK); map_size = DIV_ROUND_UP(chunks, NBWORD); bip->bli_formats[i].blf_type = XFS_LI_BUF; bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn; bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len; bip->bli_formats[i].blf_map_size = map_size; } |
1da177e4c Linux-2.6.12-rc2 |
761 |
|
1da177e4c Linux-2.6.12-rc2 |
762 763 764 765 |
/* * Put the buf item into the list of items attached to the * buffer at the front. */ |
adadbeefb xfs: remove wrapp... |
766 767 768 |
if (bp->b_fspriv) bip->bli_item.li_bio_list = bp->b_fspriv; bp->b_fspriv = bip; |
f79af0b90 xfs: fix non-debu... |
769 770 |
xfs_buf_hold(bp); return 0; |
1da177e4c Linux-2.6.12-rc2 |
771 772 773 774 775 776 777 |
} /* * Mark bytes first through last inclusive as dirty in the buf * item's bitmap. */ |
632b89e82 xfs: fix static a... |
778 |
static void |
372cc85ec xfs: support disc... |
779 |
xfs_buf_item_log_segment( |
1da177e4c Linux-2.6.12-rc2 |
780 |
uint first, |
372cc85ec xfs: support disc... |
781 782 |
uint last, uint *map) |
1da177e4c Linux-2.6.12-rc2 |
783 784 785 786 787 788 789 790 791 792 793 794 |
{ uint first_bit; uint last_bit; uint bits_to_set; uint bits_set; uint word_num; uint *wordp; uint bit; uint end_bit; uint mask; /* |
1da177e4c Linux-2.6.12-rc2 |
795 796 |
* Convert byte offsets to bit numbers. */ |
c11554104 xfs: Clean up XFS... |
797 798 |
first_bit = first >> XFS_BLF_SHIFT; last_bit = last >> XFS_BLF_SHIFT; |
1da177e4c Linux-2.6.12-rc2 |
799 800 801 802 803 804 805 806 807 808 809 |
/* * Calculate the total number of bits to be set. */ bits_to_set = last_bit - first_bit + 1; /* * Get a pointer to the first word in the bitmap * to set a bit in. */ word_num = first_bit >> BIT_TO_WORD_SHIFT; |
372cc85ec xfs: support disc... |
810 |
wordp = &map[word_num]; |
1da177e4c Linux-2.6.12-rc2 |
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
/* * Calculate the starting bit in the first word. */ bit = first_bit & (uint)(NBWORD - 1); /* * First set any bits in the first word of our range. * If it starts at bit 0 of the word, it will be * set below rather than here. That is what the variable * bit tells us. The variable bits_set tracks the number * of bits that have been set so far. End_bit is the number * of the last bit to be set in this word plus one. */ if (bit) { end_bit = MIN(bit + bits_to_set, (uint)NBWORD); |
79c350e45 xfs: fix signed i... |
827 |
mask = ((1U << (end_bit - bit)) - 1) << bit; |
1da177e4c Linux-2.6.12-rc2 |
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 |
*wordp |= mask; wordp++; bits_set = end_bit - bit; } else { bits_set = 0; } /* * Now set bits a whole word at a time that are between * first_bit and last_bit. */ while ((bits_to_set - bits_set) >= NBWORD) { *wordp |= 0xffffffff; bits_set += NBWORD; wordp++; } /* * Finally, set any bits left to be set in one last partial word. */ end_bit = bits_to_set - bits_set; if (end_bit) { |
79c350e45 xfs: fix signed i... |
850 |
mask = (1U << end_bit) - 1; |
1da177e4c Linux-2.6.12-rc2 |
851 852 |
*wordp |= mask; } |
1da177e4c Linux-2.6.12-rc2 |
853 |
} |
372cc85ec xfs: support disc... |
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 |
/* * Mark bytes first through last inclusive as dirty in the buf * item's bitmap. */ void xfs_buf_item_log( xfs_buf_log_item_t *bip, uint first, uint last) { int i; uint start; uint end; struct xfs_buf *bp = bip->bli_buf; /* |
372cc85ec xfs: support disc... |
870 871 872 873 874 875 |
* walk each buffer segment and mark them dirty appropriately. */ start = 0; for (i = 0; i < bip->bli_format_count; i++) { if (start > last) break; |
a3916e528 xfs: fix broken m... |
876 877 878 |
end = start + BBTOB(bp->b_maps[i].bm_len) - 1; /* skip to the map that includes the first byte to log */ |
372cc85ec xfs: support disc... |
879 880 881 882 |
if (first > end) { start += BBTOB(bp->b_maps[i].bm_len); continue; } |
a3916e528 xfs: fix broken m... |
883 884 885 886 887 888 889 |
/* * Trim the range to this segment and mark it in the bitmap. * Note that we must convert buffer offsets to segment relative * offsets (e.g., the first byte of each segment is byte 0 of * that segment). */ |
372cc85ec xfs: support disc... |
890 891 892 893 |
if (first < start) first = start; if (end > last) end = last; |
a3916e528 xfs: fix broken m... |
894 |
xfs_buf_item_log_segment(first - start, end - start, |
372cc85ec xfs: support disc... |
895 |
&bip->bli_formats[i].blf_data_map[0]); |
a3916e528 xfs: fix broken m... |
896 |
start += BBTOB(bp->b_maps[i].bm_len); |
372cc85ec xfs: support disc... |
897 898 |
} } |
1da177e4c Linux-2.6.12-rc2 |
899 |
|
6453c65d3 xfs: remove unnec... |
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 |
/* * Return true if the buffer has any ranges logged/dirtied by a transaction, * false otherwise. */ bool xfs_buf_item_dirty_format( struct xfs_buf_log_item *bip) { int i; for (i = 0; i < bip->bli_format_count; i++) { if (!xfs_bitmap_empty(bip->bli_formats[i].blf_data_map, bip->bli_formats[i].blf_map_size)) return true; } return false; } |
e1f5dbd70 [XFS] Fix use-aft... |
918 919 920 921 |
STATIC void xfs_buf_item_free( xfs_buf_log_item_t *bip) { |
372cc85ec xfs: support disc... |
922 |
xfs_buf_item_free_format(bip); |
b1c5ebb21 xfs: allocate log... |
923 |
kmem_free(bip->bli_item.li_lv_shadow); |
e1f5dbd70 [XFS] Fix use-aft... |
924 925 |
kmem_zone_free(xfs_buf_item_zone, bip); } |
1da177e4c Linux-2.6.12-rc2 |
926 927 928 929 930 931 932 933 934 935 936 |
/* * This is called when the buf log item is no longer needed. It should * free the buf log item associated with the given buffer and clear * the buffer's pointer to the buf log item. If there are no more * items in the list, clear the b_iodone field of the buffer (see * xfs_buf_attach_iodone() below). */ void xfs_buf_item_relse( xfs_buf_t *bp) { |
5f6bed76c xfs: Introduce an... |
937 |
xfs_buf_log_item_t *bip = bp->b_fspriv; |
1da177e4c Linux-2.6.12-rc2 |
938 |
|
0b1b213fc xfs: event tracin... |
939 |
trace_xfs_buf_item_relse(bp, _RET_IP_); |
5f6bed76c xfs: Introduce an... |
940 |
ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); |
0b1b213fc xfs: event tracin... |
941 |
|
adadbeefb xfs: remove wrapp... |
942 |
bp->b_fspriv = bip->bli_item.li_bio_list; |
cb669ca57 xfs: remove wrapp... |
943 944 |
if (bp->b_fspriv == NULL) bp->b_iodone = NULL; |
adadbeefb xfs: remove wrapp... |
945 |
|
e1f5dbd70 [XFS] Fix use-aft... |
946 947 |
xfs_buf_rele(bp); xfs_buf_item_free(bip); |
1da177e4c Linux-2.6.12-rc2 |
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
} /* * Add the given log item with its callback to the list of callbacks * to be called when the buffer's I/O completes. If it is not set * already, set the buffer's b_iodone() routine to be * xfs_buf_iodone_callbacks() and link the log item into the list of * items rooted at b_fsprivate. Items are always added as the second * entry in the list if there is a first, because the buf item code * assumes that the buf log item is first. */ void xfs_buf_attach_iodone( xfs_buf_t *bp, void (*cb)(xfs_buf_t *, xfs_log_item_t *), xfs_log_item_t *lip) { xfs_log_item_t *head_lip; |
0c842ad46 xfs: clean up buf... |
967 |
ASSERT(xfs_buf_islocked(bp)); |
1da177e4c Linux-2.6.12-rc2 |
968 969 |
lip->li_cb = cb; |
adadbeefb xfs: remove wrapp... |
970 971 |
head_lip = bp->b_fspriv; if (head_lip) { |
1da177e4c Linux-2.6.12-rc2 |
972 973 974 |
lip->li_bio_list = head_lip->li_bio_list; head_lip->li_bio_list = lip; } else { |
adadbeefb xfs: remove wrapp... |
975 |
bp->b_fspriv = lip; |
1da177e4c Linux-2.6.12-rc2 |
976 |
} |
cb669ca57 xfs: remove wrapp... |
977 978 979 |
ASSERT(bp->b_iodone == NULL || bp->b_iodone == xfs_buf_iodone_callbacks); bp->b_iodone = xfs_buf_iodone_callbacks; |
1da177e4c Linux-2.6.12-rc2 |
980 |
} |
c90821a26 xfs: consume iodo... |
981 982 983 984 985 986 987 988 989 990 991 992 |
/* * We can have many callbacks on a buffer. Running the callbacks individually * can cause a lot of contention on the AIL lock, so we allow for a single * callback to be able to scan the remaining lip->li_bio_list for other items * of the same type and callback to be processed in the first call. * * As a result, the loop walking the callback list below will also modify the * list. it removes the first item from the list and then runs the callback. * The loop then restarts from the new head of the list. This allows the * callback to scan and modify the list attached to the buffer and we don't * have to care about maintaining a next item pointer. */ |
1da177e4c Linux-2.6.12-rc2 |
993 994 |
STATIC void xfs_buf_do_callbacks( |
c90821a26 xfs: consume iodo... |
995 |
struct xfs_buf *bp) |
1da177e4c Linux-2.6.12-rc2 |
996 |
{ |
c90821a26 xfs: consume iodo... |
997 |
struct xfs_log_item *lip; |
1da177e4c Linux-2.6.12-rc2 |
998 |
|
adadbeefb xfs: remove wrapp... |
999 1000 |
while ((lip = bp->b_fspriv) != NULL) { bp->b_fspriv = lip->li_bio_list; |
1da177e4c Linux-2.6.12-rc2 |
1001 1002 1003 1004 1005 1006 1007 1008 1009 |
ASSERT(lip->li_cb != NULL); /* * Clear the next pointer so we don't have any * confusion if the item is added to another buf. * Don't touch the log item after calling its * callback, because it could have freed itself. */ lip->li_bio_list = NULL; lip->li_cb(bp, lip); |
1da177e4c Linux-2.6.12-rc2 |
1010 1011 |
} } |
0b80ae6ed xfs: Add infrastr... |
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 |
/* * Invoke the error state callback for each log item affected by the failed I/O. * * If a metadata buffer write fails with a non-permanent error, the buffer is * eventually resubmitted and so the completion callbacks are not run. The error * state may need to be propagated to the log items attached to the buffer, * however, so the next AIL push of the item knows hot to handle it correctly. */ STATIC void xfs_buf_do_callbacks_fail( struct xfs_buf *bp) { struct xfs_log_item *next; struct xfs_log_item *lip = bp->b_fspriv; struct xfs_ail *ailp = lip->li_ailp; spin_lock(&ailp->xa_lock); for (; lip; lip = next) { next = lip->li_bio_list; if (lip->li_ops->iop_error) lip->li_ops->iop_error(lip, bp); } spin_unlock(&ailp->xa_lock); } |
df3093907 xfs: add configur... |
1036 1037 |
static bool xfs_buf_iodone_callback_error( |
bfc60177f xfs: fix error ha... |
1038 |
struct xfs_buf *bp) |
1da177e4c Linux-2.6.12-rc2 |
1039 |
{ |
bfc60177f xfs: fix error ha... |
1040 1041 1042 1043 |
struct xfs_log_item *lip = bp->b_fspriv; struct xfs_mount *mp = lip->li_mountp; static ulong lasttime; static xfs_buftarg_t *lasttarg; |
df3093907 xfs: add configur... |
1044 |
struct xfs_error_cfg *cfg; |
1da177e4c Linux-2.6.12-rc2 |
1045 |
|
bfc60177f xfs: fix error ha... |
1046 1047 1048 1049 |
/* * If we've already decided to shutdown the filesystem because of * I/O errors, there's no point in giving this a retry. */ |
df3093907 xfs: add configur... |
1050 1051 |
if (XFS_FORCED_SHUTDOWN(mp)) goto out_stale; |
1da177e4c Linux-2.6.12-rc2 |
1052 |
|
49074c069 xfs: Remove the m... |
1053 |
if (bp->b_target != lasttarg || |
bfc60177f xfs: fix error ha... |
1054 1055 |
time_after(jiffies, (lasttime + 5*HZ))) { lasttime = jiffies; |
b38505b09 xfs: use xfs_ioer... |
1056 |
xfs_buf_ioerror_alert(bp, __func__); |
bfc60177f xfs: fix error ha... |
1057 |
} |
49074c069 xfs: Remove the m... |
1058 |
lasttarg = bp->b_target; |
1da177e4c Linux-2.6.12-rc2 |
1059 |
|
df3093907 xfs: add configur... |
1060 1061 1062 1063 1064 1065 |
/* synchronous writes will have callers process the error */ if (!(bp->b_flags & XBF_ASYNC)) goto out_stale; trace_xfs_buf_item_iodone_async(bp, _RET_IP_); ASSERT(bp->b_iodone != NULL); |
5539d3675 xfs: don't reset ... |
1066 |
cfg = xfs_error_get_cfg(mp, XFS_ERR_METADATA, bp->b_error); |
bfc60177f xfs: fix error ha... |
1067 |
/* |
25985edce Fix common misspe... |
1068 |
* If the write was asynchronous then no one will be looking for the |
df3093907 xfs: add configur... |
1069 1070 1071 1072 |
* error. If this is the first failure of this type, clear the error * state and write the buffer out again. This means we always retry an * async write failure at least once, but we also need to set the buffer * up to behave correctly now for repeated failures. |
bfc60177f xfs: fix error ha... |
1073 |
*/ |
0b4db5dff xfs: remove extra... |
1074 |
if (!(bp->b_flags & (XBF_STALE | XBF_WRITE_FAIL)) || |
df3093907 xfs: add configur... |
1075 |
bp->b_last_error != bp->b_error) { |
0b4db5dff xfs: remove extra... |
1076 |
bp->b_flags |= (XBF_WRITE | XBF_DONE | XBF_WRITE_FAIL); |
df3093907 xfs: add configur... |
1077 |
bp->b_last_error = bp->b_error; |
771698127 xfs: normalize "i... |
1078 1079 |
if (cfg->retry_timeout != XFS_ERR_RETRY_FOREVER && !bp->b_first_retry_time) |
5539d3675 xfs: don't reset ... |
1080 |
bp->b_first_retry_time = jiffies; |
a5ea70d25 xfs: add configur... |
1081 |
|
df3093907 xfs: add configur... |
1082 1083 1084 1085 |
xfs_buf_ioerror(bp, 0); xfs_buf_submit(bp); return true; } |
43ff2122e xfs: on-stack del... |
1086 |
|
df3093907 xfs: add configur... |
1087 1088 1089 1090 |
/* * Repeated failure on an async write. Take action according to the * error configuration we have been set up to use. */ |
a5ea70d25 xfs: add configur... |
1091 1092 1093 1094 |
if (cfg->max_retries != XFS_ERR_RETRY_FOREVER && ++bp->b_retries > cfg->max_retries) goto permanent_error; |
771698127 xfs: normalize "i... |
1095 |
if (cfg->retry_timeout != XFS_ERR_RETRY_FOREVER && |
a5ea70d25 xfs: add configur... |
1096 1097 |
time_after(jiffies, cfg->retry_timeout + bp->b_first_retry_time)) goto permanent_error; |
bfc60177f xfs: fix error ha... |
1098 |
|
e6b3bb789 xfs: add "fail at... |
1099 1100 1101 |
/* At unmount we may treat errors differently */ if ((mp->m_flags & XFS_MOUNT_UNMOUNTING) && mp->m_fail_unmount) goto permanent_error; |
0b80ae6ed xfs: Add infrastr... |
1102 1103 1104 1105 1106 |
/* * Still a transient error, run IO completion failure callbacks and let * the higher layers retry the buffer. */ xfs_buf_do_callbacks_fail(bp); |
df3093907 xfs: add configur... |
1107 1108 1109 |
xfs_buf_ioerror(bp, 0); xfs_buf_relse(bp); return true; |
0b1b213fc xfs: event tracin... |
1110 |
|
bfc60177f xfs: fix error ha... |
1111 |
/* |
df3093907 xfs: add configur... |
1112 1113 |
* Permanent error - we need to trigger a shutdown if we haven't already * to indicate that inconsistency will result from this action. |
bfc60177f xfs: fix error ha... |
1114 |
*/ |
df3093907 xfs: add configur... |
1115 1116 1117 |
permanent_error: xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); out_stale: |
c867cb616 xfs: remove XFS_B... |
1118 |
xfs_buf_stale(bp); |
b0388bf10 xfs: remove XBF_D... |
1119 |
bp->b_flags |= XBF_DONE; |
0b1b213fc xfs: event tracin... |
1120 |
trace_xfs_buf_error_relse(bp, _RET_IP_); |
df3093907 xfs: add configur... |
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 |
return false; } /* * This is the iodone() function for buffers which have had callbacks attached * to them by xfs_buf_attach_iodone(). We need to iterate the items on the * callback list, mark the buffer as having no more callbacks and then push the * buffer through IO completion processing. */ void xfs_buf_iodone_callbacks( struct xfs_buf *bp) { /* * If there is an error, process it. Some errors require us * to run callbacks after failure processing is done so we * detect that and take appropriate action. */ if (bp->b_error && xfs_buf_iodone_callback_error(bp)) return; /* * Successful IO or permanent error. Either way, we can clear the * retry state here in preparation for the next error that may occur. */ bp->b_last_error = 0; |
a5ea70d25 xfs: add configur... |
1147 |
bp->b_retries = 0; |
4dd2eb633 xfs: reset b_firs... |
1148 |
bp->b_first_retry_time = 0; |
0b1b213fc xfs: event tracin... |
1149 |
|
c90821a26 xfs: consume iodo... |
1150 |
xfs_buf_do_callbacks(bp); |
adadbeefb xfs: remove wrapp... |
1151 |
bp->b_fspriv = NULL; |
cb669ca57 xfs: remove wrapp... |
1152 |
bp->b_iodone = NULL; |
e8aaba9a7 xfs: xfs_buf_ioen... |
1153 |
xfs_buf_ioend(bp); |
1da177e4c Linux-2.6.12-rc2 |
1154 |
} |
1da177e4c Linux-2.6.12-rc2 |
1155 1156 1157 1158 1159 1160 1161 |
/* * This is the iodone() function for buffers which have been * logged. It is called when they are eventually flushed out. * It should remove the buf item from the AIL, and free the buf item. * It is called by xfs_buf_iodone_callbacks() above which will take * care of cleaning up the buffer itself. */ |
1da177e4c Linux-2.6.12-rc2 |
1162 1163 |
void xfs_buf_iodone( |
ca30b2a7b xfs: give li_cb c... |
1164 1165 |
struct xfs_buf *bp, struct xfs_log_item *lip) |
1da177e4c Linux-2.6.12-rc2 |
1166 |
{ |
ca30b2a7b xfs: give li_cb c... |
1167 |
struct xfs_ail *ailp = lip->li_ailp; |
1da177e4c Linux-2.6.12-rc2 |
1168 |
|
ca30b2a7b xfs: give li_cb c... |
1169 |
ASSERT(BUF_ITEM(lip)->bli_buf == bp); |
1da177e4c Linux-2.6.12-rc2 |
1170 |
|
e1f5dbd70 [XFS] Fix use-aft... |
1171 |
xfs_buf_rele(bp); |
1da177e4c Linux-2.6.12-rc2 |
1172 1173 1174 1175 1176 1177 |
/* * If we are forcibly shutting down, this may well be * off the AIL already. That's because we simulate the * log-committed callbacks to unpin these buffers. Or we may never * have put this item on AIL because of the transaction was |
783a2f656 [XFS] Finish remo... |
1178 |
* aborted forcibly. xfs_trans_ail_delete() takes care of these. |
1da177e4c Linux-2.6.12-rc2 |
1179 1180 1181 |
* * Either way, AIL is useless if we're forcing a shutdown. */ |
fc1829f34 [XFS] Add ail poi... |
1182 |
spin_lock(&ailp->xa_lock); |
04913fdd9 xfs: pass shutdow... |
1183 |
xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE); |
ca30b2a7b xfs: give li_cb c... |
1184 |
xfs_buf_item_free(BUF_ITEM(lip)); |
1da177e4c Linux-2.6.12-rc2 |
1185 |
} |
d3a304b62 xfs: Properly ret... |
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 |
/* * Requeue a failed buffer for writeback * * Return true if the buffer has been re-queued properly, false otherwise */ bool xfs_buf_resubmit_failed_buffers( struct xfs_buf *bp, struct xfs_log_item *lip, struct list_head *buffer_list) { struct xfs_log_item *next; /* * Clear XFS_LI_FAILED flag from all items before resubmit * * XFS_LI_FAILED set/clear is protected by xa_lock, caller this * function already have it acquired */ for (; lip; lip = next) { next = lip->li_bio_list; xfs_clear_li_failed(lip); } /* Add this buffer back to the delayed write list */ return xfs_buf_delwri_queue(bp, buffer_list); } |