Skip to content

Commit c349818

Browse files
committed
smb3: add missing worker function for SMB3 change notify
SMB3 change notify is important to allow applications to wait on directory change events of different types (e.g. adding and deleting files from others systems). Add worker functions for this. Acked-by: Aurelien Aptel <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 8eecd1c commit c349818

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

fs/cifs/smb2pdu.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,91 @@ SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
31753175
(void **)&uniqueid, NULL);
31763176
}
31773177

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+
31783263
/*
31793264
* This is a no-op for now. We're not really interested in the reply, but
31803265
* rather in the fact that the server sent one and that server->lstrp

fs/cifs/trace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ DEFINE_EVENT(smb3_inf_enter_class, smb3_##name, \
235235

236236
DEFINE_SMB3_INF_ENTER_EVENT(query_info_enter);
237237
DEFINE_SMB3_INF_ENTER_EVENT(query_info_done);
238+
DEFINE_SMB3_INF_ENTER_EVENT(notify_enter);
239+
DEFINE_SMB3_INF_ENTER_EVENT(notify_done);
238240

239241
DECLARE_EVENT_CLASS(smb3_inf_err_class,
240242
TP_PROTO(unsigned int xid,
@@ -281,6 +283,7 @@ DEFINE_EVENT(smb3_inf_err_class, smb3_##name, \
281283

282284
DEFINE_SMB3_INF_ERR_EVENT(query_info_err);
283285
DEFINE_SMB3_INF_ERR_EVENT(set_info_err);
286+
DEFINE_SMB3_INF_ERR_EVENT(notify_err);
284287
DEFINE_SMB3_INF_ERR_EVENT(fsctl_err);
285288

286289
DECLARE_EVENT_CLASS(smb3_inf_compound_enter_class,

0 commit comments

Comments
 (0)