2 * linux/fs/read_write.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Minor pieces Copyright (C) 2002 Red Hat Inc, All Rights Reserved
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/slab.h>
23 #include <linux/stat.h>
24 #include <linux/fcntl.h>
25 #include <linux/file.h>
26 #include <linux/uio.h>
27 #include <linux/smp_lock.h>
28 #include <linux/dnotify.h>
30 #include <asm/uaccess.h>
32 struct file_operations generic_ro_fops = {
33 llseek: generic_file_llseek,
34 read: generic_file_read,
35 mmap: generic_file_mmap,
38 ssize_t generic_read_dir(struct file *filp, char *buf, size_t siz, loff_t *ppos)
43 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
49 offset += file->f_dentry->d_inode->i_size;
52 offset += file->f_pos;
55 if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
56 if (offset != file->f_pos) {
59 file->f_version = ++event;
66 loff_t no_llseek(struct file *file, loff_t offset, int origin)
71 loff_t default_llseek(struct file *file, loff_t offset, int origin)
77 offset += file->f_dentry->d_inode->i_size;
80 offset += file->f_pos;
84 if (offset != file->f_pos) {
87 file->f_version = ++event;
94 static inline loff_t llseek(struct file *file, loff_t offset, int origin)
96 loff_t (*fn)(struct file *, loff_t, int);
100 if (file->f_op && file->f_op->llseek)
101 fn = file->f_op->llseek;
103 retval = fn(file, offset, origin);
108 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
119 loff_t res = llseek(file, offset, origin);
121 if (res != (loff_t)retval)
122 retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
129 #if !defined(__alpha__)
130 asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
131 unsigned long offset_low, loff_t * result,
146 offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
149 retval = (int)offset;
152 if (!copy_to_user(result, &offset, sizeof(offset)))
162 asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count)
170 if (file->f_mode & FMODE_READ) {
171 ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
172 file, file->f_pos, count);
174 ssize_t (*read)(struct file *, char *, size_t, loff_t *);
176 if (file->f_op && (read = file->f_op->read) != NULL)
177 ret = read(file, buf, count, &file->f_pos);
181 dnotify_parent(file->f_dentry, DN_ACCESS);
187 asmlinkage ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
195 if (file->f_mode & FMODE_WRITE) {
196 struct inode *inode = file->f_dentry->d_inode;
197 ret = locks_verify_area(FLOCK_VERIFY_WRITE, inode, file,
200 ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
202 if (file->f_op && (write = file->f_op->write) != NULL)
203 ret = write(file, buf, count, &file->f_pos);
207 dnotify_parent(file->f_dentry, DN_MODIFY);
214 static ssize_t do_readv_writev(int type, struct file *file,
215 const struct iovec * vector,
218 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
219 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
222 struct iovec iovstack[UIO_FASTIOV];
223 struct iovec *iov=iovstack;
230 * First get the "struct iovec" from user memory and
231 * verify all the pointers
237 if (count > UIO_MAXIOV)
241 if (count > UIO_FASTIOV) {
243 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
248 if (copy_from_user(iov, vector, count*sizeof(*vector)))
252 * Single unix specification:
253 * We should -EINVAL if an element length is not >= 0 and fitting an ssize_t
254 * The total length is fitting an ssize_t
256 * Be careful here because iov_len is a size_t not an ssize_t
261 for (i = 0 ; i < count ; i++) {
262 ssize_t len = (ssize_t) iov[i].iov_len;
263 if (len < 0) /* size_t not fitting an ssize_t .. */
266 /* We must do this work unsigned - signed overflow is
267 undefined and gcc 3.2 now uses that fact sometimes...
269 FIXME: put in a proper limits.h for each platform */
270 #if BITS_PER_LONG==64
271 if (tot_len > 0x7FFFFFFFFFFFFFFFUL)
273 if (tot_len > 0x7FFFFFFFUL)
278 inode = file->f_dentry->d_inode;
279 /* VERIFY_WRITE actually means a read, as we write to user space */
280 ret = locks_verify_area((type == VERIFY_WRITE
281 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
282 inode, file, file->f_pos, tot_len);
285 fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
287 ret = fnv(file, iov, count, &file->f_pos);
291 /* VERIFY_WRITE actually means a read, as we write to user space */
292 fn = (type == VERIFY_WRITE ? file->f_op->read :
293 (io_fn_t) file->f_op->write);
302 base = vector->iov_base;
303 len = vector->iov_len;
307 nr = fn(file, base, len, &file->f_pos);
322 /* VERIFY_WRITE actually means a read, as we write to user space */
323 if ((ret + (type == VERIFY_WRITE)) > 0)
324 dnotify_parent(file->f_dentry,
325 (type == VERIFY_WRITE) ? DN_MODIFY : DN_ACCESS);
329 asmlinkage ssize_t sys_readv(unsigned long fd, const struct iovec * vector,
340 if (file->f_op && (file->f_mode & FMODE_READ) &&
341 (file->f_op->readv || file->f_op->read))
342 ret = do_readv_writev(VERIFY_WRITE, file, vector, count);
349 asmlinkage ssize_t sys_writev(unsigned long fd, const struct iovec * vector,
360 if (file->f_op && (file->f_mode & FMODE_WRITE) &&
361 (file->f_op->writev || file->f_op->write))
362 ret = do_readv_writev(VERIFY_READ, file, vector, count);
369 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
370 lseek back to original location. They fail just like lseek does on
371 non-seekable files. */
373 asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
374 size_t count, loff_t pos)
378 ssize_t (*read)(struct file *, char *, size_t, loff_t *);
384 if (!(file->f_mode & FMODE_READ))
386 ret = locks_verify_area(FLOCK_VERIFY_READ, file->f_dentry->d_inode,
391 if (!file->f_op || !(read = file->f_op->read))
395 ret = read(file, buf, count, &pos);
397 dnotify_parent(file->f_dentry, DN_ACCESS);
404 asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
405 size_t count, loff_t pos)
409 ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
415 if (!(file->f_mode & FMODE_WRITE))
417 ret = locks_verify_area(FLOCK_VERIFY_WRITE, file->f_dentry->d_inode,
422 if (!file->f_op || !(write = file->f_op->write))
427 ret = write(file, buf, count, &pos);
429 dnotify_parent(file->f_dentry, DN_MODIFY);