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:00 -0500
commit8a7141a8b931d60d42830432b82078cd6dace83b (patch)
treee5f1f2573b7e759e8d04b39757c1491689037485 /fs/xfs/xfs_bmap.c
parent0924b585fc49bf371bc700c23e516a538bf589af (diff)
[XFS] convert xfs_getbmap to take formatter functions
Preliminary work to hook up fiemap, this allows us to pass in an arbitrary formatter to copy extent data back to userspace. The formatter takes info for 1 extent, a pointer to the user "thing*" and a pointer to a "filled" variable to indicate whether a userspace buffer did get filled in (for fiemap, hole "extents" are skipped). I'm just using the getbmapx struct as a "common denominator" because as far as I can see, it holds all info that any formatters will care about. ("*thing" because fiemap doesn't pass the user pointer around, but rather has a pointer to a fiemap info structure, and helpers associated with it) 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.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);