]> git.pld-linux.org Git - packages/kernel.git/commitdiff
- http://download.filesystems.org/unionfs/unionfs-2.x-latest/unionfs-2.5.9.2_for_3...
authorJan Rękorajski <baggins@pld-linux.org>
Mon, 11 Jul 2011 19:51:13 +0000 (19:51 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    kernel-unionfs.patch -> 1.14

kernel-unionfs.patch

index a48696a898765356e200d3dfbcc626f83629ad4e..a2a66b1c157eaedee14a4018a7fd99db1797add3 100644 (file)
@@ -532,10 +532,10 @@ index 0000000..1adde69
 +
 +For more information, see <http://unionfs.filesystems.org/>.
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 560ecce..09e38d6 100644
+index f0358cd..7ae0669 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -6276,6 +6276,14 @@ F:      Documentation/cdrom/
+@@ -6375,6 +6375,14 @@ F:      Documentation/cdrom/
  F:    drivers/cdrom/cdrom.c
  F:    include/linux/cdrom.h
  
@@ -551,10 +551,10 @@ index 560ecce..09e38d6 100644
  M:    Artem Bityutskiy <dedekind1@gmail.com>
  W:    http://www.linux-mtd.infradead.org/
 diff --git a/fs/Kconfig b/fs/Kconfig
-index 3db9caa..3dc2dfd 100644
+index 19891aa..ac8a074 100644
 --- a/fs/Kconfig
 +++ b/fs/Kconfig
-@@ -170,6 +170,7 @@ if MISC_FILESYSTEMS
+@@ -187,6 +187,7 @@ if MISC_FILESYSTEMS
  source "fs/adfs/Kconfig"
  source "fs/affs/Kconfig"
  source "fs/ecryptfs/Kconfig"
@@ -563,10 +563,10 @@ index 3db9caa..3dc2dfd 100644
  source "fs/hfsplus/Kconfig"
  source "fs/befs/Kconfig"
 diff --git a/fs/Makefile b/fs/Makefile
-index a7f7cef..672664b 100644
+index fb68c2b..8ca9290 100644
 --- a/fs/Makefile
 +++ b/fs/Makefile
-@@ -81,6 +81,7 @@ obj-$(CONFIG_ISO9660_FS)     += isofs/
+@@ -83,6 +83,7 @@ obj-$(CONFIG_ISO9660_FS)     += isofs/
  obj-$(CONFIG_HFSPLUS_FS)      += hfsplus/ # Before hfs to find wrapped HFS+
  obj-$(CONFIG_HFS_FS)          += hfs/
  obj-$(CONFIG_ECRYPT_FS)               += ecryptfs/
@@ -575,10 +575,10 @@ index a7f7cef..672664b 100644
  obj-$(CONFIG_NFS_FS)          += nfs/
  obj-$(CONFIG_EXPORTFS)                += exportfs/
 diff --git a/fs/namei.c b/fs/namei.c
-index 0087cf9..d3118a7 100644
+index 0223c41..5d0261e 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
-@@ -562,6 +562,7 @@ void release_open_intent(struct nameidata *nd)
+@@ -484,6 +484,7 @@ void release_open_intent(struct nameidata *nd)
                        fput(file);
        }
  }
@@ -586,11 +586,62 @@ index 0087cf9..d3118a7 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)
+       return __lookup_hash(&this, base, NULL);
+ }
++/* pass nameidata from caller (useful for NFS) */
++struct dentry *lookup_one_len_nd(const char *name, struct dentry *base,
++                               int len, struct nameidata *nd)
++{
++      struct qstr this;
++      unsigned long hash;
++      unsigned int c;
++
++      WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
++
++      this.name = name;
++      this.len = len;
++      if (!len)
++              return ERR_PTR(-EACCES);
++
++      hash = init_name_hash();
++      while (len--) {
++              c = *(const unsigned char *)name++;
++              if (c == '/' || c == '\0')
++                      return ERR_PTR(-EACCES);
++              hash = partial_name_hash(c, hash);
++      }
++      this.hash = end_name_hash(hash);
++      /*
++       * See if the low-level filesystem might want
++       * to use its own hash..
++       */
++      if (base->d_flags & DCACHE_OP_HASH) {
++              int err = base->d_op->d_hash(base, base->d_inode, &this);
++              if (err < 0)
++                      return ERR_PTR(err);
++      }
++
++      return __lookup_hash(&this, base, nd);
++}
++
+ int user_path_at(int dfd, const char __user *name, unsigned flags,
+                struct path *path)
+ {
+@@ -3339,6 +3376,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
+ EXPORT_SYMBOL(getname);
+ EXPORT_SYMBOL(lock_rename);
+ EXPORT_SYMBOL(lookup_one_len);
++EXPORT_SYMBOL(lookup_one_len_nd);
+ EXPORT_SYMBOL(page_follow_link_light);
+ EXPORT_SYMBOL(page_put_link);
+ EXPORT_SYMBOL(page_readlink);
 diff --git a/fs/splice.c b/fs/splice.c
-index 50a5d97..a3af841 100644
+index aa866d3..421ab86 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1081,8 +1081,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1085,8 +1085,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -601,7 +652,7 @@ index 50a5d97..a3af841 100644
  {
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
                                loff_t *, size_t, unsigned int);
-@@ -1105,13 +1105,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1109,13 +1109,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
        return splice_write(pipe, out, ppos, len, flags);
  }
@@ -619,7 +670,7 @@ index 50a5d97..a3af841 100644
  {
        ssize_t (*splice_read)(struct file *, loff_t *,
                               struct pipe_inode_info *, size_t, unsigned int);
-@@ -1131,6 +1132,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1135,6 +1136,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
  
        return splice_read(in, ppos, pipe, len, flags);
  }
@@ -627,7 +678,7 @@ index 50a5d97..a3af841 100644
  
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
-@@ -1200,7 +1202,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+@@ -1204,7 +1206,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;
  
@@ -636,7 +687,7 @@ index 50a5d97..a3af841 100644
                if (unlikely(ret <= 0))
                        goto out_release;
  
-@@ -1259,8 +1261,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
+@@ -1263,8 +1265,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
  {
        struct file *file = sd->u.file;
  
@@ -647,7 +698,7 @@ index 50a5d97..a3af841 100644
  }
  
  /**
-@@ -1345,7 +1347,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1349,7 +1351,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &out->f_pos;
  
@@ -656,7 +707,7 @@ index 50a5d97..a3af841 100644
  
                if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
                        ret = -EFAULT;
-@@ -1365,7 +1367,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1369,7 +1371,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &in->f_pos;
  
@@ -723,11 +774,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..10a321a
+index 0000000..0ece303
 --- /dev/null
 +++ b/fs/unionfs/Makefile
 @@ -0,0 +1,17 @@
-+UNIONFS_VERSION="2.5.8 (for 2.6.38-rc7)"
++UNIONFS_VERSION="2.5.9.2 (for 3.0.0-rc4)"
 +
 +EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\"
 +
@@ -746,12 +797,12 @@ index 0000000..10a321a
 +endif
 diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
 new file mode 100644
-index 0000000..51ea65e
+index 0000000..0a271f4
 --- /dev/null
 +++ b/fs/unionfs/commonfops.c
 @@ -0,0 +1,896 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -760,8 +811,8 @@ index 0000000..51ea65e
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -1064,7 +1115,7 @@ index 0000000..51ea65e
 +       * someone has copied up this file from underneath us, we also need
 +       * to refresh things.
 +       */
-+      if (d_deleted(dentry) ||
++      if ((d_deleted(dentry) && dbstart(dentry) >= fbstart(file)) ||
 +          (sbgen <= fgen &&
 +           dbstart(dentry) == fbstart(file) &&
 +           unionfs_lower_file(file)))
@@ -1258,8 +1309,11 @@ index 0000000..51ea65e
 +                      for (bindex = bstart - 1; bindex >= 0; bindex--) {
 +                              err = copyup_file(parent->d_inode, file,
 +                                                bstart, bindex, size);
-+                              if (!err)
++                              if (!err) {
++                                      /* only one regular file open */
++                                      fbend(file) = fbstart(file);
 +                                      break;
++                              }
 +                      }
 +                      return err;
 +              } else {
@@ -1400,7 +1454,7 @@ index 0000000..51ea65e
 +      struct dentry *dentry = file->f_path.dentry;
 +      struct dentry *parent;
 +      int bindex, bstart, bend;
-+      int fgen, err = 0;
++      int err = 0;
 +
 +      /*
 +       * Since mm/memory.c:might_fault() (under PROVE_LOCKING) was
@@ -1436,7 +1490,6 @@ index 0000000..51ea65e
 +      inodeinfo = UNIONFS_I(inode);
 +
 +      /* fput all the lower files */
-+      fgen = atomic_read(&fileinfo->generation);
 +      bstart = fbstart(file);
 +      bend = fbend(file);
 +
@@ -1492,10 +1545,8 @@ index 0000000..51ea65e
 +      if (lower_file->f_op->unlocked_ioctl) {
 +              err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
 +#ifdef CONFIG_COMPAT
-+      } else if (lower_file->f_op->ioctl) {
-+              err = lower_file->f_op->compat_ioctl(
-+                      lower_file->f_path.dentry->d_inode,
-+                      lower_file, cmd, arg);
++      } else if (lower_file->f_op->compat_ioctl) {
++              err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
 +#endif
 +      }
 +
@@ -1648,12 +1699,12 @@ index 0000000..51ea65e
 +}
 diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
 new file mode 100644
-index 0000000..bba3a75
+index 0000000..37c2654
 --- /dev/null
 +++ b/fs/unionfs/copyup.c
 @@ -0,0 +1,896 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -1662,8 +1713,8 @@ index 0000000..bba3a75
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -2550,15 +2601,15 @@ index 0000000..bba3a75
 +}
 diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
 new file mode 100644
-index 0000000..a76f92a
+index 0000000..6092e69
 --- /dev/null
 +++ b/fs/unionfs/debug.c
 @@ -0,0 +1,548 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -3104,12 +3155,12 @@ index 0000000..a76f92a
 +}
 diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
 new file mode 100644
-index 0000000..a0c3bba
+index 0000000..c0205a4
 --- /dev/null
 +++ b/fs/unionfs/dentry.c
-@@ -0,0 +1,397 @@
+@@ -0,0 +1,406 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -3118,8 +3169,8 @@ index 0000000..a0c3bba
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -3302,6 +3353,9 @@ index 0000000..a0c3bba
 +      bend = dbend(dentry);
 +      BUG_ON(bstart == -1);
 +      for (bindex = bstart; bindex <= bend; bindex++) {
++              int err;
++              struct nameidata lower_nd;
++
 +              lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
 +              if (!lower_dentry || !lower_dentry->d_op
 +                  || !lower_dentry->d_op->d_revalidate)
@@ -3314,8 +3368,14 @@ index 0000000..a0c3bba
 +               * invariants).  We will open lower files as and when needed
 +               * later on.
 +               */
-+              if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
++              err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
++              if (unlikely(err < 0)) {
 +                      valid = false;
++                      break;
++              }
++              if (!lower_dentry->d_op->d_revalidate(lower_dentry, &lower_nd))
++                      valid = false;
++              release_lower_nd(&lower_nd, err);
 +      }
 +
 +      if (!dentry->d_inode ||
@@ -3507,12 +3567,12 @@ index 0000000..a0c3bba
 +};
 diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
 new file mode 100644
-index 0000000..7da0ff0
+index 0000000..72a9c1a
 --- /dev/null
 +++ b/fs/unionfs/dirfops.c
 @@ -0,0 +1,302 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -3521,8 +3581,8 @@ index 0000000..7da0ff0
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -3815,12 +3875,12 @@ index 0000000..7da0ff0
 +};
 diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
 new file mode 100644
-index 0000000..033343b
+index 0000000..62ec9af
 --- /dev/null
 +++ b/fs/unionfs/dirhelper.c
 @@ -0,0 +1,158 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -3829,8 +3889,8 @@ index 0000000..033343b
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -3979,12 +4039,12 @@ index 0000000..033343b
 +}
 diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h
 new file mode 100644
-index 0000000..5b77eac
+index 0000000..ae1b86a
 --- /dev/null
 +++ b/fs/unionfs/fanout.h
 @@ -0,0 +1,407 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005      Arun M. Krishnakumar
@@ -3992,8 +4052,8 @@ index 0000000..5b77eac
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -4392,12 +4452,12 @@ index 0000000..5b77eac
 +#endif        /* not _FANOUT_H */
 diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
 new file mode 100644
-index 0000000..1c694c3
+index 0000000..416c52f
 --- /dev/null
 +++ b/fs/unionfs/file.c
 @@ -0,0 +1,382 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -4406,8 +4466,8 @@ index 0000000..1c694c3
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -4780,12 +4840,12 @@ index 0000000..1c694c3
 +};
 diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
 new file mode 100644
-index 0000000..0066238
+index 0000000..b207c13
 --- /dev/null
 +++ b/fs/unionfs/inode.c
-@@ -0,0 +1,1077 @@
+@@ -0,0 +1,1099 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -4794,8 +4854,8 @@ index 0000000..0066238
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -5575,17 +5635,23 @@ index 0000000..0066238
 +      struct inode *lower_inode = NULL;
 +      int err = 0;
 +      int bindex, bstart, bend;
-+      const int is_file = !S_ISDIR(inode->i_mode);
++      int is_file;
 +      const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
-+      struct inode *inode_grabbed = igrab(inode);
-+      struct dentry *dentry = d_find_alias(inode);
++      struct inode *inode_grabbed;
++      struct dentry *dentry;
 +
-+      if (flags & IPERM_FLAG_RCU)
-+              return -ECHILD;
++      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);
++
 +      if (!UNIONFS_I(inode)->lower_inodes) {
 +              if (is_file)    /* dirs can be unlinked but chdir'ed to */
 +                      err = -ESTALE;  /* force revalidate */
@@ -5678,6 +5744,7 @@ index 0000000..0066238
 +              dput(dentry);
 +      }
 +      iput(inode_grabbed);
++out_nograb:
 +      return err;
 +}
 +
@@ -5722,7 +5789,12 @@ index 0000000..0066238
 +              err = -EINVAL;
 +              goto out;
 +      }
-+      lower_inode = unionfs_lower_inode(inode);
++
++      /*
++       * Get the lower inode directly from lower dentry, in case ibstart
++       * is -1 (which happens when the file is open but unlinked.
++       */
++      lower_inode = lower_dentry->d_inode;
 +
 +      /* check if user has permission to change lower inode */
 +      err = inode_change_ok(lower_inode, ia);
@@ -5757,6 +5829,16 @@ index 0000000..0066238
 +              /* get updated lower_dentry/inode after copyup */
 +              lower_dentry = unionfs_lower_dentry(dentry);
 +              lower_inode = unionfs_lower_inode(inode);
++              /*
++               * check for whiteouts in writeable branch, and remove them
++               * if necessary.
++               */
++              if (lower_dentry) {
++                      err = check_unlink_whiteout(dentry, lower_dentry,
++                                                  bindex);
++                      if (err > 0) /* ignore if whiteout found and removed */
++                              err = 0;
++              }
 +      }
 +
 +      /*
@@ -5863,12 +5945,12 @@ index 0000000..0066238
 +};
 diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
 new file mode 100644
-index 0000000..b63c17e
+index 0000000..3cbde56
 --- /dev/null
 +++ b/fs/unionfs/lookup.c
 @@ -0,0 +1,569 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -5877,8 +5959,8 @@ index 0000000..b63c17e
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -6438,12 +6520,12 @@ index 0000000..b63c17e
 +}
 diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
 new file mode 100644
-index 0000000..9ee58eb
+index 0000000..fa52f61
 --- /dev/null
 +++ b/fs/unionfs/main.c
-@@ -0,0 +1,762 @@
+@@ -0,0 +1,763 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -6452,8 +6534,8 @@ index 0000000..9ee58eb
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -6659,14 +6741,14 @@ index 0000000..9ee58eb
 + * 2) it exists
 + * 3) is a directory
 + */
-+int check_branch(struct nameidata *nd)
++int check_branch(const struct path *path)
 +{
 +      /* XXX: remove in ODF code -- stacking unions allowed there */
-+      if (!strcmp(nd->path.dentry->d_sb->s_type->name, UNIONFS_NAME))
++      if (!strcmp(path->dentry->d_sb->s_type->name, UNIONFS_NAME))
 +              return -EINVAL;
-+      if (!nd->path.dentry->d_inode)
++      if (!path->dentry->d_inode)
 +              return -ENOENT;
-+      if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
++      if (!S_ISDIR(path->dentry->d_inode->i_mode))
 +              return -ENOTDIR;
 +      return 0;
 +}
@@ -6718,7 +6800,7 @@ index 0000000..9ee58eb
 +static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info
 +                           *lower_root_info, char *options)
 +{
-+      struct nameidata nd;
++      struct path path;
 +      char *name;
 +      int err = 0;
 +      int branches = 1;
@@ -6794,7 +6876,7 @@ index 0000000..9ee58eb
 +                      goto out;
 +              }
 +
-+              err = path_lookup(name, LOOKUP_FOLLOW, &nd);
++              err = kern_path(name, LOOKUP_FOLLOW, &path);
 +              if (err) {
 +                      printk(KERN_ERR "unionfs: error accessing "
 +                             "lower directory '%s' (error %d)\n",
@@ -6802,16 +6884,16 @@ index 0000000..9ee58eb
 +                      goto out;
 +              }
 +
-+              err = check_branch(&nd);
++              err = check_branch(&path);
 +              if (err) {
 +                      printk(KERN_ERR "unionfs: lower directory "
 +                             "'%s' is not a valid branch\n", name);
-+                      path_put(&nd.path);
++                      path_put(&path);
 +                      goto out;
 +              }
 +
-+              lower_root_info->lower_paths[bindex].dentry = nd.path.dentry;
-+              lower_root_info->lower_paths[bindex].mnt = nd.path.mnt;
++              lower_root_info->lower_paths[bindex].dentry = path.dentry;
++              lower_root_info->lower_paths[bindex].mnt = path.mnt;
 +
 +              set_branchperms(sb, bindex, perms);
 +              set_branch_count(sb, bindex, 0);
@@ -7137,22 +7219,23 @@ index 0000000..9ee58eb
 +      return err;
 +}
 +
-+static int unionfs_get_sb(struct file_system_type *fs_type,
-+                        int flags, const char *dev_name,
-+                        void *raw_data, struct vfsmount *mnt)
++static struct dentry *unionfs_mount(struct file_system_type *fs_type,
++                                  int flags, const char *dev_name,
++                                  void *raw_data)
 +{
-+      int err;
-+      err = get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt);
-+      if (!err)
-+              UNIONFS_SB(mnt->mnt_sb)->dev_name =
++      struct dentry *dentry;
++
++      dentry = mount_nodev(fs_type, flags, raw_data, unionfs_read_super);
++      if (!PTR_ERR(dentry))
++              UNIONFS_SB(dentry->d_sb)->dev_name =
 +                      kstrdup(dev_name, GFP_KERNEL);
-+      return err;
++      return dentry;
 +}
 +
 +static struct file_system_type unionfs_fs_type = {
 +      .owner          = THIS_MODULE,
 +      .name           = UNIONFS_NAME,
-+      .get_sb         = unionfs_get_sb,
++      .mount          = unionfs_mount,
 +      .kill_sb        = generic_shutdown_super,
 +      .fs_flags       = FS_REVAL_DOT,
 +};
@@ -7206,12 +7289,12 @@ index 0000000..9ee58eb
 +module_exit(exit_unionfs_fs);
 diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
 new file mode 100644
-index 0000000..1f70535
+index 0000000..bcc5652
 --- /dev/null
 +++ b/fs/unionfs/mmap.c
 @@ -0,0 +1,89 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -7221,8 +7304,8 @@ index 0000000..1f70535
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -7301,12 +7384,12 @@ index 0000000..1f70535
 +};
 diff --git a/fs/unionfs/rdstate.c b/fs/unionfs/rdstate.c
 new file mode 100644
-index 0000000..d57f1f8
+index 0000000..59b7333
 --- /dev/null
 +++ b/fs/unionfs/rdstate.c
 @@ -0,0 +1,285 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -7315,8 +7398,8 @@ index 0000000..d57f1f8
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -7592,12 +7675,12 @@ index 0000000..d57f1f8
 +}
 diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
 new file mode 100644
-index 0000000..936700e
+index 0000000..c8ab910
 --- /dev/null
 +++ b/fs/unionfs/rename.c
-@@ -0,0 +1,517 @@
+@@ -0,0 +1,522 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -7606,8 +7689,8 @@ index 0000000..936700e
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -7626,6 +7709,7 @@ index 0000000..936700e
 +      struct dentry *lower_dentry;
 +      struct dentry *lower_parent;
 +      int err = 0;
++      struct nameidata lower_nd;
 +
 +      verify_locked(dentry);
 +
@@ -7633,8 +7717,12 @@ index 0000000..936700e
 +
 +      BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
 +
-+      lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
-+                                    dentry->d_name.len);
++      err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
++      if (unlikely(err < 0))
++              goto out;
++      lower_dentry = lookup_one_len_nd(dentry->d_name.name, lower_parent,
++                                       dentry->d_name.len, &lower_nd);
++      release_lower_nd(&lower_nd, err);
 +      if (IS_ERR(lower_dentry)) {
 +              err = PTR_ERR(lower_dentry);
 +              goto out;
@@ -8115,18 +8203,18 @@ index 0000000..936700e
 +}
 diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
 new file mode 100644
-index 0000000..760c580
+index 0000000..b923742
 --- /dev/null
 +++ b/fs/unionfs/sioq.c
 @@ -0,0 +1,101 @@
 +/*
-+ * Copyright (c) 2006-2010 Erez Zadok
++ * Copyright (c) 2006-2011 Erez Zadok
 + * Copyright (c) 2006      Charles P. Wright
 + * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2006      Junjiro Okajima
 + * Copyright (c) 2006      David P. Quigley
-+ * Copyright (c) 2006-2010 Stony Brook University
-+ * Copyright (c) 2006-2010 The Research Foundation of SUNY
++ * Copyright (c) 2006-2011 Stony Brook University
++ * Copyright (c) 2006-2011 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
@@ -8222,18 +8310,18 @@ index 0000000..760c580
 +}
 diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
 new file mode 100644
-index 0000000..b26d248
+index 0000000..c2dfb94
 --- /dev/null
 +++ b/fs/unionfs/sioq.h
 @@ -0,0 +1,91 @@
 +/*
-+ * Copyright (c) 2006-2010 Erez Zadok
++ * Copyright (c) 2006-2011 Erez Zadok
 + * Copyright (c) 2006      Charles P. Wright
 + * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2006      Junjiro Okajima
 + * Copyright (c) 2006      David P. Quigley
-+ * Copyright (c) 2006-2010 Stony Brook University
-+ * Copyright (c) 2006-2010 The Research Foundation of SUNY
++ * Copyright (c) 2006-2011 Stony Brook University
++ * Copyright (c) 2006-2011 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
@@ -8319,12 +8407,12 @@ index 0000000..b26d248
 +#endif /* not _SIOQ_H */
 diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
 new file mode 100644
-index 0000000..570a344
+index 0000000..bdca2f7
 --- /dev/null
 +++ b/fs/unionfs/subr.c
 @@ -0,0 +1,95 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -8333,8 +8421,8 @@ index 0000000..570a344
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -8420,12 +8508,12 @@ index 0000000..570a344
 +}
 diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
 new file mode 100644
-index 0000000..45bb9bf
+index 0000000..c3ac814
 --- /dev/null
 +++ b/fs/unionfs/super.c
-@@ -0,0 +1,1029 @@
+@@ -0,0 +1,1030 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -8434,8 +8522,8 @@ index 0000000..45bb9bf
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -8609,7 +8697,7 @@ index 0000000..45bb9bf
 +      int err = -EINVAL;
 +      int perms, idx;
 +      char *modename = strchr(optarg, '=');
-+      struct nameidata nd;
++      struct path path;
 +
 +      /* by now, optarg contains the branch name */
 +      if (!*optarg) {
@@ -8636,7 +8724,7 @@ index 0000000..45bb9bf
 +       * and cache-coherency resolved, we'll address the branch-path
 +       * uniqueness.
 +       */
-+      err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++      err = kern_path(optarg, LOOKUP_FOLLOW, &path);
 +      if (err) {
 +              printk(KERN_ERR "unionfs: error accessing "
 +                     "lower directory \"%s\" (error %d)\n",
@@ -8644,10 +8732,10 @@ index 0000000..45bb9bf
 +              goto out;
 +      }
 +      for (idx = 0; idx < cur_branches; idx++)
-+              if (nd.path.mnt == new_lower_paths[idx].mnt &&
-+                  nd.path.dentry == new_lower_paths[idx].dentry)
++              if (path.mnt == new_lower_paths[idx].mnt &&
++                  path.dentry == new_lower_paths[idx].dentry)
 +                      break;
-+      path_put(&nd.path);     /* no longer needed */
++      path_put(&path);        /* no longer needed */
 +      if (idx == cur_branches) {
 +              err = -ENOENT;  /* err may have been reset above */
 +              printk(KERN_ERR "unionfs: branch \"%s\" "
@@ -8670,7 +8758,7 @@ index 0000000..45bb9bf
 +{
 +      int err = -EINVAL;
 +      int idx;
-+      struct nameidata nd;
++      struct path path;
 +
 +      /* optarg contains the branch name to delete */
 +
@@ -8680,7 +8768,7 @@ index 0000000..45bb9bf
 +       * and cache-coherency resolved, we'll address the branch-path
 +       * uniqueness.
 +       */
-+      err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++      err = kern_path(optarg, LOOKUP_FOLLOW, &path);
 +      if (err) {
 +              printk(KERN_ERR "unionfs: error accessing "
 +                     "lower directory \"%s\" (error %d)\n",
@@ -8688,10 +8776,10 @@ index 0000000..45bb9bf
 +              goto out;
 +      }
 +      for (idx = 0; idx < cur_branches; idx++)
-+              if (nd.path.mnt == new_lower_paths[idx].mnt &&
-+                  nd.path.dentry == new_lower_paths[idx].dentry)
++              if (path.mnt == new_lower_paths[idx].mnt &&
++                  path.dentry == new_lower_paths[idx].dentry)
 +                      break;
-+      path_put(&nd.path);     /* no longer needed */
++      path_put(&path);        /* no longer needed */
 +      if (idx == cur_branches) {
 +              printk(KERN_ERR "unionfs: branch \"%s\" "
 +                     "not found\n", optarg);
@@ -8737,7 +8825,7 @@ index 0000000..45bb9bf
 +      int perms;
 +      int idx = 0;            /* default: insert at beginning */
 +      char *new_branch , *modename = NULL;
-+      struct nameidata nd;
++      struct path path;
 +
 +      /*
 +       * optarg can be of several forms:
@@ -8765,7 +8853,7 @@ index 0000000..45bb9bf
 +       * and cache-coherency resolved, we'll address the branch-path
 +       * uniqueness.
 +       */
-+      err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
++      err = kern_path(optarg, LOOKUP_FOLLOW, &path);
 +      if (err) {
 +              printk(KERN_ERR "unionfs: error accessing "
 +                     "lower directory \"%s\" (error %d)\n",
@@ -8773,10 +8861,10 @@ index 0000000..45bb9bf
 +              goto out;
 +      }
 +      for (idx = 0; idx < cur_branches; idx++)
-+              if (nd.path.mnt == new_lower_paths[idx].mnt &&
-+                  nd.path.dentry == new_lower_paths[idx].dentry)
++              if (path.mnt == new_lower_paths[idx].mnt &&
++                  path.dentry == new_lower_paths[idx].dentry)
 +                      break;
-+      path_put(&nd.path);     /* no longer needed */
++      path_put(&path);        /* no longer needed */
 +      if (idx == cur_branches) {
 +              printk(KERN_ERR "unionfs: branch \"%s\" "
 +                     "not found\n", optarg);
@@ -8805,7 +8893,7 @@ index 0000000..45bb9bf
 +                     "branch \"%s\"\n", modename, new_branch);
 +              goto out;
 +      }
-+      err = path_lookup(new_branch, LOOKUP_FOLLOW, &nd);
++      err = kern_path(new_branch, LOOKUP_FOLLOW, &path);
 +      if (err) {
 +              printk(KERN_ERR "unionfs: error accessing "
 +                     "lower directory \"%s\" (error %d)\n",
@@ -8819,11 +8907,11 @@ index 0000000..45bb9bf
 +       * because this code base doesn't support stacking unionfs: the ODF
 +       * code base supports that correctly.
 +       */
-+      err = check_branch(&nd);
++      err = check_branch(&path);
 +      if (err) {
 +              printk(KERN_ERR "unionfs: lower directory "
 +                     "\"%s\" is not a valid branch\n", optarg);
-+              path_put(&nd.path);
++              path_put(&path);
 +              goto out;
 +      }
 +
@@ -8840,10 +8928,10 @@ index 0000000..45bb9bf
 +              memmove(&new_lower_paths[idx+1], &new_lower_paths[idx],
 +                      (cur_branches - idx) * sizeof(struct path));
 +      }
-+      new_lower_paths[idx].dentry = nd.path.dentry;
-+      new_lower_paths[idx].mnt = nd.path.mnt;
++      new_lower_paths[idx].dentry = path.dentry;
++      new_lower_paths[idx].mnt = path.mnt;
 +
-+      new_data[idx].sb = nd.path.dentry->d_sb;
++      new_data[idx].sb = path.dentry->d_sb;
 +      atomic_set(&new_data[idx].open_files, 0);
 +      new_data[idx].branchperms = perms;
 +      new_data[idx].branch_id = ++*high_branch_id; /* assign new branch ID */
@@ -8995,10 +9083,10 @@ index 0000000..45bb9bf
 +              path_get(&tmp_lower_paths[i]); /* drop refs at end of fxn */
 +
 +      /*******************************************************************
-+       * For each branch command, do path_lookup on the requested branch,
++       * For each branch command, do kern_path on the requested branch,
 +       * and apply the change to a temp branch list.  To handle errors, we
 +       * already dup'ed the old arrays (above), and increased the refcnts
-+       * on various f/s objects.  So now we can do all the path_lookups
++       * on various f/s objects.  So now we can do all the kern_path'ss
 +       * and branch-management commands on the new arrays.  If it fail mid
 +       * way, we free the tmp arrays and *put all objects.  If we succeed,
 +       * then we free old arrays and *put its objects, and then replace
@@ -9400,8 +9488,9 @@ index 0000000..45bb9bf
 +      int bindex, bstart, bend;
 +      int perms;
 +
++      /* to prevent a silly lockdep warning with namespace_sem */
++      lockdep_off();
 +      unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
-+
 +      unionfs_lock_dentry(sb->s_root, UNIONFS_DMUTEX_CHILD);
 +
 +      tmp_page = (char *) __get_free_page(GFP_KERNEL);
@@ -9436,8 +9525,8 @@ index 0000000..45bb9bf
 +      free_page((unsigned long) tmp_page);
 +
 +      unionfs_unlock_dentry(sb->s_root);
-+
 +      unionfs_read_unlock(sb);
++      lockdep_on();
 +
 +      return ret;
 +}
@@ -9455,12 +9544,12 @@ index 0000000..45bb9bf
 +};
 diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
 new file mode 100644
-index 0000000..6c7b9aa
+index 0000000..1821705
 --- /dev/null
 +++ b/fs/unionfs/union.h
-@@ -0,0 +1,669 @@
+@@ -0,0 +1,679 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005      Arun M. Krishnakumar
@@ -9468,8 +9557,8 @@ index 0000000..6c7b9aa
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -9494,7 +9583,6 @@ index 0000000..6c7b9aa
 +#include <linux/seq_file.h>
 +#include <linux/slab.h>
 +#include <linux/spinlock.h>
-+#include <linux/smp_lock.h>
 +#include <linux/statfs.h>
 +#include <linux/string.h>
 +#include <linux/vmalloc.h>
@@ -9508,6 +9596,7 @@ index 0000000..6c7b9aa
 +#include <linux/mman.h>
 +#include <linux/backing-dev.h>
 +#include <linux/splice.h>
++#include <linux/sched.h>
 +
 +#include <asm/system.h>
 +
@@ -9998,7 +10087,7 @@ index 0000000..6c7b9aa
 +/*
 + * EXTERNALS:
 + */
-+extern int check_branch(struct nameidata *nd);
++extern int check_branch(const struct path *path);
 +extern int parse_branch_mode(const char *name, int *perms);
 +
 +/* locking helpers */
@@ -10027,9 +10116,19 @@ index 0000000..6c7b9aa
 +                                          struct dentry *base, int len)
 +{
 +      struct dentry *d;
++      struct nameidata lower_nd;
++      int err;
++
++      err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
++      if (unlikely(err < 0)) {
++              d = ERR_PTR(err);
++              goto out;
++      }
 +      mutex_lock(&base->d_inode->i_mutex);
-+      d = lookup_one_len(name, base, len);
++      d = lookup_one_len_nd(name, base, len, &lower_nd);
++      release_lower_nd(&lower_nd, err);
 +      mutex_unlock(&base->d_inode->i_mutex);
++out:
 +      return d;
 +}
 +
@@ -10130,12 +10229,12 @@ index 0000000..6c7b9aa
 +#endif        /* not _UNION_H_ */
 diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
 new file mode 100644
-index 0000000..542c513
+index 0000000..bf447bb
 --- /dev/null
 +++ b/fs/unionfs/unlink.c
 @@ -0,0 +1,278 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -10144,8 +10243,8 @@ index 0000000..542c513
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -10414,12 +10513,12 @@ index 0000000..542c513
 +}
 diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c
 new file mode 100644
-index 0000000..405073a
+index 0000000..582cef2
 --- /dev/null
 +++ b/fs/unionfs/whiteout.c
-@@ -0,0 +1,584 @@
+@@ -0,0 +1,601 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -10428,8 +10527,8 @@ index 0000000..405073a
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -10623,8 +10722,8 @@ index 0000000..405073a
 + * Checks to see if there's a whiteout in @lower_dentry's parent directory,
 + * whose name is taken from @dentry.  Then tries to remove that whiteout, if
 + * found.  If <dentry,bindex> is a branch marked readonly, return -EROFS.
-+ * If it finds both a regular file and a whiteout, return -EIO (this should
-+ * never happen).
++ * If it finds both a regular file and a whiteout, delete whiteout (this
++ * should never happen).
 + *
 + * Return 0 if no whiteout was found.  Return 1 if one was found and
 + * successfully removed.  Therefore a value >= 0 tells the caller that
@@ -10654,13 +10753,10 @@ index 0000000..405073a
 +      }
 +
 +      /* check if regular file and whiteout were both found */
-+      if (unlikely(lower_dentry->d_inode)) {
-+              err = -EIO;
-+              printk(KERN_ERR "unionfs: found both whiteout and regular "
-+                     "file in directory %s (branch %d)\n",
++      if (unlikely(lower_dentry->d_inode))
++              printk(KERN_WARNING "unionfs: removing whiteout; regular "
++                     "file exists in directory %s (branch %d)\n",
 +                     lower_dir_dentry->d_name.name, bindex);
-+              goto out_dput;
-+      }
 +
 +      /* check if branch is writeable */
 +      err = is_robranch_super(dentry->d_sb, bindex);
@@ -10904,6 +11000,7 @@ index 0000000..405073a
 +      struct dentry *wh_lower_dentry;
 +      struct inode *lower_inode;
 +      struct sioq_args args;
++      struct nameidata lower_nd;
 +
 +      lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
 +      lower_inode = lower_dentry->d_inode;
@@ -10913,9 +11010,16 @@ index 0000000..405073a
 +      mutex_lock(&lower_inode->i_mutex);
 +
 +      if (!inode_permission(lower_inode, MAY_EXEC)) {
++              err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
++              if (unlikely(err < 0)) {
++                      mutex_unlock(&lower_inode->i_mutex);
++                      goto out;
++              }
 +              wh_lower_dentry =
-+                      lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
-+                                     sizeof(UNIONFS_DIR_OPAQUE) - 1);
++                      lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry,
++                                        sizeof(UNIONFS_DIR_OPAQUE) - 1,
++                                        &lower_nd);
++              release_lower_nd(&lower_nd, err);
 +      } else {
 +              args.is_opaque.dentry = lower_dentry;
 +              run_sioq(__is_opaque_dir, &args);
@@ -10940,9 +11044,17 @@ index 0000000..405073a
 +void __is_opaque_dir(struct work_struct *work)
 +{
 +      struct sioq_args *args = container_of(work, struct sioq_args, work);
++      struct nameidata lower_nd;
++      int err;
 +
-+      args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->is_opaque.dentry,
-+                                 sizeof(UNIONFS_DIR_OPAQUE) - 1);
++      err = init_lower_nd(&lower_nd, LOOKUP_OPEN);
++      if (unlikely(err < 0))
++              return;
++      args->ret = lookup_one_len_nd(UNIONFS_DIR_OPAQUE,
++                                    args->is_opaque.dentry,
++                                    sizeof(UNIONFS_DIR_OPAQUE) - 1,
++                                    &lower_nd);
++      release_lower_nd(&lower_nd, err);
 +      complete(&args->comp);
 +}
 +
@@ -10978,8 +11090,12 @@ index 0000000..405073a
 +             !S_ISDIR(lower_dir->i_mode));
 +
 +      mutex_lock(&lower_dir->i_mutex);
-+      diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
-+                              sizeof(UNIONFS_DIR_OPAQUE) - 1);
++      err = init_lower_nd(&nd, LOOKUP_OPEN);
++      if (unlikely(err < 0))
++              goto out;
++      diropq = lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry,
++                                 sizeof(UNIONFS_DIR_OPAQUE) - 1, &nd);
++      release_lower_nd(&nd, err);
 +      if (IS_ERR(diropq)) {
 +              err = PTR_ERR(diropq);
 +              goto out;
@@ -11004,12 +11120,12 @@ index 0000000..405073a
 +}
 diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c
 new file mode 100644
-index 0000000..9002e06
+index 0000000..a93d803
 --- /dev/null
 +++ b/fs/unionfs/xattr.c
 @@ -0,0 +1,173 @@
 +/*
-+ * Copyright (c) 2003-2010 Erez Zadok
++ * Copyright (c) 2003-2011 Erez Zadok
 + * Copyright (c) 2003-2006 Charles P. Wright
 + * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
 + * Copyright (c) 2005-2006 Junjiro Okajima
@@ -11018,8 +11134,8 @@ index 0000000..9002e06
 + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
 + * Copyright (c) 2003      Puja Gupta
 + * Copyright (c) 2003      Harikesavan Krishnan
-+ * Copyright (c) 2003-2010 Stony Brook University
-+ * Copyright (c) 2003-2010 The Research Foundation of SUNY
++ * Copyright (c) 2003-2011 Stony Brook University
++ * Copyright (c) 2003-2011 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
@@ -11207,10 +11323,10 @@ index da317c7..64f1ced 100644
   */
  
 diff --git a/include/linux/magic.h b/include/linux/magic.h
-index 62730ea..bd9832b 100644
+index 1e5df2a..01ee54d 100644
 --- a/include/linux/magic.h
 +++ b/include/linux/magic.h
-@@ -48,6 +48,8 @@
+@@ -50,6 +50,8 @@
  #define REISER2FS_SUPER_MAGIC_STRING  "ReIsEr2Fs"
  #define REISER2FS_JR_SUPER_MAGIC_STRING       "ReIsEr3Fs"
  
@@ -11220,17 +11336,21 @@ index 62730ea..bd9832b 100644
  #define USBDEVICE_SUPER_MAGIC 0x9fa2
  #define CGROUP_SUPER_MAGIC    0x27e0eb
 diff --git a/include/linux/namei.h b/include/linux/namei.h
-index f276d4f..cf4ec6c 100644
+index eba45ea..8e19e9c 100644
 --- a/include/linux/namei.h
 +++ b/include/linux/namei.h
-@@ -78,6 +78,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+@@ -81,8 +81,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 *));
 +extern void release_open_intent(struct nameidata *);
  
  extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
++extern struct dentry *lookup_one_len_nd(const char *, struct dentry *, int,
++                                    struct nameidata *nd);
  
+ 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
 --- a/include/linux/splice.h
@@ -11276,30 +11396,14 @@ index 0000000..c84d97e
 +#endif /* _LINUX_UNIONFS_H */
 +
 diff --git a/security/security.c b/security/security.c
-index 7b7308a..abdb5a5 100644
+index 4ba6d4c..093d8b4 100644
 --- a/security/security.c
 +++ b/security/security.c
-@@ -511,6 +511,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -520,6 +520,7 @@ int security_inode_permission(struct inode *inode, int mask)
                return 0;
-       return security_ops->inode_permission(inode, mask);
+       return security_ops->inode_permission(inode, mask, 0);
  }
 +EXPORT_SYMBOL(security_inode_permission);
  
  int security_inode_exec_permission(struct inode *inode, unsigned int flags)
  {
-diff -purN orig/fs/unionfs/commonfops.c linux-2.6.36/fs/unionfs/commonfops.c
---- orig/fs/unionfs/commonfops.c       2010-10-21 16:29:51.033693283 -0400
-+++ linux-2.6.36/fs/unionfs/commonfops.c       2010-10-27 10:15:30.337131546 -0400
-@@ -740,10 +740,8 @@ static long do_ioctl(struct file *file, 
-       if (lower_file->f_op->unlocked_ioctl) {
-               err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
- #ifdef CONFIG_COMPAT
--      } else if (lower_file->f_op->ioctl) {
--              err = lower_file->f_op->compat_ioctl(
--                      lower_file->f_path.dentry->d_inode,
--                      lower_file, cmd, arg);
-+      } else if (lower_file->f_op->compat_ioctl) {
-+              err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
- #endif
-       }
\ No newline at end of file
This page took 0.146114 seconds and 4 git commands to generate.