Index: xfs/linux/xfs_inodeops.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/xfs/linux/xfs_inodeops.c,v
retrieving revision 1.154
diff -u -r1.154 xfs_inodeops.c
--- xfs_inodeops.c	2001/03/06 22:21:28	1.154
+++ xfs_inodeops.c	2001/03/07 14:57:04
@@ -521,12 +521,13 @@
   do {
     if (!XFS_TOKEN_GOT(xn, tok))
       {
-	struct xfs_message_open msg;
-	msg.header.opcode = XFS_MSG_OPEN;
+	struct xfs_message_getdata msg;
+	msg.header.opcode = XFS_MSG_GETDATA;
 	msg.cred.uid = current->uid;
 	msg.cred.pag = xfs_get_pag();
 	msg.handle = xn->handle;
 	msg.tokens = tok;
+	msg.offset = 0;
 	error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
 	if (error == 0)
 	  error = ((struct xfs_message_wakeup *) &msg)->error;
@@ -759,33 +760,41 @@
  */
 
 static int
-xfs_data_valid(struct inode *vp, u_int tok)
+xfs_data_valid(struct inode *vp, u_int tok, u_int32_t offset)
 {
-  struct xfs *xfsp = XFS_FROM_VNODE(vp);
-  struct xfs_node *xn = VNODE_TO_XNODE(vp);
-  int error = 0;
-  
-  do {
-    if (!XFS_TOKEN_GOT(xn, tok))
-      {
-	struct xfs_message_getdata msg;
-	msg.header.opcode = XFS_MSG_GETDATA;
-	msg.cred.uid = current->uid;
-	msg.cred.pag = xfs_get_pag();
-	msg.handle = xn->handle;
-	msg.tokens = tok;
-	error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
-	if (error == 0)
-	  error = ((struct xfs_message_wakeup *) &msg)->error;
-      }
-    else
-      {
-	goto done;
-      }
-  } while (error == 0);
-
+    struct xfs *xfsp = XFS_FROM_VNODE(vp);
+    struct xfs_node *xn = VNODE_TO_XNODE(vp);
+    int error = 0;
+    
+    if (XFS_TOKEN_GOT(xn, tok|XFS_ATTR_R) && offset > xn->attr.xa_size) {
+	offset = xn->attr.xa_size;
+    }
+    
+    do {
+	XFSDEB(XDEBVNOPS, ("xfs_data_valid: offset: want %ld has %ld, tokens: want %lx has %lx length: %ld\n",
+			   (long) offset, (long) xn->offset,
+			   (long) tok, (long) xn->tokens,
+			   (long) xn->attr.xa_size));
+	if (!XFS_TOKEN_GOT(xn, tok) || offset > xn->offset) {
+	    struct xfs_message_getdata msg;
+	    msg.header.opcode = XFS_MSG_GETDATA;
+	    msg.cred.uid = current->uid;
+	    msg.cred.pag = xfs_get_pag();
+	    msg.handle = xn->handle;
+	    msg.tokens = tok;
+	    msg.offset = offset;
+	    error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+	    if (error == 0)
+		error = ((struct xfs_message_wakeup *) &msg)->error;
+	}
+	else
+	{
+	    goto done;
+	}
+    } while (error == 0);
+    
  done:
-  return error;
+    return error;
 }
 
 /*
@@ -819,7 +828,7 @@
     XFSDEB(XDEBVNOPS, ("xfs_mmap aliases:"));
     print_aliases(inode);
     
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, inode->i_size /* XXX */);
     if (error == 0) {
 	error = generic_file_mmap(file, vma);
 	if (error)
@@ -877,7 +886,7 @@
     XFSDEB(XDEBVNOPS, ("xfs_read_file aliases:"));
     print_aliases(xfs_inode);
     
-    error = xfs_data_valid(xfs_inode, XFS_DATA_R);
+    error = xfs_data_valid(xfs_inode, XFS_DATA_R, *ppos + count);
 
     cache_dentry = DATA_FROM_VNODE(xfs_inode);
     if (cache_dentry == NULL) {
@@ -937,7 +946,7 @@
     XFSDEB(XDEBVNOPS, ("xfs_readpage aliases:"));
     print_aliases(xfs_inode);
     
-    error = xfs_data_valid(xfs_inode, XFS_DATA_R);
+    error = xfs_data_valid(xfs_inode, XFS_DATA_R, xfs_inode->i_size);
     
     if (error)
 	return error;
@@ -987,7 +996,7 @@
     XFSDEB(XDEBVNOPS, ("xfs_write_file buf: %p (%x %x)\n", buf,
 		       (int) buf[0], (int) buf[1]));
 
-    error = xfs_data_valid(inode, XFS_DATA_W);
+    error = xfs_data_valid(inode, XFS_DATA_W, *ppos + count);
     
     if (error == 0) {
         struct dentry *t = DATA_FROM_VNODE(inode);
@@ -1052,7 +1061,7 @@
     
     XFSDEB(XDEBVNOPS, ("xfs_read_file: tokens: 0x%x\n", xn->tokens));
 
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, *ppos + count);
     if (error) {
 	XFSDEB(XDEBVNOPS, ("xfs_read_file: data not valid %d\n", error));
 	return error;
@@ -1077,7 +1086,7 @@
     
     XFSDEB(XDEBVNOPS, ("xfs_write_file: tokens: 0x%x\n", xn->tokens));
 
-    error = xfs_data_valid(inode, XFS_DATA_W);
+    error = xfs_data_valid(inode, XFS_DATA_W, *ppos + count);
     if (error) {
 	XFSDEB(XDEBVNOPS, ("xfs_write_file: data not valid %d\n", error));
 	return error;
@@ -1397,7 +1406,7 @@
 
     XFSDEB(XDEBREADDIR, ("xfs_readdir\n"));
     
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, inode->i_size);
     if (error) {
 	printk(KERN_EMERG "xfs_readdir: data not valid: %d\n", error);
 	return error;
@@ -1545,7 +1554,7 @@
     
     XFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
     
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, inode->i_size);
     XFSDEB(XDEBVNOPS, ("xfs_readlink: datavalid: %d\n", error));
     if (error == 0)
     {
@@ -1628,7 +1637,7 @@
 
     XFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
     
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, inode->i_size);
     if (error == 0)
 	error = page_readlink(dentry, buffer, buflen);
 
@@ -1648,7 +1657,7 @@
 
     XFSDEB(XDEBVNOPS, ("xfs_follow_link\n"));
     
-    error = xfs_data_valid(inode, XFS_DATA_R);
+    error = xfs_data_valid(inode, XFS_DATA_R, inode->i_size);
     if (error)
 	return error;
 
Index: xfs/linux/xfs_message.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/xfs/linux/xfs_message.c,v
retrieving revision 1.95
diff -u -r1.95 xfs_message.c
--- xfs_message.c	2001/01/30 01:36:45	1.95
+++ xfs_message.c	2001/03/04 04:07:57
@@ -315,11 +315,12 @@
 		clear_all_children (inode, 0);
 	    t->tokens = message->node.tokens;
 	    t->attr = message->node.attr;
-	    XFSDEB(XDEBMSG, ("xfs_message_installdata size before: %ld\n",
-			     (long) inode->i_size));
+	    XFSDEB(XDEBMSG, ("xfs_message_installdata size before: %ld(%ld)\n",
+			     (long) inode->i_size, (long) t->offset));
 	    xfs_attr2inode (&t->attr, inode, 1);
-	    XFSDEB(XDEBMSG, ("xfs_message_installdata size after: %ld\n",
-			     (long) inode->i_size));
+	    t->offset = message->offset;
+	    XFSDEB(XDEBMSG, ("xfs_message_installdata size after: %ld(%ld)\n",
+			     (long) inode->i_size, (long) t->offset));
 	    memmove(t->id, message->node.id, sizeof(t->id));
 	    memmove(t->rights, message->node.rights, sizeof(t->rights));
 	    t->anonrights = message->node.anonrights;
Index: xfs/linux/xfs_node.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/xfs/linux/xfs_node.c,v
retrieving revision 1.52
diff -u -r1.52 xfs_node.c
--- xfs_node.c	2001/01/30 01:35:38	1.52
+++ xfs_node.c	2001/03/06 00:02:12
@@ -189,6 +189,7 @@
 	result->handle = node->handle;
 	result->flags = 0;
 	result->tokens = 0;
+	result->offset = 0;
 	INIT_LIST_HEAD(&result->inactive_list);
 	
 	v=xfs_iget(XFS_TO_VFS(xfsp),node,result);
Index: xfs/linux/xfs/xfs_node.h
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/xfs/linux/xfs/xfs_node.h,v
retrieving revision 1.20
diff -u -r1.20 xfs_node.h
--- xfs_node.h	2000/10/02 23:48:48	1.20
+++ xfs_node.h	2001/03/04 02:31:45
@@ -43,6 +43,7 @@
     struct inode *vn;			/* inode we are associated with */
     struct dentry *data;		/* pointer to cache node */
     struct xfs_attr attr;		/* attribues of the node */
+    u_int32_t offset;			/* fetched length */
     u_int flags;			/* status of data (dirty), etc */
     u_int tokens;			/* what attr|data we have */
     xfs_handle handle;			/* the handle of the node */
