* [PATCH] Rework sendfile code to use a file operation (3rd resend)
@ 2002-07-28 12:29 Christoph Hellwig
0 siblings, 0 replies; only message in thread
From: Christoph Hellwig @ 2002-07-28 12:29 UTC (permalink / raw)
To: Linus Torvalds; +Cc: linux-kerne, linux-fsdevel
The current sendfile code only checks for the presence of a readpage method
on the filesystem from which it sends but assumes it has the same locking
semantics as generic_file_read. For all those filesystems that use the
pagecache but use a different read implementation (or a wrapper around
generic_file_read that does additional locking in most cases) this is broken
and allows for races, depending on the locking performed. Filesystems
for which this is an issue are tmpfs, smbfs, xfs and maybe others.
This patch adds a new sendfile member to the file operations vector and
splits the current sendfile implementations in a higher level part (now
in fs/read_write.c) and generic_file_sendfile that can be used for all
filesystems using generic_file_read. I've also updated all filesystems
using generic_file_read to use generic_file_sendfile aswell. Once this
is in I will add proper sendfile support to XFS.
I guess the maintainers will fixup tmpfs and smbfs (at least tmpfs is
very easy).
BK patch below:
--
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
ChangeSet@1.477, 2002-07-27 17:24:07+02:00, hch@sb.bsdonline.org
VFS: implement sendfile file operation
Currently the sendfile syscalls hardcode assumptions about the
implementation of the read file operations implementation. Although
it checks for the presence of a readpage address-space operation
filesystems in Linux are free to implement read differently from
the generic version (generic_file_read). Many filesystems such
as tmpfs, smbfs or xfs chose to implement it differently and need
additional locking, revalidation or checks.
fs/adfs/file.c | 1
fs/affs/file.c | 1
fs/bfs/file.c | 9 +--
fs/block_dev.c | 1
fs/ext2/file.c | 1
fs/ext3/file.c | 1
fs/freevxfs/vxfs_inode.c | 1
fs/hpfs/inode.c | 1
fs/jffs/inode-v23.c | 15 ++---
fs/jffs2/file.c | 1
fs/jfs/file.c | 1
fs/minix/file.c | 1
fs/ntfs/file.c | 1
fs/qnx4/file.c | 1
fs/ramfs/inode.c | 1
fs/read_write.c | 111 +++++++++++++++++++++++++++++++++++++++
fs/reiserfs/file.c | 1
fs/sysv/file.c | 1
fs/udf/file.c | 1
fs/ufs/file.c | 1
include/linux/fs.h | 2
kernel/ksyms.c | 1
mm/filemap.c | 132 ++++-------------------------------------------
23 files changed, 158 insertions, 129 deletions
diff -Nru a/fs/adfs/file.c b/fs/adfs/file.c
--- a/fs/adfs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/adfs/file.c Sun Jul 28 15:25:12 2002
@@ -36,6 +36,7 @@
mmap: generic_file_mmap,
fsync: file_fsync,
write: generic_file_write,
+ sendfile: generic_file_sendfile,
};
struct inode_operations adfs_file_inode_operations = {
diff -Nru a/fs/affs/file.c b/fs/affs/file.c
--- a/fs/affs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/affs/file.c Sun Jul 28 15:25:12 2002
@@ -50,6 +50,7 @@
open: affs_file_open,
release: affs_file_release,
fsync: file_fsync,
+ sendfile: generic_file_sendfile,
};
struct inode_operations affs_file_inode_operations = {
diff -Nru a/fs/bfs/file.c b/fs/bfs/file.c
--- a/fs/bfs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/bfs/file.c Sun Jul 28 15:25:12 2002
@@ -18,10 +18,11 @@
#endif
struct file_operations bfs_file_operations = {
- llseek: generic_file_llseek,
- read: generic_file_read,
- write: generic_file_write,
- mmap: generic_file_mmap,
+ llseek: generic_file_llseek,
+ read: generic_file_read,
+ write: generic_file_write,
+ mmap: generic_file_mmap,
+ sendfile: generic_file_sendfile,
};
static int bfs_move_block(unsigned long from, unsigned long to, struct super_block *sb)
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c Sun Jul 28 15:25:12 2002
+++ b/fs/block_dev.c Sun Jul 28 15:25:12 2002
@@ -774,6 +774,7 @@
mmap: generic_file_mmap,
fsync: block_fsync,
ioctl: blkdev_ioctl,
+ sendfile: generic_file_sendfile,
};
int ioctl_by_bdev(struct block_device *bdev, unsigned cmd, unsigned long arg)
diff -Nru a/fs/ext2/file.c b/fs/ext2/file.c
--- a/fs/ext2/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/ext2/file.c Sun Jul 28 15:25:12 2002
@@ -46,6 +46,7 @@
open: generic_file_open,
release: ext2_release_file,
fsync: ext2_sync_file,
+ sendfile: generic_file_sendfile,
};
struct inode_operations ext2_file_inode_operations = {
diff -Nru a/fs/ext3/file.c b/fs/ext3/file.c
--- a/fs/ext3/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/ext3/file.c Sun Jul 28 15:25:12 2002
@@ -84,6 +84,7 @@
open: ext3_open_file, /* BKL not held. Don't need */
release: ext3_release_file, /* BKL not held. Don't need */
fsync: ext3_sync_file, /* BKL held */
+ sendfile: generic_file_sendfile, /* BKL not held. Don't need */
};
struct inode_operations ext3_file_inode_operations = {
diff -Nru a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
--- a/fs/freevxfs/vxfs_inode.c Sun Jul 28 15:25:12 2002
+++ b/fs/freevxfs/vxfs_inode.c Sun Jul 28 15:25:12 2002
@@ -53,6 +53,7 @@
.llseek = generic_file_llseek,
.read = generic_file_read,
.mmap = generic_file_mmap,
+ .sendfile = generic_file_sendfile,
};
diff -Nru a/fs/hpfs/inode.c b/fs/hpfs/inode.c
--- a/fs/hpfs/inode.c Sun Jul 28 15:25:12 2002
+++ b/fs/hpfs/inode.c Sun Jul 28 15:25:12 2002
@@ -21,6 +21,7 @@
open: hpfs_open,
release: hpfs_file_release,
fsync: hpfs_file_fsync,
+ sendfile: generic_file_sendfile,
};
static struct inode_operations hpfs_file_iops =
diff -Nru a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
--- a/fs/jffs/inode-v23.c Sun Jul 28 15:25:12 2002
+++ b/fs/jffs/inode-v23.c Sun Jul 28 15:25:12 2002
@@ -1631,13 +1631,14 @@
static struct file_operations jffs_file_operations =
{
- open: generic_file_open,
- llseek: generic_file_llseek,
- read: generic_file_read,
- write: generic_file_write,
- ioctl: jffs_ioctl,
- mmap: generic_file_mmap,
- fsync: jffs_fsync,
+ open: generic_file_open,
+ llseek: generic_file_llseek,
+ read: generic_file_read,
+ write: generic_file_write,
+ ioctl: jffs_ioctl,
+ mmap: generic_file_mmap,
+ fsync: jffs_fsync,
+ sendfile: generic_file_sendfile,
};
diff -Nru a/fs/jffs2/file.c b/fs/jffs2/file.c
--- a/fs/jffs2/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/jffs2/file.c Sun Jul 28 15:25:12 2002
@@ -82,6 +82,7 @@
ioctl: jffs2_ioctl,
mmap: generic_file_mmap,
fsync: jffs2_fsync
+ sendfile: generic_file_sendfile,
};
/* jffs2_file_inode_operations */
diff -Nru a/fs/jfs/file.c b/fs/jfs/file.c
--- a/fs/jfs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/jfs/file.c Sun Jul 28 15:25:12 2002
@@ -98,5 +98,6 @@
.write = generic_file_write,
.read = generic_file_read,
.mmap = generic_file_mmap,
+ .sendfile = generic_file_sendfile,
.fsync = jfs_fsync,
};
diff -Nru a/fs/minix/file.c b/fs/minix/file.c
--- a/fs/minix/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/minix/file.c Sun Jul 28 15:25:12 2002
@@ -21,6 +21,7 @@
write: generic_file_write,
mmap: generic_file_mmap,
fsync: minix_sync_file,
+ sendfile: generic_file_sendfile,
};
struct inode_operations minix_file_inode_operations = {
diff -Nru a/fs/ntfs/file.c b/fs/ntfs/file.c
--- a/fs/ntfs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/ntfs/file.c Sun Jul 28 15:25:12 2002
@@ -52,6 +52,7 @@
llseek: generic_file_llseek, /* Seek inside file. */
read: generic_file_read, /* Read from file. */
mmap: generic_file_mmap, /* Mmap file. */
+ sendfile: generic_file_sendfile, /* Zero-copy data send */
open: ntfs_file_open, /* Open file. */
};
diff -Nru a/fs/qnx4/file.c b/fs/qnx4/file.c
--- a/fs/qnx4/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/qnx4/file.c Sun Jul 28 15:25:12 2002
@@ -33,6 +33,7 @@
#ifdef CONFIG_QNX4FS_RW
fsync: qnx4_sync_file,
#endif
+ sendfile: generic_file_sendfile,
};
struct inode_operations qnx4_file_inode_operations =
diff -Nru a/fs/ramfs/inode.c b/fs/ramfs/inode.c
--- a/fs/ramfs/inode.c Sun Jul 28 15:25:12 2002
+++ b/fs/ramfs/inode.c Sun Jul 28 15:25:12 2002
@@ -276,6 +276,7 @@
write: generic_file_write,
mmap: generic_file_mmap,
fsync: ramfs_sync_file,
+ sendfile: generic_file_sendfile,
};
static struct inode_operations ramfs_dir_inode_operations = {
diff -Nru a/fs/read_write.c b/fs/read_write.c
--- a/fs/read_write.c Sun Jul 28 15:25:12 2002
+++ b/fs/read_write.c Sun Jul 28 15:25:12 2002
@@ -19,6 +19,7 @@
llseek: generic_file_llseek,
read: generic_file_read,
mmap: generic_file_mmap,
+ sendfile: generic_file_sendfile,
};
loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
@@ -435,4 +436,114 @@
bad_file:
return ret;
+}
+
+static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
+ size_t count, loff_t max)
+{
+ struct file * in_file, * out_file;
+ struct inode * in_inode, * out_inode;
+ loff_t pos;
+ ssize_t retval;
+
+ /*
+ * Get input file, and verify that it is ok..
+ */
+ retval = -EBADF;
+ in_file = fget(in_fd);
+ if (!in_file)
+ goto out;
+ if (!(in_file->f_mode & FMODE_READ))
+ goto fput_in;
+ retval = -EINVAL;
+ in_inode = in_file->f_dentry->d_inode;
+ if (!in_inode)
+ goto fput_in;
+ if (!in_file->f_op || !in_file->f_op->sendfile)
+ goto fput_in;
+ retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, in_file->f_pos, count);
+ if (retval)
+ goto fput_in;
+
+ /*
+ * Get output file, and verify that it is ok..
+ */
+ retval = -EBADF;
+ out_file = fget(out_fd);
+ if (!out_file)
+ goto fput_in;
+ if (!(out_file->f_mode & FMODE_WRITE))
+ goto fput_out;
+ retval = -EINVAL;
+ if (!out_file->f_op || !out_file->f_op->sendpage)
+ goto fput_out;
+ out_inode = out_file->f_dentry->d_inode;
+ retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count);
+ if (retval)
+ goto fput_out;
+
+ if (!ppos)
+ ppos = &in_file->f_pos;
+
+ if (!max)
+ max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
+
+ pos = *ppos;
+ retval = -EINVAL;
+ if (unlikely(pos < 0))
+ goto fput_out;
+ if (unlikely(pos + count > max)) {
+ retval = -EOVERFLOW;
+ if (pos >= max)
+ goto fput_out;
+ count = max - pos;
+ }
+
+ retval = in_file->f_op->sendfile(out_file, in_file, ppos, count);
+
+ if (*ppos > max)
+ retval = -EOVERFLOW;
+
+fput_out:
+ fput(out_file);
+fput_in:
+ fput(in_file);
+out:
+ return retval;
+}
+
+asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
+{
+ loff_t pos;
+ off_t off;
+ ssize_t ret;
+
+ if (offset) {
+ if (unlikely(get_user(off, offset)))
+ return -EFAULT;
+ pos = off;
+ ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
+ if (unlikely(put_user(pos, offset)))
+ return -EFAULT;
+ return ret;
+ }
+
+ return do_sendfile(out_fd, in_fd, NULL, count, MAX_NON_LFS);
+}
+
+asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count)
+{
+ loff_t pos;
+ ssize_t ret;
+
+ if (offset) {
+ if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
+ return -EFAULT;
+ ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
+ if (unlikely(put_user(pos, offset)))
+ return -EFAULT;
+ return ret;
+ }
+
+ return do_sendfile(out_fd, in_fd, NULL, count, 0);
}
diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/reiserfs/file.c Sun Jul 28 15:25:12 2002
@@ -147,6 +147,7 @@
mmap: generic_file_mmap,
release: reiserfs_file_release,
fsync: reiserfs_sync_file,
+ sendfile: generic_file_sendfile,
};
diff -Nru a/fs/sysv/file.c b/fs/sysv/file.c
--- a/fs/sysv/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/sysv/file.c Sun Jul 28 15:25:12 2002
@@ -25,6 +25,7 @@
write: generic_file_write,
mmap: generic_file_mmap,
fsync: sysv_sync_file,
+ sendfile: generic_file_sendfile,
};
struct inode_operations sysv_file_inode_operations = {
diff -Nru a/fs/udf/file.c b/fs/udf/file.c
--- a/fs/udf/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/udf/file.c Sun Jul 28 15:25:12 2002
@@ -365,6 +365,7 @@
write: udf_file_write,
release: udf_release_file,
fsync: udf_fsync_file,
+ sendfile: generic_file_sendfile,
};
struct inode_operations udf_file_inode_operations = {
diff -Nru a/fs/ufs/file.c b/fs/ufs/file.c
--- a/fs/ufs/file.c Sun Jul 28 15:25:12 2002
+++ b/fs/ufs/file.c Sun Jul 28 15:25:12 2002
@@ -47,6 +47,7 @@
write: generic_file_write,
mmap: generic_file_mmap,
open: generic_file_open,
+ sendfile: generic_file_sendfile,
};
struct inode_operations ufs_file_inode_operations = {
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h Sun Jul 28 15:25:12 2002
+++ b/include/linux/fs.h Sun Jul 28 15:25:12 2002
@@ -757,6 +757,7 @@
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
+ ssize_t (*sendfile) (struct file *, struct file *, loff_t *, size_t);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
};
@@ -1234,6 +1235,7 @@
extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *);
+extern ssize_t generic_file_sendfile(struct file *, struct file *, loff_t *, size_t);
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
ssize_t generic_file_direct_IO(int rw, struct inode *inode, char *buf,
loff_t offset, size_t count);
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c Sun Jul 28 15:25:12 2002
+++ b/kernel/ksyms.c Sun Jul 28 15:25:12 2002
@@ -218,6 +218,7 @@
EXPORT_SYMBOL(block_truncate_page);
EXPORT_SYMBOL(generic_block_bmap);
EXPORT_SYMBOL(generic_file_read);
+EXPORT_SYMBOL(generic_file_sendfile);
EXPORT_SYMBOL(do_generic_file_read);
EXPORT_SYMBOL(generic_file_write);
EXPORT_SYMBOL(generic_file_mmap);
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c Sun Jul 28 15:25:12 2002
+++ b/mm/filemap.c Sun Jul 28 15:25:12 2002
@@ -1119,127 +1119,23 @@
return written;
}
-static ssize_t common_sendfile(int out_fd, int in_fd, loff_t *offset, size_t count, loff_t max)
+ssize_t generic_file_sendfile(struct file *in_file, struct file *out_file,
+ loff_t *ppos, size_t count)
{
- ssize_t retval;
- struct file * in_file, * out_file;
- struct inode * in_inode, * out_inode;
+ read_descriptor_t desc;
- /*
- * Get input file, and verify that it is ok..
- */
- retval = -EBADF;
- in_file = fget(in_fd);
- if (!in_file)
- goto out;
- if (!(in_file->f_mode & FMODE_READ))
- goto fput_in;
- retval = -EINVAL;
- in_inode = in_file->f_dentry->d_inode;
- if (!in_inode)
- goto fput_in;
- if (!in_inode->i_mapping->a_ops->readpage)
- goto fput_in;
- retval = locks_verify_area(FLOCK_VERIFY_READ, in_inode, in_file, in_file->f_pos, count);
- if (retval)
- goto fput_in;
+ if (!count)
+ return 0;
- retval = security_ops->file_permission (in_file, MAY_READ);
- if (retval)
- goto fput_in;
-
- /*
- * Get output file, and verify that it is ok..
- */
- retval = -EBADF;
- out_file = fget(out_fd);
- if (!out_file)
- goto fput_in;
- if (!(out_file->f_mode & FMODE_WRITE))
- goto fput_out;
- retval = -EINVAL;
- if (!out_file->f_op || !out_file->f_op->sendpage)
- goto fput_out;
- out_inode = out_file->f_dentry->d_inode;
- retval = locks_verify_area(FLOCK_VERIFY_WRITE, out_inode, out_file, out_file->f_pos, count);
- if (retval)
- goto fput_out;
-
- retval = security_ops->file_permission (out_file, MAY_WRITE);
- if (retval)
- goto fput_out;
-
- retval = 0;
- if (count) {
- read_descriptor_t desc;
- loff_t pos;
-
- if (!offset)
- offset = &in_file->f_pos;
-
- pos = *offset;
- retval = -EINVAL;
- if (unlikely(pos < 0))
- goto fput_out;
- if (unlikely(pos + count > max)) {
- retval = -EOVERFLOW;
- if (pos >= max)
- goto fput_out;
- count = max - pos;
- }
-
- desc.written = 0;
- desc.count = count;
- desc.buf = (char *) out_file;
- desc.error = 0;
- do_generic_file_read(in_file, offset, &desc, file_send_actor);
-
- retval = desc.written;
- if (!retval)
- retval = desc.error;
- pos = *offset;
- if (pos > max)
- retval = -EOVERFLOW;
- }
-
-fput_out:
- fput(out_file);
-fput_in:
- fput(in_file);
-out:
- return retval;
-}
-
-asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
-{
- loff_t pos, *ppos = NULL;
- ssize_t ret;
- if (offset) {
- off_t off;
- if (unlikely(get_user(off, offset)))
- return -EFAULT;
- pos = off;
- ppos = &pos;
- }
- ret = common_sendfile(out_fd, in_fd, ppos, count, MAX_NON_LFS);
- if (offset && put_user(pos, offset))
- ret = -EFAULT;
- return ret;
-}
-
-asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count)
-{
- loff_t pos, *ppos = NULL;
- ssize_t ret;
- if (offset) {
- if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
- return -EFAULT;
- ppos = &pos;
- }
- ret = common_sendfile(out_fd, in_fd, ppos, count, MAX_LFS_FILESIZE);
- if (offset && put_user(pos, offset))
- ret = -EFAULT;
- return ret;
+ desc.written = 0;
+ desc.count = count;
+ desc.buf = (char *)out_file;
+ desc.error = 0;
+
+ do_generic_file_read(in_file, ppos, &desc, file_send_actor);
+ if (desc.written)
+ return desc.written;
+ return desc.error;
}
static ssize_t
===================================================================
This BitKeeper patch contains the following changesets:
1.477
## Wrapped with gzip_uu ##
begin 664 bkpatch8946
M'XL(`+CP0ST``]5<>W/;-A+_6_P4N.E,SDXM&2\2I'/..&F2.T_=II,^[C&=
MT8`D:*F62!U)^>(>[[O?`A0E2B0M2FDFXSST`,'%[OX6NXL%J*_0SYE*+P:3
M8&)]A?Z69/G%(/-'?A8F\6P:JU&2WL*%#TD"%\Y3M4C.H7GY<4A'M@47?I!Y
M,$'W*LTN!F3$UBWYPT)=##Z\_>O/-Z\^6-;E)?IF(N-;]:/*T>6EE2?IO9R%
MV97,)[,D'N6IC+.YRN4H2.;%NFM!,:;PUR:"8=LIB(.Y*`(2$B(Y42&FW'6X
MM9#+V3*[RN3<EYKA70*""LR80VF!B>-AZPTB(RX$PO0<BW,J$!$7E%]@\36F
M%Q@C4,;5KA+0UY2A(;9>HS^6]V^L`/WR[L<+-)TO9FJNXAQE*@ZCZ4PA\Y(L
M5"KS:1)#1_CWS3)-H=/L`>43M>F:/62!G,TR-)%I&"2A0C++EO.%OC%#TD^6
MN;X!"*S',411$AE"J9+ASGC93M<10J]F^219WDXTF1P%$Q7<92A*4D-BD2I@
M)U":I#0$%_(6^`A#N)`-LX4,MJ71PP'?N9K#4#&ZT7:%9`IRITJ!FFLJ,>R%
MTRA2*^&C-)D#"3WNK8I5.@V,$6J)3E8-8TU_K.\\!=:_D_'#UHC9,M!RR`SE
M\T64G:%L[D<9`F$^PELP2;(='D#B.@<R#E&L5*AIA.%4RR1G:)8$=]/X]@PX
M!B.9ABLEIRMEC9#U+7*8*ZP?-A/"&A[XQ[*PQ-;+/98XGY]K>>=R,0KJQN@Q
MK\"<,U&$4OK*B^#5=X3KAZV&WT('YA.Q*:&X<!@C?"\G=RJ-U>S\+GN89TU>
MX!VS0H2"1:X,0CMRJ2>"=E[:*&VX81AS>R\W47;^6P0OTQBFR?">LB9+3%"/
M%5$H`IBTS(X\%0:"M;/426[%%P$).67[\9K&P6P9JM*_GD?9:+++%G%L0,W!
MRG/=4$11Z/C*:>>JB]B&*8=3V^VC+%_;]#A4][MZ<L&=>LPNA..[A&#;)UC*
M@'>841NE#3?,Q9Z&[O6WNF.<PXLV.NA(/($Q@;\,>H#EPA=6J$A%W`UMX2KJ
MTZ`;FCJEG2$)>.1^"M@AL0&$,L'A%?QYY-#(#Z52=D2[Y>_DA3)&G3Z\J(\Y
M;67&!7DXA!E/4<'#D`2NE"&U.WEI$-HPPQGG^\T5:,BP0S,N".0Z`)-R)>$N
M)\P//>)V<].@5(/)=FQM&0N=5W2RHD/&/3CN<_TR-G.QSI1+'.J`UZ/8+;Q0
MA`$0MQV?.QZ/.IEZA&:-/4?07E:T#*,.*R+<HZ!U5S'IALQW!5<B[-;5+J&:
M%>DLIP\O.BB._Y-.\Q;D,"A+%#9UN()<Q8W"2+C"[>2F26K##V:`>2]^Y+SR
MH$WU<$X\I[!MQD$SGB!"<$:Z)UD+K1I'#G=ZH26C3M-FG&!<1($G?&8[$GNA
M=%FW%34HU>("!LWVX6:RZ%(/3'M;Z+Q22$%M)IDC?$A'.L)G*ZFZ=C`6>Z=:
MJJ:P9&A3CXT9+2`A`#>M?.$+.Q`^F%'$NHVYE5@M2#%P)'TT]._X(^_`B[L0
M?V&2,<7`+Y(0+#IR_$Z.&I1J<YT*F^[5C\X&&CZ:PK32>1=$;E$007WN1V#)
M*O1=W@U6DU1]LMO"63-S-U/3.SE?C.0RRZ?Q:.K/-_SL0$4IL3&Q28&%ZS+0
M,=@R"\%UV*[MVX^E.9WA2X!\>Q4#(8<U]:(1!DYL&T,@M5WFN@$!5@+LDL>"
M%^M4BR>\/A8#ZX#[KDCJ84(*5ZC(Q1`F"*&.DMTNL$&IQ@WWO%ZA=#Z-IQ\[
MV,&.:XO"#\+`<8BG'"<(/=7)39-2C1V;V*Q7L.KV?H0+\%R.X%)BQ51`A:-$
M=[#JM!G&./5,96`[3=/E@2.S0$M.)257@805JS^*80W>F@&:U0+@"HIE$`UT
M-0#BR58Q@%P0[]%B`/E<M8`A6F;K-6VYA*T6^;!T+'/6]VB8_L?\@[7@#SOZ
M.V(U>6US1"PTJ`:Z&+2.?S8X?X[^I=)D&"2+!P1K6VD*$.CY>85C;6)J'/]@
M?V!I+*9QE,H0LHY.9Z"=K<-A+0BQT>:.`=A^&OB6WJN);TW&8_!U'<"W%[RO
MO[U!<9*CB9J%(X3>)/&?<U/FJ('<FA?OA_L34O1VX!\A:%-&/!M\54$@;;3+
M.8Z?A@V4*XJF#;2*>]1LM[4UC-:UP\M!AT%4@-?3D/TX'Y[_6/)N,;_Z?;K0
M)""#::?"V0I8N)]3]J0P+9.U)J9U*8^:V+S/Q*YPW$FV]T-Y3*IOW8*=QE>@
M05_&X2B6<UUR?92BS3"DYZ#BPO8\IW381#P-9,L52A/9'4&/`9=P3X=E^-,7
MX-]:L/T#5P96-I&WMP^'D!0P7VWF4E902!]+1^P^#63+14W;G/TD4$%,G6NM
MW>_@LIV#-:BUVMC^K;-CJG)6*._5;U<9*&,4JE82$$K!Z;I:G=3&U,#H/`T8
MR_IA$\::C,?@R-Q#/&^M"-0/PT/+3^T94H-,E1?1@@M!R^E(GT@,+:ME+4!&
MGP2D30\!TC\,QT.W#MIAW*6R01$\%!/'94(V&O(OX57-3D<31?]30'Q#">+6
M->7(M@:S6:;4W07:1K)L/;,&NF!]L9/QZC:X9,K8N]=,(UR<S^5B]YIN.SO`
M>#;[7_VLY]"=-^M^FB97<Z`W6F3+D0J7'=MNQIN#_3#N\=*;"_8TO$"Y4=AB
M/QLAC_$"0O1:(M?J'/00/W#HMETS)+=0\"CA$-L*CJDKGE)(+C<86ZL<G[(8
MX@>%Y/I&2"\,#]^$:??F33J5/[<+0-+FI3\G3P-+LV74A+(NY#%84G8(EKL'
M,'KA>=PAD'87VW4"1/M93^_T$5CA&ES9H95(%PW%E\BVS)F5]HI%7=)CHC5Q
M&$<"UD(.Q\BU!LE"Q;NA5;>=K8/YX`\.YM,DR&=P44LS-E\>C_!1]A`'57_S
MY8"P7]^1Z669!V\&M3N:)IF-HZ'P'3^M$IK9NVH:9%W*S^]I:KO#O:`\>%^Z
M&?E;2)217Q1Z+VQUG/5I@%CNH#=!K,EXU&+<WL9P7QVT?D2D%XQ''%#9$)TD
M<]6+I,".KI+K<\H,)FFY.G\BR)J#-2UET+J41TU/<5!65S^.U`_9@X]"Z0+W
M[=5=FLA)-Q'(`XG+78P+APL7'[G)3#XCF"WGS3>'R%5JUEJZ.-A6VMY(>Q2D
MI!>BUYR!G@BV_F?]:F7Z#'J`LFSZNQKG*$S6'4^F($*RS,=1>(;TYVEL/LZ2
M*(*>SQ>+)(-@/1CH.GIY=Y`LXWS=8RX_GEK_!8;R=!GDY2'XYX:*9@,^&N+P
M^<6ZC['GLI/Y6/4R7Z#;BC*,K.]9C9JJ'$!\`<(,SI];`[CEKTJ36BS+0<_,
MD?)[4$6D#_=+<^)\FJ'D;C32W<]UNJ-)H$LT?/OZU9MW0'S%)C1%MRH_,;*?
MZO8(G?QI=?$4I+]-\D2S6%TZ65T;OHS&<RW,,_3NN_=OWHX_O'WUYG1]1[0P
M4KW8&OKZ^U]>W91CEXJX1#5J(9A4^C!\&:ZU4?%BOK>0KO.J*20+5!1HNV7X
MLL+[,=YT#2`;ERH<2[#3DW<W[[_Y=OS+VP_7[_YI9#NK@;;&N#:4MI;20"HU
MEM2;PV[C"+K])"`K(ZN0+"UZ#65UN4M])U6'!J!__W#]T]L=1$M#:(.T/E8-
MB^VF$@S]=$<;V?5$`,KU^YJ&T1<W(\+99H:=K>F>;8W0#SO#Y:\K6;5WT)?U
M.S#R;-L2-OV,DQ@,X`UZ0<IY4EG1\.5TG/F@D3%<\Q]RE=48;5X\-23+P8QK
MZL9A"9'@3LT>3G3OOR#<BF&CX]>E`M!+X]=.$3BV^@#O0:6@V[_#K>9>?<O+
M2[02KT%^4!(S'2!FE/QJ?[RAV3%-3S80K:?98@N@E6J-%E;L=O'ZJU7Q=`%K
M,?BXI@YT5C.ANE(YO1=6V1T(+M-X[7TU\S*;0Y"]TT\G5<X90M_>B+(**/"6
M*0@?]6!B`LB6UR\_P^MV!%B+75(I\=D"$2;_&!*M5/<P8^IN!OM*E.';=Z]^
MOOE)PU,:4CF*O@Q?ZJ%Q(X1Y>[;1_QGZ[M4_QM^__WY\\^['TQ>[3&B5&B;,
M'7N8V&BX9ARZY1%6OO_YYJ:#E1X(.7Q?U.\'TD'`Z$-O8_W<6:F99S75E.,D
MT4E)_?0Q51T`$?[2P&@&5HEU[9!KK[SZX..U[86U!AF;4LC*X7\!_X_=^_I2
M)0QS&KB94->$/&Z)=,@*:?/X2"\<#WULI;T4M4NE*D3ILV!$/*V*=_F431/%
MC8Q'E3`<<5`-8W.PNA^,!Q[H[H"QL1%=GK1U"H;AMJ=TNJ<\?MZ"XB<=)C`G
MMOI-Q>83FON!//(1T=V*1??#H571PL;@JLI9:1_J7.EGK%G`"B()EX%ZY!GY
MH7X<&RU2R&3UCQ"8Q].[BU;Z&=@=(VAJYZ@-9;LTA56&<?)\O7Y%)UN5!L@=
MMK]6*4R5O$`,OB:4Z?UI]3%7$+XKHJUB'4Y=6^/V@]7[+?&81[H?K8BV/MF-
M;6S;7!]<<QRGBO7>KCU2_*4<C/JX2-(.'+2/,<^C[YC7MJ!'Q7NJCQ"^_<</
M[S_\-/[QG]^]?G]STLK""MOZ`_S[D3W\9P.L#&CETVPF_:R#A*#`-'@6I["Y
MZZ[.;I/&5N@^)#D:$N)^)C!3-4_NP9?,PH[?R&C42=?>IOMPL/YYA!T#J&OG
MJ-U30O61M6OS3JT#G,%Z(;[5NEZHKXJD\&>K=KJSAM+C<\3,^.;,C"D'ARH+
MTND"<-'56?CRPG1T$<!UK8^X`*=E)65%9KTZP:8G%\ASM)_C%'G60%,8Z1)S
MKF)8,$&?LJDJ1YCWJM%?1M!T$DQDBIZ?UJJUYJI*4X@`A@8L@&#ET]@L/MDI
M4#S3]YVAM2+',@"YJI)2G;6:&/7F%]96J^'@Q>;7<LJ?`EG.+P/7\7PNA/5_
(U8`]%(9'````
`
end
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-07-28 12:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-28 12:29 [PATCH] Rework sendfile code to use a file operation (3rd resend) Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox