diff -NurpP linux-2.6.32.6-vs2.3.0.36.28.3/fs/proc/meminfo.c linux-2.6.32.6-vs2.3.0.36.28.4/fs/proc/meminfo.c
--- linux-2.6.32.6-vs2.3.0.36.28.3/fs/proc/meminfo.c	2009-12-03 20:04:56.000000000 +0100
+++ linux-2.6.32.6-vs2.3.0.36.28.4/fs/proc/meminfo.c	2010-02-05 00:31:48.000000000 +0100
@@ -39,9 +39,10 @@ static int meminfo_proc_show(struct seq_
 	allowed = ((totalram_pages - hugetlb_total_pages())
 		* sysctl_overcommit_ratio / 100) + total_swap_pages;
 
-	cached = global_page_state(NR_FILE_PAGES) -
+	cached = vx_flags(VXF_VIRT_MEM, 0) ?
+		vx_vsi_cached(&i) : global_page_state(NR_FILE_PAGES) -
 			total_swapcache_pages - i.bufferram;
-	if (cached < 0 || vx_flags(VXF_VIRT_MEM, 0))
+	if (cached < 0)
 		cached = 0;
 
 	get_vmalloc_info(&vmi);
diff -NurpP linux-2.6.32.6-vs2.3.0.36.28.3/include/linux/memcontrol.h linux-2.6.32.6-vs2.3.0.36.28.4/include/linux/memcontrol.h
--- linux-2.6.32.6-vs2.3.0.36.28.3/include/linux/memcontrol.h	2010-01-27 23:18:26.000000000 +0100
+++ linux-2.6.32.6-vs2.3.0.36.28.4/include/linux/memcontrol.h	2010-02-05 00:15:49.000000000 +0100
@@ -69,9 +69,14 @@ extern void mem_cgroup_out_of_memory(str
 int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem);
 
 extern struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
+
 extern u64 mem_cgroup_res_read_u64(struct mem_cgroup *mem, int member);
 extern u64 mem_cgroup_memsw_read_u64(struct mem_cgroup *mem, int member);
 
+extern s64 mem_cgroup_stat_read_cache(struct mem_cgroup *mem);
+extern s64 mem_cgroup_stat_read_anon(struct mem_cgroup *mem);
+extern s64 mem_cgroup_stat_read_mapped(struct mem_cgroup *mem);
+
 static inline
 int mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *cgroup)
 {
diff -NurpP linux-2.6.32.6-vs2.3.0.36.28.3/include/linux/vserver/limit.h linux-2.6.32.6-vs2.3.0.36.28.4/include/linux/vserver/limit.h
--- linux-2.6.32.6-vs2.3.0.36.28.3/include/linux/vserver/limit.h	2009-12-03 20:04:56.000000000 +0100
+++ linux-2.6.32.6-vs2.3.0.36.28.4/include/linux/vserver/limit.h	2010-02-05 00:34:02.000000000 +0100
@@ -63,6 +63,7 @@ struct sysinfo;
 
 void vx_vsi_meminfo(struct sysinfo *);
 void vx_vsi_swapinfo(struct sysinfo *);
+long vx_vsi_cached(struct sysinfo *);
 
 #define NUM_LIMITS	24
 
diff -NurpP linux-2.6.32.6-vs2.3.0.36.28.3/kernel/vserver/limit.c linux-2.6.32.6-vs2.3.0.36.28.4/kernel/vserver/limit.c
--- linux-2.6.32.6-vs2.3.0.36.28.3/kernel/vserver/limit.c	2010-01-27 23:36:26.000000000 +0100
+++ linux-2.6.32.6-vs2.3.0.36.28.4/kernel/vserver/limit.c	2010-02-05 00:49:22.000000000 +0100
@@ -330,6 +330,7 @@ void vx_vsi_swapinfo(struct sysinfo *val
 #else
 	struct mem_cgroup *mcg = mem_cgroup_from_task(current);
 	u64 res_limit, res_usage, memsw_limit, memsw_usage;
+	s64 swap_limit, swap_usage;
 
 	if (!mcg)
 		return;
@@ -341,14 +342,25 @@ void vx_vsi_swapinfo(struct sysinfo *val
 
 	if (res_limit == RESOURCE_MAX)
 		return;
+
+	swap_limit = memsw_limit - res_limit;
 	if (memsw_limit != RESOURCE_MAX)
-		val->totalswap = (memsw_limit - res_limit) >> PAGE_SHIFT;
-	val->freeswap = val->totalswap -
-		((memsw_usage - res_usage) >> PAGE_SHIFT);
+		val->totalswap = swap_limit >> PAGE_SHIFT;
+	
+	swap_usage = memsw_usage - res_usage;
+	val->freeswap = (swap_usage < swap_limit) ?
+		val->totalswap - (swap_usage >> PAGE_SHIFT) : 0;
 #endif
 	return;
 }
 
+long vx_vsi_cached(struct sysinfo *val)
+{
+	struct mem_cgroup *mcg = mem_cgroup_from_task(current);
+
+	return mem_cgroup_stat_read_cache(mcg) >> PAGE_SHIFT;
+}
+
 
 unsigned long vx_badness(struct task_struct *task, struct mm_struct *mm)
 {
diff -NurpP linux-2.6.32.6-vs2.3.0.36.28.3/mm/memcontrol.c linux-2.6.32.6-vs2.3.0.36.28.4/mm/memcontrol.c
--- linux-2.6.32.6-vs2.3.0.36.28.3/mm/memcontrol.c	2010-01-27 23:18:26.000000000 +0100
+++ linux-2.6.32.6-vs2.3.0.36.28.4/mm/memcontrol.c	2010-02-05 00:45:18.000000000 +0100
@@ -559,6 +559,21 @@ u64 mem_cgroup_memsw_read_u64(struct mem
 	return res_counter_read_u64(&mem->memsw, member);
 }
 
+s64 mem_cgroup_stat_read_cache(struct mem_cgroup *mem)
+{
+	return mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_CACHE);
+}
+
+s64 mem_cgroup_stat_read_anon(struct mem_cgroup *mem)
+{
+	return mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_RSS);
+}
+
+s64 mem_cgroup_stat_read_mapped(struct mem_cgroup *mem)
+{
+	return mem_cgroup_read_stat(&mem->stat, MEM_CGROUP_STAT_MAPPED_FILE);
+}
+
 static struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm)
 {
 	struct mem_cgroup *mem = NULL;
