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