Skip to content

Commit

Permalink
3523 SMB NT Notify returning too soon
Browse files Browse the repository at this point in the history
Reviewed by: Albert Lee <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Reviewed by: Yakov Zaytsev <[email protected]>
Approved by: Richard Lowe <[email protected]>
  • Loading branch information
gwr committed Feb 12, 2013
1 parent bfbce3c commit ccc71be
Show file tree
Hide file tree
Showing 12 changed files with 406 additions and 489 deletions.
7 changes: 4 additions & 3 deletions usr/src/uts/common/fs/smbsrv/smb_common_transact.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/

#include <smbsrv/smb_kproto.h>
Expand Down Expand Up @@ -127,7 +128,7 @@ smb_com_transaction(smb_request_t *sr)

if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
return (SDRC_ERROR);
}
sr->r_xa = xa;
Expand Down Expand Up @@ -314,7 +315,7 @@ smb_com_transaction2(struct smb_request *sr)

if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
return (SDRC_ERROR);
}
sr->r_xa = xa;
Expand Down Expand Up @@ -586,7 +587,7 @@ smb_com_nt_transact(struct smb_request *sr)

if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
smbsr_error(sr, 0, ERRDOS, ERRsrverror);
smbsr_error(sr, 0, ERRSRV, ERRsrverror);
return (SDRC_ERROR);
}
sr->r_xa = xa;
Expand Down
27 changes: 18 additions & 9 deletions usr/src/uts/common/fs/smbsrv/smb_fem.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/

#include <smbsrv/smb_kproto.h>
Expand Down Expand Up @@ -223,7 +224,7 @@ smb_fem_fcn_create(
ct, vsecp);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_ADDED, name);

return (error);
}
Expand Down Expand Up @@ -257,7 +258,7 @@ smb_fem_fcn_remove(
error = vnext_remove(arg, name, cr, ct, flags);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_REMOVED, name);

return (error);
}
Expand All @@ -281,10 +282,18 @@ smb_fem_fcn_rename(

error = vnext_rename(arg, snm, tdvp, tnm, cr, ct, flags);

if (error == 0)
smb_node_notify_change(dnode);
if (error != 0)
return (error);

return (error);
/*
* Note that renames in the same directory are normally
* delivered in {old,new} pairs, and clients expect them
* in that order, if both events are delivered.
*/
smb_node_notify_change(dnode, FILE_ACTION_RENAMED_OLD_NAME, snm);
smb_node_notify_change(dnode, FILE_ACTION_RENAMED_NEW_NAME, tnm);

return (0);
}

static int
Expand All @@ -308,7 +317,7 @@ smb_fem_fcn_mkdir(
error = vnext_mkdir(arg, name, vap, vpp, cr, ct, flags, vsecp);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_ADDED, name);

return (error);
}
Expand All @@ -332,7 +341,7 @@ smb_fem_fcn_rmdir(
error = vnext_rmdir(arg, name, cdir, cr, ct, flags);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_REMOVED, name);

return (error);
}
Expand All @@ -356,7 +365,7 @@ smb_fem_fcn_link(
error = vnext_link(arg, svp, tnm, cr, ct, flags);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_ADDED, tnm);

return (error);
}
Expand All @@ -381,7 +390,7 @@ smb_fem_fcn_symlink(
error = vnext_symlink(arg, linkname, vap, target, cr, ct, flags);

if (error == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode, FILE_ACTION_ADDED, linkname);

return (error);
}
Expand Down
17 changes: 11 additions & 6 deletions usr/src/uts/common/fs/smbsrv/smb_fsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/

#include <sys/sid.h>
Expand Down Expand Up @@ -423,7 +424,8 @@ smb_fsop_create_stream(smb_request_t *sr, cred_t *cr,

/* notify change to the unnamed stream */
if (rc == 0)
smb_node_notify_change(dnode);
smb_node_notify_change(dnode,
FILE_ACTION_ADDED_STREAM, fname);

return (rc);
}
Expand Down Expand Up @@ -679,9 +681,10 @@ smb_fsop_remove(
rc = smb_vop_stream_remove(fnode->vp, name, flags, cr);

/* notify change to the unnamed stream */
if ((rc == 0) && fnode->n_dnode)
smb_node_notify_change(fnode->n_dnode);

if ((rc == 0) && fnode->n_dnode) {
smb_node_notify_change(fnode->n_dnode,
FILE_ACTION_REMOVED_STREAM, fnode->od_name);
}
} else if (smb_is_stream_name(name)) {
smb_stream_parse_name(name, fname, sname);

Expand Down Expand Up @@ -710,8 +713,10 @@ smb_fsop_remove(
smb_node_release(fnode);

/* notify change to the unnamed stream */
if (rc == 0)
smb_node_notify_change(dnode);
if (rc == 0) {
smb_node_notify_change(dnode,
FILE_ACTION_REMOVED_STREAM, fname);
}
} else {
rc = smb_vop_remove(dnode->vp, name, flags, cr);

Expand Down
75 changes: 60 additions & 15 deletions usr/src/uts/common/fs/smbsrv/smb_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/
/*
* SMB Node State Machine
Expand Down Expand Up @@ -784,15 +785,51 @@ smb_node_share_check(smb_node_t *node)
return (status);
}

/*
* SMB Change Notification
*/

void
smb_node_fcn_subscribe(smb_node_t *node, smb_request_t *sr)
{
smb_node_fcn_t *fcn = &node->n_fcn;

mutex_enter(&fcn->fcn_mutex);
if (fcn->fcn_count == 0)
smb_fem_fcn_install(node);
fcn->fcn_count++;
list_insert_tail(&fcn->fcn_watchers, sr);
mutex_exit(&fcn->fcn_mutex);
}

void
smb_node_fcn_unsubscribe(smb_node_t *node, smb_request_t *sr)
{
smb_node_fcn_t *fcn = &node->n_fcn;

mutex_enter(&fcn->fcn_mutex);
list_remove(&fcn->fcn_watchers, sr);
fcn->fcn_count--;
if (fcn->fcn_count == 0)
smb_fem_fcn_uninstall(node);
mutex_exit(&fcn->fcn_mutex);
}

void
smb_node_notify_change(smb_node_t *node)
smb_node_notify_change(smb_node_t *node, uint_t action, const char *name)
{
SMB_NODE_VALID(node);

if (node->flags & NODE_FLAGS_NOTIFY_CHANGE) {
node->flags |= NODE_FLAGS_CHANGED;
smb_process_node_notify_change_queue(node);
}
smb_notify_event(node, action, name);

/*
* These two events come as a pair:
* FILE_ACTION_RENAMED_OLD_NAME
* FILE_ACTION_RENAMED_NEW_NAME
* Only do the parent notify for "new".
*/
if (action == FILE_ACTION_RENAMED_OLD_NAME)
return;

smb_node_notify_parents(node);
}
Expand All @@ -808,17 +845,17 @@ smb_node_notify_change(smb_node_t *node)
void
smb_node_notify_parents(smb_node_t *dnode)
{
smb_node_t *pnode = dnode;
smb_node_t *pnode; /* parent */

SMB_NODE_VALID(dnode);
pnode = dnode->n_dnode;

while ((pnode = pnode->n_dnode) != NULL) {
while (pnode != NULL) {
SMB_NODE_VALID(pnode);
if ((pnode->flags & NODE_FLAGS_NOTIFY_CHANGE) &&
(pnode->flags & NODE_FLAGS_WATCH_TREE)) {
pnode->flags |= NODE_FLAGS_CHANGED;
smb_process_node_notify_change_queue(pnode);
}
smb_notify_event(pnode, 0, dnode->od_name);
/* cd .. */
dnode = pnode;
pnode = dnode->n_dnode;
}
}

Expand Down Expand Up @@ -1140,6 +1177,9 @@ smb_node_constructor(void *buf, void *un, int kmflags)
offsetof(smb_ofile_t, f_nnd));
smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t),
offsetof(smb_lock_t, l_lnd));
mutex_init(&node->n_fcn.fcn_mutex, NULL, MUTEX_DEFAULT, NULL);
list_create(&node->n_fcn.fcn_watchers, sizeof (smb_request_t),
offsetof(smb_request_t, sr_ncr.nc_lnd));
cv_init(&node->n_oplock.ol_cv, NULL, CV_DEFAULT, NULL);
mutex_init(&node->n_oplock.ol_mutex, NULL, MUTEX_DEFAULT, NULL);
list_create(&node->n_oplock.ol_grants, sizeof (smb_oplock_grant_t),
Expand All @@ -1165,6 +1205,8 @@ smb_node_destructor(void *buf, void *un)
rw_destroy(&node->n_lock);
cv_destroy(&node->n_oplock.ol_cv);
mutex_destroy(&node->n_oplock.ol_mutex);
list_destroy(&node->n_fcn.fcn_watchers);
mutex_destroy(&node->n_fcn.fcn_mutex);
smb_llist_destructor(&node->n_lock_list);
smb_llist_destructor(&node->n_ofile_list);
list_destroy(&node->n_oplock.ol_grants);
Expand Down Expand Up @@ -1416,9 +1458,12 @@ smb_node_setattr(smb_request_t *sr, smb_node_t *node,
if (tmp_attr.sa_mask)
smb_node_set_cached_timestamps(node, &tmp_attr);

if (tmp_attr.sa_mask & SMB_AT_MTIME || explicit_times & SMB_AT_MTIME) {
if (node->n_dnode != NULL)
smb_node_notify_change(node->n_dnode);
if ((tmp_attr.sa_mask & SMB_AT_MTIME) ||
(explicit_times & SMB_AT_MTIME)) {
if (node->n_dnode != NULL) {
smb_node_notify_change(node->n_dnode,
FILE_ACTION_MODIFIED, node->od_name);
}
}

return (0);
Expand Down
5 changes: 1 addition & 4 deletions usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/

/*
Expand Down Expand Up @@ -79,9 +80,5 @@ smb_com_nt_cancel(smb_request_t *sr)
}
smb_slist_exit(&session->s_req_list);

/* Now, search the notify change queue to find the request */

smb_reply_specific_cancel_request(sr);

return (SDRC_NO_REPLY);
}
Loading

0 comments on commit ccc71be

Please sign in to comment.