Skip to content

Commit 3ccb8b5

Browse files
Glen Overbynatoscott
authored andcommitted
[XFS] A change to inode chunk allocation to try allocating the new chunk
contiguous with the most recently allocated chunk. On a striped filesystem, this will fill a stripe unit with inodes before allocating new inodes in another stripe unit. SGI-PV: 951416 SGI-Modid: xfs-linux-melb:xfs-kern:208488a Signed-off-by: Glen Overby <overby@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
1 parent 3c674e7 commit 3ccb8b5

File tree

1 file changed

+68
-40
lines changed

1 file changed

+68
-40
lines changed

fs/xfs/xfs_ialloc.c

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ xfs_ialloc_ag_alloc(
136136
int ninodes; /* num inodes per buf */
137137
xfs_agino_t thisino; /* current inode number, for loop */
138138
int version; /* inode version number to use */
139-
int isaligned; /* inode allocation at stripe unit */
139+
int isaligned = 0; /* inode allocation at stripe unit */
140140
/* boundary */
141141

142142
args.tp = tp;
@@ -152,47 +152,75 @@ xfs_ialloc_ag_alloc(
152152
return XFS_ERROR(ENOSPC);
153153
args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
154154
/*
155-
* Set the alignment for the allocation.
156-
* If stripe alignment is turned on then align at stripe unit
157-
* boundary.
158-
* If the cluster size is smaller than a filesystem block
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;
155+
* First try to allocate inodes contiguous with the last-allocated
156+
* chunk of inodes. If the filesystem is striped, this will fill
157+
* an entire stripe unit with inodes.
158+
*/
173159
agi = XFS_BUF_TO_AGI(agbp);
174-
/*
175-
* Need to figure out where to allocate the inode blocks.
176-
* Ideally they should be spaced out through the a.g.
177-
* For now, just allocate blocks up front.
178-
*/
179-
args.agbno = be32_to_cpu(agi->agi_root);
180-
args.fsbno = XFS_AGB_TO_FSB(args.mp, be32_to_cpu(agi->agi_seqno),
181-
args.agbno);
182-
/*
183-
* Allocate a fixed-size extent of inodes.
184-
*/
185-
args.type = XFS_ALLOCTYPE_NEAR_BNO;
186-
args.mod = args.total = args.wasdel = args.isfl = args.userdata =
187-
args.minalignslop = 0;
188-
args.prod = 1;
189-
/*
190-
* Allow space for the inode btree to split.
191-
*/
192-
args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
193-
if ((error = xfs_alloc_vextent(&args)))
194-
return error;
160+
newino = be32_to_cpu(agi->agi_newino);
161+
if(likely(newino != NULLAGINO)) {
162+
args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
163+
XFS_IALLOC_BLOCKS(args.mp);
164+
args.fsbno = XFS_AGB_TO_FSB(args.mp,
165+
be32_to_cpu(agi->agi_seqno), args.agbno);
166+
args.type = XFS_ALLOCTYPE_THIS_BNO;
167+
args.mod = args.total = args.wasdel = args.isfl =
168+
args.userdata = args.minalignslop = 0;
169+
args.prod = 1;
170+
args.alignment = 1;
171+
/*
172+
* Allow space for the inode btree to split.
173+
*/
174+
args.minleft = XFS_IN_MAXLEVELS(args.mp) - 1;
175+
if ((error = xfs_alloc_vextent(&args)))
176+
return error;
177+
} else
178+
args.fsbno = NULLFSBLOCK;
195179

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+
196224
/*
197225
* If stripe alignment is turned on, then try again with cluster
198226
* alignment.

0 commit comments

Comments
 (0)