2 * linux/fs/read_write.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
7 #include <linux/malloc.h>
8 #include <linux/stat.h>
9 #include <linux/fcntl.h>
10 #include <linux/file.h>
11 #include <linux/uio.h>
12 #include <linux/smp_lock.h>
14 #include <asm/uaccess.h>
16 static loff_t
default_llseek(struct file
*file
, loff_t offset
, int origin
)
22 offset
+= file
->f_dentry
->d_inode
->i_size
;
25 offset
+= file
->f_pos
;
29 if (offset
!= file
->f_pos
) {
32 file
->f_version
= ++event
;
39 static inline loff_t
llseek(struct file
*file
, loff_t offset
, int origin
)
41 loff_t (*fn
)(struct file
*, loff_t
, int);
44 if (file
->f_op
&& file
->f_op
->llseek
)
45 fn
= file
->f_op
->llseek
;
46 return fn(file
, offset
, origin
);
49 asmlinkage off_t
sys_lseek(unsigned int fd
, off_t offset
, unsigned int origin
)
53 struct dentry
* dentry
;
61 /* N.B. Shouldn't this be ENOENT?? */
62 if (!(dentry
= file
->f_dentry
) ||
63 !(inode
= dentry
->d_inode
))
67 retval
= llseek(file
, offset
, origin
);
75 #if !defined(__alpha__)
76 asmlinkage
int sys_llseek(unsigned int fd
, unsigned long offset_high
,
77 unsigned long offset_low
, loff_t
* result
,
82 struct dentry
* dentry
;
91 /* N.B. Shouldn't this be ENOENT?? */
92 if (!(dentry
= file
->f_dentry
) ||
93 !(inode
= dentry
->d_inode
))
99 offset
= llseek(file
, ((loff_t
) offset_high
<< 32) | offset_low
,
102 retval
= (int)offset
;
105 if (!copy_to_user(result
, &offset
, sizeof(offset
)))
116 asmlinkage ssize_t
sys_read(unsigned int fd
, char * buf
, size_t count
)
120 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
128 if (!(file
->f_mode
& FMODE_READ
))
130 ret
= locks_verify_area(FLOCK_VERIFY_READ
, file
->f_dentry
->d_inode
,
131 file
, file
->f_pos
, count
);
135 if (!file
->f_op
|| !(read
= file
->f_op
->read
))
137 ret
= read(file
, buf
, count
, &file
->f_pos
);
145 asmlinkage ssize_t
sys_write(unsigned int fd
, const char * buf
, size_t count
)
149 struct inode
* inode
;
150 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
158 if (!(file
->f_mode
& FMODE_WRITE
))
160 inode
= file
->f_dentry
->d_inode
;
161 ret
= locks_verify_area(FLOCK_VERIFY_WRITE
, inode
, file
,
166 if (!file
->f_op
|| !(write
= file
->f_op
->write
))
169 ret
= write(file
, buf
, count
, &file
->f_pos
);
178 static ssize_t
do_readv_writev(int type
, struct file
*file
,
179 const struct iovec
* vector
,
182 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
185 struct iovec iovstack
[UIO_FASTIOV
];
186 struct iovec
*iov
=iovstack
;
192 * First get the "struct iovec" from user memory and
193 * verify all the pointers
199 if (count
> UIO_MAXIOV
)
201 if (count
> UIO_FASTIOV
) {
203 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
208 if (copy_from_user(iov
, vector
, count
*sizeof(*vector
)))
212 for (i
= 0 ; i
< count
; i
++)
213 tot_len
+= iov
[i
].iov_len
;
215 inode
= file
->f_dentry
->d_inode
;
216 /* VERIFY_WRITE actually means a read, as we write to user space */
217 ret
= locks_verify_area((type
== VERIFY_WRITE
218 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
219 inode
, file
, file
->f_pos
, tot_len
);
223 * Then do the actual IO. Note that sockets need to be handled
224 * specially as they have atomicity guarantees and can handle
228 ret
= sock_readv_writev(type
,inode
,file
,iov
,count
,tot_len
);
236 /* VERIFY_WRITE actually means a read, as we write to user space */
237 fn
= file
->f_op
->read
;
238 if (type
== VERIFY_READ
)
239 fn
= (io_fn_t
) file
->f_op
->write
;
248 base
= vector
->iov_base
;
249 len
= vector
->iov_len
;
253 nr
= fn(file
, base
, len
, &file
->f_pos
);
271 asmlinkage ssize_t
sys_readv(unsigned long fd
, const struct iovec
* vector
,
283 if (file
->f_op
&& file
->f_op
->read
&& (file
->f_mode
& FMODE_READ
))
284 ret
= do_readv_writev(VERIFY_WRITE
, file
, vector
, count
);
292 asmlinkage ssize_t
sys_writev(unsigned long fd
, const struct iovec
* vector
,
304 if (file
->f_op
&& file
->f_op
->write
&& (file
->f_mode
& FMODE_WRITE
)) {
305 ret
= do_readv_writev(VERIFY_READ
, file
, vector
, count
);
314 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
315 lseek back to original location. They fail just like lseek does on
316 non-seekable files. */
318 asmlinkage ssize_t
sys_pread(unsigned int fd
, char * buf
,
319 size_t count
, loff_t pos
)
323 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
331 if (!(file
->f_mode
& FMODE_READ
))
333 ret
= locks_verify_area(FLOCK_VERIFY_READ
, file
->f_dentry
->d_inode
,
338 if (!file
->f_op
|| !(read
= file
->f_op
->read
))
342 ret
= read(file
, buf
, count
, &pos
);
350 asmlinkage ssize_t
sys_pwrite(unsigned int fd
, const char * buf
,
351 size_t count
, loff_t pos
)
355 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
363 if (!(file
->f_mode
& FMODE_WRITE
))
365 ret
= locks_verify_area(FLOCK_VERIFY_WRITE
, file
->f_dentry
->d_inode
,
370 if (!file
->f_op
|| !(write
= file
->f_op
->write
))
375 ret
= write(file
, buf
, count
, &pos
);