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 ret = fsh_open(vpp, mode, cr, ct);
3147
3148 if (ret) {
3149 /*
3150 * Use the saved vp just in case the vnode ptr got trashed
3151 * by the error.
3152 */
3153 VOPSTATS_UPDATE(vp, open);
3154 if ((vp->v_type == VREG) && (mode & FREAD))
3155 atomic_add_32(&(vp->v_rdcnt), -1);
3156 if ((vp->v_type == VREG) && (mode & FWRITE))
3157 atomic_add_32(&(vp->v_wrcnt), -1);
3158 } else {
3159 /*
3160 * Some filesystems will return a different vnode,
3161 * but the same path was still used to open it.
3162 * So if we do change the vnode and need to
3163 * copy over the path, do so here, rather than special
3164 * casing each filesystem. Adjust the vnode counts to
3165 * reflect the vnode switch.
3166 */
3177 atomic_add_32(&(vp->v_wrcnt), -1);
3178 }
3179 }
3180 VN_RELE(vp);
3181 return (ret);
3182 }
3183
3184 int
3185 fop_close(
3186 vnode_t *vp,
3187 int flag,
3188 int count,
3189 offset_t offset,
3190 cred_t *cr,
3191 caller_context_t *ct)
3192 {
3193 int err;
3194
3195 VOPXID_MAP_CR(vp, cr);
3196
3197 err = fsh_close(vp, flag, count, offset, cr, ct);
3198 VOPSTATS_UPDATE(vp, close);
3199 /*
3200 * Check passed in count to handle possible dups. Vnode counts are only
3201 * kept on regular files
3202 */
3203 if ((vp->v_type == VREG) && (count == 1)) {
3204 if (flag & FREAD) {
3205 ASSERT(vp->v_rdcnt > 0);
3206 atomic_add_32(&(vp->v_rdcnt), -1);
3207 }
3208 if (flag & FWRITE) {
3209 ASSERT(vp->v_wrcnt > 0);
3210 atomic_add_32(&(vp->v_wrcnt), -1);
3211 }
3212 }
3213 return (err);
3214 }
3215
3216 int
3217 fop_read(
3218 vnode_t *vp,
3219 uio_t *uiop,
3220 int ioflag,
3221 cred_t *cr,
3222 caller_context_t *ct)
3223 {
3224 int err;
3225 ssize_t resid_start = uiop->uio_resid;
3226
3227 VOPXID_MAP_CR(vp, cr);
3228
3229 err = fsh_read(vp, uiop, ioflag, cr, ct);
3230 VOPSTATS_UPDATE_IO(vp, read,
3231 read_bytes, (resid_start - uiop->uio_resid));
3232 return (err);
3233 }
3234
3235 int
3236 fop_write(
3237 vnode_t *vp,
3238 uio_t *uiop,
3239 int ioflag,
3240 cred_t *cr,
3241 caller_context_t *ct)
3242 {
3243 int err;
3244 ssize_t resid_start = uiop->uio_resid;
3245
3246 VOPXID_MAP_CR(vp, cr);
3247
3248 err = fsh_write(vp, uiop, ioflag, cr, ct);
3249 VOPSTATS_UPDATE_IO(vp, write,
3250 write_bytes, (resid_start - uiop->uio_resid));
3251 return (err);
3252 }
3253
3254 int
3255 fop_ioctl(
3256 vnode_t *vp,
3257 int cmd,
3258 intptr_t arg,
3259 int flag,
3260 cred_t *cr,
3261 int *rvalp,
3262 caller_context_t *ct)
3263 {
3264 int err;
3265
3266 VOPXID_MAP_CR(vp, cr);
3267
3268 err = (*(vp)->v_op->vop_ioctl)(vp, cmd, arg, flag, cr, rvalp, ct);
|