aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c62
1 files changed, 25 insertions, 37 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index c3912213645c..8077580a7199 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5811,9 +5811,9 @@ error0:
5811STATIC int 5811STATIC int
5812xfs_getbmapx_fix_eof_hole( 5812xfs_getbmapx_fix_eof_hole(
5813 xfs_inode_t *ip, /* xfs incore inode pointer */ 5813 xfs_inode_t *ip, /* xfs incore inode pointer */
5814 struct getbmap *out, /* output structure */ 5814 struct getbmapx *out, /* output structure */
5815 int prealloced, /* this is a file with 5815 int prealloced, /* this is a file with
5816 * preallocated data space */ 5816 * preallocated data space */
5817 __int64_t end, /* last block requested */ 5817 __int64_t end, /* last block requested */
5818 xfs_fsblock_t startblock) 5818 xfs_fsblock_t startblock)
5819{ 5819{
@@ -5839,14 +5839,18 @@ xfs_getbmapx_fix_eof_hole(
5839} 5839}
5840 5840
5841/* 5841/*
5842 * Fcntl interface to xfs_bmapi. 5842 * Get inode's extents as described in bmv, and format for output.
5843 * Calls formatter to fill the user's buffer until all extents
5844 * are mapped, until the passed-in bmv->bmv_count slots have
5845 * been filled, or until the formatter short-circuits the loop,
5846 * if it is tracking filled-in extents on its own.
5843 */ 5847 */
5844int /* error code */ 5848int /* error code */
5845xfs_getbmap( 5849xfs_getbmap(
5846 xfs_inode_t *ip, 5850 xfs_inode_t *ip,
5847 struct getbmap *bmv, /* user bmap structure */ 5851 struct getbmapx *bmv, /* user bmap structure */
5848 void __user *ap, /* pointer to user's array */ 5852 xfs_bmap_format_t formatter, /* format to user */
5849 int interface) /* interface flags */ 5853 void *arg) /* formatter arg */
5850{ 5854{
5851 __int64_t bmvend; /* last block requested */ 5855 __int64_t bmvend; /* last block requested */
5852 int error; /* return value */ 5856 int error; /* return value */
@@ -5859,19 +5863,20 @@ xfs_getbmap(
5859 int nexleft; /* # of user extents left */ 5863 int nexleft; /* # of user extents left */
5860 int subnex; /* # of bmapi's can do */ 5864 int subnex; /* # of bmapi's can do */
5861 int nmap; /* number of map entries */ 5865 int nmap; /* number of map entries */
5862 struct getbmap out; /* output structure */ 5866 struct getbmapx out; /* output structure */
5863 int whichfork; /* data or attr fork */ 5867 int whichfork; /* data or attr fork */
5864 int prealloced; /* this is a file with 5868 int prealloced; /* this is a file with
5865 * preallocated data space */ 5869 * preallocated data space */
5866 int sh_unwritten; /* true, if unwritten */ 5870 int sh_unwritten; /* true, if unwritten */
5867 /* extents listed separately */ 5871 /* extents listed separately */
5872 int iflags; /* interface flags */
5868 int bmapi_flags; /* flags for xfs_bmapi */ 5873 int bmapi_flags; /* flags for xfs_bmapi */
5869 __int32_t oflags; /* getbmapx bmv_oflags field */
5870 5874
5871 mp = ip->i_mount; 5875 mp = ip->i_mount;
5876 iflags = bmv->bmv_iflags;
5872 5877
5873 whichfork = interface & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK; 5878 whichfork = iflags & BMV_IF_ATTRFORK ? XFS_ATTR_FORK : XFS_DATA_FORK;
5874 sh_unwritten = (interface & BMV_IF_PREALLOC) != 0; 5879 sh_unwritten = (iflags & BMV_IF_PREALLOC) != 0;
5875 5880
5876 /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not 5881 /* If the BMV_IF_NO_DMAPI_READ interface bit specified, do not
5877 * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ 5882 * generate a DMAPI read event. Otherwise, if the DM_EVENT_READ
@@ -5886,7 +5891,7 @@ xfs_getbmap(
5886 * could misinterpret holes in a DMAPI file as true holes, 5891 * could misinterpret holes in a DMAPI file as true holes,
5887 * when in fact they may represent offline user data. 5892 * when in fact they may represent offline user data.
5888 */ 5893 */
5889 if ((interface & BMV_IF_NO_DMAPI_READ) == 0 && 5894 if ((iflags & BMV_IF_NO_DMAPI_READ) == 0 &&
5890 DM_EVENT_ENABLED(ip, DM_EVENT_READ) && 5895 DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
5891 whichfork == XFS_DATA_FORK) { 5896 whichfork == XFS_DATA_FORK) {
5892 error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL); 5897 error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, 0, 0, 0, NULL);
@@ -5993,52 +5998,35 @@ xfs_getbmap(
5993 ASSERT(nmap <= subnex); 5998 ASSERT(nmap <= subnex);
5994 5999
5995 for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) { 6000 for (i = 0; i < nmap && nexleft && bmv->bmv_length; i++) {
5996 nexleft--; 6001 out.bmv_oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ?
5997 oflags = (map[i].br_state == XFS_EXT_UNWRITTEN) ?
5998 BMV_OF_PREALLOC : 0; 6002 BMV_OF_PREALLOC : 0;
5999 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff); 6003 out.bmv_offset = XFS_FSB_TO_BB(mp, map[i].br_startoff);
6000 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount); 6004 out.bmv_length = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
6005 out.bmv_unused1 = out.bmv_unused2 = 0;
6001 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK); 6006 ASSERT(map[i].br_startblock != DELAYSTARTBLOCK);
6002 if (map[i].br_startblock == HOLESTARTBLOCK && 6007 if (map[i].br_startblock == HOLESTARTBLOCK &&
6003 whichfork == XFS_ATTR_FORK) { 6008 whichfork == XFS_ATTR_FORK) {
6004 /* came to the end of attribute fork */ 6009 /* came to the end of attribute fork */
6005 goto unlock_and_return; 6010 goto unlock_and_return;
6006 } else { 6011 } else {
6012 int full = 0; /* user array is full */
6013
6007 if (!xfs_getbmapx_fix_eof_hole(ip, &out, 6014 if (!xfs_getbmapx_fix_eof_hole(ip, &out,
6008 prealloced, bmvend, 6015 prealloced, bmvend,
6009 map[i].br_startblock)) { 6016 map[i].br_startblock)) {
6010 goto unlock_and_return; 6017 goto unlock_and_return;
6011 } 6018 }
6012 6019
6013 /* return either getbmap/getbmapx structure. */ 6020 /* format results & advance arg */
6014 if (interface & BMV_IF_EXTENDED) { 6021 error = formatter(&arg, &out, &full);
6015 struct getbmapx outx; 6022 if (error || full)
6016 6023 goto unlock_and_return;
6017 GETBMAP_CONVERT(out,outx); 6024 nexleft--;
6018 outx.bmv_oflags = oflags;
6019 outx.bmv_unused1 = outx.bmv_unused2 = 0;
6020 if (copy_to_user(ap, &outx,
6021 sizeof(outx))) {
6022 error = XFS_ERROR(EFAULT);
6023 goto unlock_and_return;
6024 }
6025 } else {
6026 if (copy_to_user(ap, &out,
6027 sizeof(out))) {
6028 error = XFS_ERROR(EFAULT);
6029 goto unlock_and_return;
6030 }
6031 }
6032 bmv->bmv_offset = 6025 bmv->bmv_offset =
6033 out.bmv_offset + out.bmv_length; 6026 out.bmv_offset + out.bmv_length;
6034 bmv->bmv_length = MAX((__int64_t)0, 6027 bmv->bmv_length = MAX((__int64_t)0,
6035 (__int64_t)(bmvend - bmv->bmv_offset)); 6028 (__int64_t)(bmvend - bmv->bmv_offset));
6036 bmv->bmv_entries++; 6029 bmv->bmv_entries++;
6037 ap = (interface & BMV_IF_EXTENDED) ?
6038 (void __user *)
6039 ((struct getbmapx __user *)ap + 1) :
6040 (void __user *)
6041 ((struct getbmap __user *)ap + 1);
6042 } 6030 }
6043 } 6031 }
6044 } while (nmap && nexleft && bmv->bmv_length); 6032 } while (nmap && nexleft && bmv->bmv_length);