]>
Commit | Line | Data |
---|---|---|
68184a5a JR |
1 | From 8f487debf8187dc88c7b0a6db8cd73f4ad27ffa5 Mon Sep 17 00:00:00 2001 |
2 | From: Andy Whitcroft <apw@canonical.com> | |
3 | Date: Fri, 1 Oct 2010 18:48:02 +0100 | |
4 | Subject: [PATCH 05/13] overlayfs: add statfs support | |
5 | Patch-mainline: not yet | |
6 | ||
7 | Add support for statfs to the overlayfs filesystem. As the upper layer | |
8 | is the target of all write operations assume that the space in that | |
9 | filesystem is the space in the overlayfs. There will be some inaccuracy as | |
10 | overwriting a file will copy it up and consume space we were not expecting, | |
11 | but it is better than nothing. | |
12 | ||
13 | Use the upper layer dentry and mount from the overlayfs root inode, | |
14 | passing the statfs call to that filesystem. | |
15 | ||
16 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
17 | Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> | |
18 | --- | |
19 | fs/overlayfs/super.c | 40 ++++++++++++++++++++++++++++++++++++++++ | |
20 | 1 file changed, 40 insertions(+) | |
21 | ||
22 | Index: linux-3.6-rc7-master/fs/overlayfs/super.c | |
23 | =================================================================== | |
24 | --- linux-3.6-rc7-master.orig/fs/overlayfs/super.c 2012-09-28 13:36:53.000000000 +0200 | |
25 | +++ linux-3.6-rc7-master/fs/overlayfs/super.c 2012-09-28 13:36:55.000000000 +0200 | |
26 | @@ -17,15 +17,19 @@ | |
27 | #include <linux/module.h> | |
28 | #include <linux/cred.h> | |
29 | #include <linux/sched.h> | |
30 | +#include <linux/statfs.h> | |
31 | #include "overlayfs.h" | |
32 | ||
33 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |
34 | MODULE_DESCRIPTION("Overlay filesystem"); | |
35 | MODULE_LICENSE("GPL"); | |
36 | ||
37 | +#define OVERLAYFS_SUPER_MAGIC 0x794c764f | |
38 | + | |
39 | struct ovl_fs { | |
40 | struct vfsmount *upper_mnt; | |
41 | struct vfsmount *lower_mnt; | |
42 | + long lower_namelen; | |
43 | }; | |
44 | ||
45 | struct ovl_entry { | |
46 | @@ -406,9 +410,36 @@ static int ovl_remount_fs(struct super_b | |
47 | return mnt_want_write(ufs->upper_mnt); | |
48 | } | |
49 | ||
50 | +/** | |
51 | + * ovl_statfs | |
52 | + * @sb: The overlayfs super block | |
53 | + * @buf: The struct kstatfs to fill in with stats | |
54 | + * | |
55 | + * Get the filesystem statistics. As writes always target the upper layer | |
56 | + * filesystem pass the statfs to the same filesystem. | |
57 | + */ | |
58 | +static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) | |
59 | +{ | |
60 | + struct ovl_fs *ofs = dentry->d_sb->s_fs_info; | |
61 | + struct dentry *root_dentry = dentry->d_sb->s_root; | |
62 | + struct path path; | |
63 | + int err; | |
64 | + | |
65 | + ovl_path_upper(root_dentry, &path); | |
66 | + | |
67 | + err = vfs_statfs(&path, buf); | |
68 | + if (!err) { | |
69 | + buf->f_namelen = max(buf->f_namelen, ofs->lower_namelen); | |
70 | + buf->f_type = OVERLAYFS_SUPER_MAGIC; | |
71 | + } | |
72 | + | |
73 | + return err; | |
74 | +} | |
75 | + | |
76 | static const struct super_operations ovl_super_operations = { | |
77 | .put_super = ovl_put_super, | |
78 | .remount_fs = ovl_remount_fs, | |
79 | + .statfs = ovl_statfs, | |
80 | }; | |
81 | ||
82 | struct ovl_config { | |
83 | @@ -474,6 +505,7 @@ static int ovl_fill_super(struct super_b | |
84 | struct ovl_entry *oe; | |
85 | struct ovl_fs *ufs; | |
86 | struct ovl_config config; | |
87 | + struct kstatfs statfs; | |
88 | int err; | |
89 | ||
90 | err = ovl_parse_opt((char *) data, &config); | |
91 | @@ -508,6 +540,13 @@ static int ovl_fill_super(struct super_b | |
92 | !S_ISDIR(lowerpath.dentry->d_inode->i_mode)) | |
93 | goto out_put_lowerpath; | |
94 | ||
95 | + err = vfs_statfs(&lowerpath, &statfs); | |
96 | + if (err) { | |
97 | + printk(KERN_ERR "overlayfs: statfs failed on lowerpath\n"); | |
98 | + goto out_put_lowerpath; | |
99 | + } | |
100 | + ufs->lower_namelen = statfs.f_namelen; | |
101 | + | |
102 | ufs->upper_mnt = clone_private_mount(&upperpath); | |
103 | err = PTR_ERR(ufs->upper_mnt); | |
104 | if (IS_ERR(ufs->upper_mnt)) { | |
105 | @@ -556,6 +595,7 @@ static int ovl_fill_super(struct super_b | |
106 | root_dentry->d_fsdata = oe; | |
107 | root_dentry->d_op = &ovl_dentry_operations; | |
108 | ||
109 | + sb->s_magic = OVERLAYFS_SUPER_MAGIC; | |
110 | sb->s_op = &ovl_super_operations; | |
111 | sb->s_root = root_dentry; | |
112 | sb->s_fs_info = ufs; |