115 lines
3.4 KiB
Diff
115 lines
3.4 KiB
Diff
|
From 57c8073caecaaaeb087d1bad0de1baa497189181 Mon Sep 17 00:00:00 2001
|
||
|
From: Andy Whitcroft <apw@canonical.com>
|
||
|
Date: Thu, 27 Jun 2013 16:39:50 +0200
|
||
|
Subject: [PATCH 6/9] overlayfs: add statfs support
|
||
|
|
||
|
Add support for statfs to the overlayfs filesystem. As the upper layer
|
||
|
is the target of all write operations assume that the space in that
|
||
|
filesystem is the space in the overlayfs. There will be some inaccuracy as
|
||
|
overwriting a file will copy it up and consume space we were not expecting,
|
||
|
but it is better than nothing.
|
||
|
|
||
|
Use the upper layer dentry and mount from the overlayfs root inode,
|
||
|
passing the statfs call to that filesystem.
|
||
|
|
||
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
||
|
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
|
||
|
---
|
||
|
fs/overlayfs/super.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 40 insertions(+)
|
||
|
|
||
|
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
|
||
|
index d209dd9..a9970b5 100644
|
||
|
--- a/fs/overlayfs/super.c
|
||
|
+++ b/fs/overlayfs/super.c
|
||
|
@@ -17,15 +17,19 @@
|
||
|
#include <linux/module.h>
|
||
|
#include <linux/cred.h>
|
||
|
#include <linux/sched.h>
|
||
|
+#include <linux/statfs.h>
|
||
|
#include "overlayfs.h"
|
||
|
|
||
|
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
|
||
|
MODULE_DESCRIPTION("Overlay filesystem");
|
||
|
MODULE_LICENSE("GPL");
|
||
|
|
||
|
+#define OVERLAYFS_SUPER_MAGIC 0x794c764f
|
||
|
+
|
||
|
struct ovl_fs {
|
||
|
struct vfsmount *upper_mnt;
|
||
|
struct vfsmount *lower_mnt;
|
||
|
+ long lower_namelen;
|
||
|
};
|
||
|
|
||
|
struct ovl_entry {
|
||
|
@@ -406,9 +410,36 @@ static int ovl_remount_fs(struct super_block *sb, int *flagsp, char *data)
|
||
|
return mnt_want_write(ufs->upper_mnt);
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * ovl_statfs
|
||
|
+ * @sb: The overlayfs super block
|
||
|
+ * @buf: The struct kstatfs to fill in with stats
|
||
|
+ *
|
||
|
+ * Get the filesystem statistics. As writes always target the upper layer
|
||
|
+ * filesystem pass the statfs to the same filesystem.
|
||
|
+ */
|
||
|
+static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
|
||
|
+{
|
||
|
+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
|
||
|
+ struct dentry *root_dentry = dentry->d_sb->s_root;
|
||
|
+ struct path path;
|
||
|
+ int err;
|
||
|
+
|
||
|
+ ovl_path_upper(root_dentry, &path);
|
||
|
+
|
||
|
+ err = vfs_statfs(&path, buf);
|
||
|
+ if (!err) {
|
||
|
+ buf->f_namelen = max(buf->f_namelen, ofs->lower_namelen);
|
||
|
+ buf->f_type = OVERLAYFS_SUPER_MAGIC;
|
||
|
+ }
|
||
|
+
|
||
|
+ return err;
|
||
|
+}
|
||
|
+
|
||
|
static const struct super_operations ovl_super_operations = {
|
||
|
.put_super = ovl_put_super,
|
||
|
.remount_fs = ovl_remount_fs,
|
||
|
+ .statfs = ovl_statfs,
|
||
|
};
|
||
|
|
||
|
struct ovl_config {
|
||
|
@@ -474,6 +505,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
|
||
|
struct ovl_entry *oe;
|
||
|
struct ovl_fs *ufs;
|
||
|
struct ovl_config config;
|
||
|
+ struct kstatfs statfs;
|
||
|
int err;
|
||
|
|
||
|
err = ovl_parse_opt((char *) data, &config);
|
||
|
@@ -508,6 +540,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
|
||
|
!S_ISDIR(lowerpath.dentry->d_inode->i_mode))
|
||
|
goto out_put_lowerpath;
|
||
|
|
||
|
+ err = vfs_statfs(&lowerpath, &statfs);
|
||
|
+ if (err) {
|
||
|
+ pr_err("overlayfs: statfs failed on lowerpath\n");
|
||
|
+ goto out_put_lowerpath;
|
||
|
+ }
|
||
|
+ ufs->lower_namelen = statfs.f_namelen;
|
||
|
+
|
||
|
ufs->upper_mnt = clone_private_mount(&upperpath);
|
||
|
err = PTR_ERR(ufs->upper_mnt);
|
||
|
if (IS_ERR(ufs->upper_mnt)) {
|
||
|
@@ -556,6 +595,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
|
||
|
root_dentry->d_fsdata = oe;
|
||
|
root_dentry->d_op = &ovl_dentry_operations;
|
||
|
|
||
|
+ sb->s_magic = OVERLAYFS_SUPER_MAGIC;
|
||
|
sb->s_op = &ovl_super_operations;
|
||
|
sb->s_root = root_dentry;
|
||
|
sb->s_fs_info = ufs;
|
||
|
--
|
||
|
1.8.3.2
|
||
|
|