*** a/fs/aufs/xino.c 2017-09-20 14:25:41.841850111 +0000 --- b/fs/aufs/xino.c 2017-09-20 19:23:31.065603010 +0000 *************** ssize_t xino_fread(au_readf_t func, stru *** 53,58 **** --- 53,61 ---- /* ---------------------------------------------------------------------- */ + static ssize_t xino_fwrite_wkq(au_writef_t func, struct file *file, void *buf, + size_t size, loff_t *pos); + static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf, size_t size, loff_t *pos) { *************** static ssize_t do_xino_fwrite(au_writef_ *** 63,75 **** const char __user *u; } buf; buf.k = kbuf; oldfs = get_fs(); set_fs(KERNEL_DS); do { - /* todo: signal_pending? */ err = func(file, buf.u, size, pos); ! } while (err == -EAGAIN || err == -EINTR); set_fs(oldfs); #if 0 /* reserved for future use */ --- 66,92 ---- const char __user *u; } buf; + int i; + const int prevent_endless = 10; + + i = 0; buf.k = kbuf; oldfs = get_fs(); set_fs(KERNEL_DS); do { err = func(file, buf.u, size, pos); ! if (err == -EINTR ! && !au_wkq_test() ! && fatal_signal_pending(current)) { ! set_fs(oldfs); ! err = xino_fwrite_wkq(func, file, kbuf, size, pos); ! BUG_ON(err == -EINTR); ! oldfs = get_fs(); ! set_fs(KERNEL_DS); ! } ! } while (i++ < prevent_endless && ! (err == -EAGAIN || err == -EINTR)); ! set_fs(oldfs); #if 0 /* reserved for future use */ *************** ssize_t xino_fwrite(au_writef_t func, st *** 100,132 **** { ssize_t err; - /* todo: signal block and no wkq? */ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { lockdep_off(); err = do_xino_fwrite(func, file, buf, size, pos); lockdep_on(); } else { ! /* ! * it breaks RLIMIT_FSIZE and normal user's limit, ! * users should care about quota and real 'filesystem full.' ! */ ! int wkq_err; ! struct do_xino_fwrite_args args = { ! .errp = &err, ! .func = func, ! .file = file, ! .buf = buf, ! .size = size, ! .pos = pos ! }; ! ! wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ! if (unlikely(wkq_err)) ! err = wkq_err; } return err; } /* ---------------------------------------------------------------------- */ --- 117,157 ---- { ssize_t err; if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { lockdep_off(); err = do_xino_fwrite(func, file, buf, size, pos); lockdep_on(); } else { ! err = xino_fwrite_wkq(func, file, buf, size, pos); } return err; } + + static ssize_t xino_fwrite_wkq(au_writef_t func, struct file *file, void *buf, + size_t size, loff_t *pos) + { + ssize_t err; + int wkq_err; + struct do_xino_fwrite_args args = { + .errp = &err, + .func = func, + .file = file, + .buf = buf, + .size = size, + .pos = pos + }; + + /* + * it breaks RLIMIT_FSIZE and normal user's limit, + * users should care about quota and real 'filesystem full.' + */ + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); + if (unlikely(wkq_err)) + err = wkq_err; + + return err; + } /* ---------------------------------------------------------------------- */