diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 23dcb72fc5e6..116ef1ddb3e3 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c | |||
@@ -22,9 +22,7 @@ | |||
22 | #include "xfs_log_format.h" | 22 | #include "xfs_log_format.h" |
23 | #include "xfs_trans_resv.h" | 23 | #include "xfs_trans_resv.h" |
24 | #include "xfs_bit.h" | 24 | #include "xfs_bit.h" |
25 | #include "xfs_inum.h" | ||
26 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
27 | #include "xfs_ag.h" | ||
28 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
29 | #include "xfs_inode.h" | 27 | #include "xfs_inode.h" |
30 | #include "xfs_btree.h" | 28 | #include "xfs_btree.h" |
@@ -39,7 +37,6 @@ | |||
39 | #include "xfs_buf_item.h" | 37 | #include "xfs_buf_item.h" |
40 | #include "xfs_icreate_item.h" | 38 | #include "xfs_icreate_item.h" |
41 | #include "xfs_icache.h" | 39 | #include "xfs_icache.h" |
42 | #include "xfs_dinode.h" | ||
43 | #include "xfs_trace.h" | 40 | #include "xfs_trace.h" |
44 | 41 | ||
45 | 42 | ||
@@ -48,12 +45,12 @@ | |||
48 | */ | 45 | */ |
49 | static inline int | 46 | static inline int |
50 | xfs_ialloc_cluster_alignment( | 47 | xfs_ialloc_cluster_alignment( |
51 | xfs_alloc_arg_t *args) | 48 | struct xfs_mount *mp) |
52 | { | 49 | { |
53 | if (xfs_sb_version_hasalign(&args->mp->m_sb) && | 50 | if (xfs_sb_version_hasalign(&mp->m_sb) && |
54 | args->mp->m_sb.sb_inoalignmt >= | 51 | mp->m_sb.sb_inoalignmt >= |
55 | XFS_B_TO_FSBT(args->mp, args->mp->m_inode_cluster_size)) | 52 | XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size)) |
56 | return args->mp->m_sb.sb_inoalignmt; | 53 | return mp->m_sb.sb_inoalignmt; |
57 | return 1; | 54 | return 1; |
58 | } | 55 | } |
59 | 56 | ||
@@ -412,7 +409,7 @@ xfs_ialloc_ag_alloc( | |||
412 | * but not to use them in the actual exact allocation. | 409 | * but not to use them in the actual exact allocation. |
413 | */ | 410 | */ |
414 | args.alignment = 1; | 411 | args.alignment = 1; |
415 | args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1; | 412 | args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1; |
416 | 413 | ||
417 | /* Allow space for the inode btree to split. */ | 414 | /* Allow space for the inode btree to split. */ |
418 | args.minleft = args.mp->m_in_maxlevels - 1; | 415 | args.minleft = args.mp->m_in_maxlevels - 1; |
@@ -448,7 +445,7 @@ xfs_ialloc_ag_alloc( | |||
448 | args.alignment = args.mp->m_dalign; | 445 | args.alignment = args.mp->m_dalign; |
449 | isaligned = 1; | 446 | isaligned = 1; |
450 | } else | 447 | } else |
451 | args.alignment = xfs_ialloc_cluster_alignment(&args); | 448 | args.alignment = xfs_ialloc_cluster_alignment(args.mp); |
452 | /* | 449 | /* |
453 | * Need to figure out where to allocate the inode blocks. | 450 | * Need to figure out where to allocate the inode blocks. |
454 | * Ideally they should be spaced out through the a.g. | 451 | * Ideally they should be spaced out through the a.g. |
@@ -477,7 +474,7 @@ xfs_ialloc_ag_alloc( | |||
477 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 474 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
478 | args.agbno = be32_to_cpu(agi->agi_root); | 475 | args.agbno = be32_to_cpu(agi->agi_root); |
479 | args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); | 476 | args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno); |
480 | args.alignment = xfs_ialloc_cluster_alignment(&args); | 477 | args.alignment = xfs_ialloc_cluster_alignment(args.mp); |
481 | if ((error = xfs_alloc_vextent(&args))) | 478 | if ((error = xfs_alloc_vextent(&args))) |
482 | return error; | 479 | return error; |
483 | } | 480 | } |
@@ -632,10 +629,24 @@ xfs_ialloc_ag_select( | |||
632 | } | 629 | } |
633 | 630 | ||
634 | /* | 631 | /* |
635 | * Is there enough free space for the file plus a block of | 632 | * Check that there is enough free space for the file plus a |
636 | * inodes? (if we need to allocate some)? | 633 | * chunk of inodes if we need to allocate some. If this is the |
634 | * first pass across the AGs, take into account the potential | ||
635 | * space needed for alignment of inode chunks when checking the | ||
636 | * longest contiguous free space in the AG - this prevents us | ||
637 | * from getting ENOSPC because we have free space larger than | ||
638 | * m_ialloc_blks but alignment constraints prevent us from using | ||
639 | * it. | ||
640 | * | ||
641 | * If we can't find an AG with space for full alignment slack to | ||
642 | * be taken into account, we must be near ENOSPC in all AGs. | ||
643 | * Hence we don't include alignment for the second pass and so | ||
644 | * if we fail allocation due to alignment issues then it is most | ||
645 | * likely a real ENOSPC condition. | ||
637 | */ | 646 | */ |
638 | ineed = mp->m_ialloc_blks; | 647 | ineed = mp->m_ialloc_blks; |
648 | if (flags && ineed > 1) | ||
649 | ineed += xfs_ialloc_cluster_alignment(mp); | ||
639 | longest = pag->pagf_longest; | 650 | longest = pag->pagf_longest; |
640 | if (!longest) | 651 | if (!longest) |
641 | longest = pag->pagf_flcount > 0; | 652 | longest = pag->pagf_flcount > 0; |
@@ -1137,11 +1148,7 @@ xfs_dialloc_ag_update_inobt( | |||
1137 | XFS_WANT_CORRUPTED_RETURN((rec.ir_free == frec->ir_free) && | 1148 | XFS_WANT_CORRUPTED_RETURN((rec.ir_free == frec->ir_free) && |
1138 | (rec.ir_freecount == frec->ir_freecount)); | 1149 | (rec.ir_freecount == frec->ir_freecount)); |
1139 | 1150 | ||
1140 | error = xfs_inobt_update(cur, &rec); | 1151 | return xfs_inobt_update(cur, &rec); |
1141 | if (error) | ||
1142 | return error; | ||
1143 | |||
1144 | return 0; | ||
1145 | } | 1152 | } |
1146 | 1153 | ||
1147 | /* | 1154 | /* |