socsvn commit: r223369 - in soc2011/gk/ino64-head/sys:
compat/freebsd32 kern sys
gk at FreeBSD.org
gk at FreeBSD.org
Fri Jun 17 22:29:34 UTC 2011
Author: gk
Date: Fri Jun 17 22:29:32 2011
New Revision: 223369
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223369
Log:
Change dirent struct to use ino_t and add dir offset field; Add new syscalls
Modified:
soc2011/gk/ino64-head/sys/compat/freebsd32/freebsd32_misc.c
soc2011/gk/ino64-head/sys/compat/freebsd32/syscalls.master
soc2011/gk/ino64-head/sys/kern/syscalls.master
soc2011/gk/ino64-head/sys/kern/vfs_syscalls.c
soc2011/gk/ino64-head/sys/sys/dirent.h
soc2011/gk/ino64-head/sys/sys/syscallsubr.h
Modified: soc2011/gk/ino64-head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- soc2011/gk/ino64-head/sys/compat/freebsd32/freebsd32_misc.c Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/compat/freebsd32/freebsd32_misc.c Fri Jun 17 22:29:32 2011 (r223369)
@@ -1478,6 +1478,42 @@
}
#endif
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) || \
+ defined(COMPAT_FREEBSD8)
+int
+freebsd8_freebsd32_getdirentries(struct thread *td,
+ struct freebsd8_freebsd32_getdirentries_args *uap)
+{
+ long base;
+ int32_t base32;
+ int error;
+
+ error = freebsd8_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, NULL);
+ if (error)
+ return (error);
+ if (uap->basep != NULL) {
+ base32 = base;
+ error = copyout(&base32, uap->basep, sizeof(int32_t));
+ }
+ return (error);
+}
+
+int
+freebsd8_freebsd32_getdents(struct thread *td,
+ struct freebsd8_freebsd32_getdents_args *uap)
+{
+ struct freebsd8_freebsd32_getdirentries_args ap;
+
+ ap.fd = uap->fd;
+ ap.buf = uap->buf;
+ ap.count = uap->count;
+ ap.basep = NULL;
+ return (freebsd8_freebsd32_getdirentries(td, &ap));
+}
+#endif /* COMPAT_FREEBSD8 */
+
int
freebsd32_getdirentries(struct thread *td,
struct freebsd32_getdirentries_args *uap)
Modified: soc2011/gk/ino64-head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- soc2011/gk/ino64-head/sys/compat/freebsd32/syscalls.master Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/compat/freebsd32/syscalls.master Fri Jun 17 22:29:32 2011 (r223369)
@@ -359,7 +359,7 @@
195 AUE_SETRLIMIT NOPROTO { int setrlimit(u_int which, \
struct rlimit *rlp); } setrlimit \
__setrlimit_args int
-196 AUE_GETDIRENTRIES STD { int freebsd32_getdirentries(int fd, \
+196 AUE_GETDIRENTRIES COMPAT8 { int freebsd32_getdirentries(int fd, \
char *buf, u_int count, int32_t *basep); }
197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
@@ -485,7 +485,7 @@
269 AUE_NULL UNIMPL nosys
270 AUE_NULL UNIMPL nosys
271 AUE_NULL UNIMPL nosys
-272 AUE_O_GETDENTS NOPROTO { int getdents(int fd, char *buf, \
+272 AUE_O_GETDENTS COMPAT8 { int freebsd32_getdents(int fd, char *buf, \
size_t count); }
273 AUE_NULL UNIMPL nosys
274 AUE_LCHMOD NOPROTO { int lchmod(char *path, mode_t mode); }
@@ -1002,3 +1002,7 @@
struct stat32 *sb); }
536 AUE_FSTATAT STD { int freebsd32_fstatat(int fd, char *path, \
struct stat32 *buf, int flag); }
+537 AUE_O_GETDENTS NOPROTO { int getdents(int fd, char *buf, \
+ size_t count); }
+538 AUE_GETDIRENTRIES STD { int freebsd32_getdirentries(int fd, \
+ char *buf, u_int count, int32_t *basep); }
Modified: soc2011/gk/ino64-head/sys/kern/syscalls.master
==============================================================================
--- soc2011/gk/ino64-head/sys/kern/syscalls.master Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/kern/syscalls.master Fri Jun 17 22:29:32 2011 (r223369)
@@ -379,7 +379,7 @@
195 AUE_SETRLIMIT STD { int setrlimit(u_int which, \
struct rlimit *rlp); } setrlimit \
__setrlimit_args int
-196 AUE_GETDIRENTRIES STD { int getdirentries(int fd, char *buf, \
+196 AUE_GETDIRENTRIES COMPAT8 { int getdirentries(int fd, char *buf, \
u_int count, long *basep); }
197 AUE_MMAP STD { caddr_t freebsd6_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
@@ -496,7 +496,7 @@
269 AUE_NULL UNIMPL nosys
270 AUE_NULL UNIMPL nosys
271 AUE_NULL UNIMPL nosys
-272 AUE_O_GETDENTS STD { int getdents(int fd, char *buf, \
+272 AUE_O_GETDENTS COMPAT8 { int getdents(int fd, char *buf, \
size_t count); }
273 AUE_NULL UNIMPL nosys
274 AUE_LCHMOD STD { int lchmod(char *path, mode_t mode); }
@@ -958,5 +958,9 @@
struct stat *sb); }
536 AUE_FSTATAT STD { int fstatat(int fd, char *path, \
struct stat *buf, int flag); }
+537 AUE_O_GETDENTS STD { int getdents(int fd, char *buf, \
+ size_t count); }
+538 AUE_GETDIRENTRIES STD { int getdirentries(int fd, char *buf, \
+ u_int count, long *basep); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Modified: soc2011/gk/ino64-head/sys/kern/vfs_syscalls.c
==============================================================================
--- soc2011/gk/ino64-head/sys/kern/vfs_syscalls.c Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/kern/vfs_syscalls.c Fri Jun 17 22:29:32 2011 (r223369)
@@ -4006,7 +4006,85 @@
return (error);
}
+#if defined(COMPAT_43) || defined(COMPAT_FREEBSD4) || \
+ defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD6) || \
+ defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD8)
+int
+freebsd8_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int count,
+ long *basep, void (*func)(struct freebsd8_dirent *))
+{
+ struct freebsd8_dirent dstdp;
+ struct dirent *dp, *edp;
+ char *dirbuf;
+ ssize_t resid, ucount;
+ int error;
+
+ /* XXX arbitrary sanity limit on `count'. */
+ count = min(count, 64 * 1024);
+
+ dirbuf = malloc(count, M_TEMP, M_WAITOK);
+
+ error = kern_getdirentries(td, fd, dirbuf, count, basep, &resid,
+ UIO_SYSSPACE);
+ if (error != 0)
+ goto done;
+
+ ucount = 0;
+ for (dp = (struct dirent *)dirbuf,
+ edp = (struct dirent *)&dirbuf[count - resid];
+ ucount < count && dp < edp; ) {
+ if (dp->d_reclen == 0)
+ break;
+ if (dp->d_namlen > sizeof(dstdp.d_name) - 1)
+ continue;
+ dstdp.d_type = dp->d_type;
+ dstdp.d_namlen = dp->d_namlen;
+ dstdp.d_fileno = dp->d_fileno; /* truncate */
+ dstdp.d_reclen = sizeof(dstdp) - sizeof(dstdp.d_name) +
+ ((dp->d_namlen + 1 + 3) &~ 3);
+ bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen);
+ bzero(dstdp.d_name + dstdp.d_namlen,
+ dstdp.d_reclen - offsetof(struct freebsd8_dirent, d_name) -
+ dstdp.d_namlen);
+ MPASS(dstdp.d_reclen <= dp->d_reclen);
+ MPASS(ucount + dstdp.d_reclen <= count);
+ if (func != NULL)
+ func(&dstdp);
+ error = copyout(&dstdp, ubuf + ucount, dstdp.d_reclen);
+ if (error != 0)
+ break;
+ dp = (struct dirent *)((char *)dp + dp->d_reclen);
+ ucount += dstdp.d_reclen;
+ }
+
+done:
+ free(dirbuf, M_TEMP);
+ if (error == 0)
+ td->td_retval[0] = ucount;
+ return (error);
+}
+#endif /* COMPAT */
+
#ifdef COMPAT_43
+static void
+ogetdirentries_cvt(struct freebsd8_dirent *dp)
+{
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /*
+ * The expected low byte of dp->d_namlen is our dp->d_type.
+ * The high MBZ byte of dp->d_namlen is our dp->d_namlen.
+ */
+ dp->d_type = dp->d_namlen;
+ dp->d_namlen = 0;
+#else
+ /*
+ * The dp->d_type is the high byte of the expected dp->d_namlen,
+ * so must be zero'ed.
+ */
+ dp->d_type = 0;
+#endif
+}
+
/*
* Read a block of directory entries in a filesystem independent format.
*/
@@ -4034,131 +4112,69 @@
kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
long *ploff)
{
- struct vnode *vp;
- struct file *fp;
- struct uio auio, kuio;
- struct iovec aiov, kiov;
- struct dirent *dp, *edp;
- caddr_t dirbuf;
- int error, eofflag, readcnt, vfslocked;
- long loff;
+ long base;
+ int error;
/* XXX arbitrary sanity limit on `count'. */
if (uap->count > 64 * 1024)
return (EINVAL);
- if ((error = getvnode(td->td_proc->p_fd, uap->fd, &fp)) != 0)
- return (error);
- if ((fp->f_flag & FREAD) == 0) {
- fdrop(fp, td);
- return (EBADF);
- }
- vp = fp->f_vnode;
-unionread:
- vfslocked = VFS_LOCK_GIANT(vp->v_mount);
- if (vp->v_type != VDIR) {
- VFS_UNLOCK_GIANT(vfslocked);
- fdrop(fp, td);
- return (EINVAL);
- }
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->count;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_td = td;
- auio.uio_resid = uap->count;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- loff = auio.uio_offset = fp->f_offset;
-#ifdef MAC
- error = mac_vnode_check_readdir(td->td_ucred, vp);
- if (error) {
- VOP_UNLOCK(vp, 0);
- VFS_UNLOCK_GIANT(vfslocked);
- fdrop(fp, td);
- return (error);
- }
-#endif
-# if (BYTE_ORDER != LITTLE_ENDIAN)
- if (vp->v_mount->mnt_maxsymlinklen <= 0) {
- error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
- NULL, NULL);
- fp->f_offset = auio.uio_offset;
- } else
-# endif
- {
- kuio = auio;
- kuio.uio_iov = &kiov;
- kuio.uio_segflg = UIO_SYSSPACE;
- kiov.iov_len = uap->count;
- dirbuf = malloc(uap->count, M_TEMP, M_WAITOK);
- kiov.iov_base = dirbuf;
- error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
- NULL, NULL);
- fp->f_offset = kuio.uio_offset;
- if (error == 0) {
- readcnt = uap->count - kuio.uio_resid;
- edp = (struct dirent *)&dirbuf[readcnt];
- for (dp = (struct dirent *)dirbuf; dp < edp; ) {
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- /*
- * The expected low byte of
- * dp->d_namlen is our dp->d_type.
- * The high MBZ byte of dp->d_namlen
- * is our dp->d_namlen.
- */
- dp->d_type = dp->d_namlen;
- dp->d_namlen = 0;
-# else
- /*
- * The dp->d_type is the high byte
- * of the expected dp->d_namlen,
- * so must be zero'ed.
- */
- dp->d_type = 0;
-# endif
- if (dp->d_reclen > 0) {
- dp = (struct dirent *)
- ((char *)dp + dp->d_reclen);
- } else {
- error = EIO;
- break;
- }
- }
- if (dp >= edp)
- error = uiomove(dirbuf, readcnt, &auio);
- }
- free(dirbuf, M_TEMP);
- }
- if (error) {
- VOP_UNLOCK(vp, 0);
- VFS_UNLOCK_GIANT(vfslocked);
- fdrop(fp, td);
- return (error);
- }
- if (uap->count == auio.uio_resid &&
- (vp->v_vflag & VV_ROOT) &&
- (vp->v_mount->mnt_flag & MNT_UNION)) {
- struct vnode *tvp = vp;
- vp = vp->v_mount->mnt_vnodecovered;
- VREF(vp);
- fp->f_vnode = vp;
- fp->f_data = vp;
- fp->f_offset = 0;
- vput(tvp);
- VFS_UNLOCK_GIANT(vfslocked);
- goto unionread;
- }
- VOP_UNLOCK(vp, 0);
- VFS_UNLOCK_GIANT(vfslocked);
- fdrop(fp, td);
- td->td_retval[0] = uap->count - auio.uio_resid;
- if (error == 0)
- *ploff = loff;
+
+ error = freebsd8_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, ogetdirentries_cvt);
+
+ if (error == 0 && uap->basep != NULL)
+ error = copyout(&base, uap->basep, sizeof(long));
+
return (error);
}
#endif /* COMPAT_43 */
+#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
+ defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) || \
+ defined(COMPAT_FREEBSD8)
+#ifndef _SYS_SYSPROTO_H_
+struct freebsd8_getdirentries_args {
+ int fd;
+ char *buf;
+ u_int count;
+ long *basep;
+};
+#endif
+int
+freebsd8_getdirentries(struct thread *td,
+ struct freebsd8_getdirentries_args *uap)
+{
+ long base;
+ int error;
+
+ error = freebsd8_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, NULL);
+
+ if (error == 0 && uap->basep != NULL)
+ error = copyout(&base, uap->basep, sizeof(long));
+ return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
+struct freebsd8_getdents_args {
+ int fd;
+ char *buf;
+ size_t count;
+};
+#endif
+int
+freebsd8_getdents(struct thread *td, struct freebsd8_getdents_args *uap)
+{
+ struct freebsd8_getdirentries_args ap;
+
+ ap.fd = uap->fd;
+ ap.buf = uap->buf;
+ ap.count = uap->count;
+ ap.basep = NULL;
+ return (freebsd8_getdirentries(td, &ap));
+}
+#endif /* COMPAT_FREEBSD8 */
+
/*
* Read a block of directory entries in a filesystem independent format.
*/
Modified: soc2011/gk/ino64-head/sys/sys/dirent.h
==============================================================================
--- soc2011/gk/ino64-head/sys/sys/dirent.h Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/sys/dirent.h Fri Jun 17 22:29:32 2011 (r223369)
@@ -36,6 +36,16 @@
#include <sys/cdefs.h>
#include <sys/_types.h>
+#ifndef _INO_T_DECLARED
+typedef __ino_t ino_t;
+#define _INO_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
/*
* The dirent structure defines the format of directory entries returned by
* the getdirentries(2) system call.
@@ -48,10 +58,13 @@
*/
struct dirent {
- __uint32_t d_fileno; /* file number of entry */
+ ino_t d_fileno; /* file number of entry */
+ off_t d_off__unused; /* directory offset of entry */
__uint16_t d_reclen; /* length of this record */
+ __uint16_t d_namlen; /* length of string in d_name */
__uint8_t d_type; /* file type, see below */
- __uint8_t d_namlen; /* length of string in d_name */
+ __uint8_t d_unused1;
+ __uint16_t d_unused2;
#if __BSD_VISIBLE
#define MAXNAMLEN 255
char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
@@ -61,6 +74,14 @@
};
#if __BSD_VISIBLE
+struct freebsd8_dirent {
+ __uint32_t d_fileno; /* file number of entry */
+ __uint16_t d_reclen; /* length of this record */
+ __uint8_t d_type; /* file type, see below */
+ __uint8_t d_namlen; /* length of string in d_name */
+ char d_name[255 + 1]; /* name must be no longer than this */
+};
+
/*
* File types
*/
Modified: soc2011/gk/ino64-head/sys/sys/syscallsubr.h
==============================================================================
--- soc2011/gk/ino64-head/sys/sys/syscallsubr.h Fri Jun 17 22:29:18 2011 (r223368)
+++ soc2011/gk/ino64-head/sys/sys/syscallsubr.h Fri Jun 17 22:29:32 2011 (r223369)
@@ -238,4 +238,9 @@
#define KSA_OSIGSET 0x0001 /* uses osigact_t */
#define KSA_FREEBSD4 0x0002 /* uses ucontext4 */
+struct freebsd8_dirent;
+
+int freebsd8_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int
+ count, long *basep, void (*func)(struct freebsd8_dirent *));
+
#endif /* !_SYS_SYSCALLSUBR_H_ */
More information about the svn-soc-all
mailing list