]> granicus.if.org Git - zfs/commitdiff
Fix some incorrect error handling.
authorRicardo M. Correia <Ricardo.M.Correia@Sun.COM>
Wed, 10 Mar 2010 17:53:53 +0000 (09:53 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 10 Mar 2010 17:53:53 +0000 (09:53 -0800)
In vn_open(), if fstat64() returned an error, the real errno
was being obscured by calling close().

Add error handling for both pwrite64() calls in vn_rdwr().

.topdeps [new file with mode: 0644]
.topmsg [new file with mode: 0644]
lib/libzpool/kernel.c

diff --git a/.topdeps b/.topdeps
new file mode 100644 (file)
index 0000000..1f7391f
--- /dev/null
+++ b/.topdeps
@@ -0,0 +1 @@
+master
diff --git a/.topmsg b/.topmsg
new file mode 100644 (file)
index 0000000..8a0394a
--- /dev/null
+++ b/.topmsg
@@ -0,0 +1,12 @@
+From: Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
+Subject: [PATCH] fix error handling
+
+Fix some incorrect error handling.
+
+1) In vn_open(), if fstat64() returned an error, the real errno
+was being obscured by calling close().
+
+2) Add error handling for both pwrite64() calls in vn_rdwr().
+
+Signed-off-by: Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
index 89108fe5b2b1bf0950eeec985282701da4a9a355..af4329a4dcaaba11aa9a9e154d3f790cdf5b87e8 100644 (file)
@@ -325,6 +325,7 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
        int old_umask;
        char realpath[MAXPATHLEN];
        struct stat64 st;
+       int err;
 
        /*
         * If we're accessing a real disk from userland, we need to use
@@ -373,8 +374,9 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
                return (errno);
 
        if (fstat64(fd, &st) == -1) {
+               err = errno;
                close(fd);
-               return (errno);
+               return (err);
        }
 
        (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -412,26 +414,32 @@ int
 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
        int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
 {
-       ssize_t iolen, split;
+       ssize_t rc, done = 0, split;
 
        if (uio == UIO_READ) {
-               iolen = pread64(vp->v_fd, addr, len, offset);
+               rc = pread64(vp->v_fd, addr, len, offset);
        } else {
                /*
                 * To simulate partial disk writes, we split writes into two
                 * system calls so that the process can be killed in between.
                 */
                split = (len > 0 ? rand() % len : 0);
-               iolen = pwrite64(vp->v_fd, addr, split, offset);
-               iolen += pwrite64(vp->v_fd, (char *)addr + split,
-                   len - split, offset + split);
+               rc = pwrite64(vp->v_fd, addr, split, offset);
+               if (rc != -1) {
+                       done = rc;
+                       rc = pwrite64(vp->v_fd, (char *)addr + split,
+                           len - split, offset + split);
+               }
        }
 
-       if (iolen == -1)
+       if (rc == -1)
                return (errno);
+
+       done += rc;
+
        if (residp)
-               *residp = len - iolen;
-       else if (iolen != len)
+               *residp = len - done;
+       else if (done != len)
                return (EIO);
        return (0);
 }