fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / include / linux / vs_dlimit.h
1 #ifndef _VS_DLIMIT_H
2 #define _VS_DLIMIT_H
3
4 #include "vserver/dlimit.h"
5 #include "vserver/base.h"
6 #include "vserver/debug.h"
7
8
9 #define get_dl_info(i)  __get_dl_info(i,__FILE__,__LINE__)
10
11 static inline struct dl_info *__get_dl_info(struct dl_info *dli,
12         const char *_file, int _line)
13 {
14         if (!dli)
15                 return NULL;
16         vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
17                 dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
18                 _file, _line);
19         atomic_inc(&dli->dl_usecnt);
20         return dli;
21 }
22
23
24 #define free_dl_info(i) \
25         call_rcu(&i->dl_rcu, rcu_free_dl_info);
26
27 #define put_dl_info(i)  __put_dl_info(i,__FILE__,__LINE__)
28
29 static inline void __put_dl_info(struct dl_info *dli,
30         const char *_file, int _line)
31 {
32         if (!dli)
33                 return;
34         vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
35                 dli, dli?dli->dl_tag:0, dli?atomic_read(&dli->dl_usecnt):0,
36                 _file, _line);
37         if (atomic_dec_and_test(&dli->dl_usecnt))
38                 free_dl_info(dli);
39 }
40
41
42 #define __dlimit_char(d)        ((d)?'*':' ')
43
44 static inline int __dl_alloc_space(struct super_block *sb,
45         tag_t tag, dlsize_t nr, const char *file, int line)
46 {
47         struct dl_info *dli = NULL;
48         int ret = 0;
49
50         if (nr == 0)
51                 goto out;
52         dli = locate_dl_info(sb, tag);
53         if (!dli)
54                 goto out;
55
56         spin_lock(&dli->dl_lock);
57         ret = (dli->dl_space_used + nr > dli->dl_space_total);
58         if (!ret)
59                 dli->dl_space_used += nr;
60         spin_unlock(&dli->dl_lock);
61         put_dl_info(dli);
62 out:
63         vxlprintk(VXD_CBIT(dlim, 1),
64                 "ALLOC (%p,#%d)%c %lld bytes (%d)",
65                 sb, tag, __dlimit_char(dli), (long long)nr,
66                 ret, file, line);
67         return ret;
68 }
69
70 static inline void __dl_free_space(struct super_block *sb,
71         tag_t tag, dlsize_t nr, const char *_file, int _line)
72 {
73         struct dl_info *dli = NULL;
74
75         if (nr == 0)
76                 goto out;
77         dli = locate_dl_info(sb, tag);
78         if (!dli)
79                 goto out;
80
81         spin_lock(&dli->dl_lock);
82         if (dli->dl_space_used > nr)
83                 dli->dl_space_used -= nr;
84         else
85                 dli->dl_space_used = 0;
86         spin_unlock(&dli->dl_lock);
87         put_dl_info(dli);
88 out:
89         vxlprintk(VXD_CBIT(dlim, 1),
90                 "FREE  (%p,#%d)%c %lld bytes",
91                 sb, tag, __dlimit_char(dli), (long long)nr,
92                 _file, _line);
93 }
94
95 static inline int __dl_alloc_inode(struct super_block *sb,
96         tag_t tag, const char *_file, int _line)
97 {
98         struct dl_info *dli;
99         int ret = 0;
100
101         dli = locate_dl_info(sb, tag);
102         if (!dli)
103                 goto out;
104
105         spin_lock(&dli->dl_lock);
106         ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
107         if (!ret)
108                 dli->dl_inodes_used++;
109         spin_unlock(&dli->dl_lock);
110         put_dl_info(dli);
111 out:
112         vxlprintk(VXD_CBIT(dlim, 0),
113                 "ALLOC (%p,#%d)%c inode (%d)",
114                 sb, tag, __dlimit_char(dli), ret, _file, _line);
115         return ret;
116 }
117
118 static inline void __dl_free_inode(struct super_block *sb,
119         tag_t tag, const char *_file, int _line)
120 {
121         struct dl_info *dli;
122
123         dli = locate_dl_info(sb, tag);
124         if (!dli)
125                 goto out;
126
127         spin_lock(&dli->dl_lock);
128         if (dli->dl_inodes_used > 1)
129                 dli->dl_inodes_used--;
130         else
131                 dli->dl_inodes_used = 0;
132         spin_unlock(&dli->dl_lock);
133         put_dl_info(dli);
134 out:
135         vxlprintk(VXD_CBIT(dlim, 0),
136                 "FREE  (%p,#%d)%c inode",
137                 sb, tag, __dlimit_char(dli), _file, _line);
138 }
139
140 static inline void __dl_adjust_block(struct super_block *sb, tag_t tag,
141         unsigned long long *free_blocks, unsigned long long *root_blocks,
142         const char *_file, int _line)
143 {
144         struct dl_info *dli;
145         uint64_t broot, bfree;
146
147         dli = locate_dl_info(sb, tag);
148         if (!dli)
149                 return;
150
151         spin_lock(&dli->dl_lock);
152         broot = (dli->dl_space_total -
153                 (dli->dl_space_total >> 10) * dli->dl_nrlmult)
154                 >> sb->s_blocksize_bits;
155         bfree = (dli->dl_space_total - dli->dl_space_used)
156                         >> sb->s_blocksize_bits;
157         spin_unlock(&dli->dl_lock);
158
159         vxlprintk(VXD_CBIT(dlim, 2),
160                 "ADJUST: %lld,%lld on %lld,%lld [mult=%d]",
161                 (long long)bfree, (long long)broot,
162                 *free_blocks, *root_blocks, dli->dl_nrlmult,
163                 _file, _line);
164         if (free_blocks) {
165                 if (*free_blocks > bfree)
166                         *free_blocks = bfree;
167         }
168         if (root_blocks) {
169                 if (*root_blocks > broot)
170                         *root_blocks = broot;
171         }
172         put_dl_info(dli);
173 }
174
175 #define DLIMIT_ALLOC_SPACE(in, bytes) \
176         __dl_alloc_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
177                 __FILE__, __LINE__ )
178
179 #define DLIMIT_FREE_SPACE(in, bytes) \
180         __dl_free_space((in)->i_sb, (in)->i_tag, (dlsize_t)(bytes), \
181                 __FILE__, __LINE__ )
182
183 #define DLIMIT_ALLOC_BLOCK(in, nr) \
184         __dl_alloc_space((in)->i_sb, (in)->i_tag, \
185                 ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
186                 __FILE__, __LINE__ )
187
188 #define DLIMIT_FREE_BLOCK(in, nr) \
189         __dl_free_space((in)->i_sb, (in)->i_tag, \
190                 ((dlsize_t)(nr)) << (in)->i_sb->s_blocksize_bits, \
191                 __FILE__, __LINE__ )
192
193
194 #define DLIMIT_ALLOC_INODE(in) \
195         __dl_alloc_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
196
197 #define DLIMIT_FREE_INODE(in) \
198         __dl_free_inode((in)->i_sb, (in)->i_tag, __FILE__, __LINE__ )
199
200
201 #define DLIMIT_ADJUST_BLOCK(sb, tag, fb, rb) \
202         __dl_adjust_block(sb, tag, fb, rb, __FILE__, __LINE__ )
203
204
205 #else
206 #warning duplicate inclusion
207 #endif