patch-2.6.6-vs1.9.1
[linux-2.6.git] / include / linux / vinline.h
1 #ifndef _VX_INLINE_H
2 #define _VX_INLINE_H
3
4
5 // #define VX_DEBUG
6
7 #include <linux/kernel.h>
8 #include <linux/rcupdate.h>
9 #include <linux/sched.h>
10
11 #include "vserver/context.h"
12 #include "vserver/limit.h"
13 #include "vserver/cvirt.h"
14
15 #if defined(VX_DEBUG)
16 #define vxdprintk(x...) printk("vxd: " x)
17 #else
18 #define vxdprintk(x...)
19 #endif
20
21
22
23 extern int proc_pid_vx_info(struct task_struct *, char *);
24
25
26 #define get_vx_info(i)  __get_vx_info(i,__FILE__,__LINE__)
27
28 static inline struct vx_info *__get_vx_info(struct vx_info *vxi,
29         const char *_file, int _line)
30 {
31         if (!vxi)
32                 return NULL;
33         vxdprintk("get_vx_info(%p[#%d.%d])\t%s:%d\n",
34                 vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
35                 _file, _line);
36         atomic_inc(&vxi->vx_usecnt);
37         return vxi;
38 }
39
40
41 #define free_vx_info(vxi)       \
42         call_rcu(&vxi->vx_rcu, rcu_free_vx_info, vxi);
43
44 #define put_vx_info(i)  __put_vx_info(i,__FILE__,__LINE__)
45
46 static inline void __put_vx_info(struct vx_info *vxi, const char *_file, int _line)
47 {
48         if (!vxi)
49                 return;
50         vxdprintk("put_vx_info(%p[#%d.%d])\t%s:%d\n",
51                 vxi, vxi?vxi->vx_id:0, vxi?atomic_read(&vxi->vx_usecnt):0,
52                 _file, _line);
53         if (atomic_dec_and_test(&vxi->vx_usecnt))
54                 free_vx_info(vxi);
55 }
56
57 #define set_vx_info(p,i) __set_vx_info(p,i,__FILE__,__LINE__)
58
59 static inline void __set_vx_info(struct vx_info **vxp, struct vx_info *vxi,
60         const char *_file, int _line)
61 {
62         BUG_ON(*vxp);
63         if (!vxi)
64                 return;
65         vxdprintk("set_vx_info(%p[#%d.%d.%d])\t%s:%d\n",
66                 vxi, vxi?vxi->vx_id:0,
67                 vxi?atomic_read(&vxi->vx_usecnt):0,
68                 vxi?atomic_read(&vxi->vx_refcnt):0,
69                 _file, _line);
70         atomic_inc(&vxi->vx_refcnt);
71         *vxp = __get_vx_info(vxi, _file, _line);
72 }
73
74 #define clr_vx_info(p)  __clr_vx_info(p,__FILE__,__LINE__)
75
76 static inline void __clr_vx_info(struct vx_info **vxp,
77         const char *_file, int _line)
78 {
79         struct vx_info *vxo = *vxp;
80
81         if (!vxo)
82                 return;
83         vxdprintk("clr_vx_info(%p[#%d.%d.%d])\t%s:%d\n",
84                 vxo, vxo?vxo->vx_id:0,
85                 vxo?atomic_read(&vxo->vx_usecnt):0,
86                 vxo?atomic_read(&vxo->vx_refcnt):0,
87                 _file, _line);
88         *vxp = NULL;
89         wmb();
90         if (vxo && atomic_dec_and_test(&vxo->vx_refcnt))
91                 unhash_vx_info(vxo);
92         __put_vx_info(vxo, _file, _line);
93 }
94
95
96 #define task_get_vx_info(i)     __task_get_vx_info(i,__FILE__,__LINE__)
97
98 static __inline__ struct vx_info *__task_get_vx_info(struct task_struct *p,
99         const char *_file, int _line)
100 {
101         struct vx_info *vxi;
102         
103         task_lock(p);
104         vxi = __get_vx_info(p->vx_info, _file, _line);
105         task_unlock(p);
106         return vxi;
107 }
108
109
110 #define vx_verify_info(p,i)     \
111         __vx_verify_info((p)->vx_info,i,__FILE__,__LINE__)
112
113 static __inline__ void __vx_verify_info(
114         struct vx_info *vxa, struct vx_info *vxb,
115         const char *_file, int _line)
116 {
117         if (vxa == vxb)
118                 return;
119         printk(KERN_ERR "vx bad assumption (%p==%p) at %s:%d\n",
120                 vxa, vxb, _file, _line);
121 }
122
123
124 #define vx_task_xid(t)  ((t)->xid)
125
126 #define vx_current_xid() vx_task_xid(current)
127
128 #define vx_check(c,m)   __vx_check(vx_current_xid(),c,m)
129
130 #define vx_weak_check(c,m)      ((m) ? vx_check(c,m) : 1)
131
132
133 /*
134  * check current context for ADMIN/WATCH and
135  * optionally agains supplied argument
136  */
137 static __inline__ int __vx_check(xid_t cid, xid_t id, unsigned int mode)
138 {
139         if (mode & VX_ARG_MASK) {
140                 if ((mode & VX_IDENT) &&
141                         (id == cid))
142                         return 1;
143         }
144         if (mode & VX_ATR_MASK) {
145                 if ((mode & VX_DYNAMIC) &&
146                         (id >= MIN_D_CONTEXT) &&
147                         (id <= MAX_S_CONTEXT))
148                         return 1;
149                 if ((mode & VX_STATIC) &&
150                         (id > 1) && (id < MIN_D_CONTEXT))
151                         return 1;
152         }
153         return (((mode & VX_ADMIN) && (cid == 0)) ||
154                 ((mode & VX_WATCH) && (cid == 1)));
155 }
156
157
158 #define __vx_flags(v,m,f)       (((v) & (m)) ^ (f))
159
160 #define __vx_task_flags(t,m,f) \
161         (((t) && ((t)->vx_info)) ? \
162                 __vx_flags((t)->vx_info->vx_flags,(m),(f)) : 0)
163
164 #define vx_current_flags() \
165         ((current->vx_info) ? current->vx_info->vx_flags : 0)
166
167 #define vx_flags(m,f)   __vx_flags(vx_current_flags(),(m),(f))
168
169
170 #define vx_current_ccaps() \
171         ((current->vx_info) ? current->vx_info->vx_ccaps : 0)
172
173 #define vx_ccaps(c)     (vx_current_ccaps() & (c))
174
175 #define vx_current_bcaps() \
176         (((current->vx_info) && !vx_flags(VXF_STATE_SETUP, 0)) ? \
177         current->vx_info->vx_bcaps : cap_bset)
178
179
180 #define VX_DEBUG_ACC_RSS   0
181 #define VX_DEBUG_ACC_VM    0
182 #define VX_DEBUG_ACC_VML   0
183
184 #undef  vxdprintk
185 #if     (VX_DEBUG_ACC_RSS) || (VX_DEBUG_ACC_VM) || (VX_DEBUG_ACC_VML)
186 #define vxdprintk(x...) printk("vxd: " x)
187 #else
188 #define vxdprintk(x...)
189 #endif
190
191 #define vx_acc_page(m, d, v, r) \
192         __vx_acc_page(&(m->v), m->mm_vx_info, r, d, __FILE__, __LINE__)
193
194 static inline void __vx_acc_page(unsigned long *v, struct vx_info *vxi,
195                 int res, int dir, char *file, int line)
196 {
197         if (v) {
198                 if (dir > 0)
199                         ++(*v);
200                 else
201                         --(*v);
202         }
203         if (vxi) {
204                 if (dir > 0)
205                         atomic_inc(&vxi->limit.res[res]);
206                 else
207                         atomic_dec(&vxi->limit.res[res]);
208         }
209 }
210
211
212 #define vx_acc_pages(m, p, v, r) \
213         __vx_acc_pages(&(m->v), m->mm_vx_info, r, p, __FILE__, __LINE__)
214
215 static inline void __vx_acc_pages(unsigned long *v, struct vx_info *vxi,
216                 int res, int pages, char *file, int line)
217 {
218         if ((res == RLIMIT_RSS && VX_DEBUG_ACC_RSS) ||
219                 (res == RLIMIT_AS && VX_DEBUG_ACC_VM) ||
220                 (res == RLIMIT_MEMLOCK && VX_DEBUG_ACC_VML))
221                 vxdprintk("vx_acc_pages  [%5d,%2d]: %5d += %5d in %s:%d\n",
222                         (vxi?vxi->vx_id:-1), res,
223                         (vxi?atomic_read(&vxi->limit.res[res]):0),
224                         pages, file, line);
225         if (pages == 0)
226                 return;
227         if (v)
228                 *v += pages;
229         if (vxi)
230                 atomic_add(pages, &vxi->limit.res[res]);
231 }
232
233
234
235 #define vx_acc_vmpage(m,d)     vx_acc_page(m, d, total_vm,  RLIMIT_AS)
236 #define vx_acc_vmlpage(m,d)    vx_acc_page(m, d, locked_vm, RLIMIT_MEMLOCK)
237 #define vx_acc_rsspage(m,d)    vx_acc_page(m, d, rss,       RLIMIT_RSS)
238
239 #define vx_acc_vmpages(m,p)    vx_acc_pages(m, p, total_vm,  RLIMIT_AS)
240 #define vx_acc_vmlpages(m,p)   vx_acc_pages(m, p, locked_vm, RLIMIT_MEMLOCK)
241 #define vx_acc_rsspages(m,p)   vx_acc_pages(m, p, rss,       RLIMIT_RSS)
242
243 #define vx_pages_add(s,r,p)    __vx_acc_pages(0, s, r, p, __FILE__, __LINE__)
244 #define vx_pages_sub(s,r,p)    __vx_pages_add(s, r, -(p))
245
246 #define vx_vmpages_inc(m)      vx_acc_vmpage(m, 1)
247 #define vx_vmpages_dec(m)      vx_acc_vmpage(m,-1)
248 #define vx_vmpages_add(m,p)    vx_acc_vmpages(m, p)
249 #define vx_vmpages_sub(m,p)    vx_acc_vmpages(m,-(p))
250
251 #define vx_vmlocked_inc(m)     vx_acc_vmlpage(m, 1)
252 #define vx_vmlocked_dec(m)     vx_acc_vmlpage(m,-1)
253 #define vx_vmlocked_add(m,p)   vx_acc_vmlpages(m, p)
254 #define vx_vmlocked_sub(m,p)   vx_acc_vmlpages(m,-(p))
255
256 #define vx_rsspages_inc(m)     vx_acc_rsspage(m, 1)
257 #define vx_rsspages_dec(m)     vx_acc_rsspage(m,-1)
258 #define vx_rsspages_add(m,p)   vx_acc_rsspages(m, p)
259 #define vx_rsspages_sub(m,p)   vx_acc_rsspages(m,-(p))
260
261
262
263 #define vx_pages_avail(m, p, r) \
264         __vx_pages_avail((m)->mm_vx_info, (r), (p), __FILE__, __LINE__)
265
266 static inline int __vx_pages_avail(struct vx_info *vxi,
267                 int res, int pages, char *file, int line)
268 {
269         if ((res == RLIMIT_RSS && VX_DEBUG_ACC_RSS) ||
270                 (res == RLIMIT_AS && VX_DEBUG_ACC_VM) ||
271                 (res == RLIMIT_MEMLOCK && VX_DEBUG_ACC_VML))
272                 printk("vx_pages_avail[%5d,%2d]: %5ld > %5d + %5d in %s:%d\n",
273                         (vxi?vxi->vx_id:-1), res,
274                         (vxi?vxi->limit.rlim[res]:1),
275                         (vxi?atomic_read(&vxi->limit.res[res]):0),
276                         pages, file, line);
277         if (!vxi)
278                 return 1;
279         if (vxi->limit.rlim[res] == RLIM_INFINITY)
280                 return 1;
281         if (atomic_read(&vxi->limit.res[res]) + pages < vxi->limit.rlim[res])
282                 return 1;
283         return 0;
284 }
285
286 #define vx_vmpages_avail(m,p)  vx_pages_avail(m, p, RLIMIT_AS)
287 #define vx_vmlocked_avail(m,p) vx_pages_avail(m, p, RLIMIT_MEMLOCK)
288 #define vx_rsspages_avail(m,p) vx_pages_avail(m, p, RLIMIT_RSS)
289
290 /* file limits */
291
292 #define VX_DEBUG_ACC_FILE       0
293 #define VX_DEBUG_ACC_OPENFD     0
294
295 #undef  vxdprintk
296 #if     (VX_DEBUG_ACC_FILE) || (VX_DEBUG_ACC_OPENFD)
297 #define vxdprintk(x...) printk("vxd: " x)
298 #else
299 #define vxdprintk(x...)
300 #endif
301
302
303 #define vx_acc_cres(v,d,r) \
304         __vx_acc_cres((v), (r), (d), __FILE__, __LINE__)
305
306 static inline void __vx_acc_cres(struct vx_info *vxi,
307         int res, int dir, char *file, int line)
308 {
309         if (vxi) {
310         if ((res == RLIMIT_NOFILE && VX_DEBUG_ACC_FILE) ||
311                         (res == RLIMIT_OPENFD && VX_DEBUG_ACC_OPENFD))
312         printk("vx_acc_cres[%5d,%2d]: %5d%s in %s:%d\n",
313                         (vxi?vxi->vx_id:-1), res,
314                         (vxi?atomic_read(&vxi->limit.res[res]):0),
315                         (dir>0)?"++":"--", file, line);
316                 if (dir > 0)
317                         atomic_inc(&vxi->limit.res[res]);
318                 else
319                         atomic_dec(&vxi->limit.res[res]);
320         }
321 }
322
323 #define vx_files_inc(f) vx_acc_cres(current->vx_info, 1, RLIMIT_NOFILE)
324 #define vx_files_dec(f) vx_acc_cres(current->vx_info,-1, RLIMIT_NOFILE)
325
326 #define vx_openfd_inc(f) vx_acc_cres(current->vx_info, 1, RLIMIT_OPENFD)
327 #define vx_openfd_dec(f) vx_acc_cres(current->vx_info,-1, RLIMIT_OPENFD)
328
329 #define vx_cres_avail(v,n,r) \
330         __vx_cres_avail((v), (r), (n), __FILE__, __LINE__)
331
332 static inline int __vx_cres_avail(struct vx_info *vxi,
333                 int res, int num, char *file, int line)
334 {
335         if ((res == RLIMIT_NOFILE && VX_DEBUG_ACC_FILE) ||
336                 (res == RLIMIT_OPENFD && VX_DEBUG_ACC_OPENFD))
337                 printk("vx_cres_avail[%5d,%2d]: %5ld > %5d + %5d in %s:%d\n",
338                         (vxi?vxi->vx_id:-1), res,
339                         (vxi?vxi->limit.rlim[res]:1),
340                         (vxi?atomic_read(&vxi->limit.res[res]):0),
341                         num, file, line);
342         if (!vxi)
343                 return 1;
344         if (vxi->limit.rlim[res] == RLIM_INFINITY)
345                 return 1;
346         if (vxi->limit.rlim[res] < atomic_read(&vxi->limit.res[res]) + num)
347                 return 0;
348         return 1;
349 }
350
351 #define vx_files_avail(n) \
352         vx_cres_avail(current->vx_info, (n), RLIMIT_NOFILE)
353
354 #define vx_openfd_avail(n) \
355         vx_cres_avail(current->vx_info, (n), RLIMIT_OPENFD)
356
357 /* socket limits */
358
359 #define vx_sock_inc(f)  vx_acc_cres(current->vx_info, 1, VLIMIT_SOCK)
360 #define vx_sock_dec(f)  vx_acc_cres(current->vx_info,-1, VLIMIT_SOCK)
361
362 #define vx_sock_avail(n) \
363         vx_cres_avail(current->vx_info, (n), VLIMIT_SOCK)
364
365 /* procfs ioctls */
366
367 #define FIOC_GETXFLG    _IOR('x', 5, long)
368 #define FIOC_SETXFLG    _IOW('x', 6, long)
369
370 /* utsname virtualization */
371
372 static inline struct new_utsname *vx_new_utsname(void)
373 {
374         if (current->vx_info)
375                 return &current->vx_info->cvirt.utsname;
376         return &system_utsname;
377 }
378
379 #define vx_new_uts(x)           ((vx_new_utsname())->x)
380
381 /* generic flag merging */
382
383 #define vx_mask_flags(v,f,m)    (((v) & ~(m)) | ((f) & (m)))
384
385 #define vx_mask_mask(v,f,m)     (((v) & ~(m)) | ((v) & (f) & (m)))
386
387
388 /* socket accounting */
389
390 #include <linux/socket.h>
391
392 static inline int vx_sock_type(int family)
393 {
394         int type = 4;
395
396         if (family > 0 && family < 3)
397                 type = family;
398         else if (family == PF_INET6)
399                 type = 3;
400         return type;
401 }
402
403 #define vx_acc_sock(v,f,p,s) \
404         __vx_acc_sock((v), (f), (p), (s), __FILE__, __LINE__)
405
406 static inline void __vx_acc_sock(struct vx_info *vxi,
407         int family, int pos, int size, char *file, int line)
408 {
409         if (vxi) {
410                 int type = vx_sock_type(family);
411
412                 atomic_inc(&vxi->cacct.sock[type][pos].count);
413                 atomic_add(size, &vxi->cacct.sock[type][pos].total);
414         }
415 }
416
417 #define vx_sock_recv(sk,s) \
418         vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 0, (s))
419 #define vx_sock_send(sk,s) \
420         vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 1, (s))
421 #define vx_sock_fail(sk,s) \
422         vx_acc_sock((sk)->sk_vx_info, (sk)->sk_family, 2, (s))
423
424
425 #define sock_vx_init(s)  do {           \
426         (s)->sk_xid = 0;                \
427         (s)->sk_vx_info = NULL;         \
428         } while (0)
429
430
431 /* pid faking stuff */
432
433
434 #define vx_map_tgid(v,p) \
435         __vx_map_tgid((v), (p), __FILE__, __LINE__)
436
437 static inline int __vx_map_tgid(struct vx_info *vxi, int pid,
438         char *file, int line)
439 {
440         if (vxi && __vx_flags(vxi->vx_flags, VXF_INFO_INIT, 0)) {
441                 vxdprintk("vx_map_tgid: %p/%llx: %d -> %d in %s:%d\n",
442                         vxi, vxi->vx_flags, pid,
443                         (pid == vxi->vx_initpid)?1:pid,
444                         file, line);
445                 if (pid == vxi->vx_initpid)
446                         return 1;
447         }
448         return pid;
449 }
450
451 #define vx_rmap_tgid(v,p) \
452         __vx_rmap_tgid((v), (p), __FILE__, __LINE__)
453
454 static inline int __vx_rmap_tgid(struct vx_info *vxi, int pid,
455         char *file, int line)
456 {
457         if (vxi && __vx_flags(vxi->vx_flags, VXF_INFO_INIT, 0)) {
458                 vxdprintk("vx_rmap_tgid: %p/%llx: %d -> %d in %s:%d\n",
459                         vxi, vxi->vx_flags, pid,
460                         (pid == 1)?vxi->vx_initpid:pid,
461                         file, line);
462                 if ((pid == 1) && vxi->vx_initpid)
463                         return vxi->vx_initpid;
464         }
465         return pid;
466 }
467
468 #undef  vxdprintk
469 #define vxdprintk(x...)
470
471 #endif