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