1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * File Change Notification (FCN)
29 * SMB1 specific part.
30 */
31
32 /*
33 * SMB: nt_transact_notify_change
34 *
35 * Client Setup Words Description
36 * ================================== =================================
37 *
38 * ULONG CompletionFilter; Specifies operation to monitor
39 * USHORT Fid; Fid of directory to monitor
40 * BOOLEAN WatchTree; TRUE = watch all subdirectories too
41 * UCHAR Reserved; MBZ
42 *
43 * This command notifies the client when the directory specified by Fid is
44 * modified. See smb_notify.c for details.
45 *
46 * The MaxParameterCount field in the NT transact header determines
47 * the size of the buffer used to return change information:
48 *
49 * Server Response Description
50 * ================================== ================================
51 * ParameterCount # of bytes of change data
52 * Parameters[ ParameterCount ] FILE_NOTIFY_INFORMATION
53 * structures
54 *
55 * See smb_notify.c for details of FILE_NOTIFY_INFORMATION
56 */
57
58 #include <smbsrv/smb_kproto.h>
59
60 /*
61 * We add this flag to the CompletionFilter (see above) when the
62 * client sets WatchTree. Must not overlap FILE_NOTIFY_VALID_MASK.
63 */
64 #define NODE_FLAGS_WATCH_TREE 0x10000000
65 #if (NODE_FLAGS_WATCH_TREE & FILE_NOTIFY_VALID_MASK)
66 #error "NODE_FLAGS_WATCH_TREE"
67 #endif
68
69 /*
70 * smb_nt_transact_notify_change
71 *
72 * Handle and SMB NT transact NOTIFY CHANGE request.
73 * Basically, wait until "something has changed", and either
74 * return information about what changed, or return a special
75 * error telling the client "many things changed".
76 *
77 * The implementation uses a per-node list of waiting notify
78 * requests like this one, each with a blocked worker thead.
79 * Later, FEM and/or smbsrv events wake these threads, which
80 * then send the reply to the client.
81 */
82 smb_sdrc_t
smb_nt_transact_notify_change(smb_request_t * sr,struct smb_xa * xa)83 smb_nt_transact_notify_change(smb_request_t *sr, struct smb_xa *xa)
84 {
85 uint32_t CompletionFilter;
86 unsigned char WatchTree;
87 uint32_t status;
88 hrtime_t t1, t2;
89
90 if (smb_mbc_decodef(&xa->req_setup_mb, "lwb",
91 &CompletionFilter, &sr->smb_fid, &WatchTree) != 0) {
92 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
93 return (SDRC_ERROR);
94 }
95 CompletionFilter &= FILE_NOTIFY_VALID_MASK;
96 if (WatchTree)
97 CompletionFilter |= NODE_FLAGS_WATCH_TREE;
98
99 smbsr_lookup_file(sr);
100
101 t1 = gethrtime();
102 status = smb_notify_common(sr, &xa->rep_data_mb, CompletionFilter);
103 t2 = gethrtime();
104
105 /*
106 * We don't want to include the (indefinite) wait time of the
107 * smb_notify_common() call in the SMB1 transact latency.
108 * The easiest way to do that, without adding special case
109 * logic to the common SMB1 dispatch handler is to adjust the
110 * start time of this request to effectively subtract out the
111 * time we were blocked in smb_notify_common().
112 */
113 sr->sr_time_start += (t2 - t1);
114
115 if (status != 0)
116 smbsr_error(sr, status, 0, 0);
117
118 return (SDRC_SUCCESS);
119 }
120