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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_vnops.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_vnops.c
↓ open down ↓ 15 lines elided ↑ open up ↑
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
  24   24   * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25   25   * Copyright (c) 2014 Integros [integros.com]
  26      - * Copyright 2015 Joyent, Inc.
       26 + * Copyright 2016 Joyent, Inc.
  27   27   */
  28   28  
  29   29  /* Portions Copyright 2007 Jeremy Teo */
  30   30  /* Portions Copyright 2010 Robert Milkowski */
  31   31  
  32   32  #include <sys/types.h>
  33   33  #include <sys/param.h>
  34   34  #include <sys/time.h>
  35   35  #include <sys/systm.h>
  36   36  #include <sys/sysmacros.h>
↓ open down ↓ 620 lines elided ↑ open up ↑
 657  657          ssize_t         tx_bytes;
 658  658          uint64_t        end_size;
 659  659          dmu_tx_t        *tx;
 660  660          zfsvfs_t        *zfsvfs = zp->z_zfsvfs;
 661  661          zilog_t         *zilog;
 662  662          offset_t        woff;
 663  663          ssize_t         n, nbytes;
 664  664          rl_t            *rl;
 665  665          int             max_blksz = zfsvfs->z_max_blksz;
 666  666          int             error = 0;
      667 +        int             prev_error;
 667  668          arc_buf_t       *abuf;
 668  669          iovec_t         *aiov = NULL;
 669  670          xuio_t          *xuio = NULL;
 670  671          int             i_iov = 0;
 671  672          int             iovcnt = uio->uio_iovcnt;
 672  673          iovec_t         *iovp = uio->uio_iov;
 673  674          int             write_eof;
 674  675          int             count = 0;
 675  676          sa_bulk_attr_t  bulk[4];
 676  677          uint64_t        mtime[2], ctime[2];
↓ open down ↓ 284 lines elided ↑ open up ↑
 961  962                  zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime,
 962  963                      B_TRUE);
 963  964  
 964  965                  /*
 965  966                   * Update the file size (zp_size) if it has changed;
 966  967                   * account for possible concurrent updates.
 967  968                   */
 968  969                  while ((end_size = zp->z_size) < uio->uio_loffset) {
 969  970                          (void) atomic_cas_64(&zp->z_size, end_size,
 970  971                              uio->uio_loffset);
 971      -                        ASSERT(error == 0);
 972  972                  }
 973  973                  /*
 974  974                   * If we are replaying and eof is non zero then force
 975  975                   * the file size to the specified eof. Note, there's no
 976  976                   * concurrency during replay.
 977  977                   */
 978  978                  if (zfsvfs->z_replay && zfsvfs->z_replay_eof != 0)
 979  979                          zp->z_size = zfsvfs->z_replay_eof;
 980  980  
      981 +                /*
      982 +                 * Keep track of a possible pre-existing error from a partial
      983 +                 * write via dmu_write_uio_dbuf above.
      984 +                 */
      985 +                prev_error = error;
 981  986                  error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
 982  987  
 983  988                  zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes, ioflag);
 984  989                  dmu_tx_commit(tx);
 985  990  
 986      -                if (error != 0)
      991 +                if (prev_error != 0 || error != 0)
 987  992                          break;
 988  993                  ASSERT(tx_bytes == nbytes);
 989  994                  n -= nbytes;
 990  995  
 991  996                  if (!xuio && n > 0)
 992  997                          uio_prefaultpages(MIN(n, max_blksz), uio);
 993  998          }
 994  999  
 995 1000          zfs_range_unlock(rl);
 996 1001  
↓ open down ↓ 1828 lines elided ↑ open up ↑
2825 2830                   * block if there are locks present... this
2826 2831                   * should be addressed in openat().
2827 2832                   */
2828 2833                  /* XXX - would it be OK to generate a log record here? */
2829 2834                  err = zfs_freesp(zp, vap->va_size, 0, 0, FALSE);
2830 2835                  if (err) {
2831 2836                          ZFS_EXIT(zfsvfs);
2832 2837                          return (err);
2833 2838                  }
2834 2839  
2835      -                if (vap->va_size == 0)
     2840 +                if (vap->va_size == 0) {
2836 2841                          vnevent_truncate(ZTOV(zp), ct);
     2842 +                } else {
     2843 +                        vnevent_resize(ZTOV(zp), ct);
     2844 +                }
2837 2845          }
2838 2846  
2839 2847          if (mask & (AT_ATIME|AT_MTIME) ||
2840 2848              ((mask & AT_XVATTR) && (XVA_ISSET_REQ(xvap, XAT_HIDDEN) ||
2841 2849              XVA_ISSET_REQ(xvap, XAT_READONLY) ||
2842 2850              XVA_ISSET_REQ(xvap, XAT_ARCHIVE) ||
2843 2851              XVA_ISSET_REQ(xvap, XAT_OFFLINE) ||
2844 2852              XVA_ISSET_REQ(xvap, XAT_SPARSE) ||
2845 2853              XVA_ISSET_REQ(xvap, XAT_CREATETIME) ||
2846 2854              XVA_ISSET_REQ(xvap, XAT_SYSTEM)))) {
↓ open down ↓ 907 lines elided ↑ open up ↑
3754 3762                  }
3755 3763          }
3756 3764  
3757 3765          dmu_tx_commit(tx);
3758 3766  
3759 3767          if (tzp && rm_err == 0)
3760 3768                  vnevent_rename_dest(ZTOV(tzp), tdvp, tnm, ct);
3761 3769  
3762 3770          if (error == 0) {
3763 3771                  vnevent_rename_src(ZTOV(szp), sdvp, snm, ct);
3764      -                /* notify the target dir if it is not the same as source dir */
3765      -                if (tdvp != sdvp)
3766      -                        vnevent_rename_dest_dir(tdvp, ct);
     3772 +                vnevent_rename_dest_dir(tdvp, ZTOV(szp), tnm, ct);
3767 3773          }
3768 3774  out:
3769 3775          if (zl != NULL)
3770 3776                  zfs_rename_unlock(&zl);
3771 3777  
3772 3778          zfs_dirent_unlock(sdl);
3773 3779          zfs_dirent_unlock(tdl);
3774 3780  
3775 3781          if (sdzp == tdzp)
3776 3782                  rw_exit(&sdzp->z_name_lock);
↓ open down ↓ 1075 lines elided ↑ open up ↑
4852 4858          if (bfp->l_len < 0) {
4853 4859                  ZFS_EXIT(zfsvfs);
4854 4860                  return (SET_ERROR(EINVAL));
4855 4861          }
4856 4862  
4857 4863          off = bfp->l_start;
4858 4864          len = bfp->l_len; /* 0 means from off to end of file */
4859 4865  
4860 4866          error = zfs_freesp(zp, off, len, flag, TRUE);
4861 4867  
4862      -        if (error == 0 && off == 0 && len == 0)
4863      -                vnevent_truncate(ZTOV(zp), ct);
     4868 +        if (error == 0 && len == 0) {
     4869 +                if (off == 0) {
     4870 +                        vnevent_truncate(ZTOV(zp), ct);
     4871 +                } else {
     4872 +                        vnevent_resize(ZTOV(zp), ct);
     4873 +                }
     4874 +        }
4864 4875  
4865 4876          ZFS_EXIT(zfsvfs);
4866 4877          return (error);
4867 4878  }
4868 4879  
4869 4880  /*ARGSUSED*/
4870 4881  static int
4871 4882  zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct)
4872 4883  {
4873 4884          znode_t         *zp = VTOZ(vp);
↓ open down ↓ 497 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX