[Libsysio-commit] cplant: libsysio/drivers/native fs_native.c
Brought to you by:
lward
|
From: Ruth K. <rk...@us...> - 2003-10-14 23:39:46
|
Update of /cvsroot/libsysio/libsysio/drivers/native
In directory sc8-pr-cvs1:/tmp/cvs-serv28674/drivers/native
Modified Files:
Tag: cplant
fs_native.c
Log Message:
Merge HEAD changes into cplant branch
Index: fs_native.c
===================================================================
RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v
retrieving revision 1.16.2.1
retrieving revision 1.16.2.2
diff -u -w -b -B -p -r1.16.2.1 -r1.16.2.2
--- fs_native.c 20 Aug 2003 21:05:49 -0000 1.16.2.1
+++ fs_native.c 14 Oct 2003 23:39:36 -0000 1.16.2.2
@@ -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,18 +145,15 @@ 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)
-#define __SYS_STAT SYS_stat
+#define __SYS_STAT SYS_lstat
#define __SYS_FSTAT SYS_fstat
#define __SYS_TRUNCATE SYS_truncate
#define __SYS_FTRUNCATE SYS_ftruncate
#else
-#define __SYS_STAT SYS_stat64
+#define __SYS_STAT SYS_lstat64
#define __SYS_FSTAT SYS_fstat64
#define __SYS_TRUNCATE SYS_truncate64
#define __SYS_FTRUNCATE SYS_ftruncate64
@@ -200,20 +216,20 @@ 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);
static int native_inop_readlink(struct pnode *pno, char *buf, size_t bufsiz);
static int native_inop_open(struct pnode *pno, int flags, mode_t mode);
static int native_inop_close(struct inode *ino);
+static int native_inop_link(struct pnode *old, struct pnode *new);
static int native_inop_unlink(struct pnode *pno);
+static int native_inop_rename(struct pnode *old, struct pnode *new);
static int native_inop_ipreadv(struct inode *ino,
- struct io_arguments *ioargs,
- struct ioctx **ioctxp);
+ struct ioctx *ioctx);
static int native_inop_ipwritev(struct inode *ino,
- struct io_arguments *ioargs,
- struct ioctx **ioctxp);
+ struct ioctx *ioctx);
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_sync(struct inode *ino);
@@ -222,9 +238,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 = {
@@ -238,7 +256,9 @@ static struct inode_ops native_i_ops = {
native_inop_readlink,
native_inop_open,
native_inop_close,
+ native_inop_link,
native_inop_unlink,
+ native_inop_rename,
native_inop_ipreadv,
native_inop_ipwritev,
native_inop_iodone,
@@ -247,7 +267,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
};
@@ -264,7 +286,7 @@ static struct fssw_ops native_fssw_ops =
static void native_fsop_gone(struct filesys *fs);
static struct filesys_ops native_inodesys_ops = {
- native_fsop_gone,
+ native_fsop_gone
};
/*
@@ -832,30 +854,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;
- cc = syscall(__SYS_GETDENTS, nino->ni_fd, buf, nbytes);
+#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;
}
@@ -1019,6 +1103,32 @@ native_inop_close(struct inode *ino)
}
static int
+native_inop_link(struct pnode *old, struct pnode *new)
+{
+ int err;
+ char *opath, *npath;
+
+ err = 0;
+
+ opath = _sysio_pb_path(old->p_base, '/');
+ npath = _sysio_pb_path(new->p_base, '/');
+ if (!(opath && npath)) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = syscall(SYS_link, opath, npath);
+
+out:
+ if (opath)
+ free(opath);
+ if (npath)
+ free(npath);
+
+ return err;
+}
+
+static int
native_inop_unlink(struct pnode *pno)
{
char *path;
@@ -1053,30 +1163,32 @@ 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 ioctx *ioctx)
{
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);
- if (ioargs->ioarg_iovlen && (int )ioargs->ioarg_iovlen < 0)
+ if ((ioctx->ioctx_iovlen && (int )ioctx->ioctx_iovlen < 0) ||
+ !(S_ISREG(ino->i_mode) ||
+ S_ISCHR(ino->i_mode) ||
+ S_ISSOCK(ino->i_mode) ||
+ S_ISFIFO(ino->i_mode)))
return -EINVAL;
- /*
- * Get a new IO context.
- */
- ioctx = _sysio_ioctx_new(ino, ioargs);
- if (!ioctx)
- return -ENOMEM;
-
+#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.
@@ -1086,71 +1198,138 @@ 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)
+{
+ int err;
+ char *opath, *npath;
+
+ opath = _sysio_pb_path(old->p_base, '/');
+ npath = _sysio_pb_path(new->p_base, '/');
+ if (!(opath && npath)) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = syscall(SYS_rename, opath, npath);
+
+out:
+ if (opath)
+ free(opath);
+ if (npath)
+ free(npath);
+
+ return err;
+}
static int
native_inop_ipreadv(struct inode *ino,
- struct io_arguments *ioargs,
- struct ioctx **ioctxp)
+ struct ioctx *ioctx)
{
- return doio(_readv, ino, ioargs, ioctxp);
+ return doio(native_read, ino, ioctx);
}
/*
* Helper function passed to doio(), above, to accomplish a real writev.
*/
+#ifdef REDSTORM
+static ssize_t
+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
-_writev(int fd, const struct iovec *vector, int count)
+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,
- struct io_arguments *ioargs,
- struct ioctx **ioctxp)
+ struct ioctx *ioctx)
{
- return doio(_writev, ino, ioargs, ioctxp);
+ return doio(native_write, ino, ioctx);
}
static int
@@ -1185,6 +1364,7 @@ native_inop_mknod(struct pnode *pno __IS
return -ENOSYS;
}
+#ifdef _HAVE_STATVFS
static int
native_inop_statvfs(struct pnode *pno,
struct inode *ino,
@@ -1235,6 +1415,7 @@ native_inop_statvfs(struct pnode *pno,
buf->f_namemax = fs.f_namelen;
return 0;
}
+#endif
static int
native_inop_sync(struct inode *ino)
@@ -1251,7 +1432,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
|