From b893b3ffd8580daf181b0180622bb9bdcfc2842b Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Tue, 26 Nov 2013 22:01:34 -0500 Subject: [PATCH] Unionfs: port to 3.6 Signed-off-by: Erez Zadok --- fs/unionfs/commonfops.c | 37 +++++++++++++--------- fs/unionfs/copyup.c | 22 ++++++------- fs/unionfs/debug.c | 20 ------------ fs/unionfs/dentry.c | 28 +++-------------- fs/unionfs/dirhelper.c | 6 +++- fs/unionfs/inode.c | 39 +++++++++-------------- fs/unionfs/lookup.c | 69 ----------------------------------------- fs/unionfs/rename.c | 13 +++----- fs/unionfs/sioq.c | 2 +- fs/unionfs/sioq.h | 2 +- fs/unionfs/super.c | 2 +- fs/unionfs/union.h | 19 +++--------- fs/unionfs/unlink.c | 4 +-- fs/unionfs/whiteout.c | 47 ++++++---------------------- fs/unionfs/xattr.c | 8 ++--- include/linux/namei.h | 2 -- 16 files changed, 84 insertions(+), 236 deletions(-) diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c index 970b252b7d88..9dc89e16c956 100644 --- a/fs/unionfs/commonfops.c +++ b/fs/unionfs/commonfops.c @@ -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; diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c index 078ca2740884..6b24957e8454 100644 --- a/fs/unionfs/copyup.c +++ b/fs/unionfs/copyup.c @@ -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; diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c index 21ce90cbcf8a..5c000be0b39f 100644 --- a/fs/unionfs/debug.c +++ b/fs/unionfs/debug.c @@ -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); diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c index 1628dad90500..2183e5c3e736 100644 --- a/fs/unionfs/dentry.c +++ b/fs/unionfs/dentry.c @@ -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); diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c index 62ec9af38eb9..bd1c1fcf3249 100644 --- a/fs/unionfs/dirhelper.c +++ b/fs/unionfs/dirhelper.c @@ -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); diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c index dd522c2054ed..f25703ccd400 100644 --- a/fs/unionfs/inode.c +++ b/fs/unionfs/inode.c @@ -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; } diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c index 041d674279a4..005a5c861946 100644 --- a/fs/unionfs/lookup.c +++ b/fs/unionfs/lookup.c @@ -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 * diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c index ce85b8421177..912c1e9e33d9 100644 --- a/fs/unionfs/rename.c +++ b/fs/unionfs/rename.c @@ -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; diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c index b923742046d4..3c8eb7703792 100644 --- a/fs/unionfs/sioq.c +++ b/fs/unionfs/sioq.c @@ -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); } diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h index c2dfb9444505..2b465c56133e 100644 --- a/fs/unionfs/sioq.h +++ b/fs/unionfs/sioq.h @@ -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 { diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c index 53d289b19c39..8ad2595c0157 100644 --- a/fs/unionfs/super.c +++ b/fs/unionfs/super.c @@ -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; diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h index f074970581bd..6c21093b0f1e 100644 --- a/fs/unionfs/union.h +++ b/fs/unionfs/union.h @@ -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, diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c index 25943a5643f5..50cbd546a7a1 100644 --- a/fs/unionfs/unlink.c +++ b/fs/unionfs/unlink.c @@ -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; diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c index 582cef285dd8..41c9b09f7df9 100644 --- a/fs/unionfs/whiteout.c +++ b/fs/unionfs/whiteout.c @@ -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); diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c index a93d8036f8e9..84063dd6ce17 100644 --- a/fs/unionfs/xattr.c +++ b/fs/unionfs/xattr.c @@ -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; diff --git a/include/linux/namei.h b/include/linux/namei.h index 34fbc2d33966..492de72560fa 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -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 *); -- 2.34.1