Print this page
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
re #13613 rb4516 Tunables needs volatile keyword

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/nfs/nfs_vnops.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_vnops.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  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) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  23   24   *
  24   25   *      Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
  25   26   *      All rights reserved.
  26   27   */
  27   28  
  28   29  /*
  29   30   * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  30   31   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  31   32   */
  32   33  
↓ open down ↓ 1419 lines elided ↑ open up ↑
1452 1453          if (crgetuid(cr) != va.va_uid) {
1453 1454                  shift += 3;
1454 1455                  if (!groupmember(va.va_gid, cr))
1455 1456                          shift += 3;
1456 1457          }
1457 1458  
1458 1459          return (secpolicy_vnode_access2(cr, vp, va.va_uid,
1459 1460              va.va_mode << shift, mode));
1460 1461  }
1461 1462  
1462      -static int nfs_do_symlink_cache = 1;
     1463 +volatile int nfs_do_symlink_cache = 1;
1463 1464  
1464 1465  /* ARGSUSED */
1465 1466  static int
1466 1467  nfs_readlink(vnode_t *vp, struct uio *uiop, cred_t *cr, caller_context_t *ct)
1467 1468  {
1468 1469          int error;
1469 1470          struct nfsrdlnres rl;
1470 1471          rnode_t *rp;
1471 1472          int douprintf;
1472 1473          failinfo_t fi;
↓ open down ↓ 282 lines elided ↑ open up ↑
1755 1756                  VN_RELE(vp);
1756 1757          }
1757 1758  
1758 1759  out:
1759 1760          if (avp != NULL)
1760 1761                  VN_RELE(avp);
1761 1762  
1762 1763          return (error);
1763 1764  }
1764 1765  
1765      -static int nfs_lookup_neg_cache = 1;
     1766 +volatile int nfs_lookup_neg_cache = 1;
1766 1767  
1767 1768  #ifdef DEBUG
1768 1769  static int nfs_lookup_dnlc_hits = 0;
1769 1770  static int nfs_lookup_dnlc_misses = 0;
1770 1771  static int nfs_lookup_dnlc_neg_hits = 0;
1771 1772  static int nfs_lookup_dnlc_disappears = 0;
1772 1773  static int nfs_lookup_dnlc_lookups = 0;
1773 1774  #endif
1774 1775  
1775 1776  /* ARGSUSED */
↓ open down ↓ 1170 lines elided ↑ open up ↑
2946 2947  }
2947 2948  
2948 2949  #ifdef DEBUG
2949 2950  static int nfs_readdir_cache_hits = 0;
2950 2951  static int nfs_readdir_cache_shorts = 0;
2951 2952  static int nfs_readdir_cache_waits = 0;
2952 2953  static int nfs_readdir_cache_misses = 0;
2953 2954  static int nfs_readdir_readahead = 0;
2954 2955  #endif
2955 2956  
2956      -static int nfs_shrinkreaddir = 0;
     2957 +volatile int nfs_shrinkreaddir = 0;
2957 2958  
2958 2959  /*
2959 2960   * Read directory entries.
2960 2961   * There are some weird things to look out for here.  The uio_offset
2961 2962   * field is either 0 or it is the offset returned from a previous
2962 2963   * readdir.  It is an opaque value used by the server to find the
2963 2964   * correct directory block to read. The count field is the number
2964 2965   * of blocks to read on the server.  This is advisory only, the server
2965 2966   * may return only one block's worth of entries.  Entries may be compressed
2966 2967   * on the server.
↓ open down ↓ 312 lines elided ↑ open up ↑
3279 3280                  fi.vp = vp;
3280 3281                  fi.fhp = (caddr_t)&rda.rda_fh;
3281 3282                  fi.copyproc = nfscopyfh;
3282 3283                  fi.lookupproc = nfslookup;
3283 3284                  fi.xattrdirproc = acl_getxattrdir2;
3284 3285                  fip = &fi;
3285 3286          } else {
3286 3287                  fip = NULL;
3287 3288          }
3288 3289  
3289      -        rd.rd_entries = kmem_alloc(rdc->buflen, KM_SLEEP);
     3290 +        rd.rd_dirents = kmem_alloc(rdc->buflen, KM_SLEEP);
3290 3291          rd.rd_size = count;
3291 3292          rd.rd_offset = rda.rda_offset;
3292 3293  
3293 3294          douprintf = 1;
3294 3295  
3295 3296          if (mi->mi_io_kstats) {
3296 3297                  mutex_enter(&mi->mi_lock);
3297 3298                  kstat_runq_enter(KSTAT_IO_PTR(mi->mi_io_kstats));
3298 3299                  mutex_exit(&mi->mi_lock);
3299 3300          }
↓ open down ↓ 29 lines elided ↑ open up ↑
3329 3330                          rdc->nfs_ncookie = rd.rd_offset;
3330 3331                          rdc->eof = rd.rd_eof ? 1 : 0;
3331 3332                          rdc->entlen = rd.rd_size;
3332 3333                          ASSERT(rdc->entlen <= rdc->buflen);
3333 3334  #ifdef DEBUG
3334 3335                          rdc->entries = rddir_cache_buf_alloc(rdc->buflen,
3335 3336                              KM_SLEEP);
3336 3337  #else
3337 3338                          rdc->entries = kmem_alloc(rdc->buflen, KM_SLEEP);
3338 3339  #endif
3339      -                        bcopy(rd.rd_entries, rdc->entries, rdc->entlen);
     3340 +                        bcopy(rd.rd_dirents, rdc->entries, rdc->entlen);
3340 3341                          rdc->error = 0;
3341 3342                          if (mi->mi_io_kstats) {
3342 3343                                  mutex_enter(&mi->mi_lock);
3343 3344                                  KSTAT_IO_PTR(mi->mi_io_kstats)->reads++;
3344 3345                                  KSTAT_IO_PTR(mi->mi_io_kstats)->nread +=
3345 3346                                      rd.rd_size;
3346 3347                                  mutex_exit(&mi->mi_lock);
3347 3348                          }
3348 3349                  } else {
3349 3350                          PURGE_STALE_FH(error, vp, cr);
3350 3351                  }
3351 3352          }
3352 3353          if (error) {
3353 3354                  rdc->entries = NULL;
3354 3355                  rdc->error = error;
3355 3356          }
3356      -        kmem_free(rd.rd_entries, rdc->buflen);
     3357 +        kmem_free(rd.rd_dirents, rdc->buflen);
3357 3358  
3358 3359          mutex_enter(&rp->r_statelock);
3359 3360          rdc->flags &= ~RDDIR;
3360 3361          if (rdc->flags & RDDIRWAIT) {
3361 3362                  rdc->flags &= ~RDDIRWAIT;
3362 3363                  cv_broadcast(&rdc->cv);
3363 3364          }
3364 3365          if (error)
3365 3366                  rdc->flags |= RDDIRREQ;
3366 3367          mutex_exit(&rp->r_statelock);
↓ open down ↓ 239 lines elided ↑ open up ↑
3606 3607                  return (0);
3607 3608          if (*noffp < 0 || *noffp > MAXOFF32_T)
3608 3609                  return (EINVAL);
3609 3610          return (0);
3610 3611  }
3611 3612  
3612 3613  /*
3613 3614   * number of NFS_MAXDATA blocks to read ahead
3614 3615   * optimized for 100 base-T.
3615 3616   */
3616      -static int nfs_nra = 4;
     3617 +volatile int nfs_nra = 4;
3617 3618  
3618 3619  #ifdef DEBUG
3619 3620  static int nfs_lostpage = 0;    /* number of times we lost original page */
3620 3621  #endif
3621 3622  
3622 3623  /*
3623 3624   * Return all the pages from [off..off+len) in file
3624 3625   */
3625 3626  /* ARGSUSED */
3626 3627  static int
↓ open down ↓ 1470 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX