patch-2.4.5 linux/mm/filemap.c
Next file: linux/mm/highmem.c
Previous file: linux/mm/bootmem.c
Back to the patch index
Back to the overall index
- Lines: 107
- Date:
Tue May 22 10:52:35 2001
- Orig file:
v2.4.4/linux/mm/filemap.c
- Orig date:
Wed Apr 25 16:13:50 2001
diff -u --recursive --new-file v2.4.4/linux/mm/filemap.c linux/mm/filemap.c
@@ -9,6 +9,7 @@
* most "normal" filesystems (but you don't /have/ to use this:
* the NFS filesystem used to do this differently, for example)
*/
+#include <linux/module.h>
#include <linux/slab.h>
#include <linux/shm.h>
#include <linux/mman.h>
@@ -284,6 +285,34 @@
spin_unlock(&pagecache_lock);
}
+/*
+ * This function is pretty much like __find_page_nolock(), but it only
+ * requires 2 arguments and doesn't mark the page as touched, making it
+ * ideal for ->writepage() clustering and other places where you don't
+ * want to mark the page referenced.
+ *
+ * The caller needs to hold the pagecache_lock.
+ */
+static struct page * FASTCALL(__find_page_simple(struct address_space *, unsigned long));
+static struct page * __find_page_simple(struct address_space *mapping, unsigned long index)
+{
+ struct page **next = page_hash(mapping, index);;
+
+ for (;;) {
+ struct page *page = *next;
+ if (!page)
+ break;
+ next = &page->next_hash;
+ if (page->mapping != mapping)
+ continue;
+ if (page->index != index)
+ continue;
+ return page;
+ }
+
+ return NULL;
+}
+
static inline struct page * __find_page_nolock(struct address_space *mapping, unsigned long offset, struct page *page)
{
goto inside;
@@ -298,14 +327,9 @@
if (page->index == offset)
break;
}
- /*
- * Touching the page may move it to the active list.
- * If we end up with too few inactive pages, we wake
- * up kswapd.
- */
- age_page_up(page);
- if (inactive_shortage() > inactive_target / 2 && free_shortage())
- wakeup_kswapd();
+ /* Mark the page referenced, kswapd will find it later. */
+ SetPageReferenced(page);
+
not_found:
return page;
}
@@ -331,7 +355,7 @@
return 0;
}
-static int waitfor_one_page(struct page *page)
+int waitfor_one_page(struct page *page)
{
int error = 0;
struct buffer_head *bh, *head = page->buffers;
@@ -762,7 +786,6 @@
{
struct inode *inode = file->f_dentry->d_inode;
struct address_space *mapping = inode->i_mapping;
- struct page **hash;
struct page *page;
unsigned long start;
@@ -783,8 +806,7 @@
*/
spin_lock(&pagecache_lock);
while (--index >= start) {
- hash = page_hash(mapping, index);
- page = __find_page_nolock(mapping, index, *hash);
+ page = __find_page_simple(mapping, index);
if (!page)
break;
deactivate_page(page);
@@ -2549,11 +2571,14 @@
* Linus frestrict idea will clean these up nicely..
*/
- if (pos > inode->i_sb->s_maxbytes)
+ if (pos >= inode->i_sb->s_maxbytes)
{
- send_sig(SIGXFSZ, current, 0);
- err = -EFBIG;
- goto out;
+ if (count || pos > inode->i_sb->s_maxbytes) {
+ send_sig(SIGXFSZ, current, 0);
+ err = -EFBIG;
+ goto out;
+ }
+ /* zero-length writes at ->s_maxbytes are OK */
}
if (pos + count > inode->i_sb->s_maxbytes)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)