From 58fa00472edb92e5cef936727774625b47e70ec3 Mon Sep 17 00:00:00 2001 From: adilger Date: Thu, 23 Feb 2006 22:06:36 +0000 Subject: [PATCH] Land b_release_1_4_6 onto HEAD (20060223_1455) * the b1_5_* and b_iam* branches will to continue to use the old libsysio * until they can be updated from b1_4 liblustre because of the API change. - API changegetdirentries->filldirentries changed from upstream - symlink following fixup - fix getcwd for out-of-libsysio directory - lseek fixups for large files - flock/fcntl fixups for 64-bit systems --- build/buildcvs | 4 + libsysio/dev/stdfd/stdfd.c | 2 +- libsysio/drivers/incore/fs_incore.c | 41 ++-- libsysio/drivers/native/fs_native.c | 130 ++++++------ libsysio/drivers/sockets/sockets.c | 16 +- libsysio/drivers/yod/fs_yod.c | 27 +-- libsysio/include/dev.h | 6 +- libsysio/include/file.h | 35 +++- libsysio/include/inode.h | 9 +- libsysio/include/module.mk | 2 +- libsysio/include/sysio-cmn.h | 55 ++++-- libsysio/include/sysio.h | 63 +++++- libsysio/include/xtio.h | 215 ++++++++++---------- libsysio/src/dev.c | 2 +- libsysio/src/dup.c | 10 - libsysio/src/fcntl.c | 189 ++++++++++++++++-- libsysio/src/file.c | 6 +- libsysio/src/file_hack.c | 6 +- libsysio/src/getdirentries.c | 229 +++++++++------------ libsysio/src/init.c | 384 ++++++++++++++++++++++++++++++++---- libsysio/src/ioctx.c | 28 ++- libsysio/src/iowait.c | 5 +- libsysio/src/link.c | 7 +- libsysio/src/lseek.c | 66 ++++--- libsysio/src/mount.c | 2 +- libsysio/src/namei.c | 13 +- libsysio/src/open.c | 50 +++-- libsysio/src/readdir.c | 13 +- libsysio/src/rename.c | 7 +- libsysio/src/rmdir.c | 11 +- libsysio/src/rw.c | 10 +- libsysio/src/stddir.c | 5 +- libsysio/src/symlink.c | 5 + libsysio/src/unlink.c | 7 +- libsysio/tests/Makefile.am | 28 +-- libsysio/tests/module.mk | 2 +- libsysio/tests/startup.c | 46 +++-- libsysio/tests/sysio-run-start.c | 4 +- libsysio/tests/test_copy.c | 43 +++- libsysio/tests/test_getcwd.c | 7 +- libsysio/tests/test_link.c | 7 +- libsysio/tests/test_list.c | 15 +- libsysio/tests/test_path.c | 7 +- libsysio/tests/test_regions.c | 19 +- libsysio/tests/test_rename.c | 7 +- libsysio/tests/test_stats.c | 17 +- libsysio/tests/test_stddir.c | 9 +- libsysio/tests/test_unlink.c | 5 +- 48 files changed, 1277 insertions(+), 599 deletions(-) diff --git a/build/buildcvs b/build/buildcvs index 741a97d..f8d2e56 100644 --- a/build/buildcvs +++ b/build/buildcvs @@ -64,6 +64,8 @@ case "$lustretag" in snmptag="HEAD" portalstag="b_hd_newconfig" lnettag="b_hd_newconfig" + # XXX temorary tag until b1_5* is updated from b1_4 liblustre + libsysiotag="HEAD_RELEASE_1_4_6_LAND_PARENT_20060223_1455" ;; b_cmd*) @@ -74,6 +76,8 @@ case "$lustretag" in snmptag="HEAD" portalstag="b_hd_newconfig" lnettag="b_hd_newconfig" + # XXX temorary tag until b_iam* is updated from b1_4 liblustre + libsysiotag="HEAD_RELEASE_1_4_6_LAND_PARENT_20060223_1455" ;; b_ioprovement) diff --git a/libsysio/dev/stdfd/stdfd.c b/libsysio/dev/stdfd/stdfd.c index 26ade6c..6ea426c 100644 --- a/libsysio/dev/stdfd/stdfd.c +++ b/libsysio/dev/stdfd/stdfd.c @@ -54,8 +54,8 @@ #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "native.h" #include "inode.h" #include "dev.h" diff --git a/libsysio/drivers/incore/fs_incore.c b/libsysio/drivers/incore/fs_incore.c index 4d69821..26b1911 100644 --- a/libsysio/drivers/incore/fs_incore.c +++ b/libsysio/drivers/incore/fs_incore.c @@ -61,8 +61,8 @@ #endif #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "fs.h" #include "mount.h" #include "inode.h" @@ -131,10 +131,10 @@ static int _sysio_incore_inop_setattr(struct pnode *pno, struct inode *ino, unsigned mask, struct intnl_stat *stbuf); -static ssize_t _sysio_incore_dirop_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep); +static ssize_t _sysio_incore_dirop_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes); static int _sysio_incore_dirop_mkdir(struct pnode *pno, mode_t mode); static int _sysio_incore_dirop_rmdir(struct pnode *pno); static int _sysio_incore_inop_open(struct pnode *pno, int flags, mode_t mode); @@ -187,7 +187,7 @@ static struct inode_ops _sysio_incore_dir_ops = { _sysio_incore_dirop_lookup, _sysio_incore_inop_getattr, _sysio_incore_inop_setattr, - _sysio_incore_dirop_getdirentries, + _sysio_incore_dirop_filldirentries, _sysio_incore_dirop_mkdir, _sysio_incore_dirop_rmdir, _sysio_incore_dirop_symlink, @@ -217,11 +217,11 @@ static struct inode_ops _sysio_incore_dir_ops = { struct inode **, \ struct intent *, \ const char *))_sysio_do_illop -#define _sysio_incore_filop_getdirentries \ +#define _sysio_incore_filop_filldirentries \ (ssize_t (*)(struct inode *, \ - char *, \ - size_t, \ - _SYSIO_OFF_T *))_sysio_do_illop + _SYSIO_OFF_T *, \ + char *, \ + size_t))_sysio_do_illop #define _sysio_incore_filop_mkdir \ (int (*)(struct pnode *, mode_t))_sysio_do_illop #define _sysio_incore_filop_rmdir \ @@ -243,7 +243,7 @@ static struct inode_ops _sysio_incore_file_ops = { _sysio_incore_filop_lookup, _sysio_incore_inop_getattr, _sysio_incore_inop_setattr, - _sysio_incore_filop_getdirentries, + _sysio_incore_filop_filldirentries, _sysio_incore_filop_mkdir, _sysio_incore_filop_rmdir, _sysio_incore_filop_symlink, @@ -272,7 +272,7 @@ static struct inode_ops _sysio_incore_dev_ops = { _sysio_incore_filop_lookup, _sysio_incore_inop_getattr, _sysio_incore_inop_setattr, - _sysio_incore_filop_getdirentries, + _sysio_incore_filop_filldirentries, _sysio_incore_filop_mkdir, _sysio_incore_filop_rmdir, _sysio_incore_filop_symlink, @@ -955,31 +955,30 @@ incore_directory_enumerate(struct intnl_dirent *de, } static ssize_t -_sysio_incore_dirop_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) +_sysio_incore_dirop_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes) { struct incore_inode *icino = I2IC(ino); off_t off; struct intnl_dirent *de; struct copy_info copy_info; - if (*basep > icino->ici_st.st_size) + if (*posp >= icino->ici_st.st_size) return 0; de = incore_directory_probe(icino->ici_data, icino->ici_st.st_size, - *basep, + *posp, (probe_ty )incore_directory_position, NULL, - (char *)icino->ici_data + *basep); + (char *)icino->ici_data + *posp); if (!de) { /* * Past EOF. */ - *basep = 0; return 0; } @@ -997,7 +996,7 @@ _sysio_incore_dirop_getdirentries(struct inode *ino, icino->ici_st.st_atime = time(NULL); if (!nbytes) return -EOVERFLOW; - *basep = nbytes; + *posp += nbytes; return (ssize_t )nbytes; } diff --git a/libsysio/drivers/native/fs_native.c b/libsysio/drivers/native/fs_native.c index 65f10dc..684b37f 100644 --- a/libsysio/drivers/native/fs_native.c +++ b/libsysio/drivers/native/fs_native.c @@ -72,8 +72,8 @@ #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "native.h" #include "fs.h" #include "mount.h" @@ -86,13 +86,10 @@ #endif #if defined(SYSIO_SYS_getdirentries) -#define DIR_STREAMED 0 #define DIR_CVT_64 0 #elif defined(SYSIO_SYS_getdents64) -#define DIR_STREAMED 1 #define DIR_CVT_64 0 #elif defined(SYSIO_SYS_getdents) -#define DIR_STREAMED 1 #if defined(_LARGEFILE64_SOURCE) #define DIR_CVT_64 1 /* @@ -143,7 +140,8 @@ struct native_inode_identifier { struct native_inode { unsigned ni_seekok : 1, /* can seek? */ - ni_attrvalid : 1; /* cached attrs ok? */ + ni_attrvalid : 1, /* cached attrs ok? */ + ni_resetfpos : 1; /* reset fpos? */ struct native_inode_identifier ni_ident; /* unique identifier */ struct file_identifier ni_fileid; /* ditto */ int ni_fd; /* host fildes */ @@ -178,10 +176,10 @@ static int native_inop_setattr(struct pnode *pno, struct inode *ino, unsigned mask, struct intnl_stat *stbuf); -static ssize_t native_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep); +static ssize_t native_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes); 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); @@ -213,7 +211,7 @@ static struct inode_ops native_i_ops = { native_inop_lookup, native_inop_getattr, native_inop_setattr, - native_getdirentries, + native_filldirentries, native_inop_mkdir, native_inop_rmdir, native_inop_symlink, @@ -324,6 +322,8 @@ native_i_new(struct filesys *fs, time_t expiration, struct intnl_stat *buf) return NULL; bzero(&nino->ni_ident, sizeof(nino->ni_ident)); nino->ni_seekok = 0; + nino->ni_attrvalid = 0; + nino->ni_resetfpos = 0; nino->ni_ident.dev = buf->st_dev; nino->ni_ident.ino = buf->st_ino; #ifdef HAVE_GENERATION @@ -494,7 +494,6 @@ error: _sysio_pb_gone(rootpb); if (fs) { FS_RELE(fs); - _sysio_fs_gone(fs); nfs = NULL; } if (nfs) @@ -953,26 +952,34 @@ native_pos(int fd, _SYSIO_OFF_T *offset, int whence) } static ssize_t -native_filldirentries(struct native_inode *nino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) +native_ifilldirentries(struct native_inode *nino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes) { int err; ssize_t cc; +#if defined(SYSIO_SYS_getdirentries) + _SYSIO_OFF_T waste; +#endif - if (*basep < 0) + if (*posp < 0) return -EINVAL; -#if DIR_STREAMED /* * Stream-oriented access requires that we reposition prior to the * fill call. */ - if ((err = native_pos(nino->ni_fd, basep, SEEK_SET)) != 0) - return err; -#endif - nino->ni_fpos = *basep; + assert(nino->ni_seekok); + if (*posp != nino->ni_fpos || nino->ni_resetfpos) { + nino->ni_fpos = *posp; + err = native_pos(nino->ni_fd, &nino->ni_fpos, SEEK_SET); + if (err) { + nino->ni_resetfpos = 1; + return err; + } + nino->ni_resetfpos = 0; + } cc = #if defined(SYSIO_SYS_getdirentries) @@ -980,7 +987,7 @@ native_filldirentries(struct native_inode *nino, nino->ni_fd, buf, nbytes, - basep); + &waste); #elif defined(SYSIO_SYS_getdents64) syscall(SYSIO_SYS_getdents64, nino->ni_fd, buf, nbytes); #elif defined(SYSIO_SYS_getdents) @@ -989,24 +996,26 @@ native_filldirentries(struct native_inode *nino, if (cc < 0) return -errno; -#if DIR_STREAMED /* * Stream-oriented access requires that we discover where we are * after the call. */ - *basep = 0; - if ((err = native_pos(nino->ni_fd, basep, SEEK_CUR)) != 0) + if ((err = native_pos(nino->ni_fd, &nino->ni_fpos, SEEK_CUR)) != 0) { + /* + * Leave the position at the old I suppose. + */ + nino->ni_resetfpos = 1; return err; -#endif - nino->ni_fpos = *basep; + } + *posp = nino->ni_fpos; return cc; } static ssize_t -native_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) +native_filldirentries(struct inode *ino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes) { struct native_inode *nino = I2NI(ino); #if DIR_CVT_64 @@ -1016,12 +1025,6 @@ native_getdirentries(struct inode *ino, struct dirent64 *d64p; size_t namlen; size_t reclen; - /* - * Work-around for broken 64 bit basep update - * Get value of basep to return from last directory - * entry d_off value - */ - _SYSIO_OFF_T last_offset = *basep; #else #define bp buf #define count nbytes @@ -1038,7 +1041,7 @@ native_getdirentries(struct inode *ino, return -ENOMEM; } #endif - cc = native_filldirentries(nino, bp, count, basep); + cc = native_ifilldirentries(nino, posp, bp, count); if (cc < 0) { #if DIR_CVT_64 free(bp); @@ -1048,30 +1051,31 @@ native_getdirentries(struct inode *ino, #if DIR_CVT_64 ldp = (struct linux_dirent *)bp; d64p = (struct dirent64 *)buf; - for (;;) { - if (cc < 0 || (size_t )cc <= sizeof(*ldp)) - break; + while (cc) { namlen = strlen(ldp->ld_name); - reclen = sizeof(*d64p) - sizeof(d64p->d_name) + namlen + 1; - if (nbytes < reclen) + reclen = sizeof(*d64p) - sizeof(d64p->d_name) + namlen; + if (nbytes <= reclen) break; d64p->d_ino = ldp->ld_ino; - d64p->d_off = ldp->ld_off; + d64p->d_off = nino->ni_fpos = ldp->ld_off; d64p->d_reclen = - (((reclen + sizeof(long) - 1)) / sizeof(long)) * - sizeof(long); + (((reclen + sizeof(long))) / sizeof(long)) * sizeof(long); if (nbytes < d64p->d_reclen) - d64p->d_reclen = reclen; + d64p->d_reclen = reclen + 1; d64p->d_type = DT_UNKNOWN; /* you lose -- sorry. */ - (void )strncpy(d64p->d_name, ldp->ld_name, namlen); - *(d64p->d_name + namlen) = '\0'; + (void )memcpy(d64p->d_name, ldp->ld_name, namlen); + /* + * Zero pad the rest. + */ + for (cp = d64p->d_name + namlen, n = d64p->d_reclen - reclen; + n; + n--) + *cp++ = 0; cc -= ldp->ld_reclen; ldp = (struct linux_dirent *)((char *)ldp + ldp->ld_reclen); nbytes -= d64p->d_reclen; - last_offset = d64p->d_off; d64p = (struct dirent64 *)((char *)d64p + d64p->d_reclen); } - nino->ni_fpos = *basep = last_offset; free(bp); cc = (d64p == (struct dirent64 *)buf && cc) @@ -1223,6 +1227,7 @@ native_inop_open(struct pnode *pno, int flags, mode_t mode) /* * Invariant; First open. Must init. */ + nino->ni_resetfpos = 0; nino->ni_fpos = 0; nino->ni_fd = fd; /* @@ -1260,6 +1265,7 @@ native_inop_close(struct inode *ino) return -errno; nino->ni_fd = -1; + nino->ni_resetfpos = 0; nino->ni_fpos = 0; return 0; } @@ -1349,13 +1355,10 @@ dopio(void *buf, size_t count, _SYSIO_OFF_T off, struct native_io *nio) { ssize_t cc; - if (!(off == nio->nio_nino->ni_fpos || nio->nio_nino->ni_seekok)) - return -ESPIPE; - if (!nio->nio_nino->ni_seekok) { if (off != nio->nio_nino->ni_fpos) { /* - * They've done a p{read,write} or somesuch. Can't + * They're trying to reposition. Can't * seek on this descriptor so we err out now. */ errno = ESPIPE; @@ -1408,8 +1411,11 @@ doiov(const struct iovec *iov, int err; err = native_pos(nio->nio_nino->ni_fd, &off, SEEK_SET); - if (err) + if (err) { + nio->nio_nino->ni_resetfpos = 1; return err; + } + nio->nio_nino->ni_resetfpos = 0; nio->nio_nino->ni_fpos = off; } @@ -1745,6 +1751,7 @@ native_inop_ioctl(struct inode *ino, { struct native_inode *nino; long arg1, arg2, arg3, arg4; + int rtn; nino = I2NI(ino); assert(nino->ni_fd >= 0); @@ -1753,8 +1760,12 @@ native_inop_ioctl(struct inode *ino, arg3 = va_arg(ap, long); arg4 = va_arg(ap, long); - return syscall(SYSIO_SYS_ioctl, I2NI(ino)->ni_fd, request, - arg1, arg2, arg3, arg4); + rtn = + syscall(SYSIO_SYS_ioctl, I2NI(ino)->ni_fd, request, + arg1, arg2, arg3, arg4); + if (rtn < 0) + rtn = -errno; + return rtn; } #else static int @@ -1766,8 +1777,7 @@ native_inop_ioctl(struct inode *ino __IS_UNUSED, /* * I'm lazy. Maybe implemented later. */ - errno = ENOTTY; - return -1; + return -ENOTTY; } #endif diff --git a/libsysio/drivers/sockets/sockets.c b/libsysio/drivers/sockets/sockets.c index 3ac7894..d5d5c3c 100644 --- a/libsysio/drivers/sockets/sockets.c +++ b/libsysio/drivers/sockets/sockets.c @@ -65,8 +65,8 @@ #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "native.h" #include "fs.h" #include "inode.h" @@ -387,7 +387,7 @@ _sysio_sockets_inew() } int -socket(int domain, int type, int protocol) +SYSIO_INTERFACE_NAME(socket)(int domain, int type, int protocol) { int err; struct inode *ino; @@ -445,7 +445,7 @@ error: } int -accept(int s, struct sockaddr *addr, socklen_t *addrlen) +SYSIO_INTERFACE_NAME(accept)(int s, struct sockaddr *addr, socklen_t *addrlen) { int err; struct inode *ino; @@ -517,7 +517,9 @@ error: } int -bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) +SYSIO_INTERFACE_NAME(bind)(int sockfd, + const struct sockaddr *my_addr, + socklen_t addrlen) { int err; struct file *fil; @@ -553,7 +555,7 @@ out: } int -listen(int s, int backlog) +SYSIO_INTERFACE_NAME(listen)(int s, int backlog) { int err; struct file *fil; @@ -587,7 +589,9 @@ out: } int -connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) +SYSIO_INTERFACE_NAME(connect)(int sockfd, + const struct sockaddr *serv_addr, + socklen_t addrlen) { int err; struct file *fil; diff --git a/libsysio/drivers/yod/fs_yod.c b/libsysio/drivers/yod/fs_yod.c index c9bfcf3..6750ffb 100644 --- a/libsysio/drivers/yod/fs_yod.c +++ b/libsysio/drivers/yod/fs_yod.c @@ -160,10 +160,10 @@ static int yod_inop_setattr(struct pnode *pno, struct inode *ino, unsigned mask, struct intnl_stat *stbuf); -static ssize_t yod_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - off64_t *basep); +static ssize_t yod_filldirentries(struct inode *ino, + off64_t *posp, + char *buf, + size_t nbytes); static int yod_inop_mkdir(struct pnode *pno, mode_t mode); static int yod_inop_rmdir(struct pnode *pno); static int yod_inop_symlink(struct pnode *pno, const char *data); @@ -195,7 +195,7 @@ static struct inode_ops yod_i_ops = { yod_inop_lookup, yod_inop_getattr, yod_inop_setattr, - yod_getdirentries, + yod_filldirentries, yod_inop_mkdir, yod_inop_rmdir, yod_inop_symlink, @@ -412,7 +412,6 @@ error: _sysio_pb_gone(rootpb); if (fs) { FS_RELE(fs); - _sysio_fs_gone(fs); } return err; @@ -741,10 +740,10 @@ out: } static ssize_t -yod_getdirentries(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep) +yod_filldirentries(struct inode *ino, + char *buf, + _SYSIO_OFF_T *posp, + size_t nbytes) { struct yod_inode *nino = I2NI(ino); _SYSIO_OFF_T result; @@ -755,15 +754,19 @@ yod_getdirentries(struct inode *ino, result = *basep; if (*basep != nino->ni_fpos && (result = lseek_yod(nino->ni_fd, - *basep, + *posp, SEEK_SET) == -1)) return -errno; nino->ni_fpos = result; memset(buf, 0, nbytes); + /* + * This is almost certainly broken. The resulting position parameter + * points to the block just filled, not the next. + */ cc = getdirentries_yod(nino->ni_fd, buf, nbytes, &result); if (cc < 0) return -errno; - nino->ni_fpos = *basep = result; + nino->ni_fpos = *posp = result; return cc; } diff --git a/libsysio/include/dev.h b/libsysio/include/dev.h index a62f581..2620d49 100644 --- a/libsysio/include/dev.h +++ b/libsysio/include/dev.h @@ -80,11 +80,11 @@ extern const struct inode_ops _sysio_nodev_ops; struct inode *, \ unsigned , \ struct intnl_stat *))_sysio_do_ebadf -#define _sysio_nodev_getdirentries \ +#define _sysio_nodev_filldirentries \ (ssize_t (*)(struct inode *, \ + _SYSIO_OFF_T *, \ char *, \ - size_t , \ - _SYSIO_OFF_T *))_sysio_do_illop + size_t))_sysio_do_illop #define _sysio_nodev_inop_mkdir \ (int (*)(struct pnode *, \ mode_t))_sysio_do_illop diff --git a/libsysio/include/file.h b/libsysio/include/file.h index 82317d5..161b887 100644 --- a/libsysio/include/file.h +++ b/libsysio/include/file.h @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2003 Sandia Corporation. + * Cplant(TM) Copyright 1998-2005 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -46,6 +46,28 @@ */ /* + * Test whether large file support on this file. + */ +#ifdef O_LARGEFILE +#define _F_LARGEFILE(fil) \ + ((fil)->f_flags & O_LARGEFILE) +#else +#define _F_LARGEFILE(fil) \ + (1) +#endif +/* + * Return max seek value for this file. + */ +#define _SEEK_MAX(fil) \ + (_F_LARGEFILE(fil) ? _SYSIO_OFF_T_MAX : LONG_MAX) + +#if _LARGEFILE64_SOURCE +#define _SYSIO_FLOCK flock64 +#else +#define _SYSIO_FLOCK flock +#endif + +/* * A file record is maintained for each open file in the system. It holds * all the info necessary to track the context and parameters for the * operations that may be performed. @@ -64,7 +86,6 @@ struct file { do { \ (fil)->f_ref++; \ assert((fil)->f_ref); \ - I_REF((fil)->f_ino); \ } while (0) /* @@ -72,14 +93,10 @@ struct file { */ #define F_RELE(fil) \ do { \ - struct inode *ino; \ - \ assert((fil)->f_ref); \ (fil)->f_ref--; \ - ino = (fil)->f_ino; \ if (!(fil)->f_ref) \ _sysio_fgone(fil); \ - I_RELE(ino); \ } while (0) /* @@ -91,7 +108,7 @@ struct file { do { \ (fil)->f_ino = (ino); \ (fil)->f_pos = 0; \ - (fil)->f_ref = 1; \ + (fil)->f_ref = 0; \ (fil)->f_flags = (flags); \ } while (0) @@ -108,3 +125,7 @@ extern int _sysio_fd_close_all(void); #if ZERO_SUM_MEMORY extern void _sysio_fd_shutdown(void); #endif +extern _SYSIO_OFF_T _sysio_lseek_prepare(struct file *fil, + _SYSIO_OFF_T offset, + int whence, + _SYSIO_OFF_T max); diff --git a/libsysio/include/inode.h b/libsysio/include/inode.h index e6d9843..a825faf 100644 --- a/libsysio/include/inode.h +++ b/libsysio/include/inode.h @@ -86,10 +86,10 @@ struct inode_ops { struct inode *ino, unsigned mask, struct intnl_stat *stbuf); - ssize_t (*inop_getdirentries)(struct inode *ino, - char *buf, - size_t nbytes, - _SYSIO_OFF_T *basep); + ssize_t (*inop_filldirentries)(struct inode *ino, + _SYSIO_OFF_T *posp, + char *buf, + size_t nbytes); int (*inop_mkdir)(struct pnode *pno, mode_t mode); int (*inop_rmdir)(struct pnode *pno); int (*inop_symlink)(struct pnode *pno, const char *data); @@ -483,6 +483,7 @@ extern int _sysio_ioctx_cb(struct ioctx *ioctx, void *data); extern void _sysio_ioctx_cb_free(struct ioctx_callback *cb); extern struct ioctx *_sysio_ioctx_find(void *id); +extern int _sysio_ioctx_done(struct ioctx *ioctx); extern ssize_t _sysio_ioctx_wait(struct ioctx *ioctx); extern void _sysio_ioctx_complete(struct ioctx *ioctx); extern int _sysio_open(struct pnode *pno, int flags, mode_t mode); diff --git a/libsysio/include/module.mk b/libsysio/include/module.mk index 8f7b5f7..8a53f39 100644 --- a/libsysio/include/module.mk +++ b/libsysio/include/module.mk @@ -1,5 +1,5 @@ INCLUDE_EXTRA = include/dev.h include/file.h include/fs.h \ include/inode.h include/mount.h include/sysio.h include/sysio-cmn.h \ - include/sysio-symbols.h include/cplant-yod.h \ + include/sysio-cmn.h include/sysio-symbols.h include/cplant-yod.h \ include/module.mk include/xtio.h include/stddir.h \ include/native.h diff --git a/libsysio/include/sysio-cmn.h b/libsysio/include/sysio-cmn.h index 830f187..cd97756 100644 --- a/libsysio/include/sysio-cmn.h +++ b/libsysio/include/sysio-cmn.h @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2004 Sandia Corporation. + * Cplant(TM) Copyright 1998-2005 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -89,14 +89,18 @@ struct intnl_xtvec; struct iovec; + +#define _PREPEND_HELPER(p, x) \ + p ## x +#define PREPEND(p, x) \ + _PREPEND_HELPER(p, x) + /* * SYSIO name label macros */ -#define XPREPEND(p,x) p ## x -#define PREPEND(p,x) XPREPEND(p,x) -#define SYSIO_LABEL_NAMES 0 -#if SYSIO_LABEL_NAMES -#define SYSIO_INTERFACE_NAME(x) PREPEND(sysio__, x) +#ifdef SYSIO_LABEL_NAMES +#define SYSIO_INTERFACE_NAME(x) \ + PREPEND(SYSIO_LABEL_NAMES, x) #else #define SYSIO_INTERFACE_NAME(x) x #endif @@ -147,23 +151,36 @@ struct iovec; } while(0) /* Interface enter/leave hook functions */ -#if 0 -extern void _sysio_sysenter(); -extern void _sysio_sysleave(); - +#if SYSIO_TRACING +extern void *_sysio_entry_trace_q; +extern void *_sysio_exit_trace_q; + +extern void *_sysio_register_trace(void *q, + void (*)(const char *file, + const char *func, + int line)); +extern void _sysio_remove_trace(void *q, void *p); +extern void _sysio_run_trace_q(void *q, + const char *file, + const char *func, + int line); #define SYSIO_ENTER \ - do { \ - _sysio_sysenter(); \ - } while(0) + do { \ + _sysio_run_trace_q(_sysio_entry_trace_q, \ + __FILE__, __func__, __LINE__); \ + } while (0) + #define SYSIO_LEAVE \ - do { \ - _sysio_sysleave(); \ - } while(0) + do { \ + _sysio_run_trace_q(_sysio_exit_trace_q, \ + __FILE__, __func__, __LINE__); \ + } while (0) #else -#define SYSIO_ENTER -#define SYSIO_LEAVE - +#define SYSIO_ENTER \ + do { } while (0) +#define SYSIO_LEAVE \ + do { } while (0) #endif /* accounting for IO stats read and write char count */ diff --git a/libsysio/include/sysio.h b/libsysio/include/sysio.h index c6139d7..9d914b8 100644 --- a/libsysio/include/sysio.h +++ b/libsysio/include/sysio.h @@ -50,6 +50,15 @@ #include "sysio-cmn.h" +#if defined(_DIRENT_H) && _DIRENT_H +/* + * Need directory access routines too. + */ +#define _DECLARE_DIR_ACCESS 1 +#else +#define _DECLARE_DIR_ACCESS 0 +#endif + #ifndef PATH_SEPARATOR /* * Path separator. @@ -113,12 +122,16 @@ extern mode_t _sysio_umask; extern int _sysio_init(void); extern void _sysio_shutdown(void); -#if DEFER_INIT_CWD -extern int _sysio_boot(const char *buf, const char *path); -#else -extern int _sysio_boot(const char *buf); + +#if 0 +struct _sysio_boot_ctl { + const char *onam; + const char *oarg; +}; #endif +extern int _sysio_boot(const char *opt, const char *arg); + /* * Option-value pair information. */ @@ -138,6 +151,10 @@ extern char * _sysio_get_args(char *buf, struct option_value_info *vec); extern time_t _sysio_local_time(void); +#if SYSIO_TRACING +extern void _sysio_cprintf(const char *fmt, ...); +#endif + /* * The following should be defined by the system includes, and probably are, * but it's not illegal to have multiple externs, so long as they are the @@ -154,7 +171,11 @@ extern int SYSIO_INTERFACE_NAME(close)(int d); extern int SYSIO_INTERFACE_NAME(dup)(int oldfd); extern int SYSIO_INTERFACE_NAME(dup2)(int oldfd, int newfd); extern int SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...); +extern int SYSIO_INTERFACE_NAME(fcntl64)(int fd, int cmd, ...); extern int SYSIO_INTERFACE_NAME(fstat)(int fd, struct stat *buf); +#if _LARGEFILE64_SOURCE +extern int SYSIO_INTERFACE_NAME(fstat64)(int fd, struct stat64 *buf); +#endif extern int SYSIO_INTERFACE_NAME(fsync)(int fd); extern char *SYSIO_INTERFACE_NAME(getcwd)(char *buf, size_t size); extern off_t SYSIO_INTERFACE_NAME(lseek)(int fd, off_t offset, int whence); @@ -189,6 +210,22 @@ extern int SYSIO_INTERFACE_NAME(stat)(const char *path, struct stat *buf); #if _LARGEFILE64_SOURCE extern int SYSIO_INTERFACE_NAME(stat64)(const char *path, struct stat64 *buf); #endif +extern ssize_t SYSIO_INTERFACE_NAME(read)(int fd, void *buf, size_t count); +extern ssize_t SYSIO_INTERFACE_NAME(pread)(int fd, void *buf, size_t count, + off_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(readv)(int fd, + const struct iovec *iov, + int count); +extern ssize_t SYSIO_INTERFACE_NAME(write)(int fd, + const void *buf, + size_t count); +extern ssize_t SYSIO_INTERFACE_NAME(pwrite)(int fd, + const void *buf, + size_t count, + off_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(writev)(int fd, + const struct iovec *iov, + int count); #ifdef _HAVE_STATVFS extern int SYSIO_INTERFACE_NAME(statvfs)(const char *path, struct statvfs *buf); #if _LARGEFILE64_SOURCE @@ -229,3 +266,21 @@ extern int SYSIO_INTERFACE_NAME(mount)(const char *source, const char *target, unsigned long mountflags, const void *data); extern int SYSIO_INTERFACE_NAME(umount)(const char *target); +#if _DECLARE_DIR_ACCESS +extern DIR *SYSIO_INTERFACE_NAME(opendir)(const char *name); +extern int SYSIO_INTERFACE_NAME(closedir)(DIR *dir); +extern struct dirent *SYSIO_INTERFACE_NAME(readdir)(DIR *dir); +extern int SYSIO_INTERFACE_NAME(scandir)(const char *dir, + struct dirent ***namelist, + int(*filter)(const struct dirent *), + int(*compar)(const void *, + const void *)); +#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) +extern ssize_t SYSIO_INTERFACE_NAME(getdirentries)(int fd, + char *buf, + size_t nbytes, + off_t *basep); +#endif +#endif /* _DECLARE_DIR_ACCESS */ + +#undef _DECLARE_DIR_ACCESS diff --git a/libsysio/include/xtio.h b/libsysio/include/xtio.h index 87cf981..5f9050d 100644 --- a/libsysio/include/xtio.h +++ b/libsysio/include/xtio.h @@ -49,6 +49,17 @@ #ifndef _XTIO_H_ #define _XTIO_H_ +/* + * When compiled for use with libsysio, this allows one to move all the + * externals to a distinct namespace. When not, we want it to do nothing. + * + * NB: The choice of macro name here is dangerous. It's in the global + * namespace! We should fix that one of these days. + */ +#if !defined(SYSIO_INTERFACE_NAME) +#define SYSIO_INTERFACE_NAME(_n) _n +#endif + #ifndef _IOID_T_DEFINED #define _IOID_T_DEFINED typedef void *ioid_t; @@ -80,80 +91,80 @@ struct iovec; /* * Get status of previously posted async file IO operation. */ -extern int iodone(ioid_t ioid); +extern int SYSIO_INTERFACE_NAME(iodone)(ioid_t ioid); /* * Wait for completion of a previously posted asynch file IO request. */ -extern ssize_t iowait(ioid_t ioid); +extern ssize_t SYSIO_INTERFACE_NAME(iowait)(ioid_t ioid); /* * Post asynch read into buffers mapped by an iovec from file at given offset. */ -extern ioid_t ipreadv(int fd, - const struct iovec *iov, - size_t count, - off_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipreadv)(int fd, + const struct iovec *iov, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Post asynch read into buffers mapped by an iovec from file at given offset. */ -extern ioid_t ipread64v(int fd, - const struct iovec *iov, - size_t count, - off64_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipread64v)(int fd, + const struct iovec *iov, + size_t count, + off64_t offset); #endif /* * Post asynch read into buffer from file at given offset. */ -extern ioid_t ipread(int fd, - void *buf, - size_t count, - off_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipread)(int fd, + void *buf, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Post asynch read into buffer from file at given offset. */ -extern ioid_t ipread64(int fd, - void *buf, - size_t count, - off64_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipread64)(int fd, + void *buf, + size_t count, + off64_t offset); #endif /* * Read into buffers mapped by an iovec from file at given offset. */ -extern ssize_t preadv(int fd, - const struct iovec *iov, - size_t count, - off_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(preadv)(int fd, + const struct iovec *iov, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Read into buffers mapped by an iovec from file at given offset. */ -extern ssize_t pread64v(int fd, - const struct iovec *iov, - size_t count, - off64_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(pread64v)(int fd, + const struct iovec *iov, + size_t count, + off64_t offset); #endif /* * Post asynch read into buffers mapped by an iovec. */ -extern ioid_t ireadv(int fd, - const struct iovec *iov, - int count); +extern ioid_t SYSIO_INTERFACE_NAME(ireadv)(int fd, + const struct iovec *iov, + int count); /* * Read into buffer. */ -extern ioid_t iread(int fd, - void *buf, - size_t count); +extern ioid_t SYSIO_INTERFACE_NAME(iread)(int fd, + void *buf, + size_t count); /* * Post async read into buffers mapped by iovec from regions mapped @@ -161,11 +172,11 @@ extern ioid_t iread(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ioid_t ireadx(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec *xtv, - size_t xtv_count); +extern ioid_t SYSIO_INTERFACE_NAME(ireadx)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec *xtv, + size_t xtv_count); #ifdef __USE_LARGEFILE64 /* @@ -174,11 +185,11 @@ extern ioid_t ireadx(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ioid_t iread64x(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec64 *xtv, - size_t xtv_count); +extern ioid_t SYSIO_INTERFACE_NAME(iread64x)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec64 *xtv, + size_t xtv_count); #endif /* @@ -187,11 +198,11 @@ extern ioid_t iread64x(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ssize_t readx(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec *xtv, - size_t xtv_count); +extern ssize_t SYSIO_INTERFACE_NAME(readx)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec *xtv, + size_t xtv_count); #ifdef __USE_LARGEFILE64 /* @@ -200,79 +211,79 @@ extern ssize_t readx(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ssize_t read64x(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec64 *xtv, - size_t xtv_count); +extern ssize_t SYSIO_INTERFACE_NAME(read64x)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec64 *xtv, + size_t xtv_count); #endif /* * Post asynch write from buffers mapped by an iovec to file at given offset. */ -extern ioid_t ipwritev(int fd, - const struct iovec *iov, - size_t count, - off_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipwritev)(int fd, + const struct iovec *iov, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Post asynch write from buffers mapped by an iovec to file at given offset. */ -extern ioid_t ipwrite64v(int fd, - const struct iovec *iov, - size_t count, - off64_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipwrite64v)(int fd, + const struct iovec *iov, + size_t count, + off64_t offset); #endif /* * Post asynch write from buffer to file at given offset. */ -extern ioid_t ipwrite(int fd, - const void *buf, - size_t count, - off_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipwrite)(int fd, + const void *buf, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Post asynch write from buffer to file at given offset. */ -extern ioid_t ipwrite64(int fd, - const void *buf, - size_t count, - off64_t offset); +extern ioid_t SYSIO_INTERFACE_NAME(ipwrite64)(int fd, + const void *buf, + size_t count, + off64_t offset); #endif /* * Write from buffers mapped by an iovec to file at given offset. */ -extern ssize_t pwritev(int fd, - const struct iovec *iov, - size_t count, - off_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(pwritev)(int fd, + const struct iovec *iov, + size_t count, + off_t offset); #if _LARGEFILE64_SOURCE /* * Write from buffers mapped by an iovec to file at given offset. */ -extern ssize_t pwrite64v(int fd, - const struct iovec *iov, - size_t count, - off64_t offset); +extern ssize_t SYSIO_INTERFACE_NAME(pwrite64v)(int fd, + const struct iovec *iov, + size_t count, + off64_t offset); #endif /* * Post asynch write from buffer to file at given offset. */ -extern ioid_t iwritev(int fd, - const struct iovec *iov, - int count); +extern ioid_t SYSIO_INTERFACE_NAME(iwritev)(int fd, + const struct iovec *iov, + int count); /* * Write from buffer to file at given offset. */ -extern ioid_t iwrite(int fd, - const void *buf, - size_t count); +extern ioid_t SYSIO_INTERFACE_NAME(iwrite)(int fd, + const void *buf, + size_t count); /* * Post async write from buffers mapped by iovec to regions mapped @@ -280,11 +291,11 @@ extern ioid_t iwrite(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ioid_t iwritex(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec *xtv, - size_t xtv_count); +extern ioid_t SYSIO_INTERFACE_NAME(iwritex)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec *xtv, + size_t xtv_count); #ifdef __USE_LARGEFILE64 /* @@ -293,11 +304,11 @@ extern ioid_t iwritex(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ioid_t iwrite64x(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec64 *xtv, - size_t xtv_count); +extern ioid_t SYSIO_INTERFACE_NAME(iwrite64x)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec64 *xtv, + size_t xtv_count); #endif /* @@ -306,11 +317,11 @@ extern ioid_t iwrite64x(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ssize_t writex(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec *xtv, - size_t xtv_count); +extern ssize_t SYSIO_INTERFACE_NAME(writex)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec *xtv, + size_t xtv_count); #ifdef __USE_LARGEFILE64 /* @@ -319,10 +330,10 @@ extern ssize_t writex(int fd, * * NB: An adaptation of "listio" from Argonne's PVFS. */ -extern ssize_t write64x(int fd, - const struct iovec *iov, - size_t iov_count, - const struct xtvec64 *xtv, - size_t xtv_count); +extern ssize_t SYSIO_INTERFACE_NAME(write64x)(int fd, + const struct iovec *iov, + size_t iov_count, + const struct xtvec64 *xtv, + size_t xtv_count); #endif #endif /* ! _XTIO_H_ */ diff --git a/libsysio/src/dev.c b/libsysio/src/dev.c index 046e35f..7fca77a 100644 --- a/libsysio/src/dev.c +++ b/libsysio/src/dev.c @@ -56,7 +56,7 @@ const struct inode_ops _sysio_nodev_ops = { _sysio_nodev_inop_lookup, _sysio_nodev_inop_getattr, _sysio_nodev_inop_setattr, - _sysio_nodev_getdirentries, + _sysio_nodev_filldirentries, _sysio_nodev_inop_mkdir, _sysio_nodev_inop_rmdir, _sysio_nodev_inop_symlink, diff --git a/libsysio/src/dup.c b/libsysio/src/dup.c index 947d7f0..ba3d24c 100644 --- a/libsysio/src/dup.c +++ b/libsysio/src/dup.c @@ -59,16 +59,6 @@ SYSIO_INTERFACE_NAME(dup2)(int oldfd, int newfd) SYSIO_INTERFACE_ENTER; if (newfd < 0) SYSIO_INTERFACE_RETURN(-1, -EBADF); - - if (oldfd == newfd) { - struct file *fil; - - fil = _sysio_fd_find(oldfd); - if (!(fil && fil->f_ino)) - SYSIO_INTERFACE_RETURN(-1, -EBADF); - SYSIO_INTERFACE_RETURN(newfd, 0); - } - fd = _sysio_fd_dup(oldfd, newfd, 1); SYSIO_INTERFACE_RETURN(fd < 0 ? -1 : fd, fd < 0 ? fd : 0); } diff --git a/libsysio/src/fcntl.c b/libsysio/src/fcntl.c index 22e9382..68ce4de 100644 --- a/libsysio/src/fcntl.c +++ b/libsysio/src/fcntl.c @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2003 Sandia Corporation. + * Cplant(TM) Copyright 1998-2005 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -41,8 +41,11 @@ * lee@sandia.gov */ +#include #include +#include #include +#include #include #include #include @@ -56,9 +59,11 @@ #ifdef HAVE_LUSTRE_HACK #include #include +#endif +#ifdef HAVE_LUSTRE_HACK static int -_sysio_fcntl(int fd, int cmd, va_list ap, int *rtn) +_sysio_lustre_fcntl(int fd, int cmd, va_list ap, int *rtn) { long arg = va_arg(ap, long); @@ -67,13 +72,92 @@ _sysio_fcntl(int fd, int cmd, va_list ap, int *rtn) } #endif -int -SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...) +static int +_sysio_fcntl_raw_call(struct inode *ino, int *r, int cmd, ...) +{ + va_list ap; + int err; + + va_start(ap, cmd); + err = ino->i_ops.inop_fcntl(ino, cmd, ap, r); + va_end(ap); + return err; +} + +/* + * Convert offsets to absolute, when appropriate, and call appropriate driver + * to complete the fcntl lock function. If successful, convert + * returned values back to appropriate form. + */ +static int +_sysio_fcntl_lock(struct file *fil, int cmd, struct _SYSIO_FLOCK *fl) +{ + struct _SYSIO_FLOCK flock; + _SYSIO_OFF_T pos; + int err; + int rtn; + + /* + * The drivers will not have a clue as to the + * current position of the file pointer. We need to + * convert relative whence values to absolute + * file adresses for them, then. + */ + flock = *fl; + switch (flock.l_whence) { + case SEEK_SET: + /* + * At least parameter check this one, too. + */ + case SEEK_CUR: + case SEEK_END: + pos = + _sysio_lseek_prepare(fil, + flock.l_start, + flock.l_whence, + _SEEK_MAX(fil)); + if (pos < 0) + return (int )pos; + flock.l_start = pos; + flock.l_whence = SEEK_SET; + break; + default: + return -EINVAL; + } + err = + _sysio_fcntl_raw_call(fil->f_ino, &rtn, cmd, &flock); + if (err) + return err; + /* + * Ugh, convert back to relative form. + */ + switch (fl->l_whence) { + case SEEK_SET: + break; + case SEEK_CUR: + fl->l_start = flock.l_start; + fl->l_start -= fil->f_pos; + break; + case SEEK_END: + fl->l_start = flock.l_start; + fl->l_start -= + fil->f_ino->i_stbuf.st_size; + break; + default: + abort(); + } + /* + * Return success. + */ + return 0; +} + +static int +_sysio_vfcntl(int fd, int cmd, va_list ap) { int err; int rtn; struct file *fil; - va_list ap; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; @@ -81,12 +165,9 @@ SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...) fil = _sysio_fd_find(fd); if (!fil) { #ifdef HAVE_LUSTRE_HACK - va_start(ap, cmd); - err = _sysio_fcntl(fd, cmd, ap, &rtn); - va_end(ap); + err = _sysio_lustre_fcntl(fd, cmd, ap, &rtn); goto out; #else - rtn = -1; err = -EBADF; goto out; @@ -99,9 +180,7 @@ SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...) { long newfd; - va_start(ap, cmd); newfd = va_arg(ap, long); - va_end(ap); if (newfd != (int )newfd || newfd < 0) { rtn = -1; err = -EBADF; @@ -114,10 +193,79 @@ SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...) } } break; +#if !(_LARGEFILE64_SOURCE || F_GETLK64 == F_GETLK) + case F_GETLK: + case F_SETLK: + case F_SETLKW: + { + struct intnl_stat buf; + struct flock *fl; +#if _LARGEFILE64_SOURCE + struct _SYSIO_FLOCK flock64; +#endif + + /* + * Refresh the cached attributes. + */ + err = + fil->f_ino->i_ops.inop_getattr(NULL, + fil->f_ino, + &buf); + if (err) { + rtn = -1; + break; + } + /* + * Copy args to a temp and normalize. + */ + fl = va_arg(ap, struct flock *); +#if _LARGEFILE64_SOURCE + flock64.l_type = fl->l_type; + flock64.l_whence = fl->l_whence; + flock64.l_start = fl->l_start; + flock64.l_len = fl->l_len; + flock64.l_pid = fl->l_pid; + err = _sysio_fcntl_lock(fil, cmd, &flock64); +#else + err = _sysio_fcntl_lock(fil, cmd, fl); +#endif + if (err < 0) { + rtn = -1; + break; + } +#if _LARGEFILE64_SOURCE + /* + * Copy back. Note that the fcntl_lock call + * should have ensured that no overflow was possible. + */ + fl->l_type = flock64.l_type; + fl->l_whence = flock64.l_whence; + fl->l_start = flock64.l_start; + assert(fl->l_start == flock64.l_start); + fl->l_len = flock64.l_len; + assert(fl->l_len == flock64.l_len); + fl->l_pid = flock64.l_pid; +#endif + rtn = 0; + } + break; +#endif /* !(_LARGEFILE64_SOURCE || F_GETLK64 == F_GETLK) */ +#if _LARGEFILE64_SOURCE + case F_GETLK64: + case F_SETLK64: + case F_SETLKW64: + { + struct flock64 *fl64; + + fl64 = va_arg(ap, struct flock64 *); + err = _sysio_fcntl_lock(fil, cmd, fl64); + if (err) + rtn = -1; + } + break; +#endif default: - va_start(ap, cmd); err = fil->f_ino->i_ops.inop_fcntl(fil->f_ino, cmd, ap, &rtn); - va_end(ap); break; } @@ -125,6 +273,21 @@ out: SYSIO_INTERFACE_RETURN(rtn, err); } +int +SYSIO_INTERFACE_NAME(fcntl)(int fd, int cmd, ...) +{ + va_list ap; + int err; + + va_start(ap, cmd); + err = _sysio_vfcntl(fd, cmd, ap); + va_end(ap); + return err; +} + +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(fcntl), + SYSIO_INTERFACE_NAME(fcntl64)) + #ifdef __GLIBC__ #undef __fcntl sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(fcntl), diff --git a/libsysio/src/file.c b/libsysio/src/file.c index a346413..fbd91d8 100644 --- a/libsysio/src/file.c +++ b/libsysio/src/file.c @@ -75,7 +75,8 @@ _sysio_fnew(struct inode *ino, int flags) return NULL; _SYSIO_FINIT(fil, ino, flags); - I_REF(ino); + F_REF(fil); + I_REF(fil->f_ino); return fil; } @@ -92,6 +93,7 @@ _sysio_fgone(struct file *fil) assert(fil->f_ino); err = (*fil->f_ino->i_ops.inop_close)(fil->f_ino); assert(!err); + I_RELE(fil->f_ino); free(fil); } @@ -272,7 +274,7 @@ _sysio_fd_dup(int oldfd, int newfd, int force) struct file *fil; int fd; - if (oldfd == newfd) + if (oldfd == newfd && oldfd >= 0) return newfd; fil = _sysio_fd_find(oldfd); diff --git a/libsysio/src/file_hack.c b/libsysio/src/file_hack.c index 13e5c5d..c09a97d 100644 --- a/libsysio/src/file_hack.c +++ b/libsysio/src/file_hack.c @@ -106,6 +106,7 @@ _sysio_fnew(struct inode *ino, int flags) return NULL; _SYSIO_FINIT(fil, ino, flags); + F_REF(fil); I_REF(ino); return fil; @@ -122,6 +123,7 @@ _sysio_fgone(struct file *fil) assert(!fil->f_ref); assert(fil->f_ino); err = (*fil->f_ino->i_ops.inop_close)(fil->f_ino); + I_RELE(fil->f_ino); assert(!err); free(fil); } @@ -361,8 +363,8 @@ _sysio_fd_dup(int oldfd, int newfd, int force) init_oftab(); - if (oldfd == newfd) - return 0; + if (oldfd == newfd && oldfd >= 0) + return newfd; fil = _sysio_fd_find(oldfd); if (!fil) diff --git a/libsysio/src/getdirentries.c b/libsysio/src/getdirentries.c index d78f04e..aa25cd8 100644 --- a/libsysio/src/getdirentries.c +++ b/libsysio/src/getdirentries.c @@ -85,6 +85,28 @@ #endif static ssize_t +filldirents(struct file *fil, + char *buf, size_t nbytes, + _SYSIO_OFF_T *__restrict basep) +{ + _SYSIO_OFF_T opos; + ssize_t cc; + + if (!S_ISDIR(fil->f_ino->i_stbuf.st_mode)) + return -ENOTDIR; + + opos = fil->f_pos; + cc = + (*fil->f_ino->i_ops.inop_filldirentries)(fil->f_ino, + &fil->f_pos, + buf, nbytes); + if (cc < 0) + return cc; + *basep = opos; + return cc; +} + +static ssize_t PREPEND(_, SYSIO_INTERFACE_NAME(getdirentries64))(int fd, char *buf, size_t nbytes, @@ -99,16 +121,9 @@ PREPEND(_, SYSIO_INTERFACE_NAME(getdirentries64))(int fd, fil = _sysio_fd_find(fd); if (!(fil && fil->f_ino)) - SYSIO_INTERFACE_RETURN(-1, -EBADF); - - if (!S_ISDIR(fil->f_ino->i_stbuf.st_mode)) - SYSIO_INTERFACE_RETURN(-1, -ENOTDIR); + return -EBADF; - cc = - (*fil->f_ino->i_ops.inop_getdirentries)(fil->f_ino, - buf, - nbytes, - basep); + cc = filldirents(fil, buf, nbytes, basep); SYSIO_INTERFACE_RETURN(cc < 0 ? -1 : cc, cc < 0 ? (int )cc : 0); } @@ -137,6 +152,17 @@ sysio_sym_strong_alias(PREPEND(_, SYSIO_INTERFACE_NAME(getdirentries64)), ((((n) + (boundary) - 1 ) / (boundary)) * (boundary)) #endif +#define _dbaselen ((size_t )&((struct dirent *)0)->d_name[0]) + +#ifdef __GLIBC__ +#define _dreclen(namlen) \ + ((_dbaselen + (namlen) + __alignof__ (struct dirent)) & \ + ~(__alignof__ (struct dirent) - 1)) +#else /* !defined(__GLIBC__) */ +#define _dreclen(namlen) \ + _rndup(_dbaselen + (namlen) + 1, sizeof(int)) +#endif + #ifndef BSD ssize_t SYSIO_INTERFACE_NAME(getdirentries)(int fd, @@ -151,144 +177,83 @@ SYSIO_INTERFACE_NAME(getdirentries)(int fd, long * __restrict basep) #endif { - size_t inbytes; - void *ibuf; - _SYSIO_OFF_T ibase; - ssize_t cc; - struct dirent *dp, *nxtdp; -#if defined(BSD) - int off; -#endif - struct intnl_dirent *od64p, *d64p; - size_t n; - size_t reclen; + struct file *fil; + _SYSIO_OFF_T b; + ssize_t cc, count; + struct dirent64 *d64p, d64; + struct dirent *dp; + size_t n, reclen; + void *p; char *cp; SYSIO_INTERFACE_DISPLAY_BLOCK; -#define _dbaselen ((size_t )&((struct dirent *)0)->d_name[0]) - -#ifdef __GLIBC__ -#define _dreclen(namlen) \ - ((_dbaselen + (namlen) + __alignof__ (struct dirent)) & \ - ~(__alignof__ (struct dirent) - 1)) -#else /* !defined(__GLIBC__) */ -#define _dreclen(namlen) \ - _rndup(_dbaselen + (namlen) + 1, sizeof(int)) -#endif - -#if defined(__GLIBC__) -#define _fast_alloc(n) alloca(n) -#define _fast_free(p) -#else /* !defined(__GLIBC__) */ -#define _fast_alloc(n) malloc(n) -#define _fast_free(p) free(p) -#endif - SYSIO_INTERFACE_ENTER; -#if defined(BSD) - if (nbytes < 0) - SYSIO_INTERFACE_RETURN(-1, -EINVAL); -#endif - - inbytes = nbytes; - if (inbytes > 8 * 1024) { - /* - * Limit stack use. - */ - inbytes = 8 * 1024; - } - ibuf = _fast_alloc(inbytes); - if (!ibuf) - SYSIO_INTERFACE_RETURN(-1, -ENOMEM); - - dp = (struct dirent *)buf; - ibase = *basep; - cc = - PREPEND(_, SYSIO_INTERFACE_NAME(getdirentries64))(fd, - ibuf, - inbytes, - &ibase); - if (cc < 0) { - cc = -errno; - goto out; - } - *basep = (off_t )ibase; - if (sizeof(*basep) != sizeof(ibase) && *basep != ibase) { - cc = -EOVERFLOW; - goto out; - } + fil = _sysio_fd_find(fd); + if (!(fil && fil->f_ino)) + return -EBADF; -#if defined(BSD) - off = *basep; -#endif - od64p = NULL; - d64p = ibuf; - for (;;) { - if (!cc) - break; -#ifdef HAVE_D_NAMLEN - n = d64p->d_namlen; -#else - n = strlen(d64p->d_name); -#endif + count = cc = filldirents(fil, buf, nbytes, &b); + d64p = (void *)buf; + dp = (void *)buf; + reclen = 0; + while (cc > 0) { + n = _namlen(d64p); reclen = _dreclen(n); - if (reclen >= (unsigned )nbytes) - break; - dp->d_ino = (ino_t )d64p->d_ino; -#if !(defined(BSD)) - dp->d_off = (off_t )d64p->d_off; -#endif - if ((sizeof(dp->d_ino) != sizeof(d64p->d_ino) && - dp->d_ino != d64p->d_ino) - || -#if !(defined(BSD)) - (sizeof(dp->d_off) != sizeof(d64p->d_off) && - dp->d_off != d64p->d_off) -#else - (off + (int )reclen < off) -#endif - ) { - cc = -EOVERFLOW; + d64.d_ino = d64p->d_ino; + d64.d_off = d64p->d_off; + d64.d_type = d64p->d_type; + d64.d_reclen = d64p->d_reclen; + /* + * Copy name first. + */ + (void )memcpy(dp->d_name, d64p->d_name, n); + /* + * Then, the rest. + */ + dp->d_ino = d64.d_ino; + dp->d_off = d64.d_off; + if (dp->d_ino != d64.d_ino || + dp->d_off != d64.d_off) { + /* + * If conversion failure then we are done. + */ + if (cc == count) { + /* + * Couldn't process any entries. We return + * the error now. + */ + cc = - EOVERFLOW; + } break; } - dp->d_type = d64p->d_type; + fil->f_pos = dp->d_off; + dp->d_type = d64.d_type; dp->d_reclen = reclen; - nxtdp = (struct dirent *)((char *)dp + dp->d_reclen); - (void )memcpy(dp->d_name, d64p->d_name, n); - for (cp = dp->d_name + n; cp < (char *)nxtdp; *cp++ = '\0') - ; - cc -= d64p->d_reclen; - od64p = d64p; - d64p = (struct dirent64 *)((char *)d64p + d64p->d_reclen); - nbytes -= reclen; -#if defined(BSD) - off += reclen; + /* + * Fill the remainder with zeros. + */ + p = (char *)dp + dp->d_reclen; +#ifdef HAVE_D_NAMLEN + dp->d_namlen = n; #endif - dp = nxtdp; + cp = dp->d_name + n; + do { + *cp++ = 0; + } while (cp < (char *)p); + /* + * Advance. + */ + dp = p; + cc -= d64.d_reclen; + d64p = (struct dirent64 *)((char *)d64p + d64.d_reclen); } -out: - _fast_free(ibuf); - - if (dp == (struct dirent *)buf && cc < 0) - SYSIO_INTERFACE_RETURN(-1, (int )cc); + if (cc < 0) + SYSIO_INTERFACE_RETURN(-1, cc); cc = (char *)dp - buf; - if (cc) - *basep = -#if !(defined(BSD)) - od64p->d_off; -#else - off; -#endif + *basep = b; SYSIO_INTERFACE_RETURN(cc, 0); - -#ifdef __GLIBC__ -#undef _fast_alloc -#undef _fast_free -#endif -#undef _dreclen -#undef _dbaselen } #else /* !defined(DIRENT64_IS_NATURAL) */ sysio_sym_strong_alias(PREPEND(_, SYSIO_INTERFACE_NAME(getdirentries64), diff --git a/libsysio/src/init.c b/libsysio/src/init.c index ce253cc..b50ce12 100644 --- a/libsysio/src/init.c +++ b/libsysio/src/init.c @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2004 Sandia Corporation. + * Cplant(TM) Copyright 1998-2005 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -43,10 +43,19 @@ #define _BSD_SOURCE +#if SYSIO_TRACING +#include +#endif #include +#if SYSIO_TRACING +#include +#endif #include #include #include +#if SYSIO_TRACING +#include +#endif #include #include #include @@ -55,8 +64,11 @@ #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" +#if SYSIO_TRACING +#include "native.h" +#endif #include "inode.h" #include "fs.h" #include "mount.h" @@ -67,12 +79,55 @@ #include "stdfd.h" #endif +#if SYSIO_TRACING + +/* + * Tracing callback record. + */ +struct trace_callback { + TAILQ_ENTRY(trace_callback) links; + void (*f)(const char *file, const char *func, int line); +}; + +/* + * Initialize a tracing callback record. + */ +#define TCB_INIT(__tcb, __f) \ + do { \ + (__tcb)->f = (__f); \ + } while (0); + +/* + * Trace queue head record. + */ +TAILQ_HEAD(trace_q, trace_callback); + +/* + * The entry and exit queue heads, and queue pointers. + */ +static struct trace_q _sysio_entry_trace_head; +void *_sysio_entry_trace_q = &_sysio_entry_trace_head; +static struct trace_q _sysio_exit_trace_head; +void *_sysio_exit_trace_q = &_sysio_exit_trace_head; +#endif + /* * White space characters. */ #define IGNORE_WHITE " \t\r\n" /* + * Check if long overflows integer range. + */ +#if LONG_MAX <= INT_MAX +#define _irecheck(_l, _e) \ + ((_l) == LONG_MAX && (_e) == ERANGE) +#else +#define _irecheck(_l, _e) \ + ((_l) > INT_MAX) +#endif + +/* * Sysio library initialization. Must be called before anything else in the * library. */ @@ -81,7 +136,15 @@ _sysio_init() { int err; #ifdef WITH_SOCKETS - int _sysio_sockets_init(void); + extern int _sysio_sockets_init(void); +#endif + +#if SYSIO_TRACING + /* + * Initialize tracing callback queues. + */ + TAILQ_INIT(&_sysio_entry_trace_head); + TAILQ_INIT(&_sysio_exit_trace_head); #endif err = _sysio_ioctx_init(); @@ -134,9 +197,179 @@ _sysio_shutdown() _sysio_fd_shutdown(); _sysio_i_shutdown(); _sysio_fssw_shutdown(); +#if SYSIO_TRACING + { + struct trace_callback *tcb; + + /* + * Empty the trace queues and free the entries. + */ + while ((tcb = _sysio_entry_trace_head.tqh_first) != NULL) { + TAILQ_REMOVE(&_sysio_entry_trace_head, tcb, links); + free(tcb); + } + while ((tcb = _sysio_exit_trace_head.tqh_first) != NULL) { + TAILQ_REMOVE(&_sysio_exit_trace_head, tcb, links); + free(tcb); + } + } +#endif #endif } +#if SYSIO_TRACING + +#if !(defined(_HAVE_ASPRINTF) && _HAVE_ASPRINTF) +/* + * Print a string to allocated memory. + */ +static int +vasprintf(char **strp, const char *fmt, va_list ap) +{ + size_t siz; + int oerrno; + char *s; + va_list aq; + int n; + + siz = 50; + oerrno = errno; + if (!(s = malloc(siz))) { + errno = oerrno; + return -1; + } + for (;;) { + va_copy(aq, ap); + n = vsnprintf (s, siz, fmt, aq); + va_end(aq); + if (n > -1 && (size_t )n < siz) + break; + if (n > -1) /* glibc 2.1 */ + siz = n+1; /* precise */ + else /* glibc 2.0 */ + siz *= 2; /* twice the old */ + if (!(s = realloc (s, siz))) + break; + } + *strp = s; + errno = oerrno; + return n; +} + +#if 0 +static int +asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + int n; + + va_start(ap, fmt); + n = vasprintf(strp, fmt, ap); + va_end(ap); + return n; +} +#endif +#endif /* !(defined(_HAVE_ASPRINTF) && _HAVE_ASPRINTF) */ + +static void +_sysio_cwrite(const char *buf, size_t len) +{ + int oerrno; + + oerrno = errno; + (void )syscall(SYSIO_SYS_write, STDERR_FILENO, buf, len); + errno = oerrno; +} + +/* + * Console printf. + */ +void +_sysio_cprintf(const char *fmt, ...) +{ + va_list ap; + int len; + char *buf; + + va_start(ap, fmt); + buf = NULL; + len = vasprintf(&buf, fmt, ap); + va_end(ap); + if (len < 0) + return; + _sysio_cwrite(buf, len); + free(buf); +} + +/* + * Register a trace callback. + * + * The pointer to the trace record is returned. + */ +void * +_sysio_register_trace(void *q, + void (*f)(const char *file, + const char *func, + int line)) +{ + struct trace_callback *tcb; + + tcb = malloc(sizeof(struct trace_callback)); + if (!tcb) + return NULL; + TCB_INIT(tcb, f); + TAILQ_INSERT_TAIL((struct trace_q *)q, tcb, links); + return tcb; +} + +/* + * Remove a registered trace callback. + */ +void +_sysio_remove_trace(void *q, void *p) +{ + + TAILQ_REMOVE((struct trace_q *)q, (struct trace_callback *)p, links); + free(p); +} + +void +/* + * Run a trace queue, making all the callbacks. + */ +_sysio_run_trace_q(void *q, + const char *file, + const char *func, + int line) +{ + struct trace_callback *tcb; + + tcb = ((struct trace_q *)q)->tqh_first; + while (tcb) { + (*tcb->f)(file, func, line); + tcb = tcb->links.tqe_next; + } +} + +static void +_sysio_trace_entry(const char *file __IS_UNUSED, + const char *func, + int line __IS_UNUSED) +{ + + _sysio_cprintf("+ENTER+ %s\n", func); +} + +static void +_sysio_trace_exit(const char *file __IS_UNUSED, + const char *func, + int line __IS_UNUSED) +{ + + _sysio_cprintf("+EXIT+ %s\n", func); +} +#endif /* defined(SYSIO_TRACING) */ + /* * (kind of)Duplicates strtok function. * @@ -581,17 +814,6 @@ do_open(char *args) int err; struct file *fil; -/* - * Check if long overflows integer range. - */ -#if LONG_MAX <= INT_MAX -#define _irecheck(_l, _e) \ - ((_l) == LONG_MAX && (_e) == ERANGE) -#else -#define _irecheck(_l, _e) \ - ((_l) > INT_MAX) -#endif - len = strlen(args); if (_sysio_get_args(args, v) - args != (ssize_t )len || !(v[0].ovi_value && v[1].ovi_value && v[2].ovi_value)) @@ -634,8 +856,6 @@ do_open(char *args) if (pno) P_RELE(pno); return err; - -#undef _irecheck } /* @@ -668,38 +888,76 @@ do_command(char *buf) return -EINVAL; } +#if SYSIO_TRACING /* - * Given a command sequence buffer, parse it and run the given - * commands + * Set/Unset tracing. */ -int -_sysio_boot(const char *buf -#if DEFER_INIT_CWD - , const char *path +static int +_sysio_boot_tracing(const char *arg) +{ + long l; + char *cp; + static struct trace_callback + *entcb = NULL, + *exitcb = NULL; + + l = 0; + if (arg) { + l = strtol(arg, (char **)&cp, 0); + if (*cp || !(l == 0 || l == 1)) + return -EINVAL; + } + if (l) { + if (entcb == NULL) + entcb = + _sysio_register_trace(_sysio_entry_trace_q, + _sysio_trace_entry); + if (entcb == NULL) + return -errno; + if (exitcb == NULL) + exitcb = + _sysio_register_trace(_sysio_exit_trace_q, + _sysio_trace_exit); + if (exitcb == NULL) + return -errno; + } else { + if (entcb != NULL) + _sysio_remove_trace(_sysio_entry_trace_q, entcb); + entcb = NULL; + if (exitcb != NULL) + _sysio_remove_trace(_sysio_exit_trace_q, exitcb); + exitcb = NULL; + } + return 0; +} #endif - ) + +/* + * Initialize the namespace. + */ +static int +_sysio_boot_namespace(const char *arg) { char c, *tok; ssize_t len; int err; - - if (!buf) - buf = ""; + unsigned count; /* * Allocate token buffer. */ - len = strlen(buf); + len = strlen(arg); tok = malloc(len ? len : 1); if (!tok) return -ENOMEM; err = 0; + count = 0; while (1) { /* * Discard leading white space. */ - while ((c = *buf) != '\0' && + while ((c = *arg) != '\0' && !(c == '{' || strchr(IGNORE_WHITE, c) == NULL)) - buf++; + arg++; if (c == '\0') break; if (c != '{') { @@ -709,16 +967,18 @@ _sysio_boot(const char *buf /* * Get the command. */ - buf = - (char *)_sysio_get_token(buf + 1, + *tok = '\0'; + arg = + (char *)_sysio_get_token(arg + 1, 0, "}", IGNORE_WHITE, tok); - if (!buf) { + if (!arg) { err = -EINVAL; break; } + count++; /* * Perform. */ @@ -726,11 +986,63 @@ _sysio_boot(const char *buf if (err) break; } - free(tok); -#if DEFER_INIT_CWD +#if SYSIO_TRACING if (err) - return err; - _sysio_init_cwd = path; + _sysio_cprintf("+NS init+ failed at expr %u (last = %s): %s\n", + count, + tok && *tok ? tok : "NULL", + strerror(-err)); #endif + free(tok); return err; } + +#if DEFER_INIT_CWD +/* + * Set deferred initial working directory. + */ +static int +_sysio_boot_cwd(const char *arg) +{ + + _sysio_init_cwd = arg; + return 0; +} +#endif + +/* + * Given an identifier and it's arguments, perform optional initializations. + */ +int +_sysio_boot(const char *opt, const char *arg) +{ + struct option_value_info vec[] = { +#if SYSIO_TRACING + { "trace", NULL }, /* tracing? */ +#endif + { "namespace", NULL }, /* init namespace? */ +#if DEFER_INIT_CWD + { "cwd", NULL }, /* init working dir */ +#endif + { NULL, NULL } + }; + struct option_value_info *v; + unsigned u; + static int (*f[])(const char *) = { +#if SYSIO_TRACING + _sysio_boot_tracing, +#endif + _sysio_boot_namespace, +#if DEFER_INIT_CWD + _sysio_boot_cwd, +#endif + NULL /* can't happen */ + }; + + for (v = vec, u = 0; v->ovi_name; v++, u++) + if (strcmp(v->ovi_name, opt) == 0) + break; + if (!v->ovi_name) + return -EINVAL; + return (*f[u])(arg); +} diff --git a/libsysio/src/ioctx.c b/libsysio/src/ioctx.c index 0bfd497..6c06654 100644 --- a/libsysio/src/ioctx.c +++ b/libsysio/src/ioctx.c @@ -44,14 +44,15 @@ #include #include #include +#include #include #include #include #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "inode.h" #if defined(REDSTORM) @@ -175,6 +176,21 @@ _sysio_ioctx_find(void *id) } /* + * Check if asynchronous IO operation is complete. + */ +int +_sysio_ioctx_done(struct ioctx *ioctx) +{ + + if (ioctx->ioctx_done) + return 1; + if (!(*ioctx->ioctx_ino->i_ops.inop_iodone)(ioctx)) + return 0; + ioctx->ioctx_done = 1; + return 1; +} + +/* * Wait for asynchronous IO operation to complete, return status * and dispose of the context. * @@ -189,9 +205,11 @@ _sysio_ioctx_wait(struct ioctx *ioctx) /* * Wait for async operation to complete. */ - while (!(ioctx->ioctx_done || - (*ioctx->ioctx_ino->i_ops.inop_iodone)(ioctx))) - ; + while (!_sysio_ioctx_done(ioctx)) { +#ifdef POSIX_PRIORITY_SCHEDULING + (void )sched_yield(); +#endif + } /* * Get status. @@ -228,7 +246,7 @@ _sysio_ioctx_complete(struct ioctx *ioctx) /* update IO stats */ - _SYSIO_UPDACCT(ioctx->ioctx_write, ioctx); + _SYSIO_UPDACCT(ioctx->ioctx_write, ioctx->ioctx_cc); /* * Run the call-back queue. diff --git a/libsysio/src/iowait.c b/libsysio/src/iowait.c index 4ed52db..939b921 100644 --- a/libsysio/src/iowait.c +++ b/libsysio/src/iowait.c @@ -68,10 +68,7 @@ SYSIO_INTERFACE_NAME(iodone)(void *ioid) if (!ioctx) SYSIO_INTERFACE_RETURN(-1, -EINVAL); - rc = - (ioctx->ioctx_done || - (*ioctx->ioctx_ino->i_ops.inop_iodone)(ioctx)); - + rc = _sysio_ioctx_done(ioctx); SYSIO_INTERFACE_RETURN(rc < 0 ? -1 : rc, rc < 0 ? rc : 0); } diff --git a/libsysio/src/link.c b/libsysio/src/link.c index bf0907b..638bd7e 100644 --- a/libsysio/src/link.c +++ b/libsysio/src/link.c @@ -84,7 +84,12 @@ SYSIO_INTERFACE_NAME(link)(const char *oldpath, const char *newpath) err = -EXDEV; goto error2; } - err = old->p_base->pb_ino->i_ops.inop_link(old, new); + /* + * Use the parent node operations to request the task in case the + * driver is implemented using differentiated inode operations based + * on file type, such as incore does. + */ + err = old->p_parent->p_base->pb_ino->i_ops.inop_link(old, new); if (err) goto error2; /* diff --git a/libsysio/src/lseek.c b/libsysio/src/lseek.c index 9c955dc..687071b 100644 --- a/libsysio/src/lseek.c +++ b/libsysio/src/lseek.c @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2003 Sandia Corporation. + * Cplant(TM) Copyright 1998-2005 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "sysio.h" @@ -54,17 +55,15 @@ #include "sysio-symbols.h" -static _SYSIO_OFF_T -_sysio_lseek(int fd, _SYSIO_OFF_T offset, int whence) +_SYSIO_OFF_T +_sysio_lseek_prepare(struct file *fil, + _SYSIO_OFF_T offset, + int whence, + _SYSIO_OFF_T max) { - struct file *fil; _SYSIO_OFF_T off, pos; struct intnl_stat stbuf; - fil = _sysio_fd_find(fd); - if (!fil) - return -EBADF; - off = -1; switch (whence) { @@ -99,14 +98,22 @@ _sysio_lseek(int fd, _SYSIO_OFF_T offset, int whence) pos = off + offset; if ((offset < 0 && -offset > off) || (offset > 0 && pos <= off)) return -EINVAL; - -#ifdef O_LARGEFILE - if (pos >= ((fil->f_flags & O_LARGEFILE) ? _SYSIO_OFF_T_MAX : LONG_MAX)) - return -EOVERFLOW; -#else - if (pos >= _SYSIO_OFF_T_MAX) + if (pos >= max) return -EOVERFLOW; -#endif + return pos; +} + +static _SYSIO_OFF_T +_sysio_lseek(struct file *fil, + _SYSIO_OFF_T offset, + int whence, + _SYSIO_OFF_T max) +{ + _SYSIO_OFF_T pos; + + pos = _sysio_lseek_prepare(fil, offset, whence, max); + if (pos < 0) + return pos; pos = (fil->f_ino->i_ops.inop_pos)(fil->f_ino, pos); if (pos < 0) return pos; @@ -120,17 +127,18 @@ _sysio_lseek(int fd, _SYSIO_OFF_T offset, int whence) extern off64_t SYSIO_INTERFACE_NAME(lseek64)(int fd, off64_t offset, int whence) { - _SYSIO_OFF_T off; - off64_t rtn; + struct file *fil; + off64_t off; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; - off = _sysio_lseek(fd, offset, whence); - if (off < 0) - SYSIO_INTERFACE_RETURN((off64_t )-1, (int )off); - rtn = (off64_t )off; - assert(rtn == off); - SYSIO_INTERFACE_RETURN(rtn, 0); + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN((off64_t )-1, -EBADF); + off = _sysio_lseek(fil, offset, whence, _SEEK_MAX(fil)); + SYSIO_INTERFACE_RETURN(off < 0 ? (off64_t )-1 : off, + off < 0 ? (int )off : 0); + } #ifdef __GLIBC__ #undef __lseek64 @@ -149,12 +157,16 @@ sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(lseek64), extern off_t SYSIO_INTERFACE_NAME(lseek)(int fd, off_t offset, int whence) { + struct file *fil; _SYSIO_OFF_T off; off_t rtn; SYSIO_INTERFACE_DISPLAY_BLOCK; SYSIO_INTERFACE_ENTER; - off = _sysio_lseek(fd, offset, whence); + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN((off_t )-1, -EBADF); + off = _sysio_lseek(fil, offset, whence, LONG_MAX); if (off < 0) SYSIO_INTERFACE_RETURN((off_t )-1, (int )off); rtn = (off_t )off; @@ -177,6 +189,7 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned int fd __IS_UNUSED, loff_t *result __IS_UNUSED, unsigned int whence __IS_UNUSED) { + struct file *fil; loff_t off; SYSIO_INTERFACE_DISPLAY_BLOCK; @@ -184,6 +197,9 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned int fd __IS_UNUSED, * This is just plain goofy. */ SYSIO_INTERFACE_ENTER; + fil = _sysio_fd_find(fd); + if (!fil) + SYSIO_INTERFACE_RETURN(-1, -EBADF); #if !_LARGEFILE64_SOURCE if (offset_high) { /* @@ -197,7 +213,7 @@ SYSIO_INTERFACE_NAME(llseek)(unsigned int fd __IS_UNUSED, off <<= 32; off |= offset_low; #endif - off = _sysio_lseek(fd, off, whence); + off = _sysio_lseek(fil, off, whence, _SEEK_MAX(fil)); if (off < 0) SYSIO_INTERFACE_RETURN((off_t )-1, (int )off); *result = off; diff --git a/libsysio/src/mount.c b/libsysio/src/mount.c index de46e08..9e8f9ea 100644 --- a/libsysio/src/mount.c +++ b/libsysio/src/mount.c @@ -53,8 +53,8 @@ #endif #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "fs.h" #include "mount.h" #include "inode.h" diff --git a/libsysio/src/namei.c b/libsysio/src/namei.c index 9dc7a15..6167189 100644 --- a/libsysio/src/namei.c +++ b/libsysio/src/namei.c @@ -186,19 +186,22 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) if (!parent) { const char *icwd; - if (!_sysio_init_cwd) + if (!_sysio_init_cwd && !nd->nd_root) abort(); /* - * Finally have to set the curretn working directory. We can + * Finally have to set the current working directory. We can * not tolerate errors here or else risk leaving the process * in a very unexpected location. We abort then unless all goes * well. */ icwd = _sysio_init_cwd; _sysio_init_cwd = NULL; - if (_sysio_namei(NULL, icwd, 0, NULL, &parent) != 0 || - _sysio_p_chdir(parent) != 0) + parent = nd->nd_root; + if (!parent) + abort(); + (void )_sysio_namei(nd->nd_root, icwd, 0, NULL, &parent); + if (_sysio_p_chdir(parent) != 0) abort(); } #endif @@ -257,8 +260,6 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) lpath[cc] = '\0'; /* NUL term */ /* * Handle symbolic links with recursion. Yuck! - * Pass the NULL intent for recursive symlink - * except the last component. */ ND_INIT(&nameidata, (nd->nd_flags | ND_NEGOK), diff --git a/libsysio/src/open.c b/libsysio/src/open.c index 5845009..2542d94 100644 --- a/libsysio/src/open.c +++ b/libsysio/src/open.c @@ -112,6 +112,10 @@ _sysio_open(struct pnode *pno, int flags, mode_t mode) err = -EEXIST; else if (!ino) err = _sysio_p_validate(pno, NULL, NULL); +#ifdef O_NOFOLLOW + else if (flags & O_NOFOLLOW && S_ISLNK(ino->i_stbuf.st_mode)) + err = -ELOOP; +#endif else { /* * Simple open of pre-existing file. @@ -162,13 +166,7 @@ SYSIO_INTERFACE_NAME(open)(const char *path, int flags, ...) #endif va_end(ap); mode &= ~(_sysio_umask & 0777) | 07000; /* apply umask */ - - if (flags & O_EXCL) { - /* - * Tell others we intend to create this file. - */ - intent.int_opmask |= INT_CREAT; - } + intent.int_opmask |= INT_CREAT; } #ifdef O_NOFOLLOW if (flags & O_NOFOLLOW) @@ -216,21 +214,25 @@ error: #ifdef __GLIBC__ #undef __open -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), __open) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), + PREPEND(__, SYSIO_INTERFACE_NAME(open))) #undef open64 sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), SYSIO_INTERFACE_NAME(open64)) #undef __open64 -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), __open64) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), + PREPEND(__, SYSIO_INTERFACE_NAME(open64))) #endif #ifdef REDSTORM #undef __libc_open64 -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), __libc_open64) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), + PREPEND(__, SYSIO_INTERFACE_NAME(libc_open64))) #endif #ifdef BSD #undef _open -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), _open) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(open), + PREPEND(_, SYSIO_INTERFACE_NAME(open))) #endif int @@ -246,43 +248,50 @@ SYSIO_INTERFACE_NAME(close)(int fd) #ifdef __GLIBC__ #undef __close -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(close), __close) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(close), + PREPEND(__, SYSIO_INTERFACE_NAME(close))) #endif #ifdef BSD #undef _close -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(close), _close) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(close), + PREPEND(_, SYSIO_INTERFACE_NAME(close))) #endif int SYSIO_INTERFACE_NAME(creat)(const char *path, mode_t mode) { - return open(path, O_CREAT|O_WRONLY|O_TRUNC, mode); + return SYSIO_INTERFACE_NAME(open)(path, O_CREAT|O_WRONLY|O_TRUNC, mode); } #ifdef __GLIBC__ #undef __creat -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), __creat) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), + PREPEND(__, SYSIO_INTERFACE_NAME(creat))) #undef creat64 #ifndef HAVE_LUSTRE_HACK sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), SYSIO_INTERFACE_NAME(creat64)) #else /* XXX workaround SuSE SLES 8, glibc-2.2.5 */ -sysio_sym_strong_alias(SYSIO_INTERFACE_NAME(creat), SYSIO_INTERFACE_NAME(creat64)) +sysio_sym_strong_alias(SYSIO_INTERFACE_NAME(creat), + SYSIO_INTERFACE_NAME(creat64)) #endif #undef __creat64 -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), __creat64) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), + PREPEND(__, SYSIO_INTERFACE_NAME(creat64))) #endif #ifdef REDSTORM #undef __libc_creat -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), __libc_creat) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), + PREPEND(__, SYSIO_INTERFACE_NAME(libc_creat))) #endif #ifdef BSD #undef _creat -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), _creat) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(creat), + PREPEND(_, SYSIO_INTERFACE_NAME(creat))) #endif mode_t @@ -297,5 +306,6 @@ SYSIO_INTERFACE_NAME(umask)(mode_t mask) #ifdef REDSTORM #undef __umask -sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(umask), __umask) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(umask), + PREPEND(__, SYSIO_INTERFACE_NAME(umask))) #endif diff --git a/libsysio/src/readdir.c b/libsysio/src/readdir.c index af21c16..c232b29 100644 --- a/libsysio/src/readdir.c +++ b/libsysio/src/readdir.c @@ -105,7 +105,7 @@ int _SCANDIR(const char *dirname, _DIRENT_T ***namelist, int (*filter) (const _DIRENT_T *), - int (*cmp) (const void *, const void *)) + int (*compar) (const void *, const void *)) { DIR *dir = NULL; _DIRENT_T *de = NULL, @@ -117,7 +117,7 @@ _SCANDIR(const char *dirname, SYSIO_INTERFACE_ENTER; - if ((dir = opendir(dirname)) == NULL) + if ((dir = SYSIO_INTERFACE_NAME(opendir)(dirname)) == NULL) SYSIO_INTERFACE_RETURN(-1, -errno); while ((de = _READDIR(dir)) != NULL) { @@ -137,12 +137,15 @@ _SCANDIR(const char *dirname, s[i++] = (_DIRENT_T *)memcpy(nextde, de, desize); } } - if (cmp) - qsort (s, i, sizeof (*s), cmp); + if (compar) + qsort (s, + i, + sizeof (*s), + (int (*)(const void *, const void *))compar); *namelist = s; - closedir(dir); + SYSIO_INTERFACE_NAME(closedir)(dir); SYSIO_INTERFACE_RETURN(i, 0); } diff --git a/libsysio/src/rename.c b/libsysio/src/rename.c index bf8724c..269516b8 100644 --- a/libsysio/src/rename.c +++ b/libsysio/src/rename.c @@ -161,7 +161,12 @@ SYSIO_INTERFACE_NAME(rename)(const char *oldpath, const char *newpath) err = -EBUSY; goto error1; } - err = old->p_base->pb_ino->i_ops.inop_rename(old, new); + /* + * Use the parent node operations to request the task in case the + * driver is implemented using differentiated inode operations based + * on file type, such as incore does. + */ + err = old->p_parent->p_base->pb_ino->i_ops.inop_rename(old, new); if (err) goto error1; /* diff --git a/libsysio/src/rmdir.c b/libsysio/src/rmdir.c index b26b16b..36df40c 100644 --- a/libsysio/src/rmdir.c +++ b/libsysio/src/rmdir.c @@ -68,6 +68,10 @@ SYSIO_INTERFACE_NAME(rmdir)(const char *path) err = _sysio_namei(_sysio_cwd, path, 0, &intent, &pno); if (err) goto out; + if (!S_ISDIR(pno->p_base->pb_ino->i_stbuf.st_mode)) { + err = -ENOTDIR; + goto error; + } if (IS_RDONLY(pno, pno->p_base->pb_ino)) { err = -EROFS; goto error; @@ -76,7 +80,12 @@ SYSIO_INTERFACE_NAME(rmdir)(const char *path) err = -EBUSY; goto error; } - err = pno->p_base->pb_ino->i_ops.inop_rmdir(pno); + /* + * Use the parent node operations to request the task in case the + * driver is implemented using differentiated inode operations based + * on file type, such as incore does. + */ + err = pno->p_parent->p_base->pb_ino->i_ops.inop_rmdir(pno); if (err) goto error; /* diff --git a/libsysio/src/rw.c b/libsysio/src/rw.c index bd4ae6b..e482379 100644 --- a/libsysio/src/rw.c +++ b/libsysio/src/rw.c @@ -50,8 +50,8 @@ #include #include -#include "xtio.h" #include "sysio.h" +#include "xtio.h" #include "file.h" #include "inode.h" @@ -773,7 +773,7 @@ SYSIO_INTERFACE_NAME(readx)(int fd, xtv, xtv_count)) == IOID_FAIL) return -1; - return iowait(ioid); + return SYSIO_INTERFACE_NAME(iowait)(ioid); } #if _LARGEFILE64_SOURCE @@ -791,7 +791,7 @@ SYSIO_INTERFACE_NAME(read64x)(int fd, xtv, xtv_count)) == IOID_FAIL) return -1; - return iowait(ioid); + return SYSIO_INTERFACE_NAME(iowait)(ioid); } #endif @@ -1298,7 +1298,7 @@ SYSIO_INTERFACE_NAME(writex)(int fd, xtv, xtv_count)) == IOID_FAIL) return -1; - return iowait(ioid); + return SYSIO_INTERFACE_NAME(iowait)(ioid); } #if _LARGEFILE64_SOURCE @@ -1316,7 +1316,7 @@ SYSIO_INTERFACE_NAME(write64x)(int fd, xtv, xtv_count)) == IOID_FAIL) return -1; - return iowait(ioid); + return SYSIO_INTERFACE_NAME(iowait)(ioid); } #endif diff --git a/libsysio/src/stddir.c b/libsysio/src/stddir.c index b41a9a1..41f589b 100644 --- a/libsysio/src/stddir.c +++ b/libsysio/src/stddir.c @@ -57,7 +57,7 @@ SYSIO_INTERFACE_NAME(opendir)(const char *name) if (!dir) SYSIO_INTERFACE_RETURN(NULL, -ENOMEM); - dir->fd = open(name, O_RDONLY); + dir->fd = SYSIO_INTERFACE_NAME(open)(name, O_RDONLY); if (dir->fd < 0) { free(dir); SYSIO_INTERFACE_RETURN(NULL, -errno); @@ -65,7 +65,8 @@ SYSIO_INTERFACE_NAME(opendir)(const char *name) return dir; } -sysio_sym_weak_alias(opendir, __opendir) +sysio_sym_weak_alias(SYSIO_INTERFACE_NAME(opendir), + PREPEND(__, SYSIO_INTERFACE_NAME(opendir))) int SYSIO_INTERFACE_NAME(closedir)(DIR *dir) diff --git a/libsysio/src/symlink.c b/libsysio/src/symlink.c index 1925466..a90aba0 100644 --- a/libsysio/src/symlink.c +++ b/libsysio/src/symlink.c @@ -76,6 +76,11 @@ SYSIO_INTERFACE_NAME(symlink)(const char *oldpath, const char *newpath) err = -EROFS; goto error; } + /* + * Use the parent node operations to request the task in case the + * driver is implemented using differentiated inode operations based + * on file type, such as incore does. + */ err = (*pno->p_parent->p_base->pb_ino->i_ops.inop_symlink)(pno, oldpath); error: diff --git a/libsysio/src/unlink.c b/libsysio/src/unlink.c index 197ddd6..c672651 100644 --- a/libsysio/src/unlink.c +++ b/libsysio/src/unlink.c @@ -73,7 +73,12 @@ SYSIO_INTERFACE_NAME(unlink)(const char *path) err = -EROFS; goto error; } - err = (*ino->i_ops.inop_unlink)(pno); + /* + * Use the parent node operations to request the task in case the + * driver is implemented using differentiated inode operations based + * on file type, such as incore does. + */ + err = (*pno->p_parent->p_base->pb_ino->i_ops.inop_unlink)(pno); if (err) goto error; assert(pno->p_base->pb_ino); diff --git a/libsysio/tests/Makefile.am b/libsysio/tests/Makefile.am index fcbadb1..0491ab0 100644 --- a/libsysio/tests/Makefile.am +++ b/libsysio/tests/Makefile.am @@ -1,6 +1,6 @@ noinst_PROGRAMS = test_copy test_stats test_path test_list \ test_getcwd test_link test_unlink test_rename \ - test_regions test_driver test_stddir + test_regions test_stddir test_fcntl_lock CLEANFILES=drv_data.c @@ -34,13 +34,6 @@ DRIVERS=$(NATIVE_DRIVER_NAME) $(INCORE_DRIVER_NAME) $(YOD_DRIVER_NAME) \ CMNSRC=startup.c drv_init_all.c drv_data.c BUILT_SOURCES=drv_data.c -check_PROGRAMS=test_driver -if TEST_ALPHA_ARG -TESTS_ENVIRONMENT=IS_ALPHA=yes -else -TESTS_ENVIRONMENT=IS_ALPHA=no -endif -TESTS=test_all.pl CFL=$(AM_CFLAGS) $(AM_CPPFLAGS) \ $(NATIVE_DRIVER_CFLAGS) $(INCORE_DRIVER_CFLAGS) \ @@ -50,59 +43,48 @@ LIBS=$(LIBBUILD_DIR)/libsysio.a test_copy_SOURCES=test_copy.c $(CMNSRC) test_copy_CFLAGS=$(CFL) -test_copy_LDADD=$(LIBS) test_copy_DEPENDENCIES=$(LIBS) test_stats_SOURCES=test_stats.c $(CMNSRC) test_stats_CFLAGS=$(CFL) -test_stats_LDADD=$(LIBS) test_stats_DEPENDENCIES=$(LIBS) test_path_SOURCES=test_path.c $(CMNSRC) test_path_CFLAGS=$(CFL) -test_path_LDADD=$(LIBS) test_path_DEPENDENCIES=$(LIBS) test_list_SOURCES=test_list.c $(CMNSRC) test_list_CFLAGS=$(CFL) -test_list_LDADD=$(LIBS) test_list_DEPENDENCIES=$(LIBS) test_getcwd_SOURCES=test_getcwd.c $(CMNSRC) test_getcwd_CFLAGS=$(CFL) -test_getcwd_LDADD=$(LIBS) test_getcwd_DEPENDENCIES=$(LIBS) test_link_SOURCES=test_link.c $(CMNSRC) test_link_CFLAGS=$(CFL) -test_link_LDADD=$(LIBS) test_link_DEPENDENCIES=$(LIBS) test_unlink_SOURCES=test_unlink.c $(CMNSRC) test_unlink_CFLAGS=$(CFL) -test_unlink_LDADD=$(LIBS) test_unlink_DEPENDENCIES=$(LIBS) test_rename_SOURCES=test_rename.c $(CMNSRC) test_rename_CFLAGS=$(CFL) -test_rename_LDADD=$(LIBS) test_rename_DEPENDENCIES=$(LIBS) test_regions_SOURCES=test_regions.c $(CMNSRC) test_regions_CFLAGS=$(CFL) -test_regions_LDADD=$(LIBS) test_regions_DEPENDENCIES=$(LIBS) -test_driver_SOURCES=test_driver.c sysio_tests.c sysio_stubs.c help.c $(CMNSRC) -test_driver_CFLAGS=$(CFL) -test_driver_LDADD=$(LIBS) -test_driver_DEPENDENCIES=$(LIBS) - test_stddir_SOURCES=test_stddir.c $(CMNSRC) test_stddir_CFLAGS=$(CFL) -test_stddir_LDADD=$(LIBS) test_stddir_DEPENDENCIES=$(LIBS) +test_fcntl_lock_SOURCES=test_fcntl_lock.c $(CMNSRC) +test_fcntl_lock_CFLAGS=$(CFL) +test_fcntl_lock_DEPENDENCIES=$(LIBS) + drv_data.c: $(CONFIG_DEPENDENCIES) $(top_srcdir)/tests/gendrvdata.sh test -z "drv_data.c" && rm -f drv_data.c; \ $(SHELL) $(top_srcdir)/tests/gendrvdata.sh $(DRIVERS) > drv_data.c diff --git a/libsysio/tests/module.mk b/libsysio/tests/module.mk index b6ed491..3ed43b0 100644 --- a/libsysio/tests/module.mk +++ b/libsysio/tests/module.mk @@ -1,2 +1,2 @@ -TESTS_EXTRA = $(shell ls tests/*.[ch] tests/*.sh tests/*.p[lm]) \ +TESTS_EXTRA = $(shell ls tests/*.[ch]) \ tests/Makefile.am tests/Makefile.in tests/module.mk diff --git a/libsysio/tests/startup.c b/libsysio/tests/startup.c index fcb54d4..764fa05 100644 --- a/libsysio/tests/startup.c +++ b/libsysio/tests/startup.c @@ -4,17 +4,16 @@ #include #include -#include "xtio.h" #include "test.h" #include "sysio.h" +#include "xtio.h" int _test_sysio_startup() { int err; - const char *cwd; - const char *s; + char *arg; err = _sysio_init(); if (err) @@ -22,30 +21,39 @@ _test_sysio_startup() err = drv_init_all(); if (err) return err; - s = getenv("SYSIO_NAMESPACE"); - if (!(s || (s = getenv("SYSIO_MANUAL")))) { +#if SYSIO_TRACING + /* + * tracing + */ + arg = getenv("SYSIO_TRACING"); + err = _sysio_boot("trace", arg); + if (err) + return err; +#endif + /* + * namespace + */ + arg = getenv("SYSIO_NAMESPACE"); + if (!(arg || (arg = getenv("SYSIO_MANUAL")))) { /* - * Assume a native mount at root. + * Assume a native mount at root with automounts enabled. */ - s = "{mnt,dev=\"native:/\",dir=/,fl=0}"; + arg = "{mnt,dev=\"native:/\",dir=/,fl=2}"; } - cwd = getenv("SYSIO_CWD"); -#if DEFER_INIT_CWD - err = _sysio_boot(s, cwd ? cwd : "/"); -#else - err = _sysio_boot(s); -#endif + err = _sysio_boot("namespace", arg); if (err) return err; - -#if !DEFER_INIT_CWD - if (!cwd) - s = "/"; - err = chdir(s); +#if DEFER_INIT_CWD + /* + * Current working directory. + */ + arg = getenv("SYSIO_CWD"); + if (!arg) + arg = "/"; + err = _sysio_boot("cwd", arg); if (err) return err; #endif - return 0; } diff --git a/libsysio/tests/sysio-run-start.c b/libsysio/tests/sysio-run-start.c index 409e94f..d09fba4 100644 --- a/libsysio/tests/sysio-run-start.c +++ b/libsysio/tests/sysio-run-start.c @@ -17,10 +17,10 @@ _sysio_startup() if (err) { errno = -err; perror("sysio startup"); - exit(1); + abort(); } if (atexit(_test_sysio_shutdown) != 0) { perror("atexit"); - exit(1); + abort(); } } diff --git a/libsysio/tests/test_copy.c b/libsysio/tests/test_copy.c index 9ac97b1..bff098a 100644 --- a/libsysio/tests/test_copy.c +++ b/libsysio/tests/test_copy.c @@ -53,6 +53,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -136,7 +139,7 @@ open_file(const char *path, int flags, mode_t mode) { int fd; - fd = open(path, flags, mode); + fd = SYSIO_INTERFACE_NAME(open)(path, flags, mode); if (fd < 0) perror(path); @@ -149,11 +152,14 @@ copy_file(const char *spath, const char *dpath) int sfd, dfd; int flags; int rtn; - static char buf[1024]; + struct stat stat; + char *buf; + size_t bufsiz; ssize_t cc, wcc; sfd = dfd = -1; rtn = -1; + buf = NULL; sfd = open_file(spath, O_RDONLY, 0); if (sfd < 0) @@ -165,8 +171,23 @@ copy_file(const char *spath, const char *dpath) if (dfd < 0) goto out; - while ((cc = read(sfd, buf, sizeof(buf))) > 0) - if ((wcc = write(dfd, buf, cc)) != cc) { + rtn = SYSIO_INTERFACE_NAME(fstat)(dfd, &stat); + if (rtn != 0) { + perror(dpath); + goto out; + } + bufsiz = stat.st_blksize; + if (bufsiz < (64 * 1024)) + bufsiz = + (((64 * 1024) / stat.st_blksize - 1) + 1) * (64 * 1024); + buf = malloc(bufsiz); + if (!buf) { + perror(dpath); + goto out; + } + + while ((cc = SYSIO_INTERFACE_NAME(read)(sfd, buf, bufsiz)) > 0) + if ((wcc = SYSIO_INTERFACE_NAME(write)(dfd, buf, cc)) != cc) { if (wcc < 0) { perror(dpath); break; @@ -178,14 +199,20 @@ copy_file(const char *spath, const char *dpath) (unsigned )cc); break; } - if (cc < 0) + if (cc < 0) { perror(spath); + rtn = -1; + } out: - if (sfd >= 0 && close(sfd) != 0) + if (buf) + free(buf); + if (sfd >= 0 && SYSIO_INTERFACE_NAME(close)(sfd) != 0) perror(spath); - if (dfd >= 0 && (fsync(dfd) != 0 || close(dfd) != 0)) + if (dfd >= 0 && + (SYSIO_INTERFACE_NAME(fsync)(dfd) != 0 || + SYSIO_INTERFACE_NAME(close)(dfd) != 0)) perror(dpath); - return 0; + return rtn; } diff --git a/libsysio/tests/test_getcwd.c b/libsysio/tests/test_getcwd.c index 8cd160d..888c9a6 100644 --- a/libsysio/tests/test_getcwd.c +++ b/libsysio/tests/test_getcwd.c @@ -53,6 +53,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "mount.h" @@ -144,11 +147,11 @@ doit(const char *path) { char *buf; - if (chdir(path) != 0) { + if (SYSIO_INTERFACE_NAME(chdir)(path) != 0) { perror(path); return -1; } - buf = getcwd(NULL, 0); + buf = SYSIO_INTERFACE_NAME(getcwd)(NULL, 0); if (!buf) { perror(path); return -1; diff --git a/libsysio/tests/test_link.c b/libsysio/tests/test_link.c index 218dd49..2ec1786 100644 --- a/libsysio/tests/test_link.c +++ b/libsysio/tests/test_link.c @@ -54,6 +54,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -106,11 +109,11 @@ main(int argc, char *const argv[]) old = argv[optind++]; new = argv[optind++]; - if ((err = link(old, new)) != 0) { + if ((err = SYSIO_INTERFACE_NAME(link)(old, new)) != 0) { perror("link"); break; } - if ((err = lstat(new, &stbuf)) != 0) { + if ((err = SYSIO_INTERFACE_NAME(lstat)(new, &stbuf)) != 0) { perror(new); break; } diff --git a/libsysio/tests/test_list.c b/libsysio/tests/test_list.c index 292bb54..a539314 100644 --- a/libsysio/tests/test_list.c +++ b/libsysio/tests/test_list.c @@ -55,6 +55,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -149,7 +152,7 @@ listit(const char *path) off_t base; ssize_t cc; - fd = open(path, O_RDONLY); + fd = SYSIO_INTERFACE_NAME(open)(path, O_RDONLY); if (fd < 0) { perror(path); return -1; @@ -163,8 +166,10 @@ listit(const char *path) goto out; } - base = 0; - while ((cc = getdirentries(fd, (char *)buf, n, &base)) > 0) { + while ((cc = SYSIO_INTERFACE_NAME(getdirentries)(fd, + (char *)buf, + n, + &base)) > 0) { dp = buf; while (cc > 0) { (void )printf("\t%s: ino %llu type %u\n", @@ -174,8 +179,6 @@ listit(const char *path) cc -= dp->d_reclen; dp = (struct dirent *)((char *)dp + dp->d_reclen); } - if (!base) - break; } out: @@ -186,7 +189,7 @@ out: { int oerrno = errno; - if (close(fd) != 0) { + if (SYSIO_INTERFACE_NAME(close)(fd) != 0) { perror(path); if (cc < 0) errno = oerrno; diff --git a/libsysio/tests/test_path.c b/libsysio/tests/test_path.c index 80cc74e..518dbfe 100644 --- a/libsysio/tests/test_path.c +++ b/libsysio/tests/test_path.c @@ -52,6 +52,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -149,7 +152,7 @@ statit(const char *path) /* * Get file attrs. */ - err = lstat(path, &stbuf); + err = SYSIO_INTERFACE_NAME(lstat)(path, &stbuf); if (err) { perror(path); return -1; @@ -197,7 +200,7 @@ statit(const char *path) * Print path and type. */ if (S_ISLNK(stbuf.st_mode)) { - cc = readlink(path, buf, sizeof(buf)); + cc = SYSIO_INTERFACE_NAME(readlink)(path, buf, sizeof(buf)); if (cc < 0) { perror(path); return -1; diff --git a/libsysio/tests/test_regions.c b/libsysio/tests/test_regions.c index ba78800a..ded2c83 100644 --- a/libsysio/tests/test_regions.c +++ b/libsysio/tests/test_regions.c @@ -65,6 +65,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -197,7 +200,7 @@ main(int argc, char * const argv[]) if (use64) flags |= O_LARGEFILE; #endif - fd = open(path, flags, 0666); + fd = SYSIO_INTERFACE_NAME(open)(path, flags, 0666); if (fd < 0) { perror(path); err = 1; @@ -205,11 +208,11 @@ main(int argc, char * const argv[]) } #ifdef GO64 if (use64) - off64 = lseek64(fd, off64, SEEK_SET); + off64 = SYSIO_INTERFACE_NAME(lseek64)(fd, off64, SEEK_SET); else off64 = #endif - off = lseek(fd, off, SEEK_SET); + off = SYSIO_INTERFACE_NAME(lseek)(fd, off, SEEK_SET); #ifdef GO64 if ((use64 && off64 < 0) || (!use64 && off < 0)) { perror(use64 ? "lseek64" : "lseek"); @@ -224,9 +227,9 @@ main(int argc, char * const argv[]) } #endif if (which == 'r') - cc = read(fd, buf, nbytes); + cc = SYSIO_INTERFACE_NAME(read)(fd, buf, nbytes); else - cc = write(fd, buf, nbytes); + cc = SYSIO_INTERFACE_NAME(write)(fd, buf, nbytes); if (cc < 0) { perror(path); err = 1; @@ -234,11 +237,11 @@ main(int argc, char * const argv[]) } #ifdef GO64 if (use64) { - off64 = lseek64(fd, 0, SEEK_CUR); + off64 = SYSIO_INTERFACE_NAME(lseek64)(fd, 0, SEEK_CUR); } else off64 = #endif - off = lseek(fd, 0, SEEK_CUR); + off = SYSIO_INTERFACE_NAME(lseek)(fd, 0, SEEK_CUR); (void )printf(("%s%s@" #ifdef GO64 "%lld" @@ -269,7 +272,7 @@ main(int argc, char * const argv[]) ); error: - if (fd > 0 && close(fd) != 0) + if (fd > 0 && SYSIO_INTERFACE_NAME(close)(fd) != 0) perror(path); free(buf); out: diff --git a/libsysio/tests/test_rename.c b/libsysio/tests/test_rename.c index 8bc2ec82..dbb0d92 100644 --- a/libsysio/tests/test_rename.c +++ b/libsysio/tests/test_rename.c @@ -52,6 +52,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -95,7 +98,7 @@ main(int argc, char * const argv[]) exit(1); } - (void )umask(022); + (void )SYSIO_INTERFACE_NAME(umask)(022); /* * Source @@ -110,7 +113,7 @@ main(int argc, char * const argv[]) if (argc - optind) usage(); - err = rename(spath, dpath); + err = SYSIO_INTERFACE_NAME(rename)(spath, dpath); if (err) perror("rename"); diff --git a/libsysio/tests/test_stats.c b/libsysio/tests/test_stats.c index 951e7cf..dac7b8d 100644 --- a/libsysio/tests/test_stats.c +++ b/libsysio/tests/test_stats.c @@ -55,6 +55,9 @@ #endif #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -91,7 +94,7 @@ main(int argc, char * const argv[]) exit(1); } - (void )umask(022); + (void )SYSIO_INTERFACE_NAME(umask)(022); while (optind < argc) do_stats(argv[optind++]); @@ -124,19 +127,19 @@ do_stats(const char *path) struct statvfs stvfsbuf1, stvfsbuf2; #endif - fd = open(path, O_RDONLY); + fd = SYSIO_INTERFACE_NAME(open)(path, O_RDONLY); if (fd < 0) { perror(path); return; } - err = fstat(fd, &stbuf1); + err = SYSIO_INTERFACE_NAME(fstat)(fd, &stbuf1); if (!err) - err = stat(path, &stbuf2); + err = SYSIO_INTERFACE_NAME(stat)(path, &stbuf2); #ifdef notdef if (!err) - err = fstatvfs(fd, &stvfsbuf1); + err = SYSIO_INTERFACE_NAME(fstatvfs)(fd, &stvfsbuf1); if (!err) - err = statvfs(path, &stvfsbuf1); + err = SYSIO_INTERFACE_NAME(statvfs)(path, &stvfsbuf1); #endif if (err) { perror(path); @@ -182,6 +185,6 @@ do_stats(const char *path) (unsigned long )stbuf1.st_mtime, (unsigned long )stbuf1.st_ctime); out: - if (close(fd) != 0) + if (SYSIO_INTERFACE_NAME(close)(fd) != 0) perror("closing file"); } diff --git a/libsysio/tests/test_stddir.c b/libsysio/tests/test_stddir.c index 941dea4..b122f93 100644 --- a/libsysio/tests/test_stddir.c +++ b/libsysio/tests/test_stddir.c @@ -49,6 +49,9 @@ #include #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -139,17 +142,17 @@ testit(const char *path) printf("testing directory functions on %s\n", path); - if ((d = opendir(path)) == NULL) { + if ((d = SYSIO_INTERFACE_NAME(opendir)(path)) == NULL) { perror(path); return errno; } - while ((de = readdir(d)) != NULL) + while ((de = SYSIO_INTERFACE_NAME(readdir)(d)) != NULL) printf("\t %s: ino %lu off %lu type %u\n", de->d_name, (unsigned long )de->d_ino, (unsigned long )de->d_off, (int )de->d_type); - if (closedir(d)) { + if (SYSIO_INTERFACE_NAME(closedir)(d)) { perror("closedir"); return errno; } diff --git a/libsysio/tests/test_unlink.c b/libsysio/tests/test_unlink.c index d168b28..99f634b 100644 --- a/libsysio/tests/test_unlink.c +++ b/libsysio/tests/test_unlink.c @@ -52,6 +52,9 @@ #endif #include +#if defined(SYSIO_LABEL_NAMES) +#include "sysio.h" +#endif #include "xtio.h" #include "test.h" @@ -141,7 +144,7 @@ static int unlinkit(const char *path) { - if (unlink(path) != 0) { + if (SYSIO_INTERFACE_NAME(unlink)(path) != 0) { perror(path); return -1; } -- 1.8.3.1