From: Volker Lendecke Date: Mon, 17 Sep 2018 11:14:22 +0000 (+0200) Subject: smbd: Add share_mode_forall_leases() X-Git-Tag: tdb-1.4.1~401 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=302bdd7f9132b64daf65ceddc1658c3f91d7f0c1;p=thirdparty%2Fsamba.git smbd: Add share_mode_forall_leases() Function to walk all leases for a file exactly once. This used to be simpler with the leases[] array, thus this function that encapsulates the complexity. Signed-off-by: Volker Lendecke Reviewed-by: Christof Schmitt --- diff --git a/source3/locking/locking.c b/source3/locking/locking.c index ddae9203986..0c08a2d5830 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -1296,3 +1296,77 @@ bool file_has_open_streams(files_struct *fsp) TALLOC_FREE(lock); return false; } + +/* + * Walk share mode entries, looking at every lease only once + */ + +bool share_mode_forall_leases( + struct share_mode_lock *lck, + bool (*fn)(struct share_mode_lock *lck, + struct share_mode_entry *e, + void *private_data), + void *private_data) +{ + struct share_mode_data *d = lck->data; + uint32_t *leases = NULL; + uint32_t num_leases = 0; + uint32_t i; + + leases = talloc_array(talloc_tos(), uint32_t, d->num_share_modes); + if (leases == NULL) { + return false; + } + + for (i=0; inum_share_modes; i++) { + struct share_mode_entry *e = &d->share_modes[i]; + uint32_t j; + bool ok, stop; + + ok = is_valid_share_mode_entry(e); + if (!ok) { + continue; + } + + if (e->op_type != LEASE_OPLOCK) { + continue; + } + + /* + * See if we have already seen "e"'s lease. This is + * O(n^2). If we sort "leases", we can get this down + * to O(n). + */ + + for (j=0; jshare_modes[idx]; + + if (smb2_lease_equal(&e->client_guid, + &e->lease_key, + &l->client_guid, + &l->lease_key)) { + break; + } + } + if (j < num_leases) { + /* + * Don't look at "e"'s lease, we've already + * seen it. + */ + continue; + } + + stop = fn(lck, e, private_data); + if (stop) { + TALLOC_FREE(leases); + return true; + } + + leases[num_leases] = i; + num_leases += 1; + } + + TALLOC_FREE(leases); + return true; +} diff --git a/source3/locking/proto.h b/source3/locking/proto.h index c021d978d44..9a9feffc0a4 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -217,6 +217,12 @@ int share_entry_forall(int (*fn)(struct file_id fid, void *private_data); bool share_mode_cleanup_disconnected(struct file_id id, uint64_t open_persistent_id); +bool share_mode_forall_leases( + struct share_mode_lock *lck, + bool (*fn)(struct share_mode_lock *lck, + struct share_mode_entry *e, + void *private_data), + void *private_data); /* The following definitions come from locking/posix.c */