diff options
author | Gregor Beck <gbeck@sernet.de> | 2013-03-13 11:35:37 +0100 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2013-04-18 13:15:13 +0200 |
commit | f608bedfca4118b7e3606802df40e266bcc099d8 (patch) | |
tree | 012ea1fc0b807c2c6e207d77dfb6b2f30f8525f6 /source3/locking | |
parent | 0ac0b35dad796d10cf04ab77a53a926420cc0589 (diff) | |
download | samba-f608bedfca4118b7e3606802df40e266bcc099d8.tar.gz samba-f608bedfca4118b7e3606802df40e266bcc099d8.tar.bz2 samba-f608bedfca4118b7e3606802df40e266bcc099d8.zip |
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.h | 3 | ||||
-rw-r--r-- | source3/locking/share_mode_lock.c | 99 |
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; +} |