RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 03-May-2017 16:50:45 Branch: rpm-5_4 Handle: 2017050314504401 Modified files: (Branch: rpm-5_4) rpm CHANGES rpm/rpmio iosm.c iosm.h rpmio.c rpmio_internal.h Log: - rpmio: support for O_DIRECT through Fopen. Summary: Revision Changes Path 1.3501.2.538+1 -0 rpm/CHANGES 1.43.2.13 +10 -2 rpm/rpmio/iosm.c 1.18.4.7 +11 -9 rpm/rpmio/iosm.h 1.230.2.44 +85 -49 rpm/rpmio/rpmio.c 2.127.2.13 +6 -5 rpm/rpmio/rpmio_internal.h ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3501.2.537 -r1.3501.2.538 CHANGES --- rpm/CHANGES 21 Apr 2017 06:19:16 -0000 1.3501.2.537 +++ rpm/CHANGES 3 May 2017 14:50:44 -0000 1.3501.2.538 @@ -1,4 +1,5 @@ 5.4.17 -> 5.4.18: + - jbj: rpmio: support for O_DIRECT through Fopen. - jbj: autofu: refactor to add --with-{epoll,eventfd,fanotify,inotify,ipc,mount,personality,prctl,timerfd}. - jbj: rpmio: add getauxval+personality. - jbj: autofu: refactor to add --with-{aio,clock,mq,sched,search,sem,shm,timer,xattr,attr,cap,acl,keyutils} subsystem detection build options. @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/iosm.c ============================================================================ $ cvs diff -u -r1.43.2.12 -r1.43.2.13 iosm.c --- rpm/rpmio/iosm.c 19 Apr 2017 20:42:15 -0000 1.43.2.12 +++ rpm/rpmio/iosm.c 3 May 2017 14:50:45 -0000 1.43.2.13 @@ -2552,7 +2552,7 @@ iosm->rfdno = -1; /* XXX */ break; case IOSM_WOPEN: - iosm->wfd = Fopen(iosm->path, "wb+eIONFP?.fdio"); + iosm->wfd = Fopen(iosm->path, "wb+etIONF?.fdio"); if (iosm->wfd == NULL || Ferror(iosm->wfd)) { (void) iosmNext(iosm, IOSM_WCLOSE); rc = IOSMERR_OPEN_FAILED; @@ -2588,9 +2588,16 @@ if (iosm->wfd != NULL) { if (iosm->debug && (stage & IOSM_SYSCALL)) rpmlog(RPMLOG_DEBUG, " %8s (%p)\n", cur, iosm->wfd); + /* Ensure the corect file size (with O_DIRECT). */ + if (RPMFD_ISSET(iosm->wfd, FTRUNCATE)) { + rc = Ftruncate(iosm->wfd, st->st_size); + if (rc < 0) + rc = IOSMERR_RESIZE_FAILED; + } fdstat_sum(iosm->wfd, iosm->stats); (void) Fclose(iosm->wfd); - errno = saveerrno; + if (!rc) + errno = saveerrno; } iosm->wfd = NULL; iosm->wfdno = -1; /* XXX */ @@ -2735,6 +2742,7 @@ case IOSMERR_READ_FAILED: s = "read"; break; case IOSMERR_COPY_FAILED: s = "copy"; break; case IOSMERR_LSETFCON_FAILED: s = "lsetfilecon"; break; + case IOSMERR_RESIZE_FAILED: s = "ftruncate"; break; case IOSMERR_HDR_SIZE: s = _("Header size too big"); break; case IOSMERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/iosm.h ============================================================================ $ cvs diff -u -r1.18.4.6 -r1.18.4.7 iosm.h --- rpm/rpmio/iosm.h 17 Apr 2017 19:25:27 -0000 1.18.4.6 +++ rpm/rpmio/iosm.h 3 May 2017 14:50:45 -0000 1.18.4.7 @@ -88,15 +88,17 @@ IOSMERR_READ_FAILED = (20 | IOSMERR_CHECK_ERRNO), IOSMERR_COPY_FAILED = (21 | IOSMERR_CHECK_ERRNO), IOSMERR_LSETFCON_FAILED = (22 | IOSMERR_CHECK_ERRNO), - IOSMERR_HDR_SIZE = (23 ), - IOSMERR_HDR_TRAILER = (24 ), - IOSMERR_UNKNOWN_FILETYPE= (25 ), - IOSMERR_MISSING_HARDLINK= (26 ), - IOSMERR_DIGEST_MISMATCH = (27 ), - IOSMERR_INTERNAL = (28 ), - IOSMERR_UNMAPPED_FILE = (29 ), - IOSMERR_ENOENT = (30 ), - IOSMERR_ENOTEMPTY = (31 ) + IOSMERR_RESIZE_FAILED = (23 | IOSMERR_CHECK_ERRNO), + + IOSMERR_HDR_SIZE = (24 ), + IOSMERR_HDR_TRAILER = (25 ), + IOSMERR_UNKNOWN_FILETYPE= (26 ), + IOSMERR_MISSING_HARDLINK= (27 ), + IOSMERR_DIGEST_MISMATCH = (28 ), + IOSMERR_INTERNAL = (29 ), + IOSMERR_UNMAPPED_FILE = (30 ), + IOSMERR_ENOENT = (31 ), + IOSMERR_ENOTEMPTY = (32 ) }; #endif @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmio.c ============================================================================ $ cvs diff -u -r1.230.2.43 -r1.230.2.44 rpmio.c --- rpm/rpmio/rpmio.c 21 Apr 2017 02:58:43 -0000 1.230.2.43 +++ rpm/rpmio/rpmio.c 3 May 2017 14:50:45 -0000 1.230.2.44 @@ -17,6 +17,10 @@ # include <sys/socket.h> #endif +#if defined(HAVE_SYS_SYSCALL_H) +# include <sys/syscall.h> +#endif + #if defined(HAVE_SYS_XATTR_H) # include <sys/xattr.h> #endif @@ -25,33 +29,7 @@ #define NI_MAXHOST 1025 #endif -#if defined(__LCLINT__) -struct addrinfo -{ - int ai_flags; /* Input flags. */ - int ai_family; /* Protocol family for socket. */ - int ai_socktype; /* Socket type. */ - int ai_protocol; /* Protocol for socket. */ - socklen_t ai_addrlen; /* Length of socket address. */ - struct sockaddr *ai_addr; /* Socket address for socket. */ - char *ai_canonname; /* Canonical name for service location. */ - struct addrinfo *ai_next; /* Pointer to next in list. */ -}; - -extern int getaddrinfo (__const char *__restrict __name, - __const char *__restrict __service, - __const struct addrinfo *__restrict __req, - struct addrinfo **__restrict __pai); - -extern int getnameinfo (__const struct sockaddr *__restrict __sa, - socklen_t __salen, char *__restrict __host, - socklen_t __hostlen, char *__restrict __serv, - socklen_t __servlen, unsigned int __flags); - -extern void freeaddrinfo (struct addrinfo *__ai); -#else #include <netdb.h> /* XXX getaddrinfo et al */ -#endif #include <netinet/in.h> #include <arpa/inet.h> /* XXX for inet_aton and HP-UX */ @@ -106,7 +84,7 @@ #endif /* XXX HP-UX w/o -D_XOPEN_SOURCE needs */ -#if !defined(HAVE_HERRNO) && (defined(hpux) || defined(__hpux) || defined(__LCLINT__)) +#if !defined(HAVE_HERRNO) && (defined(hpux) || defined(__hpux)) extern int h_errno; #endif @@ -315,6 +293,9 @@ (void) rpmDigestFinal(ctx, NULL, NULL, 0); fd->digests[i] = NULL; } + fd->nio = 0; + if (fd->io) free(fd->io); + fd->io = NULL; fd->digests = _free(fd->digests); fd->ndigests = 0; fd->contentType = _free(fd->contentType); @@ -378,6 +359,16 @@ fd->oflags = 0; fd->omode = 0; + fd->nio = 0; + fd->io = NULL; + if (fd->nio > 0) { +#if defined(HAVE_POSIX_MEMALIGN) + assert(posix_memalign((void **)&fd->io, BUFSIZ, fd->nio) == 0); +#else + fd->io = xmalloc(fd->nio); +#endif + } + fd->xar = NULL; fd->dig = NULL; fd->stats = (FDSTAT_t) xcalloc(1, sizeof(*fd->stats)); @@ -393,6 +384,15 @@ return (FD_t)rpmioLinkPoolItem((rpmioItem)fd, msg, fn, ln); } +static int fdChkAlign(FD_t fd, const void *buf, size_t count) +{ + static unsigned long m = (512 - 1); + unsigned long slop = ((unsigned long)buf & m) + (count & m); + int rc = (fd->flags & O_DIRECT) && slop ? 0 : 1; +DBGIO(fd, (stderr, "<--\tfdChkAlign(%p,%p,%lx) rc %d\n", fd, buf, (long)count, rc)); + return rc; +} + static ssize_t fdRead(void * cookie, char * buf, size_t count) { static const int opx = FDSTAT_READ; @@ -402,9 +402,14 @@ /* XXX handle fd->req similar to ufdRead() */ if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */ + fdstat_enter(fd, opx); - /* HACK: flimsy wiring for davRead */ - if (fd->req != NULL) { + + if (!fdChkAlign(fd, buf, count)) { + errno = EINVAL; + rc = -1; + } else + if (fd->req != NULL) { /* HACK: flimsy wiring for davRead */ #ifdef WITH_NEON if (fd->req != (void *)-1) rc = davRead(fd, buf, (count > (size_t)fd->bytesRemain ? (size_t)fd->bytesRemain : count)); @@ -425,6 +430,7 @@ #endif } else rc = read(fdFileno(fd), buf, (count > (size_t)fd->bytesRemain ? (size_t)fd->bytesRemain : count)); + fdstat_exit(fd, opx, rc); if (fd->ndigests > 0 && rc > 0) fdUpdateDigests(fd, (const unsigned char *)buf, rc); @@ -439,6 +445,11 @@ static const int opx = FDSTAT_WRITE; FD_t fd = c2f(cookie); int fdno = fdFileno(fd); + /* XXX Round up last write to block boundary. */ + static size_t blksize = 512; + size_t pad = (fd->flags & O_DIRECT) && (count % blksize) + ? 512 - (count % blksize) + : 0; ssize_t rc; if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */ @@ -448,18 +459,25 @@ if (count == 0) return 0; fdstat_enter(fd, opx); - /* HACK: flimsy wiring for davWrite */ - if (fd->req != NULL) + + if (!fdChkAlign(fd, buf, count+pad)) { + errno = EINVAL; + rc = -1; + } else + if (fd->req != NULL) /* HACK: flimsy wiring for davWrite */ #ifdef WITH_NEON if (fd->req != (void *)-1) rc = davWrite(fd, buf, (count > (size_t)fd->bytesRemain ? (size_t)fd->bytesRemain : count)); else - rc = -1; -#else - rc = -1; #endif - else - rc = write(fdno, buf, (count > (size_t)fd->bytesRemain ? (size_t)fd->bytesRemain : count)); + rc = -1; + else { + size_t nw = count; + if (pad) nw += pad; + rc = write(fdno, buf, (nw > (size_t)fd->bytesRemain ? (size_t)fd->bytesRemain : nw)); + if (pad) rc -= pad; + } + fdstat_exit(fd, opx, rc); DBGIO(fd, (stderr, "<--\tfdWrite(%p,%p,%ld) rc %ld %s\n", cookie, buf, (long)count, (long)rc, fdbg(fd))); @@ -478,7 +496,7 @@ FD_t fd = c2f(cookie); off_t rc; - assert(fd->bytesRemain == -1); /* XXX FIXME fadio only for now */ + assert(fd->bytesRemain == -1); /* XXX FIXME fdio only for now */ fdstat_enter(fd, opx); rc = lseek(fdFileno(fd), p, whence); fdstat_exit(fd, opx, rc); @@ -572,7 +590,7 @@ int rc = -2; #if defined(HAVE_MEMFD_CREATE) rc = memfd_create(name, flags); -#elif defined(linux) && defined(x86_64) && defined(SYS_memfd_create) +#elif defined(SYS_memfd_create) rc = syscall(SYS_memfd_create, name, flags); #else errno = ENOSYS; @@ -662,7 +680,15 @@ int fdno; int oflags = (flags & _oflagmask); - fdno = open(path, oflags, mode); +#if defined(HAVE_MEMFD_CREATE) || defined(SYS_memfd_create) + if (flags & RPMFD_FLAG_MEMFD) { + unsigned _mflags = 3; /* MFD_CLOEXEC=1, MFD_ALLOW_SEALING=2 */ + fdno = Memfd_create(path, _mflags); + } else +#endif + { + fdno = open(path, oflags, mode); + } if (fdno < 0) return NULL; if (fcntl(fdno, F_SETFD, FD_CLOEXEC)) { (void) close(fdno); @@ -2617,13 +2643,14 @@ * - bzopen: 'q' sets verbosity to 0 * - bzopen: 'v' does verbosity++ (up to 4) * - HACK: '.' terminates, rest is type of I/O - * - HACK: 'D' sync (O_DSYNC) + * - HACK: 'D' sync (O_DIRECT) * - HACK: 'S' sync (O_SYNC) * - HACK: 'I' fallocate(2) * - HACK: 'O' fdatasync(2) * - HACK: 'N' fadvise(2) * - HACK: 'F' fsync(2) * - HACK: 'P' syncfs(2) + * - HACK: 'M' memfd_create(2) * - HACK: 't' truncate (O_TRUNC) * - HACK: 'T' tempfile (O_TMPFILE) * - HACK: '?' debug I/O + refcnt @@ -2692,10 +2719,11 @@ continue; break; case 'D': - flags |= O_DSYNC; + flags |= O_DIRECT; + RPMFD_SET(flags, FTRUNCATE); goto other; case 'S': - flags |= O_SYNC; + flags |= O_SYNC; /* XXX O_DSYNC? */ goto other; case 'I': RPMFD_SET(flags, FALLOCATE); @@ -2703,7 +2731,7 @@ case 'O': RPMFD_SET(flags, FDATASYNC); goto other; - case 'N': + case 'N': /* XXX O_NONBLOCK? */ RPMFD_SET(flags, FADVISE); goto other; case 'F': @@ -2712,6 +2740,13 @@ case 'P': RPMFD_SET(flags, SYNCFS); goto other; + case 'M': +#if defined(HAVE_MEMFD_CREATE) || defined(SYS_memfd_create) + RPMFD_SET(flags, MEMFD); + goto other; +#else + continue; +#endif case '?': RPMFD_SET(flags, DEBUGIO); RPMFD_SET(flags, DEBUGREFS); @@ -2720,7 +2755,6 @@ other: if (--nother > 0) *other++ = c; continue; - break; } break; } @@ -2826,6 +2860,8 @@ ciof.close = iof->close; fp = fopencookie(fd, stdio, ciof); DBGIO(fd, (stderr, "<-- fopencookie(%p,\"%s\",*%p) returns fp %p\n", fd, stdio, iof, fp)); + if (fp && (fd->flags & O_DIRECT)) + assert(setvbuf(fp, NULL, _IONBF, 0) == 0); } #elif defined(HAVE_FUNOPEN) { void * cookie = (void *) fd; @@ -2862,7 +2898,7 @@ FD_t Fopen(const char *path, const char *_fmode) { const char * fmode = NULL; - char stdio[20], other[20]; + char stdio[64], other[64]; const char *end = NULL; mode_t perms = 0666; int flags = 0; @@ -3314,7 +3350,7 @@ int rc = -2; fdstat_enter(fd, opx); -#if defined(HAVE_FDATASYNC) +#if defined(HAVE_FDATASYNC) || defined(HAVE_RAW_DECL_FDATASYNC) rc = fdSyscall( fdatasync(fdno) ); #else errno = ENOSYS; @@ -3331,7 +3367,7 @@ int rc = -2; fdstat_enter(fd, opx); -#if defined(HAVE_FSYNC) +#if defined(HAVE_FSYNC) || defined(HAVE_RAW_DECL_FSYNC) rc = fdSyscall( fsync(fdno) ); #else errno = ENOSYS; @@ -3600,7 +3636,7 @@ return rc; } -#if defined(WITH_NSS) && !defined(__LCLINT__) /* XXX TODO: add nssDestroy */ +#if defined(WITH_NSS) /* XXX TODO: add nssDestroy */ #ifdef __cplusplus extern "C" { #endif @@ -3630,7 +3666,7 @@ #if defined(WITH_NEON) davDestroy(); #endif -#if defined(WITH_NSS) && !defined(__LCLINT__) +#if defined(WITH_NSS) if (_rpmnss_init) { #ifdef HAVE_NSS_INITCONTEXT if (_rpmnss_context != NULL) @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmio_internal.h ============================================================================ $ cvs diff -u -r2.127.2.12 -r2.127.2.13 rpmio_internal.h --- rpm/rpmio/rpmio_internal.h 21 Apr 2017 02:58:43 -0000 2.127.2.12 +++ rpm/rpmio/rpmio_internal.h 3 May 2017 14:50:45 -0000 2.127.2.13 @@ -62,8 +62,9 @@ */ typedef enum fdFlags_e { RPMFD_FLAG_NONE = 0, - /* 0 - 23 unused */ - RPMFD_FLAG_MEMFD = (1 << 23), + /* 0 - 21 unused */ + RPMFD_FLAG_MEMFD = (1 << 22), + RPMFD_FLAG_FTRUNCATE = (1 << 23), RPMFD_FLAG_SYNCFS = (1 << 24), RPMFD_FLAG_FSYNC = (1 << 25), RPMFD_FLAG_FDATASYNC = (1 << 26), @@ -113,11 +114,13 @@ int syserrno; /* last system errno encountered */ const void *errcookie; /* gzdio/bzdio/ufdio: */ -/*null@*/ const char *opath; /* open(2) args. */ int oflags; mode_t omode; + size_t nio; /* stdio: buffer size. */ + void * io; /* stdio: buffer. */ + rpmxar xar; /* xar archive wrapper */ pgpDig dig; /* signature parameters */ @@ -126,9 +129,7 @@ size_t ndigests; /* no. of digests. */ DIGEST_CTX *digests; /* digest contexts. */ -/*null@*/ const char *contentType; /* ufdio: (HTTP) */ -/*null@*/ const char *contentDisposition; /* ufdio: (HTTP) */ time_t lastModified; /* ufdio: (HTTP) */ int ftpFileDoneNeeded; /* ufdio: (FTP) */ @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org