Blame view

fs/xfs/xfs_trans_buf.c 20.2 KB
0b61f8a40   Dave Chinner   xfs: convert to S...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
7b7187698   Nathan Scott   [XFS] Update lice...
3
4
   * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
  #include "xfs.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
7
  #include "xfs_fs.h"
70a9883c5   Dave Chinner   xfs: create a sha...
8
  #include "xfs_shared.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
9
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
10
11
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
  #include "xfs_mount.h"
239880ef6   Dave Chinner   xfs: decouple log...
13
  #include "xfs_trans.h"
a844f4510   Nathan Scott   [XFS] Remove xfs_...
14
  #include "xfs_buf_item.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include "xfs_trans_priv.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
16
  #include "xfs_trace.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17

4a5224d7b   Christoph Hellwig   xfs: simplify buf...
18
19
20
21
22
23
24
25
  /*
   * 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,
de2a4f591   Dave Chinner   xfs: add disconti...
26
27
  	struct xfs_buf_map	*map,
  	int			nmaps)
4a5224d7b   Christoph Hellwig   xfs: simplify buf...
28
  {
e6631f855   Dave Chinner   xfs: get rid of t...
29
  	struct xfs_log_item	*lip;
e98c414f9   Christoph Hellwig   xfs: simplify log...
30
  	struct xfs_buf_log_item	*blip;
de2a4f591   Dave Chinner   xfs: add disconti...
31
32
33
34
35
  	int			len = 0;
  	int			i;
  
  	for (i = 0; i < nmaps; i++)
  		len += map[i].bm_len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

e6631f855   Dave Chinner   xfs: get rid of t...
37
38
  	list_for_each_entry(lip, &tp->t_items, li_trans) {
  		blip = (struct xfs_buf_log_item *)lip;
e98c414f9   Christoph Hellwig   xfs: simplify log...
39
  		if (blip->bli_item.li_type == XFS_LI_BUF &&
49074c069   Chandra Seetharaman   xfs: Remove the m...
40
  		    blip->bli_buf->b_target == target &&
de2a4f591   Dave Chinner   xfs: add disconti...
41
42
43
  		    XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn &&
  		    blip->bli_buf->b_length == len) {
  			ASSERT(blip->bli_buf->b_map_count == nmaps);
e98c414f9   Christoph Hellwig   xfs: simplify log...
44
  			return blip->bli_buf;
de2a4f591   Dave Chinner   xfs: add disconti...
45
  		}
4a5224d7b   Christoph Hellwig   xfs: simplify buf...
46
47
48
49
  	}
  
  	return NULL;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50

d7e84f413   Christoph Hellwig   xfs: factor commo...
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  /*
   * 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...
67
  	ASSERT(bp->b_transp == NULL);
d7e84f413   Christoph Hellwig   xfs: factor commo...
68
69
  
  	/*
fb1755a64   Carlos Maiolino   Split buffer's b_...
70
  	 * The xfs_buf_log_item pointer is stored in b_log_item.  If
d7e84f413   Christoph Hellwig   xfs: factor commo...
71
72
73
74
  	 * 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);
fb1755a64   Carlos Maiolino   Split buffer's b_...
75
  	bip = bp->b_log_item;
d7e84f413   Christoph Hellwig   xfs: factor commo...
76
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
77
  	ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
d7e84f413   Christoph Hellwig   xfs: factor commo...
78
79
80
81
82
83
84
85
86
87
  	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);
  
  	/*
e6631f855   Dave Chinner   xfs: get rid of t...
88
89
  	 * Attach the item to the transaction so we can find it in
  	 * xfs_trans_get_buf() and friends.
d7e84f413   Christoph Hellwig   xfs: factor commo...
90
  	 */
e98c414f9   Christoph Hellwig   xfs: simplify log...
91
  	xfs_trans_add_item(tp, &bip->bli_item);
bf9d9013a   Christoph Hellwig   xfs: add a proper...
92
  	bp->b_transp = tp;
d7e84f413   Christoph Hellwig   xfs: factor commo...
93
94
95
96
97
98
99
100
101
  
  }
  
  void
  xfs_trans_bjoin(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp)
  {
  	_xfs_trans_bjoin(tp, bp, 0);
fb1755a64   Carlos Maiolino   Split buffer's b_...
102
  	trace_xfs_trans_bjoin(bp->b_log_item);
d7e84f413   Christoph Hellwig   xfs: factor commo...
103
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
  
  /*
   * 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
111
112
113
   * If the transaction pointer is NULL, make this just a normal
   * get_buf() call.
   */
9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
114
  int
de2a4f591   Dave Chinner   xfs: add disconti...
115
116
117
118
119
  xfs_trans_get_buf_map(
  	struct xfs_trans	*tp,
  	struct xfs_buftarg	*target,
  	struct xfs_buf_map	*map,
  	int			nmaps,
9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
120
121
  	xfs_buf_flags_t		flags,
  	struct xfs_buf		**bpp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
  {
  	xfs_buf_t		*bp;
70a206553   Carlos Maiolino   Get rid of xfs_bu...
124
  	struct xfs_buf_log_item	*bip;
3848b5f67   Darrick J. Wong   xfs: make xfs_buf...
125
  	int			error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126

9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
127
128
129
  	*bpp = NULL;
  	if (!tp)
  		return xfs_buf_get_map(target, map, nmaps, flags, bpp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
133
134
135
136
  
  	/*
  	 * 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.
  	 */
de2a4f591   Dave Chinner   xfs: add disconti...
137
  	bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  	if (bp != NULL) {
0c842ad46   Christoph Hellwig   xfs: clean up buf...
139
  		ASSERT(xfs_buf_islocked(bp));
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
140
141
  		if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
  			xfs_buf_stale(bp);
b0388bf10   Dave Chinner   xfs: remove XBF_D...
142
  			bp->b_flags |= XBF_DONE;
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
143
  		}
0b1b213fc   Christoph Hellwig   xfs: event tracin...
144

bf9d9013a   Christoph Hellwig   xfs: add a proper...
145
  		ASSERT(bp->b_transp == tp);
fb1755a64   Carlos Maiolino   Split buffer's b_...
146
  		bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
148
149
  		ASSERT(bip != NULL);
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
  		bip->bli_recur++;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
150
  		trace_xfs_trans_get_buf_recur(bip);
9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
151
152
  		*bpp = bp;
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  	}
3848b5f67   Darrick J. Wong   xfs: make xfs_buf...
154
155
  	error = xfs_buf_get_map(target, map, nmaps, flags, &bp);
  	if (error)
9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
156
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
158
  	ASSERT(!bp->b_error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

d7e84f413   Christoph Hellwig   xfs: factor commo...
160
  	_xfs_trans_bjoin(tp, bp, 1);
fb1755a64   Carlos Maiolino   Split buffer's b_...
161
  	trace_xfs_trans_get_buf(bp->b_log_item);
9676b54e6   Darrick J. Wong   xfs: make xfs_tra...
162
163
  	*bpp = bp;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
165
166
  }
  
  /*
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
167
   * Get and lock the superblock buffer for the given transaction.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
   */
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
169
  struct xfs_buf *
70a206553   Carlos Maiolino   Get rid of xfs_bu...
170
  xfs_trans_getsb(
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
171
  	struct xfs_trans	*tp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  {
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
173
  	struct xfs_buf		*bp = tp->t_mountp->m_sb_bp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
  
  	/*
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
176
177
  	 * Just increment the lock recursion count if the buffer is already
  	 * attached to this transaction.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
  	 */
bf9d9013a   Christoph Hellwig   xfs: add a proper...
179
  	if (bp->b_transp == tp) {
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
180
  		struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
  		ASSERT(bip != NULL);
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
  		bip->bli_recur++;
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
184

0b1b213fc   Christoph Hellwig   xfs: event tracin...
185
  		trace_xfs_trans_getsb_recur(bip);
cead0b10f   Christoph Hellwig   xfs: simplify xfs...
186
187
188
189
  	} else {
  		xfs_buf_lock(bp);
  		xfs_buf_hold(bp);
  		_xfs_trans_bjoin(tp, bp, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190

cead0b10f   Christoph Hellwig   xfs: simplify xfs...
191
192
  		trace_xfs_trans_getsb(bp->b_log_item);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193

d99831ff3   Eric Sandeen   xfs: return is no...
194
  	return bp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
197
198
199
200
201
202
  /*
   * 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
203
204
205
206
   * If the transaction pointer is NULL, make this just a normal
   * read_buf() call.
   */
  int
de2a4f591   Dave Chinner   xfs: add disconti...
207
208
209
210
211
212
213
  xfs_trans_read_buf_map(
  	struct xfs_mount	*mp,
  	struct xfs_trans	*tp,
  	struct xfs_buftarg	*target,
  	struct xfs_buf_map	*map,
  	int			nmaps,
  	xfs_buf_flags_t		flags,
c3f8fc73a   Dave Chinner   xfs: make buffer ...
214
  	struct xfs_buf		**bpp,
1813dd640   Dave Chinner   xfs: convert buff...
215
  	const struct xfs_buf_ops *ops)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  {
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
217
218
  	struct xfs_buf		*bp = NULL;
  	struct xfs_buf_log_item	*bip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
  	int			error;
7ca790a50   Dave Chinner   xfs: kill xfs_rea...
220
  	*bpp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
222
223
224
225
226
227
228
  	/*
  	 * 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.
  	 */
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
229
230
231
  	if (tp)
  		bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
  	if (bp) {
0c842ad46   Christoph Hellwig   xfs: clean up buf...
232
  		ASSERT(xfs_buf_islocked(bp));
bf9d9013a   Christoph Hellwig   xfs: add a proper...
233
  		ASSERT(bp->b_transp == tp);
fb1755a64   Carlos Maiolino   Split buffer's b_...
234
  		ASSERT(bp->b_log_item != NULL);
5a52c2a58   Chandra Seetharaman   xfs: Remove the m...
235
  		ASSERT(!bp->b_error);
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
236
  		ASSERT(bp->b_flags & XBF_DONE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
239
240
241
  		/*
  		 * 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...
242
  			trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
2451337dd   Dave Chinner   xfs: global error...
243
  			return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
  		}
1aff5696f   Darrick J. Wong   xfs: always assig...
245
246
247
248
249
250
251
252
253
254
255
256
257
  		/*
  		 * Check if the caller is trying to read a buffer that is
  		 * already attached to the transaction yet has no buffer ops
  		 * assigned.  Ops are usually attached when the buffer is
  		 * attached to the transaction, or by the read caller if
  		 * special circumstances.  That didn't happen, which is not
  		 * how this is supposed to go.
  		 *
  		 * If the buffer passes verification we'll let this go, but if
  		 * not we have to shut down.  Let the transaction cleanup code
  		 * release this buffer when it kills the tranaction.
  		 */
  		ASSERT(bp->b_ops != NULL);
75d023031   Brian Foster   xfs: clarify docu...
258
  		error = xfs_buf_reverify(bp, ops);
1aff5696f   Darrick J. Wong   xfs: always assig...
259
  		if (error) {
cdbcf82b8   Darrick J. Wong   xfs: fix xfs_buf_...
260
  			xfs_buf_ioerror_alert(bp, __return_address);
1aff5696f   Darrick J. Wong   xfs: always assig...
261
262
263
264
265
266
267
268
269
270
  
  			if (tp->t_flags & XFS_TRANS_DIRTY)
  				xfs_force_shutdown(tp->t_mountp,
  						SHUTDOWN_META_IO_ERROR);
  
  			/* bad CRC means corrupted metadata */
  			if (error == -EFSBADCRC)
  				error = -EFSCORRUPTED;
  			return error;
  		}
fb1755a64   Carlos Maiolino   Split buffer's b_...
271
  		bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
273
274
  		bip->bli_recur++;
  
  		ASSERT(atomic_read(&bip->bli_refcount) > 0);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
275
  		trace_xfs_trans_read_buf_recur(bip);
1aff5696f   Darrick J. Wong   xfs: always assig...
276
  		ASSERT(bp->b_ops != NULL || ops == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
279
  		*bpp = bp;
  		return 0;
  	}
cdbcf82b8   Darrick J. Wong   xfs: fix xfs_buf_...
280
281
  	error = xfs_buf_read_map(target, map, nmaps, flags, &bp, ops,
  			__return_address);
4ed8e27b4   Darrick J. Wong   xfs: make xfs_buf...
282
283
284
285
  	switch (error) {
  	case 0:
  		break;
  	default:
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
286
  		if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
7d04a335b   Nathan Scott   [XFS] Shutdown th...
287
  			xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
4ed8e27b4   Darrick J. Wong   xfs: make xfs_buf...
288
289
290
  		/* fall through */
  	case -ENOMEM:
  	case -EAGAIN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
  		return error;
  	}
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
293
294
295
296
297
  
  	if (XFS_FORCED_SHUTDOWN(mp)) {
  		xfs_buf_relse(bp);
  		trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299

e9892d3cc   Dave Chinner   xfs: only trace b...
300
  	if (tp) {
2d3d0c53d   Dave Chinner   xfs: lobotomise x...
301
  		_xfs_trans_bjoin(tp, bp, 1);
fb1755a64   Carlos Maiolino   Split buffer's b_...
302
  		trace_xfs_trans_read_buf(bp->b_log_item);
e9892d3cc   Dave Chinner   xfs: only trace b...
303
  	}
1aff5696f   Darrick J. Wong   xfs: always assig...
304
  	ASSERT(bp->b_ops != NULL || ops == NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
306
  	*bpp = bp;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  }
38b6238eb   Darrick J. Wong   xfs: fix buffer s...
308
309
310
311
312
313
314
315
316
317
318
319
  /* Has this buffer been dirtied by anyone? */
  bool
  xfs_trans_buf_is_dirty(
  	struct xfs_buf		*bp)
  {
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
  
  	if (!bip)
  		return false;
  	ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
  	return test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  /*
23420d05e   Brian Foster   xfs: clean up xfs...
321
322
323
324
325
   * Release a buffer previously joined to the transaction. If the buffer is
   * modified within this transaction, 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
   *
23420d05e   Brian Foster   xfs: clean up xfs...
327
328
   * If the buffer is to be released and it was not already dirty before this
   * transaction began, then also free the buf_log_item associated with it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
   *
23420d05e   Brian Foster   xfs: clean up xfs...
330
   * If the transaction pointer is NULL, this is a normal xfs_buf_relse() call.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
   */
  void
70a206553   Carlos Maiolino   Get rid of xfs_bu...
333
  xfs_trans_brelse(
23420d05e   Brian Foster   xfs: clean up xfs...
334
335
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
  {
23420d05e   Brian Foster   xfs: clean up xfs...
337
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
338

23420d05e   Brian Foster   xfs: clean up xfs...
339
340
341
  	ASSERT(bp->b_transp == tp);
  
  	if (!tp) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
  		xfs_buf_relse(bp);
  		return;
  	}
23420d05e   Brian Foster   xfs: clean up xfs...
345
  	trace_xfs_trans_brelse(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  	ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  	/*
23420d05e   Brian Foster   xfs: clean up xfs...
349
350
  	 * If the release is for a recursive lookup, then decrement the count
  	 * and return.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
  	 */
  	if (bip->bli_recur > 0) {
  		bip->bli_recur--;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
357
  		return;
  	}
  
  	/*
23420d05e   Brian Foster   xfs: clean up xfs...
358
  	 * If the buffer is invalidated or dirty in this transaction, we can't
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
360
  	 * release it until we commit.
  	 */
e6631f855   Dave Chinner   xfs: get rid of t...
361
  	if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  		return;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
363
  	if (bip->bli_flags & XFS_BLI_STALE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  	/*
23420d05e   Brian Foster   xfs: clean up xfs...
367
368
  	 * Unlink the log item from the transaction and clear the hold flag, if
  	 * set. We wouldn't want the next user of the buffer to get confused.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
  	 */
23420d05e   Brian Foster   xfs: clean up xfs...
370
  	ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
e98c414f9   Christoph Hellwig   xfs: simplify log...
371
  	xfs_trans_del_item(&bip->bli_item);
23420d05e   Brian Foster   xfs: clean up xfs...
372
  	bip->bli_flags &= ~XFS_BLI_HOLD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373

95808459b   Brian Foster   xfs: refactor xfs...
374
375
  	/* drop the reference to the bli */
  	xfs_buf_item_put(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376

5b03ff1b2   Christoph Hellwig   xfs: remove xfs_t...
377
  	bp->b_transp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  	xfs_buf_relse(bp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
   * Mark the buffer as not needing to be unlocked when the buf item's
ddf92053e   Christoph Hellwig   xfs: split iop_un...
383
   * iop_committing() routine is called.  The buffer must already be locked
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
385
386
387
   * and associated with the given transaction.
   */
  /* ARGSUSED */
  void
70a206553   Carlos Maiolino   Get rid of xfs_bu...
388
389
390
  xfs_trans_bhold(
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
392
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393

bf9d9013a   Christoph Hellwig   xfs: add a proper...
394
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
395
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
397
  	ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
399

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  	bip->bli_flags |= XFS_BLI_HOLD;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
401
  	trace_xfs_trans_bhold(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
  }
  
  /*
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
405
406
407
408
   * Cancel the previous buffer hold request made on this buffer
   * for this transaction.
   */
  void
70a206553   Carlos Maiolino   Get rid of xfs_bu...
409
410
411
  xfs_trans_bhold_release(
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
412
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
413
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
414

bf9d9013a   Christoph Hellwig   xfs: add a proper...
415
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
416
  	ASSERT(bip != NULL);
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
417
  	ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
418
  	ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
419
420
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  	ASSERT(bip->bli_flags & XFS_BLI_HOLD);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
421

adadbeefb   Christoph Hellwig   xfs: remove wrapp...
422
  	bip->bli_flags &= ~XFS_BLI_HOLD;
0b1b213fc   Christoph Hellwig   xfs: event tracin...
423
  	trace_xfs_trans_bhold_release(bip);
efa092f3d   Tim Shimmin   [XFS] Fixes a bug...
424
425
426
  }
  
  /*
9684010d3   Brian Foster   xfs: refactor buf...
427
   * Mark a buffer dirty in the transaction.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
   */
  void
9684010d3   Brian Foster   xfs: refactor buf...
430
431
432
  xfs_trans_dirty_buf(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
433
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
434
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435

bf9d9013a   Christoph Hellwig   xfs: add a proper...
436
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
437
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
  
  	/*
  	 * 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
b01d1461a   Dave Chinner   xfs: call xfs_buf...
443
  	 * to disk.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
  	 */
b0388bf10   Dave Chinner   xfs: remove XBF_D...
445
  	bp->b_flags |= XBF_DONE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
451
452
453
454
455
  
  	/*
  	 * 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
456
  		bip->bli_flags &= ~XFS_BLI_STALE;
5cfd28b6a   Dave Chinner   xfs: remove XBF_S...
457
458
  		ASSERT(bp->b_flags & XBF_STALE);
  		bp->b_flags &= ~XBF_STALE;
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
459
  		bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	}
9684010d3   Brian Foster   xfs: refactor buf...
461
  	bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  	tp->t_flags |= XFS_TRANS_DIRTY;
e6631f855   Dave Chinner   xfs: get rid of t...
464
  	set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
9684010d3   Brian Foster   xfs: refactor buf...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
  }
  
  /*
   * 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(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp,
  	uint			first,
  	uint			last)
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
483
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
9684010d3   Brian Foster   xfs: refactor buf...
484
485
  
  	ASSERT(first <= last && last < BBTOB(bp->b_length));
8dc518dfa   Brian Foster   xfs: don't log di...
486
  	ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
9684010d3   Brian Foster   xfs: refactor buf...
487
488
  
  	xfs_trans_dirty_buf(tp, bp);
5f6bed76c   Dave Chinner   xfs: Introduce an...
489

9684010d3   Brian Foster   xfs: refactor buf...
490
  	trace_xfs_trans_log_buf(bip);
8dc518dfa   Brian Foster   xfs: don't log di...
491
  	xfs_buf_item_log(bip, first, last);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
493
494
495
  }
  
  
  /*
43ff2122e   Christoph Hellwig   xfs: on-stack del...
496
497
498
499
500
501
   * 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
   *
43ff2122e   Christoph Hellwig   xfs: on-stack del...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
   * We prevent the buffer from being written out by marking it stale.  We can't
   * get rid of the buf log item at this point 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 that happens we will
   * keep the buffer locked so that the buffer and buf log item are not reused.
   *
   * We also set the XFS_BLF_CANCEL flag in the buf log format structure 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.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523
524
525
   */
  void
  xfs_trans_binval(
70a206553   Carlos Maiolino   Get rid of xfs_bu...
526
527
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
529
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
91e4bac0b   Mark Tinguely   xfs: fix the mult...
530
  	int			i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531

bf9d9013a   Christoph Hellwig   xfs: add a proper...
532
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
533
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
0b1b213fc   Christoph Hellwig   xfs: event tracin...
535
  	trace_xfs_trans_binval(bip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
538
539
540
  	if (bip->bli_flags & XFS_BLI_STALE) {
  		/*
  		 * If the buffer is already invalidated, then
  		 * just return.
  		 */
5cfd28b6a   Dave Chinner   xfs: remove XBF_S...
541
  		ASSERT(bp->b_flags & XBF_STALE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  		ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
543
  		ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_INODE_BUF));
61fe135c1   Dave Chinner   xfs: buffer type ...
544
  		ASSERT(!(bip->__bli_format.blf_flags & XFS_BLFT_MASK));
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
545
  		ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
e6631f855   Dave Chinner   xfs: get rid of t...
546
  		ASSERT(test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  		ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
548
549
  		return;
  	}
c867cb616   Christoph Hellwig   xfs: remove XFS_B...
550
  	xfs_buf_stale(bp);
43ff2122e   Christoph Hellwig   xfs: on-stack del...
551

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
  	bip->bli_flags |= XFS_BLI_STALE;
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
553
  	bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
0f22f9d0c   Mark Tinguely   xfs: rename bli_f...
554
555
  	bip->__bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
  	bip->__bli_format.blf_flags |= XFS_BLF_CANCEL;
61fe135c1   Dave Chinner   xfs: buffer type ...
556
  	bip->__bli_format.blf_flags &= ~XFS_BLFT_MASK;
91e4bac0b   Mark Tinguely   xfs: fix the mult...
557
558
559
560
  	for (i = 0; i < bip->bli_format_count; i++) {
  		memset(bip->bli_formats[i].blf_data_map, 0,
  		       (bip->bli_formats[i].blf_map_size * sizeof(uint)));
  	}
e6631f855   Dave Chinner   xfs: get rid of t...
561
  	set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
  	tp->t_flags |= XFS_TRANS_DIRTY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
  }
  
  /*
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
566
567
568
569
570
   * 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
571
   *
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
572
573
574
   * 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
575
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576
577
  void
  xfs_trans_inode_buf(
70a206553   Carlos Maiolino   Get rid of xfs_bu...
578
579
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
580
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
581
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582

bf9d9013a   Christoph Hellwig   xfs: add a proper...
583
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
584
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
ccf7c23fc   Dave Chinner   xfs: Ensure inode...
586
  	bip->bli_flags |= XFS_BLI_INODE_BUF;
f593bf144   Dave Chinner   xfs: mark inode b...
587
  	bp->b_flags |= _XBF_INODES;
61fe135c1   Dave Chinner   xfs: buffer type ...
588
  	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
590
591
592
593
  }
  
  /*
   * This call is used to indicate that the buffer is going to
   * be staled and was an inode buffer. This means it gets
93848a999   Christoph Hellwig   xfs: add version ...
594
   * special processing during unpin - where any inodes
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
597
598
599
600
601
   * 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(
70a206553   Carlos Maiolino   Get rid of xfs_bu...
602
603
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
605
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606

bf9d9013a   Christoph Hellwig   xfs: add a proper...
607
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
608
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
610
611
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  
  	bip->bli_flags |= XFS_BLI_STALE_INODE;
f593bf144   Dave Chinner   xfs: mark inode b...
612
  	bp->b_flags |= _XBF_INODES;
61fe135c1   Dave Chinner   xfs: buffer type ...
613
  	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
614
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
615
616
617
618
619
620
621
622
623
624
625
  /*
   * 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(
70a206553   Carlos Maiolino   Get rid of xfs_bu...
626
627
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
629
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630

bf9d9013a   Christoph Hellwig   xfs: add a proper...
631
  	ASSERT(bp->b_transp == tp);
adadbeefb   Christoph Hellwig   xfs: remove wrapp...
632
  	ASSERT(bip != NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
  
  	bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
f593bf144   Dave Chinner   xfs: mark inode b...
636
  	bp->b_flags |= _XBF_INODES;
61fe135c1   Dave Chinner   xfs: buffer type ...
637
  	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  }
ee1a47ab0   Christoph Hellwig   xfs: add support ...
639
  /*
8dc518dfa   Brian Foster   xfs: don't log di...
640
641
642
643
644
   * Mark the buffer as ordered for this transaction. This means that the contents
   * of the buffer are not recorded in the transaction but it is tracked in the
   * AIL as though it was. This allows us to record logical changes in
   * transactions rather than the physical changes we make to the buffer without
   * changing writeback ordering constraints of metadata buffers.
5f6bed76c   Dave Chinner   xfs: Introduce an...
645
   */
a5814bcee   Brian Foster   xfs: disallow mar...
646
  bool
5f6bed76c   Dave Chinner   xfs: Introduce an...
647
648
649
650
  xfs_trans_ordered_buf(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp)
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
651
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
5f6bed76c   Dave Chinner   xfs: Introduce an...
652
653
654
655
  
  	ASSERT(bp->b_transp == tp);
  	ASSERT(bip != NULL);
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
a5814bcee   Brian Foster   xfs: disallow mar...
656
657
658
  
  	if (xfs_buf_item_dirty_format(bip))
  		return false;
5f6bed76c   Dave Chinner   xfs: Introduce an...
659
660
661
  
  	bip->bli_flags |= XFS_BLI_ORDERED;
  	trace_xfs_buf_item_ordered(bip);
8dc518dfa   Brian Foster   xfs: don't log di...
662
663
664
665
666
667
  
  	/*
  	 * We don't log a dirty range of an ordered buffer but it still needs
  	 * to be marked dirty and that it has been logged.
  	 */
  	xfs_trans_dirty_buf(tp, bp);
a5814bcee   Brian Foster   xfs: disallow mar...
668
  	return true;
5f6bed76c   Dave Chinner   xfs: Introduce an...
669
670
671
  }
  
  /*
ee1a47ab0   Christoph Hellwig   xfs: add support ...
672
673
674
675
676
677
678
   * Set the type of the buffer for log recovery so that it can correctly identify
   * and hence attach the correct buffer ops to the buffer after replay.
   */
  void
  xfs_trans_buf_set_type(
  	struct xfs_trans	*tp,
  	struct xfs_buf		*bp,
61fe135c1   Dave Chinner   xfs: buffer type ...
679
  	enum xfs_blft		type)
ee1a47ab0   Christoph Hellwig   xfs: add support ...
680
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
681
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
ee1a47ab0   Christoph Hellwig   xfs: add support ...
682

d75afeb3d   Dave Chinner   xfs: add buffer t...
683
684
  	if (!tp)
  		return;
ee1a47ab0   Christoph Hellwig   xfs: add support ...
685
686
687
  	ASSERT(bp->b_transp == tp);
  	ASSERT(bip != NULL);
  	ASSERT(atomic_read(&bip->bli_refcount) > 0);
ee1a47ab0   Christoph Hellwig   xfs: add support ...
688

61fe135c1   Dave Chinner   xfs: buffer type ...
689
  	xfs_blft_to_flags(&bip->__bli_format, type);
ee1a47ab0   Christoph Hellwig   xfs: add support ...
690
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691

d75afeb3d   Dave Chinner   xfs: add buffer t...
692
693
694
695
696
  void
  xfs_trans_buf_copy_type(
  	struct xfs_buf		*dst_bp,
  	struct xfs_buf		*src_bp)
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
697
698
  	struct xfs_buf_log_item	*sbip = src_bp->b_log_item;
  	struct xfs_buf_log_item	*dbip = dst_bp->b_log_item;
61fe135c1   Dave Chinner   xfs: buffer type ...
699
  	enum xfs_blft		type;
d75afeb3d   Dave Chinner   xfs: add buffer t...
700

61fe135c1   Dave Chinner   xfs: buffer type ...
701
702
  	type = xfs_blft_from_flags(&sbip->__bli_format);
  	xfs_blft_to_flags(&dbip->__bli_format, type);
d75afeb3d   Dave Chinner   xfs: add buffer t...
703
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
707
708
709
710
711
712
713
714
715
716
  /*
   * 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(
70a206553   Carlos Maiolino   Get rid of xfs_bu...
717
718
719
  	xfs_trans_t		*tp,
  	xfs_buf_t		*bp,
  	uint			type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
  {
fb1755a64   Carlos Maiolino   Split buffer's b_...
721
  	struct xfs_buf_log_item	*bip = bp->b_log_item;
61fe135c1   Dave Chinner   xfs: buffer type ...
722

c11554104   Dave Chinner   xfs: Clean up XFS...
723
724
725
  	ASSERT(type == XFS_BLF_UDQUOT_BUF ||
  	       type == XFS_BLF_PDQUOT_BUF ||
  	       type == XFS_BLF_GDQUOT_BUF);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726

61fe135c1   Dave Chinner   xfs: buffer type ...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  	bip->__bli_format.blf_flags |= type;
  
  	switch (type) {
  	case XFS_BLF_UDQUOT_BUF:
  		type = XFS_BLFT_UDQUOT_BUF;
  		break;
  	case XFS_BLF_PDQUOT_BUF:
  		type = XFS_BLFT_PDQUOT_BUF;
  		break;
  	case XFS_BLF_GDQUOT_BUF:
  		type = XFS_BLFT_GDQUOT_BUF;
  		break;
  	default:
  		type = XFS_BLFT_UNKNOWN_BUF;
  		break;
  	}
0c7e5afbe   Dave Chinner   xfs: mark dquot b...
743
  	bp->b_flags |= _XBF_DQUOTS;
ee1a47ab0   Christoph Hellwig   xfs: add support ...
744
  	xfs_trans_buf_set_type(tp, bp, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
  }