Commit be3f6e60 authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: atomic_open 2/5, introduce vfsub_atomic_open()



Following the design in another commit, aufs calls branch fs's
->atomic_open() if exits. Ideally it would be better to call
VFS:do_last, lookup_open() or atomic_open, but it is very hard for
aufs. This implementation is far from the best.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 4aa9a6a1
...@@ -53,6 +53,64 @@ struct file *vfsub_filp_open(const char *path, int oflags, int mode) ...@@ -53,6 +53,64 @@ struct file *vfsub_filp_open(const char *path, int oflags, int mode)
return file; return file;
} }
/*
* Ideally this function should call VFS:do_last() in order to keep all its
* checkings. But it is very hard for aufs to regenerate several VFS internal
* structure such as nameidata. This is a second (or third) best approach.
* cf. linux/fs/namei.c:do_last(), lookup_open() and atomic_open().
*/
int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
struct vfsub_aopen_args *args)
{
int err;
struct au_branch *br = args->br;
struct file *file = args->file;
/* copied from linux/fs/namei.c:atomic_open() */
struct dentry *const DENTRY_NOT_SET = (void *)-1UL;
IMustLock(dir);
AuDebugOn(!dir->i_op->atomic_open);
err = au_br_test_oflag(args->open_flag, br);
if (unlikely(err))
goto out;
au_lcnt_inc(&br->br_nfiles);
file->f_path.dentry = DENTRY_NOT_SET;
file->f_path.mnt = au_br_mnt(br);
AuDbg("%ps\n", dir->i_op->atomic_open);
err = dir->i_op->atomic_open(dir, dentry, file, args->open_flag,
args->create_mode);
if (unlikely(err < 0)) {
au_lcnt_dec(&br->br_nfiles);
goto out;
}
/* temporary workaround for nfsv4 branch */
if (au_test_nfs(dir->i_sb))
nfs_mark_for_revalidate(dir);
if (file->f_mode & FMODE_CREATED)
fsnotify_create(dir, dentry);
if (!(file->f_mode & FMODE_OPENED)) {
au_lcnt_dec(&br->br_nfiles);
goto out;
}
/* todo: call VFS:may_open() here */
/* todo: ima_file_check() too? */
if (!err && (args->open_flag & __FMODE_EXEC))
err = deny_write_access(file);
if (!err)
fsnotify_open(file);
else
au_lcnt_dec(&br->br_nfiles);
/* note that the file is created and still opened */
out:
return err;
}
int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) int vfsub_kern_path(const char *name, unsigned int flags, struct path *path)
{ {
int err; int err;
......
...@@ -58,6 +58,15 @@ int vfsub_sync_filesystem(struct super_block *h_sb, int wait); ...@@ -58,6 +58,15 @@ int vfsub_sync_filesystem(struct super_block *h_sb, int wait);
struct file *vfsub_dentry_open(struct path *path, int flags); struct file *vfsub_dentry_open(struct path *path, int flags);
struct file *vfsub_filp_open(const char *path, int oflags, int mode); struct file *vfsub_filp_open(const char *path, int oflags, int mode);
struct au_branch;
struct vfsub_aopen_args {
struct file *file;
unsigned int open_flag;
umode_t create_mode;
struct au_branch *br;
};
int vfsub_atomic_open(struct inode *dir, struct dentry *dentry,
struct vfsub_aopen_args *args);
int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
struct dentry *vfsub_lookup_one_len_unlocked(const char *name, struct dentry *vfsub_lookup_one_len_unlocked(const char *name,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment