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
This commit is contained in:
parent
7f6a000fce
commit
6bce3f23d0
@ -75,15 +75,9 @@ __FBSDID("$FreeBSD$");
|
|||||||
static int vop_nolookup(struct vop_lookup_args *);
|
static int vop_nolookup(struct vop_lookup_args *);
|
||||||
static int vop_norename(struct vop_rename_args *);
|
static int vop_norename(struct vop_rename_args *);
|
||||||
static int vop_nostrategy(struct vop_strategy_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,
|
static int dirent_exists(struct vnode *vp, const char *dirname,
|
||||||
struct thread *td);
|
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_stdis_text(struct vop_is_text_args *ap);
|
||||||
static int vop_stdunset_text(struct vop_unset_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);
|
static int vop_stdadd_writecount(struct vop_add_writecount_args *ap);
|
||||||
@ -281,65 +275,6 @@ vop_nostrategy (struct vop_strategy_args *ap)
|
|||||||
return (EOPNOTSUPP);
|
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.
|
* 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;
|
off = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
do {
|
do {
|
||||||
error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off,
|
error = vn_dir_next_dirent(vp, &dp, dirbuf, dirbuflen, &off,
|
||||||
&cpos, &len, &eofflag, td);
|
&cpos, &len, &eofflag, td);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -808,8 +743,8 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap)
|
|||||||
len = 0;
|
len = 0;
|
||||||
do {
|
do {
|
||||||
/* call VOP_READDIR of parent */
|
/* call VOP_READDIR of parent */
|
||||||
error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off,
|
error = vn_dir_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off,
|
||||||
&cpos, &len, &eofflag, td);
|
&cpos, &len, &eofflag, td);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/namei.h>
|
#include <sys/namei.h>
|
||||||
#include <sys/vnode.h>
|
#include <sys/vnode.h>
|
||||||
|
#include <sys/dirent.h>
|
||||||
#include <sys/bio.h>
|
#include <sys/bio.h>
|
||||||
#include <sys/buf.h>
|
#include <sys/buf.h>
|
||||||
#include <sys/filio.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);
|
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;
|
static u_long vn_lock_pair_pause_cnt;
|
||||||
SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD,
|
SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD,
|
||||||
&vn_lock_pair_pause_cnt, 0,
|
&vn_lock_pair_pause_cnt, 0,
|
||||||
|
@ -1099,6 +1099,9 @@ void vfs_hash_remove(struct vnode *vp);
|
|||||||
|
|
||||||
int vfs_kqfilter(struct vop_kqfilter_args *);
|
int vfs_kqfilter(struct vop_kqfilter_args *);
|
||||||
struct dirent;
|
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_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
|
||||||
int vfs_emptydir(struct vnode *vp);
|
int vfs_emptydir(struct vnode *vp);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user