int xfs_readfile_btree(xfs_inode_t *ip, void *buffer, off_t offset, size_t len, int *last_extent) { xfs_extnum_t nextents; xfs_extnum_t extent; xfs_ifork_t *dp; xfs_bmbt_rec_host_t *ep; xfs_bmbt_irec_t rec; xfs_mount_t *mp = ip->i_mount; /* filesystem mount point */ xfs_fsize_t size = ip->i_d.di_size; int error; if (offset >= size) return 0; if (offset + len > size) len = size - offset; dp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); if (!(dp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK))) return error; nextents = XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK); for (extent=0; extent<nextents; extent++) { ep = xfs_iext_get_ext(dp, extent); xfs_bmbt_get_all(ep, &rec); if (extent_overlaps_buffer(mp, rec, offset, len)) { error = copy_extent_to_buffer(mp, rec, buffer, offset, len); if (error) return error; } } return len; }
/* * Count leaf blocks given a range of extent records. */ STATIC void xfs_bmap_count_leaves( xfs_ifork_t *ifp, xfs_extnum_t idx, int numrecs, int *count) { int b; for (b = 0; b < numrecs; b++) { xfs_bmbt_rec_host_t *frp = xfs_iext_get_ext(ifp, idx + b); *count += xfs_bmbt_get_blockcount(frp); } }
STATIC int xfs_qm_get_rtblks( xfs_inode_t *ip, xfs_qcnt_t *O_rtblks) { xfs_filblks_t rtblks; /* total rt blks */ xfs_extnum_t idx; /* extent record index */ xfs_ifork_t *ifp; /* inode fork pointer */ xfs_extnum_t nextents; /* number of extent entries */ int error; ASSERT(XFS_IS_REALTIME_INODE(ip)); ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); if (!(ifp->if_flags & XFS_IFEXTENTS)) { if ((error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK))) return error; } rtblks = 0; nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); for (idx = 0; idx < nextents; idx++) rtblks += xfs_bmbt_get_blockcount(xfs_iext_get_ext(ifp, idx)); *O_rtblks = (xfs_qcnt_t)rtblks; return 0; }