diff options
-rw-r--r-- | fs/xfs/xfs_bmap.c | 46 | ||||
-rw-r--r-- | fs/xfs/xfs_fs.h | 6 |
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. |