int err = 0;
struct dentry *lower_dentry;
struct dentry *lower_parent_dentry = NULL;
- struct nameidata lower_nd;
- struct path lower_path;
+ struct path lower_path, saved_path;
wrapfs_get_lower_path(dentry, &lower_path);
lower_dentry = lower_path.dentry;
if (err)
goto out_unlock;
- err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
- if (err < 0)
- goto out;
- err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
- &lower_nd);
- release_lower_nd(&lower_nd, err);
+ pathcpy(&saved_path, &nd->path);
+ pathcpy(&nd->path, &lower_path);
+ err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
+ pathcpy(&nd->path, &saved_path);
if (err)
goto out;
- /* XXX; should we pass lower_nd.path instead of lower_path? */
+
err = wrapfs_interpose(dentry, dir->i_sb, &lower_path);
if (err)
goto out;
return 0;
}
-/*
- * 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 file system return an
- * open file for us (esp. 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 (!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("wrapfs: 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 */
-}
-
static int wrapfs_inode_test(struct inode *inode, void *candidate_lower_inode)
{
struct inode *current_lower_inode = wrapfs_lower_inode(inode);
extern void wrapfs_destroy_dentry_cache(void);
extern int new_dentry_private_data(struct dentry *dentry);
extern void free_dentry_private_data(struct dentry *dentry);
-extern int init_lower_nd(struct nameidata *nd, unsigned int flags);
-extern void release_lower_nd(struct nameidata *nd, int err);
extern struct dentry *wrapfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd);
extern int wrapfs_interpose(struct dentry *dentry, struct super_block *sb,