Whamcloud - gitweb
Revert "b=23913 fix "ASSERTION(!cfs_list_empty(&dquot->dq_hash)) failed""
[fs/lustre-release.git] / lnet / libcfs / user-bitops.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 #ifndef __KERNEL__
37
38 #include <libcfs/libcfs.h>
39 #include <libcfs/kp30.h>
40 #include <libcfs/user-bitops.h>
41
42 #define OFF_BY_START(start)     ((start)/BITS_PER_LONG)
43
44 unsigned long find_next_bit(unsigned long *addr,
45                             unsigned long size, unsigned long offset)
46 {
47         unsigned long *word, *last;
48         unsigned long first_bit, bit, base;
49
50         word = addr + OFF_BY_START(offset);
51         last = addr + OFF_BY_START(size-1);
52         first_bit = offset % BITS_PER_LONG;
53         base = offset - first_bit;
54
55         if (offset >= size)
56                 return size;
57         if (first_bit != 0) {
58                 int tmp = (*word++) & (~0UL << first_bit);
59                 bit = __ffs(tmp);
60                 if (bit < BITS_PER_LONG)
61                         goto found;
62                 word++;
63                 base += BITS_PER_LONG;
64         }
65         while (word <= last) {
66                 if (*word != 0UL) {
67                         bit = __ffs(*word);
68                         goto found;
69                 }
70                 word++;
71                 base += BITS_PER_LONG;
72         }
73         return size;
74 found:
75         return base + bit;
76 }
77
78 unsigned long find_next_zero_bit(unsigned long *addr,
79                                  unsigned long size, unsigned long offset)
80 {
81         unsigned long *word, *last;
82         unsigned long first_bit, bit, base;
83
84         word = addr + OFF_BY_START(offset);
85         last = addr + OFF_BY_START(size-1);
86         first_bit = offset % BITS_PER_LONG;
87         base = offset - first_bit;
88
89         if (offset >= size)
90                 return size;
91         if (first_bit != 0) {
92                 int tmp = (*word++) & (~0UL << first_bit);
93                 bit = __ffz(tmp);
94                 if (bit < BITS_PER_LONG)
95                         goto found;
96                 word++;
97                 base += BITS_PER_LONG;
98         }
99         while (word <= last) {
100                 if (*word != ~0UL) {
101                         bit = __ffz(*word);
102                         goto found;
103                 }
104                 word++;
105                 base += BITS_PER_LONG;
106         }
107         return size;
108 found:
109         return base + bit;
110 }
111
112 #endif