From: Urban Widmark <urban@teststation.com>

Add the necessary bits for loop-over-smbfs.


---

 25-akpm/fs/smbfs/file.c    |   22 ++++++++++++++++++++++
 25-akpm/fs/smbfs/proc.c    |    6 ------
 25-akpm/fs/smbfs/request.c |    6 ++++++
 25-akpm/fs/smbfs/smbiod.c  |    3 +++
 4 files changed, 31 insertions(+), 6 deletions(-)

diff -puN fs/smbfs/file.c~smbfs-loop-support fs/smbfs/file.c
--- 25/fs/smbfs/file.c~smbfs-loop-support	Tue Feb 17 16:11:08 2004
+++ 25-akpm/fs/smbfs/file.c	Tue Feb 17 16:11:08 2004
@@ -257,6 +257,27 @@ out:
 	return status;
 }
 
+static ssize_t
+smb_file_sendfile(struct file *file, loff_t *ppos,
+		  size_t count, read_actor_t actor, void __user *target)
+{
+	struct dentry *dentry = file->f_dentry;
+	ssize_t status;
+
+	VERBOSE("file %s/%s, pos=%Ld, count=%d\n",
+		DENTRY_PATH(dentry), *ppos, count);
+
+	status = smb_revalidate_inode(dentry);
+	if (status) {
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), status);
+		goto out;
+	}
+	status = generic_file_sendfile(file, ppos, count, actor, target);
+out:
+	return status;
+}
+
 /*
  * This does the "real" work of the write. The generic routine has
  * allocated the page, locked it, done all the page alignment stuff
@@ -388,6 +409,7 @@ struct file_operations smb_file_operatio
 	.open		= smb_file_open,
 	.release	= smb_file_release,
 	.fsync		= smb_fsync,
+	.sendfile	= smb_file_sendfile,
 };
 
 struct inode_operations smb_file_inode_operations =
diff -puN fs/smbfs/proc.c~smbfs-loop-support fs/smbfs/proc.c
--- 25/fs/smbfs/proc.c~smbfs-loop-support	Tue Feb 17 16:11:08 2004
+++ 25-akpm/fs/smbfs/proc.c	Tue Feb 17 16:11:08 2004
@@ -1015,12 +1015,6 @@ smb_setup_header(struct smb_request *req
 	p += 19;
 	p += 8;
 
-	/* FIXME: the request will fail if the 'tid' is changed. This
-	   should perhaps be set just before transmitting ... */
-	WSET(req->rq_header, smb_tid, server->opt.tid);
-	WSET(req->rq_header, smb_pid, 1);
-	WSET(req->rq_header, smb_uid, server->opt.server_uid);
-
 	if (server->opt.protocol > SMB_PROTOCOL_CORE) {
 		int flags = SMB_FLAGS_CASELESS_PATHNAMES;
 		int flags2 = SMB_FLAGS2_LONG_PATH_COMPONENTS |
diff -puN fs/smbfs/request.c~smbfs-loop-support fs/smbfs/request.c
--- 25/fs/smbfs/request.c~smbfs-loop-support	Tue Feb 17 16:11:08 2004
+++ 25-akpm/fs/smbfs/request.c	Tue Feb 17 16:11:08 2004
@@ -384,6 +384,12 @@ int smb_request_send_req(struct smb_requ
 	struct smb_sb_info *server = req->rq_server;
 	int result;
 
+	if (req->rq_bytes_sent == 0) {
+		WSET(req->rq_header, smb_tid, server->opt.tid);
+		WSET(req->rq_header, smb_pid, 1);
+		WSET(req->rq_header, smb_uid, server->opt.server_uid);
+	}
+
 	result = smb_send_request(req);
 	if (result < 0 && result != -EAGAIN)
 		goto out;
diff -puN fs/smbfs/smbiod.c~smbfs-loop-support fs/smbfs/smbiod.c
--- 25/fs/smbfs/smbiod.c~smbfs-loop-support	Tue Feb 17 16:11:08 2004
+++ 25-akpm/fs/smbfs/smbiod.c	Tue Feb 17 16:11:08 2004
@@ -161,6 +161,9 @@ int smbiod_retry(struct smb_sb_info *ser
 	while (head != &server->xmitq) {
 		req = list_entry(head, struct smb_request, rq_queue);
 		head = head->next;
+
+		WSET(req->rq_header, smb_uid, -1);
+		req->rq_bytes_sent = 0;
 		if (req->rq_flags & SMB_REQ_NORETRY) {
 			VERBOSE("aborting request %p on xmitq\n", req);
 			req->rq_errno = -EIO;

_