[Cluster-devel] cluster/gfs-kernel/src/gfs dir.c file.c file.h ...
wcheng at sourceware.org
wcheng at sourceware.org
Tue Oct 17 19:02:36 UTC 2006
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,
More information about the Cluster-devel
mailing list