Print this page
basic fsh prototype (no comments yet)


  48 #include <sys/vfs.h>
  49 #include <sys/vfs_opreg.h>
  50 #include <sys/vnode.h>
  51 #include <sys/rwstlock.h>
  52 #include <sys/fem.h>
  53 #include <sys/stat.h>
  54 #include <sys/mode.h>
  55 #include <sys/conf.h>
  56 #include <sys/sysmacros.h>
  57 #include <sys/cmn_err.h>
  58 #include <sys/systm.h>
  59 #include <sys/kmem.h>
  60 #include <sys/debug.h>
  61 #include <c2/audit.h>
  62 #include <sys/acl.h>
  63 #include <sys/nbmlock.h>
  64 #include <sys/fcntl.h>
  65 #include <fs/fs_subr.h>
  66 #include <sys/taskq.h>
  67 #include <fs/fs_reparse.h>

  68 
  69 /* Determine if this vnode is a file that is read-only */
  70 #define ISROFILE(vp)    \
  71         ((vp)->v_type != VCHR && (vp)->v_type != VBLK && \
  72             (vp)->v_type != VFIFO && vn_is_readonly(vp))
  73 
  74 /* Tunable via /etc/system; used only by admin/install */
  75 int nfs_global_client_only;
  76 
  77 /*
  78  * Array of vopstats_t for per-FS-type vopstats.  This array has the same
  79  * number of entries as and parallel to the vfssw table.  (Arguably, it could
  80  * be part of the vfssw table.)  Once it's initialized, it's accessed using
  81  * the same fstype index that is used to index into the vfssw table.
  82  */
  83 vopstats_t **vopstats_fstype;
  84 
  85 /* vopstats initialization template used for fast initialization via bcopy() */
  86 static vopstats_t *vs_templatep;
  87 


3125          * Adding to the vnode counts before calling open
3126          * avoids the need for a mutex. It circumvents a race
3127          * condition where a query made on the vnode counts results in a
3128          * false negative. The inquirer goes away believing the file is
3129          * not open when there is an open on the file already under way.
3130          *
3131          * The counts are meant to prevent NFS from granting a delegation
3132          * when it would be dangerous to do so.
3133          *
3134          * The vnode counts are only kept on regular files
3135          */
3136         if ((*vpp)->v_type == VREG) {
3137                 if (mode & FREAD)
3138                         atomic_add_32(&((*vpp)->v_rdcnt), 1);
3139                 if (mode & FWRITE)
3140                         atomic_add_32(&((*vpp)->v_wrcnt), 1);
3141         }
3142 
3143         VOPXID_MAP_CR(vp, cr);
3144 
3145         ret = (*(*(vpp))->v_op->vop_open)(vpp, mode, cr, ct);




3146 
3147         if (ret) {
3148                 /*
3149                  * Use the saved vp just in case the vnode ptr got trashed
3150                  * by the error.
3151                  */
3152                 VOPSTATS_UPDATE(vp, open);
3153                 if ((vp->v_type == VREG) && (mode & FREAD))
3154                         atomic_add_32(&(vp->v_rdcnt), -1);
3155                 if ((vp->v_type == VREG) && (mode & FWRITE))
3156                         atomic_add_32(&(vp->v_wrcnt), -1);
3157         } else {
3158                 /*
3159                  * Some filesystems will return a different vnode,
3160                  * but the same path was still used to open it.
3161                  * So if we do change the vnode and need to
3162                  * copy over the path, do so here, rather than special
3163                  * casing each filesystem. Adjust the vnode counts to
3164                  * reflect the vnode switch.
3165                  */


3176                                 atomic_add_32(&(vp->v_wrcnt), -1);
3177                 }
3178         }
3179         VN_RELE(vp);
3180         return (ret);
3181 }
3182 
3183 int
3184 fop_close(
3185         vnode_t *vp,
3186         int flag,
3187         int count,
3188         offset_t offset,
3189         cred_t *cr,
3190         caller_context_t *ct)
3191 {
3192         int err;
3193 
3194         VOPXID_MAP_CR(vp, cr);
3195 
3196         err = (*(vp)->v_op->vop_close)(vp, flag, count, offset, cr, ct);
3197         VOPSTATS_UPDATE(vp, close);
3198         /*
3199          * Check passed in count to handle possible dups. Vnode counts are only
3200          * kept on regular files
3201          */
3202         if ((vp->v_type == VREG) && (count == 1))  {
3203                 if (flag & FREAD) {
3204                         ASSERT(vp->v_rdcnt > 0);
3205                         atomic_add_32(&(vp->v_rdcnt), -1);
3206                 }
3207                 if (flag & FWRITE) {
3208                         ASSERT(vp->v_wrcnt > 0);
3209                         atomic_add_32(&(vp->v_wrcnt), -1);
3210                 }
3211         }
3212         return (err);
3213 }
3214 
3215 int
3216 fop_read(
3217         vnode_t *vp,
3218         uio_t *uiop,
3219         int ioflag,
3220         cred_t *cr,
3221         caller_context_t *ct)
3222 {
3223         int     err;
3224         ssize_t resid_start = uiop->uio_resid;
3225 
3226         VOPXID_MAP_CR(vp, cr);
3227 
3228         err = (*(vp)->v_op->vop_read)(vp, uiop, ioflag, cr, ct);
3229         VOPSTATS_UPDATE_IO(vp, read,
3230             read_bytes, (resid_start - uiop->uio_resid));
3231         return (err);
3232 }
3233 
3234 int
3235 fop_write(
3236         vnode_t *vp,
3237         uio_t *uiop,
3238         int ioflag,
3239         cred_t *cr,
3240         caller_context_t *ct)
3241 {
3242         int     err;
3243         ssize_t resid_start = uiop->uio_resid;
3244 
3245         VOPXID_MAP_CR(vp, cr);
3246 
3247         err = (*(vp)->v_op->vop_write)(vp, uiop, ioflag, cr, ct);
3248         VOPSTATS_UPDATE_IO(vp, write,
3249             write_bytes, (resid_start - uiop->uio_resid));
3250         return (err);
3251 }
3252 
3253 int
3254 fop_ioctl(
3255         vnode_t *vp,
3256         int cmd,
3257         intptr_t arg,
3258         int flag,
3259         cred_t *cr,
3260         int *rvalp,
3261         caller_context_t *ct)
3262 {
3263         int     err;
3264 
3265         VOPXID_MAP_CR(vp, cr);
3266 
3267         err = (*(vp)->v_op->vop_ioctl)(vp, cmd, arg, flag, cr, rvalp, ct);




  48 #include <sys/vfs.h>
  49 #include <sys/vfs_opreg.h>
  50 #include <sys/vnode.h>
  51 #include <sys/rwstlock.h>
  52 #include <sys/fem.h>
  53 #include <sys/stat.h>
  54 #include <sys/mode.h>
  55 #include <sys/conf.h>
  56 #include <sys/sysmacros.h>
  57 #include <sys/cmn_err.h>
  58 #include <sys/systm.h>
  59 #include <sys/kmem.h>
  60 #include <sys/debug.h>
  61 #include <c2/audit.h>
  62 #include <sys/acl.h>
  63 #include <sys/nbmlock.h>
  64 #include <sys/fcntl.h>
  65 #include <fs/fs_subr.h>
  66 #include <sys/taskq.h>
  67 #include <fs/fs_reparse.h>
  68 #include <sys/fsh_impl.h>
  69 
  70 /* Determine if this vnode is a file that is read-only */
  71 #define ISROFILE(vp)    \
  72         ((vp)->v_type != VCHR && (vp)->v_type != VBLK && \
  73             (vp)->v_type != VFIFO && vn_is_readonly(vp))
  74 
  75 /* Tunable via /etc/system; used only by admin/install */
  76 int nfs_global_client_only;
  77 
  78 /*
  79  * Array of vopstats_t for per-FS-type vopstats.  This array has the same
  80  * number of entries as and parallel to the vfssw table.  (Arguably, it could
  81  * be part of the vfssw table.)  Once it's initialized, it's accessed using
  82  * the same fstype index that is used to index into the vfssw table.
  83  */
  84 vopstats_t **vopstats_fstype;
  85 
  86 /* vopstats initialization template used for fast initialization via bcopy() */
  87 static vopstats_t *vs_templatep;
  88 


3126          * Adding to the vnode counts before calling open
3127          * avoids the need for a mutex. It circumvents a race
3128          * condition where a query made on the vnode counts results in a
3129          * false negative. The inquirer goes away believing the file is
3130          * not open when there is an open on the file already under way.
3131          *
3132          * The counts are meant to prevent NFS from granting a delegation
3133          * when it would be dangerous to do so.
3134          *
3135          * The vnode counts are only kept on regular files
3136          */
3137         if ((*vpp)->v_type == VREG) {
3138                 if (mode & FREAD)
3139                         atomic_add_32(&((*vpp)->v_rdcnt), 1);
3140                 if (mode & FWRITE)
3141                         atomic_add_32(&((*vpp)->v_wrcnt), 1);
3142         }
3143 
3144         VOPXID_MAP_CR(vp, cr);
3145 
3146         /*
3147          * Control is passed to fsh. In the end, underlying vop_vopen()
3148          * is called.
3149          */
3150         ret = fsh_open(vpp, mode, cr, ct);
3151 
3152         if (ret) {
3153                 /*
3154                  * Use the saved vp just in case the vnode ptr got trashed
3155                  * by the error.
3156                  */
3157                 VOPSTATS_UPDATE(vp, open);
3158                 if ((vp->v_type == VREG) && (mode & FREAD))
3159                         atomic_add_32(&(vp->v_rdcnt), -1);
3160                 if ((vp->v_type == VREG) && (mode & FWRITE))
3161                         atomic_add_32(&(vp->v_wrcnt), -1);
3162         } else {
3163                 /*
3164                  * Some filesystems will return a different vnode,
3165                  * but the same path was still used to open it.
3166                  * So if we do change the vnode and need to
3167                  * copy over the path, do so here, rather than special
3168                  * casing each filesystem. Adjust the vnode counts to
3169                  * reflect the vnode switch.
3170                  */


3181                                 atomic_add_32(&(vp->v_wrcnt), -1);
3182                 }
3183         }
3184         VN_RELE(vp);
3185         return (ret);
3186 }
3187 
3188 int
3189 fop_close(
3190         vnode_t *vp,
3191         int flag,
3192         int count,
3193         offset_t offset,
3194         cred_t *cr,
3195         caller_context_t *ct)
3196 {
3197         int err;
3198 
3199         VOPXID_MAP_CR(vp, cr);
3200 
3201         err = fsh_close(vp, flag, count, offset, cr, ct);
3202         VOPSTATS_UPDATE(vp, close);
3203         /*
3204          * Check passed in count to handle possible dups. Vnode counts are only
3205          * kept on regular files
3206          */
3207         if ((vp->v_type == VREG) && (count == 1))  {
3208                 if (flag & FREAD) {
3209                         ASSERT(vp->v_rdcnt > 0);
3210                         atomic_add_32(&(vp->v_rdcnt), -1);
3211                 }
3212                 if (flag & FWRITE) {
3213                         ASSERT(vp->v_wrcnt > 0);
3214                         atomic_add_32(&(vp->v_wrcnt), -1);
3215                 }
3216         }
3217         return (err);
3218 }
3219 
3220 int
3221 fop_read(
3222         vnode_t *vp,
3223         uio_t *uiop,
3224         int ioflag,
3225         cred_t *cr,
3226         caller_context_t *ct)
3227 {
3228         int     err;
3229         ssize_t resid_start = uiop->uio_resid;
3230 
3231         VOPXID_MAP_CR(vp, cr);
3232 
3233         err = fsh_read(vp, uiop, ioflag, cr, ct);
3234         VOPSTATS_UPDATE_IO(vp, read,
3235             read_bytes, (resid_start - uiop->uio_resid));
3236         return (err);
3237 }
3238 
3239 int
3240 fop_write(
3241         vnode_t *vp,
3242         uio_t *uiop,
3243         int ioflag,
3244         cred_t *cr,
3245         caller_context_t *ct)
3246 {
3247         int     err;
3248         ssize_t resid_start = uiop->uio_resid;
3249 
3250         VOPXID_MAP_CR(vp, cr);
3251 
3252         err = fsh_write(vp, uiop, ioflag, cr, ct);
3253         VOPSTATS_UPDATE_IO(vp, write,
3254             write_bytes, (resid_start - uiop->uio_resid));
3255         return (err);
3256 }
3257 
3258 int
3259 fop_ioctl(
3260         vnode_t *vp,
3261         int cmd,
3262         intptr_t arg,
3263         int flag,
3264         cred_t *cr,
3265         int *rvalp,
3266         caller_context_t *ct)
3267 {
3268         int     err;
3269 
3270         VOPXID_MAP_CR(vp, cr);
3271 
3272         err = (*(vp)->v_op->vop_ioctl)(vp, cmd, arg, flag, cr, rvalp, ct);