aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_bmap.c46
-rw-r--r--fs/xfs/xfs_fs.h6
2 files changed, 37 insertions, 15 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 8077580a7199..138308e70d14 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5819,6 +5819,9 @@ xfs_getbmapx_fix_eof_hole(
5819{ 5819{
5820 __int64_t fixlen; 5820 __int64_t fixlen;
5821 xfs_mount_t *mp; /* file system mount point */ 5821 xfs_mount_t *mp; /* file system mount point */
5822 xfs_ifork_t *ifp; /* inode fork pointer */
5823 xfs_extnum_t lastx; /* last extent pointer */
5824 xfs_fileoff_t fileblock;
5822 5825
5823 if (startblock == HOLESTARTBLOCK) { 5826 if (startblock == HOLESTARTBLOCK) {
5824 mp = ip->i_mount; 5827 mp = ip->i_mount;
@@ -5832,7 +5835,15 @@ xfs_getbmapx_fix_eof_hole(
5832 out->bmv_length = fixlen; 5835 out->bmv_length = fixlen;
5833 } 5836 }
5834 } else { 5837 } else {
5835 out->bmv_block = XFS_FSB_TO_DB(ip, startblock); 5838 if (startblock == DELAYSTARTBLOCK)
5839 out->bmv_block = -2;
5840 else
5841 out->bmv_block = XFS_FSB_TO_DB(ip, startblock);
5842 fileblock = XFS_BB_TO_FSB(ip->i_mount, out->bmv_offset);
5843 ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
5844 if (xfs_iext_bno_to_ext(ifp, fileblock, &lastx) &&
5845 (lastx == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))-1))
5846 out->bmv_oflags |= BMV_OF_LAST;
5836 } 5847 }
5837 5848
5838 return 1; 5849 return 1;
@@ -5867,8 +5878,6 @@ xfs_getbmap(
5867 int whichfork; /* data or attr fork */ 5878 int whichfork; /* data or attr fork */
5868 int prealloced; /* this is a file with 5879 int prealloced; /* this is a file with
5869 * preallocated data space */ 5880 * preallocated data space */
5870 int sh_unwritten; /* true, if unwritten */
5871 /* extents listed separately */
5872 int iflags; /* interface flags */ 5881 int iflags; /* interface flags */
5873 int bmapi_flags; /* flags for xfs_bmapi */ 5882 int bmapi_flags; /* flags for xfs_bmapi */
5874 5883
@@ -5876,7 +5885,6 @@ xfs_getbmap(
5876 iflags = bmv->bmv_iflags; 5885 iflags = bmv->bmv_iflags;
5877 5886
5878 whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; 5887 whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
5879 sh_unwritten = (iflags & BMV_IF_PREALLOC) != 0;
5880 5888
5881 /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not 5889 /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
5882 * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ 5890 * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ
@@ -5947,8 +5955,9 @@ xfs_getbmap(
5947 5955
5948 xfs_ilock(ip, XFS_IOLOCK_SHARED); 5956 xfs_ilock(ip, XFS_IOLOCK_SHARED);
5949 5957
5950 if (whichfork == XFS_DATA_FORK && 5958 if (((iflags & BMV_IF_DELALLOC) == 0) &&
5951 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) { 5959 (whichfork == XFS_DATA_FORK) &&
5960 (ip->i_delayed_blks || ip->i_size > ip->i_d.di_size)) {
5952 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */ 5961 /* xfs_fsize_t last_byte = xfs_file_last_byte(ip); */
5953 error = xfs_flush_pages(ip, (xfs_off_t)0, 5962 error = xfs_flush_pages(ip, (xfs_off_t)0,
5954 -1, 0, FI_REMAPF); 5963 -1, 0, FI_REMAPF);
@@ -5958,7 +5967,8 @@ xfs_getbmap(
5958 } 5967 }
5959 } 5968 }
5960 5969
5961 ASSERT(whichfork == XFS_ATTR_FORK || ip->i_delayed_blks == 0); 5970 ASSERT(whichfork == XFS_ATTR_FORK || (iflags & BMV_IF_DELALLOC) ||
5971 ip->i_delayed_blks == 0);
5962 5972
5963 lock = xfs_ilock_map_shared(ip); 5973 lock = xfs_ilock_map_shared(ip);
5964 5974
@@ -5970,7 +5980,7 @@ xfs_getbmap(
5970 nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1; 5980 nex = XFS_IFORK_NEXTENTS(ip, whichfork) * 2 + 1;
5971 5981
5972 bmapi_flags = XFS_BMAPI_AFLAG(whichfork) | 5982 bmapi_flags = XFS_BMAPI_AFLAG(whichfork) |
5973 ((sh_unwritten) ? 0 : XFS_BMAPI_IGSTATE); 5983 ((iflags & BMV_IF_PREALLOC) ? 0 : XFS_BMAPI_IGSTATE);
5974 5984
5975 /* 5985 /*
5976 * Allocate enough space to handle "subnex" maps at a time. 5986 * Allocate enough space to handle "subnex" maps at a time.
@@ -5980,9 +5990,12 @@ xfs_getbmap(
5980 5990
5981 bmv->bmv_entries = 0; 5991 bmv->bmv_entries = 0;
5982 5992
5983 if (XFS_IFORK_NEXTENTS(ip, whichfork) == 0) { 5993 if ((XFS_IFORK_NEXTENTS(ip, whichfork) == 0)) {
5984 error = 0; 5994 if (((iflags & BMV_IF_DELALLOC) == 0) ||
5985 goto unlock_and_return; 5995 whichfork == XFS_ATTR_FORK) {
5996 error = 0;
5997 goto unlock_and_return;
5998 }
5986 } 5999 }
5987 6000
5988 nexleft = nex; 6001 nexleft = nex;
@@ -5998,15 +6011,20 @@ xfs_getbmap(
5998 ASSERT(nmap <= subnex); 6011 ASSERT(nmap <= subnex);
5999 6012
6000 for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) { 6013 for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
6001 out.bmv_oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ? 6014 out.bmv_oflags = 0;
6002 BMV_OF_PREALLOC : 0; 6015 if (map[i].br_state == XFS_EXT_UNWRITTEN)
6016 out.bmv_oflags |= BMV_OF_PREALLOC;
6017 else if (map[i].br_startblock == DELAYSTARTBLOCK)
6018 out.bmv_oflags |= BMV_OF_DELALLOC;
6003 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff); 6019 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
6004 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 6020 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
6005 out.bmv_unused1 = out.bmv_unused2 = 0; 6021 out.bmv_unused1 = out.bmv_unused2 = 0;
6006 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 6022 ASSERT(((iflags & BMV_IF_DELALLOC) != 0) ||
6023 (map[i].br_startblock != DELAYSTARTBLOCK));
6007 if (map[i].br_startblock == HOLESTARTBLOCK && 6024 if (map[i].br_startblock == HOLESTARTBLOCK &&
6008 whichfork == XFS_ATTR_FORK) { 6025 whichfork == XFS_ATTR_FORK) {
6009 /* came to the end of attribute fork */ 6026 /* came to the end of attribute fork */
6027 out.bmv_oflags |= BMV_OF_LAST;
6010 goto unlock_and_return; 6028 goto unlock_and_return;
6011 } else { 6029 } else {
6012 int full = 0; /* user array is full */ 6030 int full = 0; /* user array is full */
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index df859d62a163..4ae03bae992f 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -113,10 +113,14 @@ struct getbmapx {
113#define BMV_IF_ATTRFORK 0x1 /* return attr fork rather than data */ 113#define BMV_IF_ATTRFORK 0x1 /* return attr fork rather than data */
114#define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */ 114#define BMV_IF_NO_DMAPI_READ 0x2 /* Do not generate DMAPI read event */
115#define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */ 115#define BMV_IF_PREALLOC 0x4 /* rtn status BMV_OF_PREALLOC if req */
116#define BMV_IF_VALID (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC) 116#define BMV_IF_DELALLOC 0x8 /* rtn status BMV_OF_DELALLOC if req */
117#define BMV_IF_VALID \
118 (BMV_IF_ATTRFORK|BMV_IF_NO_DMAPI_READ|BMV_IF_PREALLOC|BMV_IF_DELALLOC)
117 119
118/* bmv_oflags values - returned for for each non-header segment */ 120/* bmv_oflags values - returned for for each non-header segment */
119#define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */ 121#define BMV_OF_PREALLOC 0x1 /* segment = unwritten pre-allocation */
122#define BMV_OF_DELALLOC 0x2 /* segment = delayed allocation */
123#define BMV_OF_LAST 0x4 /* segment is the last in the file */
120 124
121/* 125/*
122 * Structure for XFS_IOC_FSSETDM. 126 * Structure for XFS_IOC_FSSETDM.