aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_bmap.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 94b5c5fe2681..aa19e1fee11f 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5743,6 +5743,39 @@ error0:
5743} 5743}
5744 5744
5745/* 5745/*
5746 * returns 1 for success, 0 if we failed to map the extent.
5747 */
5748STATIC int
5749xfs_getbmapx_fix_eof_hole(
5750 xfs_inode_t *ip, /* xfs incore inode pointer */
5751 struct getbmap *out, /* output structure */
5752 int prealloced, /* this is a file with
5753 * preallocated data space */
5754 __int64_t end, /* last block requested */
5755 xfs_fsblock_t startblock)
5756{
5757 __int64_t fixlen;
5758 xfs_mount_t *mp; /* file system mount point */
5759
5760 if (startblock == HOLESTARTBLOCK) {
5761 mp = ip->i_mount;
5762 out->bmv_block = -1;
5763 fixlen = XFS_FSB_TO_BB(mp, XFS_B_TO_FSB(mp, ip->i_size));
5764 fixlen -= out->bmv_offset;
5765 if (prealloced && out->bmv_offset + out->bmv_length == end) {
5766 /* Came to hole at EOF. Trim it. */
5767 if (fixlen <= 0)
5768 return 0;
5769 out->bmv_length = fixlen;
5770 }
5771 } else {
5772 out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
5773 }
5774
5775 return 1;
5776}
5777
5778/*
5746 * Fcntl interface to xfs_bmapi. 5779 * Fcntl interface to xfs_bmapi.
5747 */ 5780 */
5748int /* error code */ 5781int /* error code */
@@ -5904,18 +5937,15 @@ xfs_getbmap(
5904 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 5937 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
5905 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 5938 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
5906 if (map[i].br_startblock == HOLESTARTBLOCK && 5939 if (map[i].br_startblock == HOLESTARTBLOCK &&
5907 ((prealloced && out.bmv_offset + out.bmv_length == bmvend) || 5940 whichfork == XFS_ATTR_FORK) {
5908 whichfork == XFS_ATTR_FORK )) { 5941 /* came to the end of attribute fork */
5909 /*
5910 * came to hole at end of file or the end of
5911 attribute fork
5912 */
5913 goto unlock_and_return; 5942 goto unlock_and_return;
5914 } else { 5943 } else {
5915 out.bmv_block = 5944 if (!xfs_getbmapx_fix_eof_hole(ip, &out,
5916 (map[i].br_startblock == HOLESTARTBLOCK) ? 5945 prealloced, bmvend,
5917 -1 : 5946 map[i].br_startblock)) {
5918 XFS_FSB_TO_DB(ip, map[i].br_startblock); 5947 goto unlock_and_return;
5948 }
5919 5949
5920 /* return either getbmap/getbmapx structure. */ 5950 /* return either getbmap/getbmapx structure. */
5921 if (interface & BMV_IF_EXTENDED) { 5951 if (interface & BMV_IF_EXTENDED) {