summaryrefslogtreecommitdiff
path: root/target/linux/generic/patches-3.10/100-overlayfs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/patches-3.10/100-overlayfs.patch')
-rw-r--r--target/linux/generic/patches-3.10/100-overlayfs.patch109
1 files changed, 75 insertions, 34 deletions
diff --git a/target/linux/generic/patches-3.10/100-overlayfs.patch b/target/linux/generic/patches-3.10/100-overlayfs.patch
index e8896aa..5d1c5f6 100644
--- a/target/linux/generic/patches-3.10/100-overlayfs.patch
+++ b/target/linux/generic/patches-3.10/100-overlayfs.patch
@@ -243,7 +243,7 @@
will be called when part or all of the page is to be removed
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -6009,6 +6009,13 @@ F: drivers/scsi/osd/
+@@ -6019,6 +6019,13 @@ F: drivers/scsi/osd/
F: include/scsi/osd_*
F: fs/exofs/
@@ -287,7 +287,7 @@
+
+ rc = -EINVAL;
+ if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
-+ printk(KERN_ERR "eCryptfs: maximum fs stacking depth exceeded\n");
++ pr_err("eCryptfs: maximum fs stacking depth exceeded\n");
+ goto out_free;
+ }
@@ -307,6 +307,19 @@
* namespace.c
*/
extern int copy_mount_options(const void __user *, unsigned long *);
+@@ -132,12 +127,6 @@ extern struct dentry *__d_alloc(struct s
+ extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
+
+ /*
+- * splice.c
+- */
+-extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
+- loff_t *opos, size_t len, unsigned int flags);
+-
+-/*
+ * pipe.c
+ */
+ extern const struct file_operations pipefifo_fops;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -402,6 +402,7 @@ int __inode_permission(struct inode *ino
@@ -335,10 +348,19 @@
goto out;
--- a/fs/namespace.c
+++ b/fs/namespace.c
-@@ -1442,6 +1442,24 @@ void drop_collected_mounts(struct vfsmou
+@@ -1442,6 +1442,33 @@ void drop_collected_mounts(struct vfsmou
namespace_unlock();
}
++/**
++ * clone_private_mount - create a private clone of a path
++ *
++ * This creates a new vfsmount, which will be the clone of @path. The new will
++ * not be attached anywhere in the namespace and will be private (i.e. changes
++ * to the originating mount won't be propagated into this).
++ *
++ * Release with mntput().
++ */
+struct vfsmount *clone_private_mount(struct path *path)
+{
+ struct mount *old_mnt = real_mount(path->mnt);
@@ -350,8 +372,8 @@
+ down_read(&namespace_sem);
+ new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE);
+ up_read(&namespace_sem);
-+ if (!new_mnt)
-+ return ERR_PTR(-ENOMEM);
++ if (IS_ERR(new_mnt))
++ return ERR_CAST(new_mnt);
+
+ return &new_mnt->mnt;
+}
@@ -401,11 +423,17 @@
int lookup_flags = 0;
--- /dev/null
+++ b/fs/overlayfs/Kconfig
-@@ -0,0 +1,4 @@
+@@ -0,0 +1,10 @@
+config OVERLAYFS_FS
+ tristate "Overlay filesystem support"
+ help
-+ Add support for overlay filesystem.
++ An overlay filesystem combines two filesystems - an 'upper' filesystem
++ and a 'lower' filesystem. When a name exists in both filesystems, the
++ object in the 'upper' filesystem is visible while the object in the
++ 'lower' filesystem is either hidden or, in the case of directories,
++ merged with the 'upper' object.
++
++ For more information see Documentation/filesystems/overlayfs.txt
--- /dev/null
+++ b/fs/overlayfs/Makefile
@@ -0,0 +1,7 @@
@@ -418,7 +446,7 @@
+overlayfs-objs := super.o inode.o dir.o readdir.o copy_up.o
--- /dev/null
+++ b/fs/overlayfs/copy_up.c
-@@ -0,0 +1,385 @@
+@@ -0,0 +1,387 @@
+/*
+ *
+ * Copyright (C) 2011 Novell Inc.
@@ -494,6 +522,8 @@
+{
+ struct file *old_file;
+ struct file *new_file;
++ loff_t old_pos = 0;
++ loff_t new_pos = 0;
+ int error = 0;
+
+ if (len == 0)
@@ -511,7 +541,6 @@
+
+ /* FIXME: copy up sparse files efficiently */
+ while (len) {
-+ loff_t offset = new_file->f_pos;
+ size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
+ long bytes;
+
@@ -523,8 +552,9 @@
+ break;
+ }
+
-+ bytes = do_splice_direct(old_file, &offset, new_file, this_len,
-+ SPLICE_F_MOVE);
++ bytes = do_splice_direct(old_file, &old_pos,
++ new_file, &new_pos,
++ this_len, SPLICE_F_MOVE);
+ if (bytes <= 0) {
+ error = bytes;
+ break;
@@ -806,7 +836,7 @@
+}
--- /dev/null
+++ b/fs/overlayfs/dir.c
-@@ -0,0 +1,604 @@
+@@ -0,0 +1,605 @@
+/*
+ *
+ * Copyright (C) 2011 Novell Inc.
@@ -881,7 +911,7 @@
+ * There's no way to recover from failure to whiteout.
+ * What should we do? Log a big fat error and... ?
+ */
-+ printk(KERN_ERR "overlayfs: ERROR - failed to whiteout '%s'\n",
++ pr_err("overlayfs: ERROR - failed to whiteout '%s'\n",
+ dentry->d_name.name);
+ }
+
@@ -1254,8 +1284,10 @@
+ }
+ newinode = ovl_new_inode(old->d_sb, newdentry->d_inode->i_mode,
+ new->d_fsdata);
-+ if (!newinode)
++ if (!newinode) {
++ err = -ENOMEM;
+ goto link_fail;
++ }
+ ovl_copyattr(upperdir->d_inode, newinode);
+
+ ovl_dentry_version_inc(new->d_parent);
@@ -1272,7 +1304,6 @@
+ mutex_unlock(&upperdir->d_inode->i_mutex);
+out:
+ return err;
-+
+}
+
+static int ovl_rename(struct inode *olddir, struct dentry *old,
@@ -2218,7 +2249,7 @@
+ loff_t res;
+ struct ovl_dir_file *od = file->private_data;
+
-+ mutex_lock(&file->f_dentry->d_inode->i_mutex);
++ mutex_lock(&file_inode(file)->i_mutex);
+ if (!file->f_pos)
+ ovl_dir_reset(file);
+
@@ -2248,7 +2279,7 @@
+ res = offset;
+ }
+out_unlock:
-+ mutex_unlock(&file->f_dentry->d_inode->i_mutex);
++ mutex_unlock(&file_inode(file)->i_mutex);
+
+ return res;
+}
@@ -2394,7 +2425,7 @@
+
+ dentry = lookup_one_len(p->name, upperdir, p->len);
+ if (IS_ERR(dentry)) {
-+ printk(KERN_WARNING
++ pr_warn(
+ "overlayfs: failed to lookup whiteout %.*s: %li\n",
+ p->len, p->name, PTR_ERR(dentry));
+ continue;
@@ -2402,7 +2433,7 @@
+ ret = vfs_unlink(upperdir->d_inode, dentry);
+ dput(dentry);
+ if (ret)
-+ printk(KERN_WARNING
++ pr_warn(
+ "overlayfs: failed to unlink whiteout %.*s: %i\n",
+ p->len, p->name, ret);
+ }
@@ -2818,7 +2849,6 @@
+
+struct file *ovl_path_open(struct path *path, int flags)
+{
-+ path_get(path);
+ return dentry_open(path, flags, current_cred());
+}
+
@@ -2906,15 +2936,15 @@
+};
+
+enum {
-+ Opt_lowerdir,
-+ Opt_upperdir,
-+ Opt_err,
++ OPT_LOWERDIR,
++ OPT_UPPERDIR,
++ OPT_ERR,
+};
+
+static const match_table_t ovl_tokens = {
-+ {Opt_lowerdir, "lowerdir=%s"},
-+ {Opt_upperdir, "upperdir=%s"},
-+ {Opt_err, NULL}
++ {OPT_LOWERDIR, "lowerdir=%s"},
++ {OPT_UPPERDIR, "upperdir=%s"},
++ {OPT_ERR, NULL}
+};
+
+static int ovl_parse_opt(char *opt, struct ovl_config *config)
@@ -2933,14 +2963,14 @@
+
+ token = match_token(p, ovl_tokens, args);
+ switch (token) {
-+ case Opt_upperdir:
++ case OPT_UPPERDIR:
+ kfree(config->upperdir);
+ config->upperdir = match_strdup(&args[0]);
+ if (!config->upperdir)
+ return -ENOMEM;
+ break;
+
-+ case Opt_lowerdir:
++ case OPT_LOWERDIR:
+ kfree(config->lowerdir);
+ config->lowerdir = match_strdup(&args[0]);
+ if (!config->lowerdir)
@@ -2976,7 +3006,7 @@
+
+ err = -EINVAL;
+ if (!ufs->config.upperdir || !ufs->config.lowerdir) {
-+ printk(KERN_ERR "overlayfs: missing upperdir or lowerdir\n");
++ pr_err("overlayfs: missing upperdir or lowerdir\n");
+ goto out_free_config;
+ }
+
@@ -2999,7 +3029,7 @@
+
+ err = vfs_statfs(&lowerpath, &statfs);
+ if (err) {
-+ printk(KERN_ERR "overlayfs: statfs failed on lowerpath\n");
++ pr_err("overlayfs: statfs failed on lowerpath\n");
+ goto out_put_lowerpath;
+ }
+ ufs->lower_namelen = statfs.f_namelen;
@@ -3009,7 +3039,7 @@
+
+ err = -EINVAL;
+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
-+ printk(KERN_ERR "overlayfs: maximum fs stacking depth exceeded\n");
++ pr_err("overlayfs: maximum fs stacking depth exceeded\n");
+ goto out_put_lowerpath;
+ }
+
@@ -3017,14 +3047,14 @@
+ ufs->upper_mnt = clone_private_mount(&upperpath);
+ err = PTR_ERR(ufs->upper_mnt);
+ if (IS_ERR(ufs->upper_mnt)) {
-+ printk(KERN_ERR "overlayfs: failed to clone upperpath\n");
++ pr_err("overlayfs: failed to clone upperpath\n");
+ goto out_put_lowerpath;
+ }
+
+ ufs->lower_mnt = clone_private_mount(&lowerpath);
+ err = PTR_ERR(ufs->lower_mnt);
+ if (IS_ERR(ufs->lower_mnt)) {
-+ printk(KERN_ERR "overlayfs: failed to clone lowerpath\n");
++ pr_err("overlayfs: failed to clone lowerpath\n");
+ goto out_put_upper_mnt;
+ }
+
@@ -3103,6 +3133,7 @@
+ .mount = ovl_mount,
+ .kill_sb = kill_anon_super,
+};
++MODULE_ALIAS_FS("overlayfs");
+
+static int __init ovl_init(void)
+{
@@ -3118,7 +3149,7 @@
+module_exit(ovl_exit);
--- a/fs/splice.c
+++ b/fs/splice.c
-@@ -1311,6 +1311,7 @@ long do_splice_direct(struct file *in, l
+@@ -1313,6 +1313,7 @@ long do_splice_direct(struct file *in, l
return ret;
}
@@ -3177,6 +3208,16 @@
extern int generic_permission(struct inode *, int);
static inline bool execute_ok(struct inode *inode)
+@@ -2414,6 +2428,9 @@ extern ssize_t generic_file_splice_write
+ struct file *, loff_t *, size_t, unsigned int);
+ extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe,
+ struct file *out, loff_t *, size_t len, unsigned int flags);
++extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
++ loff_t *opos, size_t len, unsigned int flags);
++
+
+ extern void
+ file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -68,6 +68,9 @@ extern void mnt_pin(struct vfsmount *mnt