Utility function called by locking requests.
****************************************************************************/
-struct byte_range_lock *do_lock(files_struct *fsp,
+struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
+ files_struct *fsp,
uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
enum brl_type lock_type,
enum brl_flavour lock_flav,
BOOL blocking_lock,
- NTSTATUS *perr)
+ NTSTATUS *perr,
+ uint32 *plock_pid)
{
struct byte_range_lock *br_lck = NULL;
return NULL;
}
- *perr = brl_lock(br_lck,
+ *perr = brl_lock(msg_ctx,
+ br_lck,
lock_pid,
procid_self(),
offset,
count,
lock_type,
lock_flav,
- blocking_lock);
+ blocking_lock,
+ plock_pid);
+
+ /* blocking ie. pending, locks also count here,
+ * as this is an efficiency counter to avoid checking
+ * the lock db. on close. JRA. */
+
+ fsp->current_lock_count++;
return br_lck;
}
Utility function called by unlocking requests.
****************************************************************************/
-NTSTATUS do_unlock(files_struct *fsp,
+NTSTATUS do_unlock(struct messaging_context *msg_ctx,
+ files_struct *fsp,
uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
return NT_STATUS_NO_MEMORY;
}
- ok = brl_unlock(br_lck,
+ ok = brl_unlock(msg_ctx,
+ br_lck,
lock_pid,
procid_self(),
offset,
return NT_STATUS_RANGE_NOT_LOCKED;
}
+ SMB_ASSERT(fsp->current_lock_count > 0);
+ fsp->current_lock_count--;
+
return NT_STATUS_OK;
}
return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
+ SMB_ASSERT(fsp->current_lock_count > 0);
+ fsp->current_lock_count--;
+
return NT_STATUS_OK;
}
Remove any locks on this fd. Called from file_close().
****************************************************************************/
-void locking_close_file(files_struct *fsp)
+void locking_close_file(struct messaging_context *msg_ctx,
+ files_struct *fsp)
{
struct byte_range_lock *br_lck;
return;
}
+ /* If we have not outstanding locks or pending
+ * locks then we don't need to look in the lock db.
+ */
+
+ if (fsp->current_lock_count == 0) {
+ return;
+ }
+
br_lck = brl_get_locks(NULL,fsp);
if (br_lck) {
cancel_pending_lock_requests_by_fid(fsp, br_lck);
- brl_close_fnum(br_lck);
+ brl_close_fnum(msg_ctx, br_lck);
TALLOC_FREE(br_lck);
}
}
memset(&key, '\0', sizeof(key));
key.dev = dev;
key.ino = inode;
- kbuf.dptr = (char *)&key;
+ kbuf.dptr = (uint8 *)&key;
kbuf.dsize = sizeof(key);
return kbuf;
}
}
lck->share_modes = (struct share_mode_entry *)
- talloc_memdup(lck, dbuf.dptr+sizeof(*data),
+ TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data),
lck->num_share_modes *
sizeof(struct share_mode_entry));
/* Get any delete token. */
if (data->u.s.delete_token_size) {
- char *p = dbuf.dptr + sizeof(*data) +
+ uint8 *p = dbuf.dptr + sizeof(*data) +
(lck->num_share_modes *
sizeof(struct share_mode_entry));
}
/* Save off the associated service path and filename. */
- lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
+ lck->servicepath = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) +
(lck->num_share_modes *
sizeof(struct share_mode_entry)) +
data->u.s.delete_token_size );
smb_panic("talloc_strdup failed\n");
}
- lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
+ lck->filename = talloc_strdup(lck, (const char *)dbuf.dptr + sizeof(*data) +
(lck->num_share_modes *
sizeof(struct share_mode_entry)) +
data->u.s.delete_token_size +
delete_token_size +
sp_len + 1 +
strlen(lck->filename) + 1;
- result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
+ result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
if (result.dptr == NULL) {
smb_panic("talloc failed\n");
/* Store any delete on close token. */
if (lck->delete_token) {
- char *p = result.dptr + offset;
+ uint8 *p = result.dptr + offset;
memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
p += sizeof(uid_t);
offset = p - result.dptr;
}
- safe_strcpy(result.dptr + offset, lck->servicepath,
+ safe_strcpy((char *)result.dptr + offset, lck->servicepath,
result.dsize - offset - 1);
offset += sp_len + 1;
- safe_strcpy(result.dptr + offset, lck->filename,
+ safe_strcpy((char *)result.dptr + offset, lck->filename,
result.dsize - offset - 1);
if (DEBUGLEVEL >= 10) {
Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
********************************************************************/
-BOOL rename_share_filename(struct share_mode_lock *lck,
+BOOL rename_share_filename(struct messaging_context *msg_ctx,
+ struct share_mode_lock *lck,
const char *servicepath,
const char *newname)
{
size_t msg_len;
char *frm = NULL;
int i;
+ DATA_BLOB msg;
if (!lck) {
return False;
safe_strcpy(&frm[16], lck->servicepath, sp_len);
safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
+ msg = data_blob_const(frm, msg_len);
+
/* Send the messages. */
for (i=0; i<lck->num_share_modes; i++) {
struct share_mode_entry *se = &lck->share_modes[i];
(unsigned int)lck->dev, (double)lck->ino,
lck->servicepath, lck->filename ));
- message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
- frm, msg_len, True);
+ messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &msg);
}
return True;
}
void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
- uid_t uid, uint16 mid, uint16 op_type)
+ uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed)
{
struct share_mode_entry entry;
fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
+ if (initial_delete_on_close_allowed) {
+ entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
+ }
add_share_mode_entry(lck, &entry);
}
return NT_STATUS_OK;
}
+/****************************************************************************
+ Do we have an open file handle that created this entry ?
+****************************************************************************/
+
+BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck)
+{
+ int i;
+
+ for (i=0; i<lck->num_share_modes; i++) {
+ if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) {
+ return True;
+ }
+ }
+ return False;
+}
+
/*************************************************************************
Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
(Should this be in locking.c.... ?).
return True;
}
+/****************************************************************************
+ Sets the allow initial delete on close flag for this share mode.
+****************************************************************************/
+
+BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close)
+{
+ struct share_mode_entry entry, *e;
+
+ /* Don't care about the pid owner being correct here - just a search. */
+ fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
+
+ e = find_share_mode_entry(lck, &entry);
+ if (e == NULL) {
+ return False;
+ }
+
+ if (delete_on_close) {
+ e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
+ } else {
+ e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
+ }
+ lck->modified = True;
+ return True;
+}
+
struct forall_state {
void (*fn)(const struct share_mode_entry *entry,
const char *sharepath,
data = (struct locking_data *)dbuf.dptr;
shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
- sharepath = dbuf.dptr + sizeof(*data) +
+ sharepath = (const char *)dbuf.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares) +
data->u.s.delete_token_size;
- fname = dbuf.dptr + sizeof(*data) +
+ fname = (const char *)dbuf.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares) +
data->u.s.delete_token_size +
strlen(sharepath) + 1;