diff options
Diffstat (limited to 'fs/aufs/cpup.c')
-rw-r--r-- | fs/aufs/cpup.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c index cd322746c..a34648874 100644 --- a/fs/aufs/cpup.c +++ b/fs/aufs/cpup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2015 Junjiro R. Okajima + * Copyright (C) 2005-2016 Junjiro R. Okajima */ /* @@ -8,6 +8,7 @@ #include <linux/fs_stack.h> #include <linux/mm.h> +#include <linux/task_work.h> #include "aufs.h" void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) @@ -380,6 +381,7 @@ static int au_cp_regular(struct au_cp_generic *cpg) } }; struct super_block *sb; + struct task_struct *tsk = current; /* bsrc branch can be ro/rw. */ sb = cpg->dentry->d_sb; @@ -397,7 +399,21 @@ static int au_cp_regular(struct au_cp_generic *cpg) IMustLock(d_inode(file[SRC].dentry)); err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); - fput(file[DST].file); + /* i wonder if we had O_NO_DELAY_FPUT flag */ + if (tsk->flags & PF_KTHREAD) + __fput_sync(file[DST].file); + else { + WARN(1, "%pD\nPlease report this warning to aufs-users ML", + file[DST].file); + fput(file[DST].file); + /* + * too bad. + * we have to call both since we don't know which place the file + * was added to. + */ + task_work_run(); + flush_delayed_fput(); + } au_sbr_put(sb, file[DST].bindex); out_src: |