static int zvol_read(struct bio *bio) { zvol_state_t *zv = bio->bi_bdev->bd_disk->private_data; uint64_t offset = BIO_BI_SECTOR(bio) << 9; uint64_t size = BIO_BI_SIZE(bio); int error; rl_t *rl; uio_t uio; if (size == 0) return (0); uio.uio_bvec = &bio->bi_io_vec[BIO_BI_IDX(bio)]; uio.uio_skip = BIO_BI_SKIP(bio); uio.uio_resid = size; uio.uio_iovcnt = bio->bi_vcnt - BIO_BI_IDX(bio); uio.uio_loffset = offset; uio.uio_limit = MAXOFFSET_T; uio.uio_segflg = UIO_BVEC; rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_READER); error = dmu_read_uio(zv->zv_objset, ZVOL_OBJ, &uio, size); zfs_range_unlock(rl); /* convert checksum errors into IO errors */ if (error == ECKSUM) error = SET_ERROR(EIO); return (error); }
void getfinderinfo(znode_t *zp, cred_t *cr, finderinfo_t *fip) { vnode_t *xdvp = NULLVP; vnode_t *xvp = NULLVP; struct uio *auio = NULL; struct componentname cn; int error; uint64_t xattr = 0; if (sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zp->z_zfsvfs), &xattr, sizeof(xattr)) || (xattr == 0)) { goto nodata; } auio = uio_create(1, 0, UIO_SYSSPACE, UIO_READ); if (auio == NULL) { goto nodata; } uio_addiov(auio, CAST_USER_ADDR_T(fip), sizeof (finderinfo_t)); /* * Grab the hidden attribute directory vnode. * * XXX - switch to embedded Finder Info when it becomes available */ if ((error = zfs_get_xattrdir(zp, &xdvp, cr, 0))) { goto out; } bzero(&cn, sizeof (cn)); cn.cn_nameiop = LOOKUP; cn.cn_flags = ISLASTCN; cn.cn_nameptr = XATTR_FINDERINFO_NAME; cn.cn_namelen = strlen(cn.cn_nameptr); if ((error = zfs_dirlook(VTOZ(xdvp), cn.cn_nameptr, &xvp, 0, NULL, &cn))) { goto out; } error = dmu_read_uio(zp->z_zfsvfs->z_os, VTOZ(xvp)->z_id, auio, sizeof (finderinfo_t)); out: if (auio) uio_free(auio); if (xvp) vnode_put(xvp); if (xdvp) vnode_put(xdvp); if (error == 0) return; nodata: bzero(fip, sizeof (finderinfo_t)); }