276 */
277 const fs_operation_def_t port_vfssrc_template[] = {
278 VFSNAME_UNMOUNT, { .fsemop_unmount = port_fop_unmount },
279 NULL, NULL
280 };
281
282 fem_t *fop_femop;
283 fsem_t *fop_fsemop;
284
285 static fem_t *
286 port_fop_femop()
287 {
288 fem_t *femp;
289 if (fop_femop != NULL)
290 return (fop_femop);
291 if (fem_create("portfop_fem",
292 (const struct fs_operation_def *)port_vnodesrc_template,
293 (fem_t **)&femp)) {
294 return (NULL);
295 }
296 if (casptr(&fop_femop, NULL, femp) != NULL) {
297 /*
298 * some other thread beat us to it.
299 */
300 fem_free(femp);
301 }
302 return (fop_femop);
303 }
304
305 static fsem_t *
306 port_fop_fsemop()
307 {
308 fsem_t *fsemp;
309 if (fop_fsemop != NULL)
310 return (fop_fsemop);
311 if (fsem_create("portfop_fsem", port_vfssrc_template, &fsemp)) {
312 return (NULL);
313 }
314 if (casptr(&fop_fsemop, NULL, fsemp) != NULL) {
315 /*
316 * some other thread beat us to it.
317 */
318 fsem_free(fsemp);
319 }
320 return (fop_fsemop);
321 }
322
323 /*
324 * port_fop_callback()
325 * - PORT_CALLBACK_DEFAULT
326 * The file event will be delivered to the application.
327 * - PORT_CALLBACK_DISSOCIATE
328 * The object will be dissociated from the port.
329 * - PORT_CALLBACK_CLOSE
330 * The object will be dissociated from the port because the port
331 * is being closed.
332 */
333 /* ARGSUSED */
334 static int
1070
1071 /*
1072 * Installs the portfop_vp_t data structure on the
1073 * vnode. The 'pvp_femp == NULL' indicates it is not
1074 * active. The fem hooks have to be installed.
1075 * The portfop_vp_t is only freed when the vnode gets freed.
1076 */
1077 void
1078 port_install_fopdata(vnode_t *vp)
1079 {
1080 portfop_vp_t *npvp;
1081
1082 npvp = kmem_zalloc(sizeof (*npvp), KM_SLEEP);
1083 mutex_init(&npvp->pvp_mutex, NULL, MUTEX_DEFAULT, NULL);
1084 list_create(&npvp->pvp_pfoplist, sizeof (portfop_t),
1085 offsetof(portfop_t, pfop_node));
1086 npvp->pvp_vp = vp;
1087 /*
1088 * If v_fopdata is not null, some other thread beat us to it.
1089 */
1090 if (casptr(&vp->v_fopdata, NULL, npvp) != NULL) {
1091 mutex_destroy(&npvp->pvp_mutex);
1092 list_destroy(&npvp->pvp_pfoplist);
1093 kmem_free(npvp, sizeof (*npvp));
1094 }
1095 }
1096
1097
1098 /*
1099 * Allocate and add a portfop_t to the per port cache. Also add the portfop_t
1100 * to the vnode's list. The association is identified by the object pointer
1101 * address and pid.
1102 */
1103 int
1104 port_pfp_setup(portfop_t **pfpp, port_t *pp, vnode_t *vp, portfop_cache_t *pfcp,
1105 uintptr_t object, int events, void *user, char *cname, int clen,
1106 vnode_t *dvp)
1107 {
1108 portfop_t *pfp = NULL;
1109 port_kevent_t *pkevp;
1110 fem_t *femp;
|
276 */
277 const fs_operation_def_t port_vfssrc_template[] = {
278 VFSNAME_UNMOUNT, { .fsemop_unmount = port_fop_unmount },
279 NULL, NULL
280 };
281
282 fem_t *fop_femop;
283 fsem_t *fop_fsemop;
284
285 static fem_t *
286 port_fop_femop()
287 {
288 fem_t *femp;
289 if (fop_femop != NULL)
290 return (fop_femop);
291 if (fem_create("portfop_fem",
292 (const struct fs_operation_def *)port_vnodesrc_template,
293 (fem_t **)&femp)) {
294 return (NULL);
295 }
296 if (atomic_cas_ptr(&fop_femop, NULL, femp) != NULL) {
297 /*
298 * some other thread beat us to it.
299 */
300 fem_free(femp);
301 }
302 return (fop_femop);
303 }
304
305 static fsem_t *
306 port_fop_fsemop()
307 {
308 fsem_t *fsemp;
309 if (fop_fsemop != NULL)
310 return (fop_fsemop);
311 if (fsem_create("portfop_fsem", port_vfssrc_template, &fsemp)) {
312 return (NULL);
313 }
314 if (atomic_cas_ptr(&fop_fsemop, NULL, fsemp) != NULL) {
315 /*
316 * some other thread beat us to it.
317 */
318 fsem_free(fsemp);
319 }
320 return (fop_fsemop);
321 }
322
323 /*
324 * port_fop_callback()
325 * - PORT_CALLBACK_DEFAULT
326 * The file event will be delivered to the application.
327 * - PORT_CALLBACK_DISSOCIATE
328 * The object will be dissociated from the port.
329 * - PORT_CALLBACK_CLOSE
330 * The object will be dissociated from the port because the port
331 * is being closed.
332 */
333 /* ARGSUSED */
334 static int
1070
1071 /*
1072 * Installs the portfop_vp_t data structure on the
1073 * vnode. The 'pvp_femp == NULL' indicates it is not
1074 * active. The fem hooks have to be installed.
1075 * The portfop_vp_t is only freed when the vnode gets freed.
1076 */
1077 void
1078 port_install_fopdata(vnode_t *vp)
1079 {
1080 portfop_vp_t *npvp;
1081
1082 npvp = kmem_zalloc(sizeof (*npvp), KM_SLEEP);
1083 mutex_init(&npvp->pvp_mutex, NULL, MUTEX_DEFAULT, NULL);
1084 list_create(&npvp->pvp_pfoplist, sizeof (portfop_t),
1085 offsetof(portfop_t, pfop_node));
1086 npvp->pvp_vp = vp;
1087 /*
1088 * If v_fopdata is not null, some other thread beat us to it.
1089 */
1090 if (atomic_cas_ptr(&vp->v_fopdata, NULL, npvp) != NULL) {
1091 mutex_destroy(&npvp->pvp_mutex);
1092 list_destroy(&npvp->pvp_pfoplist);
1093 kmem_free(npvp, sizeof (*npvp));
1094 }
1095 }
1096
1097
1098 /*
1099 * Allocate and add a portfop_t to the per port cache. Also add the portfop_t
1100 * to the vnode's list. The association is identified by the object pointer
1101 * address and pid.
1102 */
1103 int
1104 port_pfp_setup(portfop_t **pfpp, port_t *pp, vnode_t *vp, portfop_cache_t *pfcp,
1105 uintptr_t object, int events, void *user, char *cname, int clen,
1106 vnode_t *dvp)
1107 {
1108 portfop_t *pfp = NULL;
1109 port_kevent_t *pkevp;
1110 fem_t *femp;
|