aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c73
1 files changed, 71 insertions, 2 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 580fa0758039..a16df2d435fe 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -4266,11 +4266,80 @@ xfs_iext_destroy(
4266} 4266}
4267 4267
4268/* 4268/*
4269 * Return a pointer to the extent record for file system block bno.
4270 */
4271xfs_bmbt_rec_t * /* pointer to found extent record */
4272xfs_iext_bno_to_ext(
4273 xfs_ifork_t *ifp, /* inode fork pointer */
4274 xfs_fileoff_t bno, /* block number to search for */
4275 xfs_extnum_t *idxp) /* index of target extent */
4276{
4277 xfs_bmbt_rec_t *base; /* pointer to first extent */
4278 xfs_filblks_t blockcount = 0; /* number of blocks in extent */
4279 xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */
4280 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
4281 int high; /* upper boundry in search */
4282 xfs_extnum_t idx = 0; /* index of target extent */
4283 int low; /* lower boundry in search */
4284 xfs_extnum_t nextents; /* number of file extents */
4285 xfs_fileoff_t startoff = 0; /* start offset of extent */
4286
4287 nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
4288 if (nextents == 0) {
4289 *idxp = 0;
4290 return NULL;
4291 }
4292 low = 0;
4293 if (ifp->if_flags & XFS_IFEXTIREC) {
4294 /* Find target extent list */
4295 int erp_idx = 0;
4296 erp = xfs_iext_bno_to_irec(ifp, bno, &erp_idx);
4297 base = erp->er_extbuf;
4298 high = erp->er_extcount - 1;
4299 } else {
4300 base = ifp->if_u1.if_extents;
4301 high = nextents - 1;
4302 }
4303 /* Binary search extent records */
4304 while (low <= high) {
4305 idx = (low + high) >> 1;
4306 ep = base + idx;
4307 startoff = xfs_bmbt_get_startoff(ep);
4308 blockcount = xfs_bmbt_get_blockcount(ep);
4309 if (bno < startoff) {
4310 high = idx - 1;
4311 } else if (bno >= startoff + blockcount) {
4312 low = idx + 1;
4313 } else {
4314 /* Convert back to file-based extent index */
4315 if (ifp->if_flags & XFS_IFEXTIREC) {
4316 idx += erp->er_extoff;
4317 }
4318 *idxp = idx;
4319 return ep;
4320 }
4321 }
4322 /* Convert back to file-based extent index */
4323 if (ifp->if_flags & XFS_IFEXTIREC) {
4324 idx += erp->er_extoff;
4325 }
4326 if (bno >= startoff + blockcount) {
4327 if (++idx == nextents) {
4328 ep = NULL;
4329 } else {
4330 ep = xfs_iext_get_ext(ifp, idx);
4331 }
4332 }
4333 *idxp = idx;
4334 return ep;
4335}
4336
4337/*
4269 * Return a pointer to the indirection array entry containing the 4338 * Return a pointer to the indirection array entry containing the
4270 * extent record for filesystem block bno. Store the index of the 4339 * extent record for filesystem block bno. Store the index of the
4271 * target irec in *erp_idxp. 4340 * target irec in *erp_idxp.
4272 */ 4341 */
4273xfs_ext_irec_t * 4342xfs_ext_irec_t * /* pointer to found extent record */
4274xfs_iext_bno_to_irec( 4343xfs_iext_bno_to_irec(
4275 xfs_ifork_t *ifp, /* inode fork pointer */ 4344 xfs_ifork_t *ifp, /* inode fork pointer */
4276 xfs_fileoff_t bno, /* block number to search for */ 4345 xfs_fileoff_t bno, /* block number to search for */
@@ -4278,7 +4347,7 @@ xfs_iext_bno_to_irec(
4278{ 4347{
4279 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ 4348 xfs_ext_irec_t *erp = NULL; /* indirection array pointer */
4280 xfs_ext_irec_t *erp_next; /* next indirection array entry */ 4349 xfs_ext_irec_t *erp_next; /* next indirection array entry */
4281 xfs_extnum_t erp_idx; /* indirection array index */ 4350 int erp_idx; /* indirection array index */
4282 int nlists; /* number of extent irec's (lists) */ 4351 int nlists; /* number of extent irec's (lists) */
4283 int high; /* binary search upper limit */ 4352 int high; /* binary search upper limit */
4284 int low; /* binary search lower limit */ 4353 int low; /* binary search lower limit */