summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking.c40
-rw-r--r--source3/locking/proto.h1
-rw-r--r--source3/locking/share_mode_lock.c42
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);