endif
if WITH_LUSTRE_HACK
-OPTIONAL_LUSTRE_SRCDIR_SRCS = $(LUSTRE_SRCDIR_SRCS)
# it would be better that let configure script check this
-AM_CFLAGS = -fPIC
-else
-OPTIONAL_LUSTRE_SRCDIR_SRCS =
+OPTIONAL_LUSTRE_CFLAGS = -fPIC
endif
+AM_CFLAGS = $(OPTIONAL_LUSTRE_CFLAGS)
+
__LIBBUILD_DIR__libsysio_a_SOURCES = \
$(SRCDIR_SRCS) \
- $(OPTIONAL_LUSTRE_SRCDIR_SRCS) \
$(OPTIONAL_STDFD_SRCS) \
$(OPTIONAL_INCORE_SRCS) \
$(OPTIONAL_SOCKETS_SRCS) \
DEV_CPPFLAGS = $(STDFD_DEV_CPPFLAGS)
AM_CPPFLAGS = \
+ -D_POSIX_C_SOURCE=199506L -D_XOPEN_SOURCE=600 \
$(AUTOMOUNT) $(ZERO_SUM_MEMORY) $(DEV_CPPFLAGS) $(SOCKETS_CPPFLAGS) \
-I$(top_srcdir)/include
#include <errno.h>
#include <sys/syscall.h>
#include <unistd.h>
-#include <sys/uio.h>
#include <sys/types.h>
#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "inode.h"
#include "dev.h"
#endif
#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "fs.h"
#include "mount.h"
static _SYSIO_OFF_T _sysio_incore_filop_pos(struct inode *ino,
_SYSIO_OFF_T off);
static int _sysio_incore_filop_iodone(struct ioctx *ioctx);
-static int _sysio_incore_filop_fcntl(struct inode *ino, int cmd, va_list ap);
+static int _sysio_incore_filop_fcntl(struct inode *ino,
+ int cmd, va_list ap, int *rtn);
static int _sysio_incore_inop_sync(struct inode *ino);
static int _sysio_incore_filop_ioctl(struct inode *ino,
unsigned long int request,
#define _sysio_incore_dirop_iodone \
(int (*)(struct ioctx *))_sysio_do_illop
#define _sysio_incore_dirop_fcntl \
- (int (*)(struct inode *, int, va_list))_sysio_do_eisdir
+ (int (*)(struct inode *, int, va_list, int *))_sysio_do_eisdir
#define _sysio_incore_dirop_ioctl \
(int (*)(struct inode *, \
unsigned long int, \
static int
_sysio_incore_filop_fcntl(struct inode *ino __IS_UNUSED,
int cmd __IS_UNUSED,
- va_list ap __IS_UNUSED)
+ va_list ap __IS_UNUSED,
+ int *rtn)
{
/*
* No fcntl's supported.
*/
+ *rtn = -1;
return -ENOTTY;
}
#include <string.h>
#endif
#include <unistd.h>
+#if !(defined(REDSTORM) || defined(MAX_IOVEC))
+#include <limits.h>
+#endif
#include <errno.h>
#include <assert.h>
#include <syscall.h>
#include <sys/statfs.h>
#endif
#include <utime.h>
+#include <sys/uio.h>
#include <sys/queue.h>
-#if !(defined(REDSTORM) || defined(MAX_IOVEC))
-#include <limits.h>
-#endif
+#include "xtio.h"
#include "sysio.h"
#include "fs.h"
#include "mount.h"
#include "inode.h"
-#include "xtio.h"
#include "fs_native.h"
int ni_oflags; /* flags, from open */
unsigned ni_nopens; /* soft ref count */
_SYSIO_OFF_T ni_fpos; /* current pos */
+ struct intnl_stat ni_stat; /* cached attrs */
};
/*
static int native_inop_write(struct inode *ino, struct ioctx *ioctx);
static _SYSIO_OFF_T native_inop_pos(struct inode *ino, _SYSIO_OFF_T off);
static int native_inop_iodone(struct ioctx *ioctx);
-static int native_inop_fcntl(struct inode *ino, int cmd, va_list ap);
+static int native_inop_fcntl(struct inode *ino, int cmd, va_list ap, int *rtn);
static int native_inop_sync(struct inode *ino);
static int native_inop_datasync(struct inode *ino);
static int native_inop_ioctl(struct inode *ino,
* stat -- by path.
*/
static int
-native_stat(const char *path, struct intnl_stat *buf)
+native_stat(const char *path, struct native_inode *nino, struct intnl_stat *buf)
{
int err;
struct __native_stat stbuf;
err = syscall(__SYS_STAT, path, &stbuf);
- if (err)
+ if (err) {
err = -errno;
- COPY_STAT(&stbuf, buf);
+ goto out;
+ }
+ if (!nino) {
+ COPY_STAT(&stbuf, buf);
+ goto out;
+ }
+ COPY_STAT(&stbuf, &nino->ni_stat);
+ if (&nino->ni_stat != buf)
+ (void )memcpy(buf, &nino->ni_stat, sizeof(struct intnl_stat));
+out:
return err;
}
* stat -- by fildes
*/
static int
-native_fstat(int fd, struct intnl_stat *buf)
+native_fstat(int fd, struct native_inode *nino, struct intnl_stat *buf)
{
int err;
struct __native_stat stbuf;
err = syscall(__SYS_FSTAT, fd, &stbuf);
- if (err)
+ if (err) {
err = -errno;
- COPY_STAT(&stbuf, buf);
+ goto out;
+ }
+ if (!nino) {
+ COPY_STAT(&stbuf, buf);
+ goto out;
+ }
+ COPY_STAT(&stbuf, &nino->ni_stat);
+ if (&nino->ni_stat != buf)
+ (void )memcpy(buf, &nino->ni_stat, sizeof(struct intnl_stat));
+out:
return err;
}
nino->ni_oflags = 0;
nino->ni_nopens = 0;
nino->ni_fpos = 0;
+ (void )memcpy(&nino->ni_stat, buf, sizeof(struct intnl_stat));
ino =
_sysio_i_new(fs,
&nino->ni_fileid,
#else
buf->st_mode, /* all of the bits! */
#endif
- 0,
+ buf->st_rdev,
0,
&native_i_ops,
nino);
/*
* Get root i-node.
*/
- err = native_stat("/", &stbuf);
+ err = native_stat("/", NULL, &stbuf);
if (err)
goto error;
rootino = native_i_new(fs, &stbuf);
/*
* Get file status.
*/
- err = native_stat(path, &stbuf);
+ err = native_stat(path, *inop ? I2NI(*inop) : NULL, &stbuf);
if (err) {
*inop = NULL;
return err;
fileid.fid_data = &ident;
fileid.fid_len = sizeof(ident);
ino = _sysio_i_find(fs, &fileid);
- if (ino && forced) {
+ if (ino &&
+ (forced || (ino->i_mode & S_IFMT) != (stbuf.st_mode & S_IFMT))) {
/*
- * Insertion was forced but it's already present!
+ * Insertion was forced or dup inum but it's already present!
*/
if (native_i_invalid(ino, stbuf)) {
/*
}
static int
-native_inop_getattr(struct pnode *pno, struct inode *ino, struct intnl_stat *stbuf)
+native_inop_getattr(struct pnode *pno,
+ struct inode *ino,
+ struct intnl_stat *stbuf)
{
char *path;
+ struct native_inode *nino;
int err;
- path = NULL;
- if (!ino || I2NI(ino)->ni_fd < 0) {
+ nino = ino ? I2NI(ino) : NULL;
+ err = 0; /* compiler cookie */
+ if (!ino) {
path = _sysio_pb_path(pno->p_base, '/');
if (!path)
return -ENOMEM;
- }
- err =
- path
- ? native_stat(path, stbuf)
- : native_fstat(I2NI(ino)->ni_fd, stbuf);
- if (path)
+ err = native_stat(path, nino, stbuf);
free(path);
+ } else if (nino->ni_fd >= 0)
+ err = native_fstat(nino->ni_fd, nino, stbuf);
+ else {
+ /*
+ * Dev inodes don't open in this driver. We won't have
+ * a file descriptor with which to do the deed then. Satisfy
+ * the request from the cached copy of the attributes.
+ */
+ (void )memcpy(stbuf,
+ &nino->ni_stat,
+ sizeof(struct intnl_stat));
+ err = 0;
+ }
+
return err;
}
struct intnl_stat *stbuf)
{
char *path;
+ struct native_inode *nino;
int fd;
- struct intnl_stat st;
+ struct intnl_stat *stbp, _stbuf;
int err;
path = NULL;
- fd = ino ? I2NI(ino)->ni_fd : -1;
+ nino = ino ? I2NI(ino) : NULL;
+ fd = -1;
+ stbp = &_stbuf;
+ if (nino) {
+ fd = nino->ni_fd;
+ stbp = &nino->ni_stat;
+ }
if (fd < 0 || mask & (SETATTR_MTIME|SETATTR_ATIME)) {
if (!pno)
return -EEXIST;
*/
err =
fd < 0
- ? native_stat(path, &st)
- : native_fstat(fd, &st);
+ ? native_stat(path, nino, stbp)
+ : native_fstat(fd, nino, stbp);
if (err)
goto out;
/*
* Alter access and/or modify time attributes.
*/
- ut.actime = st.st_atime;
- ut.modtime = st.st_mtime;
+ ut.actime = stbuf->st_atime;
+ ut.modtime = stbuf->st_mtime;
if (mask & SETATTR_MTIME)
ut.modtime = stbuf->st_mtime;
if (mask & SETATTR_ATIME)
? syscall(SYS_chown,
path,
mask & SETATTR_UID
- ? st.st_uid
+ ? stbp->st_uid
: (uid_t )-1,
mask & SETATTR_GID
- ? st.st_gid
+ ? stbp->st_gid
: (gid_t )-1)
: syscall(SYS_fchown,
fd,
mask & SETATTR_UID
- ? st.st_uid
+ ? stbp->st_uid
: (uid_t )-1,
mask & SETATTR_GID
- ? st.st_gid
+ ? stbp->st_gid
: (gid_t )-1));
}
if (mask & (SETATTR_MTIME|SETATTR_ATIME)) {
struct utimbuf ut;
- ut.actime = st.st_atime;
- ut.modtime = st.st_mtime;
+ ut.actime = stbp->st_atime;
+ ut.modtime = stbp->st_mtime;
(void )syscall(__SYS_UTIME, path, &ut);
}
if (mask & SETATTR_MODE) {
fd < 0
- ? syscall(SYS_chmod, path, st.st_mode & 07777)
- : syscall(SYS_fchmod, fd, st.st_mode & 07777);
+ ? syscall(SYS_chmod, path, stbp->st_mode & 07777)
+ : syscall(SYS_fchmod, stbp->st_mode & 07777);
}
out:
+ /*
+ * We must refresh the cached attributes on success.
+ */
+ if (!err && (fd < 0
+ ? native_stat(path, nino, stbp)
+ : native_fstat(fd, nino, stbp)) != 0)
+ abort();
if (path)
free(path);
return err;
static int
native_inop_fcntl(struct inode *ino,
int cmd,
- va_list ap)
+ va_list ap,
+ int *rtn)
{
struct native_inode *nino = I2NI(ino);
long arg;
if (nino->ni_fd < 0)
abort();
+ err = 0;
switch (cmd) {
case F_GETFD:
case F_GETFL:
+#ifdef F_GETOWN
case F_GETOWN:
- err = syscall(SYS_fcntl, nino->ni_fd, cmd);
- if (err < 0)
+#endif
+ *rtn = syscall(SYS_fcntl, nino->ni_fd, cmd);
+ if (*rtn == -1)
err = -errno;
+ break;
case F_DUPFD:
case F_SETFD:
case F_SETFL:
case F_GETLK:
case F_SETLK:
case F_SETLKW:
+#ifdef F_SETOWN
case F_SETOWN:
+#endif
arg = va_arg(ap, long);
- err = syscall(SYS_fcntl, nino->ni_fd, cmd, arg);
- if (err)
+ *rtn = syscall(SYS_fcntl, nino->ni_fd, cmd, arg);
+ if (*rtn == -1)
err = -errno;
+ break;
default:
+ *rtn = -1;
err = -EINVAL;
}
return err;
return err;
}
+#ifdef HAVE_LUSTRE_HACK
+static int
+native_inop_ioctl(struct inode *ino,
+ unsigned long int request,
+ va_list ap)
+{
+ long arg1, arg2, arg3, arg4;
+
+ assert(I2NI(ino)->ni_fd >= 0);
+
+ arg1 = va_arg(ap, long);
+ arg2 = va_arg(ap, long);
+ arg3 = va_arg(ap, long);
+ arg4 = va_arg(ap, long);
+
+ return syscall(SYS_ioctl, I2NI(ino)->ni_fd, request,
+ arg1, arg2, arg3, arg4);
+}
+#else
static int
native_inop_ioctl(struct inode *ino __IS_UNUSED,
unsigned long int request __IS_UNUSED,
errno = ENOTTY;
return -1;
}
+#endif
static void
native_inop_gone(struct inode *ino)
if (nino->ni_fd >= 0)
(void )syscall(SYS_close, nino->ni_fd);
+
free(ino->i_private);
}
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
-#include <sys/queue.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <linux/net.h>
+#include <sys/uio.h>
+#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "fs.h"
#include "inode.h"
static int sockets_inop_iodone(struct ioctx *ioctx);
static int sockets_inop_sync(struct inode *ino);
static int sockets_inop_datasync(struct inode *ino);
-static int sockets_inop_fcntl(struct inode *ino, int cmd, va_list ap);
+static int sockets_inop_fcntl(struct inode *ino, int cmd, va_list ap, int *rtn);
static int sockets_inop_ioctl(struct inode *ino,
unsigned long int request,
va_list ap);
}
static _SYSIO_OFF_T
-sockets_inop_pos(struct inode *ino, _SYSIO_OFF_T off)
+sockets_inop_pos(struct inode *ino __IS_UNUSED, _SYSIO_OFF_T off __IS_UNUSED)
{
return -EINVAL;
}
static int
sockets_inop_fcntl(struct inode *ino __IS_UNUSED,
int cmd __IS_UNUSED,
- va_list ap __IS_UNUSED)
+ va_list ap __IS_UNUSED,
+ int *rtn)
{
long arg;
case F_GETFD:
case F_GETFL:
case F_GETOWN:
- return syscall(SYS_fcntl, I2SKI(ino)->ski_fd, cmd);
+ *rtn = syscall(SYS_fcntl, I2SKI(ino)->ski_fd, cmd);
+ break;
case F_DUPFD:
case F_SETFD:
case F_SETFL:
case F_SETLKW:
case F_SETOWN:
arg = va_arg(ap, long);
- return syscall(SYS_fcntl, I2SKI(ino)->ski_fd, cmd, arg);
+ *rtn = syscall(SYS_fcntl, I2SKI(ino)->ski_fd, cmd, arg);
+ break;
default:
- printf("uncatched cmd %d\n", cmd);
- abort();
+ *rtn = -1;
+ errno = EINVAL;
}
- return -1;
+ return *rtn == -1 ? -errno : 0;
}
static int
return syscall(SYS_fdatasync, I2SKI(ino)->ski_fd);
}
+#ifdef HAVE_LUSTRE_HACK
+/*
+ * we blindly extract 4 params and pass to host kernel, the stack
+ * should be ok. hope no ioctl will consume more then 4 params...
+ */
+static int
+sockets_inop_ioctl(struct inode *ino,
+ unsigned long int request,
+ va_list ap)
+{
+ long arg1, arg2, arg3, arg4;
+
+ assert(I2SKI(ino)->ski_fd >= 0);
+
+ arg1 = va_arg(ap, long);
+ arg2 = va_arg(ap, long);
+ arg3 = va_arg(ap, long);
+ arg4 = va_arg(ap, long);
+
+ return syscall(SYS_ioctl, I2SKI(ino)->ski_fd, request,
+ arg1, arg2, arg3, arg4);
+}
+#else
static int
sockets_inop_ioctl(struct inode *ino __IS_UNUSED,
unsigned long int request __IS_UNUSED,
*/
return -ENOTTY;
}
+#endif
static void
sockets_inop_gone(struct inode *ino)
goto error;
}
- err = _sysio_fd_set(fil, ski->ski_fd);
+#ifdef HAVE_LUSTRE_HACK
+ err = _sysio_fd_set(fil, ski->ski_fd, 1);
+#else
+ err = _sysio_fd_set(fil, -1, 0);
+#endif
if (err < 0)
goto error;
goto error;
}
- err = _sysio_fd_set(nfil, ski->ski_fd);
+#ifdef HAVE_LUSTRE_HACK
+ err = _sysio_fd_set(nfil, ski->ski_fd, 1);
+#else
+ err = _sysio_fd_set(nfil, -1, 0);
+#endif
if (err < 0)
goto error;
#endif
#include <utime.h>
#include <sys/queue.h>
-#include <sys/uio.h>
+#include "xtio.h"
#include "sysio.h"
#include "fs.h"
#include "mount.h"
static int yod_inop_read(struct inode *ino, struct ioctx *ioctx);
static int yod_inop_write(struct inode *ino, struct ioctx *ioctx);
static int yod_inop_iodone(struct ioctx *ioctx);
-static int yod_inop_fcntl(struct inode *ino, int cmd, va_list ap);
+static int yod_inop_fcntl(struct inode *ino, int cmd, va_list ap, int *rtn);
static int yod_inop_sync(struct inode *ino);
static int yod_inop_datasync(struct inode *ino);
static int yod_inop_ioctl(struct inode *ino,
}
static int
-yod_inop_fcntl(struct inode *ino __IS_UNUSED, int cmd, va_list ap __IS_UNUSED)
+yod_inop_fcntl(struct inode *ino, int cmd, va_list ap, int *rtn)
{
- switch (cmd)
- {
- case F_DUPFD: /* do something to the ino */
+ struct yod_inode *nino = I2NI(ino);
+ long arg;
+ int err;
+
+ if (nino->ni_fd < 0)
+ abort();
+
+ err = 0;
+ switch (cmd) {
+ case F_GETFD:
+ case F_GETFL:
+#ifdef F_GETOWN
+ case F_GETOWN:
+#endif
+ *rtn = syscall(SYS_fcntl, nino->ni_fd, cmd);
+ if (*rtn == -1)
+ err = -errno;
+ break;
+ case F_DUPFD:
+ case F_SETFD:
+ case F_SETFL:
+ case F_GETLK:
+ case F_SETLK:
+ case F_SETLKW:
+#ifdef F_SETOWN
+ case F_SETOWN:
+#endif
+ arg = va_arg(ap, long);
+ *rtn = syscall(SYS_fcntl, nino->ni_fd, cmd, arg);
+ if (*rtn == -1)
+ err = -errno;
break;
default:
- errno = EINVAL;
- return -1;
+ *rtn = -1;
+ err = -EINVAL;
}
- return 0;
-
+ return err;
}
static int
#define _sysio_nodev_inop_open \
(int (*)(struct pnode *, \
int, \
- mode_t))_sysio_do_enoent
+ mode_t))_sysio_do_enodev
#define _sysio_nodev_inop_close \
(int (*)(struct inode *))_sysio_do_ebadf
#define _sysio_nodev_inop_link \
#define _sysio_nodev_inop_fcntl \
(int (*)(struct inode *, \
int, \
- va_list))_sysio_do_ebadf
+ va_list, \
+ int *))_sysio_do_ebadf
#define _sysio_nodev_inop_sync \
(int (*)(struct inode *))_sysio_do_ebadf
#define _sysio_nodev_inop_datasync \
extern void _sysio_fcompletio(struct ioctx *ioctx, struct file *fil);
extern int _sysio_fd_close(int fd);
extern struct file *_sysio_fd_find(int fd);
-extern int _sysio_fd_set(struct file *fil, int fd);
-extern int _sysio_fd_dup2(int oldfd, int newfd);
+extern int _sysio_fd_set(struct file *fil, int fd, int force);
+extern int _sysio_fd_dup(int oldfd, int newfd, int force);
extern int _sysio_fd_close_all(void);
#if ZERO_SUM_MEMORY
extern void _sysio_fd_shutdown(void);
int (*inop_write)(struct inode *ino, struct ioctx *ioctx);
_SYSIO_OFF_T (*inop_pos)(struct inode *ino, _SYSIO_OFF_T off);
int (*inop_iodone)(struct ioctx *iocp);
- int (*inop_fcntl)(struct inode *ino, int cmd, va_list ap);
+ int (*inop_fcntl)(struct inode *ino, int cmd, va_list ap, int *rtn);
int (*inop_sync)(struct inode *ino);
int (*inop_datasync)(struct inode *ino);
int (*inop_ioctl)(struct inode *ino, unsigned long int request, va_list ap);
ioctx_fast : 1, /* from stack space */
ioctx_done : 1, /* transfer complete */
ioctx_write : 1; /* op is a write */
- ioid_t ioctx_id; /* unique ident */
struct inode *ioctx_ino; /* i-node */
const struct iovec *ioctx_iov; /* scatter/gather vec */
size_t ioctx_iovlen; /* iovec length */
/*
* Init IO context record.
*/
-#define IOCTX_INIT(ioctx, fast, id, wr, ino, iov, iovlen, xtv, xtvlen) \
+#define IOCTX_INIT(ioctx, fast, wr, ino, iov, iovlen, xtv, xtvlen) \
do { \
(ioctx)->ioctx_fast = (fast); \
(ioctx)->ioctx_done = 0; \
(ioctx)->ioctx_write = (wr) ? 1 : 0; \
- (ioctx)->ioctx_id = (id); \
(ioctx)->ioctx_ino = (ino); \
(ioctx)->ioctx_iov = (iov); \
(ioctx)->ioctx_iovlen = (iovlen); \
extern int _sysio_do_ebadf(void);
extern int _sysio_do_einval(void);
extern int _sysio_do_enoent(void);
+extern int _sysio_do_enodev(void);
extern int _sysio_do_espipe(void);
extern int _sysio_do_eisdir(void);
extern int _sysio_do_enosys(void);
void (*f)(struct ioctx *, void *),
void *data);
extern void _sysio_ioctx_cb_free(struct ioctx_callback *cb);
-extern struct ioctx *_sysio_ioctx_find(ioid_t id);
+extern struct ioctx *_sysio_ioctx_find(void *id);
extern ssize_t _sysio_ioctx_wait(struct ioctx *ioctx);
extern void _sysio_ioctx_complete(struct ioctx *ioctx);
extern ssize_t _sysio_validx(const struct intnl_xtvec *xtv, size_t xtvlen,
#include <limits.h>
#include <stdarg.h>
-#ifndef _IOID_T_DEFINED
-#define _IOID_T_DEFINED
-/*
- * FIXME:
- *
- * This section about ioid_t and it's failure belong in <sys/types.h>
- */
-typedef void *ioid_t;
-
-#define IOID_FAIL 0
-#endif
-
#if !defined(__IS_UNUSED) && defined(__GNUC__)
#define __IS_UNUSED __attribute__ ((unused))
#else
extern int SYSIO_INTERFACE_NAME(fdatasync)(int fd);
extern int SYSIO_INTERFACE_NAME(ioctl)(int fd, unsigned long request, ...);
extern mode_t SYSIO_INTERFACE_NAME(umask)(mode_t mask);
-extern int SYSIO_INTERFACE_NAME(iodone)(ioid_t ioid);
-extern ssize_t SYSIO_INTERFACE_NAME(iowait)(ioid_t ioid);
-extern ioid_t SYSIO_INTERFACE_NAME(ipreadv)(int fd, const struct iovec *iov,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ioid_t SYSIO_INTERFACE_NAME(ipread64v)(int fd, const struct iovec *iov,
- size_t count, off64_t offset);
-#endif
-extern ioid_t SYSIO_INTERFACE_NAME(ipread)(int fd, void *buf, size_t count,
- off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ioid_t SYSIO_INTERFACE_NAME(ipread64)(int fd, void *buf, size_t count,
- off64_t offset);
-#endif
-extern ssize_t SYSIO_INTERFACE_NAME(preadv)(int fd, const struct iovec *iov,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ssize_t SYSIO_INTERFACE_NAME(pread64v)(int fd, const struct iovec *iov,
- size_t count, off64_t offset);
-#endif
-extern ssize_t SYSIO_INTERFACE_NAME(pread)(int fd, void *buf, size_t count,
- off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ssize_t SYSIO_INTERFACE_NAME(pread64)(int fd, void *buf, size_t count,
- off64_t offset);
-#endif
-extern ioid_t SYSIO_INTERFACE_NAME(ireadv)(int fd, const struct iovec *iov,
- int count);
-extern ioid_t SYSIO_INTERFACE_NAME(iread)(int fd, void *buf, size_t count);
-extern ssize_t SYSIO_INTERFACE_NAME(readv)(int fd, const struct iovec *iov,
- int count);
-extern ssize_t SYSIO_INTERFACE_NAME(read)(int fd, void *buf, size_t count);
-extern ioid_t SYSIO_INTERFACE_NAME(ipwritev)(int fd, const struct iovec *iov,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ioid_t SYSIO_INTERFACE_NAME(ipwrite64v)(int fd, const struct iovec *iov,
- size_t count, off64_t offset);
-#endif
-extern ioid_t SYSIO_INTERFACE_NAME(ipwrite)(int fd, const void *buf,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ioid_t SYSIO_INTERFACE_NAME(ipwrite64)(int fd, const void *buf,
- size_t count, off64_t offset);
-#endif
-extern ssize_t SYSIO_INTERFACE_NAME(pwritev)(int fd, const struct iovec *iov,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ssize_t SYSIO_INTERFACE_NAME(pwrite64v)(int fd, const struct iovec *iov,
- size_t count, off64_t offset);
-#endif
-extern ssize_t SYSIO_INTERFACE_NAME(pwrite)(int fd, const void *buf,
- size_t count, off_t offset);
-#if _LARGEFILE64_SOURCE
-extern ssize_t SYSIO_INTERFACE_NAME(pwrite64)(int fd, const void *buf,
- size_t count, off64_t offset);
-#endif
-extern ioid_t SYSIO_INTERFACE_NAME(iwritev)(int fd,
- const struct iovec *iov,
- int count);
-extern ioid_t SYSIO_INTERFACE_NAME(iwrite)(int fd, const void *buf,
- size_t count);
-extern ssize_t SYSIO_INTERFACE_NAME(writev)(int fd, const struct iovec *iov,
- int count);
-extern ssize_t SYSIO_INTERFACE_NAME(write)(int fd, const void *buf,
- size_t count);
extern int SYSIO_INTERFACE_NAME(mknod)(const char *path,
mode_t mode, dev_t dev);
extern int SYSIO_INTERFACE_NAME(utime)(const char *path,
#define SYSIO_LEAVE
#endif
+
+/* accounting for IO stats read and write char count */
+#if defined(REDSTORM)
+#define _SYSIO_UPDACCT(w, cc) \
+ do { \
+ if ((cc) < 0) \
+ break; \
+ if (!w) \
+ _add_iostats(0, (size_t )(cc)); \
+ else \
+ _add_iostats((size_t )(cc), 0); \
+ } while(0)
+#else
+#define _SYSIO_UPDACCT(w, cc)
+#endif
*/
/*
+ * Extended application programmers interface for IO as found on Cray RedStorm
+ * and the other current SUNMos/Puma/Cougar/Catamount systems.
+ */
+
+#ifndef _XTIO_H_
+#define _XTIO_H_
+
+#ifndef _IOID_T_DEFINED
+#define _IOID_T_DEFINED
+typedef void *ioid_t;
+
+#define IOID_FAIL 0
+#endif
+
+/*
* Structure for strided I/O.
*/
struct xtvec {
};
#endif
-extern ioid_t SYSIO_INTERFACE_NAME(ireadx)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec *xtv,
- size_t xtv_count);
+struct iovec;
+
+/*
+ * Get status of previously posted async file IO operation.
+ */
+extern int iodone(ioid_t ioid);
+
+/*
+ * Wait for completion of a previously posted asynch file IO request.
+ */
+extern ssize_t iowait(ioid_t ioid);
+
+/*
+ * Post asynch read into buffers mapped by an iovec from file at given offset.
+ */
+extern ioid_t ipreadv(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off_t offset);
+
+#if _LARGEFILE64_SOURCE
+/*
+ * Post asynch read into buffers mapped by an iovec from file at given offset.
+ */
+extern ioid_t ipread64v(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off64_t offset);
+#endif
+
+/*
+ * Post asynch read into buffer from file at given offset.
+ */
+extern ioid_t ipread(int fd,
+ void *buf,
+ size_t count,
+ off_t offset);
+
+#if _LARGEFILE64_SOURCE
+/*
+ * Post asynch read into buffer from file at given offset.
+ */
+extern ioid_t ipread64(int fd,
+ void *buf,
+ size_t count,
+ off64_t offset);
+#endif
+
+/*
+ * Read into buffers mapped by an iovec from file at given offset.
+ */
+extern ssize_t preadv(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off_t offset);
+
+#if _LARGEFILE64_SOURCE
+/*
+ * Read into buffers mapped by an iovec from file at given offset.
+ */
+extern ssize_t pread64v(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off64_t offset);
+#endif
+
+/*
+ * Post asynch read into buffers mapped by an iovec.
+ */
+extern ioid_t ireadv(int fd,
+ const struct iovec *iov,
+ int count);
+
+/*
+ * Read into buffer.
+ */
+extern ioid_t iread(int fd,
+ void *buf,
+ size_t count);
+
+/*
+ * Post async read into buffers mapped by iovec from regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ioid_t ireadx(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec *xtv,
+ size_t xtv_count);
+
#ifdef __USE_LARGEFILE64
-extern ioid_t SYSIO_INTERFACE_NAME(iread64x)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec64 *xtv,
- size_t xtv_count);
+/*
+ * Post async read into buffers mapped by iovec from regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ioid_t iread64x(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec64 *xtv,
+ size_t xtv_count);
#endif
-extern ssize_t SYSIO_INTERFACE_NAME(readx)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec *xtv,
- size_t xtv_count);
+
+/*
+ * Read into buffers mapped by iovec from regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ssize_t readx(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec *xtv,
+ size_t xtv_count);
+
#ifdef __USE_LARGEFILE64
-extern ssize_t SYSIO_INTERFACE_NAME(read64x)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec64 *xtv,
- size_t xtv_count);
+/*
+ * Read into buffers mapped by iovec from regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ssize_t read64x(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec64 *xtv,
+ size_t xtv_count);
+#endif
+
+/*
+ * Post asynch write from buffers mapped by an iovec to file at given offset.
+ */
+extern ioid_t ipwritev(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off_t offset);
+#if _LARGEFILE64_SOURCE
+/*
+ * Post asynch write from buffers mapped by an iovec to file at given offset.
+ */
+extern ioid_t ipwrite64v(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off64_t offset);
#endif
-extern ioid_t SYSIO_INTERFACE_NAME(iwritex)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec *xtv,
- size_t xtv_count);
+
+/*
+ * Post asynch write from buffer to file at given offset.
+ */
+extern ioid_t ipwrite(int fd,
+ const void *buf,
+ size_t count,
+ off_t offset);
+
+#if _LARGEFILE64_SOURCE
+/*
+ * Post asynch write from buffer to file at given offset.
+ */
+extern ioid_t ipwrite64(int fd,
+ const void *buf,
+ size_t count,
+ off64_t offset);
+#endif
+
+/*
+ * Write from buffers mapped by an iovec to file at given offset.
+ */
+extern ssize_t pwritev(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off_t offset);
+
+#if _LARGEFILE64_SOURCE
+/*
+ * Write from buffers mapped by an iovec to file at given offset.
+ */
+extern ssize_t pwrite64v(int fd,
+ const struct iovec *iov,
+ size_t count,
+ off64_t offset);
+#endif
+
+/*
+ * Post asynch write from buffer to file at given offset.
+ */
+extern ioid_t iwritev(int fd,
+ const struct iovec *iov,
+ int count);
+
+/*
+ * Write from buffer to file at given offset.
+ */
+extern ioid_t iwrite(int fd,
+ const void *buf,
+ size_t count);
+
+/*
+ * Post async write from buffers mapped by iovec to regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ioid_t iwritex(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec *xtv,
+ size_t xtv_count);
+
#ifdef __USE_LARGEFILE64
-extern ioid_t SYSIO_INTERFACE_NAME(iwrite64x)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec64 *xtv,
- size_t xtv_count);
+/*
+ * Post async write from buffers mapped by iovec to regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ioid_t iwrite64x(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec64 *xtv,
+ size_t xtv_count);
#endif
-extern ssize_t SYSIO_INTERFACE_NAME(writex)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec *xtv,
- size_t xtv_count);
+
+/*
+ * Write from buffers mapped by iovec to regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ssize_t writex(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec *xtv,
+ size_t xtv_count);
+
#ifdef __USE_LARGEFILE64
-extern ssize_t SYSIO_INTERFACE_NAME(write64x)(int fd,
- const struct iovec *iov,
- size_t iov_count,
- const struct xtvec64 *xtv,
- size_t xtv_count);
+/*
+ * Write from buffers mapped by iovec to regions mapped
+ * by xtvec.
+ *
+ * NB: An adaptation of "listio" from Argonne's PVFS.
+ */
+extern ssize_t write64x(int fd,
+ const struct iovec *iov,
+ size_t iov_count,
+ const struct xtvec64 *xtv,
+ size_t xtv_count);
#endif
+#endif /* ! _XTIO_H_ */
{creat, ft=chr,nm=\"/dev/stderr\",pm=0200,mm=0+2} \
{creat, ft=dir,nm=\"/dev/fd\",pm=0755,ow=0,gr=0} \
{creat, ft=chr,nm=\"/dev/fd/0\",pm=0400,mm=0+0} \
+ {open, nm=\"/dev/fd/0\",fd=0,m=0} \
{creat, ft=chr,nm=\"/dev/fd/1\",pm=0200,mm=0+1} \
+ {open, nm=\"/dev/fd/1\",fd=1,m=1} \
{creat, ft=chr,nm=\"/dev/fd/2\",pm=0200,mm=0+2} \
+ {open, nm=\"/dev/fd/2\",fd=2,m=1} \
{cd, dir=\"$HOME\"} \
${_extras} \
"
#include <stdlib.h>
#include <errno.h>
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
+#include <sys/queue.h>
-#include "sysio-symbols.h"
#include "sysio.h"
+#include "sysio-symbols.h"
int
SYSIO_INTERFACE_NAME(access)(const char *path, int amode)
SYSIO_INTERFACE_ENTER;
err = 0;
+ /*
+ * Check amode.
+ */
+ if ((amode & (R_OK|W_OK|X_OK)) != amode)
+ SYSIO_INTERFACE_RETURN(-1, -EINVAL);
+
n = getgroups(0, NULL);
list = NULL;
if (n) {
err = -errno;
goto out;
}
+ if (!amode)
+ SYSIO_INTERFACE_RETURN(0, 0);
+
mask = 0;
if (amode & R_OK)
SYSIO_INTERFACE_RETURN(newfd, 0);
}
- fd = _sysio_fd_dup2(oldfd, newfd);
+ fd = _sysio_fd_dup(oldfd, newfd, 1);
SYSIO_INTERFACE_RETURN(fd < 0 ? -1 : fd, fd < 0 ? fd : 0);
}
SYSIO_INTERFACE_DISPLAY_BLOCK;
SYSIO_INTERFACE_ENTER;
- fd = _sysio_fd_dup2(oldfd, -1);
+ fd = _sysio_fd_dup(oldfd, -1, 0);
SYSIO_INTERFACE_RETURN(fd < 0 ? -1 : fd, fd < 0 ? fd : 0);
}
#include <syscall.h>
static int
-_sysio_fcntl(int fd, int cmd, va_list ap)
+_sysio_fcntl(int fd, int cmd, va_list ap, int *rtn)
{
- int err;
- long arg;
-
- switch (cmd) {
- case F_GETFD:
- case F_GETFL:
- case F_GETOWN:
- return syscall(SYS_fcntl, fd, cmd);
- case F_DUPFD:
- case F_SETFD:
- case F_SETFL:
- case F_GETLK:
- case F_SETLK:
- case F_SETLKW:
- case F_SETOWN:
- arg = va_arg(ap, long);
- return syscall(SYS_fcntl, fd, cmd, arg);
- }
+ long arg = va_arg(ap, long);
- errno = ENOSYS;
- return -1;
+ *rtn = syscall(SYS_fcntl, fd, cmd, arg);
+ return *rtn == -1 ? -errno : 0;
}
#endif
SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...)
{
int err;
+ int rtn;
struct file *fil;
va_list ap;
SYSIO_INTERFACE_DISPLAY_BLOCK;
if (!fil) {
#ifdef HAVE_LUSTRE_HACK
va_start(ap, cmd);
- err = _sysio_fcntl(fd, cmd, ap);
+ err = _sysio_fcntl(fd, cmd, ap, &rtn);
va_end(ap);
- if (err == -1)
- err = -errno;
goto out;
#else
+
+ rtn = -1;
err = -EBADF;
goto out;
#endif
newfd = va_arg(ap, long);
va_end(ap);
if (newfd != (int )newfd || newfd < 0) {
+ rtn = -1;
err = -EBADF;
goto out;
}
- err = _sysio_fd_dup2(fd, (int )newfd);
+ rtn = _sysio_fd_dup(fd, (int )newfd, 0);
+ if (rtn < 0) {
+ err = rtn;
+ rtn = -1;
+ }
}
break;
default:
va_start(ap, cmd);
- err = fil->f_ino->i_ops.inop_fcntl(fil->f_ino, cmd, ap);
+ err = fil->f_ino->i_ops.inop_fcntl(fil->f_ino, cmd, ap, &rtn);
va_end(ap);
break;
}
out:
- SYSIO_INTERFACE_RETURN(err ? -1 : 0, err);
+ SYSIO_INTERFACE_RETURN(rtn, err);
}
#ifdef __GLIBC__
#include "sysio.h"
#include "file.h"
#include "inode.h"
-#include "xtio.h"
/*
* Support for file IO.
static int
fd_grow(size_t n)
{
- int fd;
size_t count;
struct file **noftab, **filp;
/*
* Sanity check the new size.
*/
- fd = (int )n;
- if ((size_t )fd != n)
+ if ((int )n < 0)
return -EMFILE;
- if (n < 8)
- n = 8;
- if (n >= _sysio_oftab_size && n - _sysio_oftab_size < _sysio_oftab_size)
- n = (n + 1) * 2;
+ /*
+ * We never shrink the table.
+ */
+ if (n <= _sysio_oftab_size)
+ return 0;
+
noftab = realloc(_sysio_oftab, n * sizeof(struct file *));
if (!noftab)
return -ENOMEM;
_sysio_oftab = noftab;
count = _sysio_oftab_size;
_sysio_oftab_size = n;
- if (n < count)
- return 0;
filp = _sysio_oftab + count;
n -= count;
while (n--)
#endif
/*
- * Find a free slot in the open files table.
+ * Find a free slot in the open files table greater than or equal to the
+ * argument.
*/
static int
-find_free_fildes()
+find_free_fildes(int low)
{
- size_t n;
+ int n;
int err;
struct file **filp;
- for (n = 0, filp = _sysio_oftab;
- n < _sysio_oftab_size && *filp;
+ for (n = low, filp = _sysio_oftab + low;
+ n >= 0 && (unsigned )n < _sysio_oftab_size && *filp;
n++, filp++)
;
- if (n >= _sysio_oftab_size) {
- err = fd_grow(n);
+ if (n < 0)
+ return -ENFILE;
+ if ((unsigned )n >= _sysio_oftab_size) {
+ err = fd_grow((unsigned )n + 1);
if (err)
return err;
filp = &_sysio_oftab[n];
}
/*
- * Associate open file record with given file descriptor or any available
- * file descriptor if less than zero.
+ * Associate open file record with given file descriptor (if forced), or any
+ * available file descriptor if less than zero, or any available descriptor
+ * greater than or equal to the given one if not forced.
*/
int
-_sysio_fd_set(struct file *fil, int fd)
+_sysio_fd_set(struct file *fil, int fd, int force)
{
int err;
struct file *ofil;
/*
- * New fd < 0 => any available descriptor.
+ * Search for a free descriptor if needed.
*/
- if (fd < 0) {
- fd = find_free_fildes();
+ if (fd < 0 || !force) {
+ if (fd < 0)
+ fd = 0;
+ fd = find_free_fildes(fd);
if (fd < 0)
return fd;
}
if ((unsigned )fd >= _sysio_oftab_size) {
- err = fd_grow(fd);
+ err = fd_grow((unsigned )fd + 1);
if (err)
return err;
}
* Duplicate old file descriptor.
*
* If the new file descriptor is less than zero, the new file descriptor
- * is chosen freely.
+ * is chosen freely. Otherwise, choose an available descriptor greater
+ * than or equal to the new, if not forced. Otherwise, if forced, (re)use
+ * the new.
*/
int
-_sysio_fd_dup2(int oldfd, int newfd)
+_sysio_fd_dup(int oldfd, int newfd, int force)
{
struct file *fil;
int fd;
if (oldfd == newfd)
- return 0;
+ return newfd;
fil = _sysio_fd_find(oldfd);
if (!fil)
return -EBADF;
- fd = _sysio_fd_set(fil, newfd);
+ fd = _sysio_fd_set(fil, newfd, force);
if (fd >= 0)
F_REF(fil);
return fd;
#include "sysio.h"
#include "file.h"
#include "inode.h"
-#include "xtio.h"
/*
* Support for file IO.
#endif
/*
- * Find a free slot in the open files table.
- * target < 0: any free slot
- * target >= 0: get slot [target]
+ * Find a free slot in the open files table which >= @low
+ * low < 0 means any
*/
static int
-find_free_fildes(oftab_t *oftab, int target)
+find_free_fildes(oftab_t *oftab, int low)
{
int n;
int err;
struct file **filp;
- if (target < 0) {
- for (n = 0, filp = oftab->table;
- n < oftab->size && *filp;
- n++, filp++)
- ;
- } else
- n = target - oftab->offset;
+ if (low < 0)
+ low = oftab->offset;
+
+ n = low - oftab->offset;
+ if (n < 0)
+ return -ENFILE;
+
+ for (filp = oftab->table + n;
+ n < oftab->size && *filp;
+ n++, filp++)
+ ;
if (n >= oftab->size) {
err = fd_grow(oftab, n);
assert(!*filp);
}
-#ifdef HAVE_LUSTRE_HACK
- /* FIXME sometimes we could intercept open/socket to create
- * a fd, but missing close()? currently we have this problem
- * with resolv lib. as a workaround simply destroy the file
- * struct here.
- */
- if (oftab->table[n]) {
- free(oftab->table[n]);
- oftab->table[n] = NULL;
- }
-#endif
-
return oftab->offset + n;
}
}
/*
- * Associate open file record with given file descriptor or any available
- * file descriptor if less than zero.
+ * Associate open file record with given file descriptor (if forced), or any
+ * available file descriptor if less than zero, or any available descriptor
+ * greater than or equal to the given one if not forced.
*/
int
-_sysio_fd_set(struct file *fil, int fd)
+_sysio_fd_set(struct file *fil, int fd, int force)
{
int err;
struct file *ofil;
oftab_t *oftab;
+ if (force && fd < 0)
+ abort();
+
init_oftab();
oftab = select_oftab(fd);
/*
- * New fd < 0 => any available descriptor.
+ * Search for a free descriptor if needed.
*/
- fd = find_free_fildes(oftab, fd);
- if (fd < 0)
- return fd;
+ if (!force) {
+ fd = find_free_fildes(oftab, fd);
+ if (fd < 0)
+ return fd;
+ }
- assert(fd < oftab->offset + oftab->size);
+ if (fd - oftab->offset >= oftab->size) {
+ err = fd_grow(oftab, fd - oftab->offset);
+ if (err)
+ return err;
+ }
/*
* Remember old.
*/
ofil = __sysio_fd_get(fd, 1);
- if (ofil)
- F_RELE(ofil);
+ if (ofil) {
+ /* FIXME sometimes we could intercept open/socket to create
+ * a fd, but missing close()? currently we have this problem
+ * with resolv lib. as a workaround simply destroy the file
+ * struct here. And this hack will break the behavior of
+ * DUPFD.
+ */
+ if (fd >= 0 && oftab == &_sysio_oftab[0])
+ free(ofil);
+ else
+ F_RELE(ofil);
+ }
oftab->table[fd - oftab->offset] = fil;
* Duplicate old file descriptor.
*
* If the new file descriptor is less than zero, the new file descriptor
- * is chosen freely.
+ * is chosen freely. Otherwise, choose an available descriptor greater
+ * than or equal to the new, if not forced. Otherwise, if forced, (re)use
+ * the new.
*/
int
-_sysio_fd_dup2(int oldfd, int newfd)
+_sysio_fd_dup(int oldfd, int newfd, int force)
{
struct file *fil;
int fd;
if (select_oftab(oldfd) != select_oftab(newfd))
return -EINVAL;
- fd = _sysio_fd_set(fil, newfd);
+ fd = _sysio_fd_set(fil, newfd, force);
if (fd >= 0)
F_REF(fil);
return fd;
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/uio.h>
-
-#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/uio.h>
+#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "inode.h"
#include "fs.h"
#include "mount.h"
#include "file.h"
#include "dev.h"
-#include "xtio.h"
#ifdef STDFD_DEV
#include "stdfd.h"
xtvec.xtv_len = iovec.iov_len;
IOCTX_INIT(&io_context,
1,
- (ioid_t )&io_context,
1,
ino,
&iovec, 1,
return err;
}
+static int
+do_open(char *args)
+{
+ size_t len;
+ struct named_argument v[] = {
+ { "nm", NULL }, /* path */
+ { "fd", NULL }, /* fildes */
+ { "m", NULL }, /* mode */
+ { NULL, NULL }
+ };
+ char *cp;
+ int fd;
+ mode_t m;
+ struct pnode *dir, *pno;
+ struct intent intent;
+ int err;
+ struct file *fil;
+
+ len = strlen(args);
+ if (get_args(args, v) - args != (ssize_t )len ||
+ !(v[0].value && v[1].value && v[2].value))
+ return -EINVAL;
+ fd = strtol(v[1].value, (char **)&cp, 0);
+ if (*cp ||
+ (((fd == LONG_MIN || fd == LONG_MAX) && errno == ERANGE)) ||
+ fd < 0)
+ return -EINVAL;
+ m = strtoul(v[1].value, (char **)&cp, 0);
+ if (*cp ||
+ (m == LONG_MAX && errno == ERANGE))
+ return -EINVAL;
+ m &= O_RDONLY|O_WRONLY|O_RDWR;
+
+ if (!(dir = _sysio_cwd) && !(dir = _sysio_root))
+ return -ENOENT;
+ INTENT_INIT(&intent, INT_OPEN, &m, NULL);
+ pno = NULL;
+ err = _sysio_namei(dir, v[0].value, 0, &intent, &pno);
+ if (err)
+ return err;
+ fil = NULL;
+ do {
+ err = _sysio_open(pno, m, 0);
+ if (err)
+ break;
+ fil = _sysio_fnew(pno->p_base->pb_ino, m);
+ if (!fil) {
+ err = -ENOMEM;
+ break;
+ }
+ err = _sysio_fd_set(fil, fd, 1);
+ if (err < 0)
+ break;
+ P_RELE(pno);
+ return 0;
+ } while (0);
+ if (fil)
+ F_RELE(fil);
+ if (pno)
+ P_RELE(pno);
+ return err;
+}
+
/*
* Execute the given cmd.
*
return do_cd(args);
if (strcmp("chmd", cmd) == 0)
return do_chmd(args);
+ if (strcmp("open", cmd) == 0)
+ return do_open(args);
}
return -EINVAL;
}
#include <string.h>
#include <errno.h>
#include <assert.h>
-#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/queue.h>
#include "sysio.h"
#include "fs.h"
return -ENOSYS;
}
+
+
+/*
+ * Return -ENODEV
+ */
+int
+_sysio_do_enodev()
+{
+
+ return -ENODEV;
+}
#include <string.h>
#include <errno.h>
#include <assert.h>
-#include <sys/types.h>
#include <sys/uio.h>
+#include <sys/types.h>
#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "inode.h"
-#include "xtio.h"
+
+
+#if defined(REDSTORM)
+#include <catamount/do_iostats.h>
+#endif
+
/*
* Asynchronous IO context support.
IOCTX_INIT(ioctx,
0,
- (ioid_t )ioctx,
wr,
ino,
iov, iovlen,
* this implementation.
*/
struct ioctx *
-_sysio_ioctx_find(ioid_t id)
+_sysio_ioctx_find(void *id)
{
struct ioctx *ioctx;
for (ioctx = aioq.lh_first; ioctx; ioctx = ioctx->ioctx_link.le_next)
- if (ioctx->ioctx_id == id)
+ if (ioctx == id)
return ioctx;
return NULL;
{
struct ioctx_callback *entry;
+
+ /* update IO stats */
+ _SYSIO_UPDACCT(ioctx->ioctx_write, ioctx);
+
/*
* Run the call-back queue.
*/
while (xtvec.xtv_len) {
if (iovec.iov_len) {
tmp = iovec.iov_len;
- if (iovec.iov_len > xtvec.xtv_len) {
+ if (iovec.iov_len > xtvec.xtv_len)
iovec.iov_len = xtvec.xtv_len;
- }
cc =
(*f)(&iovec, 1,
xtvec.xtv_off,
if (acc && tmp <= acc)
abort(); /* paranoia */
acc = tmp;
- } else {
+ } else if (iovlen) {
start = iov;
n = xtvec.xtv_len;
do {
} while (--iovlen);
if (iov == start) {
iovec = *iov++;
-#if 0
- if (iovec.iov_len > n) {
- iovec.iov_len = n;
- }
-#endif
+ iovlen--;
continue;
}
remain = xtvec.xtv_len - n;
cc =
(*f)(start, iov - start,
- xtvec.xtv_off,
- xtvec.xtv_len - n,
+ xtvec.xtv_off,
+ remain,
arg);
if (cc <= 0) {
if (acc)
if (acc && tmp <= acc)
abort(); /* paranoia */
acc = tmp;
-
- if (remain && !iovlen)
- return acc;
-
+
remain -= cc;
if (remain)
return acc; /* short */
- }
+ } else
+ return acc; /* short out */
xtvec.xtv_off += cc;
xtvec.xtv_len -= cc;
}
* Poll status of asynch IO request.
*/
int
-SYSIO_INTERFACE_NAME(iodone)(ioid_t ioid)
+SYSIO_INTERFACE_NAME(iodone)(void *ioid)
{
struct ioctx *ioctx;
int rc;
* The identifier is no longer valid after return.
*/
ssize_t
-SYSIO_INTERFACE_NAME(iowait)(ioid_t ioid)
+SYSIO_INTERFACE_NAME(iowait)(void *ioid)
{
struct ioctx *ioctx;
ssize_t cc;
struct file *fil;
_SYSIO_OFF_T off, pos;
struct intnl_stat stbuf;
- SYSIO_INTERFACE_DISPLAY_BLOCK;
- SYSIO_INTERFACE_ENTER;
fil = _sysio_fd_find(fd);
if (!fil)
return -EBADF;
fil->f_ino,
&stbuf);
if (err)
- SYSIO_INTERFACE_RETURN((off_t )-1, (int )err);
+ return err;
}
off = stbuf.st_size;
}
pos = off + offset;
if ((offset < 0 && -offset > off) || (offset > 0 && pos <= off))
- SYSIO_INTERFACE_RETURN((off_t )-1, -EINVAL);
+ return -EINVAL;
#ifdef O_LARGEFILE
if (pos >= ((fil->f_flags & O_LARGEFILE) ? _SYSIO_OFF_T_MAX : LONG_MAX))
- SYSIO_INTERFACE_RETURN((off_t )-1, -EOVERFLOW);
+ return -EOVERFLOW;
#else
if (pos >= _SYSIO_OFF_T_MAX)
- SYSIO_INTERFACE_RETURN((off_t )-1, -EOVERFLOW);
+ return -EOVERFLOW;
#endif
pos = (fil->f_ino->i_ops.inop_pos)(fil->f_ino, pos);
if (pos < 0)
- SYSIO_INTERFACE_RETURN((off_t )-1, (int )pos);
+ return pos;
fil->f_pos = pos;
- SYSIO_INTERFACE_RETURN((off_t )pos, 0);
+ return pos;
}
#if _LARGEFILE64_SOURCE
#undef lseek64
-sysio_sym_weak_alias(_sysio_lseek, SYSIO_INTERFACE_NAME(lseek64))
+
+extern off64_t
+SYSIO_INTERFACE_NAME(lseek64)(int fd, off64_t offset, int whence)
+{
+ _SYSIO_OFF_T off;
+ off_t rtn;
+ SYSIO_INTERFACE_DISPLAY_BLOCK;
+
+ SYSIO_INTERFACE_ENTER;
+ off = _sysio_lseek(fd, offset, whence);
+ if (off < 0)
+ SYSIO_INTERFACE_RETURN((off_t )-1, (int )off);
+ rtn = (off64_t )off;
+ assert(rtn == off);
+ SYSIO_INTERFACE_RETURN(rtn, 0);
+}
#ifdef __GLIBC__
#undef __lseek64
-sysio_sym_weak_alias(_sysio_lseek, PREPEND(__, SYSIO_INTERFACE_NAME(lseek64)))
+sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(lseek64),
+ PREPEND(__, SYSIO_INTERFACE_NAME(lseek64)))
#endif
#ifdef REDSTORM
#undef __libc_lseek64
-sysio_sym_weak_alias(_sysio_lseek,
+sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(lseek64),
PREPEND(__, SYSIO_INTERFACE_NAME(libc_lseek64)))
#endif
#endif
src/rmdir.c src/stat64.c src/stat.c \
src/symlink.c src/readlink.c \
src/truncate.c src/unlink.c src/utime.c \
- $(FILE_SUPPORT) $(LUSTRE_SRCDIR_SOURCES)
+ $(FILE_SUPPORT) $(LUSTRE_SRCDIR_SRCS)
SRCDIR_EXTRA = src/module.mk
#endif
#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "fs.h"
#include "mount.h"
#include "inode.h"
-#ifdef AUTOMOUNT_FILE_NAME
-#include "xtio.h"
-#endif
/*
* File system and volume mount support.
xtvec.xtv_len = stbuf.st_size;
IOCTX_INIT(&iocontext,
1,
- (ioid_t )&iocontext,
0,
ino,
&iovec, 1,
#include <errno.h>
#include <assert.h>
#include <sys/param.h>
-#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/queue.h>
#include "sysio.h"
#include "mount.h"
#include "mount.h"
#include "sysio-symbols.h"
-#include "sysio-symbols.h"
-
/*
* Open file support.
*/
rtn = -ENOMEM;
goto error;
}
- rtn = _sysio_fd_set(fil, -1);
+ rtn = _sysio_fd_set(fil, -1, 0);
if (rtn < 0)
goto error;
*/
INTENT_INIT(&intent, INT_UPDPARENT, NULL, NULL);
err = _sysio_namei(_sysio_cwd, newpath, ND_NEGOK, &intent, &new);
- if (err && !new)
+ if (err)
goto error2;
if (old->p_mount->mnt_root == old || old->p_cover ||
#include <sys/uio.h>
#include <sys/queue.h>
+#include "xtio.h"
#include "sysio.h"
#include "file.h"
#include "inode.h"
-#include "xtio.h"
#include "sysio-symbols.h"
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
ssize_t
free(iov);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
ssize_t
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#if _LARGEFILE64_SOURCE
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#if _LARGEFILE64_SOURCE
NULL,
&ioctx);
- SYSIO_INTERFACE_RETURN(err ? IOID_FAIL : ioctx->ioctx_id, err);
+ SYSIO_INTERFACE_RETURN(err ? IOID_FAIL : ioctx, err);
}
#if _LARGEFILE64_SOURCE
free(ixtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#else
#undef ireadx
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
ssize_t
free(iov);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
ssize_t
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#if _LARGEFILE64_SOURCE
free(xtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#if _LARGEFILE64_SOURCE
NULL,
&ioctx);
- SYSIO_INTERFACE_RETURN(err ? IOID_FAIL : ioctx->ioctx_id, err);
+ SYSIO_INTERFACE_RETURN(err ? IOID_FAIL : ioctx, err);
}
#if _LARGEFILE64_SOURCE
free(ixtv);
SYSIO_INTERFACE_RETURN(IOID_FAIL, err);
}
- SYSIO_INTERFACE_RETURN(ioctx->ioctx_id, 0);
+ SYSIO_INTERFACE_RETURN(ioctx, 0);
}
#else
#undef iwritex
dir->effective = 0;
}
+#if 0
int scandir(const char *dir, struct dirent ***namelist,
int(*select)(const struct dirent *),
int(*compar)(const void *, const void *))
errno = ENOSYS;
return -1;
}
+#endif
/***********************************************************
* FIXME workaround for linux only *
print $cmdfh $cmdstr;
my $res = <$outfh>;
- chop($res);
+ if (defined $res) {
+ chop($res);
+ }
+
print $cmdfh "exit\n";
close $outfh;
print $cmdfh $cmdstr;
my $res = <$outfh>;
- chop($res);
+ if (defined $res) {
+ chop($res);
+ } else {
+ print_and_exit($cmdfh, $outfh, 1, "ERROR! Cmd $cmdstr returned null value!\n");
+ }
+
if ($res ne "0000 ") {
print_and_exit($cmdfh, $outfh, 1, "ERROR! Command $cmd failed with code $res\n");
}
send_cmd($cmdfh, $outfh, "PRINT", $cmdstr);
my $res = <$outfh>;
- chop($res);
+ if (defined $res) {
+ chop($res);
+ } else {
+ print_and_exit($cmdfh, $outfh, 1, "ERROR! Cmd $cmdstr returned null value!\n");
+ }
if ($res eq "0xffffffff") {
send_cmd($cmdfh, $outfh, "PRINT", $cmdstr);
my $err = <$outfh>;
- chop($err);
+ if (defined $err) {
+ chop($err);
+ } else {
+ print_and_exit($cmdfh, $outfh, 1, "ERROR! Cmd $cmdstr returned null value!\n");
+ }
+
print_and_exit($cmdfh, $outfh, 1, "ERROR! $cmd returned $err\n");
}
return $res;
#include <stdlib.h>
+#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/queue.h>
-#include "sysio.h"
-
+#include "xtio.h"
#include "test.h"
+#include "sysio.h"
+
int
_test_sysio_startup()
{
if (err)
return err;
s = getenv("SYSIO_NAMESPACE");
- err = s ? _sysio_boot(s) : -ENOTTY;
+ if (s)
+ err = _sysio_boot(s);
+ else if (!(s = getenv("SYSIO_MANUAL"))) {
+ /*
+ * Assume a native mount at root.
+ */
+ err = _sysio_boot("{mnt,dev=\"native:/\",dir=/,fl=0}");
+ }
if (err)
return err;
+
+ s = getenv("SYSIO_CWD");
+ if (s) {
+ err = chdir(s);
+ if (err)
+ return err;
+ }
+
return 0;
}
+
+void
+_test_sysio_shutdown()
+{
+
+ _sysio_shutdown();
+}
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
+#include <sys/queue.h>
-#include "test_driver.h"
-#include "sysio.h"
#include "xtio.h"
+#include "sysio.h"
+#include "test_driver.h"
/*
* ################################################
#include <sys/statvfs.h>
#include <fcntl.h>
#include <sys/queue.h>
+#include <unistd.h>
#include <dirent.h>
+#include <sys/mount.h>
-#include "sysio.h"
+#include "xtio.h"
#include "mount.h"
#include "test.h"
#include "test_driver.h"
extern int (*drvinits[])(void);
extern int drv_init_all(void);
+extern int _test_sysio_startup(void);
+extern void _test_sysio_shutdown(void);
{creat, ft=chr,nm=\"/dev/stderr\",pm=0200,mm=0+2} \
{creat, ft=dir,nm=\"/dev/fd\",pm=0755,ow=0,gr=0} \
{creat, ft=chr,nm=\"/dev/fd/0\",pm=0400,mm=0+0} \
+ {open, nm=\"/dev/fd/0\",fd=0,m=0} \
{creat, ft=chr,nm=\"/dev/fd/1\",pm=0200,mm=0+1} \
+ {open, nm=\"/dev/fd/1\",fd=1,m=1} \
{creat, ft=chr,nm=\"/dev/fd/2\",pm=0200,mm=0+2} \
+ {open, nm=\"/dev/fd/2\",fd=2,m=1} \
{cd, dir=\"$home\"} \
$extras ";
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/uio.h>
#include <sys/queue.h>
-#include "sysio.h"
-#include "mount.h"
-
-#include "fs_native.h"
-
+#include "xtio.h"
#include "test.h"
/*
int i;
int err;
const char *spath, *dpath;
- extern int _test_sysio_startup(void);
/*
* Parse command-line args.
err = copy_file(spath, dpath);
- _sysio_shutdown();
+ _test_sysio_shutdown();
return err;
}
+#ifndef _BSD_SOURCE
#define _BSD_SOURCE
-#define _XOPEN_SOURCE 600
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/uio.h>
#include <sys/statvfs.h>
#include <fcntl.h>
-#include <sys/queue.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
+#include <sys/uio.h>
+#include <sys/queue.h>
-#include "sysio.h"
+#include "xtio.h"
#include "mount.h"
#include "test.h"
#include "test_driver.h"
*/
err = _test_sysio_startup();
- /* Temp. hack until I do the right thing to fix this...*/
- open("/dev/stdin",O_RDONLY);
- open("/dev/stdout",O_WRONLY);
- open("/dev/stderr",O_WRONLY);
-
infp = stdin;
outfp = stdout;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#else
#include <unistd.h>
-#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/uio.h>
#include <sys/queue.h>
#include <dirent.h>
-#include "sysio.h"
+#include "xtio.h"
#include "mount.h"
#include "test.h"
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return 0;
}
use FindBin;
use lib "$FindBin::Bin";
use helper;
-use Fcntl ':mode';
+use Fcntl;
sub usage
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#endif
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/queue.h>
#if 0
#include <dirent.h>
#endif
+#include <sys/uio.h>
+#include <sys/queue.h>
-#include "sysio.h"
-#include "mount.h"
-
+#include "xtio.h"
#include "test.h"
/*
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return err ? -1 : 0;
}
* lee@sandia.gov
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#else
#include <unistd.h>
-#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/queue.h>
#include <dirent.h>
+#include <sys/uio.h>
+#include <sys/queue.h>
-#include "sysio.h"
-#include "mount.h"
-
+#include "xtio.h"
#include "test.h"
/*
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return 0;
}
* lee@sandia.gov
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#else
-#include <unistd.h>
-#endif
#include <errno.h>
-
-#include <assert.h>
-#include <sys/queue.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/uio.h>
-#include "sysio.h"
-#include "mount.h"
-
+#include "xtio.h"
#include "test.h"
/*
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return 0;
}
use lib "$FindBin::Bin";
use helper;
use POSIX;
-use Fcntl ':mode';
+use Fcntl;
sub usage
{
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#endif
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/queue.h>
-
-#include "sysio.h"
-#include "mount.h"
+#include <sys/uio.h>
+#include "xtio.h"
#include "test.h"
/*
perror(path);
free(buf);
out:
- _sysio_shutdown();
+ _test_sysio_shutdown();
return err;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/queue.h>
-
-#include "sysio.h"
-#include "mount.h"
-
-#include "fs_native.h"
+#include <sys/uio.h>
+#include "xtio.h"
#include "test.h"
/*
if (err)
perror("rename");
- _sysio_shutdown();
+ _test_sysio_shutdown();
return err;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#endif
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#include <sys/queue.h>
#ifdef notdef
#include <sys/statvfs.h>
#endif
+#include <sys/uio.h>
-#include "sysio.h"
-#include "mount.h"
-
+#include "xtio.h"
#include "test.h"
/*
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifndef REDSTORM
-#include <getopt.h>
-#else
#include <unistd.h>
-#endif
#include <errno.h>
#include <sys/types.h>
-#include <sys/queue.h>
#if 0
#include <dirent.h>
#endif
+#include <sys/uio.h>
-#include "sysio.h"
-#include "mount.h"
-
+#include "xtio.h"
#include "test.h"
/*
/*
* Clean up.
*/
- _sysio_shutdown();
+ _test_sysio_shutdown();
return 0;
}