Changeset View
Changeset View
Standalone View
Standalone View
sys/contrib/openzfs/module/os/freebsd/zfs/zfs_ctldir.c
Show First 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | sfs_reclaim_vnode(vnode_t *vp) | ||||
sfs_vnode_remove(vp); | sfs_vnode_remove(vp); | ||||
data = vp->v_data; | data = vp->v_data; | ||||
vp->v_data = NULL; | vp->v_data = NULL; | ||||
return (data); | return (data); | ||||
} | } | ||||
static int | static int | ||||
sfs_readdir_common(uint64_t parent_id, uint64_t id, struct vop_readdir_args *ap, | sfs_readdir_common(uint64_t parent_id, uint64_t id, struct vop_readdir_args *ap, | ||||
uio_t *uio, off_t *offp) | zfs_uio_t *uio, off_t *offp) | ||||
{ | { | ||||
struct dirent entry; | struct dirent entry; | ||||
int error; | int error; | ||||
/* Reset ncookies for subsequent use of vfs_read_dirent. */ | /* Reset ncookies for subsequent use of vfs_read_dirent. */ | ||||
if (ap->a_ncookies != NULL) | if (ap->a_ncookies != NULL) | ||||
*ap->a_ncookies = 0; | *ap->a_ncookies = 0; | ||||
if (uio->uio_resid < sizeof (entry)) | if (zfs_uio_resid(uio) < sizeof (entry)) | ||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
if (uio->uio_offset < 0) | if (zfs_uio_offset(uio) < 0) | ||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
if (uio->uio_offset == 0) { | if (zfs_uio_offset(uio) == 0) { | ||||
entry.d_fileno = id; | entry.d_fileno = id; | ||||
entry.d_type = DT_DIR; | entry.d_type = DT_DIR; | ||||
entry.d_name[0] = '.'; | entry.d_name[0] = '.'; | ||||
entry.d_name[1] = '\0'; | entry.d_name[1] = '\0'; | ||||
entry.d_namlen = 1; | entry.d_namlen = 1; | ||||
entry.d_reclen = sizeof (entry); | entry.d_reclen = sizeof (entry); | ||||
error = vfs_read_dirent(ap, &entry, uio->uio_offset); | error = vfs_read_dirent(ap, &entry, zfs_uio_offset(uio)); | ||||
if (error != 0) | if (error != 0) | ||||
return (SET_ERROR(error)); | return (SET_ERROR(error)); | ||||
} | } | ||||
if (uio->uio_offset < sizeof (entry)) | if (zfs_uio_offset(uio) < sizeof (entry)) | ||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
if (uio->uio_offset == sizeof (entry)) { | if (zfs_uio_offset(uio) == sizeof (entry)) { | ||||
entry.d_fileno = parent_id; | entry.d_fileno = parent_id; | ||||
entry.d_type = DT_DIR; | entry.d_type = DT_DIR; | ||||
entry.d_name[0] = '.'; | entry.d_name[0] = '.'; | ||||
entry.d_name[1] = '.'; | entry.d_name[1] = '.'; | ||||
entry.d_name[2] = '\0'; | entry.d_name[2] = '\0'; | ||||
entry.d_namlen = 2; | entry.d_namlen = 2; | ||||
entry.d_reclen = sizeof (entry); | entry.d_reclen = sizeof (entry); | ||||
error = vfs_read_dirent(ap, &entry, uio->uio_offset); | error = vfs_read_dirent(ap, &entry, zfs_uio_offset(uio)); | ||||
if (error != 0) | if (error != 0) | ||||
return (SET_ERROR(error)); | return (SET_ERROR(error)); | ||||
} | } | ||||
if (offp != NULL) | if (offp != NULL) | ||||
*offp = 2 * sizeof (entry); | *offp = 2 * sizeof (entry); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 362 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
zfsctl_root_readdir(struct vop_readdir_args *ap) | zfsctl_root_readdir(struct vop_readdir_args *ap) | ||||
{ | { | ||||
struct dirent entry; | struct dirent entry; | ||||
vnode_t *vp = ap->a_vp; | vnode_t *vp = ap->a_vp; | ||||
zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; | zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; | ||||
zfsctl_root_t *node = vp->v_data; | zfsctl_root_t *node = vp->v_data; | ||||
uio_t *uio = ap->a_uio; | zfs_uio_t uio; | ||||
int *eofp = ap->a_eofflag; | int *eofp = ap->a_eofflag; | ||||
off_t dots_offset; | off_t dots_offset; | ||||
int error; | int error; | ||||
zfs_uio_init(&uio, ap->a_uio); | |||||
ASSERT(vp->v_type == VDIR); | ASSERT(vp->v_type == VDIR); | ||||
error = sfs_readdir_common(zfsvfs->z_root, ZFSCTL_INO_ROOT, ap, uio, | error = sfs_readdir_common(zfsvfs->z_root, ZFSCTL_INO_ROOT, ap, &uio, | ||||
&dots_offset); | &dots_offset); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ENAMETOOLONG) /* ran out of destination space */ | if (error == ENAMETOOLONG) /* ran out of destination space */ | ||||
error = 0; | error = 0; | ||||
return (error); | return (error); | ||||
} | } | ||||
if (uio->uio_offset != dots_offset) | if (zfs_uio_offset(&uio) != dots_offset) | ||||
return (SET_ERROR(EINVAL)); | return (SET_ERROR(EINVAL)); | ||||
CTASSERT(sizeof (node->snapdir->sn_name) <= sizeof (entry.d_name)); | CTASSERT(sizeof (node->snapdir->sn_name) <= sizeof (entry.d_name)); | ||||
entry.d_fileno = node->snapdir->sn_id; | entry.d_fileno = node->snapdir->sn_id; | ||||
entry.d_type = DT_DIR; | entry.d_type = DT_DIR; | ||||
strcpy(entry.d_name, node->snapdir->sn_name); | strcpy(entry.d_name, node->snapdir->sn_name); | ||||
entry.d_namlen = strlen(entry.d_name); | entry.d_namlen = strlen(entry.d_name); | ||||
entry.d_reclen = sizeof (entry); | entry.d_reclen = sizeof (entry); | ||||
error = vfs_read_dirent(ap, &entry, uio->uio_offset); | error = vfs_read_dirent(ap, &entry, zfs_uio_offset(&uio)); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ENAMETOOLONG) | if (error == ENAMETOOLONG) | ||||
error = 0; | error = 0; | ||||
return (SET_ERROR(error)); | return (SET_ERROR(error)); | ||||
} | } | ||||
if (eofp != NULL) | if (eofp != NULL) | ||||
*eofp = 1; | *eofp = 1; | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 324 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
zfsctl_snapdir_readdir(struct vop_readdir_args *ap) | zfsctl_snapdir_readdir(struct vop_readdir_args *ap) | ||||
{ | { | ||||
char snapname[ZFS_MAX_DATASET_NAME_LEN]; | char snapname[ZFS_MAX_DATASET_NAME_LEN]; | ||||
struct dirent entry; | struct dirent entry; | ||||
vnode_t *vp = ap->a_vp; | vnode_t *vp = ap->a_vp; | ||||
zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; | zfsvfs_t *zfsvfs = vp->v_vfsp->vfs_data; | ||||
uio_t *uio = ap->a_uio; | zfs_uio_t uio; | ||||
int *eofp = ap->a_eofflag; | int *eofp = ap->a_eofflag; | ||||
off_t dots_offset; | off_t dots_offset; | ||||
int error; | int error; | ||||
zfs_uio_init(&uio, ap->a_uio); | |||||
ASSERT(vp->v_type == VDIR); | ASSERT(vp->v_type == VDIR); | ||||
error = sfs_readdir_common(ZFSCTL_INO_ROOT, ZFSCTL_INO_SNAPDIR, ap, uio, | error = sfs_readdir_common(ZFSCTL_INO_ROOT, ZFSCTL_INO_SNAPDIR, ap, | ||||
&dots_offset); | &uio, &dots_offset); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ENAMETOOLONG) /* ran out of destination space */ | if (error == ENAMETOOLONG) /* ran out of destination space */ | ||||
error = 0; | error = 0; | ||||
return (error); | return (error); | ||||
} | } | ||||
ZFS_ENTER(zfsvfs); | ZFS_ENTER(zfsvfs); | ||||
for (;;) { | for (;;) { | ||||
uint64_t cookie; | uint64_t cookie; | ||||
uint64_t id; | uint64_t id; | ||||
cookie = uio->uio_offset - dots_offset; | cookie = zfs_uio_offset(&uio) - dots_offset; | ||||
dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG); | dsl_pool_config_enter(dmu_objset_pool(zfsvfs->z_os), FTAG); | ||||
error = dmu_snapshot_list_next(zfsvfs->z_os, sizeof (snapname), | error = dmu_snapshot_list_next(zfsvfs->z_os, sizeof (snapname), | ||||
snapname, &id, &cookie, NULL); | snapname, &id, &cookie, NULL); | ||||
dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG); | dsl_pool_config_exit(dmu_objset_pool(zfsvfs->z_os), FTAG); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ENOENT) { | if (error == ENOENT) { | ||||
if (eofp != NULL) | if (eofp != NULL) | ||||
*eofp = 1; | *eofp = 1; | ||||
error = 0; | error = 0; | ||||
} | } | ||||
ZFS_EXIT(zfsvfs); | ZFS_EXIT(zfsvfs); | ||||
return (error); | return (error); | ||||
} | } | ||||
entry.d_fileno = id; | entry.d_fileno = id; | ||||
entry.d_type = DT_DIR; | entry.d_type = DT_DIR; | ||||
strcpy(entry.d_name, snapname); | strcpy(entry.d_name, snapname); | ||||
entry.d_namlen = strlen(entry.d_name); | entry.d_namlen = strlen(entry.d_name); | ||||
entry.d_reclen = sizeof (entry); | entry.d_reclen = sizeof (entry); | ||||
error = vfs_read_dirent(ap, &entry, uio->uio_offset); | error = vfs_read_dirent(ap, &entry, zfs_uio_offset(&uio)); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ENAMETOOLONG) | if (error == ENAMETOOLONG) | ||||
error = 0; | error = 0; | ||||
ZFS_EXIT(zfsvfs); | ZFS_EXIT(zfsvfs); | ||||
return (SET_ERROR(error)); | return (SET_ERROR(error)); | ||||
} | } | ||||
uio->uio_offset = cookie + dots_offset; | zfs_uio_setoffset(&uio, cookie + dots_offset); | ||||
} | } | ||||
/* NOTREACHED */ | /* NOTREACHED */ | ||||
} | } | ||||
static int | static int | ||||
zfsctl_snapdir_getattr(struct vop_getattr_args *ap) | zfsctl_snapdir_getattr(struct vop_getattr_args *ap) | ||||
{ | { | ||||
vnode_t *vp = ap->a_vp; | vnode_t *vp = ap->a_vp; | ||||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |