194a312a1SFrançois Tigeot /*- 294a312a1SFrançois Tigeot * Copyright (c) 2010 Isilon Systems, Inc. 394a312a1SFrançois Tigeot * Copyright (c) 2010 iX Systems, Inc. 494a312a1SFrançois Tigeot * Copyright (c) 2010 Panasas, Inc. 532dbd5b5SFrançois Tigeot * Copyright (c) 2013 François Tigeot 694a312a1SFrançois Tigeot * All rights reserved. 794a312a1SFrançois Tigeot * 894a312a1SFrançois Tigeot * Redistribution and use in source and binary forms, with or without 994a312a1SFrançois Tigeot * modification, are permitted provided that the following conditions 1094a312a1SFrançois Tigeot * are met: 1194a312a1SFrançois Tigeot * 1. Redistributions of source code must retain the above copyright 1294a312a1SFrançois Tigeot * notice unmodified, this list of conditions, and the following 1394a312a1SFrançois Tigeot * disclaimer. 1494a312a1SFrançois Tigeot * 2. Redistributions in binary form must reproduce the above copyright 1594a312a1SFrançois Tigeot * notice, this list of conditions and the following disclaimer in the 1694a312a1SFrançois Tigeot * documentation and/or other materials provided with the distribution. 1794a312a1SFrançois Tigeot * 1894a312a1SFrançois Tigeot * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1994a312a1SFrançois Tigeot * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2094a312a1SFrançois Tigeot * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2194a312a1SFrançois Tigeot * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2294a312a1SFrançois Tigeot * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2394a312a1SFrançois Tigeot * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2494a312a1SFrançois Tigeot * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2594a312a1SFrançois Tigeot * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2694a312a1SFrançois Tigeot * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2794a312a1SFrançois Tigeot * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2894a312a1SFrançois Tigeot */ 2994a312a1SFrançois Tigeot #ifndef _LINUX_KREF_H_ 3094a312a1SFrançois Tigeot #define _LINUX_KREF_H_ 3194a312a1SFrançois Tigeot 3294a312a1SFrançois Tigeot #include <sys/refcount.h> 3394a312a1SFrançois Tigeot 3494a312a1SFrançois Tigeot struct kref { 3532dbd5b5SFrançois Tigeot atomic_t refcount; 3694a312a1SFrançois Tigeot }; 3794a312a1SFrançois Tigeot 3894a312a1SFrançois Tigeot static inline void 3994a312a1SFrançois Tigeot kref_init(struct kref *kref) 4094a312a1SFrançois Tigeot { 4194a312a1SFrançois Tigeot 4232dbd5b5SFrançois Tigeot refcount_init(&kref->refcount.counter, 1); 4394a312a1SFrançois Tigeot } 4494a312a1SFrançois Tigeot 4594a312a1SFrançois Tigeot static inline void 4694a312a1SFrançois Tigeot kref_get(struct kref *kref) 4794a312a1SFrançois Tigeot { 4894a312a1SFrançois Tigeot 4932dbd5b5SFrançois Tigeot refcount_acquire(&kref->refcount.counter); 5094a312a1SFrançois Tigeot } 5194a312a1SFrançois Tigeot 5294a312a1SFrançois Tigeot static inline int 5394a312a1SFrançois Tigeot kref_put(struct kref *kref, void (*rel)(struct kref *kref)) 5494a312a1SFrançois Tigeot { 5594a312a1SFrançois Tigeot 5632dbd5b5SFrançois Tigeot if (refcount_release(&kref->refcount.counter)) { 5732dbd5b5SFrançois Tigeot rel(kref); 5832dbd5b5SFrançois Tigeot return 1; 5932dbd5b5SFrançois Tigeot } 6032dbd5b5SFrançois Tigeot return 0; 6132dbd5b5SFrançois Tigeot } 6232dbd5b5SFrançois Tigeot 6332dbd5b5SFrançois Tigeot static inline int 6432dbd5b5SFrançois Tigeot kref_sub(struct kref *kref, unsigned int count, 6532dbd5b5SFrançois Tigeot void (*rel)(struct kref *kref)) 6632dbd5b5SFrançois Tigeot { 6732dbd5b5SFrançois Tigeot if (refcount_release_n(&kref->refcount.counter, count)) { 6894a312a1SFrançois Tigeot rel(kref); 6994a312a1SFrançois Tigeot return 1; 7094a312a1SFrançois Tigeot } 7194a312a1SFrançois Tigeot return 0; 7294a312a1SFrançois Tigeot } 7394a312a1SFrançois Tigeot 74*1dca5014SFrançois Tigeot /* 75*1dca5014SFrançois Tigeot * kref_get_unless_zero: Increment refcount for object unless it is zero. 76*1dca5014SFrançois Tigeot */ 77*1dca5014SFrançois Tigeot static inline int __must_check kref_get_unless_zero(struct kref *kref) 78*1dca5014SFrançois Tigeot { 79*1dca5014SFrançois Tigeot return atomic_add_unless(&kref->refcount, 1, 0); 80*1dca5014SFrançois Tigeot } 81*1dca5014SFrançois Tigeot 82*1dca5014SFrançois Tigeot #endif /* _LINUX_KREF_H_ */ 83