git: 6ea02becc78c - stable/13 - vfs: Export get_next_dirent() as vn_dir_next_dirent()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 05 May 2023 06:38:55 UTC
The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=6ea02becc78c1885ae13713a94e83a5160e63396 commit 6ea02becc78c1885ae13713a94e83a5160e63396 Author: Olivier Certner <olce.freebsd@certner.fr> AuthorDate: 2023-04-23 07:47:58 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-05-05 06:20:58 +0000 vfs: Export get_next_dirent() as vn_dir_next_dirent() (cherry picked from commit 6bce3f23d0aa045d61c0ec8d27100eb186a33375) --- sys/kern/vfs_default.c | 73 +++----------------------------------------------- sys/kern/vfs_vnops.c | 62 ++++++++++++++++++++++++++++++++++++++++++ sys/sys/vnode.h | 3 +++ 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 6201426d582c..502a81d3036c 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -75,15 +75,9 @@ __FBSDID("$FreeBSD$"); static int vop_nolookup(struct vop_lookup_args *); static int vop_norename(struct vop_rename_args *); static int vop_nostrategy(struct vop_strategy_args *); -static int get_next_dirent(struct vnode *vp, struct dirent **dpp, - char *dirbuf, int dirbuflen, off_t *off, - char **cpos, int *len, int *eofflag, - struct thread *td); static int dirent_exists(struct vnode *vp, const char *dirname, struct thread *td); -#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) - static int vop_stdis_text(struct vop_is_text_args *ap); static int vop_stdunset_text(struct vop_unset_text_args *ap); static int vop_stdadd_writecount(struct vop_add_writecount_args *ap); @@ -280,65 +274,6 @@ vop_nostrategy (struct vop_strategy_args *ap) return (EOPNOTSUPP); } -static int -get_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, - int dirbuflen, off_t *off, char **cpos, int *len, - int *eofflag, struct thread *td) -{ - int error, reclen; - struct uio uio; - struct iovec iov; - struct dirent *dp; - - KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); - KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); - - if (*len == 0) { - iov.iov_base = dirbuf; - iov.iov_len = dirbuflen; - - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = *off; - uio.uio_resid = dirbuflen; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_READ; - uio.uio_td = td; - - *eofflag = 0; - -#ifdef MAC - error = mac_vnode_check_readdir(td->td_ucred, vp); - if (error == 0) -#endif - error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, - NULL, NULL); - if (error) - return (error); - - *off = uio.uio_offset; - - *cpos = dirbuf; - *len = (dirbuflen - uio.uio_resid); - - if (*len == 0) - return (ENOENT); - } - - dp = (struct dirent *)(*cpos); - reclen = dp->d_reclen; - *dpp = dp; - - /* check for malformed directory.. */ - if (reclen < DIRENT_MINSIZE) - return (EINVAL); - - *cpos += reclen; - *len -= reclen; - - return (0); -} - /* * Check if a named file exists in a given directory vnode. */ @@ -368,8 +303,8 @@ dirent_exists(struct vnode *vp, const char *dirname, struct thread *td) off = 0; len = 0; do { - error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, - &cpos, &len, &eofflag, td); + error = vn_dir_next_dirent(vp, &dp, dirbuf, dirbuflen, &off, + &cpos, &len, &eofflag, td); if (error) goto out; @@ -806,8 +741,8 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap) len = 0; do { /* call VOP_READDIR of parent */ - error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, - &cpos, &len, &eofflag, td); + error = vn_dir_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off, + &cpos, &len, &eofflag, td); if (error) goto out; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 215c9d1cc0cc..c35370d9d6b3 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <sys/namei.h> #include <sys/vnode.h> +#include <sys/dirent.h> #include <sys/bio.h> #include <sys/buf.h> #include <sys/filio.h> @@ -3594,6 +3595,67 @@ vn_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td) return (error); } +#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) + +int +vn_dir_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, + int dirbuflen, off_t *off, char **cpos, int *len, + int *eofflag, struct thread *td) +{ + int error, reclen; + struct uio uio; + struct iovec iov; + struct dirent *dp; + + KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp)); + KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp)); + + if (*len == 0) { + iov.iov_base = dirbuf; + iov.iov_len = dirbuflen; + + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = *off; + uio.uio_resid = dirbuflen; + uio.uio_segflg = UIO_SYSSPACE; + uio.uio_rw = UIO_READ; + uio.uio_td = td; + + *eofflag = 0; + +#ifdef MAC + error = mac_vnode_check_readdir(td->td_ucred, vp); + if (error == 0) +#endif + error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag, + NULL, NULL); + if (error) + return (error); + + *off = uio.uio_offset; + + *cpos = dirbuf; + *len = (dirbuflen - uio.uio_resid); + + if (*len == 0) + return (ENOENT); + } + + dp = (struct dirent *)(*cpos); + reclen = dp->d_reclen; + *dpp = dp; + + /* check for malformed directory.. */ + if (reclen < DIRENT_MINSIZE) + return (EINVAL); + + *cpos += reclen; + *len -= reclen; + + return (0); +} + static u_long vn_lock_pair_pause_cnt; SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD, &vn_lock_pair_pause_cnt, 0, diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 37cafdb0d5ae..d5d2776b2f5e 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -1096,6 +1096,9 @@ void vfs_hash_remove(struct vnode *vp); int vfs_kqfilter(struct vop_kqfilter_args *); struct dirent; +int vn_dir_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf, + int dirbuflen, off_t *off, char **cpos, int *len, + int *eofflag, struct thread *td); int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off); int vfs_emptydir(struct vnode *vp);