diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 73 |
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 | */ | ||
4271 | xfs_bmbt_rec_t * /* pointer to found extent record */ | ||
4272 | xfs_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 | */ |
4273 | xfs_ext_irec_t * | 4342 | xfs_ext_irec_t * /* pointer to found extent record */ |
4274 | xfs_iext_bno_to_irec( | 4343 | xfs_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 */ |