All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cluster-devel] cluster/gfs-kernel/src/gfs dir.c file.c file.h ...
@ 2006-10-17 19:02 wcheng
  0 siblings, 0 replies; only message in thread
From: wcheng @ 2006-10-17 19:02 UTC (permalink / raw)
  To: cluster-devel.redhat.com

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	wcheng at sourceware.org	2006-10-17 19:02:35

Modified files:
	gfs-kernel/src/gfs: dir.c file.c file.h ioctl.c ops_file.c 

Log message:
	Port RHEL4 GFS AIO (asynchronous IO) implementation into RHEL5/FC6 and
	community-version of GFS1.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/dir.c.diff?cvsroot=cluster&r1=1.13&r2=1.14
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/file.c.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/file.h.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ioctl.c.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs-kernel/src/gfs/ops_file.c.diff?cvsroot=cluster&r1=1.25&r2=1.26

--- cluster/gfs-kernel/src/gfs/dir.c	2006/07/10 23:22:34	1.13
+++ cluster/gfs-kernel/src/gfs/dir.c	2006/10/17 19:02:35	1.14
@@ -2210,7 +2210,7 @@
 		dip->i_di.di_blocks--;
 	}
 
-	error = gfs_writei(dip, ht, index * sizeof (uint64_t), size, gfs_zero_blocks);
+	error = gfs_writei(dip, ht, index * sizeof (uint64_t), size, gfs_zero_blocks, NULL);
 
 	if (error != size) {
 		if (error >= 0)
--- cluster/gfs-kernel/src/gfs/file.c	2006/07/10 23:22:34	1.8
+++ cluster/gfs-kernel/src/gfs/file.c	2006/10/17 19:02:35	1.9
@@ -306,7 +306,8 @@
 int
 gfs_writei(struct gfs_inode *ip, void *buf,
 	   uint64_t offset, unsigned int size,
-	   write_copy_fn_t copy_fn)
+	   write_copy_fn_t copy_fn,
+           struct kiocb *iocb)
 {
 	struct gfs_sbd *sdp = ip->i_sbd;
 	struct buffer_head *dibh, *bh;
--- cluster/gfs-kernel/src/gfs/file.h	2006/07/10 23:22:34	1.4
+++ cluster/gfs-kernel/src/gfs/file.h	2006/10/17 19:02:35	1.5
@@ -32,7 +32,8 @@
 int gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf,
 		       unsigned int offset, unsigned int size, int new);
 int gfs_writei(struct gfs_inode *ip, void *buf, uint64_t offset,
-	       unsigned int size, write_copy_fn_t copy_fn);
+               unsigned int size, write_copy_fn_t copy_fn,
+               struct kiocb *iocb);
 
 int gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf,
 		    unsigned int offset, unsigned int size, int new);
@@ -48,7 +49,7 @@
 gfs_internal_write(struct gfs_inode *ip, char *buf, uint64_t offset,
 		   unsigned int size)
 {
-	return gfs_writei(ip, buf, offset, size, gfs_copy_from_mem);
+	return gfs_writei(ip, buf, offset, size, gfs_copy_from_mem, NULL);
 }
 
 #endif /* __FILE_DOT_H__ */
--- cluster/gfs-kernel/src/gfs/ioctl.c	2006/08/11 14:32:32	1.12
+++ cluster/gfs-kernel/src/gfs/ioctl.c	2006/10/17 19:02:35	1.13
@@ -1229,7 +1229,7 @@
 	}
 
 	error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size,
-			   gfs_copy_from_user);
+			   gfs_copy_from_user, NULL);
 
 	gfs_trans_end(sdp);
 
--- cluster/gfs-kernel/src/gfs/ops_file.c	2006/08/11 14:32:32	1.25
+++ cluster/gfs-kernel/src/gfs/ops_file.c	2006/10/17 19:02:35	1.26
@@ -23,6 +23,7 @@
 #include <linux/uio.h>
 #include <linux/blkdev.h>
 #include <linux/mm.h>
+#include <linux/aio.h>
 #include <asm/uaccess.h>
 
 #include "gfs_ioctl.h"
@@ -76,6 +77,7 @@
 typedef ssize_t(*do_rw_t) (struct file * file,
 			   char *buf,
 			   size_t size, loff_t * offset,
+                           struct kiocb *iocb,
 			   unsigned int num_gh, struct gfs_holder * ghs);
 
 /**
@@ -129,7 +131,7 @@
 
 static ssize_t
 walk_vm_hard(struct file *file, char *buf, size_t size, loff_t *offset,
-	     do_rw_t operation)
+             struct kiocb *iocb, do_rw_t operation)
 {
 	struct gfs_holder *ghs;
 	unsigned int num_gh = 0;
@@ -178,7 +180,7 @@
 		gfs_assert(get_v2sdp(sb), x == num_gh,);
 	}
 
-	count = operation(file, buf, size, offset, num_gh, ghs);
+	count = operation(file, buf, size, offset, iocb, num_gh, ghs);
 
 	while (num_gh--)
 		gfs_holder_uninit(&ghs[num_gh]);
@@ -204,6 +206,7 @@
 
 static ssize_t
 walk_vm(struct file *file, char *buf, size_t size, loff_t *offset,
+	struct kiocb *iocb,	
 	do_rw_t operation)
 {
 	if (current->mm) {
@@ -231,11 +234,11 @@
 
 	{
 		struct gfs_holder gh;
-		return operation(file, buf, size, offset, 0, &gh);
+		return operation(file, buf, size, offset, iocb, 0, &gh);
 	}
 
  do_locks:
-	return walk_vm_hard(file, buf, size, offset, operation);
+	return walk_vm_hard(file, buf, size, offset, iocb, operation);
 }
 
 /**
@@ -250,7 +253,8 @@
  */
 
 static ssize_t
-do_read_readi(struct file *file, char *buf, size_t size, loff_t *offset)
+do_read_readi(struct file *file, char *buf, size_t size, loff_t *offset,
+              struct kiocb *iocb)
 {
 	struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
 	ssize_t count = 0;
@@ -267,6 +271,8 @@
 			size = 0x7FFFFFFFull - *offset;
 	}
 
+	/* ToDo: not sure about iocb .. wcheng
+	 */
 	count = gfs_readi(ip, buf, *offset, size, gfs_copy2user);
 
 	if (count > 0)
@@ -291,7 +297,8 @@
 
 static ssize_t
 do_read_direct(struct file *file, char *buf, size_t size, loff_t *offset,
-	       unsigned int num_gh, struct gfs_holder *ghs)
+		struct kiocb *iocb,
+		unsigned int num_gh, struct gfs_holder *ghs)
 {
 	struct inode *inode = file->f_mapping->host;
 	struct gfs_inode *ip = get_v2ip(inode);
@@ -324,10 +331,16 @@
 		if (((*offset) & mask) || (((unsigned long)buf) & mask))
 			goto out_gunlock;
 
-		count = do_read_readi(file, buf, size & ~mask, offset);
+		count = do_read_readi(file, buf, size & ~mask, offset, iocb);
+	}
+	else {
+		if (!iocb) 
+			count = generic_file_read(file, buf, size, offset);
+		else {
+		        struct iovec local_iov = { .iov_base = buf, .iov_len = size};
+			count = __generic_file_aio_read(iocb, &local_iov, 1, offset);
+		}
 	}
-	else
-		count = generic_file_read(file, buf, size, offset);
 
 	error = 0;
 
@@ -356,7 +369,8 @@
 
 static ssize_t
 do_read_buf(struct file *file, char *buf, size_t size, loff_t *offset,
-	    unsigned int num_gh, struct gfs_holder *ghs)
+		struct kiocb *iocb,
+		unsigned int num_gh, struct gfs_holder *ghs)
 {
 	struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
 	ssize_t count = 0;
@@ -370,9 +384,22 @@
 
 	if (gfs_is_jdata(ip) ||
 	    (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags)))
-		count = do_read_readi(file, buf, size, offset);
-	else
-		count = generic_file_read(file, buf, size, offset);
+		count = do_read_readi(file, buf, size, offset, iocb);
+	else {
+		if (!iocb) {
+			count = generic_file_read(file, buf, size, offset);
+		} else {
+			struct iovec local_iov = {
+				.iov_base = (char __user *)buf,
+				.iov_len = size 
+			};
+
+		        count = __generic_file_aio_read(iocb, 
+					&local_iov, 1, offset);
+			if (count == -EIOCBQUEUED)
+				count = wait_on_sync_kiocb(iocb);
+		}
+	}
 
 	gfs_glock_dq_m(num_gh + 1, ghs);
 
@@ -382,6 +409,17 @@
 	return (count) ? count : error;
 }
 
+static ssize_t
+__gfs_read(struct file *file, char *buf, size_t size, loff_t *offset, struct kiocb *iocb)
+{
+	atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file);
+
+	if (file->f_flags & O_DIRECT)
+		return walk_vm(file, buf, size, offset, iocb, do_read_direct);
+	else
+		return walk_vm(file, buf, size, offset, iocb, do_read_buf);
+}
+
 /**
  * gfs_read - Read bytes from a file
  * @file: The file to read from
@@ -397,12 +435,20 @@
 static ssize_t
 gfs_read(struct file *file, char *buf, size_t size, loff_t *offset)
 {
-	atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file);
+	return(__gfs_read(file, buf, size, offset, NULL));
+}
 
-	if (file->f_flags & O_DIRECT)
-		return walk_vm(file, buf, size, offset, do_read_direct);
-	else
-		return walk_vm(file, buf, size, offset, do_read_buf);
+/*
+ * gfs_aio_read: match with vfs generic_file_aio_read as:
+ * 	(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
+ */
+static ssize_t
+gfs_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
+{
+	struct file *filp = iocb->ki_filp;
+
+	BUG_ON(iocb->ki_pos != pos);
+	return(__gfs_read(filp, buf, count, &iocb->ki_pos, iocb));
 }
 
 /**
@@ -449,7 +495,8 @@
  */
 
 static ssize_t
-do_write_direct_alloc(struct file *file, char *buf, size_t size, loff_t *offset)
+do_write_direct_alloc(struct file *file, char *buf, size_t size, loff_t *offset,
+			struct kiocb *iocb)
 {
 	struct inode *inode = file->f_mapping->host;
 	struct gfs_inode *ip = get_v2ip(inode);
@@ -502,13 +549,15 @@
 		brelse(dibh);
 	}
 
-	if (gfs_is_stuffed(ip)) {
-		error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL);
-		if (error)
+	if (gfs_is_stuffed(ip)) { error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); if (error)
 			goto fail_end_trans;
 	}
 
-	count = generic_file_write_nolock(file, &local_iov, 1, offset);
+	if (!iocb)
+		count = generic_file_write_nolock(file, &local_iov, 1, offset);
+	else {
+		count = generic_file_aio_write_nolock(iocb, &local_iov, 1, offset);
+	}
 	if (count < 0) {
 		error = count;
 		goto fail_end_trans;
@@ -528,6 +577,10 @@
 
 	gfs_trans_end(sdp);
 
+	/* Question (wcheng)
+	 * 1. should IS_SYNC flush glock ?
+	 * 2. does gfs_log_flush_glock flush data ?
+	 */
 	if (file->f_flags & O_SYNC)
 		gfs_log_flush_glock(ip->i_gl);
 
@@ -576,6 +629,7 @@
 
 static ssize_t
 do_write_direct(struct file *file, char *buf, size_t size, loff_t *offset,
+		struct kiocb *iocb,
 		unsigned int num_gh, struct gfs_holder *ghs)
 {
 	struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
@@ -652,7 +706,7 @@
 			if (s > size)
 				s = size;
 
-			error = do_write_direct_alloc(file, buf, s, offset);
+			error = do_write_direct_alloc(file, buf, s, offset, iocb);
 			if (error < 0)
 				goto out_gunlock;
 
@@ -670,8 +724,16 @@
 		if (error)
 			goto out_gunlock;
 
-		count = generic_file_write_nolock(file, &local_iov, 1, offset);
-
+		/* Todo: It would be nice if init_sync_kiocb is exported.
+		 *  .. wcheng
+		 */
+		if (!iocb) 
+			count = 
+			generic_file_write_nolock(file, &local_iov, 1, offset);
+		else {
+			count = 
+			generic_file_aio_write_nolock(iocb, &local_iov, 1, offset);
+		}
 		gfs_glock_dq_uninit(&t_gh);
 	}
 
@@ -699,7 +761,8 @@
  */
 
 static ssize_t
-do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset)
+do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset,
+		struct kiocb *iocb)
 {
 	struct inode *inode = file->f_mapping->host;
 	struct gfs_inode *ip = get_v2ip(inode);
@@ -777,7 +840,7 @@
 	    (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags) &&
 	     *offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode))) {
 
-		count = gfs_writei(ip, buf, *offset, size, gfs_copy_from_user);
+		count = gfs_writei(ip, buf, *offset, size, gfs_copy_from_user, iocb);
 		if (count < 0) {
 			error = count;
 			goto fail_end_trans;
@@ -794,7 +857,14 @@
 	} else {
 		struct iovec local_iov = { .iov_base = buf, .iov_len = size };
 
-		count = generic_file_write_nolock(file, &local_iov, 1, offset);
+		if (!iocb) {
+			count = generic_file_write_nolock(file, &local_iov, 1, offset);
+		} else {
+			count = generic_file_aio_write_nolock(iocb, 
+				&local_iov, 1, offset);
+			if (count == -EIOCBQUEUED)
+				count = wait_on_sync_kiocb(iocb);
+		}
 		if (count < 0) {
 			error = count;
 			goto fail_end_trans;
@@ -869,8 +939,9 @@
 
 static ssize_t
 do_write_buf(struct file *file,
-	     char *buf, size_t size, loff_t *offset,
-	     unsigned int num_gh, struct gfs_holder *ghs)
+		char *buf, size_t size, loff_t *offset,
+		struct kiocb *iocb,
+		unsigned int num_gh, struct gfs_holder *ghs)
 {
 	struct gfs_inode *ip = get_v2ip(file->f_mapping->host);
 	struct gfs_sbd *sdp = ip->i_sbd;
@@ -907,7 +978,7 @@
 		if (s > size)
 			s = size;
 
-		error = do_do_write_buf(file, buf, s, offset);
+		error = do_do_write_buf(file, buf, s, offset, iocb);
 		if (error < 0)
 			goto out_gunlock;
 
@@ -940,7 +1011,7 @@
  */
 
 static ssize_t
-gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset)
+__gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset, struct kiocb *iocb)
 {
 	struct inode *inode = file->f_mapping->host;
 	ssize_t count;
@@ -954,14 +1025,30 @@
 
 	mutex_lock(&inode->i_mutex);
 	if (file->f_flags & O_DIRECT)
-		count = walk_vm(file, (char *)buf, size, offset, do_write_direct);
+		count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_direct);
 	else
-		count = walk_vm(file, (char *)buf, size, offset, do_write_buf);
+		count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_buf);
 	mutex_unlock(&inode->i_mutex);
 
 	return count;
 }
 
+static ssize_t
+gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset)
+{
+	return(__gfs_write(file, buf, size, offset, NULL));
+}
+
+static ssize_t
+gfs_aio_write(struct kiocb *iocb, const char __user *buf, size_t size, loff_t pos)
+{
+	struct file *file = iocb->ki_filp;
+
+	BUG_ON(iocb->ki_pos != pos);
+
+	return(__gfs_write(file, buf, size, &iocb->ki_pos, iocb));
+}
+
 /**
  * filldir_reg_func - Report a directory entry to the caller of gfs_dir_read()
  * @opaque: opaque data used by the function
@@ -1642,6 +1729,8 @@
 	.llseek = gfs_llseek,
 	.read = gfs_read,
 	.write = gfs_write,
+        .aio_read = gfs_aio_read,
+        .aio_write = gfs_aio_write,
 	.ioctl = gfs_ioctl,
 	.mmap = gfs_mmap,
 	.open = gfs_open,



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-10-17 19:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-17 19:02 [Cluster-devel] cluster/gfs-kernel/src/gfs dir.c file.c file.h wcheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.