diff --git a/patch/kernel/pine64-default/aufs-hang.patch b/patch/kernel/pine64-default/aufs-hang.patch new file mode 100644 index 0000000000..5032ff74d8 --- /dev/null +++ b/patch/kernel/pine64-default/aufs-hang.patch @@ -0,0 +1,134 @@ +*** 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; ++ } + + /* ---------------------------------------------------------------------- */ +