Print this page
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16

*** 22,31 **** --- 22,35 ---- /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ + /* + * Copyright 2018 Nexenta Systems, Inc. + */ + #include <fs/fs_subr.h> #include <sys/errno.h> #include <sys/file.h> #include <sys/kmem.h>
*** 43,84 **** /* * sharefs_snap_create: create a large character buffer with * the shares enumerated. */ static int ! sharefs_snap_create(shnode_t *sft) { sharetab_t *sht; share_t *sh; size_t sWritten = 0; int iCount = 0; char *buf; ! rw_enter(&sharefs_lock, RW_WRITER); ! rw_enter(&sharetab_lock, RW_READER); if (sft->sharefs_snap) { /* * Nothing has changed, so no need to grab a new copy! */ ! if (sft->sharefs_generation == sharetab_generation) { ! rw_exit(&sharetab_lock); ! rw_exit(&sharefs_lock); return (0); } ASSERT(sft->sharefs_size != 0); kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_snap = NULL; } ! sft->sharefs_size = sharetab_size; ! sft->sharefs_count = sharetab_count; if (sft->sharefs_size == 0) { ! rw_exit(&sharetab_lock); ! rw_exit(&sharefs_lock); return (0); } sft->sharefs_snap = kmem_zalloc(sft->sharefs_size + 1, KM_SLEEP); --- 47,88 ---- /* * sharefs_snap_create: create a large character buffer with * the shares enumerated. */ static int ! sharefs_snap_create(sharetab_globals_t *sg, shnode_t *sft) { sharetab_t *sht; share_t *sh; size_t sWritten = 0; int iCount = 0; char *buf; ! rw_enter(&sg->sharefs_lock, RW_WRITER); ! rw_enter(&sg->sharetab_lock, RW_READER); if (sft->sharefs_snap) { /* * Nothing has changed, so no need to grab a new copy! */ ! if (sft->sharefs_generation == sg->sharetab_generation) { ! rw_exit(&sg->sharetab_lock); ! rw_exit(&sg->sharefs_lock); return (0); } ASSERT(sft->sharefs_size != 0); kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_snap = NULL; } ! sft->sharefs_size = sg->sharetab_size; ! sft->sharefs_count = sg->sharetab_count; if (sft->sharefs_size == 0) { ! rw_exit(&sg->sharetab_lock); ! rw_exit(&sg->sharefs_lock); return (0); } sft->sharefs_snap = kmem_zalloc(sft->sharefs_size + 1, KM_SLEEP);
*** 85,95 **** buf = sft->sharefs_snap; /* * Walk the Sharetab, dumping each entry. */ ! for (sht = sharefs_sharetab; sht != NULL; sht = sht->s_next) { int i; for (i = 0; i < SHARETAB_HASHES; i++) { for (sh = sht->s_buckets[i].ssh_sh; sh != NULL; --- 89,99 ---- buf = sft->sharefs_snap; /* * Walk the Sharetab, dumping each entry. */ ! for (sht = sg->sharefs_sharetab; sht != NULL; sht = sht->s_next) { int i; for (i = 0; i < SHARETAB_HASHES; i++) { for (sh = sht->s_buckets[i].ssh_sh; sh != NULL;
*** 130,157 **** /* * We want to record the generation number and * mtime inside this snapshot. */ ! gethrestime(&sharetab_snap_time); ! sft->sharefs_snap_time = sharetab_snap_time; ! sft->sharefs_generation = sharetab_generation; ASSERT(iCount == sft->sharefs_count); ! rw_exit(&sharetab_lock); ! rw_exit(&sharefs_lock); return (0); error_fault: kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_size = 0; sft->sharefs_count = 0; sft->sharefs_snap = NULL; ! rw_exit(&sharetab_lock); ! rw_exit(&sharefs_lock); return (EFAULT); } /* ARGSUSED */ --- 134,161 ---- /* * We want to record the generation number and * mtime inside this snapshot. */ ! gethrestime(&sg->sharetab_snap_time); ! sft->sharefs_snap_time = sg->sharetab_snap_time; ! sft->sharefs_generation = sg->sharetab_generation; ASSERT(iCount == sft->sharefs_count); ! rw_exit(&sg->sharetab_lock); ! rw_exit(&sg->sharefs_lock); return (0); error_fault: kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_size = 0; sft->sharefs_count = 0; sft->sharefs_snap = NULL; ! rw_exit(&sg->sharetab_lock); ! rw_exit(&sg->sharefs_lock); return (EFAULT); } /* ARGSUSED */
*** 159,193 **** sharefs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, caller_context_t *ct) { timestruc_t now; shnode_t *sft = VTOSH(vp); vap->va_type = VREG; vap->va_mode = S_IRUSR | S_IRGRP | S_IROTH; vap->va_nodeid = SHAREFS_INO_FILE; vap->va_nlink = 1; ! rw_enter(&sharefs_lock, RW_READER); /* * If we get asked about a snapped vnode, then * we must report the data in that vnode. * * Else we report what is currently in the * sharetab. */ if (sft->sharefs_real_vp) { ! rw_enter(&sharetab_lock, RW_READER); ! vap->va_size = sharetab_size; ! vap->va_mtime = sharetab_mtime; ! rw_exit(&sharetab_lock); } else { vap->va_size = sft->sharefs_size; vap->va_mtime = sft->sharefs_snap_time; } ! rw_exit(&sharefs_lock); gethrestime(&now); vap->va_atime = vap->va_ctime = now; vap->va_uid = 0; --- 163,198 ---- sharefs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, caller_context_t *ct) { timestruc_t now; shnode_t *sft = VTOSH(vp); + sharetab_globals_t *sg = sharetab_get_globals(vp->v_vfsp->vfs_zone); vap->va_type = VREG; vap->va_mode = S_IRUSR | S_IRGRP | S_IROTH; vap->va_nodeid = SHAREFS_INO_FILE; vap->va_nlink = 1; ! rw_enter(&sg->sharefs_lock, RW_READER); /* * If we get asked about a snapped vnode, then * we must report the data in that vnode. * * Else we report what is currently in the * sharetab. */ if (sft->sharefs_real_vp) { ! rw_enter(&sg->sharetab_lock, RW_READER); ! vap->va_size = sg->sharetab_size; ! vap->va_mtime = sg->sharetab_mtime; ! rw_exit(&sg->sharetab_lock); } else { vap->va_size = sft->sharefs_size; vap->va_mtime = sft->sharefs_snap_time; } ! rw_exit(&sg->sharefs_lock); gethrestime(&now); vap->va_atime = vap->va_ctime = now; vap->va_uid = 0;
*** 257,267 **** /* * Since the sharetab could easily change on us whilst we * are dumping an extremely huge sharetab, we make a copy * of it here and use it to dump instead. */ ! error = sharefs_snap_create(sft); return (error); } /* ARGSUSED */ --- 262,273 ---- /* * Since the sharetab could easily change on us whilst we * are dumping an extremely huge sharetab, we make a copy * of it here and use it to dump instead. */ ! error = sharefs_snap_create(sharetab_get_globals(vp->v_vfsp->vfs_zone), ! sft); return (error); } /* ARGSUSED */
*** 268,292 **** int sharefs_close(vnode_t *vp, int flag, int count, offset_t off, cred_t *cr, caller_context_t *ct) { shnode_t *sft = VTOSH(vp); if (count > 1) return (0); ! rw_enter(&sharefs_lock, RW_WRITER); if (vp->v_count == 1) { if (sft->sharefs_snap != NULL) { kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_size = 0; sft->sharefs_snap = NULL; sft->sharefs_generation = 0; } } atomic_dec_32(&sft->sharefs_refs); ! rw_exit(&sharefs_lock); return (0); } /* ARGSUSED */ --- 274,299 ---- int sharefs_close(vnode_t *vp, int flag, int count, offset_t off, cred_t *cr, caller_context_t *ct) { shnode_t *sft = VTOSH(vp); + sharetab_globals_t *sg = sharetab_get_globals(vp->v_vfsp->vfs_zone); if (count > 1) return (0); ! rw_enter(&sg->sharefs_lock, RW_WRITER); if (vp->v_count == 1) { if (sft->sharefs_snap != NULL) { kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); sft->sharefs_size = 0; sft->sharefs_snap = NULL; sft->sharefs_generation = 0; } } atomic_dec_32(&sft->sharefs_refs); ! rw_exit(&sg->sharefs_lock); return (0); } /* ARGSUSED */
*** 296,359 **** { shnode_t *sft = VTOSH(vp); off_t off = uio->uio_offset; size_t len = uio->uio_resid; int error = 0; ! rw_enter(&sharefs_lock, RW_READER); /* * First check to see if we need to grab a new snapshot. */ if (off == (off_t)0) { ! rw_exit(&sharefs_lock); ! error = sharefs_snap_create(sft); if (error) { return (EFAULT); } ! rw_enter(&sharefs_lock, RW_READER); } /* LINTED */ if (len <= 0 || off >= sft->sharefs_size) { ! rw_exit(&sharefs_lock); return (error); } if ((size_t)(off + len) > sft->sharefs_size) len = sft->sharefs_size - off; if (off < 0 || len > sft->sharefs_size) { ! rw_exit(&sharefs_lock); return (EFAULT); } if (len != 0) { error = uiomove(sft->sharefs_snap + off, len, UIO_READ, uio); } ! rw_exit(&sharefs_lock); return (error); } /* ARGSUSED */ static void sharefs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *tx) { gfs_file_t *fp = vp->v_data; shnode_t *sft; sft = (shnode_t *)gfs_file_inactive(vp); if (sft) { ! rw_enter(&sharefs_lock, RW_WRITER); if (sft->sharefs_snap != NULL) { kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); } kmem_free(sft, fp->gfs_size); ! rw_exit(&sharefs_lock); } } vnode_t * sharefs_create_root_file(vfs_t *vfsp) --- 303,368 ---- { shnode_t *sft = VTOSH(vp); off_t off = uio->uio_offset; size_t len = uio->uio_resid; int error = 0; + sharetab_globals_t *sg = sharetab_get_globals(vp->v_vfsp->vfs_zone); ! rw_enter(&sg->sharefs_lock, RW_READER); /* * First check to see if we need to grab a new snapshot. */ if (off == (off_t)0) { ! rw_exit(&sg->sharefs_lock); ! error = sharefs_snap_create(sg, sft); if (error) { return (EFAULT); } ! rw_enter(&sg->sharefs_lock, RW_READER); } /* LINTED */ if (len <= 0 || off >= sft->sharefs_size) { ! rw_exit(&sg->sharefs_lock); return (error); } if ((size_t)(off + len) > sft->sharefs_size) len = sft->sharefs_size - off; if (off < 0 || len > sft->sharefs_size) { ! rw_exit(&sg->sharefs_lock); return (EFAULT); } if (len != 0) { error = uiomove(sft->sharefs_snap + off, len, UIO_READ, uio); } ! rw_exit(&sg->sharefs_lock); return (error); } /* ARGSUSED */ static void sharefs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *tx) { gfs_file_t *fp = vp->v_data; shnode_t *sft; + sharetab_globals_t *sg = sharetab_get_globals(vp->v_vfsp->vfs_zone); sft = (shnode_t *)gfs_file_inactive(vp); if (sft) { ! rw_enter(&sg->sharefs_lock, RW_WRITER); if (sft->sharefs_snap != NULL) { kmem_free(sft->sharefs_snap, sft->sharefs_size + 1); } kmem_free(sft, fp->gfs_size); ! rw_exit(&sg->sharefs_lock); } } vnode_t * sharefs_create_root_file(vfs_t *vfsp)