patch-2.3.99-pre9 linux/fs/nfs/write.c

Next file: linux/fs/nfsd/nfscache.c
Previous file: linux/fs/nfs/read.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre8/linux/fs/nfs/write.c linux/fs/nfs/write.c
@@ -89,8 +89,7 @@
 /*
  * Local function declarations
  */
-static struct nfs_page * nfs_update_request(struct file*, struct dentry *,
-					    struct page *page,
+static struct nfs_page * nfs_update_request(struct file*, struct page *page,
 					    unsigned int, unsigned int);
 static void	nfs_strategy(struct inode *inode);
 static void	nfs_writeback_done(struct rpc_task *);
@@ -168,9 +167,10 @@
  * Offset is the data offset within the page.
  */
 static int
-nfs_writepage_sync(struct dentry *dentry, struct page *page,
+nfs_writepage_sync(struct file *file, struct page *page,
 		   unsigned int offset, unsigned int count)
 {
+	struct dentry	*dentry = file->f_dentry;
 	struct inode	*inode = dentry->d_inode;
 	loff_t		base;
 	unsigned int	wsize = NFS_SERVER(inode)->wsize;
@@ -193,7 +193,7 @@
 		if (count < wsize && !IS_SWAPFILE(inode))
 			wsize = count;
 
-		result = NFS_PROTO(inode)->write(dentry, &fattr, flags,
+		result = NFS_PROTO(inode)->write(file, &fattr, flags,
 						 base, wsize, buffer, &verf);
 		nfs_write_attributes(inode, &fattr);
 
@@ -229,18 +229,18 @@
 }
 
 static int
-nfs_writepage_async(struct file *file, struct dentry *dentry, struct page *page,
+nfs_writepage_async(struct file *file, struct page *page,
 		    unsigned int offset, unsigned int count)
 {
 	struct nfs_page	*req;
 	int		status;
 
-	req = nfs_update_request(file, dentry, page, offset, count);
+	req = nfs_update_request(file, page, offset, count);
 	status = (IS_ERR(req)) ? PTR_ERR(req) : 0;
 	if (status < 0)
 		goto out;
 	nfs_release_request(req);
-	nfs_strategy(dentry->d_inode);
+	nfs_strategy(file->f_dentry->d_inode);
  out:
 	return status;
 }
@@ -251,8 +251,7 @@
 int
 nfs_writepage(struct file *file, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
-	struct inode *inode = dentry->d_inode;
+	struct inode *inode = file->f_dentry->d_inode;
 	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
 	unsigned offset = PAGE_CACHE_SIZE;
 	int err;
@@ -267,11 +266,11 @@
 		return -EIO;
 do_it:
 	if (!PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) {
-		err = nfs_writepage_async(file, dentry, page, 0, offset);
+		err = nfs_writepage_async(file, page, 0, offset);
 		if (err >= 0)
 			goto out_ok;
 	}
-	err = nfs_writepage_sync(dentry, page, 0, offset); 
+	err = nfs_writepage_sync(file, page, 0, offset); 
 	if ( err == offset)
 		goto out_ok;
 	return err; 
@@ -476,10 +475,12 @@
  * Page must be locked by the caller. This makes sure we never create
  * two different requests for the same page, and avoids possible deadlock
  * when we reach the hard limit on the number of dirty pages.
+ * It should be safe to sleep here.
  */
-struct nfs_page *nfs_create_request(struct dentry *dentry, struct page *page,
+struct nfs_page *nfs_create_request(struct file *file, struct page *page,
 				    unsigned int offset, unsigned int count)
 {
+	struct dentry		*dentry = file->f_dentry;
 	struct inode		*inode = dentry->d_inode;
 	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
 	struct nfs_page		*req = NULL;
@@ -531,8 +532,10 @@
 	page_cache_get(page);
 	req->wb_offset  = offset;
 	req->wb_bytes   = count;
-	req->wb_dentry  = dget(dentry);
-	req->wb_cred	= rpcauth_lookupcred(NFS_CLIENT(inode)->cl_auth, 0);
+	req->wb_file    = file;
+	get_file(file);
+	req->wb_dentry  = dentry;
+	req->wb_cred	= nfs_file_cred(file);
 	req->wb_count   = 1;
 
 	/* register request's existence */
@@ -573,12 +576,7 @@
 	if (NFS_WBACK_BUSY(req))
 		printk(KERN_ERR "NFS: Request released while still locked!\n");
 
-	rpcauth_releasecred(NFS_CLIENT(inode)->cl_auth, req->wb_cred);
-	lock_kernel();
-	if (req->wb_file)
-		fput(req->wb_file);
-	dput(req->wb_dentry);
-	unlock_kernel();
+	fput(req->wb_file);
 	page_cache_release(page);
 	nfs_page_free(req);
 	/* wake up anyone waiting to allocate a request */
@@ -789,10 +787,6 @@
 		if (prev) {
 			if (req->wb_file != prev->wb_file)
 				break;
-			if (req->wb_dentry != prev->wb_dentry)
-				break;
-			if (req->wb_cred != prev->wb_cred)
-				break;
 			if (page_index(req->wb_page) != page_index(prev->wb_page)+1)
 				break;
 
@@ -818,10 +812,10 @@
  * Note: Should always be called with the Page Lock held!
  */
 static struct nfs_page *
-nfs_update_request(struct file* file, struct dentry *dentry, struct page *page,
+nfs_update_request(struct file* file, struct page *page,
 		   unsigned int offset, unsigned int bytes)
 {
-	struct inode		*inode = dentry->d_inode;
+	struct inode		*inode = file->f_dentry->d_inode;
 	struct nfs_page		*req, *new = NULL;
 	unsigned long		rqend, end;
 
@@ -856,21 +850,14 @@
 		}
 		spin_unlock(&nfs_wreq_lock);
 
-
-		/* Create the request. It's safe to sleep in this call because
-		 * we only get here if the page is locked.
-		 *
+		/*
 		 * If we're over the soft limit, flush out old requests
 		 */
-		if (file && nfs_nr_requests >= MAX_REQUEST_SOFT)
+		if (inode->u.nfs_i.npages >= MAX_REQUEST_SOFT)
 			nfs_wb_file(inode, file);
-		new = nfs_create_request(dentry, page, offset, bytes);
+		new = nfs_create_request(file, page, offset, bytes);
 		if (!new)
 			return ERR_PTR(-ENOMEM);
-		if (file) {
-			new->wb_file = file;
-			get_file(file);
-		}
 		/* If the region is locked, adjust the timeout */
 		if (region_locked(inode, new))
 			new->wb_timeout = jiffies + NFS_WRITEBACK_LOCKDELAY;
@@ -1006,7 +993,7 @@
 	 * page synchronously.
 	 */
 	if (NFS_SERVER(inode)->wsize < PAGE_SIZE)
-		return nfs_writepage_sync(dentry, page, offset, count);
+		return nfs_writepage_sync(file, page, offset, count);
 
 	/*
 	 * Try to find an NFS request corresponding to this page
@@ -1015,7 +1002,7 @@
 	 * it out now.
 	 */
 	do {
-		req = nfs_update_request(file, dentry, page, offset, count);
+		req = nfs_update_request(file, page, offset, count);
 		status = (IS_ERR(req)) ? PTR_ERR(req) : 0;
 		if (status != -EBUSY)
 			break;

FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])