Commit e89b7533 authored by Trond Myklebust's avatar Trond Myklebust

NFS_O_DIRECT: there's a code path in nfs_direct_write_seg

    where NFS_I(inode)->data_updates can get out of sync
    with reality, which will lead to a BUG() in nfs_clear_inode
    later on.

    Patch by Olaf Kirch.
parent 283eb003
...@@ -252,9 +252,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -252,9 +252,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
{ {
const unsigned int wsize = NFS_SERVER(inode)->wsize; const unsigned int wsize = NFS_SERVER(inode)->wsize;
size_t request; size_t request;
int need_commit; int curpage, need_commit, result, tot_bytes;
int tot_bytes;
int curpage;
struct nfs_writeverf first_verf; struct nfs_writeverf first_verf;
struct nfs_write_data wdata = { struct nfs_write_data wdata = {
.inode = inode, .inode = inode,
...@@ -281,8 +279,6 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -281,8 +279,6 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
wdata.args.pgbase = user_addr & ~PAGE_MASK; wdata.args.pgbase = user_addr & ~PAGE_MASK;
wdata.args.offset = file_offset; wdata.args.offset = file_offset;
do { do {
int result;
wdata.args.count = request; wdata.args.count = request;
if (wdata.args.count > wsize) if (wdata.args.count > wsize)
wdata.args.count = wsize; wdata.args.count = wsize;
...@@ -299,7 +295,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -299,7 +295,7 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
if (result <= 0) { if (result <= 0) {
if (tot_bytes > 0) if (tot_bytes > 0)
break; break;
return result; goto out;
} }
if (tot_bytes == 0) if (tot_bytes == 0)
...@@ -324,8 +320,6 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -324,8 +320,6 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
* Commit data written so far, even in the event of an error * Commit data written so far, even in the event of an error
*/ */
if (need_commit) { if (need_commit) {
int result;
wdata.args.count = tot_bytes; wdata.args.count = tot_bytes;
wdata.args.offset = file_offset; wdata.args.offset = file_offset;
...@@ -338,9 +332,12 @@ nfs_direct_write_seg(struct inode *inode, struct file *file, ...@@ -338,9 +332,12 @@ nfs_direct_write_seg(struct inode *inode, struct file *file,
VERF_SIZE) != 0) VERF_SIZE) != 0)
goto sync_retry; goto sync_retry;
} }
result = tot_bytes;
out:
nfs_end_data_update_defer(inode); nfs_end_data_update_defer(inode);
return tot_bytes; return result;
sync_retry: sync_retry:
wdata.args.stable = NFS_FILE_SYNC; wdata.args.stable = NFS_FILE_SYNC;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment