mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 19:19:32 +03:00
Fix vn_open/vn_rdwr 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>
This commit is contained in:
parent
235db0acea
commit
4d58b69de8
@ -328,6 +328,7 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
|
|||||||
int old_umask;
|
int old_umask;
|
||||||
char realpath[MAXPATHLEN];
|
char realpath[MAXPATHLEN];
|
||||||
struct stat64 st;
|
struct stat64 st;
|
||||||
|
int err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're accessing a real disk from userland, we need to use
|
* If we're accessing a real disk from userland, we need to use
|
||||||
@ -376,8 +377,9 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
|
|||||||
return (errno);
|
return (errno);
|
||||||
|
|
||||||
if (fstat64(fd, &st) == -1) {
|
if (fstat64(fd, &st) == -1) {
|
||||||
|
err = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
return (errno);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
@ -415,26 +417,32 @@ int
|
|||||||
vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
|
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)
|
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) {
|
if (uio == UIO_READ) {
|
||||||
iolen = pread64(vp->v_fd, addr, len, offset);
|
rc = pread64(vp->v_fd, addr, len, offset);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* To simulate partial disk writes, we split writes into two
|
* To simulate partial disk writes, we split writes into two
|
||||||
* system calls so that the process can be killed in between.
|
* system calls so that the process can be killed in between.
|
||||||
*/
|
*/
|
||||||
split = (len > 0 ? rand() % len : 0);
|
split = (len > 0 ? rand() % len : 0);
|
||||||
iolen = pwrite64(vp->v_fd, addr, split, offset);
|
rc = pwrite64(vp->v_fd, addr, split, offset);
|
||||||
iolen += pwrite64(vp->v_fd, (char *)addr + split,
|
if (rc != -1) {
|
||||||
len - split, offset + split);
|
done = rc;
|
||||||
|
rc = pwrite64(vp->v_fd, (char *)addr + split,
|
||||||
|
len - split, offset + split);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iolen == -1)
|
if (rc == -1)
|
||||||
return (errno);
|
return (errno);
|
||||||
|
|
||||||
|
done += rc;
|
||||||
|
|
||||||
if (residp)
|
if (residp)
|
||||||
*residp = len - iolen;
|
*residp = len - done;
|
||||||
else if (iolen != len)
|
else if (done != len)
|
||||||
return (EIO);
|
return (EIO);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user