Date: Thu, 24 May 2012 08:00:26 +0000 (UTC) From: Gleb Kurtsou <gleb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r235886 - in head/sys: compat/freebsd32 kern sys Message-ID: <201205240800.q4O80QQk023994@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gleb Date: Thu May 24 08:00:26 2012 New Revision: 235886 URL: http://svn.freebsd.org/changeset/base/235886 Log: Add kern_fhstat(), adjust sys_fhstat() to use it. Extend kern_getdirentries() to accept uio segflag and optionally return buffer residue. Sponsored by: Google Summer of Code 2011 Modified: head/sys/compat/freebsd32/freebsd32_misc.c head/sys/kern/vfs_syscalls.c head/sys/sys/syscallsubr.h Modified: head/sys/compat/freebsd32/freebsd32_misc.c ============================================================================== --- head/sys/compat/freebsd32/freebsd32_misc.c Thu May 24 05:30:17 2012 (r235885) +++ head/sys/compat/freebsd32/freebsd32_misc.c Thu May 24 08:00:26 2012 (r235886) @@ -1528,7 +1528,8 @@ freebsd32_getdirentries(struct thread *t int32_t base32; int error; - error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); + error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, + NULL, UIO_USERSPACE); if (error) return (error); if (uap->basep != NULL) { Modified: head/sys/kern/vfs_syscalls.c ============================================================================== --- head/sys/kern/vfs_syscalls.c Thu May 24 05:30:17 2012 (r235885) +++ head/sys/kern/vfs_syscalls.c Thu May 24 08:00:26 2012 (r235886) @@ -4136,7 +4136,8 @@ sys_getdirentries(td, uap) long base; int error; - error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base); + error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base, + NULL, UIO_USERSPACE); if (error) return (error); if (uap->basep != NULL) @@ -4146,7 +4147,7 @@ sys_getdirentries(td, uap) int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, - long *basep) + long *basep, ssize_t *residp, enum uio_seg bufseg) { struct vnode *vp; struct file *fp; @@ -4180,7 +4181,7 @@ unionread: auio.uio_iov = &aiov; auio.uio_iovcnt = 1; auio.uio_rw = UIO_READ; - auio.uio_segflg = UIO_USERSPACE; + auio.uio_segflg = bufseg; auio.uio_td = td; vn_lock(vp, LK_SHARED | LK_RETRY); AUDIT_ARG_VNODE1(vp); @@ -4213,6 +4214,8 @@ unionread: VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); *basep = loff; + if (residp != NULL) + *residp = auio.uio_resid; td->td_retval[0] = count - auio.uio_resid; fail: fdrop(fp, td); @@ -4679,7 +4682,22 @@ sys_fhstat(td, uap) } */ *uap; { struct stat sb; - fhandle_t fh; + struct fhandle fh; + int error; + + error = copyin(uap->u_fhp, &fh, sizeof(fh)); + if (error != 0) + return (error); + error = kern_fhstat(td, fh, &sb); + if (error != 0) + return (error); + error = copyout(&sb, uap->sb, sizeof(sb)); + return (error); +} + +int +kern_fhstat(struct thread *td, struct fhandle fh, struct stat *sb) +{ struct mount *mp; struct vnode *vp; int vfslocked; @@ -4688,9 +4706,6 @@ sys_fhstat(td, uap) error = priv_check(td, PRIV_VFS_FHSTAT); if (error) return (error); - error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t)); - if (error) - return (error); if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) return (ESTALE); vfslocked = VFS_LOCK_GIANT(mp); @@ -4700,12 +4715,9 @@ sys_fhstat(td, uap) VFS_UNLOCK_GIANT(vfslocked); return (error); } - error = vn_stat(vp, &sb, td->td_ucred, NOCRED, td); + error = vn_stat(vp, sb, td->td_ucred, NOCRED, td); vput(vp); VFS_UNLOCK_GIANT(vfslocked); - if (error) - return (error); - error = copyout(&sb, uap->sb, sizeof(sb)); return (error); } Modified: head/sys/sys/syscallsubr.h ============================================================================== --- head/sys/sys/syscallsubr.h Thu May 24 05:30:17 2012 (r235885) +++ head/sys/sys/syscallsubr.h Thu May 24 08:00:26 2012 (r235886) @@ -89,6 +89,7 @@ int kern_fchmodat(struct thread *td, int int kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int uid, int gid, int flag); int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg); +int kern_fhstat(struct thread *td, fhandle_t fh, struct stat *buf); int kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf); int kern_fstat(struct thread *td, int fd, struct stat *sbp); int kern_fstatfs(struct thread *td, int fd, struct statfs *buf); @@ -96,7 +97,7 @@ int kern_ftruncate(struct thread *td, in int kern_futimes(struct thread *td, int fd, struct timeval *tptr, enum uio_seg tptrseg); int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count, - long *basep); + long *basep, ssize_t *residp, enum uio_seg bufseg); int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, enum uio_seg bufseg, int flags); int kern_getgroups(struct thread *td, u_int *ngrp, gid_t *groups);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205240800.q4O80QQk023994>