Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / read_write.c
1 /*
2  *  linux/fs/read_write.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/slab.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>
13 #include <linux/fsnotify.h>
14 #include <linux/security.h>
15 #include <linux/module.h>
16 #include <linux/syscalls.h>
17 #include <linux/pagemap.h>
18
19 #include <asm/uaccess.h>
20 #include <asm/unistd.h>
21
22 const struct file_operations generic_ro_fops = {
23         .llseek         = generic_file_llseek,
24         .read           = generic_file_read,
25         .mmap           = generic_file_readonly_mmap,
26         .sendfile       = generic_file_sendfile,
27 };
28
29 EXPORT_SYMBOL(generic_ro_fops);
30
31 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
32 {
33         long long retval;
34         struct inode *inode = file->f_mapping->host;
35
36         mutex_lock(&inode->i_mutex);
37         switch (origin) {
38                 case 2:
39                         offset += inode->i_size;
40                         break;
41                 case 1:
42                         offset += file->f_pos;
43         }
44         retval = -EINVAL;
45         if (offset>=0 && offset<=inode->i_sb->s_maxbytes) {
46                 if (offset != file->f_pos) {
47                         file->f_pos = offset;
48                         file->f_version = 0;
49                 }
50                 retval = offset;
51         }
52         mutex_unlock(&inode->i_mutex);
53         return retval;
54 }
55
56 EXPORT_SYMBOL(generic_file_llseek);
57
58 loff_t remote_llseek(struct file *file, loff_t offset, int origin)
59 {
60         long long retval;
61
62         lock_kernel();
63         switch (origin) {
64                 case 2:
65                         offset += i_size_read(file->f_dentry->d_inode);
66                         break;
67                 case 1:
68                         offset += file->f_pos;
69         }
70         retval = -EINVAL;
71         if (offset>=0 && offset<=file->f_dentry->d_inode->i_sb->s_maxbytes) {
72                 if (offset != file->f_pos) {
73                         file->f_pos = offset;
74                         file->f_version = 0;
75                 }
76                 retval = offset;
77         }
78         unlock_kernel();
79         return retval;
80 }
81 EXPORT_SYMBOL(remote_llseek);
82
83 loff_t no_llseek(struct file *file, loff_t offset, int origin)
84 {
85         return -ESPIPE;
86 }
87 EXPORT_SYMBOL(no_llseek);
88
89 loff_t default_llseek(struct file *file, loff_t offset, int origin)
90 {
91         long long retval;
92
93         lock_kernel();
94         switch (origin) {
95                 case 2:
96                         offset += i_size_read(file->f_dentry->d_inode);
97                         break;
98                 case 1:
99                         offset += file->f_pos;
100         }
101         retval = -EINVAL;
102         if (offset >= 0) {
103                 if (offset != file->f_pos) {
104                         file->f_pos = offset;
105                         file->f_version = 0;
106                 }
107                 retval = offset;
108         }
109         unlock_kernel();
110         return retval;
111 }
112 EXPORT_SYMBOL(default_llseek);
113
114 loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
115 {
116         loff_t (*fn)(struct file *, loff_t, int);
117
118         fn = no_llseek;
119         if (file->f_mode & FMODE_LSEEK) {
120                 fn = default_llseek;
121                 if (file->f_op && file->f_op->llseek)
122                         fn = file->f_op->llseek;
123         }
124         return fn(file, offset, origin);
125 }
126 EXPORT_SYMBOL(vfs_llseek);
127
128 asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
129 {
130         off_t retval;
131         struct file * file;
132         int fput_needed;
133
134         retval = -EBADF;
135         file = fget_light(fd, &fput_needed);
136         if (!file)
137                 goto bad;
138
139         retval = -EINVAL;
140         if (origin <= 2) {
141                 loff_t res = vfs_llseek(file, offset, origin);
142                 retval = res;
143                 if (res != (loff_t)retval)
144                         retval = -EOVERFLOW;    /* LFS: should only happen on 32 bit platforms */
145         }
146         fput_light(file, fput_needed);
147 bad:
148         return retval;
149 }
150
151 #ifdef __ARCH_WANT_SYS_LLSEEK
152 asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
153                            unsigned long offset_low, loff_t __user * result,
154                            unsigned int origin)
155 {
156         int retval;
157         struct file * file;
158         loff_t offset;
159         int fput_needed;
160
161         retval = -EBADF;
162         file = fget_light(fd, &fput_needed);
163         if (!file)
164                 goto bad;
165
166         retval = -EINVAL;
167         if (origin > 2)
168                 goto out_putf;
169
170         offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
171                         origin);
172
173         retval = (int)offset;
174         if (offset >= 0) {
175                 retval = -EFAULT;
176                 if (!copy_to_user(result, &offset, sizeof(offset)))
177                         retval = 0;
178         }
179 out_putf:
180         fput_light(file, fput_needed);
181 bad:
182         return retval;
183 }
184 #endif
185
186 /*
187  * rw_verify_area doesn't like huge counts. We limit
188  * them to something that fits in "int" so that others
189  * won't have to do range checks all the time.
190  */
191 #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
192
193 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
194 {
195         struct inode *inode;
196         loff_t pos;
197
198         if (unlikely((ssize_t) count < 0))
199                 goto Einval;
200         pos = *ppos;
201         if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
202                 goto Einval;
203
204         inode = file->f_dentry->d_inode;
205         if (unlikely(inode->i_flock && MANDATORY_LOCK(inode))) {
206                 int retval = locks_mandatory_area(
207                         read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
208                         inode, file, pos, count);
209                 if (retval < 0)
210                         return retval;
211         }
212         return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
213
214 Einval:
215         return -EINVAL;
216 }
217
218 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
219 {
220         set_current_state(TASK_UNINTERRUPTIBLE);
221         if (!kiocbIsKicked(iocb))
222                 schedule();
223         else
224                 kiocbClearKicked(iocb);
225         __set_current_state(TASK_RUNNING);
226 }
227
228 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
229 {
230         struct kiocb kiocb;
231         ssize_t ret;
232
233         init_sync_kiocb(&kiocb, filp);
234         kiocb.ki_pos = *ppos;
235         while (-EIOCBRETRY ==
236                 (ret = filp->f_op->aio_read(&kiocb, buf, len, kiocb.ki_pos)))
237                 wait_on_retry_sync_kiocb(&kiocb);
238
239         if (-EIOCBQUEUED == ret)
240                 ret = wait_on_sync_kiocb(&kiocb);
241         *ppos = kiocb.ki_pos;
242         return ret;
243 }
244
245 EXPORT_SYMBOL(do_sync_read);
246
247 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
248 {
249         ssize_t ret;
250
251         if (!(file->f_mode & FMODE_READ))
252                 return -EBADF;
253         if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
254                 return -EINVAL;
255         if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
256                 return -EFAULT;
257
258         ret = rw_verify_area(READ, file, pos, count);
259         if (ret >= 0) {
260                 count = ret;
261                 ret = security_file_permission (file, MAY_READ);
262                 if (!ret) {
263                         if (file->f_op->read)
264                                 ret = file->f_op->read(file, buf, count, pos);
265                         else
266                                 ret = do_sync_read(file, buf, count, pos);
267                         if (ret > 0) {
268                                 fsnotify_access(file->f_dentry);
269                                 current->rchar += ret;
270                         }
271                         current->syscr++;
272                 }
273         }
274
275         return ret;
276 }
277
278 EXPORT_SYMBOL(vfs_read);
279
280 ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
281 {
282         struct kiocb kiocb;
283         ssize_t ret;
284
285         init_sync_kiocb(&kiocb, filp);
286         kiocb.ki_pos = *ppos;
287         while (-EIOCBRETRY ==
288                (ret = filp->f_op->aio_write(&kiocb, buf, len, kiocb.ki_pos)))
289                 wait_on_retry_sync_kiocb(&kiocb);
290
291         if (-EIOCBQUEUED == ret)
292                 ret = wait_on_sync_kiocb(&kiocb);
293         *ppos = kiocb.ki_pos;
294         return ret;
295 }
296
297 EXPORT_SYMBOL(do_sync_write);
298
299 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
300 {
301         ssize_t ret;
302
303         if (!(file->f_mode & FMODE_WRITE))
304                 return -EBADF;
305         if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
306                 return -EINVAL;
307         if (unlikely(!access_ok(VERIFY_READ, buf, count)))
308                 return -EFAULT;
309
310         ret = rw_verify_area(WRITE, file, pos, count);
311         if (ret >= 0) {
312                 count = ret;
313                 ret = security_file_permission (file, MAY_WRITE);
314                 if (!ret) {
315                         if (file->f_op->write)
316                                 ret = file->f_op->write(file, buf, count, pos);
317                         else
318                                 ret = do_sync_write(file, buf, count, pos);
319                         if (ret > 0) {
320                                 fsnotify_modify(file->f_dentry);
321                                 current->wchar += ret;
322                         }
323                         current->syscw++;
324                 }
325         }
326
327         return ret;
328 }
329
330 EXPORT_SYMBOL(vfs_write);
331
332 static inline loff_t file_pos_read(struct file *file)
333 {
334         return file->f_pos;
335 }
336
337 static inline void file_pos_write(struct file *file, loff_t pos)
338 {
339         file->f_pos = pos;
340 }
341
342 asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count)
343 {
344         struct file *file;
345         ssize_t ret = -EBADF;
346         int fput_needed;
347
348         file = fget_light(fd, &fput_needed);
349         if (file) {
350                 loff_t pos = file_pos_read(file);
351                 ret = vfs_read(file, buf, count, &pos);
352                 file_pos_write(file, pos);
353                 fput_light(file, fput_needed);
354         }
355
356         return ret;
357 }
358 EXPORT_SYMBOL_GPL(sys_read);
359
360 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)
361 {
362         struct file *file;
363         ssize_t ret = -EBADF;
364         int fput_needed;
365
366         file = fget_light(fd, &fput_needed);
367         if (file) {
368                 loff_t pos = file_pos_read(file);
369                 ret = vfs_write(file, buf, count, &pos);
370                 file_pos_write(file, pos);
371                 fput_light(file, fput_needed);
372         }
373
374         return ret;
375 }
376
377 EXPORT_SYMBOL_GPL(sys_write);
378
379 asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf,
380                              size_t count, loff_t pos)
381 {
382         struct file *file;
383         ssize_t ret = -EBADF;
384         int fput_needed;
385
386         if (pos < 0)
387                 return -EINVAL;
388
389         file = fget_light(fd, &fput_needed);
390         if (file) {
391                 ret = -ESPIPE;
392                 if (file->f_mode & FMODE_PREAD)
393                         ret = vfs_read(file, buf, count, &pos);
394                 fput_light(file, fput_needed);
395         }
396
397         return ret;
398 }
399
400 asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf,
401                               size_t count, loff_t pos)
402 {
403         struct file *file;
404         ssize_t ret = -EBADF;
405         int fput_needed;
406
407         if (pos < 0)
408                 return -EINVAL;
409
410         file = fget_light(fd, &fput_needed);
411         if (file) {
412                 ret = -ESPIPE;
413                 if (file->f_mode & FMODE_PWRITE)  
414                         ret = vfs_write(file, buf, count, &pos);
415                 fput_light(file, fput_needed);
416         }
417
418         return ret;
419 }
420
421 /*
422  * Reduce an iovec's length in-place.  Return the resulting number of segments
423  */
424 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
425 {
426         unsigned long seg = 0;
427         size_t len = 0;
428
429         while (seg < nr_segs) {
430                 seg++;
431                 if (len + iov->iov_len >= to) {
432                         iov->iov_len = to - len;
433                         break;
434                 }
435                 len += iov->iov_len;
436                 iov++;
437         }
438         return seg;
439 }
440
441 EXPORT_UNUSED_SYMBOL(iov_shorten);  /*  June 2006  */
442
443 /* A write operation does a read from user space and vice versa */
444 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
445
446 static ssize_t do_readv_writev(int type, struct file *file,
447                                const struct iovec __user * uvector,
448                                unsigned long nr_segs, loff_t *pos)
449 {
450         typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
451         typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
452
453         size_t tot_len;
454         struct iovec iovstack[UIO_FASTIOV];
455         struct iovec *iov=iovstack, *vector;
456         ssize_t ret;
457         int seg;
458         io_fn_t fn;
459         iov_fn_t fnv;
460
461         /*
462          * SuS says "The readv() function *may* fail if the iovcnt argument
463          * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
464          * traditionally returned zero for zero segments, so...
465          */
466         ret = 0;
467         if (nr_segs == 0)
468                 goto out;
469
470         /*
471          * First get the "struct iovec" from user memory and
472          * verify all the pointers
473          */
474         ret = -EINVAL;
475         if (nr_segs > UIO_MAXIOV)
476                 goto out;
477         if (!file->f_op)
478                 goto out;
479         if (nr_segs > UIO_FASTIOV) {
480                 ret = -ENOMEM;
481                 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
482                 if (!iov)
483                         goto out;
484         }
485         ret = -EFAULT;
486         if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector)))
487                 goto out;
488
489         /*
490          * Single unix specification:
491          * We should -EINVAL if an element length is not >= 0 and fitting an
492          * ssize_t.  The total length is fitting an ssize_t
493          *
494          * Be careful here because iov_len is a size_t not an ssize_t
495          */
496         tot_len = 0;
497         ret = -EINVAL;
498         for (seg = 0; seg < nr_segs; seg++) {
499                 void __user *buf = iov[seg].iov_base;
500                 ssize_t len = (ssize_t)iov[seg].iov_len;
501
502                 if (len < 0)    /* size_t not fitting an ssize_t .. */
503                         goto out;
504                 if (unlikely(!access_ok(vrfy_dir(type), buf, len)))
505                         goto Efault;
506                 tot_len += len;
507                 if ((ssize_t)tot_len < 0) /* maths overflow on the ssize_t */
508                         goto out;
509         }
510         if (tot_len == 0) {
511                 ret = 0;
512                 goto out;
513         }
514
515         ret = rw_verify_area(type, file, pos, tot_len);
516         if (ret < 0)
517                 goto out;
518         ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
519         if (ret)
520                 goto out;
521
522         fnv = NULL;
523         if (type == READ) {
524                 fn = file->f_op->read;
525                 fnv = file->f_op->readv;
526         } else {
527                 fn = (io_fn_t)file->f_op->write;
528                 fnv = file->f_op->writev;
529         }
530         if (fnv) {
531                 ret = fnv(file, iov, nr_segs, pos);
532                 goto out;
533         }
534
535         /* Do it by hand, with file-ops */
536         ret = 0;
537         vector = iov;
538         while (nr_segs > 0) {
539                 void __user * base;
540                 size_t len;
541                 ssize_t nr;
542
543                 base = vector->iov_base;
544                 len = vector->iov_len;
545                 vector++;
546                 nr_segs--;
547
548                 nr = fn(file, base, len, pos);
549
550                 if (nr < 0) {
551                         if (!ret) ret = nr;
552                         break;
553                 }
554                 ret += nr;
555                 if (nr != len)
556                         break;
557         }
558 out:
559         if (iov != iovstack)
560                 kfree(iov);
561         if ((ret + (type == READ)) > 0) {
562                 if (type == READ)
563                         fsnotify_access(file->f_dentry);
564                 else
565                         fsnotify_modify(file->f_dentry);
566         }
567         return ret;
568 Efault:
569         ret = -EFAULT;
570         goto out;
571 }
572
573 ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
574                   unsigned long vlen, loff_t *pos)
575 {
576         if (!(file->f_mode & FMODE_READ))
577                 return -EBADF;
578         if (!file->f_op || (!file->f_op->readv && !file->f_op->read))
579                 return -EINVAL;
580
581         return do_readv_writev(READ, file, vec, vlen, pos);
582 }
583
584 EXPORT_SYMBOL(vfs_readv);
585
586 ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
587                    unsigned long vlen, loff_t *pos)
588 {
589         if (!(file->f_mode & FMODE_WRITE))
590                 return -EBADF;
591         if (!file->f_op || (!file->f_op->writev && !file->f_op->write))
592                 return -EINVAL;
593
594         return do_readv_writev(WRITE, file, vec, vlen, pos);
595 }
596
597 EXPORT_SYMBOL(vfs_writev);
598
599 asmlinkage ssize_t
600 sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
601 {
602         struct file *file;
603         ssize_t ret = -EBADF;
604         int fput_needed;
605
606         file = fget_light(fd, &fput_needed);
607         if (file) {
608                 loff_t pos = file_pos_read(file);
609                 ret = vfs_readv(file, vec, vlen, &pos);
610                 file_pos_write(file, pos);
611                 fput_light(file, fput_needed);
612         }
613
614         if (ret > 0)
615                 current->rchar += ret;
616         current->syscr++;
617         return ret;
618 }
619
620 asmlinkage ssize_t
621 sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen)
622 {
623         struct file *file;
624         ssize_t ret = -EBADF;
625         int fput_needed;
626
627         file = fget_light(fd, &fput_needed);
628         if (file) {
629                 loff_t pos = file_pos_read(file);
630                 ret = vfs_writev(file, vec, vlen, &pos);
631                 file_pos_write(file, pos);
632                 fput_light(file, fput_needed);
633         }
634
635         if (ret > 0)
636                 current->wchar += ret;
637         current->syscw++;
638         return ret;
639 }
640
641 static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
642                            size_t count, loff_t max)
643 {
644         struct file * in_file, * out_file;
645         struct inode * in_inode, * out_inode;
646         loff_t pos;
647         ssize_t retval;
648         int fput_needed_in, fput_needed_out;
649
650         /*
651          * Get input file, and verify that it is ok..
652          */
653         retval = -EBADF;
654         in_file = fget_light(in_fd, &fput_needed_in);
655         if (!in_file)
656                 goto out;
657         if (!(in_file->f_mode & FMODE_READ))
658                 goto fput_in;
659         retval = -EINVAL;
660         in_inode = in_file->f_dentry->d_inode;
661         if (!in_inode)
662                 goto fput_in;
663         if (!in_file->f_op || !in_file->f_op->sendfile)
664                 goto fput_in;
665         retval = -ESPIPE;
666         if (!ppos)
667                 ppos = &in_file->f_pos;
668         else
669                 if (!(in_file->f_mode & FMODE_PREAD))
670                         goto fput_in;
671         retval = rw_verify_area(READ, in_file, ppos, count);
672         if (retval < 0)
673                 goto fput_in;
674         count = retval;
675
676         retval = security_file_permission (in_file, MAY_READ);
677         if (retval)
678                 goto fput_in;
679
680         /*
681          * Get output file, and verify that it is ok..
682          */
683         retval = -EBADF;
684         out_file = fget_light(out_fd, &fput_needed_out);
685         if (!out_file)
686                 goto fput_in;
687         if (!(out_file->f_mode & FMODE_WRITE))
688                 goto fput_out;
689         retval = -EINVAL;
690         if (!out_file->f_op || !out_file->f_op->sendpage)
691                 goto fput_out;
692         out_inode = out_file->f_dentry->d_inode;
693         retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
694         if (retval < 0)
695                 goto fput_out;
696         count = retval;
697
698         retval = security_file_permission (out_file, MAY_WRITE);
699         if (retval)
700                 goto fput_out;
701
702         if (!max)
703                 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
704
705         pos = *ppos;
706         retval = -EINVAL;
707         if (unlikely(pos < 0))
708                 goto fput_out;
709         if (unlikely(pos + count > max)) {
710                 retval = -EOVERFLOW;
711                 if (pos >= max)
712                         goto fput_out;
713                 count = max - pos;
714         }
715
716         retval = in_file->f_op->sendfile(in_file, ppos, count, file_send_actor, out_file);
717
718         if (retval > 0) {
719                 current->rchar += retval;
720                 current->wchar += retval;
721         }
722         current->syscr++;
723         current->syscw++;
724
725         if (*ppos > max)
726                 retval = -EOVERFLOW;
727
728 fput_out:
729         fput_light(out_file, fput_needed_out);
730 fput_in:
731         fput_light(in_file, fput_needed_in);
732 out:
733         return retval;
734 }
735
736 asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count)
737 {
738         loff_t pos;
739         off_t off;
740         ssize_t ret;
741
742         if (offset) {
743                 if (unlikely(get_user(off, offset)))
744                         return -EFAULT;
745                 pos = off;
746                 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
747                 if (unlikely(put_user(pos, offset)))
748                         return -EFAULT;
749                 return ret;
750         }
751
752         return do_sendfile(out_fd, in_fd, NULL, count, 0);
753 }
754
755 asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count)
756 {
757         loff_t pos;
758         ssize_t ret;
759
760         if (offset) {
761                 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
762                         return -EFAULT;
763                 ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
764                 if (unlikely(put_user(pos, offset)))
765                         return -EFAULT;
766                 return ret;
767         }
768
769         return do_sendfile(out_fd, in_fd, NULL, count, 0);
770 }