aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@sandeen.net>2008-11-27 22:23:35 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:29:28 -0500
commit5af317c942aebc928ab244eb69581bd8e5333215 (patch)
treebcfd7f8362ec92b9087df15a9548f57cbf1a2729 /fs/xfs/xfs_bmap.c
parent8a7141a8b931d60d42830432b82078cd6dace83b (diff)
[XFS] Add new getbmap flags.
This adds a new output flag, BMV_OF_LAST to indicate if we've hit the last extent in the inode. This potentially saves an extra call from userspace to see when the whole mapping is done. It also adds BMV_IF_DELALLOC and BMV_OF_DELALLOC to request, and indicate, delayed-allocation extents. In this case bmv_block is set to -2 (-1 was already taken for HOLESTARTBLOCK; unfortunately these are the reverse of the in-kernel constants.) These new flags facilitate addition of the new fiemap interface. Rather than adding sh_delalloc, remove sh_unwritten & just test the flags directly. Signed-off-by: Eric Sandeen <sandeen@sandeen.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c46
1 files changed, 32 insertions, 14 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 */