aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.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/linux-2.6/xfs_ioctl.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/linux-2.6/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index f1bd6c36e6fe..d59705999534 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -1250,43 +1250,67 @@ xfs_ioc_setxflags(
1250} 1250}
1251 1251
1252STATIC int 1252STATIC int
1253xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full)
1254{
1255 struct getbmap __user *base = *ap;
1256
1257 /* copy only getbmap portion (not getbmapx) */
1258 if (copy_to_user(base, bmv, sizeof(struct getbmap)))
1259 return XFS_ERROR(EFAULT);
1260
1261 *ap += sizeof(struct getbmap);
1262 return 0;
1263}
1264
1265STATIC int
1253xfs_ioc_getbmap( 1266xfs_ioc_getbmap(
1254 struct xfs_inode *ip, 1267 struct xfs_inode *ip,
1255 int ioflags, 1268 int ioflags,
1256 unsigned int cmd, 1269 unsigned int cmd,
1257 void __user *arg) 1270 void __user *arg)
1258{ 1271{
1259 struct getbmap bm; 1272 struct getbmapx bmx;
1260 int iflags;
1261 int error; 1273 int error;
1262 1274
1263 if (copy_from_user(&bm, arg, sizeof(bm))) 1275 if (copy_from_user(&bmx, arg, sizeof(struct getbmapx)))
1264 return -XFS_ERROR(EFAULT); 1276 return -XFS_ERROR(EFAULT);
1265 1277
1266 if (bm.bmv_count < 2) 1278 if (bmx.bmv_count < 2)
1267 return -XFS_ERROR(EINVAL); 1279 return -XFS_ERROR(EINVAL);
1268 1280
1269 iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); 1281 bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0);
1270 if (ioflags & IO_INVIS) 1282 if (ioflags & IO_INVIS)
1271 iflags |= BMV_IF_NO_DMAPI_READ; 1283 bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ;
1272 1284
1273 error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags); 1285 error = xfs_getbmap(ip, &bmx, xfs_getbmap_format,
1286 (struct getbmap *)arg+1);
1274 if (error) 1287 if (error)
1275 return -error; 1288 return -error;
1276 1289
1277 if (copy_to_user(arg, &bm, sizeof(bm))) 1290 /* copy back header - only size of getbmap */
1291 if (copy_to_user(arg, &bmx, sizeof(struct getbmap)))
1278 return -XFS_ERROR(EFAULT); 1292 return -XFS_ERROR(EFAULT);
1279 return 0; 1293 return 0;
1280} 1294}
1281 1295
1282STATIC int 1296STATIC int
1297xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full)
1298{
1299 struct getbmapx __user *base = *ap;
1300
1301 if (copy_to_user(base, bmv, sizeof(struct getbmapx)))
1302 return XFS_ERROR(EFAULT);
1303
1304 *ap += sizeof(struct getbmapx);
1305 return 0;
1306}
1307
1308STATIC int
1283xfs_ioc_getbmapx( 1309xfs_ioc_getbmapx(
1284 struct xfs_inode *ip, 1310 struct xfs_inode *ip,
1285 void __user *arg) 1311 void __user *arg)
1286{ 1312{
1287 struct getbmapx bmx; 1313 struct getbmapx bmx;
1288 struct getbmap bm;
1289 int iflags;
1290 int error; 1314 int error;
1291 1315
1292 if (copy_from_user(&bmx, arg, sizeof(bmx))) 1316 if (copy_from_user(&bmx, arg, sizeof(bmx)))
@@ -1295,26 +1319,16 @@ xfs_ioc_getbmapx(
1295 if (bmx.bmv_count < 2) 1319 if (bmx.bmv_count < 2)
1296 return -XFS_ERROR(EINVAL); 1320 return -XFS_ERROR(EINVAL);
1297 1321
1298 /* 1322 if (bmx.bmv_iflags & (~BMV_IF_VALID))
1299 * Map input getbmapx structure to a getbmap
1300 * structure for xfs_getbmap.
1301 */
1302 GETBMAP_CONVERT(bmx, bm);
1303
1304 iflags = bmx.bmv_iflags;
1305
1306 if (iflags & (~BMV_IF_VALID))
1307 return -XFS_ERROR(EINVAL); 1323 return -XFS_ERROR(EINVAL);
1308 1324
1309 iflags |= BMV_IF_EXTENDED; 1325 error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format,
1310 1326 (struct getbmapx *)arg+1);
1311 error = xfs_getbmap(ip, &bm, (struct getbmapx __user *)arg+1, iflags);
1312 if (error) 1327 if (error)
1313 return -error; 1328 return -error;
1314 1329
1315 GETBMAP_CONVERT(bm, bmx); 1330 /* copy back header */
1316 1331 if (copy_to_user(arg, &bmx, sizeof(struct getbmapx)))
1317 if (copy_to_user(arg, &bmx, sizeof(bmx)))
1318 return -XFS_ERROR(EFAULT); 1332 return -XFS_ERROR(EFAULT);
1319 1333
1320 return 0; 1334 return 0;