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);
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);
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);
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);
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;
* 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;
}
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);
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);
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;
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);
}
/* 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;
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;
}
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);
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;
__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);
* 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;
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 ||
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);
struct file *lower_file;
struct unionfs_rdutil_callback *buf = NULL;
int bindex, bstart, bend, bopaque;
+ struct path path;
sb = dentry->d_sb;
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);
}
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;
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) {
*/
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;
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;
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;
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;
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;
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;
}
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);
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);
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;
}
}
}
-
-/*
- * 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
*
struct dentry *lower_dentry;
struct dentry *lower_parent;
int err = 0;
- struct nameidata lower_nd;
verify_locked(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;
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;
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);
}
struct inode *parent;
struct dentry *dentry;
umode_t mode;
- struct nameidata *nd;
+ bool want_excl;
};
struct mkdir_args {
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;
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:
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);
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;
}
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,
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;
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;
struct dentry *lower_dir_dentry;
struct dentry *lower_dentry;
struct dentry *lower_wh_dentry;
- struct nameidata nd;
char *name = NULL;
int err = -EINVAL;
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;
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;
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);
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);
}
int err = 0;
struct dentry *lower_dentry, *diropq;
struct inode *lower_dir;
- struct nameidata nd;
const struct cred *old_creds;
struct cred *new_creds;
!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);
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;
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;
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;
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;
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 *);