summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgleb <gleb@FreeBSD.org>2012-05-24 08:00:26 +0000
committergleb <gleb@FreeBSD.org>2012-05-24 08:00:26 +0000
commit3c7243df78747d294e451596c19e50e9397cf115 (patch)
treeafad455e2157c851f1824ca662f574359ffb64a8 /sys
parent5755c92002b1bfcd30e0b240b42bc8a28df9c96e (diff)
downloadFreeBSD-src-3c7243df78747d294e451596c19e50e9397cf115.zip
FreeBSD-src-3c7243df78747d294e451596c19e50e9397cf115.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c3
-rw-r--r--sys/kern/vfs_syscalls.c34
-rw-r--r--sys/sys/syscallsubr.h3
3 files changed, 27 insertions, 13 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 81568ae..ce8bd7a 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1528,7 +1528,8 @@ freebsd32_getdirentries(struct thread *td,
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) {
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 0400504..79206a0 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -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);
}
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 08dba2f..4335550 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -89,6 +89,7 @@ int kern_fchmodat(struct thread *td, int fd, char *path,
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, int fd, off_t length);
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);
OpenPOWER on IntegriCloud