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
))
170 ret
= write(file
, buf
, count
, &file
->f_pos
);
180 static ssize_t
do_readv_writev(int type
, struct file
*file
,
181 const struct iovec
* vector
,
184 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
187 struct iovec iovstack
[UIO_FASTIOV
];
188 struct iovec
*iov
=iovstack
;
194 * First get the "struct iovec" from user memory and
195 * verify all the pointers
201 if (count
> UIO_MAXIOV
)
203 if (count
> UIO_FASTIOV
) {
205 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
210 if (copy_from_user(iov
, vector
, count
*sizeof(*vector
)))
214 for (i
= 0 ; i
< count
; i
++)
215 tot_len
+= iov
[i
].iov_len
;
217 inode
= file
->f_dentry
->d_inode
;
218 /* VERIFY_WRITE actually means a read, as we write to user space */
219 ret
= locks_verify_area((type
== VERIFY_WRITE
220 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
221 inode
, file
, file
->f_pos
, tot_len
);
225 * Then do the actual IO. Note that sockets need to be handled
226 * specially as they have atomicity guarantees and can handle
230 ret
= sock_readv_writev(type
,inode
,file
,iov
,count
,tot_len
);
238 /* VERIFY_WRITE actually means a read, as we write to user space */
239 fn
= file
->f_op
->read
;
240 if (type
== VERIFY_READ
)
241 fn
= (io_fn_t
) file
->f_op
->write
;
250 base
= vector
->iov_base
;
251 len
= vector
->iov_len
;
255 nr
= fn(file
, base
, len
, &file
->f_pos
);
273 asmlinkage ssize_t
sys_readv(unsigned long fd
, const struct iovec
* vector
,
285 if (file
->f_op
&& file
->f_op
->read
&& (file
->f_mode
& FMODE_READ
))
286 ret
= do_readv_writev(VERIFY_WRITE
, file
, vector
, count
);
294 asmlinkage ssize_t
sys_writev(unsigned long fd
, const struct iovec
* vector
,
306 if (file
->f_op
&& file
->f_op
->write
&& (file
->f_mode
& FMODE_WRITE
)) {
307 down(&file
->f_dentry
->d_inode
->i_sem
);
308 ret
= do_readv_writev(VERIFY_READ
, file
, vector
, count
);
309 up(&file
->f_dentry
->d_inode
->i_sem
);
318 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
319 lseek back to original location. They fail just like lseek does on
320 non-seekable files. */
322 asmlinkage ssize_t
sys_pread(unsigned int fd
, char * buf
,
323 size_t count
, loff_t pos
)
327 ssize_t (*read
)(struct file
*, char *, size_t, loff_t
*);
335 if (!(file
->f_mode
& FMODE_READ
))
337 ret
= locks_verify_area(FLOCK_VERIFY_READ
, file
->f_dentry
->d_inode
,
342 if (!file
->f_op
|| !(read
= file
->f_op
->read
))
346 ret
= read(file
, buf
, count
, &pos
);
354 asmlinkage ssize_t
sys_pwrite(unsigned int fd
, const char * buf
,
355 size_t count
, loff_t pos
)
359 ssize_t (*write
)(struct file
*, const char *, size_t, loff_t
*);
367 if (!(file
->f_mode
& FMODE_WRITE
))
369 ret
= locks_verify_area(FLOCK_VERIFY_WRITE
, file
->f_dentry
->d_inode
,
374 if (!file
->f_op
|| !(write
= file
->f_op
->write
))
379 down(&file
->f_dentry
->d_inode
->i_sem
);
380 ret
= write(file
, buf
, count
, &pos
);
381 up(&file
->f_dentry
->d_inode
->i_sem
);