git: 6bce3f23d0aa - main - vfs: Export get_next_dirent() as vn_dir_next_dirent()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 28 Apr 2023 01:29:54 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=6bce3f23d0aa045d61c0ec8d27100eb186a33375
commit 6bce3f23d0aa045d61c0ec8d27100eb186a33375
Author: Olivier Certner <olce.freebsd@certner.fr>
AuthorDate: 2023-04-23 07:47:58 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-04-28 01:27:54 +0000
vfs: Export get_next_dirent() as vn_dir_next_dirent()
Move internal-to-'vfs_default.c' get_next_dirent() to 'vfs_vnops.c' and
export it for use by other parts of the VFS. This is a preparatory
change for using it in vfs_emptydir().
No functional change.
Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D39755
---
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 ee1310215621..7da4f7b62cff 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);
@@ -281,65 +275,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.
*/
@@ -369,8 +304,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;
@@ -808,8 +743,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 581d620e348e..ad9b0c8864b0 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>
@@ -3736,6 +3737,67 @@ vn_fspacectl(struct file *fp, int cmd, off_t *offset, off_t *length, int flags,
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 fa889826867e..282f75bcdd71 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1099,6 +1099,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);