patch-2.1.126 linux/mm/filemap.c

Next file: linux/mm/memory.c
Previous file: linux/kernel/sys.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.125/linux/mm/filemap.c linux/mm/filemap.c
@@ -153,7 +153,7 @@
 		} while (tmp != bh);
 
 		/* Refuse to swap out all buffer pages */
-		if ((buffermem >> PAGE_SHIFT) * 100 < (buffer_mem.min_percent * num_physpages))
+		if (buffer_under_min())
 			goto next;
 	}
 
@@ -167,6 +167,11 @@
 	case 1:
 		/* is it a swap-cache or page-cache page? */
 		if (page->inode) {
+			/* Throw swap-cache pages away more aggressively */
+			if (PageSwapCache(page)) {
+				delete_from_swap_cache(page);
+				return 1;
+			}
 			if (test_and_clear_bit(PG_referenced, &page->flags)) {
 				touch_page(page);
 				break;
@@ -174,12 +179,8 @@
 			age_page(page);
 			if (page->age)
 				break;
-			if (page_cache_size * 100 < (page_cache.min_percent * num_physpages))
+			if (pgcache_under_min())
 				break;
-			if (PageSwapCache(page)) {
-				delete_from_swap_cache(page);
-				return 1;
-			}
 			remove_inode_page(page);
 			return 1;
 		}
@@ -1519,24 +1520,42 @@
 {
 	struct dentry	*dentry = file->f_dentry; 
 	struct inode	*inode = dentry->d_inode; 
+	unsigned long	pos = *ppos;
+	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 	struct page	*page, **hash;
 	unsigned long	page_cache = 0;
 	unsigned long	pgpos, offset;
 	unsigned long	bytes, written;
-	unsigned long	pos;
 	long		status, sync, didread;
 
 	if (!inode->i_op || !inode->i_op->updatepage)
 		return -EIO;
 
 	sync    = file->f_flags & O_SYNC;
-	pos     = *ppos;
 	written = 0;
-	status  = 0;
 
 	if (file->f_flags & O_APPEND)
 		pos = inode->i_size;
 
+	/*
+	 * Check whether we've reached the file size limit.
+	 */
+	status = -EFBIG;
+	if (pos >= limit) {
+		send_sig(SIGXFSZ, current, 0);
+		goto out;
+	}
+
+	status  = 0;
+	/*
+	 * Check whether to truncate the write,
+	 * and send the signal if we do.
+	 */
+	if (count > limit - pos) {
+		send_sig(SIGXFSZ, current, 0);
+		count = limit - pos;
+	}
+
 	while (count) {
 		/*
 		 * Try to find the page in the cache. If it isn't there,
@@ -1621,6 +1640,7 @@
 
 	if (page_cache)
 		free_page(page_cache);
+out:
 	return written ? written : status;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov