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);
|