Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-vfs/configure.in,v
retrieving revision 1.266
diff -u -p -r1.266 configure.in
--- configure.in	8 Dec 2003 09:27:43 -0000	1.266
+++ configure.in	19 Dec 2003 13:18:22 -0000
@@ -134,7 +134,7 @@ AC_CHECK_LIB(nsl, t_accept)
 AC_CHECK_LIB(socket, socket)
 
 AC_FUNC_ALLOCA
-AC_CHECK_FUNCS(getdtablesize open64 lseek64 statvfs seteuid setegid setresuid setresgid readdir_r mbrtowc inet_pton getdelim)
+AC_CHECK_FUNCS(getdtablesize open64 lseek64 statvfs seteuid setegid setresuid setresgid readdir_r mbrtowc inet_pton getdelim posix_fadvise)
 
 dnl Volume monitor stuff			     
 AC_CHECK_FUNCS(setmntent endmntent hasmntopt getmntinfo)
Index: libgnomevfs/gnome-vfs-handle-private.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle-private.h,v
retrieving revision 1.3
diff -u -p -r1.3 gnome-vfs-handle-private.h
--- libgnomevfs/gnome-vfs-handle-private.h	19 Dec 2002 17:57:19 -0000	1.3
+++ libgnomevfs/gnome-vfs-handle-private.h	19 Dec 2003 13:18:22 -0000
@@ -65,6 +65,9 @@ GnomeVFSResult   _gnome_vfs_handle_do_fi
 						      const char              *operation,
 						      gpointer                 operation_data,
 						      GnomeVFSContext         *context);
+GnomeVFSResult   _gnome_vfs_handle_forget_cache       (GnomeVFSHandle         *handle,
+						       GnomeVFSFileOffset      offset,
+						       GnomeVFSFileSize        size);
 
 G_END_DECLS
 
Index: libgnomevfs/gnome-vfs-handle.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-handle.c,v
retrieving revision 1.23
diff -u -p -r1.23 gnome-vfs-handle.c
--- libgnomevfs/gnome-vfs-handle.c	19 Dec 2002 17:57:19 -0000	1.23
+++ libgnomevfs/gnome-vfs-handle.c	19 Dec 2003 13:18:22 -0000
@@ -135,6 +135,16 @@ _gnome_vfs_handle_do_read (GnomeVFSHandl
 }
 
 GnomeVFSResult
+_gnome_vfs_handle_forget_cache (GnomeVFSHandle *handle,
+				GnomeVFSFileOffset offset,
+				GnomeVFSFileSize size)
+{
+	INVOKE_AND_RETURN (handle, forget_cache, (handle->uri->method, handle->method_handle,
+						  offset, size));
+}
+
+
+GnomeVFSResult
 _gnome_vfs_handle_do_write (GnomeVFSHandle *handle,
 			   gconstpointer buffer,
 			   GnomeVFSFileSize num_bytes,
Index: libgnomevfs/gnome-vfs-method.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-method.h,v
retrieving revision 1.13
diff -u -p -r1.13 gnome-vfs-method.h
--- libgnomevfs/gnome-vfs-method.h	12 Nov 2002 09:29:05 -0000	1.13
+++ libgnomevfs/gnome-vfs-method.h	19 Dec 2003 13:18:22 -0000
@@ -215,6 +215,11 @@ typedef GnomeVFSResult (* GnomeVFSMethod
 					 gpointer operation_data,
 					 GnomeVFSContext *context);
 
+typedef GnomeVFSResult (* GnomeVFSMethodForgetCacheFunc)
+     					(GnomeVFSMethod *method,
+      					 GnomeVFSMethodHandle *method_handle,
+					 GnomeVFSFileOffset offset,
+					 GnomeVFSFileSize size);
 
 
 /* Use this macro to test whether a given function is implemented in
@@ -254,6 +259,7 @@ struct GnomeVFSMethod {
 	GnomeVFSMethodMonitorAddFunc monitor_add;
 	GnomeVFSMethodMonitorCancelFunc monitor_cancel;
 	GnomeVFSMethodFileControlFunc file_control;
+	GnomeVFSMethodForgetCacheFunc forget_cache;
 };
 
 gboolean	   gnome_vfs_method_init   (void);
Index: libgnomevfs/gnome-vfs-ops.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-ops.c,v
retrieving revision 1.37
diff -u -p -r1.37 gnome-vfs-ops.c
--- libgnomevfs/gnome-vfs-ops.c	12 Feb 2003 12:40:02 -0000	1.37
+++ libgnomevfs/gnome-vfs-ops.c	19 Dec 2003 13:18:23 -0000
@@ -26,6 +26,7 @@
 #include "gnome-vfs-monitor-private.h"
 #include "gnome-vfs-cancellable-ops.h"
 #include "gnome-vfs-handle-private.h"
+#include "gnome-vfs-private-utils.h"
 #include <glib/gmessages.h>
 
 /**
@@ -121,6 +122,17 @@ gnome_vfs_create (GnomeVFSHandle **handl
 	return result;
 }
 
+GnomeVFSResult
+gnome_vfs_forget_cache (GnomeVFSHandle *handle,
+			GnomeVFSFileOffset offset,
+			GnomeVFSFileSize size)
+{
+	g_return_val_if_fail (handle != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+	return _gnome_vfs_handle_forget_cache (handle, offset, size);
+}
+
+
 /**
  * gnome_vfs_create_uri:
  * @handle: A pointer to a pointer to a GnomeVFSHandle object
Index: libgnomevfs/gnome-vfs-private-utils.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-private-utils.h,v
retrieving revision 1.17
diff -u -p -r1.17 gnome-vfs-private-utils.h
--- libgnomevfs/gnome-vfs-private-utils.h	24 Apr 2003 17:51:54 -0000	1.17
+++ libgnomevfs/gnome-vfs-private-utils.h	19 Dec 2003 13:18:23 -0000
@@ -88,6 +88,11 @@ gboolean       _gnome_vfs_use_handler_fo
 gboolean       _gnome_vfs_prepend_terminal_to_vector      (int          *argc,
 							   char       ***argv);
 
+/* This is private for the moment, due to API freeze */
+GnomeVFSResult gnome_vfs_forget_cache (GnomeVFSHandle *handle,
+				       GnomeVFSFileOffset offset,
+				       GnomeVFSFileSize size);
+
 G_END_DECLS
 
 #endif /* _GNOME_VFS_PRIVATE_UTILS_H */
Index: libgnomevfs/gnome-vfs-xfer.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-xfer.c,v
retrieving revision 1.110
diff -u -p -r1.110 gnome-vfs-xfer.c
--- libgnomevfs/gnome-vfs-xfer.c	15 Dec 2003 14:57:07 -0000	1.110
+++ libgnomevfs/gnome-vfs-xfer.c	19 Dec 2003 13:18:23 -0000
@@ -64,6 +64,12 @@ enum {
 	DEFAULT_SIZE_OVERHEAD = 1024
 };
 
+/* When the total copy size is over this limit, we try to
+ * forget the data cached for the files, in order to
+ * lower VM pressure
+ */
+#define DROP_CACHE_SIZE_LIMIT (20*1024*1024)
+
 /* in asynch mode the progress callback does a context switch every time
  * it gets called. We'll only call it every now and then to not loose a
  * lot of performance
@@ -1032,6 +1038,7 @@ copy_file_data (GnomeVFSHandle *target_h
 	gpointer buffer;
 	const char *write_buffer;
 	GnomeVFSFileSize total_bytes_read;
+	gboolean forget_cache;
 
 	*skip = FALSE;
 
@@ -1041,6 +1048,9 @@ copy_file_data (GnomeVFSHandle *target_h
 
 	buffer = g_malloc (block_size);
 	total_bytes_read = 0;
+
+	/* Enable streaming if the total size is large */
+	forget_cache = progress->progress_info->bytes_total >= DROP_CACHE_SIZE_LIMIT;
 	
 	do {
 		GnomeVFSFileSize bytes_read;
@@ -1058,6 +1068,10 @@ copy_file_data (GnomeVFSHandle *target_h
 
 			result = gnome_vfs_read (source_handle, buffer,
 						 block_size, &bytes_read);
+			if (forget_cache) {
+				gnome_vfs_forget_cache (source_handle,
+							total_bytes_read, bytes_read);
+			}
 			if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF)
 				retry = handle_error (&result, progress,
 						      error_mode, skip);
@@ -1087,6 +1101,11 @@ copy_file_data (GnomeVFSHandle *target_h
 			bytes_to_write -= bytes_written;
 			write_buffer += bytes_written;
 		} while ((result == GNOME_VFS_OK && bytes_to_write > 0) || retry);
+		
+		if (forget_cache && bytes_to_write == 0) {
+			gnome_vfs_forget_cache (source_handle,
+						total_bytes_read - bytes_read, bytes_read);
+		}
 
 		progress->progress_info->phase = GNOME_VFS_XFER_PHASE_COPYING;
 
@@ -1132,7 +1151,7 @@ xfer_open_source (GnomeVFSHandle **sourc
 {
 	GnomeVFSResult result;
 	gboolean retry;
-
+	
 	*skip = FALSE;
 	do {
 		retry = FALSE;
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.122
diff -u -p -r1.122 file-method.c
--- modules/file-method.c	19 Aug 2003 13:06:30 -0000	1.122
+++ modules/file-method.c	19 Dec 2003 13:18:23 -0000
@@ -207,6 +207,12 @@ do_open (GnomeVFSMethod *method,
 	if (fd == -1)
 		return gnome_vfs_result_from_errno ();
 
+#ifdef HAVE_POSIX_FADVISE
+	if (! (mode & GNOME_VFS_OPEN_RANDOM)) {
+		posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+	}
+#endif
+	
 	if (fstat (fd, &statbuf) != 0)
 		return gnome_vfs_result_from_errno ();
 
@@ -303,6 +309,26 @@ do_close (GnomeVFSMethod *method,
 }
 
 static GnomeVFSResult
+do_forget_cache	(GnomeVFSMethod *method,
+		 GnomeVFSMethodHandle *method_handle,
+		 GnomeVFSFileOffset offset,
+		 GnomeVFSFileSize size)
+{
+	FileHandle *file_handle;
+
+	g_return_val_if_fail (method_handle != NULL, GNOME_VFS_ERROR_INTERNAL);
+
+	file_handle = (FileHandle *) method_handle;
+
+#ifdef HAVE_POSIX_FADVISE
+	posix_fadvise (file_handle->fd, offset, size, POSIX_FADV_DONTNEED);
+#endif
+	
+	return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult
 do_read (GnomeVFSMethod *method,
 	 GnomeVFSMethodHandle *method_handle,
 	 gpointer buffer,
@@ -2365,7 +2391,8 @@ static GnomeVFSMethod method = {
 	do_create_symbolic_link,
 	do_monitor_add,
 	do_monitor_cancel,
-	do_file_control
+	do_file_control,
+	do_forget_cache
 };
 
 GnomeVFSMethod *
