diff options
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 62 |
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: | |||
5811 | STATIC int | 5811 | STATIC int |
5812 | xfs_getbmapx_fix_eof_hole( | 5812 | xfs_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 | */ |
5844 | int /* error code */ | 5848 | int /* error code */ |
5845 | xfs_getbmap( | 5849 | xfs_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); |