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 int rw_verify_area(int read_write
, struct file
*file
, loff_t
*ppos
, size_t count
)
48 if (unlikely(count
> file
->f_maxcount
))
53 if (unlikely((pos
< 0) || (loff_t
) (pos
+ count
) < 0))
56 inode
= file
->f_dentry
->d_inode
;
57 if (inode
->i_flock
&& MANDATORY_LOCK(inode
))
58 return locks_mandatory_area(read_write
== READ
? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
, inode
, file
, *ppos
, count
);
65 loff_t
generic_file_llseek(struct file
*file
, loff_t offset
, int origin
)
71 offset
+= file
->f_dentry
->d_inode
->i_size
;
74 offset
+= file
->f_pos
;
77 if (offset
>=0 && offset
<=file
->f_dentry
->d_inode
->i_sb
->s_maxbytes
) {
78 if (offset
!= file
->f_pos
) {
81 file
->f_version
= ++event
;
88 loff_t
no_llseek(struct file
*file
, loff_t offset
, int origin
)
93 loff_t
default_llseek(struct file
*file
, loff_t offset
, int origin
)
99 offset
+= file
->f_dentry
->d_inode
->i_size
;
102 offset
+= file
->f_pos
;
106 if (offset
!= file
->f_pos
) {
107 file
->f_pos
= offset
;
109 file
->f_version
= ++event
;
116 static inline loff_t
llseek(struct file
*file
, loff_t offset
, int origin
)
118 loff_t (*fn
)(struct file
*, loff_t
, int);
122 if (file
->f_op
&& file
->f_op
->llseek
)
123 fn
= file
->f_op
->llseek
;
125 retval
= fn(file
, offset
, origin
);
130 asmlinkage off_t
sys_lseek(unsigned int fd
, off_t offset
, unsigned int origin
)
141 loff_t res
= llseek(file
, offset
, origin
);
143 if (res
!= (loff_t
)retval
)
144 retval
= -EOVERFLOW
; /* LFS: should only happen on 32 bit platforms */
151 #if !defined(__alpha__)
152 asmlinkage
long sys_llseek(unsigned int fd
, unsigned long offset_high
,
153 unsigned long offset_low
, loff_t
* result
,
168 offset
= llseek(file
, ((loff_t
) offset_high
<< 32) | offset_low
,
171 retval
= (int)offset
;
174 if (!copy_to_user(result
, &offset
, sizeof(offset
)))
184 asmlinkage ssize_t
sys_read(unsigned int fd
, char * buf
, size_t count
)
192 if (file
->f_mode
& FMODE_READ
) {
193 ret
= rw_verify_area(READ
, file
, &file
->f_pos
, count
);
196 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
198 if (file
->f_op
&& (read
= file
->f_op
->read
) != NULL
)
199 ret
= read(file
, buf
, count
, &file
->f_pos
);
203 dnotify_parent(file
->f_dentry
, DN_ACCESS
);
209 asmlinkage ssize_t
sys_write(unsigned int fd
, const char * buf
, size_t count
)
217 if (file
->f_mode
& FMODE_WRITE
) {
218 ret
= rw_verify_area(WRITE
, file
, &file
->f_pos
, count
);
220 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
222 if (file
->f_op
&& (write
= file
->f_op
->write
) != NULL
)
223 ret
= write(file
, buf
, count
, &file
->f_pos
);
227 dnotify_parent(file
->f_dentry
, DN_MODIFY
);
234 static ssize_t
do_readv_writev(int type
, struct file
*file
,
235 const struct iovec
* vector
,
238 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
239 typedef ssize_t (*iov_fn_t
)(struct file
*, const struct iovec
*, unsigned long, loff_t
*);
242 struct iovec iovstack
[UIO_FASTIOV
];
243 struct iovec
*iov
=iovstack
;
249 * First get the "struct iovec" from user memory and
250 * verify all the pointers
256 if (count
> UIO_MAXIOV
)
260 if (count
> UIO_FASTIOV
) {
262 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
267 if (copy_from_user(iov
, vector
, count
*sizeof(*vector
)))
271 * Single unix specification:
272 * We should -EINVAL if an element length is not >= 0 and fitting an ssize_t
273 * The total length is fitting an ssize_t
275 * Be careful here because iov_len is a size_t not an ssize_t
280 for (i
= 0 ; i
< count
; i
++) {
281 ssize_t len
= (ssize_t
) iov
[i
].iov_len
;
282 if (len
< 0) /* size_t not fitting an ssize_t .. */
285 /* We must do this work unsigned - signed overflow is
286 undefined and gcc 3.2 now uses that fact sometimes...
288 FIXME: put in a proper limits.h for each platform */
289 #if BITS_PER_LONG==64
290 if (tot_len
> 0x7FFFFFFFFFFFFFFFUL
)
292 if (tot_len
> 0x7FFFFFFFUL
)
297 /* VERIFY_WRITE actually means a read, as we write to user space */
298 ret
= rw_verify_area((type
== VERIFY_WRITE
? READ
: WRITE
),
299 file
, &file
->f_pos
, tot_len
);
303 fnv
= (type
== VERIFY_WRITE
? file
->f_op
->readv
: file
->f_op
->writev
);
305 ret
= fnv(file
, iov
, count
, &file
->f_pos
);
309 /* VERIFY_WRITE actually means a read, as we write to user space */
310 fn
= (type
== VERIFY_WRITE
? file
->f_op
->read
:
311 (io_fn_t
) file
->f_op
->write
);
320 base
= vector
->iov_base
;
321 len
= vector
->iov_len
;
325 nr
= fn(file
, base
, len
, &file
->f_pos
);
340 /* VERIFY_WRITE actually means a read, as we write to user space */
341 if ((ret
+ (type
== VERIFY_WRITE
)) > 0)
342 dnotify_parent(file
->f_dentry
,
343 (type
== VERIFY_WRITE
) ? DN_ACCESS
: DN_MODIFY
);
347 asmlinkage ssize_t
sys_readv(unsigned long fd
, const struct iovec
* vector
,
358 if (file
->f_op
&& (file
->f_mode
& FMODE_READ
) &&
359 (file
->f_op
->readv
|| file
->f_op
->read
))
360 ret
= do_readv_writev(VERIFY_WRITE
, file
, vector
, count
);
367 asmlinkage ssize_t
sys_writev(unsigned long fd
, const struct iovec
* vector
,
378 if (file
->f_op
&& (file
->f_mode
& FMODE_WRITE
) &&
379 (file
->f_op
->writev
|| file
->f_op
->write
))
380 ret
= do_readv_writev(VERIFY_READ
, file
, vector
, count
);
387 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
388 lseek back to original location. They fail just like lseek does on
389 non-seekable files. */
391 asmlinkage ssize_t
sys_pread(unsigned int fd
, char * buf
,
392 size_t count
, loff_t pos
)
396 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
402 if (!(file
->f_mode
& FMODE_READ
))
404 ret
= rw_verify_area(READ
, file
, &pos
, count
);
409 if (!file
->f_op
|| !(read
= file
->f_op
->read
))
413 ret
= read(file
, buf
, count
, &pos
);
415 dnotify_parent(file
->f_dentry
, DN_ACCESS
);
422 asmlinkage ssize_t
sys_pwrite(unsigned int fd
, const char * buf
,
423 size_t count
, loff_t pos
)
427 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
433 if (!(file
->f_mode
& FMODE_WRITE
))
435 ret
= rw_verify_area(WRITE
, file
, &pos
, count
);
440 if (!file
->f_op
|| !(write
= file
->f_op
->write
))
445 ret
= write(file
, buf
, count
, &pos
);
447 dnotify_parent(file
->f_dentry
, DN_MODIFY
);