@@ -3175,6 +3175,91 @@ SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
3175
3175
(void * * )& uniqueid , NULL );
3176
3176
}
3177
3177
3178
+ /*
3179
+ * CHANGE_NOTIFY Request is sent to get notifications on changes to a directory
3180
+ * See MS-SMB2 2.2.35 and 2.2.36
3181
+ */
3182
+
3183
+ int
3184
+ SMB2_notify_init (const unsigned int xid , struct smb_rqst * rqst ,
3185
+ struct cifs_tcon * tcon , u64 persistent_fid , u64 volatile_fid ,
3186
+ u32 completion_filter , bool watch_tree )
3187
+ {
3188
+ struct smb2_change_notify_req * req ;
3189
+ struct kvec * iov = rqst -> rq_iov ;
3190
+ unsigned int total_len ;
3191
+ int rc ;
3192
+
3193
+ rc = smb2_plain_req_init (SMB2_CHANGE_NOTIFY , tcon , (void * * ) & req , & total_len );
3194
+ if (rc )
3195
+ return rc ;
3196
+
3197
+ req -> PersistentFileId = persistent_fid ;
3198
+ req -> VolatileFileId = volatile_fid ;
3199
+ req -> OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE ;
3200
+ req -> CompletionFilter = cpu_to_le32 (completion_filter );
3201
+ if (watch_tree )
3202
+ req -> Flags = cpu_to_le16 (SMB2_WATCH_TREE );
3203
+ else
3204
+ req -> Flags = 0 ;
3205
+
3206
+ iov [0 ].iov_base = (char * )req ;
3207
+ iov [0 ].iov_len = total_len ;
3208
+
3209
+ return 0 ;
3210
+ }
3211
+
3212
+ int
3213
+ SMB2_change_notify (const unsigned int xid , struct cifs_tcon * tcon ,
3214
+ u64 persistent_fid , u64 volatile_fid , bool watch_tree ,
3215
+ u32 completion_filter )
3216
+ {
3217
+ struct cifs_ses * ses = tcon -> ses ;
3218
+ struct smb_rqst rqst ;
3219
+ struct kvec iov [1 ];
3220
+ struct kvec rsp_iov = {NULL , 0 };
3221
+ int resp_buftype = CIFS_NO_BUFFER ;
3222
+ int flags = 0 ;
3223
+ int rc = 0 ;
3224
+
3225
+ cifs_dbg (FYI , "change notify\n" );
3226
+ if (!ses || !(ses -> server ))
3227
+ return - EIO ;
3228
+
3229
+ if (smb3_encryption_required (tcon ))
3230
+ flags |= CIFS_TRANSFORM_REQ ;
3231
+
3232
+ memset (& rqst , 0 , sizeof (struct smb_rqst ));
3233
+ memset (& iov , 0 , sizeof (iov ));
3234
+ rqst .rq_iov = iov ;
3235
+ rqst .rq_nvec = 1 ;
3236
+
3237
+ rc = SMB2_notify_init (xid , & rqst , tcon , persistent_fid , volatile_fid ,
3238
+ completion_filter , watch_tree );
3239
+ if (rc )
3240
+ goto cnotify_exit ;
3241
+
3242
+ trace_smb3_notify_enter (xid , persistent_fid , tcon -> tid , ses -> Suid ,
3243
+ (u8 )watch_tree , completion_filter );
3244
+ rc = cifs_send_recv (xid , ses , & rqst , & resp_buftype , flags , & rsp_iov );
3245
+
3246
+ if (rc != 0 ) {
3247
+ cifs_stats_fail_inc (tcon , SMB2_CHANGE_NOTIFY_HE );
3248
+ trace_smb3_notify_err (xid , persistent_fid , tcon -> tid , ses -> Suid ,
3249
+ (u8 )watch_tree , completion_filter , rc );
3250
+ } else
3251
+ trace_smb3_notify_done (xid , persistent_fid , tcon -> tid ,
3252
+ ses -> Suid , (u8 )watch_tree , completion_filter );
3253
+
3254
+ cnotify_exit :
3255
+ if (rqst .rq_iov )
3256
+ cifs_small_buf_release (rqst .rq_iov [0 ].iov_base ); /* request */
3257
+ free_rsp_buf (resp_buftype , rsp_iov .iov_base );
3258
+ return rc ;
3259
+ }
3260
+
3261
+
3262
+
3178
3263
/*
3179
3264
* This is a no-op for now. We're not really interested in the reply, but
3180
3265
* rather in the fact that the server sent one and that server->lstrp
0 commit comments