Unionfs: port to 3.6
authorErez Zadok <ezk@cs.sunysb.edu>
Wed, 27 Nov 2013 03:01:34 +0000 (22:01 -0500)
committerErez Zadok <ezk@cs.sunysb.edu>
Tue, 11 Nov 2014 01:24:35 +0000 (20:24 -0500)
Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
17 files changed:
fs/namei.c
fs/unionfs/commonfops.c
fs/unionfs/copyup.c
fs/unionfs/debug.c
fs/unionfs/dentry.c
fs/unionfs/dirhelper.c
fs/unionfs/inode.c
fs/unionfs/lookup.c
fs/unionfs/rename.c
fs/unionfs/sioq.c
fs/unionfs/sioq.h
fs/unionfs/super.c
fs/unionfs/union.h
fs/unionfs/unlink.c
fs/unionfs/whiteout.c
fs/unionfs/xattr.c
include/linux/namei.h

index 4c5b1e54e3123a71675898543821e48004e699eb..dd2f2c5bda557d685cf8b14ecbc0f8fc4abcb97c 100644 (file)
@@ -4418,7 +4418,6 @@ EXPORT_SYMBOL(follow_up);
 EXPORT_SYMBOL(get_write_access); /* nfsd */
 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);
index 970b252b7d8847525d4815fd1d9367a891687c2a..9dc89e16c95660de3db992cf22d56eee7ef33a9b 100644 (file)
@@ -210,6 +210,7 @@ static int open_all_files(struct file *file)
        struct dentry *lower_dentry;
        struct dentry *dentry = file->f_path.dentry;
        struct super_block *sb = dentry->d_sb;
+       struct path path;
 
        bstart = dbstart(dentry);
        bend = dbend(dentry);
@@ -223,10 +224,10 @@ static int open_all_files(struct file *file)
                unionfs_mntget(dentry, bindex);
                branchget(sb, bindex);
 
-               lower_file =
-                       dentry_open(lower_dentry,
-                                   unionfs_lower_mnt_idx(dentry, bindex),
-                                   file->f_flags, current_cred());
+               path.dentry = lower_dentry;
+               path.mnt = unionfs_lower_mnt_idx(dentry, bindex);
+               lower_file = dentry_open(&path, file->f_flags, current_cred());
+               path_put(&path);
                if (IS_ERR(lower_file)) {
                        branchput(sb, bindex);
                        err = PTR_ERR(lower_file);
@@ -249,6 +250,7 @@ static int open_highest_file(struct file *file, bool willwrite)
        struct dentry *parent = dget_parent(dentry);
        struct inode *parent_inode = parent->d_inode;
        struct super_block *sb = dentry->d_sb;
+       struct path path;
 
        bstart = dbstart(dentry);
        bend = dbend(dentry);
@@ -269,9 +271,10 @@ static int open_highest_file(struct file *file, bool willwrite)
 
        dget(lower_dentry);
        unionfs_mntget(dentry, bstart);
-       lower_file = dentry_open(lower_dentry,
-                                unionfs_lower_mnt_idx(dentry, bstart),
-                                file->f_flags, current_cred());
+       path.dentry = lower_dentry;
+       path.mnt = unionfs_lower_mnt_idx(dentry, bstart);
+       lower_file = dentry_open(&path, file->f_flags, current_cred());
+       path_put(&path);
        if (IS_ERR(lower_file)) {
                err = PTR_ERR(lower_file);
                goto out;
@@ -464,7 +467,7 @@ int unionfs_file_revalidate(struct file *file, struct dentry *parent,
         * but not unhashed dentries.
         */
        if (!d_deleted(dentry) &&
-           !__unionfs_d_revalidate(dentry, parent, willwrite)) {
+           !__unionfs_d_revalidate(dentry, parent, willwrite, 0)) {
                err = -ESTALE;
                goto out;
        }
@@ -494,6 +497,7 @@ static int __open_dir(struct inode *inode, struct file *file,
        int bindex, bstart, bend;
        struct vfsmount *lower_mnt;
        struct dentry *dentry = file->f_path.dentry;
+       struct path path;
 
        bstart = fbstart(file) = dbstart(dentry);
        bend = fbend(file) = dbend(dentry);
@@ -508,8 +512,10 @@ static int __open_dir(struct inode *inode, struct file *file,
                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());
+               path.dentry = lower_dentry;
+               path.mnt = lower_mnt;
+               lower_file = dentry_open(&path, file->f_flags, current_cred());
+               path_put(&path);
                if (IS_ERR(lower_file))
                        return PTR_ERR(lower_file);
 
@@ -537,6 +543,7 @@ static int __open_file(struct inode *inode, struct file *file,
        int bindex, bstart, bend;
        struct dentry *dentry = file->f_path.dentry;
        struct vfsmount *lower_mnt;
+       struct path path;
 
        lower_dentry = unionfs_lower_dentry(dentry);
        lower_flags = file->f_flags;
@@ -580,12 +587,14 @@ static int __open_file(struct inode *inode, struct file *file,
        dget(lower_dentry);
 
        /*
-        * dentry_open will decrement mnt refcnt if err.
+        * dentry_open used to decrement mnt refcnt if err.
         * otherwise fput() will do an mntput() for us upon file close.
         */
        lower_mnt = unionfs_mntget(dentry, bstart);
-       lower_file = dentry_open(lower_dentry, lower_mnt, lower_flags,
-                                current_cred());
+       path.dentry = lower_dentry;
+       path.mnt = lower_mnt;
+       lower_file = dentry_open(&path, lower_flags, current_cred());
+       path_put(&path);
        if (IS_ERR(lower_file))
                return PTR_ERR(lower_file);
 
@@ -616,7 +625,7 @@ int unionfs_open(struct inode *inode, struct file *file)
        }
 
        /* XXX: should I change 'false' below to the 'willwrite' flag? */
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out_nofree;
index 078ca2740884bf989eb3c43b9f29e6ece60d1e03..6b24957e8454b638fff0b447327ff3b12bacaf50 100644 (file)
@@ -206,25 +206,19 @@ static int __copyup_ndentry(struct dentry *old_lower_dentry,
                run_sioq(__unionfs_mknod, &args);
                err = args.err;
        } else if (S_ISREG(old_mode)) {
-               struct nameidata nd;
-               err = init_lower_nd(&nd, LOOKUP_CREATE);
-               if (unlikely(err < 0))
-                       goto out;
-               args.create.nd = &nd;
                args.create.parent = new_lower_parent_dentry->d_inode;
                args.create.dentry = new_lower_dentry;
                args.create.mode = old_mode;
+               args.create.want_excl = false; /* XXX: pass to this fxn */
 
                run_sioq(__unionfs_create, &args);
                err = args.err;
-               release_lower_nd(&nd, err);
        } else {
                printk(KERN_CRIT "unionfs: unknown inode type %d\n",
                       old_mode);
                BUG();
        }
 
-out:
        return err;
 }
 
@@ -242,14 +236,17 @@ static int __copyup_reg_data(struct dentry *dentry,
        ssize_t read_bytes, write_bytes;
        loff_t size;
        int err = 0;
+       struct path input_path, output_path;
 
        /* open old file */
        unionfs_mntget(dentry, old_bindex);
        branchget(sb, old_bindex);
-       /* dentry_open calls dput and mntput if it returns an error */
-       input_file = dentry_open(old_lower_dentry,
-                                unionfs_lower_mnt_idx(dentry, old_bindex),
+       /* dentry_open used to call dput and mntput if it returns an error */
+       input_path.dentry = old_lower_dentry;
+       input_path.mnt = unionfs_lower_mnt_idx(dentry, old_bindex);
+       input_file = dentry_open(&input_path,
                                 O_RDONLY | O_LARGEFILE, current_cred());
+       path_put(&input_path);
        if (IS_ERR(input_file)) {
                dput(old_lower_dentry);
                err = PTR_ERR(input_file);
@@ -264,8 +261,11 @@ static int __copyup_reg_data(struct dentry *dentry,
        dget(new_lower_dentry);
        output_mnt = unionfs_mntget(sb->s_root, new_bindex);
        branchget(sb, new_bindex);
-       output_file = dentry_open(new_lower_dentry, output_mnt,
+       output_path.dentry = new_lower_dentry;
+       output_path.mnt = output_mnt;
+       output_file = dentry_open(&output_path,
                                  O_RDWR | O_LARGEFILE, current_cred());
+       path_put(&output_path);
        if (IS_ERR(output_file)) {
                err = PTR_ERR(output_file);
                goto out_close_in2;
index 21ce90cbcf8a6a03a2f6618e4a51c72587a44430..5c000be0b39f7ca0c8209db5fd150e08fcca94b6 100644 (file)
@@ -424,26 +424,6 @@ void __unionfs_check_file(const struct file *file,
        __unionfs_check_dentry(dentry, fname, fxn, line);
 }
 
-void __unionfs_check_nd(const struct nameidata *nd,
-                       const char *fname, const char *fxn, int line)
-{
-       struct file *file;
-       int printed_caller = 0;
-
-       if (unlikely(!nd))
-               return;
-       if (nd->flags & LOOKUP_OPEN) {
-               file = nd->intent.open.file;
-               if (unlikely(file->f_path.dentry &&
-                            strcmp(file->f_path.dentry->d_sb->s_type->name,
-                                   UNIONFS_NAME))) {
-                       PRINT_CALLER(fname, fxn, line);
-                       pr_debug(" CND1: lower_file of type %s\n",
-                                file->f_path.dentry->d_sb->s_type->name);
-               }
-       }
-}
-
 static unsigned int __mnt_get_count(struct vfsmount *mnt)
 {
        struct mount *m = real_mount(mnt);
index 1628dad90500832d41c83c38b33dc4cb6584edd9..2183e5c3e7364017fde3bd6cac1da961065b0136 100644 (file)
@@ -80,7 +80,7 @@ static inline void purge_inode_data(struct inode *inode)
  * dentry).  Returns true if valid, false otherwise.
  */
 bool __unionfs_d_revalidate(struct dentry *dentry, struct dentry *parent,
-                           bool willwrite)
+                           bool willwrite, unsigned int flags)
 {
        bool valid = true;      /* default is valid */
        struct dentry *lower_dentry;
@@ -192,29 +192,12 @@ validate_lowers:
        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)
                        continue;
-               /*
-                * Don't pass nameidata to lower file system, because we
-                * don't want an arbitrary lower file being opened or
-                * returned to us: it may be useless to us because of the
-                * fanout nature of unionfs (cf. file/directory open-file
-                * invariants).  We will open lower files as and when needed
-                * later on.
-                */
-               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))
+               if (!lower_dentry->d_op->d_revalidate(lower_dentry, flags))
                        valid = false;
-               release_lower_nd(&lower_nd, err);
        }
 
        if (!dentry->d_inode ||
@@ -314,21 +297,20 @@ bool is_newer_lower(const struct dentry *dentry)
        return false;           /* default: lower is not newer */
 }
 
-static int unionfs_d_revalidate(struct dentry *dentry,
-                               struct nameidata *nd)
+static int unionfs_d_revalidate(struct dentry *dentry, unsigned int flags)
 {
        bool valid = true;
        int err = 1;            /* 1 means valid for the VFS */
        struct dentry *parent;
 
-       if (nd && nd->flags & LOOKUP_RCU)
+       if (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);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, flags);
        if (valid) {
                unionfs_postcopyup_setmnt(dentry);
                unionfs_check_dentry(dentry);
index 62ec9af38eb91dee739ad8ab27a38d1da3718d8a..bd1c1fcf3249842e1dd69a3965df2fe2c237d895 100644 (file)
@@ -78,6 +78,7 @@ int check_empty(struct dentry *dentry, struct dentry *parent,
        struct file *lower_file;
        struct unionfs_rdutil_callback *buf = NULL;
        int bindex, bstart, bend, bopaque;
+       struct path path;
 
        sb = dentry->d_sb;
 
@@ -120,7 +121,10 @@ int check_empty(struct dentry *dentry, struct dentry *parent,
                dget(lower_dentry);
                mnt = unionfs_mntget(dentry, bindex);
                branchget(sb, bindex);
-               lower_file = dentry_open(lower_dentry, mnt, O_RDONLY, current_cred());
+               path.dentry = lower_dentry;
+               path.mnt = mnt;
+               lower_file = dentry_open(&path, O_RDONLY, current_cred());
+               path_put(&path);
                if (IS_ERR(lower_file)) {
                        err = PTR_ERR(lower_file);
                        branchput(sb, bindex);
index dd522c2054ed9e43224b9bd80c1bb505b718b175..f25703ccd4001116b0eda93d6679897611a7cdf1 100644 (file)
@@ -97,20 +97,19 @@ out:
 }
 
 static int unionfs_create(struct inode *dir, struct dentry *dentry,
-                         umode_t mode, struct nameidata *nd_unused)
+                         umode_t mode, bool want_excl)
 {
        int err = 0;
        struct dentry *lower_dentry = NULL;
        struct dentry *lower_parent_dentry = NULL;
        struct dentry *parent;
        int valid = 0;
-       struct nameidata lower_nd;
 
        unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;  /* same as what real_lookup does */
                goto out;
@@ -128,13 +127,8 @@ static int unionfs_create(struct inode *dir, struct dentry *dentry,
                goto out_unlock;
        }
 
-       err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
-       if (unlikely(err < 0))
-               goto out_unlock;
        err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
-                        &lower_nd);
-       release_lower_nd(&lower_nd, err);
-
+                        want_excl);
        if (!err) {
                err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0));
                if (!err) {
@@ -167,7 +161,8 @@ out:
  */
 static struct dentry *unionfs_lookup(struct inode *dir,
                                     struct dentry *dentry,
-                                    struct nameidata *nd_unused)
+                                    /* XXX: pass flags to lower? */
+                                    unsigned int flags_unused)
 {
        struct dentry *ret, *parent;
        int err = 0;
@@ -231,13 +226,13 @@ static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
        unionfs_double_lock_parents(old_parent, new_parent);
        unionfs_double_lock_dentry(old_dentry, new_dentry);
 
-       valid = __unionfs_d_revalidate(old_dentry, old_parent, false);
+       valid = __unionfs_d_revalidate(old_dentry, old_parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
        }
        if (new_dentry->d_inode) {
-               valid = __unionfs_d_revalidate(new_dentry, new_parent, false);
+               valid = __unionfs_d_revalidate(new_dentry, new_parent, false, 0);
                if (unlikely(!valid)) {
                        err = -ESTALE;
                        goto out;
@@ -370,7 +365,7 @@ static int unionfs_symlink(struct inode *dir, struct dentry *dentry,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -438,7 +433,7 @@ static int unionfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;  /* same as what real_lookup does */
                goto out;
@@ -563,7 +558,7 @@ static int unionfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -651,7 +646,7 @@ static int unionfs_readlink(struct dentry *dentry, char __user *buf,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) {
+       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false, 0))) {
                err = -ESTALE;
                goto out;
        }
@@ -700,10 +695,8 @@ static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd)
        err = 0;
 
 out:
-       if (err >= 0) {
-               unionfs_check_nd(nd);
+       if (err >= 0)
                unionfs_check_dentry(dentry);
-       }
 
        unionfs_unlock_dentry(dentry);
        unionfs_unlock_parent(dentry, parent);
@@ -723,15 +716,11 @@ static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false)))
+       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false, 0)))
                printk(KERN_ERR
                       "unionfs: put_link failed to revalidate dentry\n");
 
        unionfs_check_dentry(dentry);
-#if 0
-       /* XXX: can't run this check b/c this fxn can receive a poisoned 'nd' PTR */
-       unionfs_check_nd(nd);
-#endif
        buf = nd_get_link(nd);
        if (!IS_ERR(buf))
                kfree(buf);
@@ -908,7 +897,7 @@ static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) {
+       if (unlikely(!__unionfs_d_revalidate(dentry, parent, false, 0))) {
                err = -ESTALE;
                goto out;
        }
index 041d674279a411789f4c016dba4231efc07d0d7f..005a5c86194677094feb14076675e6476d94c820 100644 (file)
@@ -206,75 +206,6 @@ void update_bstart(struct dentry *dentry)
        }
 }
 
-
-/*
- * Initialize a nameidata structure (the intent part) we can pass to a lower
- * file system.  Returns 0 on success or -error (only -ENOMEM possible).
- * Inside that nd structure, this function may also return an allocated
- * struct file (for open intents).  The caller, when done with this nd, must
- * kfree the intent file (using release_lower_nd).
- *
- * XXX: this code, and the callers of this code, should be redone using
- * vfs_path_lookup() when (1) the nameidata structure is refactored into a
- * separate intent-structure, and (2) open_namei() is broken into a VFS-only
- * function and a method that other file systems can call.
- */
-int init_lower_nd(struct nameidata *nd, unsigned int flags)
-{
-       int err = 0;
-#ifdef ALLOC_LOWER_ND_FILE
-       /*
-        * XXX: one day we may need to have the lower return an open file
-        * for us.  It is not needed in 2.6.23-rc1 for nfs2/nfs3, but may
-        * very well be needed for nfs4.
-        */
-       struct file *file;
-#endif /* ALLOC_LOWER_ND_FILE */
-
-       memset(nd, 0, sizeof(struct nameidata));
-       if (!flags)
-               return err;
-
-       switch (flags) {
-       case LOOKUP_CREATE:
-               nd->intent.open.flags |= O_CREAT;
-               /* fall through: shared code for create/open cases */
-       case LOOKUP_OPEN:
-               nd->flags = flags;
-               nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE);
-#ifdef ALLOC_LOWER_ND_FILE
-               file = kzalloc(sizeof(struct file), GFP_KERNEL);
-               if (unlikely(!file)) {
-                       err = -ENOMEM;
-                       break; /* exit switch statement and thus return */
-               }
-               nd->intent.open.file = file;
-#endif /* ALLOC_LOWER_ND_FILE */
-               break;
-       default:
-               /*
-                * We should never get here, for now.
-                * We can add new cases here later on.
-                */
-               pr_debug("unionfs: unknown nameidata flag 0x%x\n", flags);
-               BUG();
-               break;
-       }
-
-       return err;
-}
-
-void release_lower_nd(struct nameidata *nd, int err)
-{
-       if (!nd->intent.open.file)
-               return;
-       else if (!err)
-               release_open_intent(nd);
-#ifdef ALLOC_LOWER_ND_FILE
-       kfree(nd->intent.open.file);
-#endif /* ALLOC_LOWER_ND_FILE */
-}
-
 /*
  * Main (and complex) driver function for Unionfs's lookup
  *
index ce85b8421177bb8870ce6103d584c065dcbd11ba..912c1e9e33d974d9f33af7f3c69937f71daff63d 100644 (file)
@@ -28,7 +28,6 @@ static int unionfs_refresh_lower_dentry(struct dentry *dentry,
        struct dentry *lower_dentry;
        struct dentry *lower_parent;
        int err = 0;
-       struct nameidata lower_nd;
 
        verify_locked(dentry);
 
@@ -36,12 +35,8 @@ static int unionfs_refresh_lower_dentry(struct dentry *dentry,
 
        BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
 
-       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);
+       lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
+                                     dentry->d_name.len); // XXX: pass flags?
        if (IS_ERR(lower_dentry)) {
                err = PTR_ERR(lower_dentry);
                goto out;
@@ -403,13 +398,13 @@ int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                unionfs_lock_dentry(new_parent, UNIONFS_DMUTEX_REVAL_CHILD);
        unionfs_double_lock_dentry(old_dentry, new_dentry);
 
-       valid = __unionfs_d_revalidate(old_dentry, old_parent, false);
+       valid = __unionfs_d_revalidate(old_dentry, old_parent, false, 0);
        if (!valid) {
                err = -ESTALE;
                goto out;
        }
        if (!d_deleted(new_dentry) && new_dentry->d_inode) {
-               valid = __unionfs_d_revalidate(new_dentry, new_parent, false);
+               valid = __unionfs_d_revalidate(new_dentry, new_parent, false, 0);
                if (!valid) {
                        err = -ESTALE;
                        goto out;
index b923742046d497bc4de38f5db6119ee0c2304887..3c8eb77037924d46e2a72f8950c82cb8d13bdf75 100644 (file)
@@ -60,7 +60,7 @@ void __unionfs_create(struct work_struct *work)
        struct sioq_args *args = container_of(work, struct sioq_args, work);
        struct create_args *c = &args->create;
 
-       args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd);
+       args->err = vfs_create(c->parent, c->dentry, c->mode, c->want_excl);
        complete(&args->comp);
 }
 
index c2dfb9444505e75210b72a2ce1167d0a4e81d4e1..2b465c56133e8b76c46ab0f4b5ebc08721e9b1e1 100644 (file)
@@ -29,7 +29,7 @@ struct create_args {
        struct inode *parent;
        struct dentry *dentry;
        umode_t mode;
-       struct nameidata *nd;
+       bool want_excl;
 };
 
 struct mkdir_args {
index 53d289b19c39131077237adad7f0e3416fd6ba54..8ad2595c015750a472628868eca47b57584a9b17 100644 (file)
@@ -135,7 +135,7 @@ static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
index f074970581bd4afbebbcbccf04cff6eecec6deff..6c21093b0f1efef3b524c9b4b734e7b786241d6f 100644 (file)
@@ -347,8 +347,6 @@ extern int new_dentry_private_data(struct dentry *dentry, int subclass);
 extern int realloc_dentry_private_data(struct dentry *dentry);
 extern void free_dentry_private_data(struct dentry *dentry);
 extern void update_bstart(struct dentry *dentry);
-extern int init_lower_nd(struct nameidata *nd, unsigned int flags);
-extern void release_lower_nd(struct nameidata *nd, int err);
 
 /*
  * EXTERNALS:
@@ -426,7 +424,8 @@ extern int unionfs_unlink(struct inode *dir, struct dentry *dentry);
 extern int unionfs_rmdir(struct inode *dir, struct dentry *dentry);
 
 extern bool __unionfs_d_revalidate(struct dentry *dentry,
-                                  struct dentry *parent, bool willwrite);
+                                  struct dentry *parent, bool willwrite,
+                                  unsigned int flags);
 extern bool is_negative_lower(const struct dentry *dentry);
 extern bool is_newer_lower(const struct dentry *dentry);
 extern void purge_sb_data(struct super_block *sb);
@@ -565,19 +564,11 @@ static inline struct dentry *lookup_lck_len(const char *name,
                                            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_nd(name, base, len, &lower_nd);
-       release_lower_nd(&lower_nd, err);
+       d = lookup_one_len(name, base, len); // XXX: pass flags?
        mutex_unlock(&base->d_inode->i_mutex);
-out:
+
        return d;
 }
 
@@ -650,8 +641,6 @@ extern void __unionfs_check_dentry(const struct dentry *dentry,
                                   int line);
 extern void __unionfs_check_file(const struct file *file,
                                 const char *fname, const char *fxn, int line);
-extern void __unionfs_check_nd(const struct nameidata *nd,
-                              const char *fname, const char *fxn, int line);
 extern void __show_branch_counts(const struct super_block *sb,
                                 const char *file, const char *fxn, int line);
 extern void __show_inode_times(const struct inode *inode,
index 25943a5643f565546e87e7b6c4e97b07966f8811..50cbd546a7a1421a8bf7038401d94a721d9df5a0 100644 (file)
@@ -132,7 +132,7 @@ int unionfs_unlink(struct inode *dir, struct dentry *dentry)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -210,7 +210,7 @@ int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
index 582cef285dd83c4d817b6fbcd8297f126b1d7eec..41c9b09f7df93eba108a9240416d3944fb4a9b00 100644 (file)
@@ -265,7 +265,6 @@ int create_whiteout(struct dentry *dentry, int start)
        struct dentry *lower_dir_dentry;
        struct dentry *lower_dentry;
        struct dentry *lower_wh_dentry;
-       struct nameidata nd;
        char *name = NULL;
        int err = -EINVAL;
 
@@ -323,19 +322,15 @@ int create_whiteout(struct dentry *dentry, int start)
                        goto out;
                }
 
-               err = init_lower_nd(&nd, LOOKUP_CREATE);
-               if (unlikely(err < 0))
-                       goto out;
                lower_dir_dentry = lock_parent_wh(lower_wh_dentry);
                err = is_robranch_super(dentry->d_sb, bindex);
                if (!err)
                        err = vfs_create(lower_dir_dentry->d_inode,
                                         lower_wh_dentry,
                                         current_umask() & S_IRUGO,
-                                        &nd);
+                                        0); // XXX: pass want_excl?
                unlock_dir(lower_dir_dentry);
                dput(lower_wh_dentry);
-               release_lower_nd(&nd, err);
 
                if (!err || !IS_COPYUP_ERR(err))
                        break;
@@ -481,7 +476,6 @@ int is_opaque_dir(struct dentry *dentry, int bindex)
        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;
@@ -491,16 +485,9 @@ int is_opaque_dir(struct dentry *dentry, int bindex)
        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_nd(UNIONFS_DIR_OPAQUE, lower_dentry,
-                                         sizeof(UNIONFS_DIR_OPAQUE) - 1,
-                                         &lower_nd);
-               release_lower_nd(&lower_nd, err);
+                       lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
+                                      sizeof(UNIONFS_DIR_OPAQUE) - 1); // XXX: pass flags?
        } else {
                args.is_opaque.dentry = lower_dentry;
                run_sioq(__is_opaque_dir, &args);
@@ -525,17 +512,10 @@ out:
 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;
 
-       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);
+       args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE,
+                                  args->is_opaque.dentry,
+                                  sizeof(UNIONFS_DIR_OPAQUE) - 1); // XXX: pass flags?
        complete(&args->comp);
 }
 
@@ -544,7 +524,6 @@ int make_dir_opaque(struct dentry *dentry, int bindex)
        int err = 0;
        struct dentry *lower_dentry, *diropq;
        struct inode *lower_dir;
-       struct nameidata nd;
        const struct cred *old_creds;
        struct cred *new_creds;
 
@@ -571,25 +550,17 @@ int make_dir_opaque(struct dentry *dentry, int bindex)
               !S_ISDIR(lower_dir->i_mode));
 
        mutex_lock(&lower_dir->i_mutex);
-       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);
+       diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
+                               sizeof(UNIONFS_DIR_OPAQUE) - 1); // XXX: pass flags?
        if (IS_ERR(diropq)) {
                err = PTR_ERR(diropq);
                goto out;
        }
 
-       err = init_lower_nd(&nd, LOOKUP_CREATE);
-       if (unlikely(err < 0))
-               goto out;
        if (!diropq->d_inode)
-               err = vfs_create(lower_dir, diropq, S_IRUGO, &nd);
+               err = vfs_create(lower_dir, diropq, S_IRUGO, 0); // XXX: pass want_excl?
        if (!err)
                dbopaque(dentry) = bindex;
-       release_lower_nd(&nd, err);
 
        dput(diropq);
 
index a93d8036f8e976280839ebe2ba82ad07f4d2c35b..84063dd6ce17ddab4cc90824dfb249f89f6bf862 100644 (file)
@@ -51,7 +51,7 @@ ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, void *value,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -85,7 +85,7 @@ int unionfs_setxattr(struct dentry *dentry, const char *name,
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -119,7 +119,7 @@ int unionfs_removexattr(struct dentry *dentry, const char *name)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
@@ -153,7 +153,7 @@ ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size)
        parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
        unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
 
-       valid = __unionfs_d_revalidate(dentry, parent, false);
+       valid = __unionfs_d_revalidate(dentry, parent, false, 0);
        if (unlikely(!valid)) {
                err = -ESTALE;
                goto out;
index 34fbc2d33966ddc535e2ee1c92092367c818afd5..492de72560fab98591ca7ca617380b7d581e5c13 100644 (file)
@@ -73,8 +73,6 @@ extern struct dentry *kern_path_locked(const char *, struct path *);
 extern int kern_path_mountpoint(int, const char *, struct path *, unsigned int);
 
 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 *);