VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / include / linux / vs_dlimit.h
index d80c563..53400ab 100644 (file)
@@ -1,21 +1,13 @@
 #ifndef _VX_VS_DLIMIT_H
 #define _VX_VS_DLIMIT_H
 
-
-// #define VX_DEBUG
-
 #include <linux/kernel.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
 
 #include "vserver/context.h"
 #include "vserver/dlimit.h"
-
-#if defined(VX_DEBUG)
-#define vxdprintk(x...) printk("vxd: " x)
-#else
-#define vxdprintk(x...)
-#endif
+#include "vserver/debug.h"
 
 
 #define get_dl_info(i) __get_dl_info(i,__FILE__,__LINE__)
@@ -25,7 +17,7 @@ static inline struct dl_info *__get_dl_info(struct dl_info *dli,
 {
        if (!dli)
                return NULL;
-       vxdprintk("get_dl_info(%p[#%d.%d])\t%s:%d\n",
+       vxlprintk(VXD_CBIT(dlim, 4), "get_dl_info(%p[#%d.%d])",
                dli, dli?dli->dl_xid:0, dli?atomic_read(&dli->dl_usecnt):0,
                _file, _line);
        atomic_inc(&dli->dl_usecnt);
@@ -34,15 +26,16 @@ static inline struct dl_info *__get_dl_info(struct dl_info *dli,
 
 
 #define        free_dl_info(i) \
-       call_rcu(&i->dl_rcu, rcu_free_dl_info, i);
+       call_rcu(&i->dl_rcu, rcu_free_dl_info);
 
 #define put_dl_info(i) __put_dl_info(i,__FILE__,__LINE__)
 
-static inline void __put_dl_info(struct dl_info *dli, const char *_file, int _line)
+static inline void __put_dl_info(struct dl_info *dli,
+       const char *_file, int _line)
 {
        if (!dli)
                return;
-       vxdprintk("put_dl_info(%p[#%d.%d])\t%s:%d\n",
+       vxlprintk(VXD_CBIT(dlim, 4), "put_dl_info(%p[#%d.%d])",
                dli, dli?dli->dl_xid:0, dli?atomic_read(&dli->dl_usecnt):0,
                _file, _line);
        if (atomic_dec_and_test(&dli->dl_usecnt))
@@ -50,8 +43,6 @@ static inline void __put_dl_info(struct dl_info *dli, const char *_file, int _li
 }
 
 
-extern int vx_debug_dlimit;
-
 #define        __dlimit_char(d)        ((d)?'*':' ')
 
 static inline int __dl_alloc_space(struct super_block *sb,
@@ -73,14 +64,14 @@ static inline int __dl_alloc_space(struct super_block *sb,
        spin_unlock(&dli->dl_lock);
        put_dl_info(dli);
 out:
-       if (vx_debug_dlimit)
-               printk("ALLOC (%p,#%d)%c %lld bytes (%d)@ %s:%d\n",
-                       sb, xid, __dlimit_char(dli), nr, ret, file, line);
+       vxlprintk(VXD_CBIT(dlim, 1),
+               "ALLOC (%p,#%d)%c %lld bytes (%d)",
+               sb, xid, __dlimit_char(dli), nr, ret, file, line);
        return ret;
 }
 
 static inline void __dl_free_space(struct super_block *sb,
-       xid_t xid, dlsize_t nr, const char *file, int line)
+       xid_t xid, dlsize_t nr, const char *_file, int _line)
 {
        struct dl_info *dli = NULL;
 
@@ -91,17 +82,20 @@ static inline void __dl_free_space(struct super_block *sb,
                goto out;
 
        spin_lock(&dli->dl_lock);
-       dli->dl_space_used -= nr;
+       if (dli->dl_space_used > nr)
+               dli->dl_space_used -= nr;
+       else
+               dli->dl_space_used = 0;
        spin_unlock(&dli->dl_lock);
        put_dl_info(dli);
 out:
-       if (vx_debug_dlimit)
-               printk("FREE  (%p,#%d)%c %lld bytes @ %s:%d\n",
-                       sb, xid, __dlimit_char(dli), nr, file, line);
+       vxlprintk(VXD_CBIT(dlim, 1),
+               "FREE  (%p,#%d)%c %lld bytes",
+               sb, xid, __dlimit_char(dli), nr, _file, _line);
 }
 
 static inline int __dl_alloc_inode(struct super_block *sb,
-       xid_t xid, const char *file, int line)
+       xid_t xid, const char *_file, int _line)
 {
        struct dl_info *dli;
        int ret = 0;
@@ -114,17 +108,24 @@ static inline int __dl_alloc_inode(struct super_block *sb,
        ret = (dli->dl_inodes_used >= dli->dl_inodes_total);
        if (!ret)
                dli->dl_inodes_used++;
+#if 0
+       else
+               printk("VSW: DLIMIT hit (%p,#%d), inode %d>=%d @ %s:%d\n",
+                       sb, xid,
+                       dli->dl_inodes_used, dli->dl_inodes_total,
+                       file, line);
+#endif
        spin_unlock(&dli->dl_lock);
        put_dl_info(dli);
 out:
-       if (vx_debug_dlimit)
-               printk("ALLOC (%p,#%d)%c inode (%d)@ %s:%d\n",
-                       sb, xid, __dlimit_char(dli), ret, file, line);
+       vxlprintk(VXD_CBIT(dlim, 0),
+               "ALLOC (%p,#%d)%c inode (%d)",
+               sb, xid, __dlimit_char(dli), ret, _file, _line);
        return ret;
 }
 
 static inline void __dl_free_inode(struct super_block *sb,
-       xid_t xid, const char *file, int line)
+       xid_t xid, const char *_file, int _line)
 {
        struct dl_info *dli;
 
@@ -133,15 +134,51 @@ static inline void __dl_free_inode(struct super_block *sb,
                goto out;
 
        spin_lock(&dli->dl_lock);
-       dli->dl_inodes_used--;
+       if (dli->dl_inodes_used > 1)
+               dli->dl_inodes_used--;
+       else
+               dli->dl_inodes_used = 0;
        spin_unlock(&dli->dl_lock);
        put_dl_info(dli);
 out:
-       if (vx_debug_dlimit)
-               printk("FREE  (%p,#%d)%c inode @ %s:%d\n",
-                       sb, xid, __dlimit_char(dli), file, line);
+       vxlprintk(VXD_CBIT(dlim, 0),
+               "FREE  (%p,#%d)%c inode",
+               sb, xid, __dlimit_char(dli), _file, _line);
 }
 
+static inline void __dl_adjust_block(struct super_block *sb, xid_t xid,
+       unsigned int *free_blocks, unsigned int *root_blocks,
+       const char *_file, int _line)
+{
+       struct dl_info *dli;
+       uint64_t broot, bfree;
+
+       dli = locate_dl_info(sb, xid);
+       if (!dli)
+               return;
+
+       spin_lock(&dli->dl_lock);
+       broot = (dli->dl_space_total -
+               (dli->dl_space_total >> 10) * dli->dl_nrlmult)
+               >> sb->s_blocksize_bits;
+       bfree = (dli->dl_space_total - dli->dl_space_used)
+                       >> sb->s_blocksize_bits;
+       spin_unlock(&dli->dl_lock);
+
+       vxlprintk(VXD_CBIT(dlim, 2),
+               "ADJUST: %lld,%lld on %d,%d [mult=%d]",
+               bfree, broot, *free_blocks, *root_blocks,
+               dli->dl_nrlmult, _file, _line);
+       if (free_blocks) {
+               if (*free_blocks > bfree)
+                       *free_blocks = bfree;
+       }
+       if (root_blocks) {
+               if (*root_blocks > broot)
+                       *root_blocks = broot;
+       }
+       put_dl_info(dli);
+}
 
 
 #define DLIMIT_ALLOC_BLOCK(sb, xid, nr) \
@@ -161,7 +198,8 @@ out:
        __dl_free_inode(sb, xid, __FILE__, __LINE__ )
 
 
-#define        DLIMIT_ADJUST_BLOCK(sb, xid, fb, rb)
+#define        DLIMIT_ADJUST_BLOCK(sb, xid, fb, rb) \
+       __dl_adjust_block(sb, xid, fb, rb, __FILE__, __LINE__ )
 
 
 #else