diff options
author | Eric Sandeen <sandeen@sandeen.net> | 2008-11-27 22:23:35 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:29:00 -0500 |
commit | 8a7141a8b931d60d42830432b82078cd6dace83b (patch) | |
tree | e5f1f2573b7e759e8d04b39757c1491689037485 /fs/xfs/linux-2.6/xfs_ioctl.c | |
parent | 0924b585fc49bf371bc700c23e516a538bf589af (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.c | 64 |
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 | ||
1252 | STATIC int | 1252 | STATIC int |
1253 | xfs_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 | |||
1265 | STATIC int | ||
1253 | xfs_ioc_getbmap( | 1266 | xfs_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 | ||
1282 | STATIC int | 1296 | STATIC int |
1297 | xfs_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 | |||
1308 | STATIC int | ||
1283 | xfs_ioc_getbmapx( | 1309 | xfs_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; |