aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_ialloc.c108
1 files changed, 68 insertions, 40 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 20c39a6e6a0c..4eeb856183b1 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -136,7 +136,7 @@ xfs_ialloc_ag_alloc(
136 int ninodes; /* num inodes per buf */ 136 int ninodes; /* num inodes per buf */
137 xfs_agino_t thisino; /* current inode number, for loop */ 137 xfs_agino_t thisino; /* current inode number, for loop */
138 int version; /* inode version number to use */ 138 int version; /* inode version number to use */
139 int isaligned; /* inode allocation at stripe unit */ 139 int isaligned = 0; /* inode allocation at stripe unit */
140 /* boundary */ 140 /* boundary */
141 141
142 args.tp = tp; 142 args.tp = tp;
@@ -152,47 +152,75 @@ xfs_ialloc_ag_alloc(
152 return XFS_ERROR(ENOSPC); 152 return XFS_ERROR(ENOSPC);
153 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp); 153 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
154 /* 154 /*
155 * Set the alignment for the allocation. 155 * First try to allocate inodes contiguous with the last-allocated
156 * If stripe alignment is turned on then align at stripe unit 156 * chunk of inodes. If the filesystem is striped, this will fill
157 * boundary. 157 * an entire stripe unit with inodes.
158 * If the cluster size is smaller than a filesystem block 158 */
159 * then we're doing I/O for inodes in filesystem block size pieces,
160 * so don't need alignment anyway.
161 */
162 isaligned = 0;
163 if (args.mp->m_sinoalign) {
164 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
165 args.alignment = args.mp->m_dalign;
166 isaligned = 1;
167 } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
168 args.mp->m_sb.sb_inoalignmt >=
169 XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
170 args.alignment = args.mp->m_sb.sb_inoalignmt;
171 else
172 args.alignment = 1;
173 agi = XFS_BUF_TO_AGI(agbp); 159 agi = XFS_BUF_TO_AGI(agbp);
174 /* 160 newino = be32_to_cpu(agi->agi_newino);
175 * Need to figure out where to allocate the inode blocks. 161 if(likely(newino != NULLAGINO)) {
176 * Ideally they should be spaced out through the a.g. 162 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
177 * For now, just allocate blocks up front. 163 XFS_IALLOC_BLOCKS(args.mp);
178 */ 164 args.fsbno = XFS_AGB_TO_FSB(args.mp,
179 args.agbno = be32_to_cpu(agi->agi_root); 165 be32_to_cpu(agi->agi_seqno), args.agbno);
180 args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno), 166 args.type = XFS_ALLOCTYPE_THIS_BNO;
181 args.agbno); 167 args.mod = args.total = args.wasdel = args.isfl =
182 /* 168 args.userdata = args.minalignslop = 0;
183 * Allocate a fixed-size extent of inodes. 169 args.prod = 1;
184 */ 170 args.alignment = 1;
185 args.type = XFS_ALLOCTYPE_NEAR_BNO; 171 /*
186 args.mod = args.total = args.wasdel = args.isfl = args.userdata = 172 * Allow space for the inode btree to split.
187 args.minalignslop = 0; 173 */
188 args.prod = 1; 174 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
189 /* 175 if ((error = xfs_alloc_vextent(&args)))
190 * Allow space for the inode btree to split. 176 return error;
191 */ 177 } else
192 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1; 178 args.fsbno = NULLFSBLOCK;
193 if ((error = xfs_alloc_vextent(&args)))
194 return error;
195 179
180 if (unlikely(args.fsbno == NULLFSBLOCK)) {
181 /*
182 * Set the alignment for the allocation.
183 * If stripe alignment is turned on then align at stripe unit
184 * boundary.
185 * If the cluster size is smaller than a filesystem block
186 * then we're doing I/O for inodes in filesystem block size
187 * pieces, so don't need alignment anyway.
188 */
189 isaligned = 0;
190 if (args.mp->m_sinoalign) {
191 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
192 args.alignment = args.mp->m_dalign;
193 isaligned = 1;
194 } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
195 args.mp->m_sb.sb_inoalignmt >=
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 /*
202 * Need to figure out where to allocate the inode blocks.
203 * Ideally they should be spaced out through the a.g.
204 * For now, just allocate blocks up front.
205 */
206 args.agbno = be32_to_cpu(agi->agi_root);
207 args.fsbno = XFS_AGB_TO_FSB(args.mp,
208 be32_to_cpu(agi->agi_seqno), args.agbno);
209 /*
210 * Allocate a fixed-size extent of inodes.
211 */
212 args.type = XFS_ALLOCTYPE_NEAR_BNO;
213 args.mod = args.total = args.wasdel = args.isfl =
214 args.userdata = args.minalignslop = 0;
215 args.prod = 1;
216 /*
217 * Allow space for the inode btree to split.
218 */
219 args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
220 if ((error = xfs_alloc_vextent(&args)))
221 return error;
222 }
223
196 /* 224 /*
197 * If stripe alignment is turned on, then try again with cluster 225 * If stripe alignment is turned on, then try again with cluster
198 * alignment. 226 * alignment.