/* * linux/fs/read_write.c * * Copyright (C) 1991, 1992 Linus Torvalds */ #include <linux/slab.h> #include <linux/stat.h>#include <linux/fcntl.h>#include <linux/file.h>#include <linux/uio.h>#include <linux/fsnotify.h>#include <linux/security.h>#include <linux/module.h>#include <linux/syscalls.h>#include <linux/pagemap.h>#include <linux/splice.h>#include "read_write.h" #include <asm/uaccess.h>#include <asm/unistd.h> const struct file_operations generic_ro_fops = { .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, .mmap = generic_file_readonly_mmap, .splice_read = generic_file_splice_read,}; EXPORT_SYMBOL(generic_ro_fops); static inline int unsigned_offsets(struct file *file){ return file->f_mode & FMODE_UNSIGNED_OFFSET;} /** * generic_file_llseek_unlocked - lockless generic llseek implementation * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * Updates the file offset to the value specified by @offset and @origin. * Locking must be provided by the caller. */loff_tgeneric_file_llseek_unlocked(struct file *file, loff_t offset, int origin){ struct inode *inode = file->f_mapping->host; switch (origin) { case SEEK_END: offset += inode->i_size; break; case SEEK_CUR: /* * Here we special-case the lseek(fd, 0, SEEK_CUR) * position-querying operation. Avoid rewriting the "same" * f_pos value back to the file because a concurrent read(), * write() or lseek() might have altered it */ if (offset == 0) return file->f_pos; offset += file->f_pos; break; } if (offset < 0 && !unsigned_offsets(file)) return -EINVAL; if (offset > inode->i_sb->s_maxbytes) return -EINVAL; /* Special lock needed here? */ if (offset != file->f_pos) { file->f_pos = offset; file->f_version = 0; } return offset;}EXPORT_SYMBOL(generic_file_llseek_unlocked); /** * generic_file_llseek - generic llseek implementation for regular files * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * This is a generic implemenation of ->llseek useable for all normal local * filesystems. It just updates the file offset to the value specified by * @offset and @origin under i_mutex. */loff_t generic_file_llseek(struct file *file, loff_t offset, int origin){ loff_t rval; mutex_lock(&file->f_dentry->d_inode->i_mutex); rval = generic_file_llseek_unlocked(file, offset, origin); mutex_unlock(&file->f_dentry->d_inode->i_mutex); return rval;}EXPORT_SYMBOL(generic_file_llseek); /** * noop_llseek - No Operation Performed llseek implementation * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * This is an implementation of ->llseek useable for the rare special case when * userspace expects the seek to succeed but the (device) file is actually not * able to perform the seek. In this case you use noop_llseek() instead of * falling back to the default implementation of ->llseek. */loff_t noop_llseek(struct file *file, loff_t offset, int origin){ return file->f_pos;}EXPORT_SYMBOL(noop_llseek); loff_t no_llseek(struct file *file, loff_t offset, int origin){ return -ESPIPE;}EXPORT_SYMBOL(no_llseek); loff_t default_llseek(struct file *file, loff_t offset, int origin){ loff_t retval; mutex_lock(&file->f_dentry->d_inode->i_mutex); switch (origin) { case SEEK_END: offset += i_size_read(file->f_path.dentry->d_inode); break; case SEEK_CUR: if (offset == 0) { retval = file->f_pos; goto out; } offset += file->f_pos; } retval = -EINVAL; if (offset >= 0 || unsigned_offsets(file)) { if (offset != file->f_pos) { file->f_pos = offset; file->f_version = 0; } retval = offset; }out: mutex_unlock(&file->f_dentry->d_inode->i_mutex); return retval;}EXPORT_SYMBOL(default_llseek); loff_t vfs_llseek(struct file *file, loff_t offset, int origin){ loff_t (*fn)(struct file *, loff_t, int); fn = no_llseek; if (file->f_mode & FMODE_LSEEK) { if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; } return fn(file, offset, origin);}EXPORT_SYMBOL(vfs_llseek); SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin){ off_t retval; struct file * file; int fput_needed; retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) goto bad; retval = -EINVAL; if (origin <= SEEK_MAX) { loff_t res = vfs_llseek(file, offset, origin); retval = res; if (res != (loff_t)retval) retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ } fput_light(file, fput_needed);bad: return retval;} #ifdef __ARCH_WANT_SYS_LLSEEKSYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, unsigned long, offset_low, loff_t __user *, result, unsigned int, origin){ int retval; struct file * file; loff_t offset; int fput_needed; retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) goto bad; retval = -EINVAL; if (origin > SEEK_MAX) goto out_putf; offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, origin); retval = (int)offset; if (offset >= 0) { retval = -EFAULT; if (!copy_to_user(result, &offset, sizeof(offset))) retval = 0; }out_putf: fput_light(file, fput_needed);bad: return retval;}#endif /* * rw_verify_area doesn't like huge counts. We limit * them to something that fits in "int" so that others * won't have to do range checks all the time. */int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count){ struct inode *inode; loff_t pos; int retval = -EINVAL; inode = file->f_path.dentry->d_inode; if (unlikely((ssize_t) count < 0)) return retval; pos = *ppos; if (unlikely(pos < 0)) { if (!unsigned_offsets(file)) return retval; if (count >= -pos) /* both values are in 0..LLONG_MAX */ return -EOVERFLOW; } else if (unlikely((loff_t) (pos + count) < 0)) { if (!unsigned_offsets(file)) return retval; } if (unlikely(inode->i_flock && mandatory_lock(inode))) { retval = locks_mandatory_area( read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); if (retval < 0) return retval; } retval = security_file_permission(file, read_write == READ ? MAY_READ : MAY_WRITE); if (retval) return retval; return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;} static void wait_on_retry_sync_kiocb(struct kiocb *iocb){ set_current_state(TASK_UNINTERRUPTIBLE); if (!kiocbIsKicked(iocb)) schedule(); else kiocbClearKicked(iocb); __set_current_state(TASK_RUNNING);} ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos){ struct iovec iov = { .iov_base = buf, .iov_len = len }; 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 = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret;} EXPORT_SYMBOL(do_sync_read); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos){ ssize_t ret; if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) return -EINVAL; if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) return -EFAULT; ret = rw_verify_area(READ, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->read) ret = file->f_op->read(file, buf, count, pos); else ret = do_sync_read(file, buf, count, pos); if (ret > 0) { fsnotify_access(file); add_rchar(current, ret); } inc_syscr(current); } return ret;} EXPORT_SYMBOL(vfs_read); ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos){ struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; 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 = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret;} EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos){ ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } return ret;} EXPORT_SYMBOL(vfs_write); static inline loff_t file_pos_read(struct file *file){ return file->f_pos;} static inline void file_pos_write(struct file *file, loff_t pos){ file->f_pos = pos;} SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count){ struct file *file; ssize_t ret = -EBADF; int fput_needed; file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); ret = vfs_read(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); } return ret;} SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count){ struct file *file; ssize_t ret = -EBADF; int fput_needed; file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); ret = vfs_write(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); } return ret;} SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, size_t count, loff_t pos){ struct file *file; ssize_t ret = -EBADF; int fput_needed; if (pos < 0) return -EINVAL; file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; if (file->f_mode & FMODE_PREAD) ret = vfs_read(file, buf, count, &pos); fput_light(file, fput_needed); } return ret;}#ifdef CONFIG_HAVE_SYSCALL_WRAPPERSasmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos){ return SYSC_pread64((unsigned int) fd, (char __user *) buf, (size_t) count, pos);}SYSCALL_ALIAS(sys_pread64, SyS_pread64);#endif SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, size_t count, loff_t pos){ struct file *file; ssize_t ret = -EBADF; int fput_needed; if (pos < 0) return -EINVAL; file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; if (file->f_mode & FMODE_PWRITE) ret = vfs_write(file, buf, count, &pos); fput_light(file, fput_needed); } return ret;}#ifdef CONFIG_HAVE_SYSCALL_WRAPPERSasmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos){ return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, (size_t) count, pos);}SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64);#endif /* * Reduce an iovec's length in-place. Return the resulting number of segments */unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to){ unsigned long seg = 0;Lines 1–500 of 948. Load more
/* * linux/fs/read_write.c * * Copyright (C) 1991, 1992 Linus Torvalds */ #include <linux/slab.h> #include <linux/stat.h> #include <linux/fcntl.h> #include <linux/file.h> #include <linux/uio.h> #include <linux/fsnotify.h> #include <linux/security.h> #include <linux/module.h> #include <linux/syscalls.h> #include <linux/pagemap.h> #include <linux/splice.h> #include "read_write.h" #include <asm/uaccess.h> #include <asm/unistd.h> const struct file_operations generic_ro_fops = { .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, .mmap = generic_file_readonly_mmap, .splice_read = generic_file_splice_read, }; EXPORT_SYMBOL(generic_ro_fops); static inline int unsigned_offsets(struct file *file) { return file->f_mode & FMODE_UNSIGNED_OFFSET; } /** * generic_file_llseek_unlocked - lockless generic llseek implementation * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * Updates the file offset to the value specified by @offset and @origin. * Locking must be provided by the caller. */ loff_t generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin) { struct inode *inode = file->f_mapping->host; switch (origin) { case SEEK_END: offset += inode->i_size; break; case SEEK_CUR: /* * Here we special-case the lseek(fd, 0, SEEK_CUR) * position-querying operation. Avoid rewriting the "same" * f_pos value back to the file because a concurrent read(), * write() or lseek() might have altered it */ if (offset == 0) return file->f_pos; offset += file->f_pos; break; } if (offset < 0 && !unsigned_offsets(file)) return -EINVAL; if (offset > inode->i_sb->s_maxbytes) return -EINVAL; /* Special lock needed here? */ if (offset != file->f_pos) { file->f_pos = offset; file->f_version = 0; } return offset; } EXPORT_SYMBOL(generic_file_llseek_unlocked); /** * generic_file_llseek - generic llseek implementation for regular files * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * This is a generic implemenation of ->llseek useable for all normal local * filesystems. It just updates the file offset to the value specified by * @offset and @origin under i_mutex. */ loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) { loff_t rval; mutex_lock(&file->f_dentry->d_inode->i_mutex); rval = generic_file_llseek_unlocked(file, offset, origin); mutex_unlock(&file->f_dentry->d_inode->i_mutex); return rval; } EXPORT_SYMBOL(generic_file_llseek); /** * noop_llseek - No Operation Performed llseek implementation * @file: file structure to seek on * @offset: file offset to seek to * @origin: type of seek * * This is an implementation of ->llseek useable for the rare special case when * userspace expects the seek to succeed but the (device) file is actually not * able to perform the seek. In this case you use noop_llseek() instead of * falling back to the default implementation of ->llseek. */ loff_t noop_llseek(struct file *file, loff_t offset, int origin) { return file->f_pos; } EXPORT_SYMBOL(noop_llseek); loff_t no_llseek(struct file *file, loff_t offset, int origin) { return -ESPIPE; } EXPORT_SYMBOL(no_llseek); loff_t default_llseek(struct file *file, loff_t offset, int origin) { loff_t retval; mutex_lock(&file->f_dentry->d_inode->i_mutex); switch (origin) { case SEEK_END: offset += i_size_read(file->f_path.dentry->d_inode); break; case SEEK_CUR: if (offset == 0) { retval = file->f_pos; goto out; } offset += file->f_pos; } retval = -EINVAL; if (offset >= 0 || unsigned_offsets(file)) { if (offset != file->f_pos) { file->f_pos = offset; file->f_version = 0; } retval = offset; } out: mutex_unlock(&file->f_dentry->d_inode->i_mutex); return retval; } EXPORT_SYMBOL(default_llseek); loff_t vfs_llseek(struct file *file, loff_t offset, int origin) { loff_t (*fn)(struct file *, loff_t, int); fn = no_llseek; if (file->f_mode & FMODE_LSEEK) { if (file->f_op && file->f_op->llseek) fn = file->f_op->llseek; } return fn(file, offset, origin); } EXPORT_SYMBOL(vfs_llseek); SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) { off_t retval; struct file * file; int fput_needed; retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) goto bad; retval = -EINVAL; if (origin <= SEEK_MAX) { loff_t res = vfs_llseek(file, offset, origin); retval = res; if (res != (loff_t)retval) retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ } fput_light(file, fput_needed); bad: return retval; } #ifdef __ARCH_WANT_SYS_LLSEEK SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, unsigned long, offset_low, loff_t __user *, result, unsigned int, origin) { int retval; struct file * file; loff_t offset; int fput_needed; retval = -EBADF; file = fget_light(fd, &fput_needed); if (!file) goto bad; retval = -EINVAL; if (origin > SEEK_MAX) goto out_putf; offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, origin); retval = (int)offset; if (offset >= 0) { retval = -EFAULT; if (!copy_to_user(result, &offset, sizeof(offset))) retval = 0; } out_putf: fput_light(file, fput_needed); bad: return retval; } #endif /* * rw_verify_area doesn't like huge counts. We limit * them to something that fits in "int" so that others * won't have to do range checks all the time. */ int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count) { struct inode *inode; loff_t pos; int retval = -EINVAL; inode = file->f_path.dentry->d_inode; if (unlikely((ssize_t) count < 0)) return retval; pos = *ppos; if (unlikely(pos < 0)) { if (!unsigned_offsets(file)) return retval; if (count >= -pos) /* both values are in 0..LLONG_MAX */ return -EOVERFLOW; } else if (unlikely((loff_t) (pos + count) < 0)) { if (!unsigned_offsets(file)) return retval; } if (unlikely(inode->i_flock && mandatory_lock(inode))) { retval = locks_mandatory_area( read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count); if (retval < 0) return retval; } retval = security_file_permission(file, read_write == READ ? MAY_READ : MAY_WRITE); if (retval) return retval; return count > MAX_RW_COUNT ? MAX_RW_COUNT : count; } static void wait_on_retry_sync_kiocb(struct kiocb *iocb) { set_current_state(TASK_UNINTERRUPTIBLE); if (!kiocbIsKicked(iocb)) schedule(); else kiocbClearKicked(iocb); __set_current_state(TASK_RUNNING); } ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = buf, .iov_len = len }; 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 = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_read); ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read)) return -EINVAL; if (unlikely(!access_ok(VERIFY_WRITE, buf, count))) return -EFAULT; ret = rw_verify_area(READ, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->read) ret = file->f_op->read(file, buf, count, pos); else ret = do_sync_read(file, buf, count, pos); if (ret > 0) { fsnotify_access(file); add_rchar(current, ret); } inc_syscr(current); } return ret; } EXPORT_SYMBOL(vfs_read); ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) { struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len }; 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 = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos); if (ret != -EIOCBRETRY) break; wait_on_retry_sync_kiocb(&kiocb); } if (-EIOCBQUEUED == ret) ret = wait_on_sync_kiocb(&kiocb); *ppos = kiocb.ki_pos; return ret; } EXPORT_SYMBOL(do_sync_write); ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { ssize_t ret; if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write)) return -EINVAL; if (unlikely(!access_ok(VERIFY_READ, buf, count))) return -EFAULT; ret = rw_verify_area(WRITE, file, pos, count); if (ret >= 0) { count = ret; if (file->f_op->write) ret = file->f_op->write(file, buf, count, pos); else ret = do_sync_write(file, buf, count, pos); if (ret > 0) { fsnotify_modify(file); add_wchar(current, ret); } inc_syscw(current); } return ret; } EXPORT_SYMBOL(vfs_write); static inline loff_t file_pos_read(struct file *file) { return file->f_pos; } static inline void file_pos_write(struct file *file, loff_t pos) { file->f_pos = pos; } SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct file *file; ssize_t ret = -EBADF; int fput_needed; file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); ret = vfs_read(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); } return ret; } SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count) { struct file *file; ssize_t ret = -EBADF; int fput_needed; file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); ret = vfs_write(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); } return ret; } SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; int fput_needed; if (pos < 0) return -EINVAL; file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; if (file->f_mode & FMODE_PREAD) ret = vfs_read(file, buf, count, &pos); fput_light(file, fput_needed); } return ret; } #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos) { return SYSC_pread64((unsigned int) fd, (char __user *) buf, (size_t) count, pos); } SYSCALL_ALIAS(sys_pread64, SyS_pread64); #endif SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; int fput_needed; if (pos < 0) return -EINVAL; file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; if (file->f_mode & FMODE_PWRITE) ret = vfs_write(file, buf, count, &pos); fput_light(file, fput_needed); } return ret; } #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) { return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, (size_t) count, pos); } SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); #endif /* * Reduce an iovec's length in-place. Return the resulting number of segments */ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to) { unsigned long seg = 0;