[PATCH] Remove readv/writev methods and use aio_read/aio_write instead
This patch removes readv() and writev() methods and replaces them with aio_read()/aio_write() methods. Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
027445c372
commit
ee0b3e671b
|
@ -257,8 +257,6 @@ static const struct file_operations raw_fops = {
|
||||||
.open = raw_open,
|
.open = raw_open,
|
||||||
.release= raw_release,
|
.release= raw_release,
|
||||||
.ioctl = raw_ioctl,
|
.ioctl = raw_ioctl,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -288,11 +288,10 @@ static inline size_t iov_total(const struct iovec *iv, unsigned long count)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Writev */
|
static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
|
||||||
static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
|
unsigned long count, loff_t pos)
|
||||||
unsigned long count, loff_t *pos)
|
|
||||||
{
|
{
|
||||||
struct tun_struct *tun = file->private_data;
|
struct tun_struct *tun = iocb->ki_filp->private_data;
|
||||||
|
|
||||||
if (!tun)
|
if (!tun)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
@ -302,14 +301,6 @@ static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv,
|
||||||
return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
|
return tun_get_user(tun, (struct iovec *) iv, iov_total(iv, count));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write */
|
|
||||||
static ssize_t tun_chr_write(struct file * file, const char __user * buf,
|
|
||||||
size_t count, loff_t *pos)
|
|
||||||
{
|
|
||||||
struct iovec iv = { (void __user *) buf, count };
|
|
||||||
return tun_chr_writev(file, &iv, 1, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put packet to the user space buffer */
|
/* Put packet to the user space buffer */
|
||||||
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
|
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
|
@ -343,10 +334,10 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Readv */
|
static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
|
||||||
static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
|
unsigned long count, loff_t pos)
|
||||||
unsigned long count, loff_t *pos)
|
|
||||||
{
|
{
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
struct tun_struct *tun = file->private_data;
|
struct tun_struct *tun = file->private_data;
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
DECLARE_WAITQUEUE(wait, current);
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
@ -426,14 +417,6 @@ static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read */
|
|
||||||
static ssize_t tun_chr_read(struct file * file, char __user * buf,
|
|
||||||
size_t count, loff_t *pos)
|
|
||||||
{
|
|
||||||
struct iovec iv = { buf, count };
|
|
||||||
return tun_chr_readv(file, &iv, 1, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tun_setup(struct net_device *dev)
|
static void tun_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct tun_struct *tun = netdev_priv(dev);
|
struct tun_struct *tun = netdev_priv(dev);
|
||||||
|
@ -764,10 +747,10 @@ static int tun_chr_close(struct inode *inode, struct file *file)
|
||||||
static struct file_operations tun_fops = {
|
static struct file_operations tun_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = tun_chr_read,
|
.read = do_sync_read,
|
||||||
.readv = tun_chr_readv,
|
.aio_read = tun_chr_aio_read,
|
||||||
.write = tun_chr_write,
|
.write = do_sync_write,
|
||||||
.writev = tun_chr_writev,
|
.aio_write = tun_chr_aio_write,
|
||||||
.poll = tun_chr_poll,
|
.poll = tun_chr_poll,
|
||||||
.ioctl = tun_chr_ioctl,
|
.ioctl = tun_chr_ioctl,
|
||||||
.open = tun_chr_open,
|
.open = tun_chr_open,
|
||||||
|
|
|
@ -40,8 +40,6 @@ static const struct file_operations bad_file_ops =
|
||||||
.aio_fsync = EIO_ERROR,
|
.aio_fsync = EIO_ERROR,
|
||||||
.fasync = EIO_ERROR,
|
.fasync = EIO_ERROR,
|
||||||
.lock = EIO_ERROR,
|
.lock = EIO_ERROR,
|
||||||
.readv = EIO_ERROR,
|
|
||||||
.writev = EIO_ERROR,
|
|
||||||
.sendfile = EIO_ERROR,
|
.sendfile = EIO_ERROR,
|
||||||
.sendpage = EIO_ERROR,
|
.sendpage = EIO_ERROR,
|
||||||
.get_unmapped_area = EIO_ERROR,
|
.get_unmapped_area = EIO_ERROR,
|
||||||
|
|
|
@ -1191,8 +1191,6 @@ const struct file_operations def_blk_fops = {
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = compat_blkdev_ioctl,
|
.compat_ioctl = compat_blkdev_ioctl,
|
||||||
#endif
|
#endif
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_write_nolock,
|
|
||||||
.sendfile = generic_file_sendfile,
|
.sendfile = generic_file_sendfile,
|
||||||
.splice_read = generic_file_splice_read,
|
.splice_read = generic_file_splice_read,
|
||||||
.splice_write = generic_file_splice_write,
|
.splice_write = generic_file_splice_write,
|
||||||
|
|
|
@ -480,18 +480,6 @@ cifs_get_sb(struct file_system_type *fs_type,
|
||||||
return simple_set_mnt(mnt, sb);
|
return simple_set_mnt(mnt, sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct inode *inode = file->f_dentry->d_inode;
|
|
||||||
ssize_t written;
|
|
||||||
|
|
||||||
written = generic_file_writev(file, iov, nr_segs, ppos);
|
|
||||||
if (!CIFS_I(inode)->clientCanCacheAll)
|
|
||||||
filemap_fdatawrite(inode->i_mapping);
|
|
||||||
return written;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long nr_segs, loff_t pos)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
|
@ -577,8 +565,6 @@ struct inode_operations cifs_symlink_inode_ops = {
|
||||||
const struct file_operations cifs_file_ops = {
|
const struct file_operations cifs_file_ops = {
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = cifs_file_writev,
|
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = cifs_file_aio_write,
|
.aio_write = cifs_file_aio_write,
|
||||||
.open = cifs_open,
|
.open = cifs_open,
|
||||||
|
@ -620,8 +606,6 @@ const struct file_operations cifs_file_direct_ops = {
|
||||||
const struct file_operations cifs_file_nobrl_ops = {
|
const struct file_operations cifs_file_nobrl_ops = {
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = cifs_file_writev,
|
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = cifs_file_aio_write,
|
.aio_write = cifs_file_aio_write,
|
||||||
.open = cifs_open,
|
.open = cifs_open,
|
||||||
|
|
44
fs/compat.c
44
fs/compat.c
|
@ -70,6 +70,8 @@ int compat_printk(const char *fmt, ...)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "read_write.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not all architectures have sys_utime, so implement this in terms
|
* Not all architectures have sys_utime, so implement this in terms
|
||||||
* of sys_utimes.
|
* of sys_utimes.
|
||||||
|
@ -1149,9 +1151,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
|
||||||
const struct compat_iovec __user *uvector,
|
const struct compat_iovec __user *uvector,
|
||||||
unsigned long nr_segs, loff_t *pos)
|
unsigned long nr_segs, loff_t *pos)
|
||||||
{
|
{
|
||||||
typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
|
|
||||||
typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
|
|
||||||
|
|
||||||
compat_ssize_t tot_len;
|
compat_ssize_t tot_len;
|
||||||
struct iovec iovstack[UIO_FASTIOV];
|
struct iovec iovstack[UIO_FASTIOV];
|
||||||
struct iovec *iov=iovstack, *vector;
|
struct iovec *iov=iovstack, *vector;
|
||||||
|
@ -1234,39 +1233,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
|
||||||
fnv = NULL;
|
fnv = NULL;
|
||||||
if (type == READ) {
|
if (type == READ) {
|
||||||
fn = file->f_op->read;
|
fn = file->f_op->read;
|
||||||
fnv = file->f_op->readv;
|
fnv = file->f_op->aio_read;
|
||||||
} else {
|
} else {
|
||||||
fn = (io_fn_t)file->f_op->write;
|
fn = (io_fn_t)file->f_op->write;
|
||||||
fnv = file->f_op->writev;
|
fnv = file->f_op->aio_write;
|
||||||
}
|
|
||||||
if (fnv) {
|
|
||||||
ret = fnv(file, iov, nr_segs, pos);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do it by hand, with file-ops */
|
if (fnv)
|
||||||
ret = 0;
|
ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
|
||||||
vector = iov;
|
pos, fnv);
|
||||||
while (nr_segs > 0) {
|
else
|
||||||
void __user * base;
|
ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
|
||||||
size_t len;
|
|
||||||
ssize_t nr;
|
|
||||||
|
|
||||||
base = vector->iov_base;
|
|
||||||
len = vector->iov_len;
|
|
||||||
vector++;
|
|
||||||
nr_segs--;
|
|
||||||
|
|
||||||
nr = fn(file, base, len, pos);
|
|
||||||
|
|
||||||
if (nr < 0) {
|
|
||||||
if (!ret) ret = nr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret += nr;
|
|
||||||
if (nr != len)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
if (iov != iovstack)
|
if (iov != iovstack)
|
||||||
kfree(iov);
|
kfree(iov);
|
||||||
|
@ -1294,7 +1272,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
|
if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos);
|
ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos);
|
||||||
|
@ -1317,7 +1295,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
|
if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);
|
ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);
|
||||||
|
|
|
@ -53,8 +53,6 @@ const struct file_operations ext2_file_operations = {
|
||||||
.open = generic_file_open,
|
.open = generic_file_open,
|
||||||
.release = ext2_release_file,
|
.release = ext2_release_file,
|
||||||
.fsync = ext2_sync_file,
|
.fsync = ext2_sync_file,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.sendfile = generic_file_sendfile,
|
.sendfile = generic_file_sendfile,
|
||||||
.splice_read = generic_file_splice_read,
|
.splice_read = generic_file_splice_read,
|
||||||
.splice_write = generic_file_splice_write,
|
.splice_write = generic_file_splice_write,
|
||||||
|
|
|
@ -112,8 +112,6 @@ const struct file_operations ext3_file_operations = {
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = ext3_file_write,
|
.aio_write = ext3_file_write,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.ioctl = ext3_ioctl,
|
.ioctl = ext3_ioctl,
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
.compat_ioctl = ext3_compat_ioctl,
|
.compat_ioctl = ext3_compat_ioctl,
|
||||||
|
|
|
@ -127,8 +127,6 @@ const struct file_operations fat_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = generic_file_aio_write,
|
||||||
.mmap = generic_file_mmap,
|
.mmap = generic_file_mmap,
|
||||||
|
|
|
@ -680,14 +680,15 @@ static int fuse_read_interrupt(struct fuse_conn *fc, struct fuse_req *req,
|
||||||
* request_end(). Otherwise add it to the processing list, and set
|
* request_end(). Otherwise add it to the processing list, and set
|
||||||
* the 'sent' flag.
|
* the 'sent' flag.
|
||||||
*/
|
*/
|
||||||
static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
|
static ssize_t fuse_dev_read(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long nr_segs, loff_t *off)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct fuse_req *req;
|
struct fuse_req *req;
|
||||||
struct fuse_in *in;
|
struct fuse_in *in;
|
||||||
struct fuse_copy_state cs;
|
struct fuse_copy_state cs;
|
||||||
unsigned reqsize;
|
unsigned reqsize;
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
struct fuse_conn *fc = fuse_get_conn(file);
|
struct fuse_conn *fc = fuse_get_conn(file);
|
||||||
if (!fc)
|
if (!fc)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
@ -761,15 +762,6 @@ static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t fuse_dev_read(struct file *file, char __user *buf,
|
|
||||||
size_t nbytes, loff_t *off)
|
|
||||||
{
|
|
||||||
struct iovec iov;
|
|
||||||
iov.iov_len = nbytes;
|
|
||||||
iov.iov_base = buf;
|
|
||||||
return fuse_dev_readv(file, &iov, 1, off);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look up request on processing list by unique ID */
|
/* Look up request on processing list by unique ID */
|
||||||
static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
|
static struct fuse_req *request_find(struct fuse_conn *fc, u64 unique)
|
||||||
{
|
{
|
||||||
|
@ -814,15 +806,15 @@ static int copy_out_args(struct fuse_copy_state *cs, struct fuse_out *out,
|
||||||
* it from the list and copy the rest of the buffer to the request.
|
* it from the list and copy the rest of the buffer to the request.
|
||||||
* The request is finished by calling request_end()
|
* The request is finished by calling request_end()
|
||||||
*/
|
*/
|
||||||
static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
|
static ssize_t fuse_dev_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long nr_segs, loff_t *off)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
unsigned nbytes = iov_length(iov, nr_segs);
|
unsigned nbytes = iov_length(iov, nr_segs);
|
||||||
struct fuse_req *req;
|
struct fuse_req *req;
|
||||||
struct fuse_out_header oh;
|
struct fuse_out_header oh;
|
||||||
struct fuse_copy_state cs;
|
struct fuse_copy_state cs;
|
||||||
struct fuse_conn *fc = fuse_get_conn(file);
|
struct fuse_conn *fc = fuse_get_conn(iocb->ki_filp);
|
||||||
if (!fc)
|
if (!fc)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
@ -898,15 +890,6 @@ static ssize_t fuse_dev_writev(struct file *file, const struct iovec *iov,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t fuse_dev_write(struct file *file, const char __user *buf,
|
|
||||||
size_t nbytes, loff_t *off)
|
|
||||||
{
|
|
||||||
struct iovec iov;
|
|
||||||
iov.iov_len = nbytes;
|
|
||||||
iov.iov_base = (char __user *) buf;
|
|
||||||
return fuse_dev_writev(file, &iov, 1, off);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
|
static unsigned fuse_dev_poll(struct file *file, poll_table *wait)
|
||||||
{
|
{
|
||||||
unsigned mask = POLLOUT | POLLWRNORM;
|
unsigned mask = POLLOUT | POLLWRNORM;
|
||||||
|
@ -1041,10 +1024,10 @@ static int fuse_dev_fasync(int fd, struct file *file, int on)
|
||||||
const struct file_operations fuse_dev_operations = {
|
const struct file_operations fuse_dev_operations = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = fuse_dev_read,
|
.read = do_sync_read,
|
||||||
.readv = fuse_dev_readv,
|
.aio_read = fuse_dev_read,
|
||||||
.write = fuse_dev_write,
|
.write = do_sync_write,
|
||||||
.writev = fuse_dev_writev,
|
.aio_write = fuse_dev_write,
|
||||||
.poll = fuse_dev_poll,
|
.poll = fuse_dev_poll,
|
||||||
.release = fuse_dev_release,
|
.release = fuse_dev_release,
|
||||||
.fasync = fuse_dev_fasync,
|
.fasync = fuse_dev_fasync,
|
||||||
|
|
|
@ -389,8 +389,6 @@ static const struct file_operations hostfs_file_fops = {
|
||||||
.sendfile = generic_file_sendfile,
|
.sendfile = generic_file_sendfile,
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = generic_file_aio_write,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.write = generic_file_write,
|
.write = generic_file_write,
|
||||||
.mmap = generic_file_mmap,
|
.mmap = generic_file_mmap,
|
||||||
.open = hostfs_file_open,
|
.open = hostfs_file_open,
|
||||||
|
|
|
@ -108,8 +108,6 @@ const struct file_operations jfs_file_operations = {
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = generic_file_aio_write,
|
||||||
.mmap = generic_file_mmap,
|
.mmap = generic_file_mmap,
|
||||||
.readv = generic_file_readv,
|
|
||||||
.writev = generic_file_writev,
|
|
||||||
.sendfile = generic_file_sendfile,
|
.sendfile = generic_file_sendfile,
|
||||||
.fsync = jfs_fsync,
|
.fsync = jfs_fsync,
|
||||||
.release = jfs_release,
|
.release = jfs_release,
|
||||||
|
|
|
@ -2298,11 +2298,9 @@ const struct file_operations ntfs_file_ops = {
|
||||||
.llseek = generic_file_llseek, /* Seek inside file. */
|
.llseek = generic_file_llseek, /* Seek inside file. */
|
||||||
.read = generic_file_read, /* Read from file. */
|
.read = generic_file_read, /* Read from file. */
|
||||||
.aio_read = generic_file_aio_read, /* Async read from file. */
|
.aio_read = generic_file_aio_read, /* Async read from file. */
|
||||||
.readv = generic_file_readv, /* Read from file. */
|
|
||||||
#ifdef NTFS_RW
|
#ifdef NTFS_RW
|
||||||
.write = ntfs_file_write, /* Write to file. */
|
.write = ntfs_file_write, /* Write to file. */
|
||||||
.aio_write = ntfs_file_aio_write, /* Async write to file. */
|
.aio_write = ntfs_file_aio_write, /* Async write to file. */
|
||||||
.writev = ntfs_file_writev, /* Write to file. */
|
|
||||||
/*.release = ,*/ /* Last file is closed. See
|
/*.release = ,*/ /* Last file is closed. See
|
||||||
fs/ext2/file.c::
|
fs/ext2/file.c::
|
||||||
ext2_release_file() for
|
ext2_release_file() for
|
||||||
|
|
59
fs/pipe.c
59
fs/pipe.c
|
@ -218,9 +218,10 @@ static struct pipe_buf_operations anon_pipe_buf_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
pipe_readv(struct file *filp, const struct iovec *_iov,
|
pipe_read(struct kiocb *iocb, const struct iovec *_iov,
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
|
struct file *filp = iocb->ki_filp;
|
||||||
struct inode *inode = filp->f_dentry->d_inode;
|
struct inode *inode = filp->f_dentry->d_inode;
|
||||||
struct pipe_inode_info *pipe;
|
struct pipe_inode_info *pipe;
|
||||||
int do_wakeup;
|
int do_wakeup;
|
||||||
|
@ -330,17 +331,10 @@ redo:
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
pipe_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
|
pipe_write(struct kiocb *iocb, const struct iovec *_iov,
|
||||||
{
|
unsigned long nr_segs, loff_t ppos)
|
||||||
struct iovec iov = { .iov_base = buf, .iov_len = count };
|
|
||||||
|
|
||||||
return pipe_readv(filp, &iov, 1, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
pipe_writev(struct file *filp, const struct iovec *_iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
{
|
||||||
|
struct file *filp = iocb->ki_filp;
|
||||||
struct inode *inode = filp->f_dentry->d_inode;
|
struct inode *inode = filp->f_dentry->d_inode;
|
||||||
struct pipe_inode_info *pipe;
|
struct pipe_inode_info *pipe;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
@ -509,15 +503,6 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
|
||||||
pipe_write(struct file *filp, const char __user *buf,
|
|
||||||
size_t count, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = count };
|
|
||||||
|
|
||||||
return pipe_writev(filp, &iov, 1, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
|
bad_pipe_r(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
|
@ -736,8 +721,8 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
|
||||||
*/
|
*/
|
||||||
const struct file_operations read_fifo_fops = {
|
const struct file_operations read_fifo_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = pipe_read,
|
.read = do_sync_read,
|
||||||
.readv = pipe_readv,
|
.aio_read = pipe_read,
|
||||||
.write = bad_pipe_w,
|
.write = bad_pipe_w,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
|
@ -749,8 +734,8 @@ const struct file_operations read_fifo_fops = {
|
||||||
const struct file_operations write_fifo_fops = {
|
const struct file_operations write_fifo_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = bad_pipe_r,
|
.read = bad_pipe_r,
|
||||||
.write = pipe_write,
|
.write = do_sync_write,
|
||||||
.writev = pipe_writev,
|
.aio_write = pipe_write,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
.open = pipe_write_open,
|
.open = pipe_write_open,
|
||||||
|
@ -760,10 +745,10 @@ const struct file_operations write_fifo_fops = {
|
||||||
|
|
||||||
const struct file_operations rdwr_fifo_fops = {
|
const struct file_operations rdwr_fifo_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = pipe_read,
|
.read = do_sync_read,
|
||||||
.readv = pipe_readv,
|
.aio_read = pipe_read,
|
||||||
.write = pipe_write,
|
.write = do_sync_write,
|
||||||
.writev = pipe_writev,
|
.aio_write = pipe_write,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
.open = pipe_rdwr_open,
|
.open = pipe_rdwr_open,
|
||||||
|
@ -773,8 +758,8 @@ const struct file_operations rdwr_fifo_fops = {
|
||||||
|
|
||||||
static struct file_operations read_pipe_fops = {
|
static struct file_operations read_pipe_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = pipe_read,
|
.read = do_sync_read,
|
||||||
.readv = pipe_readv,
|
.aio_read = pipe_read,
|
||||||
.write = bad_pipe_w,
|
.write = bad_pipe_w,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
|
@ -786,8 +771,8 @@ static struct file_operations read_pipe_fops = {
|
||||||
static struct file_operations write_pipe_fops = {
|
static struct file_operations write_pipe_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = bad_pipe_r,
|
.read = bad_pipe_r,
|
||||||
.write = pipe_write,
|
.write = do_sync_write,
|
||||||
.writev = pipe_writev,
|
.aio_write = pipe_write,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
.open = pipe_write_open,
|
.open = pipe_write_open,
|
||||||
|
@ -797,10 +782,10 @@ static struct file_operations write_pipe_fops = {
|
||||||
|
|
||||||
static struct file_operations rdwr_pipe_fops = {
|
static struct file_operations rdwr_pipe_fops = {
|
||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
.read = pipe_read,
|
.read = do_sync_read,
|
||||||
.readv = pipe_readv,
|
.aio_read = pipe_read,
|
||||||
.write = pipe_write,
|
.write = do_sync_write,
|
||||||
.writev = pipe_writev,
|
.aio_write = pipe_write,
|
||||||
.poll = pipe_poll,
|
.poll = pipe_poll,
|
||||||
.ioctl = pipe_ioctl,
|
.ioctl = pipe_ioctl,
|
||||||
.open = pipe_rdwr_open,
|
.open = pipe_rdwr_open,
|
||||||
|
|
101
fs/read_write.c
101
fs/read_write.c
|
@ -15,6 +15,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
|
#include "read_write.h"
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
@ -450,6 +451,62 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
|
||||||
|
|
||||||
EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
|
EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
|
||||||
|
|
||||||
|
ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
|
||||||
|
unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
|
||||||
|
{
|
||||||
|
struct kiocb kiocb;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
init_sync_kiocb(&kiocb, filp);
|
||||||
|
kiocb.ki_pos = *ppos;
|
||||||
|
kiocb.ki_left = len;
|
||||||
|
kiocb.ki_nbytes = len;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
|
||||||
|
if (ret != -EIOCBRETRY)
|
||||||
|
break;
|
||||||
|
wait_on_retry_sync_kiocb(&kiocb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == -EIOCBQUEUED)
|
||||||
|
ret = wait_on_sync_kiocb(&kiocb);
|
||||||
|
*ppos = kiocb.ki_pos;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do it by hand, with file-ops */
|
||||||
|
ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
|
||||||
|
unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
|
||||||
|
{
|
||||||
|
struct iovec *vector = iov;
|
||||||
|
ssize_t ret = 0;
|
||||||
|
|
||||||
|
while (nr_segs > 0) {
|
||||||
|
void __user *base;
|
||||||
|
size_t len;
|
||||||
|
ssize_t nr;
|
||||||
|
|
||||||
|
base = vector->iov_base;
|
||||||
|
len = vector->iov_len;
|
||||||
|
vector++;
|
||||||
|
nr_segs--;
|
||||||
|
|
||||||
|
nr = fn(filp, base, len, ppos);
|
||||||
|
|
||||||
|
if (nr < 0) {
|
||||||
|
if (!ret)
|
||||||
|
ret = nr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret += nr;
|
||||||
|
if (nr != len)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* A write operation does a read from user space and vice versa */
|
/* A write operation does a read from user space and vice versa */
|
||||||
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
|
#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
|
||||||
|
|
||||||
|
@ -457,12 +514,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
|
||||||
const struct iovec __user * uvector,
|
const struct iovec __user * uvector,
|
||||||
unsigned long nr_segs, loff_t *pos)
|
unsigned long nr_segs, loff_t *pos)
|
||||||
{
|
{
|
||||||
typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
|
|
||||||
typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
|
|
||||||
|
|
||||||
size_t tot_len;
|
size_t tot_len;
|
||||||
struct iovec iovstack[UIO_FASTIOV];
|
struct iovec iovstack[UIO_FASTIOV];
|
||||||
struct iovec *iov=iovstack, *vector;
|
struct iovec *iov = iovstack;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
int seg;
|
int seg;
|
||||||
io_fn_t fn;
|
io_fn_t fn;
|
||||||
|
@ -532,39 +586,18 @@ static ssize_t do_readv_writev(int type, struct file *file,
|
||||||
fnv = NULL;
|
fnv = NULL;
|
||||||
if (type == READ) {
|
if (type == READ) {
|
||||||
fn = file->f_op->read;
|
fn = file->f_op->read;
|
||||||
fnv = file->f_op->readv;
|
fnv = file->f_op->aio_read;
|
||||||
} else {
|
} else {
|
||||||
fn = (io_fn_t)file->f_op->write;
|
fn = (io_fn_t)file->f_op->write;
|
||||||
fnv = file->f_op->writev;
|
fnv = file->f_op->aio_write;
|
||||||
}
|
|
||||||
if (fnv) {
|
|
||||||
ret = fnv(file, iov, nr_segs, pos);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do it by hand, with file-ops */
|
if (fnv)
|
||||||
ret = 0;
|
ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
|
||||||
vector = iov;
|
pos, fnv);
|
||||||
while (nr_segs > 0) {
|
else
|
||||||
void __user * base;
|
ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
|
||||||
size_t len;
|
|
||||||
ssize_t nr;
|
|
||||||
|
|
||||||
base = vector->iov_base;
|
|
||||||
len = vector->iov_len;
|
|
||||||
vector++;
|
|
||||||
nr_segs--;
|
|
||||||
|
|
||||||
nr = fn(file, base, len, pos);
|
|
||||||
|
|
||||||
if (nr < 0) {
|
|
||||||
if (!ret) ret = nr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ret += nr;
|
|
||||||
if (nr != len)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
if (iov != iovstack)
|
if (iov != iovstack)
|
||||||
kfree(iov);
|
kfree(iov);
|
||||||
|
@ -585,7 +618,7 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
|
||||||
{
|
{
|
||||||
if (!(file->f_mode & FMODE_READ))
|
if (!(file->f_mode & FMODE_READ))
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
|
if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return do_readv_writev(READ, file, vec, vlen, pos);
|
return do_readv_writev(READ, file, vec, vlen, pos);
|
||||||
|
@ -598,7 +631,7 @@ ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
|
||||||
{
|
{
|
||||||
if (!(file->f_mode & FMODE_WRITE))
|
if (!(file->f_mode & FMODE_WRITE))
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
|
if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return do_readv_writev(WRITE, file, vec, vlen, pos);
|
return do_readv_writev(WRITE, file, vec, vlen, pos);
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* This file is only for sharing some helpers from read_write.c with compat.c.
|
||||||
|
* Don't use anywhere else.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
|
||||||
|
typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
|
||||||
|
unsigned long, loff_t);
|
||||||
|
|
||||||
|
ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
|
||||||
|
unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn);
|
||||||
|
ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
|
||||||
|
unsigned long nr_segs, loff_t *ppos, io_fn_t fn);
|
|
@ -123,96 +123,6 @@ xfs_file_aio_write_invis(
|
||||||
return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
|
return __xfs_file_write(iocb, iov, nr_segs, IO_ISAIO|IO_INVIS, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC inline ssize_t
|
|
||||||
__xfs_file_readv(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
int ioflags,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct inode *inode = file->f_mapping->host;
|
|
||||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
|
||||||
struct kiocb kiocb;
|
|
||||||
ssize_t rval;
|
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, file);
|
|
||||||
kiocb.ki_pos = *ppos;
|
|
||||||
|
|
||||||
if (unlikely(file->f_flags & O_DIRECT))
|
|
||||||
ioflags |= IO_ISDIRECT;
|
|
||||||
rval = bhv_vop_read(vp, &kiocb, iov, nr_segs,
|
|
||||||
&kiocb.ki_pos, ioflags, NULL);
|
|
||||||
|
|
||||||
*ppos = kiocb.ki_pos;
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC ssize_t
|
|
||||||
xfs_file_readv(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
return __xfs_file_readv(file, iov, 0, nr_segs, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC ssize_t
|
|
||||||
xfs_file_readv_invis(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC inline ssize_t
|
|
||||||
__xfs_file_writev(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
int ioflags,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct inode *inode = file->f_mapping->host;
|
|
||||||
bhv_vnode_t *vp = vn_from_inode(inode);
|
|
||||||
struct kiocb kiocb;
|
|
||||||
ssize_t rval;
|
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, file);
|
|
||||||
kiocb.ki_pos = *ppos;
|
|
||||||
if (unlikely(file->f_flags & O_DIRECT))
|
|
||||||
ioflags |= IO_ISDIRECT;
|
|
||||||
|
|
||||||
rval = bhv_vop_write(vp, &kiocb, iov, nr_segs,
|
|
||||||
&kiocb.ki_pos, ioflags, NULL);
|
|
||||||
|
|
||||||
*ppos = kiocb.ki_pos;
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC ssize_t
|
|
||||||
xfs_file_writev(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
return __xfs_file_writev(file, iov, 0, nr_segs, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC ssize_t
|
|
||||||
xfs_file_writev_invis(
|
|
||||||
struct file *file,
|
|
||||||
const struct iovec *iov,
|
|
||||||
unsigned long nr_segs,
|
|
||||||
loff_t *ppos)
|
|
||||||
{
|
|
||||||
return __xfs_file_writev(file, iov, IO_INVIS, nr_segs, ppos);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC ssize_t
|
STATIC ssize_t
|
||||||
xfs_file_sendfile(
|
xfs_file_sendfile(
|
||||||
struct file *filp,
|
struct file *filp,
|
||||||
|
@ -540,8 +450,6 @@ const struct file_operations xfs_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.readv = xfs_file_readv,
|
|
||||||
.writev = xfs_file_writev,
|
|
||||||
.aio_read = xfs_file_aio_read,
|
.aio_read = xfs_file_aio_read,
|
||||||
.aio_write = xfs_file_aio_write,
|
.aio_write = xfs_file_aio_write,
|
||||||
.sendfile = xfs_file_sendfile,
|
.sendfile = xfs_file_sendfile,
|
||||||
|
@ -565,8 +473,6 @@ const struct file_operations xfs_invis_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.readv = xfs_file_readv_invis,
|
|
||||||
.writev = xfs_file_writev_invis,
|
|
||||||
.aio_read = xfs_file_aio_read_invis,
|
.aio_read = xfs_file_aio_read_invis,
|
||||||
.aio_write = xfs_file_aio_write_invis,
|
.aio_write = xfs_file_aio_write_invis,
|
||||||
.sendfile = xfs_file_sendfile_invis,
|
.sendfile = xfs_file_sendfile_invis,
|
||||||
|
|
|
@ -1113,8 +1113,6 @@ struct file_operations {
|
||||||
int (*aio_fsync) (struct kiocb *, int datasync);
|
int (*aio_fsync) (struct kiocb *, int datasync);
|
||||||
int (*fasync) (int, struct file *, int);
|
int (*fasync) (int, struct file *, int);
|
||||||
int (*lock) (struct file *, int, struct file_lock *);
|
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 *, loff_t *, size_t, read_actor_t, void *);
|
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
|
||||||
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
|
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);
|
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
|
||||||
|
@ -1734,10 +1732,6 @@ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
|
file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
|
||||||
extern ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos);
|
|
||||||
ssize_t generic_file_writev(struct file *filp, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos);
|
|
||||||
extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
|
extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
|
||||||
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
|
extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
|
||||||
extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
|
extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
|
||||||
|
|
36
mm/filemap.c
36
mm/filemap.c
|
@ -2421,42 +2421,6 @@ ssize_t generic_file_write(struct file *file, const char __user *buf,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_file_write);
|
EXPORT_SYMBOL(generic_file_write);
|
||||||
|
|
||||||
ssize_t generic_file_readv(struct file *filp, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct kiocb kiocb;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
init_sync_kiocb(&kiocb, filp);
|
|
||||||
ret = __generic_file_aio_read(&kiocb, iov, nr_segs, ppos);
|
|
||||||
if (-EIOCBQUEUED == ret)
|
|
||||||
ret = wait_on_sync_kiocb(&kiocb);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(generic_file_readv);
|
|
||||||
|
|
||||||
ssize_t generic_file_writev(struct file *file, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct address_space *mapping = file->f_mapping;
|
|
||||||
struct inode *inode = mapping->host;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
|
||||||
ret = __generic_file_write_nolock(file, iov, nr_segs, ppos);
|
|
||||||
mutex_unlock(&inode->i_mutex);
|
|
||||||
|
|
||||||
if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = sync_page_range(inode, mapping, *ppos - ret, ret);
|
|
||||||
if (err < 0)
|
|
||||||
ret = err;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(generic_file_writev);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called under i_mutex for writes to S_ISREG files. Returns -EIO if something
|
* Called under i_mutex for writes to S_ISREG files. Returns -EIO if something
|
||||||
* went wrong during pagecache shootdown.
|
* went wrong during pagecache shootdown.
|
||||||
|
|
40
net/socket.c
40
net/socket.c
|
@ -110,10 +110,6 @@ static long compat_sock_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg);
|
unsigned int cmd, unsigned long arg);
|
||||||
#endif
|
#endif
|
||||||
static int sock_fasync(int fd, struct file *filp, int on);
|
static int sock_fasync(int fd, struct file *filp, int on);
|
||||||
static ssize_t sock_readv(struct file *file, const struct iovec *vector,
|
|
||||||
unsigned long count, loff_t *ppos);
|
|
||||||
static ssize_t sock_writev(struct file *file, const struct iovec *vector,
|
|
||||||
unsigned long count, loff_t *ppos);
|
|
||||||
static ssize_t sock_sendpage(struct file *file, struct page *page,
|
static ssize_t sock_sendpage(struct file *file, struct page *page,
|
||||||
int offset, size_t size, loff_t *ppos, int more);
|
int offset, size_t size, loff_t *ppos, int more);
|
||||||
|
|
||||||
|
@ -136,8 +132,6 @@ static struct file_operations socket_file_ops = {
|
||||||
.open = sock_no_open, /* special open code to disallow open via /proc */
|
.open = sock_no_open, /* special open code to disallow open via /proc */
|
||||||
.release = sock_close,
|
.release = sock_close,
|
||||||
.fasync = sock_fasync,
|
.fasync = sock_fasync,
|
||||||
.readv = sock_readv,
|
|
||||||
.writev = sock_writev,
|
|
||||||
.sendpage = sock_sendpage,
|
.sendpage = sock_sendpage,
|
||||||
.splice_write = generic_splice_sendpage,
|
.splice_write = generic_splice_sendpage,
|
||||||
};
|
};
|
||||||
|
@ -700,23 +694,6 @@ static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
|
||||||
return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
|
return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t sock_readv(struct file *file, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct kiocb iocb;
|
|
||||||
struct sock_iocb siocb;
|
|
||||||
struct msghdr msg;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
init_sync_kiocb(&iocb, NULL);
|
|
||||||
iocb.private = &siocb;
|
|
||||||
|
|
||||||
ret = do_sock_read(&msg, &iocb, file, iov, nr_segs);
|
|
||||||
if (-EIOCBQUEUED == ret)
|
|
||||||
ret = wait_on_sync_kiocb(&iocb);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long nr_segs, loff_t pos)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
|
@ -759,23 +736,6 @@ static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
|
||||||
return __sock_sendmsg(iocb, sock, msg, size);
|
return __sock_sendmsg(iocb, sock, msg, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t sock_writev(struct file *file, const struct iovec *iov,
|
|
||||||
unsigned long nr_segs, loff_t *ppos)
|
|
||||||
{
|
|
||||||
struct msghdr msg;
|
|
||||||
struct kiocb iocb;
|
|
||||||
struct sock_iocb siocb;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
init_sync_kiocb(&iocb, NULL);
|
|
||||||
iocb.private = &siocb;
|
|
||||||
|
|
||||||
ret = do_sock_write(&msg, &iocb, file, iov, nr_segs);
|
|
||||||
if (-EIOCBQUEUED == ret)
|
|
||||||
ret = wait_on_sync_kiocb(&iocb);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long nr_segs, loff_t pos)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2852,8 +2852,8 @@ static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
|
static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long count, loff_t * offset)
|
unsigned long nr_segs, loff_t pos)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct snd_pcm_file *pcm_file;
|
struct snd_pcm_file *pcm_file;
|
||||||
|
@ -2864,22 +2864,22 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
|
||||||
void __user **bufs;
|
void __user **bufs;
|
||||||
snd_pcm_uframes_t frames;
|
snd_pcm_uframes_t frames;
|
||||||
|
|
||||||
pcm_file = file->private_data;
|
pcm_file = iocb->ki_filp->private_data;
|
||||||
substream = pcm_file->substream;
|
substream = pcm_file->substream;
|
||||||
snd_assert(substream != NULL, return -ENXIO);
|
snd_assert(substream != NULL, return -ENXIO);
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (count > 1024 || count != runtime->channels)
|
if (nr_segs > 1024 || nr_segs != runtime->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!frame_aligned(runtime, _vector->iov_len))
|
if (!frame_aligned(runtime, iov->iov_len))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
frames = bytes_to_samples(runtime, _vector->iov_len);
|
frames = bytes_to_samples(runtime, iov->iov_len);
|
||||||
bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
|
bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
|
||||||
if (bufs == NULL)
|
if (bufs == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < nr_segs; ++i)
|
||||||
bufs[i] = _vector[i].iov_base;
|
bufs[i] = iov[i].iov_base;
|
||||||
result = snd_pcm_lib_readv(substream, bufs, frames);
|
result = snd_pcm_lib_readv(substream, bufs, frames);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
result = frames_to_bytes(runtime, result);
|
result = frames_to_bytes(runtime, result);
|
||||||
|
@ -2887,8 +2887,8 @@ static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
|
static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
unsigned long count, loff_t * offset)
|
unsigned long nr_segs, loff_t pos)
|
||||||
{
|
{
|
||||||
struct snd_pcm_file *pcm_file;
|
struct snd_pcm_file *pcm_file;
|
||||||
struct snd_pcm_substream *substream;
|
struct snd_pcm_substream *substream;
|
||||||
|
@ -2898,7 +2898,7 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
|
||||||
void __user **bufs;
|
void __user **bufs;
|
||||||
snd_pcm_uframes_t frames;
|
snd_pcm_uframes_t frames;
|
||||||
|
|
||||||
pcm_file = file->private_data;
|
pcm_file = iocb->ki_filp->private_data;
|
||||||
substream = pcm_file->substream;
|
substream = pcm_file->substream;
|
||||||
snd_assert(substream != NULL, result = -ENXIO; goto end);
|
snd_assert(substream != NULL, result = -ENXIO; goto end);
|
||||||
runtime = substream->runtime;
|
runtime = substream->runtime;
|
||||||
|
@ -2906,17 +2906,17 @@ static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
|
||||||
result = -EBADFD;
|
result = -EBADFD;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (count > 128 || count != runtime->channels ||
|
if (nr_segs > 128 || nr_segs != runtime->channels ||
|
||||||
!frame_aligned(runtime, _vector->iov_len)) {
|
!frame_aligned(runtime, iov->iov_len)) {
|
||||||
result = -EINVAL;
|
result = -EINVAL;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
frames = bytes_to_samples(runtime, _vector->iov_len);
|
frames = bytes_to_samples(runtime, iov->iov_len);
|
||||||
bufs = kmalloc(sizeof(void *) * count, GFP_KERNEL);
|
bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
|
||||||
if (bufs == NULL)
|
if (bufs == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < nr_segs; ++i)
|
||||||
bufs[i] = _vector[i].iov_base;
|
bufs[i] = iov[i].iov_base;
|
||||||
result = snd_pcm_lib_writev(substream, bufs, frames);
|
result = snd_pcm_lib_writev(substream, bufs, frames);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
result = frames_to_bytes(runtime, result);
|
result = frames_to_bytes(runtime, result);
|
||||||
|
@ -3426,7 +3426,7 @@ struct file_operations snd_pcm_f_ops[2] = {
|
||||||
{
|
{
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.write = snd_pcm_write,
|
.write = snd_pcm_write,
|
||||||
.writev = snd_pcm_writev,
|
.aio_write = snd_pcm_aio_write,
|
||||||
.open = snd_pcm_playback_open,
|
.open = snd_pcm_playback_open,
|
||||||
.release = snd_pcm_release,
|
.release = snd_pcm_release,
|
||||||
.poll = snd_pcm_playback_poll,
|
.poll = snd_pcm_playback_poll,
|
||||||
|
@ -3438,7 +3438,7 @@ struct file_operations snd_pcm_f_ops[2] = {
|
||||||
{
|
{
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.read = snd_pcm_read,
|
.read = snd_pcm_read,
|
||||||
.readv = snd_pcm_readv,
|
.aio_read = snd_pcm_aio_read,
|
||||||
.open = snd_pcm_capture_open,
|
.open = snd_pcm_capture_open,
|
||||||
.release = snd_pcm_release,
|
.release = snd_pcm_release,
|
||||||
.poll = snd_pcm_capture_poll,
|
.poll = snd_pcm_capture_poll,
|
||||||
|
|
Loading…
Reference in New Issue