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 34*ba55f2f5SFrançois Tigeot #include <linux/atomic.h> 35*ba55f2f5SFrançois Tigeot 3694a312a1SFrançois Tigeot struct kref { 3732dbd5b5SFrançois Tigeot atomic_t refcount; 3894a312a1SFrançois Tigeot }; 3994a312a1SFrançois Tigeot 4094a312a1SFrançois Tigeot static inline void 4194a312a1SFrançois Tigeot kref_init(struct kref *kref) 4294a312a1SFrançois Tigeot { 4394a312a1SFrançois Tigeot 4432dbd5b5SFrançois Tigeot refcount_init(&kref->refcount.counter, 1); 4594a312a1SFrançois Tigeot } 4694a312a1SFrançois Tigeot 4794a312a1SFrançois Tigeot static inline void 4894a312a1SFrançois Tigeot kref_get(struct kref *kref) 4994a312a1SFrançois Tigeot { 5094a312a1SFrançois Tigeot 5132dbd5b5SFrançois Tigeot refcount_acquire(&kref->refcount.counter); 5294a312a1SFrançois Tigeot } 5394a312a1SFrançois Tigeot 5494a312a1SFrançois Tigeot static inline int 5594a312a1SFrançois Tigeot kref_put(struct kref *kref, void (*rel)(struct kref *kref)) 5694a312a1SFrançois Tigeot { 5794a312a1SFrançois Tigeot 5832dbd5b5SFrançois Tigeot if (refcount_release(&kref->refcount.counter)) { 5932dbd5b5SFrançois Tigeot rel(kref); 6032dbd5b5SFrançois Tigeot return 1; 6132dbd5b5SFrançois Tigeot } 6232dbd5b5SFrançois Tigeot return 0; 6332dbd5b5SFrançois Tigeot } 6432dbd5b5SFrançois Tigeot 6532dbd5b5SFrançois Tigeot static inline int 6632dbd5b5SFrançois Tigeot kref_sub(struct kref *kref, unsigned int count, 6732dbd5b5SFrançois Tigeot void (*rel)(struct kref *kref)) 6832dbd5b5SFrançois Tigeot { 6932dbd5b5SFrançois Tigeot if (refcount_release_n(&kref->refcount.counter, count)) { 7094a312a1SFrançois Tigeot rel(kref); 7194a312a1SFrançois Tigeot return 1; 7294a312a1SFrançois Tigeot } 7394a312a1SFrançois Tigeot return 0; 7494a312a1SFrançois Tigeot } 7594a312a1SFrançois Tigeot 761dca5014SFrançois Tigeot /* 771dca5014SFrançois Tigeot * kref_get_unless_zero: Increment refcount for object unless it is zero. 781dca5014SFrançois Tigeot */ 791dca5014SFrançois Tigeot static inline int __must_check kref_get_unless_zero(struct kref *kref) 801dca5014SFrançois Tigeot { 811dca5014SFrançois Tigeot return atomic_add_unless(&kref->refcount, 1, 0); 821dca5014SFrançois Tigeot } 831dca5014SFrançois Tigeot 841dca5014SFrançois Tigeot #endif /* _LINUX_KREF_H_ */ 85