diff options
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/locking.c | 40 | ||||
-rw-r--r-- | source3/locking/proto.h | 1 | ||||
-rw-r--r-- | source3/locking/share_mode_lock.c | 42 |
3 files changed, 43 insertions, 40 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b9fba17a87..b9afd2392c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -556,10 +556,6 @@ bool rename_share_filename(struct messaging_context *msg_ctx, continue; } - if (share_mode_stale_pid(d, i)) { - continue; - } - DEBUG(10,("rename_share_filename: sending rename message to " "pid %s file_id %s sharepath %s base_name %s " "stream_name %s\n", @@ -620,9 +616,7 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e) num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0); - if (serverid_exists(&e->pid) && (num_props > 1)) { - smb_panic("Invalid share mode entry"); - } + SMB_ASSERT(num_props <= 1); return (num_props != 0); } @@ -631,38 +625,6 @@ bool is_deferred_open_entry(const struct share_mode_entry *e) return (e->op_type == DEFERRED_OPEN_ENTRY); } -/* - * In case d->share_modes[i] conflicts with something or otherwise is - * being used, we need to make sure the corresponding process still - * exists. This routine checks it and potentially removes the entry - * from d->share_modes. Modifies d->num_share_modes, watch out in - * routines iterating over that array. - */ -bool share_mode_stale_pid(struct share_mode_data *d, unsigned i) -{ - struct share_mode_entry *e; - - if (i > d->num_share_modes) { - DEBUG(1, ("Asking for index %u, only %u around\n", - i, (unsigned)d->num_share_modes)); - return false; - } - e = &d->share_modes[i]; - if (serverid_exists(&e->pid)) { - DEBUG(10, ("PID %s (index %u out of %u) still exists\n", - procid_str_static(&e->pid), i, - (unsigned)d->num_share_modes)); - return false; - } - DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n", - procid_str_static(&e->pid), i, - (unsigned)d->num_share_modes)); - *e = d->share_modes[d->num_share_modes-1]; - d->num_share_modes -= 1; - d->modified = true; - return true; -} - /******************************************************************* Fill a share mode entry. ********************************************************************/ diff --git a/source3/locking/proto.h b/source3/locking/proto.h index f6a6f2ee12..54badd9149 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -168,7 +168,6 @@ void get_file_infos(struct file_id id, struct timespec *write_time); bool is_valid_share_mode_entry(const struct share_mode_entry *e); bool is_deferred_open_entry(const struct share_mode_entry *e); -bool share_mode_stale_pid(struct share_mode_data *d, unsigned i); void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, uid_t uid, uint64_t mid, uint16 op_type); void add_deferred_open(struct share_mode_lock *lck, uint64_t mid, diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c index 1fea748e72..f28332c226 100644 --- a/source3/locking/share_mode_lock.c +++ b/source3/locking/share_mode_lock.c @@ -118,6 +118,9 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, const TDB_DATA dbuf) { struct share_mode_data *d; + int i; + struct server_id *pids; + bool *pid_exists; enum ndr_err_code ndr_err; DATA_BLOB blob; @@ -145,6 +148,45 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, NDR_PRINT_DEBUG(share_mode_data, d); } + /* + * Ensure that each entry has a real process attached. + */ + + pids = talloc_array(talloc_tos(), struct server_id, + d->num_share_modes); + if (pids == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes); + if (pid_exists == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + + for (i=0; i<d->num_share_modes; i++) { + pids[i] = d->share_modes[i].pid; + } + if (!serverids_exist(pids, d->num_share_modes, pid_exists)) { + DEBUG(0, ("serverid_exists failed\n")); + goto fail; + } + + i = 0; + while (i < d->num_share_modes) { + struct share_mode_entry *e = &d->share_modes[i]; + if (!pid_exists[i]) { + DEBUG(10, ("wipe non-existent pid %s\n", + procid_str_static(&e->pid))); + *e = d->share_modes[d->num_share_modes-1]; + d->num_share_modes -= 1; + d->modified = True; + continue; + } + i += 1; + } + TALLOC_FREE(pid_exists); + TALLOC_FREE(pids); return d; fail: TALLOC_FREE(d); |