]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/locking: tweak share_entry_forall()
authorRalph Boehme <slow@samba.org>
Sat, 12 Oct 2024 14:03:56 +0000 (16:03 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 5 Nov 2024 14:39:30 +0000 (14:39 +0000)
Gives the callback function more control about when of a locking.tdb
traverse is stopped. If the callback function returns:

  0 => continue traverse
  1 => stop loop over share_mode_entries, but continue share_mode_data traverse
 -1 => stop whole share_mode_data traverse

All existing callers of share_entry_forall() either return 0 or -1 from their
callback functions, so no change in behaviour.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15608

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/locking/share_mode_lock.c

index d0dc0cb465e382a76157bc335bfbce60c771167b..4e1b6e0292d82fafdb419274e453bd4aab9075c1 100644 (file)
@@ -1876,10 +1876,22 @@ static bool share_entry_traverse_walker(
        void *private_data)
 {
        struct share_entry_forall_state *state = private_data;
+       int ret;
 
-       state->ret = state->fn(
-               state->fid, state->data, e, state->private_data);
-       return (state->ret != 0);
+       ret = state->fn(state->fid, state->data, e, state->private_data);
+       if (ret == 0) {
+               /* Continue the whole traverse */
+               return 0;
+       } else if (ret == 1) {
+               /*
+                * Just stop share_mode_entry loop: by not setting
+                * state->ret (which was initialized to 0), the
+                * share_mode_data traverse will continue.
+                */
+               return 1;
+       }
+       state->ret = ret;
+       return 1;
 }
 
 static int share_entry_traverse_fn(struct file_id fid,
@@ -1895,6 +1907,7 @@ static int share_entry_traverse_fn(struct file_id fid,
 
        state->fid = fid;
        state->data = data;
+       state->ret = 0;
 
        ok = share_mode_forall_entries(
                &lck, share_entry_traverse_walker, state);
@@ -1908,7 +1921,13 @@ static int share_entry_traverse_fn(struct file_id fid,
 
 /*******************************************************************
  Call the specified function on each entry under management by the
- share mode system.
+ share mode system.  If the callback function returns:
+
+  0 ... continue traverse
+  1 ... stop loop over share_mode_entries, but continue share_mode_data traverse
+ -1 ... stop whole share_mode_data traverse
+
+ Any other return value is treated as -1.
 ********************************************************************/
 
 int share_entry_forall(int (*fn)(struct file_id fid,
@@ -1918,7 +1937,9 @@ int share_entry_forall(int (*fn)(struct file_id fid,
                      void *private_data)
 {
        struct share_entry_forall_state state = {
-               .fn = fn, .private_data = private_data };
+               .fn = fn,
+               .private_data = private_data,
+       };
 
        return share_mode_forall_read(share_entry_traverse_fn, &state);
 }