diff mbox series

[1/3] xarray: add xa_set

Message ID 20240812063143.3806677-2-hch@lst.de (mailing list archive)
State Accepted, archived
Headers show
Series [1/3] xarray: add xa_set | expand

Commit Message

Christoph Hellwig Aug. 12, 2024, 6:31 a.m. UTC
Add a convenience wrapper or xa_store that returns an error value when
there is an existing entry instead of the old entry.  This simplifies
code that wants to check that it is never overwriting an existing
entry.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 include/linux/xarray.h |  1 +
 lib/xarray.c           | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

Comments

Matthew Wilcox Aug. 12, 2024, 12:25 p.m. UTC | #1
On Mon, Aug 12, 2024 at 08:31:00AM +0200, Christoph Hellwig wrote:
> Add a convenience wrapper or xa_store that returns an error value when
> there is an existing entry instead of the old entry.  This simplifies
> code that wants to check that it is never overwriting an existing
> entry.

How is that different from xa_insert()?
Christoph Hellwig Aug. 12, 2024, 12:28 p.m. UTC | #2
On Mon, Aug 12, 2024 at 01:25:11PM +0100, Matthew Wilcox wrote:
> On Mon, Aug 12, 2024 at 08:31:00AM +0200, Christoph Hellwig wrote:
> > Add a convenience wrapper or xa_store that returns an error value when
> > there is an existing entry instead of the old entry.  This simplifies
> > code that wants to check that it is never overwriting an existing
> > entry.
> 
> How is that different from xa_insert()?

They do look the same from a very quick glance, no idea why I missed
it.  That's even better than having to invent new helpers.
diff mbox series

Patch

diff --git a/include/linux/xarray.h b/include/linux/xarray.h
index 0b618ec04115fc..8dc4e575378ca5 100644
--- a/include/linux/xarray.h
+++ b/include/linux/xarray.h
@@ -354,6 +354,7 @@  struct xarray {
 
 void *xa_load(struct xarray *, unsigned long index);
 void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
+int xa_set(struct xarray *, unsigned long index, void *entry, gfp_t);
 void *xa_erase(struct xarray *, unsigned long index);
 void *xa_store_range(struct xarray *, unsigned long first, unsigned long last,
 			void *entry, gfp_t);
diff --git a/lib/xarray.c b/lib/xarray.c
index 32d4bac8c94ca1..500d3405c0c8c0 100644
--- a/lib/xarray.c
+++ b/lib/xarray.c
@@ -1600,6 +1600,39 @@  void *xa_store(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
 }
 EXPORT_SYMBOL(xa_store);
 
+/**
+ * xa_set() - Store this entry in the XArray.
+ * @xa: XArray.
+ * @index: Index into array.
+ * @entry: New entry.
+ * @gfp: Memory allocation flags.
+ *
+ * After this function returns, loads from this index will return @entry.
+ * Storing into an existing multi-index entry updates the entry of every index.
+ * The marks associated with @index are unaffected unless @entry is %NULL.
+ *
+ * Context: Any context.  Takes and releases the xa_lock.
+ * May sleep if the @gfp flags permit.
+ * Return: 0 on success, -EEXIST if there already is an entry at @index, -EINVAL
+ * if @entry cannot be stored in an XArray, or -ENOMEM if memory allocation
+ * failed.
+ */
+int xa_set(struct xarray *xa, unsigned long index, void *entry, gfp_t gfp)
+{
+	int error = 0;
+	void *curr;
+
+	curr = xa_store(xa, index, entry, gfp);
+	if (curr) {
+		error = xa_err(curr);
+		if (error == 0)
+			error = -ENOENT;
+	}
+
+	return error;
+}
+EXPORT_SYMBOL(xa_set);
+
 /**
  * __xa_cmpxchg() - Store this entry in the XArray.
  * @xa: XArray.