diff options
author | Jeremy Allison <jra@samba.org> | 2005-12-13 18:11:50 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:05:49 -0500 |
commit | ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad (patch) | |
tree | d91dcd5c2a731925cec24e67c5a4e78dd3b7dac0 /source3/locking | |
parent | 7d2771e758d4e8ef0adb45e55775b524de4dba9a (diff) | |
download | samba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.tar.gz samba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.tar.bz2 samba-ab7a4f7e8e4b946a8acd0a205c16dbf6a3afecad.zip |
r12213: Final fix for #3303 - send rename messages to smbd's
that have open file handles to allow them to correctly
implement delete on close. There is a further correctness
fix I'm intending to add to this to cope with different share
paths, but not right now...
Jeremy.
(This used to be commit 932e337db8788e75344e1c7cf1ef009d090cb039)
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/locking.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 2debc2c23e..d89fe931ef 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -642,14 +642,24 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, /******************************************************************* Sets the service name and filename for rename. - At this point we should emit "rename" smbd messages to all - interested process id's. + At this point we emit "file renamed" messages to all + process id's that have this file open. + Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp> ********************************************************************/ BOOL rename_share_filename(struct share_mode_lock *lck, const char *servicepath, const char *newname) { + struct file_renamed_message *frm = NULL; + size_t sp_len; + size_t fn_len; + size_t msg_len; + int i; + + DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", + servicepath, newname)); + /* * rename_internal_fsp() and rename_internals() add './' to * head of newname if newname does not contain a '/'. @@ -658,13 +668,53 @@ BOOL rename_share_filename(struct share_mode_lock *lck, newname += 2; } - lck->filename = talloc_strdup(lck, newname); lck->servicepath = talloc_strdup(lck, servicepath); + lck->filename = talloc_strdup(lck, newname); if (lck->filename == NULL || lck->servicepath == NULL) { DEBUG(0, ("rename_share_filename: talloc failed\n")); return False; } lck->modified = True; + + sp_len = strlen(lck->servicepath); + fn_len = strlen(lck->filename); + + msg_len = sizeof(*frm) + sp_len + 1 + fn_len + 1; + + /* Set up the name changed message. */ + frm = TALLOC(lck, msg_len); + if (!frm) { + return False; + } + frm->dev = lck->dev; + frm->inode = lck->ino; + + DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len )); + + safe_strcpy(&frm->names[0], lck->servicepath, sp_len); + safe_strcpy(&frm->names[sp_len + 1], lck->filename, fn_len); + + /* Send the messages. */ + for (i=0; i<lck->num_share_modes; i++) { + struct share_mode_entry *se = &lck->share_modes[i]; + if (!is_valid_share_mode_entry(se)) { + continue; + } + /* But not to ourselves... */ + if (procid_is_me(&se->pid)) { + continue; + } + + DEBUG(10,("rename_share_filename: sending rename message to pid %u " + "dev %x, inode %.0f sharepath %s newname %s\n", + (unsigned int)procid_to_pid(&se->pid), + (unsigned int)frm->dev, (double)frm->inode, + lck->servicepath, lck->filename )); + + message_send_pid(se->pid, MSG_SMB_FILE_RENAME, + frm, msg_len, True); + } + return True; } |