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

aufs: ioctl, mvdown 2/2, callers



Support for the options of MVDOWN feature, which allows to overwrite the
existing entry, and writing to the branch even if its permission is RO.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent bc962de7
......@@ -431,6 +431,7 @@ static int au_cp_regular(struct au_cp_generic *cpg)
aufs_bindex_t bindex;
unsigned int flags;
struct dentry *dentry;
int force_wr;
struct file *file;
} *f, file[] = {
{
......@@ -440,6 +441,7 @@ static int au_cp_regular(struct au_cp_generic *cpg)
{
.bindex = cpg->bdst,
.flags = O_WRONLY | O_NOATIME | O_LARGEFILE,
.force_wr = !!au_ftest_cpup(cpg->flags, RWDST),
}
};
struct au_branch *br;
......@@ -453,7 +455,7 @@ static int au_cp_regular(struct au_cp_generic *cpg)
for (i = 0; i < 2; i++, f++) {
f->dentry = au_h_dptr(cpg->dentry, f->bindex);
f->file = au_h_open(cpg->dentry, f->bindex, f->flags,
/*file*/NULL);
/*file*/NULL, f->force_wr);
if (IS_ERR(f->file)) {
err = PTR_ERR(f->file);
if (i == SRC)
......@@ -736,19 +738,29 @@ int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent,
static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path)
{
int err;
struct dentry *dentry, *h_dentry, *h_parent;
struct dentry *dentry, *h_dentry, *h_parent, *parent;
struct inode *h_dir;
aufs_bindex_t bdst;
dentry = cpg->dentry;
bdst = cpg->bdst;
h_dentry = au_h_dptr(dentry, bdst);
dget(h_dentry);
au_set_h_dptr(dentry, bdst, NULL);
err = au_lkup_neg(dentry, bdst, /*wh*/0);
if (!err)
h_path->dentry = dget(au_h_dptr(dentry, bdst));
au_set_h_dptr(dentry, bdst, h_dentry);
if (!au_ftest_cpup(cpg->flags, OVERWRITE)) {
dget(h_dentry);
au_set_h_dptr(dentry, bdst, NULL);
err = au_lkup_neg(dentry, bdst, /*wh*/0);
if (!err)
h_path->dentry = dget(au_h_dptr(dentry, bdst));
au_set_h_dptr(dentry, bdst, h_dentry);
} else {
err = 0;
parent = dget_parent(dentry);
h_parent = au_h_dptr(parent, bdst);
dput(parent);
h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent);
if (IS_ERR(h_path->dentry))
err = PTR_ERR(h_path->dentry);
}
if (unlikely(err))
goto out;
......
......@@ -219,7 +219,7 @@ static int reopen_dir(struct file *file)
if (h_file)
continue;
h_file = au_h_open(dentry, bindex, flags, file);
h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
err = PTR_ERR(h_file);
if (IS_ERR(h_file))
goto out; /* close all? */
......@@ -257,7 +257,7 @@ static int do_open_dir(struct file *file, int flags, struct file *h_file)
if (!h_dentry)
continue;
h_file = au_h_open(dentry, bindex, flags, file);
h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
if (IS_ERR(h_file)) {
err = PTR_ERR(h_file);
break;
......@@ -577,7 +577,7 @@ static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
h_file = au_h_open(dentry, arg->bindex,
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
/*file*/NULL);
/*file*/NULL, /*force_wr*/0);
err = PTR_ERR(h_file);
if (IS_ERR(h_file))
goto out;
......
......@@ -31,7 +31,7 @@ int au_do_open_nondir(struct file *file, int flags, struct file *h_file)
atomic_set(&finfo->fi_mmapped, 0);
bindex = au_dbtop(dentry);
if (!h_file)
h_file = au_h_open(dentry, bindex, flags, file);
h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0);
else
get_file(h_file);
if (IS_ERR(h_file))
......
......@@ -23,7 +23,7 @@ unsigned int au_file_roflags(unsigned int flags)
/* common functions to regular file and dir */
struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
struct file *file)
struct file *file, int force_wr)
{
struct file *h_file;
struct dentry *h_dentry;
......@@ -55,8 +55,20 @@ struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
goto out;
/* drop flags for writing */
if (au_test_ro(sb, bindex, d_inode(dentry)))
if (au_test_ro(sb, bindex, d_inode(dentry))) {
if (force_wr && !(flags & O_WRONLY))
force_wr = 0;
flags = au_file_roflags(flags);
if (force_wr) {
h_file = ERR_PTR(-EROFS);
flags = au_file_roflags(flags);
if (unlikely(vfsub_native_ro(h_inode)
|| IS_APPEND(h_inode)))
goto out;
flags &= ~O_ACCMODE;
flags |= O_WRONLY;
}
}
flags &= ~O_CREAT;
au_lcnt_inc(&br->br_nfiles);
h_path.dentry = h_dentry;
......@@ -169,7 +181,7 @@ int au_reopen_nondir(struct file *file)
/* AuDebugOn(au_fbtop(file) < btop); */
h_file = au_h_open(dentry, btop, vfsub_file_flags(file) & ~O_TRUNC,
file);
file, /*force_wr*/0);
err = PTR_ERR(h_file);
if (IS_ERR(h_file)) {
if (h_file_tmp) {
......
......@@ -61,7 +61,7 @@ struct au_finfo {
extern const struct address_space_operations aufs_aop;
unsigned int au_file_roflags(unsigned int flags);
struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
struct file *file);
struct file *file, int force_wr);
struct au_do_open_args {
int aopen;
int (*open)(struct file *file, int flags,
......
......@@ -84,7 +84,8 @@ static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg)
}
AuDbg("wbi %d\n", wbi);
if (wbi >= 0)
h_file = au_h_open(root, wbi, wbrfd.oflags, NULL);
h_file = au_h_open(root, wbi, wbrfd.oflags, NULL,
/*force_wr*/0);
out_unlock:
aufs_read_unlock(root, AuLock_IR);
......@@ -143,6 +144,10 @@ long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg)
long err;
switch (cmd) {
case AUFS_CTL_MVDOWN:
err = au_mvdown(file->f_path.dentry, (void __user *)arg);
break;
case AUFS_CTL_WBR_FD:
err = au_wbr_fd(&file->f_path, (void __user *)arg);
break;
......
......@@ -199,6 +199,7 @@ enum {
AuCtl_WBR_FD, /* pathconf wrapper */
AuCtl_IBUSY, /* busy inode */
AuCtl_MVDOWN, /* move-down */
AuCtl_BR /* info about branches */
};
......@@ -390,6 +391,8 @@ union aufs_brinfo {
#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \
struct aufs_wbr_fd)
#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy)
#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \
struct aufs_mvdown)
#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo)
#endif /* __AUFS_TYPE_H__ */
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