]> git.pld-linux.org Git - packages/kernel.git/blobdiff - kernel-unionfs.patch
- rel 3
[packages/kernel.git] / kernel-unionfs.patch
index a2a66b1c157eaedee14a4018a7fd99db1797add3..3cdb4769d8d9219333705749432f073d66478a4f 100644 (file)
@@ -532,10 +532,10 @@ index 0000000..1adde69
 +
 +For more information, see <http://unionfs.filesystems.org/>.
 diff --git a/MAINTAINERS b/MAINTAINERS
-index f0358cd..7ae0669 100644
+index 9a648eb..81b24a8 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -6375,6 +6375,14 @@ F:      Documentation/cdrom/
+@@ -6765,6 +6765,14 @@ F:      Documentation/cdrom/
  F:    drivers/cdrom/cdrom.c
  F:    include/linux/cdrom.h
  
@@ -551,10 +551,10 @@ index f0358cd..7ae0669 100644
  M:    Artem Bityutskiy <dedekind1@gmail.com>
  W:    http://www.linux-mtd.infradead.org/
 diff --git a/fs/Kconfig b/fs/Kconfig
-index 19891aa..ac8a074 100644
+index d621f02..c12677d 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -187,6 +187,7 @@ if MISC_FILESYSTEMS
+@@ -194,6 +194,7 @@ if MISC_FILESYSTEMS
  source "fs/adfs/Kconfig"
  source "fs/affs/Kconfig"
  source "fs/ecryptfs/Kconfig"
@@ -563,7 +563,7 @@ index 19891aa..ac8a074 100644
  source "fs/hfsplus/Kconfig"
  source "fs/befs/Kconfig"
 diff --git a/fs/Makefile b/fs/Makefile
-index fb68c2b..8ca9290 100644
+index 93804d4..3ff10bb 100644
 --- a/fs/Makefile
 +++ b/fs/Makefile
 @@ -83,6 +83,7 @@ obj-$(CONFIG_ISO9660_FS)     += isofs/
@@ -575,10 +575,10 @@ index fb68c2b..8ca9290 100644
  obj-$(CONFIG_NFS_FS)          += nfs/
  obj-$(CONFIG_EXPORTFS)                += exportfs/
 diff --git a/fs/namei.c b/fs/namei.c
-index 0223c41..5d0261e 100644
+index 208c6aa..050eded 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
-@@ -484,6 +484,7 @@ void release_open_intent(struct nameidata *nd)
+@@ -491,6 +491,7 @@ void release_open_intent(struct nameidata *nd)
                        fput(file);
        }
  }
@@ -586,7 +586,7 @@ index 0223c41..5d0261e 100644
  
  static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd)
  {
-@@ -1740,6 +1741,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
+@@ -1804,6 +1805,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
        return __lookup_hash(&this, base, NULL);
  }
  
@@ -626,10 +626,10 @@ index 0223c41..5d0261e 100644
 +      return __lookup_hash(&this, base, nd);
 +}
 +
- int user_path_at(int dfd, const char __user *name, unsigned flags,
-                struct path *path)
+ int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
+                struct path *path, int *empty)
  {
-@@ -3339,6 +3376,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
+@@ -3384,6 +3421,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
  EXPORT_SYMBOL(getname);
  EXPORT_SYMBOL(lock_rename);
  EXPORT_SYMBOL(lookup_one_len);
@@ -638,10 +638,10 @@ index 0223c41..5d0261e 100644
  EXPORT_SYMBOL(page_put_link);
  EXPORT_SYMBOL(page_readlink);
 diff --git a/fs/splice.c b/fs/splice.c
-index aa866d3..421ab86 100644
+index 1ec0493..3215728 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1085,8 +1085,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1084,8 +1084,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -652,7 +652,7 @@ index aa866d3..421ab86 100644
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
-@@ -1109,13 +1109,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1108,13 +1108,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
        return splice_write(pipe, out, ppos, len, flags);
  }
@@ -670,7 +670,7 @@ index aa866d3..421ab86 100644
  {
        ssize_t (*splice_read)(struct file *, loff_t *,
                               struct pipe_inode_info *, size_t, unsigned int);
-@@ -1135,6 +1136,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1134,6 +1135,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
  
        return splice_read(in, ppos, pipe, len, flags);
  }
@@ -678,7 +678,7 @@ index aa866d3..421ab86 100644
  
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
-@@ -1204,7 +1206,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+@@ -1203,7 +1205,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
                size_t read_len;
                loff_t pos = sd->pos, prev_pos = pos;
  
@@ -687,7 +687,7 @@ index aa866d3..421ab86 100644
                if (unlikely(ret <= 0))
                        goto out_release;
  
-@@ -1263,8 +1265,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
+@@ -1262,8 +1264,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
  {
        struct file *file = sd->u.file;
  
@@ -698,7 +698,7 @@ index aa866d3..421ab86 100644
  }
  
  /**
-@@ -1349,7 +1351,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1348,7 +1350,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &out->f_pos;
  
@@ -707,7 +707,7 @@ index aa866d3..421ab86 100644
  
                if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
                        ret = -EFAULT;
-@@ -1369,7 +1371,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1368,7 +1370,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &in->f_pos;
  
@@ -716,32 +716,6 @@ index aa866d3..421ab86 100644
  
                if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
                        ret = -EFAULT;
-diff --git a/fs/stack.c b/fs/stack.c
-index 4a6f7f4..7eeef12 100644
---- a/fs/stack.c
-+++ b/fs/stack.c
-@@ -1,8 +1,20 @@
-+/*
-+ * Copyright (c) 2006-2009 Erez Zadok
-+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
-+ * Copyright (c) 2006-2009 Stony Brook University
-+ * Copyright (c) 2006-2009 The Research Foundation of SUNY
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/fs_stack.h>
--/* does _NOT_ require i_mutex to be held.
-+/*
-+ * does _NOT_ require i_mutex to be held.
-  *
-  * This function cannot be inlined since i_size_{read,write} is rather
-  * heavy-weight on 32-bit systems
 diff --git a/fs/unionfs/Kconfig b/fs/unionfs/Kconfig
 new file mode 100644
 index 0000000..f3c1ac4
@@ -774,11 +748,11 @@ index 0000000..f3c1ac4
 +        If you say Y here, you can turn on debugging output from Unionfs.
 diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
 new file mode 100644
-index 0000000..0ece303
+index 0000000..60b6060
 --- /dev/null
 +++ b/fs/unionfs/Makefile
 @@ -0,0 +1,17 @@
-+UNIONFS_VERSION="2.5.9.2 (for 3.0.0-rc4)"
++UNIONFS_VERSION="2.5.11 (for 3.3.0-rc3)"
 +
 +EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\"
 +
@@ -797,10 +771,10 @@ index 0000000..0ece303
 +endif
 diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
 new file mode 100644
-index 0000000..0a271f4
+index 0000000..71cacfe
 --- /dev/null
 +++ b/fs/unionfs/commonfops.c
-@@ -0,0 +1,896 @@
+@@ -0,0 +1,901 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -1115,7 +1089,7 @@ index 0000000..0a271f4
 +       * someone has copied up this file from underneath us, we also need
 +       * to refresh things.
 +       */
-+      if ((d_deleted(dentry) && dbstart(dentry) >= fbstart(file)) ||
++      if (d_deleted(dentry) ||
 +          (sbgen <= fgen &&
 +           dbstart(dentry) == fbstart(file) &&
 +           unionfs_lower_file(file)))
@@ -1241,31 +1215,36 @@ index 0000000..0a271f4
 +}
 +
 +/* unionfs_open helper function: open a directory */
-+static int __open_dir(struct inode *inode, struct file *file)
++static int __open_dir(struct inode *inode, struct file *file,
++                    struct dentry *parent)
 +{
 +      struct dentry *lower_dentry;
 +      struct file *lower_file;
 +      int bindex, bstart, bend;
-+      struct vfsmount *mnt;
++      struct vfsmount *lower_mnt;
++      struct dentry *dentry = file->f_path.dentry;
 +
-+      bstart = fbstart(file) = dbstart(file->f_path.dentry);
-+      bend = fbend(file) = dbend(file->f_path.dentry);
++      bstart = fbstart(file) = dbstart(dentry);
++      bend = fbend(file) = dbend(dentry);
 +
 +      for (bindex = bstart; bindex <= bend; bindex++) {
 +              lower_dentry =
-+                      unionfs_lower_dentry_idx(file->f_path.dentry, bindex);
++                      unionfs_lower_dentry_idx(dentry, bindex);
 +              if (!lower_dentry)
 +                      continue;
 +
 +              dget(lower_dentry);
-+              unionfs_mntget(file->f_path.dentry, bindex);
-+              mnt = unionfs_lower_mnt_idx(file->f_path.dentry, bindex);
-+              lower_file = dentry_open(lower_dentry, mnt, file->f_flags,
++              lower_mnt = unionfs_mntget(dentry, bindex);
++              if (!lower_mnt)
++                      lower_mnt = unionfs_mntget(parent, bindex);
++              lower_file = dentry_open(lower_dentry, lower_mnt, file->f_flags,
 +                                       current_cred());
 +              if (IS_ERR(lower_file))
 +                      return PTR_ERR(lower_file);
 +
 +              unionfs_set_lower_file_idx(file, bindex, lower_file);
++              if (!unionfs_lower_mnt_idx(dentry, bindex))
++                      unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
 +
 +              /*
 +               * The branchget goes after the open, because otherwise
@@ -1285,18 +1264,20 @@ index 0000000..0a271f4
 +      struct file *lower_file;
 +      int lower_flags;
 +      int bindex, bstart, bend;
++      struct dentry *dentry = file->f_path.dentry;
++      struct vfsmount *lower_mnt;
 +
-+      lower_dentry = unionfs_lower_dentry(file->f_path.dentry);
++      lower_dentry = unionfs_lower_dentry(dentry);
 +      lower_flags = file->f_flags;
 +
-+      bstart = fbstart(file) = dbstart(file->f_path.dentry);
-+      bend = fbend(file) = dbend(file->f_path.dentry);
++      bstart = fbstart(file) = dbstart(dentry);
++      bend = fbend(file) = dbend(dentry);
 +
 +      /*
 +       * check for the permission for lower file.  If the error is
 +       * COPYUP_ERR, copyup the file.
 +       */
-+      if (lower_dentry->d_inode && is_robranch(file->f_path.dentry)) {
++      if (lower_dentry->d_inode && is_robranch(dentry)) {
 +              /*
 +               * if the open will change the file, copy it up otherwise
 +               * defer it.
@@ -1331,11 +1312,9 @@ index 0000000..0a271f4
 +       * dentry_open will decrement mnt refcnt if err.
 +       * otherwise fput() will do an mntput() for us upon file close.
 +       */
-+      unionfs_mntget(file->f_path.dentry, bstart);
-+      lower_file =
-+              dentry_open(lower_dentry,
-+                          unionfs_lower_mnt_idx(file->f_path.dentry, bstart),
-+                          lower_flags, current_cred());
++      lower_mnt = unionfs_mntget(dentry, bstart);
++      lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags,
++                               current_cred());
 +      if (IS_ERR(lower_file))
 +              return PTR_ERR(lower_file);
 +
@@ -1404,7 +1383,7 @@ index 0000000..0a271f4
 +       * these lower file structs
 +       */
 +      if (S_ISDIR(inode->i_mode))
-+              err = __open_dir(inode, file);  /* open a dir */
++              err = __open_dir(inode, file, parent); /* open a dir */
 +      else
 +              err = __open_file(inode, file, parent); /* open a file */
 +
@@ -1699,10 +1678,10 @@ index 0000000..0a271f4
 +}
 diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
 new file mode 100644
-index 0000000..37c2654
+index 0000000..078ca27
 --- /dev/null
 +++ b/fs/unionfs/copyup.c
-@@ -0,0 +1,896 @@
+@@ -0,0 +1,899 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -2030,8 +2009,11 @@ index 0000000..37c2654
 +
 +      kfree(buf);
 +
++#if 0
++      /* XXX: code no longer needed? */
 +      if (!err)
 +              err = output_file->f_op->fsync(output_file, 0);
++#endif
 +
 +      if (err)
 +              goto out_close_out;
@@ -2601,10 +2583,10 @@ index 0000000..37c2654
 +}
 diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
 new file mode 100644
-index 0000000..6092e69
+index 0000000..21ce90c
 --- /dev/null
 +++ b/fs/unionfs/debug.c
-@@ -0,0 +1,548 @@
+@@ -0,0 +1,551 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
@@ -2617,6 +2599,7 @@ index 0000000..6092e69
 + */
 +
 +#include "union.h"
++#include "../mount.h"
 +
 +/*
 + * Helper debugging functions for maintainers (and for users to report back
@@ -2969,12 +2952,13 @@ index 0000000..6092e69
 +              pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n",
 +                       file, dentry, fstart, fend);
 +      }
-+      if (unlikely(fstart != dstart)) {
++      /* d_deleted dentries can be ignored for this test */
++      if (unlikely(fstart != dstart) && !d_deleted(dentry)) {
 +              PRINT_CALLER(fname, fxn, line);
 +              pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n",
 +                       file, dentry, fstart, dstart);
 +      }
-+      if (unlikely(fend != dend)) {
++      if (unlikely(fend != dend) && !d_deleted(dentry)) {
 +              PRINT_CALLER(fname, fxn, line);
 +              pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n",
 +                       file, dentry, fend, dend);
@@ -3051,17 +3035,18 @@ index 0000000..6092e69
 +
 +static unsigned int __mnt_get_count(struct vfsmount *mnt)
 +{
++      struct mount *m = real_mount(mnt);
 +#ifdef CONFIG_SMP
 +      unsigned int count = 0;
 +      int cpu;
 +
 +      for_each_possible_cpu(cpu) {
-+              count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count;
++              count += per_cpu_ptr(m->mnt_pcp, cpu)->mnt_count;
 +      }
 +
 +      return count;
 +#else
-+      return mnt->mnt_count;
++      return m->mnt_count;
 +#endif
 +}
 +
@@ -3155,10 +3140,10 @@ index 0000000..6092e69
 +}
 diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
 new file mode 100644
-index 0000000..c0205a4
+index 0000000..1628dad
 --- /dev/null
 +++ b/fs/unionfs/dentry.c
-@@ -0,0 +1,406 @@
+@@ -0,0 +1,409 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -3476,12 +3461,15 @@ index 0000000..c0205a4
 +}
 +
 +static int unionfs_d_revalidate(struct dentry *dentry,
-+                              struct nameidata *nd_unused)
++                              struct nameidata *nd)
 +{
 +      bool valid = true;
 +      int err = 1;            /* 1 means valid for the VFS */
 +      struct dentry *parent;
 +
++      if (nd && nd->flags & LOOKUP_RCU)
++              return -ECHILD;
++
 +      unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
 +      parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
 +      unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
@@ -4452,10 +4440,10 @@ index 0000000..ae1b86a
 +#endif        /* not _FANOUT_H */
 diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
 new file mode 100644
-index 0000000..416c52f
+index 0000000..f583c8f
 --- /dev/null
 +++ b/fs/unionfs/file.c
-@@ -0,0 +1,382 @@
+@@ -0,0 +1,386 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -4646,7 +4634,7 @@ index 0000000..416c52f
 +      return err;
 +}
 +
-+int unionfs_fsync(struct file *file, int datasync)
++int unionfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 +{
 +      int bindex, bstart, bend;
 +      struct file *lower_file;
@@ -4656,6 +4644,7 @@ index 0000000..416c52f
 +      struct inode *lower_inode, *inode;
 +      int err = -EINVAL;
 +
++      lockdep_off();
 +      unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
 +      parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
 +      unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
@@ -4665,6 +4654,10 @@ index 0000000..416c52f
 +              goto out;
 +      unionfs_check_file(file);
 +
++      err = generic_file_fsync(file, start, end, datasync);
++      if (err)
++              goto out;
++
 +      bstart = fbstart(file);
 +      bend = fbend(file);
 +      if (bstart < 0 || bend < 0)
@@ -4682,11 +4675,9 @@ index 0000000..416c52f
 +                      continue;
 +              lower_file = unionfs_lower_file_idx(file, bindex);
 +              lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
-+              mutex_lock(&lower_inode->i_mutex);
-+              err = lower_inode->i_fop->fsync(lower_file, datasync);
++              err = vfs_fsync_range(lower_file, start, end, datasync);
 +              if (!err && bindex == bstart)
 +                      fsstack_copy_attr_times(inode, lower_inode);
-+              mutex_unlock(&lower_inode->i_mutex);
 +              if (err)
 +                      goto out;
 +      }
@@ -4697,6 +4688,7 @@ index 0000000..416c52f
 +      unionfs_unlock_dentry(dentry);
 +      unionfs_unlock_parent(dentry, parent);
 +      unionfs_read_unlock(dentry->d_sb);
++      lockdep_on();
 +      return err;
 +}
 +
@@ -4840,10 +4832,10 @@ index 0000000..416c52f
 +};
 diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
 new file mode 100644
-index 0000000..b207c13
+index 0000000..dd522c2
 --- /dev/null
 +++ b/fs/unionfs/inode.c
-@@ -0,0 +1,1099 @@
+@@ -0,0 +1,1085 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -4943,7 +4935,7 @@ index 0000000..b207c13
 +}
 +
 +static int unionfs_create(struct inode *dir, struct dentry *dentry,
-+                        int mode, struct nameidata *nd_unused)
++                        umode_t mode, struct nameidata *nd_unused)
 +{
 +      int err = 0;
 +      struct dentry *lower_dentry = NULL;
@@ -4988,7 +4980,7 @@ index 0000000..b207c13
 +                      fsstack_copy_inode_size(dir,
 +                                              lower_parent_dentry->d_inode);
 +                      /* update no. of links on parent directory */
-+                      dir->i_nlink = unionfs_get_nlinks(dir);
++                      set_nlink(dir, unionfs_get_nlinks(dir));
 +              }
 +      }
 +
@@ -5099,7 +5091,7 @@ index 0000000..b207c13
 +              lower_dir_dentry = dget_parent(lower_new_dentry);
 +              fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
 +              dput(lower_dir_dentry);
-+              dir->i_nlink = unionfs_get_nlinks(dir);
++              set_nlink(dir, unionfs_get_nlinks(dir));
 +              err = 0;
 +      }
 +      if (err)
@@ -5174,7 +5166,8 @@ index 0000000..b207c13
 +      fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode);
 +
 +      /* propagate number of hard-links */
-+      old_dentry->d_inode->i_nlink = unionfs_get_nlinks(old_dentry->d_inode);
++      set_nlink(old_dentry->d_inode,
++                unionfs_get_nlinks(old_dentry->d_inode));
 +      /* new dentry's ctime may have changed due to hard-link counts */
 +      unionfs_copy_attr_times(new_dentry->d_inode);
 +
@@ -5248,7 +5241,7 @@ index 0000000..b207c13
 +                      fsstack_copy_inode_size(dir,
 +                                              lower_parent_dentry->d_inode);
 +                      /* update no. of links on parent directory */
-+                      dir->i_nlink = unionfs_get_nlinks(dir);
++                      set_nlink(dir, unionfs_get_nlinks(dir));
 +              }
 +      }
 +
@@ -5269,7 +5262,7 @@ index 0000000..b207c13
 +      return err;
 +}
 +
-+static int unionfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++static int unionfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
 +{
 +      int err = 0;
 +      struct dentry *lower_dentry = NULL;
@@ -5360,7 +5353,7 @@ index 0000000..b207c13
 +                                              lower_parent_dentry->d_inode);
 +
 +                      /* update number of links on parent directory */
-+                      dir->i_nlink = unionfs_get_nlinks(dir);
++                      set_nlink(dir, unionfs_get_nlinks(dir));
 +              }
 +
 +              err = make_dir_opaque(dentry, dbstart(dentry));
@@ -5393,7 +5386,7 @@ index 0000000..b207c13
 +      return err;
 +}
 +
-+static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
++static int unionfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
 +                       dev_t dev)
 +{
 +      int err = 0;
@@ -5440,7 +5433,7 @@ index 0000000..b207c13
 +                      fsstack_copy_inode_size(dir,
 +                                              lower_parent_dentry->d_inode);
 +                      /* update no. of links on parent directory */
-+                      dir->i_nlink = unionfs_get_nlinks(dir);
++                      set_nlink(dir, unionfs_get_nlinks(dir));
 +              }
 +      }
 +
@@ -5589,7 +5582,7 @@ index 0000000..b207c13
 + * This is a variant of fs/namei.c:permission() or inode_permission() which
 + * skips over EROFS tests (because we perform copyup on EROFS).
 + */
-+static int __inode_permission(struct inode *inode, int mask, unsigned int flags)
++static int __inode_permission(struct inode *inode, int mask)
 +{
 +      int retval;
 +
@@ -5599,7 +5592,7 @@ index 0000000..b207c13
 +
 +      /* Ordinary permission routines do not understand MAY_APPEND. */
 +      if (inode->i_op && inode->i_op->permission) {
-+              retval = inode->i_op->permission(inode, mask, flags);
++              retval = inode->i_op->permission(inode, mask);
 +              if (!retval) {
 +                      /*
 +                       * Exec permission on a regular file is denied if none
@@ -5613,7 +5606,7 @@ index 0000000..b207c13
 +                              return -EACCES;
 +              }
 +      } else {
-+              retval = generic_permission(inode, mask, flags, NULL);
++              retval = generic_permission(inode, mask);
 +      }
 +      if (retval)
 +              return retval;
@@ -5630,7 +5623,7 @@ index 0000000..b207c13
 + * unionfs_permission, or anything it calls, will use stale branch
 + * information.
 + */
-+static int unionfs_permission(struct inode *inode, int mask, unsigned int flags)
++static int unionfs_permission(struct inode *inode, int mask)
 +{
 +      struct inode *lower_inode = NULL;
 +      int err = 0;
@@ -5638,16 +5631,6 @@ index 0000000..b207c13
 +      int is_file;
 +      const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
 +      struct inode *inode_grabbed;
-+      struct dentry *dentry;
-+
-+      if (flags & IPERM_FLAG_RCU) {
-+              err = -ECHILD;
-+              goto out_nograb;
-+      }
-+
-+      dentry = d_find_alias(inode);
-+      if (dentry)
-+              unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 +
 +      inode_grabbed = igrab(inode);
 +      is_file = !S_ISDIR(inode->i_mode);
@@ -5692,7 +5675,7 @@ index 0000000..b207c13
 +               * copyup taking place later on.  However, if user never had
 +               * access to the file, then no copyup could ever take place.
 +               */
-+              err = __inode_permission(lower_inode, mask, flags);
++              err = __inode_permission(lower_inode, mask);
 +              if (err && err != -EACCES && err != EPERM && bindex > 0) {
 +                      umode_t mode = lower_inode->i_mode;
 +                      if ((is_robranch_super(inode->i_sb, bindex) ||
@@ -5715,7 +5698,7 @@ index 0000000..b207c13
 +              if (err && err == -EACCES &&
 +                  is_robranch_super(inode->i_sb, bindex) &&
 +                  lower_inode->i_sb->s_magic == NFS_SUPER_MAGIC)
-+                      err = generic_permission(lower_inode, mask, flags, NULL);
++                      err = generic_permission(lower_inode, mask);
 +
 +              /*
 +               * The permissions are an intersection of the overall directory
@@ -5739,12 +5722,7 @@ index 0000000..b207c13
 +
 +out:
 +      unionfs_check_inode(inode);
-+      if (dentry) {
-+              unionfs_unlock_dentry(dentry);
-+              dput(dentry);
-+      }
 +      iput(inode_grabbed);
-+out_nograb:
 +      return err;
 +}
 +
@@ -5945,10 +5923,10 @@ index 0000000..b207c13
 +};
 diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
 new file mode 100644
-index 0000000..3cbde56
+index 0000000..041d674
 --- /dev/null
 +++ b/fs/unionfs/lookup.c
-@@ -0,0 +1,569 @@
+@@ -0,0 +1,570 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -5981,17 +5959,17 @@ index 0000000..3cbde56
 +                          const char *name, struct vfsmount **new_mnt)
 +{
 +      struct dentry *dentry = NULL;
-+      struct nameidata lower_nd;
++      struct path lower_path = {NULL, NULL};
 +      int err;
 +
 +      /* we use flags=0 to get basic lookup */
-+      err = vfs_path_lookup(base, mnt, name, 0, &lower_nd);
++      err = vfs_path_lookup(base, mnt, name, 0, &lower_path);
 +
 +      switch (err) {
 +      case 0: /* no error */
-+              dentry = lower_nd.path.dentry;
++              dentry = lower_path.dentry;
 +              if (new_mnt)
-+                      *new_mnt = lower_nd.path.mnt; /* rc already inc'ed */
++                      *new_mnt = lower_path.mnt; /* rc already inc'ed */
 +              break;
 +      case -ENOENT:
 +               /*
@@ -6003,7 +5981,7 @@ index 0000000..3cbde56
 +                */
 +              dentry = lookup_lck_len(name, base, strlen(name));
 +              if (new_mnt)
-+                      *new_mnt = mntget(lower_nd.path.mnt);
++                      *new_mnt = mntget(lower_path.mnt);
 +              break;
 +      default: /* all other real errors */
 +              dentry = ERR_PTR(err);
@@ -6262,7 +6240,8 @@ index 0000000..3cbde56
 +      verify_locked(parent);
 +
 +      /* must initialize dentry operations */
-+      dentry->d_op = &unionfs_dops;
++      if (lookupmode == INTERPOSE_LOOKUP)
++              d_set_d_op(dentry, &unionfs_dops);
 +
 +      /* We never partial lookup the root directory. */
 +      if (IS_ROOT(dentry))
@@ -6520,10 +6499,10 @@ index 0000000..3cbde56
 +}
 diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
 new file mode 100644
-index 0000000..fa52f61
+index 0000000..ee78f1d
 --- /dev/null
 +++ b/fs/unionfs/main.c
-@@ -0,0 +1,763 @@
+@@ -0,0 +1,752 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -6671,7 +6650,7 @@ index 0000000..fa52f61
 +                       * properly.  Finally we must return this new
 +                       * dentry.
 +                       */
-+                      spliced->d_op = &unionfs_dops;
++                      d_set_d_op(spliced, &unionfs_dops);
 +                      spliced->d_fsdata = dentry->d_fsdata;
 +                      dentry->d_fsdata = NULL;
 +                      dentry = spliced;
@@ -7052,32 +7031,6 @@ index 0000000..fa52f61
 +}
 +
 +/*
-+ * our custom d_alloc_root work-alike
-+ *
-+ * we can't use d_alloc_root if we want to use our own interpose function
-+ * unchanged, so we simply call our own "fake" d_alloc_root
-+ */
-+static struct dentry *unionfs_d_alloc_root(struct super_block *sb)
-+{
-+      struct dentry *ret = NULL;
-+
-+      if (sb) {
-+              static const struct qstr name = {
-+                      .name = "/",
-+                      .len = 1
-+              };
-+
-+              ret = d_alloc(NULL, &name);
-+              if (likely(ret)) {
-+                      ret->d_op = &unionfs_dops;
-+                      ret->d_sb = sb;
-+                      ret->d_parent = ret;
-+              }
-+      }
-+      return ret;
-+}
-+
-+/*
 + * There is no need to lock the unionfs_super_info's rwsem as there is no
 + * way anyone can have a reference to the superblock at this point in time.
 + */
@@ -7087,6 +7040,7 @@ index 0000000..fa52f61
 +      int err = 0;
 +      struct unionfs_dentry_info *lower_root_info = NULL;
 +      int bindex, bstart, bend;
++      struct inode *inode = NULL;
 +
 +      if (!raw_data) {
 +              printk(KERN_ERR
@@ -7144,12 +7098,18 @@ index 0000000..fa52f61
 +
 +      sb->s_op = &unionfs_sops;
 +
-+      /* See comment next to the definition of unionfs_d_alloc_root */
-+      sb->s_root = unionfs_d_alloc_root(sb);
++      /* get a new inode and allocate our root dentry */
++      inode = unionfs_iget(sb, iunique(sb, UNIONFS_ROOT_INO));
++      if (IS_ERR(inode)) {
++              err = PTR_ERR(inode);
++              goto out_dput;
++      }
++      sb->s_root = d_make_root(inode);
 +      if (unlikely(!sb->s_root)) {
 +              err = -ENOMEM;
 +              goto out_dput;
 +      }
++      d_set_d_op(sb->s_root, &unionfs_dops);
 +
 +      /* link the upper and lower dentries */
 +      sb->s_root->d_fsdata = NULL;
@@ -7157,6 +7117,8 @@ index 0000000..fa52f61
 +      if (unlikely(err))
 +              goto out_freedpd;
 +
++      /* if get here: cannot have error */
++
 +      /* Set the lower dentries for s_root */
 +      for (bindex = bstart; bindex <= bend; bindex++) {
 +              struct dentry *d;
@@ -7174,15 +7136,18 @@ index 0000000..fa52f61
 +      /* Set the generation number to one, since this is for the mount. */
 +      atomic_set(&UNIONFS_D(sb->s_root)->generation, 1);
 +
++      if (atomic_read(&inode->i_count) <= 1)
++              unionfs_fill_inode(sb->s_root, inode);
++
 +      /*
-+       * Call interpose to create the upper level inode.  Only
-+       * INTERPOSE_LOOKUP can return a value other than 0 on err.
++       * No need to call interpose because we already have a positive
++       * dentry, which was instantiated by d_alloc_root.  Just need to
++       * d_rehash it.
 +       */
-+      err = PTR_ERR(unionfs_interpose(sb->s_root, sb, 0));
++      d_rehash(sb->s_root);
++
 +      unionfs_unlock_dentry(sb->s_root);
-+      if (!err)
-+              goto out;
-+      /* else fall through */
++      goto out; /* all is well */
 +
 +out_freedpd:
 +      if (UNIONFS_D(sb->s_root)) {
@@ -7191,6 +7156,9 @@ index 0000000..fa52f61
 +      }
 +      dput(sb->s_root);
 +
++out_iput:
++      iput(inode);
++
 +out_dput:
 +      if (lower_root_info && !IS_ERR(lower_root_info)) {
 +              for (bindex = lower_root_info->bstart;
@@ -7226,7 +7194,7 @@ index 0000000..fa52f61
 +      struct dentry *dentry;
 +
 +      dentry = mount_nodev(fs_type, flags, raw_data, unionfs_read_super);
-+      if (!PTR_ERR(dentry))
++      if (!IS_ERR(dentry))
 +              UNIONFS_SB(dentry->d_sb)->dev_name =
 +                      kstrdup(dev_name, GFP_KERNEL);
 +      return dentry;
@@ -7675,7 +7643,7 @@ index 0000000..59b7333
 +}
 diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
 new file mode 100644
-index 0000000..c8ab910
+index 0000000..ce85b84
 --- /dev/null
 +++ b/fs/unionfs/rename.c
 @@ -0,0 +1,522 @@
@@ -7893,8 +7861,8 @@ index 0000000..c8ab910
 +              fsstack_copy_attr_times(new_parent->d_inode,
 +                                      unlink_dir_dentry->d_inode);
 +              /* propagate number of hard-links */
-+              new_parent->d_inode->i_nlink =
-+                      unionfs_get_nlinks(new_parent->d_inode);
++              set_nlink(new_parent->d_inode,
++                        unionfs_get_nlinks(new_parent->d_inode));
 +
 +              unlock_dir(unlink_dir_dentry);
 +              if (!err) {
@@ -8407,7 +8375,7 @@ index 0000000..c2dfb94
 +#endif /* not _SIOQ_H */
 diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
 new file mode 100644
-index 0000000..bdca2f7
+index 0000000..e7fc5a5
 --- /dev/null
 +++ b/fs/unionfs/subr.c
 @@ -0,0 +1,95 @@
@@ -8504,11 +8472,11 @@ index 0000000..bdca2f7
 +       * Update the nlinks AFTER updating the above fields, because the
 +       * get_links callback may depend on them.
 +       */
-+      dest->i_nlink = unionfs_get_nlinks(dest);
++      set_nlink(dest, unionfs_get_nlinks(dest));
 +}
 diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
 new file mode 100644
-index 0000000..c3ac814
+index 0000000..b99f14d
 --- /dev/null
 +++ b/fs/unionfs/super.c
 @@ -0,0 +1,1030 @@
@@ -9479,9 +9447,9 @@ index 0000000..c3ac814
 +      unionfs_read_unlock(sb);
 +}
 +
-+static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt)
++static int unionfs_show_options(struct seq_file *m, struct dentry *root)
 +{
-+      struct super_block *sb = mnt->mnt_sb;
++      struct super_block *sb = root->d_sb;
 +      int ret = 0;
 +      char *tmp_page;
 +      char *path;
@@ -9544,10 +9512,10 @@ index 0000000..c3ac814
 +};
 diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
 new file mode 100644
-index 0000000..1821705
+index 0000000..8e7fcfb
 --- /dev/null
 +++ b/fs/unionfs/union.h
-@@ -0,0 +1,679 @@
+@@ -0,0 +1,681 @@
 +/*
 + * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
@@ -9598,7 +9566,7 @@ index 0000000..1821705
 +#include <linux/splice.h>
 +#include <linux/sched.h>
 +
-+#include <asm/system.h>
++
 +
 +#include <linux/union_fs.h>
 +
@@ -9966,7 +9934,8 @@ index 0000000..1821705
 +extern int unionfs_flush(struct file *file, fl_owner_t id);
 +extern long unionfs_ioctl(struct file *file, unsigned int cmd,
 +                        unsigned long arg);
-+extern int unionfs_fsync(struct file *file, int datasync);
++extern int unionfs_fsync(struct file *file, loff_t start, loff_t end,
++                       int datasync);
 +extern int unionfs_fasync(int fd, struct file *file, int flag);
 +
 +/* Inode operations */
@@ -10223,13 +10192,14 @@ index 0000000..1821705
 +#define show_inode_times(i)           do { } while (0)
 +#define show_dinode_times(d)          do { } while (0)
 +#define show_inode_counts(i)          do { } while (0)
++#define UDBG                          do { } while (0)
 +
 +#endif /* not CONFIG_UNION_FS_DEBUG */
 +
 +#endif        /* not _UNION_H_ */
 diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
 new file mode 100644
-index 0000000..bf447bb
+index 0000000..25943a5
 --- /dev/null
 +++ b/fs/unionfs/unlink.c
 @@ -0,0 +1,278 @@
@@ -10425,7 +10395,7 @@ index 0000000..bf447bb
 +
 +      fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
 +      /* propagate number of hard-links */
-+      dentry->d_inode->i_nlink = unionfs_get_nlinks(dentry->d_inode);
++      set_nlink(dentry->d_inode, unionfs_get_nlinks(dentry->d_inode));
 +
 +out:
 +      if (lower_dir_dentry)
@@ -11323,7 +11293,7 @@ index da317c7..64f1ced 100644
   */
  
 diff --git a/include/linux/magic.h b/include/linux/magic.h
-index 1e5df2a..01ee54d 100644
+index 2d4beab..39f5798 100644
 --- a/include/linux/magic.h
 +++ b/include/linux/magic.h
 @@ -50,6 +50,8 @@
@@ -11336,10 +11306,10 @@ index 1e5df2a..01ee54d 100644
  #define USBDEVICE_SUPER_MAGIC 0x9fa2
  #define CGROUP_SUPER_MAGIC    0x27e0eb
 diff --git a/include/linux/namei.h b/include/linux/namei.h
-index eba45ea..8e19e9c 100644
+index ffc0213..99802c3 100644
 --- a/include/linux/namei.h
 +++ b/include/linux/namei.h
-@@ -81,8 +81,11 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+@@ -84,8 +84,11 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
  
  extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
                int (*open)(struct inode *, struct file *));
@@ -11352,7 +11322,7 @@ index eba45ea..8e19e9c 100644
  extern int follow_down_one(struct path *);
  extern int follow_down(struct path *);
 diff --git a/include/linux/splice.h b/include/linux/splice.h
-index 997c3b4..54f5501 100644
+index 26e5b61..28213e6 100644
 --- a/include/linux/splice.h
 +++ b/include/linux/splice.h
 @@ -81,6 +81,11 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
@@ -11396,14 +11366,14 @@ index 0000000..c84d97e
 +#endif /* _LINUX_UNIONFS_H */
 +
 diff --git a/security/security.c b/security/security.c
-index 4ba6d4c..093d8b4 100644
+index d754249..f7e8373 100644
 --- a/security/security.c
 +++ b/security/security.c
-@@ -520,6 +520,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -538,6 +538,7 @@ int security_inode_permission(struct inode *inode, int mask)
                return 0;
-       return security_ops->inode_permission(inode, mask, 0);
+       return security_ops->inode_permission(inode, mask);
  }
 +EXPORT_SYMBOL(security_inode_permission);
  
- int security_inode_exec_permission(struct inode *inode, unsigned int flags)
+ int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
  {
This page took 0.24434 seconds and 4 git commands to generate.