@@ -275,6 +275,8 @@ struct xarray {
275
275
void xa_init_flags (struct xarray * , gfp_t flags );
276
276
void * xa_load (struct xarray * , unsigned long index );
277
277
void * xa_store (struct xarray * , unsigned long index , void * entry , gfp_t );
278
+ void * xa_cmpxchg (struct xarray * , unsigned long index ,
279
+ void * old , void * entry , gfp_t );
278
280
bool xa_get_mark (struct xarray * , unsigned long index , xa_mark_t );
279
281
void xa_set_mark (struct xarray * , unsigned long index , xa_mark_t );
280
282
void xa_clear_mark (struct xarray * , unsigned long index , xa_mark_t );
@@ -334,6 +336,34 @@ static inline void *xa_erase(struct xarray *xa, unsigned long index)
334
336
return xa_store (xa , index , NULL , 0 );
335
337
}
336
338
339
+ /**
340
+ * xa_insert() - Store this entry in the XArray unless another entry is
341
+ * already present.
342
+ * @xa: XArray.
343
+ * @index: Index into array.
344
+ * @entry: New entry.
345
+ * @gfp: Memory allocation flags.
346
+ *
347
+ * If you would rather see the existing entry in the array, use xa_cmpxchg().
348
+ * This function is for users who don't care what the entry is, only that
349
+ * one is present.
350
+ *
351
+ * Context: Process context. Takes and releases the xa_lock.
352
+ * May sleep if the @gfp flags permit.
353
+ * Return: 0 if the store succeeded. -EEXIST if another entry was present.
354
+ * -ENOMEM if memory could not be allocated.
355
+ */
356
+ static inline int xa_insert (struct xarray * xa , unsigned long index ,
357
+ void * entry , gfp_t gfp )
358
+ {
359
+ void * curr = xa_cmpxchg (xa , index , NULL , entry , gfp );
360
+ if (!curr )
361
+ return 0 ;
362
+ if (xa_is_err (curr ))
363
+ return xa_err (curr );
364
+ return - EEXIST ;
365
+ }
366
+
337
367
#define xa_trylock (xa ) spin_trylock(&(xa)->xa_lock)
338
368
#define xa_lock (xa ) spin_lock(&(xa)->xa_lock)
339
369
#define xa_unlock (xa ) spin_unlock(&(xa)->xa_lock)
@@ -355,9 +385,39 @@ static inline void *xa_erase(struct xarray *xa, unsigned long index)
355
385
*/
356
386
void * __xa_erase (struct xarray * , unsigned long index );
357
387
void * __xa_store (struct xarray * , unsigned long index , void * entry , gfp_t );
388
+ void * __xa_cmpxchg (struct xarray * , unsigned long index , void * old ,
389
+ void * entry , gfp_t );
358
390
void __xa_set_mark (struct xarray * , unsigned long index , xa_mark_t );
359
391
void __xa_clear_mark (struct xarray * , unsigned long index , xa_mark_t );
360
392
393
+ /**
394
+ * __xa_insert() - Store this entry in the XArray unless another entry is
395
+ * already present.
396
+ * @xa: XArray.
397
+ * @index: Index into array.
398
+ * @entry: New entry.
399
+ * @gfp: Memory allocation flags.
400
+ *
401
+ * If you would rather see the existing entry in the array, use __xa_cmpxchg().
402
+ * This function is for users who don't care what the entry is, only that
403
+ * one is present.
404
+ *
405
+ * Context: Any context. Expects xa_lock to be held on entry. May
406
+ * release and reacquire xa_lock if the @gfp flags permit.
407
+ * Return: 0 if the store succeeded. -EEXIST if another entry was present.
408
+ * -ENOMEM if memory could not be allocated.
409
+ */
410
+ static inline int __xa_insert (struct xarray * xa , unsigned long index ,
411
+ void * entry , gfp_t gfp )
412
+ {
413
+ void * curr = __xa_cmpxchg (xa , index , NULL , entry , gfp );
414
+ if (!curr )
415
+ return 0 ;
416
+ if (xa_is_err (curr ))
417
+ return xa_err (curr );
418
+ return - EEXIST ;
419
+ }
420
+
361
421
/**
362
422
* xa_erase_bh() - Erase this entry from the XArray.
363
423
* @xa: XArray.
0 commit comments