summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorGregor Beck <gbeck@sernet.de>2013-03-13 11:35:37 +0100
committerMichael Adam <obnox@samba.org>2013-04-18 13:15:13 +0200
commitf608bedfca4118b7e3606802df40e266bcc099d8 (patch)
tree012ea1fc0b807c2c6e207d77dfb6b2f30f8525f6 /source3/locking
parent0ac0b35dad796d10cf04ab77a53a926420cc0589 (diff)
downloadsamba-f608bedfca4118b7e3606802df40e266bcc099d8.tar.gz
s3:locking: add function share_mode_cleanup_disconnected()
For a given file, clean share mode entries for a given persistent file id. Pair-Programmed-With: Michael Adam <obnox@samba.org> Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> Signed-off-by: Gregor Beck <gbeck@sernet.de> Signed-off-by: Michael Adam <obnox@samba.org> Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/proto.h3
-rw-r--r--source3/locking/share_mode_lock.c99
2 files changed, 102 insertions, 0 deletions
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 1d8eb73ebd..bb7255dcdc 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -202,6 +202,9 @@ bool set_write_time(struct file_id fileid, struct timespec write_time);
int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
const char *, void *),
void *private_data);
+bool share_mode_cleanup_disconnected(struct file_id id,
+ uint64_t open_persistent_id);
+
/* The following definitions come from locking/posix.c */
diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index 56637ed43d..04ff247c6d 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -501,3 +501,102 @@ int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
return count;
}
}
+
+bool share_mode_cleanup_disconnected(struct file_id fid,
+ uint64_t open_persistent_id)
+{
+ bool ret = false;
+ TALLOC_CTX *frame = talloc_stackframe();
+ unsigned n;
+ struct share_mode_data *data;
+ struct share_mode_lock *lck;
+ bool ok;
+
+ lck = get_existing_share_mode_lock(frame, fid);
+ if (lck == NULL) {
+ DEBUG(5, ("share_mode_cleanup_disconnected: "
+ "Could not fetch share mode entry for %s\n",
+ file_id_string(frame, &fid)));
+ goto done;
+ }
+ data = lck->data;
+
+ for (n=0; n < data->num_share_modes; n++) {
+ struct share_mode_entry *entry = &data->share_modes[n];
+
+ if (!server_id_is_disconnected(&entry->pid)) {
+ DEBUG(5, ("share_mode_cleanup_disconnected: "
+ "file (file-id='%s', servicepath='%s', "
+ "base_name='%s%s%s') "
+ "is used by server %s ==> do not cleanup\n",
+ file_id_string(frame, &fid),
+ data->servicepath,
+ data->base_name,
+ (data->stream_name == NULL)
+ ? "" : "', stream_name='",
+ (data->stream_name == NULL)
+ ? "" : data->stream_name,
+ server_id_str(frame, &entry->pid)));
+ goto done;
+ }
+ if (open_persistent_id != entry->share_file_id) {
+ DEBUG(5, ("share_mode_cleanup_disconnected: "
+ "entry for file "
+ "(file-id='%s', servicepath='%s', "
+ "base_name='%s%s%s') "
+ "has share_file_id %llu but expected %llu"
+ "==> do not cleanup\n",
+ file_id_string(frame, &fid),
+ data->servicepath,
+ data->base_name,
+ (data->stream_name == NULL)
+ ? "" : "', stream_name='",
+ (data->stream_name == NULL)
+ ? "" : data->stream_name,
+ (unsigned long long)entry->share_file_id,
+ (unsigned long long)open_persistent_id));
+ goto done;
+ }
+ }
+
+ ok = brl_cleanup_disconnected(fid, open_persistent_id);
+ if (!ok) {
+ DEBUG(10, ("share_mode_cleanup_disconnected: "
+ "failed to clean up byte range locks associated "
+ "with file (file-id='%s', servicepath='%s', "
+ "base_name='%s%s%s') and open_persistent_id %llu "
+ "==> do not cleanup\n",
+ file_id_string(frame, &fid),
+ data->servicepath,
+ data->base_name,
+ (data->stream_name == NULL)
+ ? "" : "', stream_name='",
+ (data->stream_name == NULL)
+ ? "" : data->stream_name,
+ (unsigned long long)open_persistent_id));
+ goto done;
+ }
+
+ DEBUG(10, ("share_mode_cleanup_disconnected: "
+ "cleaning up %u entries for file "
+ "(file-id='%s', servicepath='%s', "
+ "base_name='%s%s%s') "
+ "from open_persistent_id %llu\n",
+ data->num_share_modes,
+ file_id_string(frame, &fid),
+ data->servicepath,
+ data->base_name,
+ (data->stream_name == NULL)
+ ? "" : "', stream_name='",
+ (data->stream_name == NULL)
+ ? "" : data->stream_name,
+ (unsigned long long)open_persistent_id));
+
+ data->num_share_modes = 0;
+ data->modified = true;
+
+ ret = true;
+done:
+ talloc_free(frame);
+ return ret;
+}