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_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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user