[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 |