VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[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), nr, ret, file, line);
70         return ret;
71 }
72
73 static inline void __dl_free_space(struct super_block *sb,
74         xid_t xid, dlsize_t nr, const char *_file, int _line)
75 {
76         struct dl_info *dli = NULL;
77
78         if (nr == 0)
79                 goto out;
80         dli = locate_dl_info(sb, xid);
81         if (!dli)
82                 goto out;
83
84         spin_lock(&dli->dl_lock);
85         if (dli->dl_space_used > nr)
86                 dli->dl_space_used -= nr;
87         else
88                 dli->dl_space_used = 0;
89         spin_unlock(&dli->dl_lock);
90         put_dl_info(dli);
91 out:
92         vxlprintk(VXD_CBIT(dlim, 1),
93                 "FREE  (%p,#%d)%c %lld bytes",
94                 sb, xid, __dlimit_char(dli), nr, _file, _line);
95 }
96
97 static inline int __dl_alloc_inode(struct super_block *sb,
98         xid_t xid, const char *_file, int _line)
99 {
100         struct dl_info *dli;
101         int ret = 0;
102
103         dli = locate_dl_info(sb, xid);
104         if (!dli)
105                 goto out;
106
107         spin_lock(&dli->dl_lock);
108         ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
109         if (!ret)
110                 dli->dl_inodes_used++;
111 #if 0
112         else
113                 printk("VSW: DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d\n",
114                         sb, xid,
115                         dli->dl_inodes_used, dli->dl_inodes_total,
116                         file, line);
117 #endif
118         spin_unlock(&dli->dl_lock);
119         put_dl_info(dli);
120 out:
121         vxlprintk(VXD_CBIT(dlim, 0),
122                 "ALLOC (%p,#%d)%c inode (%d)",
123                 sb, xid, __dlimit_char(dli), ret, _file, _line);
124         return ret;
125 }
126
127 static inline void __dl_free_inode(struct super_block *sb,
128         xid_t xid, const char *_file, int _line)
129 {
130         struct dl_info *dli;
131
132         dli = locate_dl_info(sb, xid);
133         if (!dli)
134                 goto out;
135
136         spin_lock(&dli->dl_lock);
137         if (dli->dl_inodes_used > 1)
138                 dli->dl_inodes_used--;
139         else
140                 dli->dl_inodes_used = 0;
141         spin_unlock(&dli->dl_lock);
142         put_dl_info(dli);
143 out:
144         vxlprintk(VXD_CBIT(dlim, 0),
145                 "FREE  (%p,#%d)%c inode",
146                 sb, xid, __dlimit_char(dli), _file, _line);
147 }
148
149 static inline void __dl_adjust_block(struct super_block *sb, xid_t xid,
150         unsigned int *free_blocks, unsigned int *root_blocks,
151         const char *_file, int _line)
152 {
153         struct dl_info *dli;
154         uint64_t broot, bfree;
155
156         dli = locate_dl_info(sb, xid);
157         if (!dli)
158                 return;
159
160         spin_lock(&dli->dl_lock);
161         broot = (dli->dl_space_total -
162                 (dli->dl_space_total >> 10) * dli->dl_nrlmult)
163                 >> sb->s_blocksize_bits;
164         bfree = (dli->dl_space_total - dli->dl_space_used)
165                         >> sb->s_blocksize_bits;
166         spin_unlock(&dli->dl_lock);
167
168         vxlprintk(VXD_CBIT(dlim, 2),
169                 "ADJUST: %lld,%lld on %d,%d [mult=%d]",
170                 bfree, broot, *free_blocks, *root_blocks,
171                 dli->dl_nrlmult, _file, _line);
172         if (free_blocks) {
173                 if (*free_blocks > bfree)
174                         *free_blocks = bfree;
175         }
176         if (root_blocks) {
177                 if (*root_blocks > broot)
178                         *root_blocks = broot;
179         }
180         put_dl_info(dli);
181 }
182
183
184 #define DLIMIT_ALLOC_BLOCK(sb, xid, nr) \
185         __dl_alloc_space(sb, xid, \
186                 ((dlsize_t)(nr)) << (sb)->s_blocksize_bits, \
187                 __FILE__, __LINE__ )
188
189 #define DLIMIT_FREE_BLOCK(sb, xid, nr) \
190         __dl_free_space(sb, xid, \
191                 ((dlsize_t)(nr)) << (sb)->s_blocksize_bits, \
192                 __FILE__, __LINE__ )
193
194 #define DLIMIT_ALLOC_INODE(sb, xid) \
195         __dl_alloc_inode(sb, xid, __FILE__, __LINE__ )
196
197 #define DLIMIT_FREE_INODE(sb, xid) \
198         __dl_free_inode(sb, xid, __FILE__, __LINE__ )
199
200
201 #define DLIMIT_ADJUST_BLOCK(sb, xid, fb, rb) \
202         __dl_adjust_block(sb, xid, fb, rb, __FILE__, __LINE__ )
203
204
205 #else
206 #warning duplicate inclusion
207 #endif