diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 18:11:38 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 18:11:38 -0800 |
| commit | 1a0153507ffae9cf3350e76c12d441788c0191e1 (patch) | |
| tree | d05a502b4fc05202c84c1667019460c08ea088cd /mm/filemap.c | |
| parent | b0683ac8928c4cf40646a6ce3eb6ffe94605acfa (diff) | |
v2.4.3.2 -> v2.4.3.3
- Hui-Fen Hsu: sis900 driver update
- NIIBE Yutaka: Super-H update
- Alan Cox: more resyncs (ARM down, but more to go)
- David Miller: network zerocopy, Sparc sync, qlogic,FC fix, etc.
- David Miller/me: get rid of various drivers hacks to do mmap
alignment behind the back of the VM layer. Create a real
protocol for it.
Diffstat (limited to 'mm/filemap.c')
| -rw-r--r-- | mm/filemap.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index fa253ed7862a..4fc772ce0c64 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1061,7 +1061,7 @@ void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * for (;;) { struct page *page, **hash; - unsigned long end_index, nr; + unsigned long end_index, nr, ret; end_index = inode->i_size >> PAGE_CACHE_SHIFT; if (index > end_index) @@ -1109,13 +1109,13 @@ page_ok: * "pos" here (the actor routine has to update the user buffer * pointers and the remaining count). */ - nr = actor(desc, page, offset, nr); - offset += nr; + ret = actor(desc, page, offset, nr); + offset += ret; index += offset >> PAGE_CACHE_SHIFT; offset &= ~PAGE_CACHE_MASK; page_cache_release(page); - if (nr && desc->count) + if (ret == nr && desc->count) continue; break; @@ -1208,7 +1208,7 @@ no_cached_page: UPDATE_ATIME(inode); } -static int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) +int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size) { char *kaddr; unsigned long left, count = desc->count; @@ -1261,21 +1261,29 @@ ssize_t generic_file_read(struct file * filp, char * buf, size_t count, loff_t * static int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset , unsigned long size) { - char *kaddr; ssize_t written; unsigned long count = desc->count; struct file *file = (struct file *) desc->buf; - mm_segment_t old_fs; if (size > count) size = count; - old_fs = get_fs(); - set_fs(KERNEL_DS); - kaddr = kmap(page); - written = file->f_op->write(file, kaddr + offset, size, &file->f_pos); - kunmap(page); - set_fs(old_fs); + if (file->f_op->writepage) { + written = file->f_op->writepage(file, page, offset, + size, &file->f_pos, size<count); + } else { + char *kaddr; + mm_segment_t old_fs; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + + kaddr = kmap(page); + written = file->f_op->write(file, kaddr + offset, size, &file->f_pos); + kunmap(page); + + set_fs(old_fs); + } if (written < 0) { desc->error = written; written = 0; @@ -2407,7 +2415,7 @@ struct page *grab_cache_page(struct address_space *mapping, unsigned long index) return page; } -static inline void remove_suid(struct inode *inode) +inline void remove_suid(struct inode *inode) { unsigned int mode; |
