diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 17be9619..6393ac1f 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -204,3 +204,12 @@ endif ifneq (,$(shell grep 'define register_hotcpu_notifier' include/linux/cpu.h)) ccflags-y += -DKC_CPU_NOTIFIER endif + +# +# v3.14-rc8-130-gccad2365668f +# +# generic_file_buffered_write is removed, backport it +# +ifneq (,$(shell grep 'extern ssize_t generic_file_buffered_write' include/linux/fs.h)) +ccflags-y += -DKC_GENERIC_FILE_BUFFERED_WRITE=1 +endif diff --git a/kmod/src/kernelcompat.c b/kmod/src/kernelcompat.c index 7ad197ee..7f8da413 100644 --- a/kmod/src/kernelcompat.c +++ b/kmod/src/kernelcompat.c @@ -1,4 +1,6 @@ +#include + #include "kernelcompat.h" #ifdef KC_SHRINKER_SHRINK @@ -58,3 +60,25 @@ struct timespec64 kc_current_time(struct inode *inode) return now; } #endif + +#ifndef KC_GENERIC_FILE_BUFFERED_WRITE +ssize_t +kc_generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos, loff_t *ppos, + size_t count, ssize_t written) +{ + struct file *file = iocb->ki_filp; + ssize_t status; + struct iov_iter i; + + iov_iter_init(&i, WRITE, iov, nr_segs, count); + status = generic_perform_write(file, &i, pos); + + if (likely(status >= 0)) { + written += status; + *ppos = pos + status; + } + + return written ? written : status; +} +#endif diff --git a/kmod/src/kernelcompat.h b/kmod/src/kernelcompat.h index b18fa847..32124829 100644 --- a/kmod/src/kernelcompat.h +++ b/kmod/src/kernelcompat.h @@ -266,4 +266,11 @@ static inline int kc_kernel_getpeername(struct socket *sock, struct sockaddr *ad #define kc_sock_create_kern sock_create_kern #endif +#ifndef KC_GENERIC_FILE_BUFFERED_WRITE +ssize_t kc_generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t pos, loff_t *ppos, + size_t count, ssize_t written); +#define generic_file_buffered_write kc_generic_file_buffered_write +#endif + #endif