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