Tiger Yang
2008-May-16 06:04 UTC
[Ocfs2-devel] [PATCH 1/4] ocfs2: Fix pipe operation pin() changes to confirm()
commit cac36bb06efe4880234524e117e0e712b10b1f16 in mainline changes pipe_buf_operations->pin() to ->confirm(). This patch allows building ocfs2 with kernels having/not having this change. Signed-off-by: Tiger Yang <tiger.yang at oracle.com> --- Config.make.in | 1 + configure.in | 6 ++++++ fs/ocfs2/Makefile | 4 ++++ kapi-compat/include/pipe_buf_operations.h | 10 ++++++++++ 4 files changed, 21 insertions(+), 0 deletions(-) create mode 100644 kapi-compat/include/pipe_buf_operations.h diff --git a/Config.make.in b/Config.make.in index b7d553d..1abcc55 100644 --- a/Config.make.in +++ b/Config.make.in @@ -95,6 +95,7 @@ NO_LINUX_UACCESS_H = @NO_LINUX_UACCESS_H@ NO_SYSTEM_UTSNAME = @NO_SYSTEM_UTSNAME@ HAS_MS_LOOP_NO_AOPS = @HAS_MS_LOOP_NO_AOPS@ HAS_FOPS_SENDFILE = @HAS_FOPS_SENDFILE@ +NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS = @NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS@ OCFS_DEBUG = @OCFS_DEBUG@ diff --git a/configure.in b/configure.in index bc5187f..94d981a 100644 --- a/configure.in +++ b/configure.in @@ -425,6 +425,12 @@ OCFS2_CHECK_KERNEL([task_pid_nr in sched.h], sched.h, , task_pid_nr_compat_header="task_pid_nr.h", [^static inline pid_t task_pid_nr(struct]) KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $task_pid_nr_compat_header" +NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS+OCFS2_CHECK_KERNEL([confirm() in struct pipe_buf_operations in pipe_fs_i.h], pipe_fs_i.h, + , NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS=yes, [int (\*confirm)(struct pipe_inode_info \*]) +AC_SUBST(NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS) +KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS pipe_buf_operations.h" + # using -include has two advantages: # the source doesn't need to know to include compat headers # the compat header file names don't go through the search path diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index 46aa8ee..4d1fddb 100644 --- a/fs/ocfs2/Makefile +++ b/fs/ocfs2/Makefile @@ -168,6 +168,10 @@ ifdef HAS_FOPS_SENDFILE EXTRA_CFLAGS += -DHAS_FOPS_SENDFILE endif +ifdef NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS +EXTRA_CFLAGS += -DNO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS +endif + # # Since SUBDIRS means something to kbuild, define them safely. Do not # include trailing slashes. diff --git a/kapi-compat/include/pipe_buf_operations.h b/kapi-compat/include/pipe_buf_operations.h new file mode 100644 index 0000000..8da5361 --- /dev/null +++ b/kapi-compat/include/pipe_buf_operations.h @@ -0,0 +1,10 @@ +#ifndef KAPI_PIPE_BUF_OPERATIONS_H +#define KAPI_PIPE_BUF_OPERATIONS_H + +#ifdef NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS +# define kapi_confirm(a,b) pin(a,b) +#else +# define kapi_confirm(a,b) confirm(a,b) +#endif + +#endif -- 1.5.4.4
Tiger Yang
2008-May-16 06:04 UTC
[Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock()/unlock()
commit 62752ee198dca9209b7dee504763e51b11e9e0ca in mainline added these two functions. This patch allows building ocfs2 with kernels having/not having this change. Signed-off-by: Tiger Yang <tiger.yang at oracle.com> --- Config.make.in | 1 + configure.in | 6 +++++ fs/ocfs2/Makefile | 4 +++ kapi-compat/include/inode_double_lock.h | 34 +++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 0 deletions(-) create mode 100644 kapi-compat/include/inode_double_lock.h diff --git a/Config.make.in b/Config.make.in index 1abcc55..2fddd6f 100644 --- a/Config.make.in +++ b/Config.make.in @@ -96,6 +96,7 @@ NO_SYSTEM_UTSNAME = @NO_SYSTEM_UTSNAME@ HAS_MS_LOOP_NO_AOPS = @HAS_MS_LOOP_NO_AOPS@ HAS_FOPS_SENDFILE = @HAS_FOPS_SENDFILE@ NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS = @NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS@ +NO_INODE_DOUBLE_LOCK = @NO_INODE_DOUBLE_LOCK@ OCFS_DEBUG = @OCFS_DEBUG@ diff --git a/configure.in b/configure.in index 94d981a..1a7b2b5 100644 --- a/configure.in +++ b/configure.in @@ -431,6 +431,12 @@ OCFS2_CHECK_KERNEL([confirm() in struct pipe_buf_operations in pipe_fs_i.h], pip AC_SUBST(NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS) KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS pipe_buf_operations.h" +NO_INODE_DOUBLE_LOCK+OCFS2_CHECK_KERNEL([inode_double_lock) in fs.h], fs.h, + , NO_INODE_DOUBLE_LOCK=yes, [^extern void inode_double_lock]) +AC_SUBST(NO_INODE_DOUBLE_LOCK) +KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS inode_double_lock.h" + # using -include has two advantages: # the source doesn't need to know to include compat headers # the compat header file names don't go through the search path diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index 4d1fddb..dd1a8bc 100644 --- a/fs/ocfs2/Makefile +++ b/fs/ocfs2/Makefile @@ -172,6 +172,10 @@ ifdef NO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS EXTRA_CFLAGS += -DNO_CONFIRM_IN_STRUCT_PIPE_BUF_OPERATIONS endif +ifdef NO_INODE_DOUBLE_LOCK +EXTRA_CFLAGS += -DNO_INODE_DOUBLE_LOCK +endif + # # Since SUBDIRS means something to kbuild, define them safely. Do not # include trailing slashes. diff --git a/kapi-compat/include/inode_double_lock.h b/kapi-compat/include/inode_double_lock.h new file mode 100644 index 0000000..6b28e0b --- /dev/null +++ b/kapi-compat/include/inode_double_lock.h @@ -0,0 +1,34 @@ +#ifndef KAPI_INODE_DOUBLE_LOCK_H +#define KAPI_INODE_DOUBLE_LOCK_H + +#ifdef NO_INODE_DOUBLE_LOCK +static inline void inode_double_lock(struct inode *inode1, struct inode *inode2) +{ + if (inode1 == NULL || inode2 == NULL || inode1 == inode2) { + if (inode1) + mutex_lock(&inode1->i_mutex); + else if (inode2) + mutex_lock(&inode2->i_mutex); + return; + } + + if (inode1 < inode2) { + mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD); + } else { + mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT); + mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD); + } +} + +static inline void inode_double_unlock(struct inode *inode1, struct inode *inode2) +{ + if (inode1) + mutex_unlock(&inode1->i_mutex); + + if (inode2 && inode2 != inode1) + mutex_unlock(&inode2->i_mutex); +} +#endif + +#endif -- 1.5.4.4
Tiger Yang
2008-May-16 06:04 UTC
[Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support
commit 40bee44eaef91b6030037c8bb47f909181fb1edc in mainline exported __splice_from_pipe(). This patch copied pipe_wait() and __splice_from_pipe() from mainline to allow support for splice io with enterprise kernels based on 2.6.18. Signed-off-by: Tiger Yang <tiger.yang at oracle.com> --- configure.in | 1 + fs/ocfs2/Makefile | 1 + fs/ocfs2/compat_splice.c | 129 ++++++++++++++++++++++++++++++++++++++++++ fs/ocfs2/file.c | 12 ++-- kapi-compat/include/splice.h | 16 +++++ 5 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 fs/ocfs2/compat_splice.c create mode 100644 kapi-compat/include/splice.h diff --git a/configure.in b/configure.in index 1a7b2b5..14a0316 100644 --- a/configure.in +++ b/configure.in @@ -268,6 +268,7 @@ NO_SPLICE_HEADER OCFS2_CHECK_KERNEL([struct splice_desc in splice.h], splice.h, , NO_SPLICE_HEADER=yes, [^struct splice_desc ]) AC_SUBST(NO_SPLICE_HEADER) +KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS splice.h" relatime_compat_header="" OCFS2_CHECK_KERNEL([MNT_RELATIME in mount.h], mount.h, diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile index dd1a8bc..f43da58 100644 --- a/fs/ocfs2/Makefile +++ b/fs/ocfs2/Makefile @@ -97,6 +97,7 @@ CFLAGS_file.o += -DNO_VECTORIZED_AIO endif ifdef NO_SPLICE_FROM_PIPE +SOURCES += compat_splice.c EXTRA_CFLAGS += -DNO_SPLICE_FROM_PIPE endif diff --git a/fs/ocfs2/compat_splice.c b/fs/ocfs2/compat_splice.c new file mode 100644 index 0000000..31da274 --- /dev/null +++ b/fs/ocfs2/compat_splice.c @@ -0,0 +1,129 @@ +/* + * compat_splice.c + * + * This code has been copied from mainline linux kernel git commit + * 40bee44eaef91b6030037c8bb47f909181fb1edc to allow ocfs2 to build + * against older kernels. For license, refer to fs/splice.c in mainline + * linux kernel. + * + */ + +void pipe_wait(struct pipe_inode_info *pipe) +{ + DEFINE_WAIT(wait); + + /* + * Pipes are system-local resources, so sleeping on them + * is considered a noninteractive wait: + */ + prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); + if (pipe->inode) + mutex_unlock(&pipe->inode->i_mutex); + schedule(); + finish_wait(&pipe->wait, &wait); + if (pipe->inode) + mutex_lock(&pipe->inode->i_mutex); +} + +/** + * __splice_from_pipe - splice data from a pipe to given actor + * @pipe: pipe to splice from + * @sd: information to @actor + * @actor: handler that splices the data + * + * Description: + * This function does little more than loop over the pipe and call + * @actor to do the actual moving of a single struct pipe_buffer to + * the desired destination. See pipe_to_file, pipe_to_sendpage, or + * pipe_to_user. + * + */ +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, + splice_actor *actor) +{ + int ret, do_wakeup, err; + + ret = 0; + do_wakeup = 0; + + for (;;) { + if (pipe->nrbufs) { + struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; + const struct pipe_buf_operations *ops = buf->ops; + + sd->len = buf->len; + if (sd->len > sd->total_len) + sd->len = sd->total_len; + + err = actor(pipe, buf, sd); + if (err <= 0) { + if (!ret && err != -ENODATA) + ret = err; + + break; + } + + ret += err; + buf->offset += err; + buf->len -= err; + + sd->len -= err; + sd->pos += err; + sd->total_len -= err; + if (sd->len) + continue; + + if (!buf->len) { + buf->ops = NULL; + ops->release(pipe, buf); + pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); + pipe->nrbufs--; + if (pipe->inode) + do_wakeup = 1; + } + + if (!sd->total_len) + break; + } + + if (pipe->nrbufs) + continue; + if (!pipe->writers) + break; + if (!pipe->waiting_writers) { + if (ret) + break; + } + + if (sd->flags & SPLICE_F_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + + if (do_wakeup) { + smp_mb(); + if (waitqueue_active(&pipe->wait)) + wake_up_interruptible_sync(&pipe->wait); + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); + do_wakeup = 0; + } + + pipe_wait(pipe); + } + + if (do_wakeup) { + smp_mb(); + if (waitqueue_active(&pipe->wait)) + wake_up_interruptible(&pipe->wait); + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); + } + + return ret; +} diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index af1a037..422c5f1 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -33,6 +33,8 @@ #include <linux/sched.h> #ifndef NO_SPLICE_HEADER #include <linux/splice.h> +#else +#include <linux/pipe_fs_i.h> #endif #include <linux/mount.h> #include <linux/writeback.h> @@ -2241,20 +2243,19 @@ out_sems: return written ? written : ret; } -#ifndef NO_SPLICE_FROM_PIPE static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct splice_desc *sd) { int ret, count; ssize_t copied = 0; - struct file *file = sd->u.file; + struct file *file = sd_file(sd); unsigned int offset; struct page *page = NULL; void *fsdata; char *src, *dst; - ret = buf->ops->confirm(pipe, buf); + ret = buf->ops->kapi_confirm(pipe, buf); if (ret) goto out; @@ -2301,9 +2302,9 @@ static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe, .total_len = len, .flags = flags, .pos = *ppos, - .u.file = out, }; + sd_file(&sd) = out; ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor); if (ret > 0) { *ppos += ret; @@ -2390,7 +2391,6 @@ bail: mlog_exit(ret); return ret; } -#endif static ssize_t __ocfs2_file_aio_read(struct kiocb *iocb, const struct iovec *iov, @@ -2550,10 +2550,8 @@ const struct file_operations ocfs2_fops = { .compat_ioctl = ocfs2_compat_ioctl, #endif .flock = ocfs2_flock, -#ifndef NO_SPLICE_FROM_PIPE .splice_read = ocfs2_file_splice_read, .splice_write = ocfs2_file_splice_write, -#endif #ifdef HAS_FOPS_SENDFILE .sendfile = ocfs2_file_sendfile, #endif diff --git a/kapi-compat/include/splice.h b/kapi-compat/include/splice.h new file mode 100644 index 0000000..f1fcdc0 --- /dev/null +++ b/kapi-compat/include/splice.h @@ -0,0 +1,16 @@ +#ifndef KAPI_SPLICE_H +#define KAPI_SPLICE_H + +#ifdef NO_SPLICE_FROM_PIPE +#include <linux/pipe_fs_i.h> +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, + splice_actor *actor); +#endif + +#ifdef NO_SPLICE_HEADER +# define sd_file(i) (i)->file +#else +# define sd_file(i) (i)->u.file +#endif + +#endif -- 1.5.4.4
Fixed typos added in ocfs2 1.4 git commit b77f15f3bfc3bcf747f05e5d120fa38d69f3e7ad and commit 2a96d67a1c49dbbe3eb10bb4957c93f9d74bec62 Signed-off-by: Tiger Yang <tiger.yang at oracle.com> --- configure.in | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 14a0316..bd4fe02 100644 --- a/configure.in +++ b/configure.in @@ -233,7 +233,7 @@ KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $sysctl_compat_header" configfs_compat_header="" OCFS2_CHECK_KERNEL([configfs_depend_item() in configfs.h], configfs.h, - , configfs_compat_header="configfs.h", [configfs_depend_item()]) + , configfs_compat_header="configfs.h", [configfs_depend_item(]) KAPI_COMPAT_HEADERS="$KAPI_COMPAT_HEADERS $configfs_compat_header" REGISTER_SYSCTL_TWO_ARGS@@ -413,7 +413,7 @@ AC_SUBST(NO_SYSTEM_UTSNAME) HAS_MS_LOOP_NO_AOPS OCFS2_CHECK_KERNEL([MS_LOOP_NO_AOPS flag defined], fs.h, - HAS_MS_LOOP_NO_AOPS==yes, , [MS_LOOP_NO_AOPS]) + HAS_MS_LOOP_NO_AOPS=yes, , [MS_LOOP_NO_AOPS]) AC_SUBST(HAS_MS_LOOP_NO_AOPS) HAS_FOPS_SENDFILE-- 1.5.4.4