Print this page
OS-5148 ftruncate at offset should emit proper events
Reviewed by: Bryan Cantrill <bryan@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-5291 lxbrand inotify02 LTP regression
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4319 zfs mishandles partial writes
OS-3294 add support for inotify
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
@@ -21,11 +21,11 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
- * Copyright 2015 Joyent, Inc.
+ * Copyright 2016 Joyent, Inc.
*/
/* Portions Copyright 2007 Jeremy Teo */
/* Portions Copyright 2010 Robert Milkowski */
@@ -662,10 +662,11 @@
offset_t woff;
ssize_t n, nbytes;
rl_t *rl;
int max_blksz = zfsvfs->z_max_blksz;
int error = 0;
+ int prev_error;
arc_buf_t *abuf;
iovec_t *aiov = NULL;
xuio_t *xuio = NULL;
int i_iov = 0;
int iovcnt = uio->uio_iovcnt;
@@ -966,26 +967,30 @@
* account for possible concurrent updates.
*/
while ((end_size = zp->z_size) < uio->uio_loffset) {
(void) atomic_cas_64(&zp->z_size, end_size,
uio->uio_loffset);
- ASSERT(error == 0);
}
/*
* If we are replaying and eof is non zero then force
* the file size to the specified eof. Note, there's no
* concurrency during replay.
*/
if (zfsvfs->z_replay && zfsvfs->z_replay_eof != 0)
zp->z_size = zfsvfs->z_replay_eof;
+ /*
+ * Keep track of a possible pre-existing error from a partial
+ * write via dmu_write_uio_dbuf above.
+ */
+ prev_error = error;
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes, ioflag);
dmu_tx_commit(tx);
- if (error != 0)
+ if (prev_error != 0 || error != 0)
break;
ASSERT(tx_bytes == nbytes);
n -= nbytes;
if (!xuio && n > 0)
@@ -2830,13 +2835,16 @@
if (err) {
ZFS_EXIT(zfsvfs);
return (err);
}
- if (vap->va_size == 0)
+ if (vap->va_size == 0) {
vnevent_truncate(ZTOV(zp), ct);
+ } else {
+ vnevent_resize(ZTOV(zp), ct);
}
+ }
if (mask & (AT_ATIME|AT_MTIME) ||
((mask & AT_XVATTR) && (XVA_ISSET_REQ(xvap, XAT_HIDDEN) ||
XVA_ISSET_REQ(xvap, XAT_READONLY) ||
XVA_ISSET_REQ(xvap, XAT_ARCHIVE) ||
@@ -3759,13 +3767,11 @@
if (tzp && rm_err == 0)
vnevent_rename_dest(ZTOV(tzp), tdvp, tnm, ct);
if (error == 0) {
vnevent_rename_src(ZTOV(szp), sdvp, snm, ct);
- /* notify the target dir if it is not the same as source dir */
- if (tdvp != sdvp)
- vnevent_rename_dest_dir(tdvp, ct);
+ vnevent_rename_dest_dir(tdvp, ZTOV(szp), tnm, ct);
}
out:
if (zl != NULL)
zfs_rename_unlock(&zl);
@@ -4857,12 +4863,17 @@
off = bfp->l_start;
len = bfp->l_len; /* 0 means from off to end of file */
error = zfs_freesp(zp, off, len, flag, TRUE);
- if (error == 0 && off == 0 && len == 0)
+ if (error == 0 && len == 0) {
+ if (off == 0) {
vnevent_truncate(ZTOV(zp), ct);
+ } else {
+ vnevent_resize(ZTOV(zp), ct);
+ }
+ }
ZFS_EXIT(zfsvfs);
return (error);
}