Blame view

fs/xfs/xfs_trans_buf.c 23.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
7b7187698   Nathan Scott   [XFS] Update lice...
2
3
   * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
7b7187698   Nathan Scott   [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   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * published by the Free Software Foundation.
   *
7b7187698   Nathan Scott   [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   Linus Torvalds   Linux-2.6.12-rc2
13
   *
7b7187698   Nathan Scott   [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   Linus Torvalds   Linux-2.6.12-rc2
17
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
  #include "xfs.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
19
  #include "xfs_fs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
  #include "xfs_types.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
21
  #include "xfs_bit.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
  #include "xfs_log.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
23
  #include "xfs_inum.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  #include "xfs_trans.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
  #include "xfs_sb.h"
  #include "xfs_ag.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  #include "xfs_mount.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
28
29
30
  #include "xfs_bmap_btree.h"
  #include "xfs_alloc_btree.h"
  #include "xfs_ialloc_btree.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
31
32
33
  #include "xfs_dinode.h"
  #include "xfs_inode.h"
  #include "xfs_buf_item.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
  #include "xfs_trans_priv.h"
  #include "xfs_error.h"
  #include "xfs_rw.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
37
  #include "xfs_trace.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38

4a5224d7b   Christoph Hellwig   xfs: simplify buf...
39
40
41
42
43
44
45
46
47
48
49
  /*
   * Check to see if a buffer matching the given parameters is already
   * a part of the given transaction.
   */
  STATIC struct xfs_buf *
  xfs_trans_buf_item_match(
  	struct xfs_trans	*tp,
  	struct xfs_buftarg	*target,
  	xfs_daddr_t		blkno,
  	int			len)
  {
e98c414f9   Christoph Hellwig   xfs: simplify log...
50
51
  	struct xfs_log_item_desc *lidp;
  	struct xfs_buf_log_item	*blip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52

4a5224d7b   Christoph Hellwig   xfs: simplify buf...
53
  	len = BBTOB(len);
e98c414f9   Christoph Hellwig   xfs: simplify log...
54
55
56
  	list_for_each_entry(lidp, &tp->t_items, lid_trans) {
  		blip = (struct xfs_buf_log_item *)lidp->lid_item;
  		if (blip->bli_item.li_type == XFS_LI_BUF &&
49074c069   Chandra Seetharaman   xfs: Remove the m...
57
  		    blip->bli_buf->b_target == target &&
e98c414f9   Christoph Hellwig   xfs: simplify log...
58
59
60
  		    XFS_BUF_ADDR(blip->bli_buf) == blkno &&
  		    XFS_BUF_COUNT(blip->bli_buf) == len)
  			return blip->bli_buf;
4a5224d7b   Christoph Hellwig   xfs: simplify buf...
61
62
63
64
  	}
  
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65

d7e84f413   Christoph Hellwig   xfs: factor commo...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  /*
   * Add the locked buffer to the transaction.
   *
   * The buffer must be locked, and it cannot be associated with any
   * transaction.
   *
   * If the buffer does not yet have a buf log item associated with it,
   * then allocate one for it.  Then add the buf item to the transaction.
   */
  STATIC void
  _xfs_trans_bjoin(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp,
  	int			reset_recur)
  {
  	struct xfs_buf_log_item	*bip;
bf9d9013a   Christoph Hellwig   xfs: add a proper...
82
  	ASSERT(bp->b_transp == NULL);
d7e84f413   Christoph Hellwig   xfs: factor commo...
83
84
85
86
87
88
89
  
  	/*
  	 * The xfs_buf_log_item pointer is stored in b_fsprivate.  If
  	 * it doesn't have one yet, then allocate one and initialize it.
  	 * The checks to see if one is there are in xfs_buf_item_init().
  	 */
  	xfs_buf_item_init(bp, tp->t_mountp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
90
  	bip = bp->b_fspriv;
d7e84f413   Christoph Hellwig   xfs: factor commo...
91
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
c11554104   Dave Chinner   xfs: Clean up XFS...
92
  	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
d7e84f413   Christoph Hellwig   xfs: factor commo...
93
94
95
96
97
98
99
100
101
102
103
104
  	ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
  	if (reset_recur)
  		bip->bli_recur = 0;
  
  	/*
  	 * Take a reference for this transaction on the buf item.
  	 */
  	atomic_inc(&bip->bli_refcount);
  
  	/*
  	 * Get a log_item_desc to point at the new item.
  	 */
e98c414f9   Christoph Hellwig   xfs: simplify log...
105
  	xfs_trans_add_item(tp, &bip->bli_item);
d7e84f413   Christoph Hellwig   xfs: factor commo...
106
107
108
109
110
  
  	/*
  	 * Initialize b_fsprivate2 so we can find it with incore_match()
  	 * in xfs_trans_get_buf() and friends above.
  	 */
bf9d9013a   Christoph Hellwig   xfs: add a proper...
111
  	bp->b_transp = tp;
d7e84f413   Christoph Hellwig   xfs: factor commo...
112
113
114
115
116
117
118
119
120
121
122
  
  }
  
  void
  xfs_trans_bjoin(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp)
  {
  	_xfs_trans_bjoin(tp, bp, 0);
  	trace_xfs_trans_bjoin(bp->b_fspriv);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
125
126
127
128
129
  
  /*
   * Get and lock the buffer for the caller if it is not already
   * locked within the given transaction.  If it is already locked
   * within the transaction, just increment its lock recursion count
   * and return a pointer to it.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
133
134
135
136
137
138
139
140
141
142
143
   * If the transaction pointer is NULL, make this just a normal
   * get_buf() call.
   */
  xfs_buf_t *
  xfs_trans_get_buf(xfs_trans_t	*tp,
  		  xfs_buftarg_t	*target_dev,
  		  xfs_daddr_t	blkno,
  		  int		len,
  		  uint		flags)
  {
  	xfs_buf_t		*bp;
  	xfs_buf_log_item_t	*bip;
  
  	if (flags == 0)
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
144
  		flags = XBF_LOCK | XBF_MAPPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
  
  	/*
  	 * Default to a normal get_buf() call if the tp is NULL.
  	 */
6ad112bfb   Christoph Hellwig   xfs: simplify xfs...
149
  	if (tp == NULL)
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
150
151
  		return xfs_buf_get(target_dev, blkno, len,
  				   flags | XBF_DONT_BLOCK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
153
154
155
156
157
158
  
  	/*
  	 * If we find the buffer in the cache with this transaction
  	 * pointer in its b_fsprivate2 field, then we know we already
  	 * have it locked.  In this case we just increment the lock
  	 * recursion count and return the buffer to the caller.
  	 */
4a5224d7b   Christoph Hellwig   xfs: simplify buf...
159
  	bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  	if (bp != NULL) {
0c842ad46   Christoph Hellwig   xfs: clean up buf...
161
  		ASSERT(xfs_buf_islocked(bp));
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
162
163
  		if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
  			xfs_buf_stale(bp);
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
164
165
  			XFS_BUF_DONE(bp);
  		}
0b1b213fc   Christoph Hellwig   xfs: event tracin...
166

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
171
  		/*
  		 * If the buffer is stale then it was binval'ed
  		 * since last read.  This doesn't matter since the
  		 * caller isn't allowed to use the data anyway.
  		 */
0b1b213fc   Christoph Hellwig   xfs: event tracin...
172
  		else if (XFS_BUF_ISSTALE(bp))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  			ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
0b1b213fc   Christoph Hellwig   xfs: event tracin...
174

bf9d9013a   Christoph Hellwig   xfs: add a proper...
175
  		ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
176
  		bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
  		ASSERT(bip != NULL);
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
  		bip->bli_recur++;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
180
  		trace_xfs_trans_get_buf_recur(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
  		return (bp);
  	}
  
  	/*
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
185
186
  	 * We always specify the XBF_DONT_BLOCK flag within a transaction
  	 * so that get_buf does not try to push out a delayed write buffer
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
190
191
  	 * which might cause another transaction to take place (if the
  	 * buffer was delayed alloc).  Such recursive transactions can
  	 * easily deadlock with our current transaction as well as cause
  	 * us to run out of stack space.
  	 */
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
192
  	bp = xfs_buf_get(target_dev, blkno, len, flags | XBF_DONT_BLOCK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
195
  	if (bp == NULL) {
  		return NULL;
  	}
5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
196
  	ASSERT(!bp->b_error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

d7e84f413   Christoph Hellwig   xfs: factor commo...
198
199
  	_xfs_trans_bjoin(tp, bp, 1);
  	trace_xfs_trans_get_buf(bp->b_fspriv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  	return (bp);
  }
  
  /*
   * Get and lock the superblock buffer of this file system for the
   * given transaction.
   *
   * We don't need to use incore_match() here, because the superblock
   * buffer is a private buffer which we keep a pointer to in the
   * mount structure.
   */
  xfs_buf_t *
  xfs_trans_getsb(xfs_trans_t	*tp,
  		struct xfs_mount *mp,
  		int		flags)
  {
  	xfs_buf_t		*bp;
  	xfs_buf_log_item_t	*bip;
  
  	/*
  	 * Default to just trying to lock the superblock buffer
  	 * if tp is NULL.
  	 */
  	if (tp == NULL) {
  		return (xfs_getsb(mp, flags));
  	}
  
  	/*
  	 * If the superblock buffer already has this transaction
  	 * pointer in its b_fsprivate2 field, then we know we already
  	 * have it locked.  In this case we just increment the lock
  	 * recursion count and return the buffer to the caller.
  	 */
  	bp = mp->m_sb_bp;
bf9d9013a   Christoph Hellwig   xfs: add a proper...
234
  	if (bp->b_transp == tp) {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
235
  		bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
  		ASSERT(bip != NULL);
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
  		bip->bli_recur++;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
239
  		trace_xfs_trans_getsb_recur(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
242
243
  		return (bp);
  	}
  
  	bp = xfs_getsb(mp, flags);
d7e84f413   Christoph Hellwig   xfs: factor commo...
244
  	if (bp == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

d7e84f413   Christoph Hellwig   xfs: factor commo...
247
248
  	_xfs_trans_bjoin(tp, bp, 1);
  	trace_xfs_trans_getsb(bp->b_fspriv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  	return (bp);
  }
  
  #ifdef DEBUG
  xfs_buftarg_t *xfs_error_target;
  int	xfs_do_error;
  int	xfs_req_num;
  int	xfs_error_mod = 33;
  #endif
  
  /*
   * Get and lock the buffer for the caller if it is not already
   * locked within the given transaction.  If it has not yet been
   * read in, read it from disk. If it is already locked
   * within the transaction and already read in, just increment its
   * lock recursion count and return a pointer to it.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
   * If the transaction pointer is NULL, make this just a normal
   * read_buf() call.
   */
  int
  xfs_trans_read_buf(
  	xfs_mount_t	*mp,
  	xfs_trans_t	*tp,
  	xfs_buftarg_t	*target,
  	xfs_daddr_t	blkno,
  	int		len,
  	uint		flags,
  	xfs_buf_t	**bpp)
  {
  	xfs_buf_t		*bp;
  	xfs_buf_log_item_t	*bip;
  	int			error;
  
  	if (flags == 0)
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
284
  		flags = XBF_LOCK | XBF_MAPPED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
289
  
  	/*
  	 * Default to a normal get_buf() call if the tp is NULL.
  	 */
  	if (tp == NULL) {
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
290
  		bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  		if (!bp)
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
292
  			return (flags & XBF_TRYLOCK) ?
a3f74ffb6   David Chinner   [XFS] Don't block...
293
  					EAGAIN : XFS_ERROR(ENOMEM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294

5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
295
296
  		if (bp->b_error) {
  			error = bp->b_error;
901796afc   Christoph Hellwig   xfs: clean up xfs...
297
  			xfs_buf_ioerror_alert(bp, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
301
  			xfs_buf_relse(bp);
  			return error;
  		}
  #ifdef DEBUG
a0f7bfd34   Julia Lawall   fs/xfs: Correct r...
302
  		if (xfs_do_error) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303
304
305
  			if (xfs_error_target == target) {
  				if (((xfs_req_num++) % xfs_error_mod) == 0) {
  					xfs_buf_relse(bp);
0b932cccb   Dave Chinner   xfs: Convert rema...
306
  					xfs_debug(mp, "Returning error!");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  					return XFS_ERROR(EIO);
  				}
  			}
  		}
  #endif
  		if (XFS_FORCED_SHUTDOWN(mp))
  			goto shutdown_abort;
  		*bpp = bp;
  		return 0;
  	}
  
  	/*
  	 * If we find the buffer in the cache with this transaction
  	 * pointer in its b_fsprivate2 field, then we know we already
  	 * have it locked.  If it is already read in we just increment
  	 * the lock recursion count and return the buffer to the caller.
  	 * If the buffer is not yet read in, then we read it in, increment
  	 * the lock recursion count, and return it to the caller.
  	 */
4a5224d7b   Christoph Hellwig   xfs: simplify buf...
326
  	bp = xfs_trans_buf_item_match(tp, target, blkno, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  	if (bp != NULL) {
0c842ad46   Christoph Hellwig   xfs: clean up buf...
328
  		ASSERT(xfs_buf_islocked(bp));
bf9d9013a   Christoph Hellwig   xfs: add a proper...
329
  		ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
330
  		ASSERT(bp->b_fspriv != NULL);
5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
331
  		ASSERT(!bp->b_error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
  		if (!(XFS_BUF_ISDONE(bp))) {
0b1b213fc   Christoph Hellwig   xfs: event tracin...
333
  			trace_xfs_trans_read_buf_io(bp, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
335
336
  			ASSERT(!XFS_BUF_ISASYNC(bp));
  			XFS_BUF_READ(bp);
  			xfsbdstrat(tp->t_mountp, bp);
1a1a3e97b   Christoph Hellwig   xfs: remove xfs_b...
337
  			error = xfs_buf_iowait(bp);
d64e31a2f   David Chinner   [XFS] Ensure erro...
338
  			if (error) {
901796afc   Christoph Hellwig   xfs: clean up xfs...
339
  				xfs_buf_ioerror_alert(bp, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
  				xfs_buf_relse(bp);
  				/*
d64e31a2f   David Chinner   [XFS] Ensure erro...
342
343
344
  				 * We can gracefully recover from most read
  				 * errors. Ones we can't are those that happen
  				 * after the transaction's already dirty.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
347
  				 */
  				if (tp->t_flags & XFS_TRANS_DIRTY)
  					xfs_force_shutdown(tp->t_mountp,
7d04a335b   Nathan Scott   [XFS] Shutdown th...
348
  							SHUTDOWN_META_IO_ERROR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
356
  				return error;
  			}
  		}
  		/*
  		 * We never locked this buf ourselves, so we shouldn't
  		 * brelse it either. Just get out.
  		 */
  		if (XFS_FORCED_SHUTDOWN(mp)) {
0b1b213fc   Christoph Hellwig   xfs: event tracin...
357
  			trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
  			*bpp = NULL;
  			return XFS_ERROR(EIO);
  		}
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
361
  		bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
363
364
  		bip->bli_recur++;
  
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
365
  		trace_xfs_trans_read_buf_recur(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
367
368
369
370
  		*bpp = bp;
  		return 0;
  	}
  
  	/*
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
371
372
  	 * We always specify the XBF_DONT_BLOCK flag within a transaction
  	 * so that get_buf does not try to push out a delayed write buffer
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
  	 * which might cause another transaction to take place (if the
  	 * buffer was delayed alloc).  Such recursive transactions can
  	 * easily deadlock with our current transaction as well as cause
  	 * us to run out of stack space.
  	 */
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
378
  	bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
  	if (bp == NULL) {
  		*bpp = NULL;
7401aafd5   Dave Chinner   xfs: xfs_trans_re...
381
382
  		return (flags & XBF_TRYLOCK) ?
  					0 : XFS_ERROR(ENOMEM);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  	}
5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
384
385
  	if (bp->b_error) {
  		error = bp->b_error;
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
386
  		xfs_buf_stale(bp);
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
387
  		XFS_BUF_DONE(bp);
901796afc   Christoph Hellwig   xfs: clean up xfs...
388
  		xfs_buf_ioerror_alert(bp, __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  		if (tp->t_flags & XFS_TRANS_DIRTY)
7d04a335b   Nathan Scott   [XFS] Shutdown th...
390
  			xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
393
394
395
396
397
398
  		xfs_buf_relse(bp);
  		return error;
  	}
  #ifdef DEBUG
  	if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
  		if (xfs_error_target == target) {
  			if (((xfs_req_num++) % xfs_error_mod) == 0) {
  				xfs_force_shutdown(tp->t_mountp,
7d04a335b   Nathan Scott   [XFS] Shutdown th...
399
  						   SHUTDOWN_META_IO_ERROR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  				xfs_buf_relse(bp);
0b932cccb   Dave Chinner   xfs: Convert rema...
401
  				xfs_debug(mp, "Returning trans error!");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
406
407
408
  				return XFS_ERROR(EIO);
  			}
  		}
  	}
  #endif
  	if (XFS_FORCED_SHUTDOWN(mp))
  		goto shutdown_abort;
d7e84f413   Christoph Hellwig   xfs: factor commo...
409
410
  	_xfs_trans_bjoin(tp, bp, 1);
  	trace_xfs_trans_read_buf(bp->b_fspriv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
416
417
418
419
420
421
422
423
  	*bpp = bp;
  	return 0;
  
  shutdown_abort:
  	/*
  	 * the theory here is that buffer is good but we're
  	 * bailing out because the filesystem is being forcibly
  	 * shut down.  So we should leave the b_flags alone since
  	 * the buffer's not staled and just get out.
  	 */
  #if defined(DEBUG)
  	if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp))
0b932cccb   Dave Chinner   xfs: Convert rema...
424
  		xfs_notice(mp, "about to pop assert, bp == 0x%p", bp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
  #endif
ed43233be   Chandra Seetharaman   xfs: Remove the m...
426
  	ASSERT((bp->b_flags & (XBF_STALE|XBF_DELWRI)) !=
0cadda1c5   Christoph Hellwig   xfs: remove dupli...
427
  				     (XBF_STALE|XBF_DELWRI));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428

0b1b213fc   Christoph Hellwig   xfs: event tracin...
429
  	trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  	xfs_buf_relse(bp);
  	*bpp = NULL;
  	return XFS_ERROR(EIO);
  }
  
  
  /*
   * Release the buffer bp which was previously acquired with one of the
   * xfs_trans_... buffer allocation routines if the buffer has not
   * been modified within this transaction.  If the buffer is modified
   * within this transaction, do decrement the recursion count but do
   * not release the buffer even if the count goes to 0.  If the buffer is not
   * modified within the transaction, decrement the recursion count and
   * release the buffer if the recursion count goes to 0.
   *
   * If the buffer is to be released and it was not modified before
   * this transaction began, then free the buf_log_item associated with it.
   *
   * If the transaction pointer is NULL, make this just a normal
   * brelse() call.
   */
  void
  xfs_trans_brelse(xfs_trans_t	*tp,
  		 xfs_buf_t	*bp)
  {
  	xfs_buf_log_item_t	*bip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
459
460
  
  	/*
  	 * Default to a normal brelse() call if the tp is NULL.
  	 */
  	if (tp == NULL) {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
461
  		struct xfs_log_item	*lip = bp->b_fspriv;
bf9d9013a   Christoph Hellwig   xfs: add a proper...
462
  		ASSERT(bp->b_transp == NULL);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
463

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
467
468
  		/*
  		 * If there's a buf log item attached to the buffer,
  		 * then let the AIL know that the buffer is being
  		 * unlocked.
  		 */
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
469
470
471
  		if (lip != NULL && lip->li_type == XFS_LI_BUF) {
  			bip = bp->b_fspriv;
  			xfs_trans_unlocked_item(bip->bli_item.li_ailp, lip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
474
475
  		}
  		xfs_buf_relse(bp);
  		return;
  	}
bf9d9013a   Christoph Hellwig   xfs: add a proper...
476
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
477
  	bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
478
479
  	ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
c11554104   Dave Chinner   xfs: Clean up XFS...
480
  	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
482
  	trace_xfs_trans_brelse(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
484
485
486
487
488
  	/*
  	 * If the release is just for a recursive lock,
  	 * then decrement the count and return.
  	 */
  	if (bip->bli_recur > 0) {
  		bip->bli_recur--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
491
492
493
494
495
  		return;
  	}
  
  	/*
  	 * If the buffer is dirty within this transaction, we can't
  	 * release it until we commit.
  	 */
e98c414f9   Christoph Hellwig   xfs: simplify log...
496
  	if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
502
503
504
  
  	/*
  	 * If the buffer has been invalidated, then we can't release
  	 * it until the transaction commits to disk unless it is re-dirtied
  	 * as part of this transaction.  This prevents us from pulling
  	 * the item from the AIL before we should.
  	 */
0b1b213fc   Christoph Hellwig   xfs: event tracin...
505
  	if (bip->bli_flags & XFS_BLI_STALE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
  
  	ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
511
512
  
  	/*
  	 * Free up the log item descriptor tracking the released item.
  	 */
e98c414f9   Christoph Hellwig   xfs: simplify log...
513
  	xfs_trans_del_item(&bip->bli_item);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
  
  	/*
  	 * Clear the hold flag in the buf log item if it is set.
  	 * We wouldn't want the next user of the buffer to
  	 * get confused.
  	 */
  	if (bip->bli_flags & XFS_BLI_HOLD) {
  		bip->bli_flags &= ~XFS_BLI_HOLD;
  	}
  
  	/*
  	 * Drop our reference to the buf log item.
  	 */
  	atomic_dec(&bip->bli_refcount);
  
  	/*
  	 * If the buf item is not tracking data in the log, then
  	 * we must free it before releasing the buffer back to the
  	 * free pool.  Before releasing the buffer to the free pool,
  	 * clear the transaction pointer in b_fsprivate2 to dissolve
  	 * its relation to this transaction.
  	 */
  	if (!xfs_buf_item_dirty(bip)) {
  /***
  		ASSERT(bp->b_pincount == 0);
  ***/
  		ASSERT(atomic_read(&bip->bli_refcount) == 0);
  		ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
  		ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
  		xfs_buf_item_relse(bp);
  		bip = NULL;
  	}
bf9d9013a   Christoph Hellwig   xfs: add a proper...
546
  	bp->b_transp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
549
550
551
552
  
  	/*
  	 * If we've still got a buf log item on the buffer, then
  	 * tell the AIL that the buffer is being unlocked.
  	 */
  	if (bip != NULL) {
783a2f656   David Chinner   [XFS] Finish remo...
553
  		xfs_trans_unlocked_item(bip->bli_item.li_ailp,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
556
557
558
559
560
561
  					(xfs_log_item_t*)bip);
  	}
  
  	xfs_buf_relse(bp);
  	return;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
564
565
566
567
568
569
570
   * Mark the buffer as not needing to be unlocked when the buf item's
   * IOP_UNLOCK() routine is called.  The buffer must already be locked
   * and associated with the given transaction.
   */
  /* ARGSUSED */
  void
  xfs_trans_bhold(xfs_trans_t	*tp,
  		xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
571
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
572

bf9d9013a   Christoph Hellwig   xfs: add a proper...
573
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
574
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
c11554104   Dave Chinner   xfs: Clean up XFS...
576
  	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
578

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
579
  	bip->bli_flags |= XFS_BLI_HOLD;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
580
  	trace_xfs_trans_bhold(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
582
583
  }
  
  /*
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
584
585
586
587
588
589
590
   * Cancel the previous buffer hold request made on this buffer
   * for this transaction.
   */
  void
  xfs_trans_bhold_release(xfs_trans_t	*tp,
  			xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
591
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
592

bf9d9013a   Christoph Hellwig   xfs: add a proper...
593
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
594
  	ASSERT(bip != NULL);
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
595
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
c11554104   Dave Chinner   xfs: Clean up XFS...
596
  	ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
597
598
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  	ASSERT(bip->bli_flags & XFS_BLI_HOLD);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
599

adadbeefb   Christoph Hellwig   xfs: remove wrapp...
600
  	bip->bli_flags &= ~XFS_BLI_HOLD;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
601
  	trace_xfs_trans_bhold_release(bip);
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
602
603
604
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
606
607
608
609
610
611
612
613
614
615
616
617
618
   * This is called to mark bytes first through last inclusive of the given
   * buffer as needing to be logged when the transaction is committed.
   * The buffer must already be associated with the given transaction.
   *
   * First and last are numbers relative to the beginning of this buffer,
   * so the first byte in the buffer is numbered 0 regardless of the
   * value of b_blkno.
   */
  void
  xfs_trans_log_buf(xfs_trans_t	*tp,
  		  xfs_buf_t	*bp,
  		  uint		first,
  		  uint		last)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
619
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620

bf9d9013a   Christoph Hellwig   xfs: add a proper...
621
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
622
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  	ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));
cb669ca57   Christoph Hellwig   xfs: remove wrapp...
624
625
  	ASSERT(bp->b_iodone == NULL ||
  	       bp->b_iodone == xfs_buf_iodone_callbacks);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
629
630
631
632
633
634
635
636
  
  	/*
  	 * Mark the buffer as needing to be written out eventually,
  	 * and set its iodone function to remove the buffer's buf log
  	 * item from the AIL and free it when the buffer is flushed
  	 * to disk.  See xfs_buf_attach_iodone() for more details
  	 * on li_cb and xfs_buf_iodone_callbacks().
  	 * If we end up aborting this transaction, we trap this buffer
  	 * inside the b_bdstrat callback so that this won't get written to
  	 * disk.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
637
  	XFS_BUF_DONE(bp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
cb669ca57   Christoph Hellwig   xfs: remove wrapp...
639
  	bp->b_iodone = xfs_buf_iodone_callbacks;
ca30b2a7b   Christoph Hellwig   xfs: give li_cb c...
640
  	bip->bli_item.li_cb = xfs_buf_iodone;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641

61551f1ee   Christoph Hellwig   xfs: call xfs_buf...
642
  	xfs_buf_delwri_queue(bp);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
643
  	trace_xfs_trans_log_buf(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
645
646
647
648
649
650
  	/*
  	 * If we invalidated the buffer within this transaction, then
  	 * cancel the invalidation now that we're dirtying the buffer
  	 * again.  There are no races with the code in xfs_buf_item_unpin(),
  	 * because we have a reference to the buffer this entire time.
  	 */
  	if (bip->bli_flags & XFS_BLI_STALE) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
653
  		bip->bli_flags &= ~XFS_BLI_STALE;
  		ASSERT(XFS_BUF_ISSTALE(bp));
  		XFS_BUF_UNSTALE(bp);
c11554104   Dave Chinner   xfs: Clean up XFS...
654
  		bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  	tp->t_flags |= XFS_TRANS_DIRTY;
e98c414f9   Christoph Hellwig   xfs: simplify log...
657
  	bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
  	bip->bli_flags |= XFS_BLI_LOGGED;
  	xfs_buf_item_log(bip, first, last);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
  }
  
  
  /*
   * This called to invalidate a buffer that is being used within
   * a transaction.  Typically this is because the blocks in the
   * buffer are being freed, so we need to prevent it from being
   * written out when we're done.  Allowing it to be written again
   * might overwrite data in the free blocks if they are reallocated
   * to a file.
   *
   * We prevent the buffer from being written out by clearing the
   * B_DELWRI flag.  We can't always
   * get rid of the buf log item at this point, though, because
   * the buffer may still be pinned by another transaction.  If that
   * is the case, then we'll wait until the buffer is committed to
   * disk for the last time (we can tell by the ref count) and
   * free it in xfs_buf_item_unpin().  Until it is cleaned up we
   * will keep the buffer locked so that the buffer and buf log item
   * are not reused.
   */
  void
  xfs_trans_binval(
  	xfs_trans_t	*tp,
  	xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
686
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
687

bf9d9013a   Christoph Hellwig   xfs: add a proper...
688
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
689
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
691
  	trace_xfs_trans_binval(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
693
694
695
696
697
698
699
  	if (bip->bli_flags & XFS_BLI_STALE) {
  		/*
  		 * If the buffer is already invalidated, then
  		 * just return.
  		 */
  		ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
  		ASSERT(XFS_BUF_ISSTALE(bp));
  		ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
c11554104   Dave Chinner   xfs: Clean up XFS...
700
701
  		ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF));
  		ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
e98c414f9   Christoph Hellwig   xfs: simplify log...
702
  		ASSERT(bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
  		ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
707
708
709
710
711
  		return;
  	}
  
  	/*
  	 * Clear the dirty bit in the buffer and set the STALE flag
  	 * in the buf log item.  The STALE flag will be used in
  	 * xfs_buf_item_unpin() to determine if it should clean up
  	 * when the last reference to the buf item is given up.
c11554104   Dave Chinner   xfs: Clean up XFS...
712
  	 * We set the XFS_BLF_CANCEL flag in the buf log format structure
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
714
715
716
717
718
719
720
721
722
723
724
725
726
  	 * and log the buf item.  This will be used at recovery time
  	 * to determine that copies of the buffer in the log before
  	 * this should not be replayed.
  	 * We mark the item descriptor and the transaction dirty so
  	 * that we'll hold the buffer until after the commit.
  	 *
  	 * Since we're invalidating the buffer, we also clear the state
  	 * about which parts of the buffer have been logged.  We also
  	 * clear the flag indicating that this is an inode buffer since
  	 * the data in the buffer will no longer be valid.
  	 *
  	 * We set the stale bit in the buffer as well since we're getting
  	 * rid of it.
  	 */
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
727
  	xfs_buf_stale(bp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
728
  	bip->bli_flags |= XFS_BLI_STALE;
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
729
  	bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
c11554104   Dave Chinner   xfs: Clean up XFS...
730
731
  	bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
  	bip->bli_format.blf_flags |= XFS_BLF_CANCEL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
  	memset((char *)(bip->bli_format.blf_data_map), 0,
  	      (bip->bli_format.blf_map_size * sizeof(uint)));
e98c414f9   Christoph Hellwig   xfs: simplify log...
734
  	bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
735
  	tp->t_flags |= XFS_TRANS_DIRTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
737
738
  }
  
  /*
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
739
740
741
742
743
   * This call is used to indicate that the buffer contains on-disk inodes which
   * must be handled specially during recovery.  They require special handling
   * because only the di_next_unlinked from the inodes in the buffer should be
   * recovered.  The rest of the data in the buffer is logged via the inodes
   * themselves.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
744
   *
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
745
746
747
   * All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be
   * transferred to the buffer's log format structure so that we'll know what to
   * do at recovery time.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
751
752
753
  void
  xfs_trans_inode_buf(
  	xfs_trans_t	*tp,
  	xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
754
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755

bf9d9013a   Christoph Hellwig   xfs: add a proper...
756
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
757
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
758
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
759
  	bip->bli_flags |= XFS_BLI_INODE_BUF;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
  }
  
  /*
   * This call is used to indicate that the buffer is going to
   * be staled and was an inode buffer. This means it gets
   * special processing during unpin - where any inodes 
   * associated with the buffer should be removed from ail.
   * There is also special processing during recovery,
   * any replay of the inodes in the buffer needs to be
   * prevented as the buffer may have been reused.
   */
  void
  xfs_trans_stale_inode_buf(
  	xfs_trans_t	*tp,
  	xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
776
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777

bf9d9013a   Christoph Hellwig   xfs: add a proper...
778
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
779
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
782
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  
  	bip->bli_flags |= XFS_BLI_STALE_INODE;
ca30b2a7b   Christoph Hellwig   xfs: give li_cb c...
783
  	bip->bli_item.li_cb = xfs_buf_iodone;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
786
787
788
789
790
791
792
793
794
795
796
797
798
  /*
   * Mark the buffer as being one which contains newly allocated
   * inodes.  We need to make sure that even if this buffer is
   * relogged as an 'inode buf' we still recover all of the inode
   * images in the face of a crash.  This works in coordination with
   * xfs_buf_item_committed() to ensure that the buffer remains in the
   * AIL at its original location even after it has been relogged.
   */
  /* ARGSUSED */
  void
  xfs_trans_inode_alloc_buf(
  	xfs_trans_t	*tp,
  	xfs_buf_t	*bp)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
799
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800

bf9d9013a   Christoph Hellwig   xfs: add a proper...
801
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
802
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  
  	bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
  }
  
  
  /*
   * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
   * dquots. However, unlike in inode buffer recovery, dquot buffers get
   * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag).
   * The only thing that makes dquot buffers different from regular
   * buffers is that we must not replay dquot bufs when recovering
   * if a _corresponding_ quotaoff has happened. We also have to distinguish
   * between usr dquot bufs and grp dquot bufs, because usr and grp quotas
   * can be turned off independently.
   */
  /* ARGSUSED */
  void
  xfs_trans_dquot_buf(
  	xfs_trans_t	*tp,
  	xfs_buf_t	*bp,
  	uint		type)
  {
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
826
  	xfs_buf_log_item_t	*bip = bp->b_fspriv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827

bf9d9013a   Christoph Hellwig   xfs: add a proper...
828
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
829
  	ASSERT(bip != NULL);
c11554104   Dave Chinner   xfs: Clean up XFS...
830
831
832
  	ASSERT(type == XFS_BLF_UDQUOT_BUF ||
  	       type == XFS_BLF_PDQUOT_BUF ||
  	       type == XFS_BLF_GDQUOT_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
834
835
836
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  
  	bip->bli_format.blf_flags |= type;
  }