]> git.pld-linux.org Git - packages/kernel.git/blobdiff - ovl05-overlay-filesystem.patch
- 3.16.2
[packages/kernel.git] / ovl05-overlay-filesystem.patch
index f37efbcf0b45948bd02238d907521ddb2f403502..395aae71095bd91140b99db7c1bff4921c042451 100644 (file)
@@ -87,27 +87,27 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
  fs/Makefile              |    1 
  fs/overlayfs/Kconfig     |   10 
  fs/overlayfs/Makefile    |    7 
- fs/overlayfs/copy_up.c   |  385 +++++++++++++++++++++++++++++
+ fs/overlayfs/copy_up.c   |  388 +++++++++++++++++++++++++++++
  fs/overlayfs/dir.c       |  605 ++++++++++++++++++++++++++++++++++++++++++++++
  fs/overlayfs/inode.c     |  372 ++++++++++++++++++++++++++++
  fs/overlayfs/overlayfs.h |   70 +++++
- fs/overlayfs/readdir.c   |  566 +++++++++++++++++++++++++++++++++++++++++++
+ fs/overlayfs/readdir.c   |  567 +++++++++++++++++++++++++++++++++++++++++++
  fs/overlayfs/super.c     |  612 +++++++++++++++++++++++++++++++++++++++++++++++
- 10 files changed, 2629 insertions(+)
+ 10 files changed, 2633 insertions(+)
 
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -70,6 +70,7 @@ source "fs/quota/Kconfig"
+@@ -67,6 +67,7 @@ source "fs/quota/Kconfig"
  
  source "fs/autofs4/Kconfig"
  source "fs/fuse/Kconfig"
 +source "fs/overlayfs/Kconfig"
  
- config GENERIC_ACL
-       bool
+ menu "Caches"
 --- a/fs/Makefile
 +++ b/fs/Makefile
-@@ -108,6 +108,7 @@ obj-$(CONFIG_QNX6FS_FS)            += qnx6/
+@@ -105,6 +105,7 @@ obj-$(CONFIG_QNX6FS_FS)            += qnx6/
  obj-$(CONFIG_AUTOFS4_FS)      += autofs4/
  obj-$(CONFIG_ADFS_FS)         += adfs/
  obj-$(CONFIG_FUSE_FS)         += fuse/
@@ -140,7 +140,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +overlayfs-objs := super.o inode.o dir.o readdir.o copy_up.o
 --- /dev/null
 +++ b/fs/overlayfs/copy_up.c
-@@ -0,0 +1,387 @@
+@@ -0,0 +1,388 @@
 +/*
 + *
 + * Copyright (C) 2011 Novell Inc.
@@ -253,6 +253,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +                      error = bytes;
 +                      break;
 +              }
++              WARN_ON(old_pos != new_pos);
 +
 +              len -= bytes;
 +      }
@@ -306,7 +307,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +              .ia_mtime = stat->mtime,
 +      };
 +
-+      return notify_change(upperdentry, &attr);
++      return notify_change(upperdentry, &attr, NULL);
 +}
 +
 +static int ovl_set_mode(struct dentry *upperdentry, umode_t mode)
@@ -316,7 +317,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +              .ia_mode = mode,
 +      };
 +
-+      return notify_change(upperdentry, &attr);
++      return notify_change(upperdentry, &attr, NULL);
 +}
 +
 +static int ovl_copy_up_locked(struct dentry *upperdir, struct dentry *dentry,
@@ -371,7 +372,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      if (S_ISDIR(stat->mode))
 +              vfs_rmdir(upperdir->d_inode, newpath.dentry);
 +      else
-+              vfs_unlink(upperdir->d_inode, newpath.dentry);
++              vfs_unlink(upperdir->d_inode, newpath.dentry, NULL);
 +
 +      dput(newpath.dentry);
 +
@@ -530,7 +531,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +}
 --- /dev/null
 +++ b/fs/overlayfs/dir.c
-@@ -0,0 +1,605 @@
+@@ -0,0 +1,606 @@
 +/*
 + *
 + * Copyright (C) 2011 Novell Inc.
@@ -592,7 +593,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +
 +      err = vfs_setxattr(newdentry, ovl_whiteout_xattr, "y", 1, 0);
 +      if (err)
-+              vfs_unlink(upperdir->d_inode, newdentry);
++              vfs_unlink(upperdir->d_inode, newdentry, NULL);
 +
 +out_dput:
 +      dput(newdentry);
@@ -650,7 +651,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +
 +              err = -EEXIST;
 +              if (ovl_is_whiteout(newdentry))
-+                      err = vfs_unlink(upperdir->d_inode, newdentry);
++                      err = vfs_unlink(upperdir->d_inode, newdentry, NULL);
 +
 +              revert_creds(old_cred);
 +              put_cred(override_cred);
@@ -900,7 +901,8 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +              if (is_dir)
 +                      err = vfs_rmdir(upperdir->d_inode, realpath.dentry);
 +              else
-+                      err = vfs_unlink(upperdir->d_inode, realpath.dentry);
++                      err = vfs_unlink(upperdir->d_inode, realpath.dentry,
++                                       NULL);
 +              if (err)
 +                      goto out_d_drop;
 +
@@ -969,7 +971,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +              goto out_unlock;
 +
 +      olddentry = ovl_dentry_upper(old);
-+      err = vfs_link(olddentry, upperdir->d_inode, newdentry);
++      err = vfs_link(olddentry, upperdir->d_inode, newdentry, NULL);
 +      if (!err) {
 +              if (WARN_ON(!newdentry->d_inode)) {
 +                      dput(newdentry);
@@ -1090,7 +1092,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      }
 +
 +      err = vfs_rename(old_upperdir->d_inode, olddentry,
-+                       new_upperdir->d_inode, newdentry);
++                       new_upperdir->d_inode, newdentry, NULL, 0);
 +
 +      if (err) {
 +              if (new_create && ovl_dentry_is_opaque(new))
@@ -1171,7 +1173,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +              attr->ia_valid &= ~ATTR_MODE;
 +
 +      mutex_lock(&upperdentry->d_inode->i_mutex);
-+      err = notify_change(upperdentry, attr);
++      err = notify_change(upperdentry, attr, NULL);
 +      if (!err)
 +              ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
 +      mutex_unlock(&upperdentry->d_inode->i_mutex);
@@ -1586,7 +1588,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +int ovl_copy_up_truncate(struct dentry *dentry, loff_t size);
 --- /dev/null
 +++ b/fs/overlayfs/readdir.c
-@@ -0,0 +1,566 @@
+@@ -0,0 +1,567 @@
 +/*
 + *
 + * Copyright (C) 2011 Novell Inc.
@@ -1617,6 +1619,8 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +};
 +
 +struct ovl_readdir_data {
++      struct dir_context ctx;
++      bool is_merge;
 +      struct rb_root *root;
 +      struct list_head *list;
 +      struct list_head *middle;
@@ -1714,13 +1718,12 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      return 0;
 +}
 +
-+static int ovl_fill_lower(void *buf, const char *name, int namelen,
-+                          loff_t offset, u64 ino, unsigned int d_type)
++static int ovl_fill_lower(struct ovl_readdir_data *rdd,
++                        const char *name, int namelen,
++                        loff_t offset, u64 ino, unsigned int d_type)
 +{
-+      struct ovl_readdir_data *rdd = buf;
 +      struct ovl_cache_entry *p;
 +
-+      rdd->count++;
 +      p = ovl_cache_entry_find(rdd->root, name, namelen);
 +      if (p) {
 +              list_move_tail(&p->l_node, rdd->middle);
@@ -1746,17 +1749,20 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      INIT_LIST_HEAD(list);
 +}
 +
-+static int ovl_fill_upper(void *buf, const char *name, int namelen,
++static int ovl_fill_merge(void *buf, const char *name, int namelen,
 +                        loff_t offset, u64 ino, unsigned int d_type)
 +{
 +      struct ovl_readdir_data *rdd = buf;
 +
 +      rdd->count++;
-+      return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type);
++      if (!rdd->is_merge)
++              return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type);
++      else
++              return ovl_fill_lower(rdd, name, namelen, offset, ino, d_type);
 +}
 +
 +static inline int ovl_dir_read(struct path *realpath,
-+                             struct ovl_readdir_data *rdd, filldir_t filler)
++                             struct ovl_readdir_data *rdd)
 +{
 +      struct file *realfile;
 +      int err;
@@ -1765,10 +1771,11 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      if (IS_ERR(realfile))
 +              return PTR_ERR(realfile);
 +
++      rdd->ctx.pos = 0;
 +      do {
 +              rdd->count = 0;
 +              rdd->err = 0;
-+              err = vfs_readdir(realfile, filler, rdd);
++              err = iterate_dir(realfile, &rdd->ctx);
 +              if (err >= 0)
 +                      err = rdd->err;
 +      } while (!err && rdd->count);
@@ -1838,20 +1845,25 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +
 +static inline int ovl_dir_read_merged(struct path *upperpath,
 +                                    struct path *lowerpath,
-+                                    struct ovl_readdir_data *rdd)
++                                    struct list_head *list)
 +{
 +      int err;
 +      struct rb_root root = RB_ROOT;
 +      struct list_head middle;
++      struct ovl_readdir_data rdd = {
++              .ctx.actor = ovl_fill_merge,
++              .list = list,
++              .root = &root,
++              .is_merge = false,
++      };
 +
-+      rdd->root = &root;
 +      if (upperpath->dentry) {
-+              rdd->dir = upperpath->dentry;
-+              err = ovl_dir_read(upperpath, rdd, ovl_fill_upper);
++              rdd.dir = upperpath->dentry;
++              err = ovl_dir_read(upperpath, &rdd);
 +              if (err)
 +                      goto out;
 +
-+              err = ovl_dir_mark_whiteouts(rdd);
++              err = ovl_dir_mark_whiteouts(&rdd);
 +              if (err)
 +                      goto out;
 +      }
@@ -1859,13 +1871,12 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +       * Insert lowerpath entries before upperpath ones, this allows
 +       * offsets to be reasonably constant
 +       */
-+      list_add(&middle, rdd->list);
-+      rdd->middle = &middle;
-+      err = ovl_dir_read(lowerpath, rdd, ovl_fill_lower);
++      list_add(&middle, rdd.list);
++      rdd.middle = &middle;
++      rdd.is_merge = true;
++      err = ovl_dir_read(lowerpath, &rdd);
 +      list_del(&middle);
 +out:
-+      rdd->root = NULL;
-+
 +      return err;
 +}
 +
@@ -1883,17 +1894,16 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      list_move_tail(&od->cursor, l);
 +}
 +
-+static int ovl_readdir(struct file *file, void *buf, filldir_t filler)
++static int ovl_iterate(struct file *file, struct dir_context *ctx)
 +{
 +      struct ovl_dir_file *od = file->private_data;
 +      int res;
 +
-+      if (!file->f_pos)
++      if (!ctx->pos)
 +              ovl_dir_reset(file);
 +
 +      if (od->is_real) {
-+              res = vfs_readdir(od->realfile, filler, buf);
-+              file->f_pos = od->realfile->f_pos;
++              res = iterate_dir(od->realfile, ctx);
 +
 +              return res;
 +      }
@@ -1901,37 +1911,31 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      if (!od->is_cached) {
 +              struct path lowerpath;
 +              struct path upperpath;
-+              struct ovl_readdir_data rdd = { .list = &od->cache };
 +
 +              ovl_path_lower(file->f_path.dentry, &lowerpath);
 +              ovl_path_upper(file->f_path.dentry, &upperpath);
 +
-+              res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd);
++              res = ovl_dir_read_merged(&upperpath, &lowerpath, &od->cache);
 +              if (res) {
-+                      ovl_cache_free(rdd.list);
++                      ovl_cache_free(&od->cache);
 +                      return res;
 +              }
 +
 +              od->cache_version = ovl_dentry_version_get(file->f_path.dentry);
 +              od->is_cached = true;
 +
-+              ovl_seek_cursor(od, file->f_pos);
++              ovl_seek_cursor(od, ctx->pos);
 +      }
 +
 +      while (od->cursor.next != &od->cache) {
-+              int over;
-+              loff_t off;
 +              struct ovl_cache_entry *p;
 +
 +              p = list_entry(od->cursor.next, struct ovl_cache_entry, l_node);
-+              off = file->f_pos;
 +              if (!p->is_whiteout) {
-+                      over = filler(buf, p->name, p->len, off, p->ino,
-+                                    p->type);
-+                      if (over)
++                      if (!dir_emit(ctx, p->name, p->len, p->ino, p->type))
 +                              break;
 +              }
-+              file->f_pos++;
++              ctx->pos++;
 +              list_move(&od->cursor, &p->l_node);
 +      }
 +
@@ -2039,7 +2043,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +const struct file_operations ovl_dir_operations = {
 +      .read           = generic_read_dir,
 +      .open           = ovl_dir_open,
-+      .readdir        = ovl_readdir,
++      .iterate        = ovl_iterate,
 +      .llseek         = ovl_dir_llseek,
 +      .fsync          = ovl_dir_fsync,
 +      .release        = ovl_dir_release,
@@ -2051,12 +2055,11 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +      struct path lowerpath;
 +      struct path upperpath;
 +      struct ovl_cache_entry *p;
-+      struct ovl_readdir_data rdd = { .list = list };
 +
 +      ovl_path_upper(dentry, &upperpath);
 +      ovl_path_lower(dentry, &lowerpath);
 +
-+      err = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd);
++      err = ovl_dir_read_merged(&upperpath, &lowerpath, list);
 +      if (err)
 +              return err;
 +
@@ -2124,7 +2127,7 @@ Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
 +                          p->len, p->name, PTR_ERR(dentry));
 +                      continue;
 +              }
-+              ret = vfs_unlink(upperdir->d_inode, dentry);
++              ret = vfs_unlink(upperdir->d_inode, dentry, NULL);
 +              dput(dentry);
 +              if (ret)
 +                      pr_warn(
This page took 0.050412 seconds and 4 git commands to generate.