911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER START
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * The contents of this file are subject to the terms of the
911106dfb16696472af8c1b7b4c554a829354fa8jm * Common Development and Distribution License (the "License").
911106dfb16696472af8c1b7b4c554a829354fa8jm * You may not use this file except in compliance with the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
911106dfb16696472af8c1b7b4c554a829354fa8jm * or http://www.opensolaris.org/os/licensing.
911106dfb16696472af8c1b7b4c554a829354fa8jm * See the License for the specific language governing permissions
911106dfb16696472af8c1b7b4c554a829354fa8jm * and limitations under the License.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * When distributing Covered Code, include this CDDL HEADER in each
911106dfb16696472af8c1b7b4c554a829354fa8jm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If applicable, add the following below this CDDL HEADER, with the
911106dfb16696472af8c1b7b4c554a829354fa8jm * fields enclosed by brackets "[]" replaced with your own identifying
911106dfb16696472af8c1b7b4c554a829354fa8jm * information: Portions Copyright [yyyy] [name of copyright owner]
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * CDDL HEADER END
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
911106dfb16696472af8c1b7b4c554a829354fa8jm * Use is subject to license terms.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/stat.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/ddi.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/sunddi.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/time.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/varargs.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/conf.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/modctl.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/cmn_err.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/vnode.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <fs/fs_subr.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/types.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/file.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/disp.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/sdt.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/cred.h>
bfc848c632c9eacb2a640246d96e198f1b185c03jm#include <sys/list.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm#include <sys/vscan.h>
5c5f137104b2d56181283389fa902220f2023809Richard Lowe#include <sys/sysmacros.h>
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_REQ_MAGIC 0x52515354 /* 'RQST' */
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_REQS_DEFAULT 20000 /* pending scan requests - reql */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_NODES_DEFAULT 128 /* concurrent file scans */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_WORKERS_DEFAULT 32 /* worker threads */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_SCANWAIT_DEFAULT 15*60 /* seconds to wait for scan result */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_REQL_HANDLER_TIMEOUT 30
911106dfb16696472af8c1b7b4c554a829354fa8jm#define VS_EXT_RECURSE_DEPTH 8
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* access derived from scan result (VS_STATUS_XXX) and file attributes */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_ACCESS_UNDEFINED 0
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_ACCESS_ALLOW 1 /* return 0 */
bfc848c632c9eacb2a640246d96e198f1b185c03jm#define VS_ACCESS_DENY 2 /* return EACCES */
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm#define tolower(C) (((C) >= 'A' && (C) <= 'Z') ? (C) - 'A' + 'a' : (C))
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* global variables - tunable via /etc/system */
bfc848c632c9eacb2a640246d96e198f1b185c03jmuint32_t vs_reqs_max = VS_REQS_DEFAULT; /* max scan requests */
bfc848c632c9eacb2a640246d96e198f1b185c03jmuint32_t vs_nodes_max = VS_NODES_DEFAULT; /* max in-progress scan requests */
bfc848c632c9eacb2a640246d96e198f1b185c03jmuint32_t vs_workers = VS_WORKERS_DEFAULT; /* max workers send reqs to vscand */
bfc848c632c9eacb2a640246d96e198f1b185c03jmuint32_t vs_scan_wait = VS_SCANWAIT_DEFAULT; /* secs to wait for scan result */
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_state
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_UNCONFIG |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | ^
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | svc_init | svc_fini
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_IDLE |<----|
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | svc_enable |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * |<----------------| |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+ | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_ENABLED |--| |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | svc_disable | handler thread exit,
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v | all requests complete
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_DISABLED |-----|
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +-----------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * svc_enable may occur when we are already in the ENABLED
bfc848c632c9eacb2a640246d96e198f1b185c03jm * state if vscand has exited without clean shutdown and
bfc848c632c9eacb2a640246d96e198f1b185c03jm * then reconnected within the delayed disable time period
bfc848c632c9eacb2a640246d96e198f1b185c03jm * (vs_reconnect_timeout) - see vscan_drv
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jmtypedef enum {
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_UNCONFIG,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_IDLE,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_ENABLED, /* service enabled and registered */
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_DISABLED /* service disabled and nunregistered */
bfc848c632c9eacb2a640246d96e198f1b185c03jm} vscan_svc_state_t;
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_svc_state_t vscan_svc_state = VS_SVC_UNCONFIG;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_req_state
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * When a scan request is received from the file system it is
bfc848c632c9eacb2a640246d96e198f1b185c03jm * identified in or inserted into the vscan_svc_reql (INIT).
bfc848c632c9eacb2a640246d96e198f1b185c03jm * If the request is asynchronous 0 is then returned to the caller.
bfc848c632c9eacb2a640246d96e198f1b185c03jm * If the request is synchronous the req's refcnt is incremented
bfc848c632c9eacb2a640246d96e198f1b185c03jm * and the caller waits for the request to complete.
bfc848c632c9eacb2a640246d96e198f1b185c03jm * The refcnt is also incremented when the request is inserted
bfc848c632c9eacb2a640246d96e198f1b185c03jm * in vscan_svc_nodes, and decremented on scan_complete.
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_handler processes requests from the request list,
bfc848c632c9eacb2a640246d96e198f1b185c03jm * inserting them into vscan_svc_nodes and the task queue (QUEUED).
bfc848c632c9eacb2a640246d96e198f1b185c03jm * When the task queue call back (vscan_svc_do_scan) is invoked
bfc848c632c9eacb2a640246d96e198f1b185c03jm * the request transitions to IN_PROGRESS state. If the request
bfc848c632c9eacb2a640246d96e198f1b185c03jm * is sucessfully sent to vscand (door_call) and the door response
bfc848c632c9eacb2a640246d96e198f1b185c03jm * is SCANNING then the scan result will be received asynchronously.
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Although unusual, it is possible that the async response is
bfc848c632c9eacb2a640246d96e198f1b185c03jm * received before the door call returns (hence the ASYNC_COMPLETE
bfc848c632c9eacb2a640246d96e198f1b185c03jm * state).
bfc848c632c9eacb2a640246d96e198f1b185c03jm * When the result has been determined / received,
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_scan_complete is invoked to transition the request to
bfc848c632c9eacb2a640246d96e198f1b185c03jm * COMPLETE state, decrement refcnt and signal all waiting callers.
bfc848c632c9eacb2a640246d96e198f1b185c03jm * When the last waiting caller has processed the result (refcnt == 0)
bfc848c632c9eacb2a640246d96e198f1b185c03jm * the request is removed from vscan_svc_reql and vscan_svc_nodes
bfc848c632c9eacb2a640246d96e198f1b185c03jm * and deleted.
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | ^
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | reql_insert | refcnt == 0
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v | (delete)
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ +---------------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_REQ_INIT | -----DISABLE----> | VS_SVC_REQ_COMPLETE |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ +---------------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | ^
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | insert_req, tq_dispatch |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_REQ_QUEUED | scan_complete
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | tq_callback (do_scan) |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v scan not req'd, error, |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ or door_result != SCANNING |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_REQ_IN_PROGRESS |----------------->-------------|
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +------------------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | | door_result == SCANNING |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | v |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | +---------------------------+ async result |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | | VS_SVC_REQ_SCANNING |-------->---------|
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | +---------------------------+ |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | async result |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * v |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +---------------------------+ door_result = SCANNING |
bfc848c632c9eacb2a640246d96e198f1b185c03jm * | VS_SVC_REQ_ASYNC_COMPLETE |-------->------------------|
bfc848c632c9eacb2a640246d96e198f1b185c03jm * +---------------------------+
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmtypedef enum {
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_INIT,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_QUEUED,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_IN_PROGRESS,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_SCANNING,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_ASYNC_COMPLETE,
bfc848c632c9eacb2a640246d96e198f1b185c03jm VS_SVC_REQ_COMPLETE
bfc848c632c9eacb2a640246d96e198f1b185c03jm} vscan_svc_req_state_t;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_reql - the list of pending and in-progress scan requests
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmtypedef struct vscan_req {
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsr_magic; /* VS_REQ_MAGIC */
bfc848c632c9eacb2a640246d96e198f1b185c03jm list_node_t vsr_lnode;
911106dfb16696472af8c1b7b4c554a829354fa8jm vnode_t *vsr_vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsr_idx; /* vscan_svc_nodes index */
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsr_seqnum; /* unigue request id */
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsr_refcnt;
bfc848c632c9eacb2a640246d96e198f1b185c03jm kcondvar_t vsr_cv;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_req_state_t vsr_state;
bfc848c632c9eacb2a640246d96e198f1b185c03jm} vscan_req_t;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic list_t vscan_svc_reql;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_nodes - table of files being scanned
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * The index into this table is passed in the door call to
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscand. vscand uses the idx to determine which minor node
911106dfb16696472af8c1b7b4c554a829354fa8jm * to open to read the file data. Within the kernel driver
911106dfb16696472af8c1b7b4c554a829354fa8jm * the minor device number can thus be used to identify the
911106dfb16696472af8c1b7b4c554a829354fa8jm * table index to get the appropriate vnode.
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Instance 0 is reserved for the daemon/driver control
911106dfb16696472af8c1b7b4c554a829354fa8jm * interface: enable/configure/disable
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmtypedef struct vscan_svc_node {
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *vsn_req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint8_t vsn_quarantined;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint8_t vsn_modified;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint64_t vsn_size;
bfc848c632c9eacb2a640246d96e198f1b185c03jm timestruc_t vsn_mtime;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vs_scanstamp_t vsn_scanstamp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsn_result;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsn_access;
bfc848c632c9eacb2a640246d96e198f1b185c03jm} vscan_svc_node_t;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_svc_node_t *vscan_svc_nodes;
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic int vscan_svc_nodes_sz;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* vscan_svc_taskq - queue of requests waiting to be sent to vscand */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic taskq_t *vscan_svc_taskq = NULL;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* counts of entries in vscan_svc_reql, vscan_svc_nodes & vscan_svc_taskq */
bfc848c632c9eacb2a640246d96e198f1b185c03jmtypedef struct {
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsc_reql;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsc_node;
bfc848c632c9eacb2a640246d96e198f1b185c03jm uint32_t vsc_tq;
bfc848c632c9eacb2a640246d96e198f1b185c03jm} vscan_svc_counts_t;
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_svc_counts_t vscan_svc_counts;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_mutex protects the data pertaining to scan requests:
bfc848c632c9eacb2a640246d96e198f1b185c03jm * request list - vscan_svc_reql
bfc848c632c9eacb2a640246d96e198f1b185c03jm * node table - vscan_svc_nodes
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic kmutex_t vscan_svc_mutex;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* unique request id for vscand request/response correlation */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic uint32_t vscan_svc_seqnum = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_cfg_mutex protects the configuration data:
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_config, vscan_svc_types
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic kmutex_t vscan_svc_cfg_mutex;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/* configuration data - for virus scan exemption */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic vs_config_t vscan_svc_config;
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic char *vscan_svc_types[VS_TYPES_MAX];
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* thread to insert reql entries into vscan_svc_nodes & vscan_svc_taskq */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic kthread_t *vscan_svc_reql_thread;
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic kcondvar_t vscan_svc_reql_cv;
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_req_t *vscan_svc_reql_next; /* next pending scan request */
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/* local functions */
911106dfb16696472af8c1b7b4c554a829354fa8jmint vscan_svc_scan_file(vnode_t *, cred_t *, int);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_taskq_callback(void *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscan_svc_exempt_file(vnode_t *, boolean_t *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscan_svc_exempt_filetype(char *);
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscan_svc_match_ext(char *, char *, int);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_do_scan(vscan_req_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vs_scan_req_t *vscan_svc_populate_req(int);
53c110294d8b1410cabc201a52f94b03ae2ef448jmstatic void vscan_svc_process_scan_result(int);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_scan_complete(vscan_req_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_delete_req(vscan_req_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic int vscan_svc_insert_req(vscan_req_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_remove_req(int);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_req_t *vscan_svc_reql_find(vnode_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_req_t *vscan_svc_reql_insert(vnode_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_reql_remove(vscan_req_t *);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int vscan_svc_getattr(int);
53c110294d8b1410cabc201a52f94b03ae2ef448jmstatic int vscan_svc_setattr(int, int);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/* thread to insert reql entries into vscan_svc_nodes & vscan_svc_taskq */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void vscan_svc_reql_handler(void);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_init
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_init()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state != VS_SVC_UNCONFIG) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__svc__state__violation,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, vscan_svc_state);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (-1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_init(&vscan_svc_mutex, NULL, MUTEX_DEFAULT, NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_init(&vscan_svc_cfg_mutex, NULL, MUTEX_DEFAULT, NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_init(&vscan_svc_reql_cv, NULL, CV_DEFAULT, NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_nodes_sz = sizeof (vscan_svc_node_t) * (vs_nodes_max + 1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_nodes = kmem_zalloc(vscan_svc_nodes_sz, KM_SLEEP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_counts.vsc_reql = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_counts.vsc_node = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_counts.vsc_tq = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state = VS_SVC_IDLE;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_fini
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmvoid
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_fini()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state != VS_SVC_IDLE) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__svc__state__violation,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, vscan_svc_state);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm kmem_free(vscan_svc_nodes, vscan_svc_nodes_sz);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_destroy(&vscan_svc_reql_cv);
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_destroy(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_destroy(&vscan_svc_cfg_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state = VS_SVC_UNCONFIG;
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_enable
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmint
53c110294d8b1410cabc201a52f94b03ae2ef448jmvscan_svc_enable(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
53c110294d8b1410cabc201a52f94b03ae2ef448jm mutex_enter(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm switch (vscan_svc_state) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_SVC_ENABLED:
bfc848c632c9eacb2a640246d96e198f1b185c03jm /*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * it's possible (and okay) for vscan_svc_enable to be
bfc848c632c9eacb2a640246d96e198f1b185c03jm * called when already enabled if vscand reconnects
bfc848c632c9eacb2a640246d96e198f1b185c03jm * during a delayed disable
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_SVC_IDLE:
bfc848c632c9eacb2a640246d96e198f1b185c03jm list_create(&vscan_svc_reql, sizeof (vscan_req_t),
bfc848c632c9eacb2a640246d96e198f1b185c03jm offsetof(vscan_req_t, vsr_lnode));
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_next = list_head(&vscan_svc_reql);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_taskq = taskq_create("vscan_taskq", vs_workers,
bfc848c632c9eacb2a640246d96e198f1b185c03jm MINCLSYSPRI, 1, INT_MAX, TASKQ_DYNAMIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(vscan_svc_taskq != NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_thread = thread_create(NULL, 0,
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_handler, 0, 0, &p0, TS_RUN, MINCLSYSPRI);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(vscan_svc_reql_thread != NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* ready to start processing requests */
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state = VS_SVC_ENABLED;
bfc848c632c9eacb2a640246d96e198f1b185c03jm fs_vscan_register(vscan_svc_scan_file);
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm default:
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__svc__state__violation,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, vscan_svc_state);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (-1);
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm/*
53c110294d8b1410cabc201a52f94b03ae2ef448jm * vscan_svc_disable
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Resources allocated during vscan_svc_enable are free'd by
bfc848c632c9eacb2a640246d96e198f1b185c03jm * the handler thread immediately prior to exiting
53c110294d8b1410cabc201a52f94b03ae2ef448jm */
53c110294d8b1410cabc201a52f94b03ae2ef448jmvoid
53c110294d8b1410cabc201a52f94b03ae2ef448jmvscan_svc_disable(void)
53c110294d8b1410cabc201a52f94b03ae2ef448jm{
53c110294d8b1410cabc201a52f94b03ae2ef448jm mutex_enter(&vscan_svc_mutex);
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm switch (vscan_svc_state) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_SVC_ENABLED:
bfc848c632c9eacb2a640246d96e198f1b185c03jm fs_vscan_register(NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state = VS_SVC_DISABLED;
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_signal(&vscan_svc_reql_cv); /* wake handler thread */
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm default:
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__svc__state__violation, int,
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state);
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
53c110294d8b1410cabc201a52f94b03ae2ef448jm}
53c110294d8b1410cabc201a52f94b03ae2ef448jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_in_use
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmboolean_t
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_in_use()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm boolean_t in_use;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_enter(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm switch (vscan_svc_state) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_SVC_IDLE:
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_SVC_UNCONFIG:
bfc848c632c9eacb2a640246d96e198f1b185c03jm in_use = B_FALSE;
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm default:
bfc848c632c9eacb2a640246d96e198f1b185c03jm in_use = B_TRUE;
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (in_use);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_get_vnode
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Get the file vnode indexed by idx.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmvnode_t *
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_get_vnode(int idx)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vnode_t *vp = NULL;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(idx > 0);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(idx <= vs_nodes_max);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_nodes[idx].vsn_req)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vp = vscan_svc_nodes[idx].vsn_req->vsr_vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (vp);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_scan_file
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * This function is the entry point for the file system to
911106dfb16696472af8c1b7b4c554a829354fa8jm * request that a file be virus scanned.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_scan_file(vnode_t *vp, cred_t *cr, int async)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm int access;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
911106dfb16696472af8c1b7b4c554a829354fa8jm boolean_t allow;
bfc848c632c9eacb2a640246d96e198f1b185c03jm clock_t timeout, time_left;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((vp == NULL) || (vp->v_path == NULL) || cr == NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm DTRACE_PROBE2(vscan__scan__file, char *, vp->v_path, int, async);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* check if size or type exempts file from scanning */
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscan_svc_exempt_file(vp, &allow)) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((allow == B_TRUE) || (async != 0))
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (EACCES);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state != VS_SVC_ENABLED) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__svc__state__violation,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, vscan_svc_state);
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (0);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* insert (or find) request in list */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((req = vscan_svc_reql_insert(vp)) == NULL) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm cmn_err(CE_WARN, "Virus scan request list full");
bfc848c632c9eacb2a640246d96e198f1b185c03jm return ((async != 0) ? 0 : EACCES);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* asynchronous request: return 0 */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (async) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (0);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* synchronous scan request: wait for result */
bfc848c632c9eacb2a640246d96e198f1b185c03jm ++(req->vsr_refcnt);
bfc848c632c9eacb2a640246d96e198f1b185c03jm time_left = SEC_TO_TICK(vs_scan_wait);
bfc848c632c9eacb2a640246d96e198f1b185c03jm while ((time_left > 0) && (req->vsr_state != VS_SVC_REQ_COMPLETE)) {
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni timeout = time_left;
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni time_left = cv_reltimedwait_sig(&(req->vsr_cv),
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &vscan_svc_mutex, timeout, TR_CLOCK_TICK);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (time_left == -1) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm cmn_err(CE_WARN, "Virus scan request timeout %s (%d) \n",
bfc848c632c9eacb2a640246d96e198f1b185c03jm vp->v_path, req->vsr_seqnum);
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__scan__timeout, vscan_req_t *, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state == VS_SVC_DISABLED)
bfc848c632c9eacb2a640246d96e198f1b185c03jm access = VS_ACCESS_ALLOW;
bfc848c632c9eacb2a640246d96e198f1b185c03jm else if (req->vsr_idx == 0)
bfc848c632c9eacb2a640246d96e198f1b185c03jm access = VS_ACCESS_DENY;
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm access = vscan_svc_nodes[req->vsr_idx].vsn_access;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((--req->vsr_refcnt) == 0)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_delete_req(req);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return ((access == VS_ACCESS_ALLOW) ? 0 : EACCES);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_reql_handler
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * inserts scan requests (from vscan_svc_reql) into
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_nodes and vscan_svc_taskq
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_reql_handler(void)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req, *next;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm for (;;) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((vscan_svc_state == VS_SVC_DISABLED) &&
bfc848c632c9eacb2a640246d96e198f1b185c03jm (vscan_svc_counts.vsc_reql == 0)) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* free resources allocated durining enable */
bfc848c632c9eacb2a640246d96e198f1b185c03jm taskq_destroy(vscan_svc_taskq);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_taskq = NULL;
bfc848c632c9eacb2a640246d96e198f1b185c03jm list_destroy(&vscan_svc_reql);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_state = VS_SVC_IDLE;
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * If disabled, scan_complete any pending requests.
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Otherwise insert pending requests into vscan_svc_nodes
bfc848c632c9eacb2a640246d96e198f1b185c03jm * and vscan_svc_taskq. If no slots are available in
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_nodes break loop and wait for one
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = vscan_svc_reql_next;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm while (req != NULL) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm next = list_next(&vscan_svc_reql, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state == VS_SVC_DISABLED) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_scan_complete(req);
911106dfb16696472af8c1b7b4c554a829354fa8jm } else {
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* insert request into vscan_svc_nodes */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_insert_req(req) == -1)
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* add the scan request into the taskq */
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) taskq_dispatch(vscan_svc_taskq,
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_taskq_callback,
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void *)req, TQ_SLEEP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ++(vscan_svc_counts.vsc_tq);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_state = VS_SVC_REQ_QUEUED;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = next;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_next = req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE2(vscan__req__counts, char *, "handler wait",
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_counts_t *, &vscan_svc_counts);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&vscan_svc_reql_cv, &vscan_svc_mutex,
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni SEC_TO_TICK(VS_REQL_HANDLER_TIMEOUT), TR_CLOCK_TICK);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE2(vscan__req__counts, char *, "handler wake",
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_counts_t *, &vscan_svc_counts);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_taskq_callback(void *data)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = (vscan_req_t *)data;
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_do_scan(req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (req->vsr_state != VS_SVC_REQ_SCANNING)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_scan_complete(req);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm --(vscan_svc_counts.vsc_tq);
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_do_scan
53c110294d8b1410cabc201a52f94b03ae2ef448jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Note: To avoid potential deadlock it is important that
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_mutex is not held during the call to
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_drv_create_note. vscan_drv_create_note enters
bfc848c632c9eacb2a640246d96e198f1b185c03jm * the vscan_drv_mutex and it is possible that a thread
bfc848c632c9eacb2a640246d96e198f1b185c03jm * holding that mutex could be waiting for vscan_svc_mutex.
53c110294d8b1410cabc201a52f94b03ae2ef448jm */
53c110294d8b1410cabc201a52f94b03ae2ef448jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_do_scan(vscan_req_t *req)
53c110294d8b1410cabc201a52f94b03ae2ef448jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm int idx, result;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vs_scan_req_t *door_req;
53c110294d8b1410cabc201a52f94b03ae2ef448jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm idx = req->vsr_idx;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_state = VS_SVC_REQ_IN_PROGRESS;
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* if vscan not enabled (shutting down), allow ACCESS */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_state != VS_SVC_ENABLED) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_ALLOW;
53c110294d8b1410cabc201a52f94b03ae2ef448jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_getattr(idx) != 0) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm cmn_err(CE_WARN, "Can't access xattr for %s\n",
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_vp->v_path);
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_DENY;
53c110294d8b1410cabc201a52f94b03ae2ef448jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* valid scan_req ptr guaranteed */
bfc848c632c9eacb2a640246d96e198f1b185c03jm door_req = vscan_svc_populate_req(idx);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* free up mutex around create node and door call */
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_drv_create_node(idx) != B_TRUE)
bfc848c632c9eacb2a640246d96e198f1b185c03jm result = VS_STATUS_ERROR;
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm result = vscan_door_scan_file(door_req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm kmem_free(door_req, sizeof (vs_scan_req_t));
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (result != VS_STATUS_SCANNING) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_nodes[idx].vsn_result = result;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_process_scan_result(idx);
bfc848c632c9eacb2a640246d96e198f1b185c03jm } else { /* async response */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (req->vsr_state == VS_SVC_REQ_IN_PROGRESS)
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_state = VS_SVC_REQ_SCANNING;
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
53c110294d8b1410cabc201a52f94b03ae2ef448jm}
53c110294d8b1410cabc201a52f94b03ae2ef448jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_populate_req
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Allocate a scan request to be sent to vscand, populating it
bfc848c632c9eacb2a640246d96e198f1b185c03jm * from the data in vscan_svc_nodes[idx].
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Returns: scan request object
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vs_scan_req_t *
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_populate_req(int idx)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vs_scan_req_t *scan_req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = node->vsn_req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req = kmem_zalloc(sizeof (vs_scan_req_t), KM_SLEEP);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_idx = idx;
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_seqnum = req->vsr_seqnum;
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) strncpy(scan_req->vsr_path, req->vsr_vp->v_path, MAXPATHLEN);
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_size = node->vsn_size;
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_modified = node->vsn_modified;
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_quarantined = node->vsn_quarantined;
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_req->vsr_flags = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) strncpy(scan_req->vsr_scanstamp,
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_scanstamp, sizeof (vs_scanstamp_t));
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (scan_req);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_scan_complete
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_scan_complete(vscan_req_t *req)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req != NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_state = VS_SVC_REQ_COMPLETE;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((--req->vsr_refcnt) == 0)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_delete_req(req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_broadcast(&(req->vsr_cv));
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_delete_req
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_delete_req(vscan_req_t *req)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int idx;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req != NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_refcnt == 0);
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_state == VS_SVC_REQ_COMPLETE);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((idx = req->vsr_idx) != 0)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_remove_req(idx);
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_remove(req);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_signal(&vscan_svc_reql_cv);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_scan_result
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Invoked from vscan_drv.c on receipt of an ioctl containing
bfc848c632c9eacb2a640246d96e198f1b185c03jm * an async scan result (VS_DRV_IOCTL_RESULT)
bfc848c632c9eacb2a640246d96e198f1b185c03jm * If the vsr_seqnum in the response does not match that in the
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_nodes entry the result is discarded.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmvoid
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_scan_result(vs_scan_rsp_t *scan_rsp)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[scan_rsp->vsr_idx];
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((req = node->vsn_req) == NULL) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (scan_rsp->vsr_seqnum != req->vsr_seqnum) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_result = scan_rsp->vsr_result;
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) strncpy(node->vsn_scanstamp,
bfc848c632c9eacb2a640246d96e198f1b185c03jm scan_rsp->vsr_scanstamp, sizeof (vs_scanstamp_t));
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_process_scan_result(scan_rsp->vsr_idx);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (node->vsn_req->vsr_state == VS_SVC_REQ_SCANNING)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_scan_complete(node->vsn_req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_req->vsr_state = VS_SVC_REQ_ASYNC_COMPLETE;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_scan_abort
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Abort in-progress scan requests.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmvoid
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_scan_abort()
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm int idx;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_enter(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm for (idx = 1; idx <= vs_nodes_max; idx++) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((req = vscan_svc_nodes[idx].vsn_req) == NULL)
bfc848c632c9eacb2a640246d96e198f1b185c03jm continue;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (req->vsr_state == VS_SVC_REQ_SCANNING) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__abort, vscan_req_t *, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_process_scan_result(idx);
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_scan_complete(req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_process_scan_result
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Sets vsn_access and updates file attributes based on vsn_result,
bfc848c632c9eacb2a640246d96e198f1b185c03jm * as follows:
911106dfb16696472af8c1b7b4c554a829354fa8jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * VS_STATUS_INFECTED
bfc848c632c9eacb2a640246d96e198f1b185c03jm * deny access, set quarantine attribute, clear scanstamp
bfc848c632c9eacb2a640246d96e198f1b185c03jm * VS_STATUS_CLEAN
bfc848c632c9eacb2a640246d96e198f1b185c03jm * allow access, set scanstamp,
bfc848c632c9eacb2a640246d96e198f1b185c03jm * if file not modified since scan initiated, clear modified attribute
bfc848c632c9eacb2a640246d96e198f1b185c03jm * VS_STATUS_NO_SCAN
bfc848c632c9eacb2a640246d96e198f1b185c03jm * deny access if file quarantined, otherwise allow access
bfc848c632c9eacb2a640246d96e198f1b185c03jm * VS_STATUS_UNDEFINED, VS_STATUS_ERROR
bfc848c632c9eacb2a640246d96e198f1b185c03jm * deny access if file quarantined, modified or no scanstamp
bfc848c632c9eacb2a640246d96e198f1b185c03jm * otherwise, allow access
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_process_scan_result(int idx)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm struct vattr attr;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vnode_t *vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm timestruc_t *mtime;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
53c110294d8b1410cabc201a52f94b03ae2ef448jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm switch (node->vsn_result) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_STATUS_INFECTED:
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_DENY;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_quarantined = 1;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_scanstamp[0] = '\0';
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) vscan_svc_setattr(idx,
bfc848c632c9eacb2a640246d96e198f1b185c03jm XAT_AV_QUARANTINED | XAT_AV_SCANSTAMP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_STATUS_CLEAN:
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_ALLOW;
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* if mtime has changed, don't clear the modified attribute */
bfc848c632c9eacb2a640246d96e198f1b185c03jm vp = node->vsn_req->vsr_vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm mtime = &(node->vsn_mtime);
bfc848c632c9eacb2a640246d96e198f1b185c03jm attr.va_mask = AT_MTIME;
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((VOP_GETATTR(vp, &attr, 0, kcred, NULL) != 0) ||
bfc848c632c9eacb2a640246d96e198f1b185c03jm (mtime->tv_sec != attr.va_mtime.tv_sec) ||
bfc848c632c9eacb2a640246d96e198f1b185c03jm (mtime->tv_nsec != attr.va_mtime.tv_nsec)) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__mtime__changed, vscan_svc_node_t *,
bfc848c632c9eacb2a640246d96e198f1b185c03jm node);
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) vscan_svc_setattr(idx, XAT_AV_SCANSTAMP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_modified = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) vscan_svc_setattr(idx,
bfc848c632c9eacb2a640246d96e198f1b185c03jm XAT_AV_SCANSTAMP | XAT_AV_MODIFIED);
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_STATUS_NO_SCAN:
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (node->vsn_quarantined)
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_DENY;
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_ALLOW;
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
53c110294d8b1410cabc201a52f94b03ae2ef448jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_STATUS_ERROR:
bfc848c632c9eacb2a640246d96e198f1b185c03jm case VS_STATUS_UNDEFINED:
bfc848c632c9eacb2a640246d96e198f1b185c03jm default:
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((node->vsn_quarantined) ||
bfc848c632c9eacb2a640246d96e198f1b185c03jm (node->vsn_modified) ||
bfc848c632c9eacb2a640246d96e198f1b185c03jm (node->vsn_scanstamp[0] == '\0'))
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_DENY;
bfc848c632c9eacb2a640246d96e198f1b185c03jm else
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_ALLOW;
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE4(vscan__result,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, idx, int, node->vsn_req->vsr_seqnum,
bfc848c632c9eacb2a640246d96e198f1b185c03jm int, node->vsn_result, int, node->vsn_access);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_getattr
911106dfb16696472af8c1b7b4c554a829354fa8jm *
53c110294d8b1410cabc201a52f94b03ae2ef448jm * Get the vscan related system attributes, AT_SIZE & AT_MTIME.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_getattr(int idx)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm xvattr_t xvattr;
911106dfb16696472af8c1b7b4c554a829354fa8jm xoptattr_t *xoap = NULL;
911106dfb16696472af8c1b7b4c554a829354fa8jm vnode_t *vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((vp = node->vsn_req->vsr_vp) == NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* get the attributes */
911106dfb16696472af8c1b7b4c554a829354fa8jm xva_init(&xvattr); /* sets AT_XVATTR */
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm xvattr.xva_vattr.va_mask |= AT_SIZE;
53c110294d8b1410cabc201a52f94b03ae2ef448jm xvattr.xva_vattr.va_mask |= AT_MTIME;
911106dfb16696472af8c1b7b4c554a829354fa8jm XVA_SET_REQ(&xvattr, XAT_AV_MODIFIED);
911106dfb16696472af8c1b7b4c554a829354fa8jm XVA_SET_REQ(&xvattr, XAT_AV_QUARANTINED);
911106dfb16696472af8c1b7b4c554a829354fa8jm XVA_SET_REQ(&xvattr, XAT_AV_SCANSTAMP);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (VOP_GETATTR(vp, (vattr_t *)&xvattr, 0, kcred, NULL) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((xoap = xva_getxoptattr(&xvattr)) == NULL) {
911106dfb16696472af8c1b7b4c554a829354fa8jm cmn_err(CE_NOTE, "Virus scan request failed; "
911106dfb16696472af8c1b7b4c554a829354fa8jm "file system does not support virus scanning");
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_size = xvattr.xva_vattr.va_size;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_mtime.tv_sec = xvattr.xva_vattr.va_mtime.tv_sec;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_mtime.tv_nsec = xvattr.xva_vattr.va_mtime.tv_nsec;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (XVA_ISSET_RTN(&xvattr, XAT_AV_MODIFIED) == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_modified = xoap->xoa_av_modified;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (XVA_ISSET_RTN(&xvattr, XAT_AV_QUARANTINED) == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_quarantined = xoap->xoa_av_quarantined;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (XVA_ISSET_RTN(&xvattr, XAT_AV_SCANSTAMP) != 0) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) memcpy(node->vsn_scanstamp,
911106dfb16696472af8c1b7b4c554a829354fa8jm xoap->xoa_av_scanstamp, AV_SCANSTAMP_SZ);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm DTRACE_PROBE1(vscan__getattr, vscan_svc_node_t *, node);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_setattr
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Set the vscan related system attributes.
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
53c110294d8b1410cabc201a52f94b03ae2ef448jmvscan_svc_setattr(int idx, int which)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm xvattr_t xvattr;
911106dfb16696472af8c1b7b4c554a829354fa8jm xoptattr_t *xoap = NULL;
911106dfb16696472af8c1b7b4c554a829354fa8jm vnode_t *vp;
911106dfb16696472af8c1b7b4c554a829354fa8jm int len;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
911106dfb16696472af8c1b7b4c554a829354fa8jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((vp = node->vsn_req->vsr_vp) == NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* update the attributes */
911106dfb16696472af8c1b7b4c554a829354fa8jm xva_init(&xvattr); /* sets AT_XVATTR */
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((xoap = xva_getxoptattr(&xvattr)) == NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm if (which & XAT_AV_MODIFIED) {
53c110294d8b1410cabc201a52f94b03ae2ef448jm XVA_SET_REQ(&xvattr, XAT_AV_MODIFIED);
bfc848c632c9eacb2a640246d96e198f1b185c03jm xoap->xoa_av_modified = node->vsn_modified;
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm if (which & XAT_AV_QUARANTINED) {
53c110294d8b1410cabc201a52f94b03ae2ef448jm XVA_SET_REQ(&xvattr, XAT_AV_QUARANTINED);
bfc848c632c9eacb2a640246d96e198f1b185c03jm xoap->xoa_av_quarantined = node->vsn_quarantined;
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm if (which & XAT_AV_SCANSTAMP) {
53c110294d8b1410cabc201a52f94b03ae2ef448jm XVA_SET_REQ(&xvattr, XAT_AV_SCANSTAMP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm len = strlen(node->vsn_scanstamp);
53c110294d8b1410cabc201a52f94b03ae2ef448jm (void) memcpy(xoap->xoa_av_scanstamp,
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_scanstamp, len);
53c110294d8b1410cabc201a52f94b03ae2ef448jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm /* if access is denied, set mtime to invalidate client cache */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (node->vsn_access != VS_ACCESS_ALLOW) {
911106dfb16696472af8c1b7b4c554a829354fa8jm xvattr.xva_vattr.va_mask |= AT_MTIME;
911106dfb16696472af8c1b7b4c554a829354fa8jm gethrestime(&xvattr.xva_vattr.va_mtime);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (VOP_SETATTR(vp, (vattr_t *)&xvattr, 0, kcred, NULL) != 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
53c110294d8b1410cabc201a52f94b03ae2ef448jm DTRACE_PROBE2(vscan__setattr,
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *, node, int, which);
53c110294d8b1410cabc201a52f94b03ae2ef448jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_configure
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * store configuration in vscan_svc_config
911106dfb16696472af8c1b7b4c554a829354fa8jm * set up vscan_svc_types array of pointers into
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_config.vsc_types for efficient searching
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmint
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_configure(vs_config_t *conf)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int count = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm char *p, *beg, *end;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_enter(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscan_svc_config = *conf;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm (void) memset(vscan_svc_types, 0, sizeof (vscan_svc_types));
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm beg = vscan_svc_config.vsc_types;
911106dfb16696472af8c1b7b4c554a829354fa8jm end = beg + vscan_svc_config.vsc_types_len;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm for (p = beg; p < end; p += strlen(p) + 1) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (count >= VS_TYPES_MAX) {
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm vscan_svc_types[count] = p;
911106dfb16696472af8c1b7b4c554a829354fa8jm ++count;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_exempt_file
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * check if a file's size or type exempts it from virus scanning
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * If the file is exempt from virus scanning, allow will be set
911106dfb16696472af8c1b7b4c554a829354fa8jm * to define whether files access should be allowed (B_TRUE) or
911106dfb16696472af8c1b7b4c554a829354fa8jm * denied (B_FALSE)
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 1 exempt
911106dfb16696472af8c1b7b4c554a829354fa8jm * 0 scan required
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_exempt_file(vnode_t *vp, boolean_t *allow)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm struct vattr attr;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(vp != NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(vp->v_path != NULL);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm attr.va_mask = AT_SIZE;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (VOP_GETATTR(vp, &attr, 0, kcred, NULL) != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm *allow = B_FALSE;
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_enter(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (attr.va_size > vscan_svc_config.vsc_max_size) {
911106dfb16696472af8c1b7b4c554a829354fa8jm DTRACE_PROBE2(vscan__exempt__filesize, char *,
911106dfb16696472af8c1b7b4c554a829354fa8jm vp->v_path, int, *allow);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm *allow = (vscan_svc_config.vsc_allow) ? B_TRUE : B_FALSE;
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscan_svc_exempt_filetype(vp->v_path)) {
911106dfb16696472af8c1b7b4c554a829354fa8jm DTRACE_PROBE1(vscan__exempt__filetype, char *, vp->v_path);
911106dfb16696472af8c1b7b4c554a829354fa8jm *allow = B_TRUE;
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm mutex_exit(&vscan_svc_cfg_mutex);
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_exempt_filetype
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Each entry in vscan_svc_types includes a rule indicator (+,-)
911106dfb16696472af8c1b7b4c554a829354fa8jm * followed by the match string for file types to which the rule
911106dfb16696472af8c1b7b4c554a829354fa8jm * applies. Look for first match of file type in vscan_svc_types
911106dfb16696472af8c1b7b4c554a829354fa8jm * and return 1 (exempt) if the indicator is '-', and 0 (not exempt)
911106dfb16696472af8c1b7b4c554a829354fa8jm * if the indicator is '+'.
911106dfb16696472af8c1b7b4c554a829354fa8jm * If vscan_svc_match_ext fails, or no match is found, return 0
911106dfb16696472af8c1b7b4c554a829354fa8jm * (not exempt)
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns 1: exempt, 0: not exempt
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_exempt_filetype(char *filepath)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int i, rc, exempt = 0;
911106dfb16696472af8c1b7b4c554a829354fa8jm char *filename, *ext;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm ASSERT(MUTEX_HELD(&vscan_svc_cfg_mutex));
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((filename = strrchr(filepath, '/')) == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm filename = filepath;
911106dfb16696472af8c1b7b4c554a829354fa8jm else
911106dfb16696472af8c1b7b4c554a829354fa8jm filename++;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm if ((ext = strrchr(filename, '.')) == NULL)
911106dfb16696472af8c1b7b4c554a829354fa8jm ext = "";
911106dfb16696472af8c1b7b4c554a829354fa8jm else
911106dfb16696472af8c1b7b4c554a829354fa8jm ext++;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm for (i = 0; i < VS_TYPES_MAX; i ++) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscan_svc_types[i] == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm rc = vscan_svc_match_ext(vscan_svc_types[i] + 1, ext, 1);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (rc == -1)
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm if (rc > 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm DTRACE_PROBE2(vscan__type__match, char *, ext,
911106dfb16696472af8c1b7b4c554a829354fa8jm char *, vscan_svc_types[i]);
911106dfb16696472af8c1b7b4c554a829354fa8jm exempt = (vscan_svc_types[i][0] == '-');
911106dfb16696472af8c1b7b4c554a829354fa8jm break;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm return (exempt);
911106dfb16696472af8c1b7b4c554a829354fa8jm}
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm/*
911106dfb16696472af8c1b7b4c554a829354fa8jm * vscan_svc_match_ext
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Performs a case-insensitive match for two strings. The first string
911106dfb16696472af8c1b7b4c554a829354fa8jm * argument can contain the wildcard characters '?' and '*'
911106dfb16696472af8c1b7b4c554a829354fa8jm *
911106dfb16696472af8c1b7b4c554a829354fa8jm * Returns: 0 no match
911106dfb16696472af8c1b7b4c554a829354fa8jm * 1 match
911106dfb16696472af8c1b7b4c554a829354fa8jm * -1 recursion error
911106dfb16696472af8c1b7b4c554a829354fa8jm */
911106dfb16696472af8c1b7b4c554a829354fa8jmstatic int
911106dfb16696472af8c1b7b4c554a829354fa8jmvscan_svc_match_ext(char *patn, char *str, int depth)
911106dfb16696472af8c1b7b4c554a829354fa8jm{
911106dfb16696472af8c1b7b4c554a829354fa8jm int c1, c2;
911106dfb16696472af8c1b7b4c554a829354fa8jm if (depth > VS_EXT_RECURSE_DEPTH)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (-1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm for (;;) {
911106dfb16696472af8c1b7b4c554a829354fa8jm switch (*patn) {
911106dfb16696472af8c1b7b4c554a829354fa8jm case 0:
911106dfb16696472af8c1b7b4c554a829354fa8jm return (*str == 0);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm case '?':
911106dfb16696472af8c1b7b4c554a829354fa8jm if (*str != 0) {
911106dfb16696472af8c1b7b4c554a829354fa8jm str++;
911106dfb16696472af8c1b7b4c554a829354fa8jm patn++;
911106dfb16696472af8c1b7b4c554a829354fa8jm continue;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm case '*':
911106dfb16696472af8c1b7b4c554a829354fa8jm patn++;
911106dfb16696472af8c1b7b4c554a829354fa8jm if (*patn == 0)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm while (*str) {
911106dfb16696472af8c1b7b4c554a829354fa8jm if (vscan_svc_match_ext(patn, str, depth + 1))
911106dfb16696472af8c1b7b4c554a829354fa8jm return (1);
911106dfb16696472af8c1b7b4c554a829354fa8jm str++;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm default:
911106dfb16696472af8c1b7b4c554a829354fa8jm if (*str != *patn) {
911106dfb16696472af8c1b7b4c554a829354fa8jm c1 = *str;
911106dfb16696472af8c1b7b4c554a829354fa8jm c2 = *patn;
911106dfb16696472af8c1b7b4c554a829354fa8jm
911106dfb16696472af8c1b7b4c554a829354fa8jm c1 = tolower(c1);
911106dfb16696472af8c1b7b4c554a829354fa8jm c2 = tolower(c2);
911106dfb16696472af8c1b7b4c554a829354fa8jm if (c1 != c2)
911106dfb16696472af8c1b7b4c554a829354fa8jm return (0);
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm str++;
911106dfb16696472af8c1b7b4c554a829354fa8jm patn++;
911106dfb16696472af8c1b7b4c554a829354fa8jm continue;
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm }
911106dfb16696472af8c1b7b4c554a829354fa8jm /* NOT REACHED */
911106dfb16696472af8c1b7b4c554a829354fa8jm}
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_insert_req
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Insert request in next available available slot in vscan_svc_nodes
bfc848c632c9eacb2a640246d96e198f1b185c03jm *
bfc848c632c9eacb2a640246d96e198f1b185c03jm * Returns: idx of slot, or -1 if no slot available
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic int
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_insert_req(vscan_req_t *req)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm int idx;
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_node_t *node;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_counts.vsc_node == vs_nodes_max)
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (-1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm for (idx = 1; idx <= vs_nodes_max; idx++) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_nodes[idx].vsn_req == NULL) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_idx = idx;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm node = &vscan_svc_nodes[idx];
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) memset(node, 0, sizeof (vscan_svc_node_t));
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_req = req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_modified = 1;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_result = VS_STATUS_UNDEFINED;
bfc848c632c9eacb2a640246d96e198f1b185c03jm node->vsn_access = VS_ACCESS_UNDEFINED;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ++(vscan_svc_counts.vsc_node);
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (idx);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (-1);
bfc848c632c9eacb2a640246d96e198f1b185c03jm}
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_remove_req
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_remove_req(int idx)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (idx != 0) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm (void) memset(&vscan_svc_nodes[idx], 0,
bfc848c632c9eacb2a640246d96e198f1b185c03jm sizeof (vscan_svc_node_t));
bfc848c632c9eacb2a640246d96e198f1b185c03jm --(vscan_svc_counts.vsc_node);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm}
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_reql_find
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_req_t *
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_reql_find(vnode_t *vp)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = list_head(&vscan_svc_reql);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm while (req != NULL) {
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((req->vsr_vp == vp) &&
bfc848c632c9eacb2a640246d96e198f1b185c03jm (req->vsr_state != VS_SVC_REQ_COMPLETE))
bfc848c632c9eacb2a640246d96e198f1b185c03jm break;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = list_next(&vscan_svc_reql, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm }
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm}
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_reql_insert
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic vscan_req_t *
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_reql_insert(vnode_t *vp)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_req_t *req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* if request already in list then return it */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if ((req = vscan_svc_reql_find(vp)) != NULL)
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* if list is full return NULL */
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_counts.vsc_reql == vs_reqs_max)
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* create a new request and insert into list */
bfc848c632c9eacb2a640246d96e198f1b185c03jm VN_HOLD(vp);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req = kmem_zalloc(sizeof (vscan_req_t), KM_SLEEP);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_magic = VS_REQ_MAGIC;
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_seqnum == UINT32_MAX)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_seqnum = 0;
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_seqnum = ++vscan_svc_seqnum;
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_vp = vp;
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_refcnt = 1; /* decremented in vscan_svc_scan_complete */
bfc848c632c9eacb2a640246d96e198f1b185c03jm req->vsr_state = VS_SVC_REQ_INIT;
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_init(&(req->vsr_cv), NULL, CV_DEFAULT, NULL);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm list_insert_tail(&vscan_svc_reql, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_reql_next == NULL)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_next = req;
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm ++(vscan_svc_counts.vsc_reql);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm /* wake reql handler thread */
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_signal(&vscan_svc_reql_cv);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm return (req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm}
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm/*
bfc848c632c9eacb2a640246d96e198f1b185c03jm * vscan_svc_reql_remove
bfc848c632c9eacb2a640246d96e198f1b185c03jm */
bfc848c632c9eacb2a640246d96e198f1b185c03jmstatic void
bfc848c632c9eacb2a640246d96e198f1b185c03jmvscan_svc_reql_remove(vscan_req_t *req)
bfc848c632c9eacb2a640246d96e198f1b185c03jm{
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(MUTEX_HELD(&vscan_svc_mutex));
bfc848c632c9eacb2a640246d96e198f1b185c03jm ASSERT(req->vsr_magic == VS_REQ_MAGIC);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm if (vscan_svc_reql_next == req)
bfc848c632c9eacb2a640246d96e198f1b185c03jm vscan_svc_reql_next = list_next(&vscan_svc_reql, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm list_remove(&vscan_svc_reql, req);
bfc848c632c9eacb2a640246d96e198f1b185c03jm cv_destroy(&(req->vsr_cv));
bfc848c632c9eacb2a640246d96e198f1b185c03jm VN_RELE(req->vsr_vp);
bfc848c632c9eacb2a640246d96e198f1b185c03jm
bfc848c632c9eacb2a640246d96e198f1b185c03jm kmem_free(req, sizeof (vscan_req_t));
bfc848c632c9eacb2a640246d96e198f1b185c03jm --(vscan_svc_counts.vsc_reql);
bfc848c632c9eacb2a640246d96e198f1b185c03jm}