[Libsysio-commit] b_lustre: libsysio/drivers/native fs_native.c
Brought to you by:
lward
|
From: Mei <me...@us...> - 2003-11-01 03:08:25
|
Update of /cvsroot/libsysio/libsysio/drivers/native
In directory sc8-pr-cvs1:/tmp/cvs-serv28091/drivers/native
Modified Files:
Tag: b_lustre
fs_native.c
Log Message:
merge HEAD into b_lustre, some fixes
Index: fs_native.c
===================================================================
RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v
retrieving revision 1.11.2.3
retrieving revision 1.11.2.4
diff -u -w -b -B -p -r1.11.2.3 -r1.11.2.4
--- fs_native.c 15 Aug 2003 07:43:15 -0000 1.11.2.3
+++ fs_native.c 1 Nov 2003 03:08:21 -0000 1.11.2.4
@@ -57,8 +57,13 @@
#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>
+#include <sys/statfs.h>
+#endif
#include <utime.h>
#include <sys/queue.h>
@@ -69,6 +74,22 @@
#include "fs_native.h"
+#ifdef REDSTORM
+#include <sys/uio.h>
+#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 +147,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
@@ -175,9 +193,7 @@ struct native_inode {
struct file_identifier ni_fileid; /* ditto */
int ni_fd; /* host fildes */
int ni_oflags; /* flags, from open */
-#if 0
unsigned ni_nopens; /* soft ref count */
-#endif
off_t ni_fpos; /* current pos */
};
@@ -195,20 +211,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);
@@ -217,9 +233,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 = {
@@ -233,7 +251,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,
@@ -242,7 +262,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
};
@@ -335,13 +357,10 @@ native_i_new(struct filesys *fs, struct
nino->ni_fileid.fid_len = sizeof(nino->ni_ident);
nino->ni_fd = -1;
nino->ni_oflags = 0;
-#if 0
nino->ni_nopens = 0;
-#endif
nino->ni_fpos = 0;
ino =
_sysio_i_new(fs,
- buf->st_ino,
&nino->ni_fileid,
#ifndef AUTOMOUNT_FILE_NAME
buf->st_mode & S_IFMT,
@@ -584,7 +603,7 @@ native_iget(struct filesys *fs,
#endif
fileid.fid_data = &ident;
fileid.fid_len = sizeof(ident);
- ino = _sysio_i_find(fs, stbuf.st_ino, &fileid);
+ ino = _sysio_i_find(fs, &fileid);
if (ino && forced) {
/*
* Insertion was forced but it's already present!
@@ -827,30 +846,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;
}
@@ -965,10 +1046,8 @@ native_inop_open(struct pnode *pno, int
* Remember this new open.
*/
nino = I2NI(pno->p_base->pb_ino);
-#if 0
nino->ni_nopens++;
assert(nino->ni_nopens);
-#endif
if (nino->ni_fd >= 0) {
if ((nino->ni_oflags & O_RDWR) ||
@@ -999,11 +1078,16 @@ native_inop_close(struct inode *ino)
if (nino->ni_fd < 0)
abort();
-#if 0
assert(nino->ni_nopens);
- if (--nino->ni_nopens)
+ if (--nino->ni_nopens) {
+ /*
+ * Hmmm. We really don't need anything else. However, some
+ * filesystems try to implement a sync-on-close semantic.
+ * As this appears now, that is lost. Might want to change
+ * it somehow in the future?
+ */
return 0;
-#endif
+ }
err = syscall(SYS_close, nino->ni_fd);
if (err)
@@ -1014,6 +1099,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;
@@ -1048,30 +1159,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.
@@ -1081,71 +1194,141 @@ 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;
+
+ nino->ni_fpos = ioctx->ioctx_offset;
+ while (count) {
+ cc =
+ (*f)(nino->ni_fd,
+ iov->iov_base,
+ iov->iov_len,
+ nino->ni_fpos);
+ if (cc < 0) {
+ if (ioctx->ioctx_cc) {
+ /*
+ * No data written at all. Return
+ * error.
+ */
+ ioctx->ioctx_cc = -1;
+ }
+ break;
+ }
+ ioctx->ioctx_cc += cc;
+ 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:
+ ioctx->ioctx_done = 1;
return 0;
}
/*
* Helper function passed to doio(), above, to accomplish a real readv.
*/
+#ifdef REDSTORM
static ssize_t
-_readv(int fd, const struct iovec *vector, int count)
+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
+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
-_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,
- struct io_arguments *ioargs,
- struct ioctx **ioctxp)
+ struct ioctx *ioctx)
{
- return doio(_writev, ino, ioargs, ioctxp);
+ return doio(native_write, ino, ioctx);
}
static int
@@ -1204,6 +1387,7 @@ native_inop_mknod(struct pnode *pno __IS
return -ENOSYS;
}
+#ifdef _HAVE_STATVFS
static int
native_inop_statvfs(struct pnode *pno,
struct inode *ino,
@@ -1249,6 +1433,7 @@ native_inop_statvfs(struct pnode *pno,
buf->f_namemax = fs.f_namelen;
return 0;
}
+#endif
static int
native_inop_sync(struct inode *ino)
@@ -1265,7 +1450,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
|