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