ocfs2-devel.oss.oracle.com archive mirror
 help / color / mirror / Atom feed
* [Ocfs2-devel] [PATCH 1/4] ocfs2: Fixes pipe_buf_operations->pin switch to confirm in 2.6.23.
@ 2008-05-15  8:52 Tiger Yang
  2008-05-15  8:52 ` [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock/unlock functions Tiger Yang
  0 siblings, 1 reply; 5+ messages in thread
From: Tiger Yang @ 2008-05-15  8:52 UTC (permalink / raw)
  To: ocfs2-devel

Signed-off-by: Tiger Yang <tiger.yang@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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock/unlock functions.
  2008-05-15  8:52 [Ocfs2-devel] [PATCH 1/4] ocfs2: Fixes pipe_buf_operations->pin switch to confirm in 2.6.23 Tiger Yang
@ 2008-05-15  8:52 ` Tiger Yang
  2008-05-15  8:52   ` [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support Tiger Yang
  0 siblings, 1 reply; 5+ messages in thread
From: Tiger Yang @ 2008-05-15  8:52 UTC (permalink / raw)
  To: ocfs2-devel

Signed-off-by: Tiger Yang <tiger.yang@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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support.
  2008-05-15  8:52 ` [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock/unlock functions Tiger Yang
@ 2008-05-15  8:52   ` Tiger Yang
  2008-05-15  8:52     ` [Ocfs2-devel] [PATCH 4/4] ocfs2: Fixes two typos Tiger Yang
  0 siblings, 1 reply; 5+ messages in thread
From: Tiger Yang @ 2008-05-15  8:52 UTC (permalink / raw)
  To: ocfs2-devel

Signed-off-by: Tiger Yang <tiger.yang@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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH 4/4] ocfs2: Fixes two typos.
  2008-05-15  8:52   ` [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support Tiger Yang
@ 2008-05-15  8:52     ` Tiger Yang
  0 siblings, 0 replies; 5+ messages in thread
From: Tiger Yang @ 2008-05-15  8:52 UTC (permalink / raw)
  To: ocfs2-devel

Signed-off-by: Tiger Yang <tiger.yang@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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support
  2008-05-16  6:04 ` [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock()/unlock() Tiger Yang
@ 2008-05-16  6:04   ` Tiger Yang
  0 siblings, 0 replies; 5+ messages in thread
From: Tiger Yang @ 2008-05-16  6:04 UTC (permalink / raw)
  To: ocfs2-devel

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@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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-05-16  6:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-15  8:52 [Ocfs2-devel] [PATCH 1/4] ocfs2: Fixes pipe_buf_operations->pin switch to confirm in 2.6.23 Tiger Yang
2008-05-15  8:52 ` [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock/unlock functions Tiger Yang
2008-05-15  8:52   ` [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support Tiger Yang
2008-05-15  8:52     ` [Ocfs2-devel] [PATCH 4/4] ocfs2: Fixes two typos Tiger Yang
  -- strict thread matches above, loose matches on Subject: below --
2008-05-16  6:04 [Ocfs2-devel] [PATCH 1/4] ocfs2: Fix pipe operation pin() changes to confirm() Tiger Yang
2008-05-16  6:04 ` [Ocfs2-devel] [PATCH 2/4] ocfs2: Add inode_double_lock()/unlock() Tiger Yang
2008-05-16  6:04   ` [Ocfs2-devel] [PATCH 3/4] ocfs2: Add splice read/write support Tiger Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).