STATIC int xfs_ioc_getbmapx( struct xfs_inode *ip, void __user *arg) { struct getbmapx bmx; int error; if (copy_from_user(&bmx, arg, sizeof(bmx))) return -XFS_ERROR(EFAULT); if (bmx.bmv_count < 2) return -XFS_ERROR(EINVAL); if (bmx.bmv_iflags & (~BMV_IF_VALID)) return -XFS_ERROR(EINVAL); error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format, (struct getbmapx *)arg+1); if (error) return -error; /* copy back header */ if (copy_to_user(arg, &bmx, sizeof(struct getbmapx))) return -XFS_ERROR(EFAULT); return 0; }
STATIC int xfs_ioc_getbmap( struct xfs_inode *ip, int ioflags, unsigned int cmd, void __user *arg) { struct getbmapx bmx; int error; if (copy_from_user(&bmx, arg, sizeof(struct getbmapx))) return -XFS_ERROR(EFAULT); if (bmx.bmv_count < 2) return -XFS_ERROR(EINVAL); bmx.bmv_iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); if (ioflags & IO_INVIS) bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, (struct getbmap *)arg+1); if (error) return -error; /* copy back header - only size of getbmap */ if (copy_to_user(arg, &bmx, sizeof(struct getbmap))) return -XFS_ERROR(EFAULT); return 0; }
STATIC int xfs_ioc_getbmap( bhv_desc_t *bdp, struct file *filp, int ioflags, unsigned int cmd, unsigned long arg) { struct getbmap bm; int iflags; int error; if (copy_from_user(&bm, (struct getbmap *)arg, sizeof(bm))) return -XFS_ERROR(EFAULT); if (bm.bmv_count < 2) return -XFS_ERROR(EINVAL); iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); if (ioflags & IO_INVIS) iflags |= BMV_IF_NO_DMAPI_READ; error = xfs_getbmap(bdp, &bm, (struct getbmap *)arg+1, iflags); if (error) return -error; if (copy_to_user((struct getbmap *)arg, &bm, sizeof(bm))) return -XFS_ERROR(EFAULT); return 0; }
STATIC int xfs_ioc_getbmap( struct xfs_inode *ip, int ioflags, unsigned int cmd, void __user *arg) { struct getbmap bm; int iflags; int error; if (copy_from_user(&bm, arg, sizeof(bm))) return -XFS_ERROR(EFAULT); if (bm.bmv_count < 2) return -XFS_ERROR(EINVAL); iflags = (cmd == XFS_IOC_GETBMAPA ? BMV_IF_ATTRFORK : 0); if (ioflags & IO_INVIS) iflags |= BMV_IF_NO_DMAPI_READ; error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags); if (error) return -error; if (copy_to_user(arg, &bm, sizeof(bm))) return -XFS_ERROR(EFAULT); return 0; }
STATIC int xfs_vn_fiemap( struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 length) { xfs_inode_t *ip = XFS_I(inode); struct getbmapx bm; int error; error = fiemap_check_flags(fieinfo, XFS_FIEMAP_FLAGS); if (error) return error; /* Set up bmap header for xfs internal routine */ bm.bmv_offset = BTOBB(start); /* Special case for whole file */ if (length == FIEMAP_MAX_OFFSET) bm.bmv_length = -1LL; else bm.bmv_length = BTOBB(length); /* We add one because in getbmap world count includes the header */ bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM : fieinfo->fi_extents_max + 1; bm.bmv_count = min_t(__s32, bm.bmv_count, (PAGE_SIZE * 16 / sizeof(struct getbmapx))); bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES; if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) bm.bmv_iflags |= BMV_IF_ATTRFORK; if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) bm.bmv_iflags |= BMV_IF_DELALLOC; error = xfs_getbmap(ip, &bm, xfs_fiemap_format, fieinfo); if (error) return -error; return 0; }
STATIC int xfs_ioc_getbmapx( bhv_desc_t *bdp, unsigned long arg) { struct getbmapx bmx; struct getbmap bm; int iflags; int error; if (copy_from_user(&bmx, (struct getbmapx *)arg, sizeof(bmx))) return -XFS_ERROR(EFAULT); if (bmx.bmv_count < 2) return -XFS_ERROR(EINVAL); /* * Map input getbmapx structure to a getbmap * structure for xfs_getbmap. */ GETBMAP_CONVERT(bmx, bm); iflags = bmx.bmv_iflags; if (iflags & (~BMV_IF_VALID)) return -XFS_ERROR(EINVAL); iflags |= BMV_IF_EXTENDED; error = xfs_getbmap(bdp, &bm, (struct getbmapx *)arg+1, iflags); if (error) return -error; GETBMAP_CONVERT(bm, bmx); if (copy_to_user((struct getbmapx *)arg, &bmx, sizeof(bmx))) return -XFS_ERROR(EFAULT); return 0; }
STATIC int xfs_vn_fiemap( struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 length) { xfs_inode_t *ip = XFS_I(inode); struct getbmapx bm; int error; error = fiemap_check_flags(fieinfo, XFS_FIEMAP_FLAGS); if (error) return error; /* Set up bmap header for xfs internal routine */ bm.bmv_offset = BTOBB(start); /* Special case for whole file */ if (length == FIEMAP_MAX_OFFSET) bm.bmv_length = -1LL; else bm.bmv_length = BTOBB(length); /* our formatter will tell xfs_getbmap when to stop. */ bm.bmv_count = MAXEXTNUM; bm.bmv_iflags = BMV_IF_PREALLOC; if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) bm.bmv_iflags |= BMV_IF_ATTRFORK; if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC)) bm.bmv_iflags |= BMV_IF_DELALLOC; error = xfs_getbmap(ip, &bm, xfs_fiemap_format, fieinfo); if (error) return -error; return 0; }