]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/locking: add share_entry_forall_read() and share_entry_forall() varients
authorRalph Boehme <slow@samba.org>
Sun, 13 Oct 2024 09:11:32 +0000 (11:11 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 5 Nov 2024 14:39:30 +0000 (14:39 +0000)
All existing callers use share_entry_forall_read, 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
source3/locking/share_mode_lock.h
source3/rpc_server/srvsvc/srv_srvsvc_nt.c
source3/utils/status.c

index 4e1b6e0292d82fafdb419274e453bd4aab9075c1..1f2c931c12bac7a455e1e31fad29da959cc48f07 100644 (file)
@@ -1861,11 +1861,15 @@ int share_mode_forall(int (*fn)(struct file_id fid,
 
 struct share_entry_forall_state {
        struct file_id fid;
-       const struct share_mode_data *data;
-       int (*fn)(struct file_id fid,
-                 const struct share_mode_data *data,
-                 const struct share_mode_entry *entry,
-                 void *private_data);
+       struct share_mode_data *data;
+       int (*ro_fn)(struct file_id fid,
+                    const struct share_mode_data *data,
+                    const struct share_mode_entry *entry,
+                    void *private_data);
+       int (*rw_fn)(struct file_id fid,
+                    struct share_mode_data *data,
+                    struct share_mode_entry *entry,
+                    void *private_data);
        void *private_data;
        int ret;
 };
@@ -1878,7 +1882,17 @@ static bool share_entry_traverse_walker(
        struct share_entry_forall_state *state = private_data;
        int ret;
 
-       ret = state->fn(state->fid, state->data, e, state->private_data);
+       if (state->ro_fn != NULL) {
+               ret = state->ro_fn(state->fid,
+                                  state->data,
+                                  e,
+                                  state->private_data);
+       } else {
+               ret = state->rw_fn(state->fid,
+                                  state->data,
+                                  e,
+                                  state->private_data);
+       }
        if (ret == 0) {
                /* Continue the whole traverse */
                return 0;
@@ -1894,9 +1908,9 @@ static bool share_entry_traverse_walker(
        return 1;
 }
 
-static int share_entry_traverse_fn(struct file_id fid,
-                                  const struct share_mode_data *data,
-                                  void *private_data)
+static int share_entry_ro_traverse_fn(struct file_id fid,
+                                     const struct share_mode_data *data,
+                                     void *private_data)
 {
        struct share_entry_forall_state *state = private_data;
        struct share_mode_lock lck = {
@@ -1905,6 +1919,31 @@ static int share_entry_traverse_fn(struct file_id fid,
        };
        bool ok;
 
+       state->fid = fid;
+       state->data = discard_const_p(struct share_mode_data, data);
+       state->ret = 0;
+
+       ok = share_mode_forall_entries(
+               &lck, share_entry_traverse_walker, state);
+       if (!ok) {
+               DBG_ERR("share_mode_forall_entries failed\n");
+               return false;
+       }
+
+       return state->ret;
+}
+
+static int share_entry_rw_traverse_fn(struct file_id fid,
+                                     struct share_mode_data *data,
+                                     void *private_data)
+{
+       struct share_entry_forall_state *state = private_data;
+       struct share_mode_lock lck = {
+               .id = fid,
+               .cached_data = data,
+       };
+       bool ok;
+
        state->fid = fid;
        state->data = data;
        state->ret = 0;
@@ -1930,18 +1969,32 @@ static int share_entry_traverse_fn(struct file_id fid,
  Any other return value is treated as -1.
 ********************************************************************/
 
+int share_entry_forall_read(int (*fn)(struct file_id fid,
+                                     const struct share_mode_data *data,
+                                     const struct share_mode_entry *entry,
+                                     void *private_data),
+                           void *private_data)
+{
+       struct share_entry_forall_state state = {
+               .ro_fn = fn,
+               .private_data = private_data,
+       };
+
+       return share_mode_forall_read(share_entry_ro_traverse_fn, &state);
+}
+
 int share_entry_forall(int (*fn)(struct file_id fid,
-                                const struct share_mode_data *data,
-                                const struct share_mode_entry *entry,
+                                struct share_mode_data *data,
+                                struct share_mode_entry *entry,
                                 void *private_data),
                      void *private_data)
 {
        struct share_entry_forall_state state = {
-               .fn = fn,
+               .rw_fn = fn,
                .private_data = private_data,
        };
 
-       return share_mode_forall_read(share_entry_traverse_fn, &state);
+       return share_mode_forall(share_entry_rw_traverse_fn, &state);
 }
 
 static int share_mode_entry_cmp(
index d24ba5b780e8131f80816da703e27ea694b21a78..33ed8e034e6af83cef389fb03b9a19c76df6c28d 100644 (file)
@@ -83,12 +83,16 @@ NTSTATUS fetch_share_mode_recv(
        TALLOC_CTX *mem_ctx,
        struct share_mode_lock **_lck);
 
-int share_entry_forall(
-       int (*fn)(struct file_id fid,
-                 const struct share_mode_data *data,
-                 const struct share_mode_entry *entry,
-                 void *private_data),
-       void *private_data);
+int share_entry_forall_read(int (*ro_fn)(struct file_id fid,
+                                        const struct share_mode_data *data,
+                                        const struct share_mode_entry *entry,
+                                        void *private_data),
+                           void *private_data);
+int share_entry_forall(int (*fn)(struct file_id fid,
+                                struct share_mode_data *data,
+                                struct share_mode_entry *entry,
+                                void *private_data),
+                      void *private_data);
 
 NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes);
 int share_mode_forall(
index 1129576f751ec5d4060401d416ae02ce536d3e30..9006b81805dd91fcdd0ec96a5c61eda16b78e4aa 100644 (file)
@@ -185,7 +185,7 @@ static WERROR net_enum_files(TALLOC_CTX *ctx,
        };
        uint32_t i;
 
-       share_entry_forall(enum_file_fn, (void *)&f_enum_cnt );
+       share_entry_forall_read(enum_file_fn, (void *)&f_enum_cnt );
 
        *ctr3 = f_enum_cnt.ctr3;
 
@@ -1031,7 +1031,7 @@ static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
        s_file_info.resume_handle = resume_handle;
        s_file_info.num_entries = num_entries;
 
-       share_entry_forall(count_sess_files_fn, &s_file_info);
+       share_entry_forall_read(count_sess_files_fn, &s_file_info);
 }
 
 /*******************************************************************
@@ -1151,7 +1151,7 @@ static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
        sfs.resp_entries = resp_entries;
        sfs.total_entries = total_entries;
 
-       share_entry_forall(share_file_fn, &sfs);
+       share_entry_forall_read(share_file_fn, &sfs);
 }
 
 /****************************************************************************
@@ -2966,7 +2966,7 @@ WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
        r->out.result = WERR_FILE_NOT_FOUND;
        state.r = r;
        state.msg_ctx = p->msg_ctx;
-       share_entry_forall(enum_file_close_fn, &state);
+       share_entry_forall_read(enum_file_close_fn, &state);
        return r->out.result;
 }
 
index 02a5f6dbaba15613e1f635e8429fe96fd8705a48..f47504208e645e9dd01639ac363a91be48594d90 100644 (file)
@@ -1270,7 +1270,7 @@ int main(int argc, const char *argv[])
                }
 
                prepare_share_mode(&state);
-               result = share_entry_forall(print_share_mode, &state);
+               result = share_entry_forall_read(print_share_mode, &state);
 
                if (result == 0 && !state.json_output) {
                        fprintf(stderr, "No locked files\n");