From c8494f41bb058f97569d5af5f7d70e2b48261f7d Mon Sep 17 00:00:00 2001
From: Pavel Tsekov <ptsekov@gmx.net>
Date: Wed, 25 Jan 2006 14:04:27 +0000
Subject: [PATCH] * xdirentry.h (LS_LINEAR_PREOPEN): New macro definition. *
 direntry.c (vfs_s_open): When opening a file in linear mode, defer the actual
 open operation until the first read call. (vfs_s_read): When reading in
 linear mode, open the file on the first read operation. (vfs_s_lseek): When
 in linear mode, make sure that seeking is allowed only before the first read
 operation. * ftpfs.c (ftpfs_ctl): Make the code aware of LS_LINEAR_PREOPEN. *
 fish.c (fish_ctl): Likewise.

---
 vfs/ChangeLog   | 12 ++++++++++++
 vfs/direntry.c  | 16 ++++++++++++----
 vfs/fish.c      |  2 +-
 vfs/ftpfs.c     |  2 +-
 vfs/xdirentry.h |  1 +
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/vfs/ChangeLog b/vfs/ChangeLog
index 5b2dc3dcd..873abf403 100644
--- a/vfs/ChangeLog
+++ b/vfs/ChangeLog
@@ -1,3 +1,15 @@
+2006-01-25  Jindrich Makovicka  <makovick@kmlinux.fjfi.cvut.cz>
+
+	* xdirentry.h (LS_LINEAR_PREOPEN): New macro definition.
+	* direntry.c (vfs_s_open): When opening a file in linear mode,
+	defer the actual open operation until the first read call.
+	(vfs_s_read): When reading in linear mode, open the file
+	on the first read operation.
+	(vfs_s_lseek): When in linear mode, make sure that seeking is
+	allowed only before the first read operation.
+	* ftpfs.c (ftpfs_ctl): Make the code aware of LS_LINEAR_PREOPEN.
+	* fish.c (fish_ctl): Likewise.
+
 2006-01-24  Pavel Tsekov  <ptsekov@gmx.net>
 
 	* ftpfs.c (ftpfs_dir_load): Fix a bad ERRNOR call.
diff --git a/vfs/direntry.c b/vfs/direntry.c
index 7867c0796..839ef19cd 100644
--- a/vfs/direntry.c
+++ b/vfs/direntry.c
@@ -779,10 +779,10 @@ vfs_s_open (struct vfs_class *me, const char *file, int flags, int mode)
     if (IS_LINEAR (flags)) {
 	if (MEDATA->linear_start) {
 	    print_vfs_message (_("Starting linear transfer..."));
-	    if (!MEDATA->linear_start (me, fh, 0)) {
-		g_free (fh);
-		return NULL;
-	    }
+	    fh->linear = LS_LINEAR_PREOPEN;
+	} else {
+	    g_free (fh);
+	    ERRNOR (ENOSYS, NULL);
 	}
     } else if ((MEDATA->fh_open)
 	       && (MEDATA->fh_open (me, fh, flags, mode))) {
@@ -811,6 +811,11 @@ vfs_s_read (void *fh, char *buffer, int count)
     int n;
     struct vfs_class *me = FH_SUPER->me;
 
+    if (FH->linear == LS_LINEAR_PREOPEN) {
+	if (!MEDATA->linear_start (me, FH, FH->pos))
+	    return -1;
+    }
+
     if (FH->linear == LS_LINEAR_CLOSED)
         vfs_die ("linear_start() did not set linear_state!");
 
@@ -852,6 +857,9 @@ vfs_s_lseek (void *fh, off_t offset, int whence)
 {
     off_t size = FH->ino->st.st_size;
 
+    if (FH->linear == LS_LINEAR_OPEN)
+        vfs_die ("cannot lseek() after linear_read!");
+
     if (FH->handle != -1){	/* If we have local file opened, we want to work with it */
 	int retval = lseek (FH->handle, offset, whence);
 	if (retval == -1)
diff --git a/vfs/fish.c b/vfs/fish.c
index 62bd13114..826a3e965 100644
--- a/vfs/fish.c
+++ b/vfs/fish.c
@@ -680,7 +680,7 @@ fish_ctl (void *fh, int ctlop, void *arg)
 
 		if (!FH->linear)
 		    vfs_die ("You may not do this");
-		if (FH->linear == LS_LINEAR_CLOSED)
+		if (FH->linear == LS_LINEAR_CLOSED || FH->linear == LS_LINEAR_PREOPEN)
 		    return 0;
 
 		v = vfs_s_select_on_two (FH_SUPER->u.fish.sockr, 0);
diff --git a/vfs/ftpfs.c b/vfs/ftpfs.c
index f0329ae71..a7fc95001 100644
--- a/vfs/ftpfs.c
+++ b/vfs/ftpfs.c
@@ -1462,7 +1462,7 @@ static int ftpfs_ctl (void *fh, int ctlop, void *arg)
 		
 		if (!FH->linear)
 		    vfs_die ("You may not do this");
-		if (FH->linear == LS_LINEAR_CLOSED)
+		if (FH->linear == LS_LINEAR_CLOSED || FH->linear == LS_LINEAR_PREOPEN)
 		    return 0;
 
 		v = vfs_s_select_on_two (FH->u.ftp.sock, 0);
diff --git a/vfs/xdirentry.h b/vfs/xdirentry.h
index 599086a1a..9dd2e81ea 100644
--- a/vfs/xdirentry.h
+++ b/vfs/xdirentry.h
@@ -207,5 +207,6 @@ int vfs_s_retrieve_file (struct vfs_class *me, struct vfs_s_inode *ino);
 #define LS_NOT_LINEAR 0
 #define LS_LINEAR_CLOSED 1
 #define LS_LINEAR_OPEN 2
+#define LS_LINEAR_PREOPEN 3
 
 #endif