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