]>
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 | ||
c06a8ce3 AM |
22 | --- a/fs/overlayfs/super.c |
23 | +++ b/fs/overlayfs/super.c | |
68184a5a JR |
24 | @@ -17,15 +17,19 @@ |
25 | #include <linux/module.h> | |
26 | #include <linux/cred.h> | |
27 | #include <linux/sched.h> | |
28 | +#include <linux/statfs.h> | |
29 | #include "overlayfs.h" | |
30 | ||
31 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |
32 | MODULE_DESCRIPTION("Overlay filesystem"); | |
33 | MODULE_LICENSE("GPL"); | |
34 | ||
35 | +#define OVERLAYFS_SUPER_MAGIC 0x794c764f | |
36 | + | |
37 | struct ovl_fs { | |
38 | struct vfsmount *upper_mnt; | |
39 | struct vfsmount *lower_mnt; | |
40 | + long lower_namelen; | |
41 | }; | |
42 | ||
43 | struct ovl_entry { | |
c06a8ce3 | 44 | @@ -407,9 +411,36 @@ static int ovl_remount_fs(struct super_b |
68184a5a JR |
45 | return mnt_want_write(ufs->upper_mnt); |
46 | } | |
47 | ||
48 | +/** | |
49 | + * ovl_statfs | |
50 | + * @sb: The overlayfs super block | |
51 | + * @buf: The struct kstatfs to fill in with stats | |
52 | + * | |
53 | + * Get the filesystem statistics. As writes always target the upper layer | |
54 | + * filesystem pass the statfs to the same filesystem. | |
55 | + */ | |
56 | +static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf) | |
57 | +{ | |
58 | + struct ovl_fs *ofs = dentry->d_sb->s_fs_info; | |
59 | + struct dentry *root_dentry = dentry->d_sb->s_root; | |
60 | + struct path path; | |
61 | + int err; | |
62 | + | |
63 | + ovl_path_upper(root_dentry, &path); | |
64 | + | |
65 | + err = vfs_statfs(&path, buf); | |
66 | + if (!err) { | |
67 | + buf->f_namelen = max(buf->f_namelen, ofs->lower_namelen); | |
68 | + buf->f_type = OVERLAYFS_SUPER_MAGIC; | |
69 | + } | |
70 | + | |
71 | + return err; | |
72 | +} | |
73 | + | |
74 | static const struct super_operations ovl_super_operations = { | |
75 | .put_super = ovl_put_super, | |
76 | .remount_fs = ovl_remount_fs, | |
77 | + .statfs = ovl_statfs, | |
78 | }; | |
79 | ||
80 | struct ovl_config { | |
c06a8ce3 | 81 | @@ -475,6 +506,7 @@ static int ovl_fill_super(struct super_b |
68184a5a JR |
82 | struct ovl_entry *oe; |
83 | struct ovl_fs *ufs; | |
84 | struct ovl_config config; | |
85 | + struct kstatfs statfs; | |
86 | int err; | |
87 | ||
88 | err = ovl_parse_opt((char *) data, &config); | |
c06a8ce3 | 89 | @@ -509,6 +541,13 @@ static int ovl_fill_super(struct super_b |
68184a5a JR |
90 | !S_ISDIR(lowerpath.dentry->d_inode->i_mode)) |
91 | goto out_put_lowerpath; | |
92 | ||
93 | + err = vfs_statfs(&lowerpath, &statfs); | |
94 | + if (err) { | |
c06a8ce3 | 95 | + pr_err("overlayfs: statfs failed on lowerpath\n"); |
68184a5a JR |
96 | + goto out_put_lowerpath; |
97 | + } | |
98 | + ufs->lower_namelen = statfs.f_namelen; | |
99 | + | |
100 | ufs->upper_mnt = clone_private_mount(&upperpath); | |
101 | err = PTR_ERR(ufs->upper_mnt); | |
102 | if (IS_ERR(ufs->upper_mnt)) { | |
c06a8ce3 | 103 | @@ -557,6 +596,7 @@ static int ovl_fill_super(struct super_b |
68184a5a JR |
104 | root_dentry->d_fsdata = oe; |
105 | root_dentry->d_op = &ovl_dentry_operations; | |
106 | ||
107 | + sb->s_magic = OVERLAYFS_SUPER_MAGIC; | |
108 | sb->s_op = &ovl_super_operations; | |
109 | sb->s_root = root_dentry; | |
110 | sb->s_fs_info = ufs; |