[Libsysio-commit] HEAD: libsysio/drivers/native fs_native.c
Brought to you by:
lward
|
From: Lee W. <lw...@us...> - 2003-10-10 18:52:06
|
Update of /cvsroot/libsysio/libsysio/drivers/native
In directory sc8-pr-cvs1:/tmp/cvs-serv14350/drivers/native
Modified Files:
fs_native.c
Log Message:
Red Storm branch mega-merge. Please, no more changes to any of the
Red Storm branches. We'll keep them for reference for awhile but then,
they go away. Finally!
Index: fs_native.c
===================================================================
RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -w -b -B -p -r1.17 -r1.18
--- fs_native.c 27 Sep 2003 19:42:02 -0000 1.17
+++ fs_native.c 10 Oct 2003 18:50:31 -0000 1.18
@@ -57,8 +57,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
+#if 0
#include <sys/vfs.h>
+#endif
+#ifdef _HAVE_STATVFS
#include <sys/statvfs.h>
+#endif
#include <utime.h>
#include <sys/queue.h>
@@ -69,6 +73,21 @@
#include "fs_native.h"
+#ifdef REDSTORM
+#include <catamount/syscall.h> /* ! in sys include? */
+#endif
+
+#ifdef REDSTORM
+/*
+ * The cnos IO routines on Red Storm can't do scatter/gather IO. We
+ * must use a different interface, then. The doio() routine will loop
+ * over the vector entries.
+ */
+typedef ssize_t (*iof)(int, void *, size_t, _SYSIO_OFF_T);
+#else
+typedef ssize_t (*iof)(int, const struct iovec *, int);
+#endif
+
/*
* Local host file system driver.
*/
@@ -126,9 +145,6 @@ do {
#define __native_stat intnl_stat
#define COPY_STAT(src, dest) *(dest) = *(src)
-#define CALL_LSEEK(fd, off, rc, wh) \
- (syscall(SYS_lseek, fd, off, &rc, wh))
-
#endif
#if defined(USE_NATIVE_STAT)
@@ -195,7 +211,7 @@ static int native_inop_setattr(struct pn
static ssize_t native_getdirentries(struct inode *ino,
char *buf,
size_t nbytes,
- off64_t *basep);
+ _SYSIO_OFF_T *basep);
static int native_inop_mkdir(struct pnode *pno, mode_t mode);
static int native_inop_rmdir(struct pnode *pno);
static int native_inop_symlink(struct pnode *pno, const char *data);
@@ -219,9 +235,11 @@ static int native_inop_ioctl(struct inod
unsigned long int request,
va_list ap);
static int native_inop_mknod(struct pnode *pno, mode_t mode, dev_t dev);
+#ifdef _HAVE_STATVFS
static int native_inop_statvfs(struct pnode *pno,
struct inode *ino,
struct intnl_statvfs *buf);
+#endif
static void native_inop_gone(struct inode *ino);
static struct inode_ops native_i_ops = {
@@ -246,7 +264,9 @@ static struct inode_ops native_i_ops = {
native_inop_datasync,
native_inop_ioctl,
native_inop_mknod,
+#ifdef _HAVE_STATVFS
native_inop_statvfs,
+#endif
native_inop_gone
};
@@ -831,30 +851,92 @@ out:
return err;
}
+static int
+native_pos(int fd,
+#if _LARGEFILE64_SOURCE
+ loff_t *offset
+#else
+ _SYSIO_OFF_T *offset
+#endif
+ )
+{
+
+ assert(fd >= 0);
+ assert(*offset >= 0);
+
+#if _LARGEFILE64_SOURCE && defined(SYS__llseek)
+ {
+ int err;
+ err =
+ syscall(SYS__llseek,
+ (unsigned int)fd,
+ (unsigned int)(*offset >> 32),
+ (unsigned int)*offset,
+ offset,
+ SEEK_SET);
+ if (err == -1)
+ return -errno;
+ }
+#else
+ *offset =
+ syscall(SYS_lseek,
+ fd,
+ *offset,
+ SEEK_SET);
+ if (*offset == -1)
+ return -errno;
+#endif
+
+ return 0;
+}
+
+
static ssize_t
native_getdirentries(struct inode *ino,
char *buf,
size_t nbytes,
- off64_t *basep)
+ _SYSIO_OFF_T *basep)
{
struct native_inode *nino = I2NI(ino);
+ int err;
+#ifndef SYS_getdirentries
+#if _LARGEFILE64_SOURCE
loff_t result;
+#else
+ _SYSIO_OFF_T result;
+#endif
+#endif
ssize_t cc;
assert(nino->ni_fd >= 0);
+#ifndef SYS_getdirentries
result = *basep;
- if (*basep != nino->ni_fpos &&
- CALL_LSEEK(nino->ni_fd,
- *basep,
- result,
- SEEK_SET) == -1)
- return -errno;
+ if (*basep != nino->ni_fpos) {
+ err = native_pos(nino->ni_fd, &result);
+ if (err)
+ return err;
+ }
nino->ni_fpos = result;
+#ifdef SYS_getdents64
cc = syscall(SYS_getdents64, nino->ni_fd, buf, nbytes);
+#else
+ cc = syscall(SYS_getdents, nino->ni_fd, buf, nbytes);
+#endif
+#else /* defined(SYS_getdirentries) */
+ cc =
+ syscall(SYS_getdirentries,
+ nino->ni_fd,
+ buf,
+ nbytes,
+ basep,
+ &nino->ni_fpos);
+#endif /* !defined(SYS_getdirentries) */
if (cc < 0)
return -errno;
+#ifndef SYS_getdirentries
nino->ni_fpos += cc;
+#endif
return cc;
}
@@ -1078,14 +1160,20 @@ native_inop_unlink(struct pnode *pno)
* now.
*/
static int
-doio(ssize_t (*f)(int, const struct iovec *, int),
+doio(iof f,
struct inode *ino,
struct io_arguments *ioargs,
struct ioctx **ioctxp)
{
struct native_inode *nino = I2NI(ino);
struct ioctx *ioctx;
+#ifndef REDSTORM
+#if _LARGEFILE64_SOURCE
loff_t result;
+#else
+ _SYSIO_OFF_T result;
+#endif
+#endif
assert(nino->ni_fd >= 0);
@@ -1099,9 +1187,17 @@ doio(ssize_t (*f)(int, const struct iove
if (!ioctx)
return -ENOMEM;
+ if ((ioargs->ioarg_iovlen && (int )ioargs->ioarg_iovlen < 0) ||
+ !(S_ISREG(ino->i_mode) ||
+ S_ISCHR(ino->i_mode) ||
+ S_ISSOCK(ino->i_mode) ||
+ S_ISFIFO(ino->i_mode)))
+ return -EINVAL;
+
+#ifndef REDSTORM
/*
* This implementation first positions the real system descriptor, then
- * performs the operation. This is silly because it's not atomic.
+ * performs the operation. This is not atomic.
*
* An alternative, more complex, less efficient but atomic,
* implementation might consider each entry of the iovec separately.
@@ -1111,44 +1207,81 @@ doio(ssize_t (*f)(int, const struct iove
* Avoid the reposition call if we're already at the right place.
* Allows us to access pipes and fifos.
*/
- result = nino->ni_fpos;
- if (ioctx->ioctx_offset != nino->ni_fpos &&
- !(S_ISCHR(ino->i_mode) ||
- S_ISSOCK(ino->i_mode) ||
- S_ISFIFO(ino->i_mode)) &&
- CALL_LSEEK(nino->ni_fd,
- ioctx->ioctx_offset,
- result,
- SEEK_SET) == -1) {
+ result = ioctx->ioctx_offset;
+ if (ioctx->ioctx_offset != nino->ni_fpos) {
+ int err;
+
+ err = native_pos(nino->ni_fd, &result);
+ if (err) {
ioctx->ioctx_cc = -1;
- ioctx->ioctx_errno = errno;
- } else {
+ ioctx->ioctx_errno = -err;
+ goto out;
+ }
+ nino->ni_fpos = result;
+ }
+#endif
+
/*
* Call the appropriate (read/write) IO function to
* transfer the data now.
*/
- nino->ni_fpos = result;
+#ifdef REDSTORM
+ {
+ size_t count = ioctx->ioctx_iovlen;
+ struct iovec *iov = ioctx->ioctx_iovec;
+ ssize_t cc;
+
+ while (count) {
+ cc =
+ (*f)(nino->ni_fd,
+ iov->base,
+ iov->len,
+ nino->ni_fpos);
+ if (cc < 0) {
+ if (ioctx->ioctx_cc) {
+ /*
+ * No data written at all. Return
+ * error.
+ */
+ ioctx->ioctx_cc = -1;
+ }
+ break;
+ }
+ count--, iov++;
+ }
+ }
+#else /* !defined(REDSTORM) */
ioctx->ioctx_cc =
(*f)(nino->ni_fd, ioctx->ioctx_iovec, ioctx->ioctx_iovlen);
+#endif /* defined(REDSTORM) */
if (ioctx->ioctx_cc < 0)
ioctx->ioctx_errno = errno;
if (ioctx->ioctx_cc > 0)
nino->ni_fpos += ioctx->ioctx_cc;
- }
*ioctxp = ioctx;
+out:
return 0;
}
/*
* Helper function passed to doio(), above, to accomplish a real readv.
*/
+#ifdef REDSTORM
+static ssize_t
+native_read(int fd, void *buf, size_t count, _SYSIO_OFF_T offset)
+{
+
+ return syscall(SYS_pread, fd, buf, count, offset);
+}
+#else
static ssize_t
-_readv(int fd, const struct iovec *vector, int count)
+native_read(int fd, const struct iovec *vector, int count)
{
return syscall(SYS_readv, fd, vector, count);
}
+#endif
static int
native_inop_rename(struct pnode *old, struct pnode *new)
@@ -1180,18 +1313,27 @@ native_inop_ipreadv(struct inode *ino,
struct ioctx **ioctxp)
{
- return doio(_readv, ino, ioargs, ioctxp);
+ return doio(native_read, ino, ioargs, ioctxp);
}
/*
* Helper function passed to doio(), above, to accomplish a real writev.
*/
+#ifdef REDSTORM
static ssize_t
-_writev(int fd, const struct iovec *vector, int count)
+native_write(int fd, void *buf, size_t count, _SYSIO_OFF_T offset)
+{
+
+ return syscall(SYS_pwrite, fd, buf, count, offset);
+}
+#else
+static ssize_t
+native_write(int fd, const struct iovec *vector, int count)
{
return syscall(SYS_writev, fd, vector, count);
}
+#endif
static int
native_inop_ipwritev(struct inode *ino,
@@ -1199,7 +1341,7 @@ native_inop_ipwritev(struct inode *ino,
struct ioctx **ioctxp)
{
- return doio(_writev, ino, ioargs, ioctxp);
+ return doio(native_write, ino, ioargs, ioctxp);
}
static int
@@ -1234,6 +1376,7 @@ native_inop_mknod(struct pnode *pno __IS
return -ENOSYS;
}
+#ifdef _HAVE_STATVFS
static int
native_inop_statvfs(struct pnode *pno,
struct inode *ino,
@@ -1279,6 +1422,7 @@ native_inop_statvfs(struct pnode *pno,
buf->f_namemax = fs.f_namelen;
return 0;
}
+#endif
static int
native_inop_sync(struct inode *ino)
@@ -1295,7 +1439,14 @@ native_inop_datasync(struct inode *ino)
assert(I2NI(ino)->ni_fd >= 0);
- return syscall(__SYS_FDATASYNC, I2NI(ino)->ni_fd);
+#ifdef NATIVE_FDATASYNC
+ return syscall(NATIVE_FDATASYNC, I2NI(ino)->ni_fd);
+#else
+#if 0
+#warning No fdatasync system call -- Using fsync instead!
+#endif
+ return syscall(SYS_fsync, I2NI(ino)->ni_fd);
+#endif
}
static int
|