.show   = show_vfsmnt
 };
 
+static int show_vfsstat(struct seq_file *m, void *v)
+{
+       struct vfsmount *mnt = v;
+       int err = 0;
+
+       /* device */
+       if (mnt->mnt_devname) {
+               seq_puts(m, "device ");
+               mangle(m, mnt->mnt_devname);
+       } else
+               seq_puts(m, "no device");
+
+       /* mount point */
+       seq_puts(m, " mounted on ");
+       seq_path(m, mnt, mnt->mnt_root, " \t\n\\");
+       seq_putc(m, ' ');
+
+       /* file system type */
+       seq_puts(m, "with fstype ");
+       mangle(m, mnt->mnt_sb->s_type->name);
+
+       /* optional statistics */
+       if (mnt->mnt_sb->s_op->show_stats) {
+               seq_putc(m, ' ');
+               err = mnt->mnt_sb->s_op->show_stats(m, mnt);
+       }
+
+       seq_putc(m, '\n');
+       return err;
+}
+
+struct seq_operations mountstats_op = {
+       .start  = m_start,
+       .next   = m_next,
+       .stop   = m_stop,
+       .show   = show_vfsstat,
+};
+
 /**
  * may_umount_tree - check if a mount tree is busy
  * @mnt: root of mount tree
 
        PROC_TGID_MAPS,
        PROC_TGID_NUMA_MAPS,
        PROC_TGID_MOUNTS,
+       PROC_TGID_MOUNTSTATS,
        PROC_TGID_WCHAN,
 #ifdef CONFIG_MMU
        PROC_TGID_SMAPS,
        PROC_TID_MAPS,
        PROC_TID_NUMA_MAPS,
        PROC_TID_MOUNTS,
+       PROC_TID_MOUNTSTATS,
        PROC_TID_WCHAN,
 #ifdef CONFIG_MMU
        PROC_TID_SMAPS,
        E(PROC_TGID_ROOT,      "root",    S_IFLNK|S_IRWXUGO),
        E(PROC_TGID_EXE,       "exe",     S_IFLNK|S_IRWXUGO),
        E(PROC_TGID_MOUNTS,    "mounts",  S_IFREG|S_IRUGO),
+       E(PROC_TGID_MOUNTSTATS, "mountstats", S_IFREG|S_IRUSR),
 #ifdef CONFIG_MMU
        E(PROC_TGID_SMAPS,     "smaps",   S_IFREG|S_IRUGO),
 #endif
        .poll           = mounts_poll,
 };
 
+extern struct seq_operations mountstats_op;
+static int mountstats_open(struct inode *inode, struct file *file)
+{
+       struct task_struct *task = proc_task(inode);
+       int ret = seq_open(file, &mountstats_op);
+
+       if (!ret) {
+               struct seq_file *m = file->private_data;
+               struct namespace *namespace;
+               task_lock(task);
+               namespace = task->namespace;
+               if (namespace)
+                       get_namespace(namespace);
+               task_unlock(task);
+
+               if (namespace)
+                       m->private = namespace;
+               else {
+                       seq_release(inode, file);
+                       ret = -EINVAL;
+               }
+       }
+       return ret;
+}
+
+static struct file_operations proc_mountstats_operations = {
+       .open           = mountstats_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = mounts_release,
+};
+
 #define PROC_BLOCK_SIZE        (3*1024)                /* 4K page size but our output routines use some slack for overruns */
 
 static ssize_t proc_info_read(struct file * file, char __user * buf,
                        inode->i_fop = &proc_smaps_operations;
                        break;
 #endif
+               case PROC_TID_MOUNTSTATS:
+               case PROC_TGID_MOUNTSTATS:
+                       inode->i_fop = &proc_mountstats_operations;
+                       break;
 #ifdef CONFIG_SECURITY
                case PROC_TID_ATTR:
                        inode->i_nlink = 2;
 
        void (*umount_begin) (struct super_block *);
 
        int (*show_options)(struct seq_file *, struct vfsmount *);
+       int (*show_stats)(struct seq_file *, struct vfsmount *);
 
        ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
        ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);