aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 11:39:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 11:39:39 -0400
commit253ba4e79edc695b2925bd2ef34de06ff4d4070c (patch)
tree259667140ca702d6a218cc54f4df275fbbda747b /fs/xfs/xfs_ialloc.c
parent188da98800893691e47eea9335a234378e32aceb (diff)
parent65e67f5165c8a156b34ee7adf65d5ed3b16a910d (diff)
Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6
* 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6: (87 commits) [XFS] Fix merge failure [XFS] The forward declarations for the xfs_ioctl() helpers and the [XFS] Update XFS documentation for noikeep/ikeep. [XFS] Update XFS Documentation for ikeep and ihashsize [XFS] Remove unused HAVE_SPLICE macro. [XFS] Remove CONFIG_XFS_SECURITY. [XFS] xfs_bmap_compute_maxlevels should be based on di_forkoff [XFS] Always use di_forkoff when checking for attr space. [XFS] Ensure the inode is joined in xfs_itruncate_finish [XFS] Remove periodic logging of in-core superblock counters. [XFS] fix logic error in xfs_alloc_ag_vextent_near() [XFS] Don't error out on good I/Os. [XFS] Catch log unmount failures. [XFS] Sanitise xfs_log_force error checking. [XFS] Check for errors when changing buffer pointers. [XFS] Don't allow silent errors in xfs_inactive(). [XFS] Catch errors from xfs_imap(). [XFS] xfs_bulkstat_one_dinode() never returns an error. [XFS] xfs_iflush_fork() never returns an error. [XFS] Catch unwritten extent conversion errors. ...
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 5a146cb22980..a64dfbd565a5 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -107,6 +107,16 @@ xfs_ialloc_log_di(
107/* 107/*
108 * Allocation group level functions. 108 * Allocation group level functions.
109 */ 109 */
110static inline int
111xfs_ialloc_cluster_alignment(
112 xfs_alloc_arg_t *args)
113{
114 if (xfs_sb_version_hasalign(&args->mp->m_sb) &&
115 args->mp->m_sb.sb_inoalignmt >=
116 XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp)))
117 return args->mp->m_sb.sb_inoalignmt;
118 return 1;
119}
110 120
111/* 121/*
112 * Allocate new inodes in the allocation group specified by agbp. 122 * Allocate new inodes in the allocation group specified by agbp.
@@ -167,10 +177,24 @@ xfs_ialloc_ag_alloc(
167 args.mod = args.total = args.wasdel = args.isfl = 177 args.mod = args.total = args.wasdel = args.isfl =
168 args.userdata = args.minalignslop = 0; 178 args.userdata = args.minalignslop = 0;
169 args.prod = 1; 179 args.prod = 1;
170 args.alignment = 1; 180
171 /* 181 /*
172 * Allow space for the inode btree to split. 182 * We need to take into account alignment here to ensure that
183 * we don't modify the free list if we fail to have an exact
184 * block. If we don't have an exact match, and every oher
185 * attempt allocation attempt fails, we'll end up cancelling
186 * a dirty transaction and shutting down.
187 *
188 * For an exact allocation, alignment must be 1,
189 * however we need to take cluster alignment into account when
190 * fixing up the freelist. Use the minalignslop field to
191 * indicate that extra blocks might be required for alignment,
192 * but not to use them in the actual exact allocation.
173 */ 193 */
194 args.alignment = 1;
195 args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
196
197 /* Allow space for the inode btree to split. */
174 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; 198 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
175 if ((error = xfs_alloc_vextent(&args))) 199 if ((error = xfs_alloc_vextent(&args)))
176 return error; 200 return error;
@@ -191,13 +215,8 @@ xfs_ialloc_ag_alloc(
191 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN)); 215 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
192 args.alignment = args.mp->m_dalign; 216 args.alignment = args.mp->m_dalign;
193 isaligned = 1; 217 isaligned = 1;
194 } else if (xfs_sb_version_hasalign(&args.mp->m_sb) && 218 } else
195 args.mp->m_sb.sb_inoalignmt >= 219 args.alignment = xfs_ialloc_cluster_alignment(&args);
196 XFS_B_TO_FSBT(args.mp,
197 XFS_INODE_CLUSTER_SIZE(args.mp)))
198 args.alignment = args.mp->m_sb.sb_inoalignmt;
199 else
200 args.alignment = 1;
201 /* 220 /*
202 * Need to figure out where to allocate the inode blocks. 221 * Need to figure out where to allocate the inode blocks.
203 * Ideally they should be spaced out through the a.g. 222 * Ideally they should be spaced out through the a.g.
@@ -230,12 +249,7 @@ xfs_ialloc_ag_alloc(
230 args.agbno = be32_to_cpu(agi->agi_root); 249 args.agbno = be32_to_cpu(agi->agi_root);
231 args.fsbno = XFS_AGB_TO_FSB(args.mp, 250 args.fsbno = XFS_AGB_TO_FSB(args.mp,
232 be32_to_cpu(agi->agi_seqno), args.agbno); 251 be32_to_cpu(agi->agi_seqno), args.agbno);
233 if (xfs_sb_version_hasalign(&args.mp->m_sb) && 252 args.alignment = xfs_ialloc_cluster_alignment(&args);
234 args.mp->m_sb.sb_inoalignmt >=
235 XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
236 args.alignment = args.mp->m_sb.sb_inoalignmt;
237 else
238 args.alignment = 1;
239 if ((error = xfs_alloc_vextent(&args))) 253 if ((error = xfs_alloc_vextent(&args)))
240 return error; 254 return error;
241 } 255 }