aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
committerSage Weil <sage@inktank.com>2013-08-15 14:11:45 -0400
commitee3e542fec6e69bc9fb668698889a37d93950ddf (patch)
treee74ee766a4764769ef1d3d45d266b4dea64101d3 /fs/xfs/xfs_ialloc.c
parentfe2a801b50c0bb8039d627e5ae1fec249d10ff39 (diff)
parentf1d6e17f540af37bb1891480143669ba7636c4cf (diff)
Merge remote-tracking branch 'linus/master' into testing
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c74
1 files changed, 53 insertions, 21 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index c8f5ae1debf2..7a0c17d7ec09 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -38,6 +38,7 @@
38#include "xfs_bmap.h" 38#include "xfs_bmap.h"
39#include "xfs_cksum.h" 39#include "xfs_cksum.h"
40#include "xfs_buf_item.h" 40#include "xfs_buf_item.h"
41#include "xfs_icreate_item.h"
41 42
42 43
43/* 44/*
@@ -150,12 +151,16 @@ xfs_check_agi_freecount(
150#endif 151#endif
151 152
152/* 153/*
153 * Initialise a new set of inodes. 154 * Initialise a new set of inodes. When called without a transaction context
155 * (e.g. from recovery) we initiate a delayed write of the inode buffers rather
156 * than logging them (which in a transaction context puts them into the AIL
157 * for writeback rather than the xfsbufd queue).
154 */ 158 */
155STATIC int 159int
156xfs_ialloc_inode_init( 160xfs_ialloc_inode_init(
157 struct xfs_mount *mp, 161 struct xfs_mount *mp,
158 struct xfs_trans *tp, 162 struct xfs_trans *tp,
163 struct list_head *buffer_list,
159 xfs_agnumber_t agno, 164 xfs_agnumber_t agno,
160 xfs_agblock_t agbno, 165 xfs_agblock_t agbno,
161 xfs_agblock_t length, 166 xfs_agblock_t length,
@@ -208,6 +213,18 @@ xfs_ialloc_inode_init(
208 version = 3; 213 version = 3;
209 ino = XFS_AGINO_TO_INO(mp, agno, 214 ino = XFS_AGINO_TO_INO(mp, agno,
210 XFS_OFFBNO_TO_AGINO(mp, agbno, 0)); 215 XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
216
217 /*
218 * log the initialisation that is about to take place as an
219 * logical operation. This means the transaction does not
220 * need to log the physical changes to the inode buffers as log
221 * recovery will know what initialisation is actually needed.
222 * Hence we only need to log the buffers as "ordered" buffers so
223 * they track in the AIL as if they were physically logged.
224 */
225 if (tp)
226 xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
227 mp->m_sb.sb_inodesize, length, gen);
211 } else if (xfs_sb_version_hasnlink(&mp->m_sb)) 228 } else if (xfs_sb_version_hasnlink(&mp->m_sb))
212 version = 2; 229 version = 2;
213 else 230 else
@@ -223,13 +240,8 @@ xfs_ialloc_inode_init(
223 XBF_UNMAPPED); 240 XBF_UNMAPPED);
224 if (!fbuf) 241 if (!fbuf)
225 return ENOMEM; 242 return ENOMEM;
226 /* 243
227 * Initialize all inodes in this buffer and then log them. 244 /* Initialize the inode buffers and log them appropriately. */
228 *
229 * XXX: It would be much better if we had just one transaction
230 * to log a whole cluster of inodes instead of all the
231 * individual transactions causing a lot of log traffic.
232 */
233 fbuf->b_ops = &xfs_inode_buf_ops; 245 fbuf->b_ops = &xfs_inode_buf_ops;
234 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length)); 246 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
235 for (i = 0; i < ninodes; i++) { 247 for (i = 0; i < ninodes; i++) {
@@ -247,18 +259,39 @@ xfs_ialloc_inode_init(
247 ino++; 259 ino++;
248 uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid); 260 uuid_copy(&free->di_uuid, &mp->m_sb.sb_uuid);
249 xfs_dinode_calc_crc(mp, free); 261 xfs_dinode_calc_crc(mp, free);
250 } else { 262 } else if (tp) {
251 /* just log the inode core */ 263 /* just log the inode core */
252 xfs_trans_log_buf(tp, fbuf, ioffset, 264 xfs_trans_log_buf(tp, fbuf, ioffset,
253 ioffset + isize - 1); 265 ioffset + isize - 1);
254 } 266 }
255 } 267 }
256 if (version == 3) { 268
257 /* need to log the entire buffer */ 269 if (tp) {
258 xfs_trans_log_buf(tp, fbuf, 0, 270 /*
259 BBTOB(fbuf->b_length) - 1); 271 * Mark the buffer as an inode allocation buffer so it
272 * sticks in AIL at the point of this allocation
273 * transaction. This ensures the they are on disk before
274 * the tail of the log can be moved past this
275 * transaction (i.e. by preventing relogging from moving
276 * it forward in the log).
277 */
278 xfs_trans_inode_alloc_buf(tp, fbuf);
279 if (version == 3) {
280 /*
281 * Mark the buffer as ordered so that they are
282 * not physically logged in the transaction but
283 * still tracked in the AIL as part of the
284 * transaction and pin the log appropriately.
285 */
286 xfs_trans_ordered_buf(tp, fbuf);
287 xfs_trans_log_buf(tp, fbuf, 0,
288 BBTOB(fbuf->b_length) - 1);
289 }
290 } else {
291 fbuf->b_flags |= XBF_DONE;
292 xfs_buf_delwri_queue(fbuf, buffer_list);
293 xfs_buf_relse(fbuf);
260 } 294 }
261 xfs_trans_inode_alloc_buf(tp, fbuf);
262 } 295 }
263 return 0; 296 return 0;
264} 297}
@@ -303,7 +336,7 @@ xfs_ialloc_ag_alloc(
303 * First try to allocate inodes contiguous with the last-allocated 336 * First try to allocate inodes contiguous with the last-allocated
304 * chunk of inodes. If the filesystem is striped, this will fill 337 * chunk of inodes. If the filesystem is striped, this will fill
305 * an entire stripe unit with inodes. 338 * an entire stripe unit with inodes.
306 */ 339 */
307 agi = XFS_BUF_TO_AGI(agbp); 340 agi = XFS_BUF_TO_AGI(agbp);
308 newino = be32_to_cpu(agi->agi_newino); 341 newino = be32_to_cpu(agi->agi_newino);
309 agno = be32_to_cpu(agi->agi_seqno); 342 agno = be32_to_cpu(agi->agi_seqno);
@@ -402,7 +435,7 @@ xfs_ialloc_ag_alloc(
402 * rather than a linear progression to prevent the next generation 435 * rather than a linear progression to prevent the next generation
403 * number from being easily guessable. 436 * number from being easily guessable.
404 */ 437 */
405 error = xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno, 438 error = xfs_ialloc_inode_init(args.mp, tp, NULL, agno, args.agbno,
406 args.len, prandom_u32()); 439 args.len, prandom_u32());
407 440
408 if (error) 441 if (error)
@@ -615,8 +648,7 @@ xfs_ialloc_get_rec(
615 struct xfs_btree_cur *cur, 648 struct xfs_btree_cur *cur,
616 xfs_agino_t agino, 649 xfs_agino_t agino,
617 xfs_inobt_rec_incore_t *rec, 650 xfs_inobt_rec_incore_t *rec,
618 int *done, 651 int *done)
619 int left)
620{ 652{
621 int error; 653 int error;
622 int i; 654 int i;
@@ -724,12 +756,12 @@ xfs_dialloc_ag(
724 pag->pagl_leftrec != NULLAGINO && 756 pag->pagl_leftrec != NULLAGINO &&
725 pag->pagl_rightrec != NULLAGINO) { 757 pag->pagl_rightrec != NULLAGINO) {
726 error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec, 758 error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
727 &trec, &doneleft, 1); 759 &trec, &doneleft);
728 if (error) 760 if (error)
729 goto error1; 761 goto error1;
730 762
731 error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec, 763 error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
732 &rec, &doneright, 0); 764 &rec, &doneright);
733 if (error) 765 if (error)
734 goto error1; 766 goto error1;
735 } else { 767 } else {