Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 39949
b: refs/heads/master
c: fb5527e
h: refs/heads/master
i:
  39947: 66b1895
v: v3
  • Loading branch information
Jeff Moyer authored and Linus Torvalds committed Oct 20, 2006
1 parent 7451c97 commit 56b39c4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e8e82b76e0312827f5ae04b573a05b02854a447e
refs/heads/master: fb5527e68d495650a7658fec9a7246bf922db212
51 changes: 45 additions & 6 deletions trunk/mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2222,7 +2222,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos)
{
struct file *file = iocb->ki_filp;
const struct address_space * mapping = file->f_mapping;
struct address_space * mapping = file->f_mapping;
size_t ocount; /* original count */
size_t count; /* after file limit checks */
struct inode *inode = mapping->host;
Expand Down Expand Up @@ -2275,8 +2275,11 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,

/* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
if (unlikely(file->f_flags & O_DIRECT)) {
written = generic_file_direct_write(iocb, iov,
&nr_segs, pos, ppos, count, ocount);
loff_t endbyte;
ssize_t written_buffered;

written = generic_file_direct_write(iocb, iov, &nr_segs, pos,
ppos, count, ocount);
if (written < 0 || written == count)
goto out;
/*
Expand All @@ -2285,10 +2288,46 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
*/
pos += written;
count -= written;
}
written_buffered = generic_file_buffered_write(iocb, iov,
nr_segs, pos, ppos, count,
written);
/*
* If generic_file_buffered_write() retuned a synchronous error
* then we want to return the number of bytes which were
* direct-written, or the error code if that was zero. Note
* that this differs from normal direct-io semantics, which
* will return -EFOO even if some bytes were written.
*/
if (written_buffered < 0) {
err = written_buffered;
goto out;
}

written = generic_file_buffered_write(iocb, iov, nr_segs,
pos, ppos, count, written);
/*
* We need to ensure that the page cache pages are written to
* disk and invalidated to preserve the expected O_DIRECT
* semantics.
*/
endbyte = pos + written_buffered - written - 1;
err = do_sync_file_range(file, pos, endbyte,
SYNC_FILE_RANGE_WAIT_BEFORE|
SYNC_FILE_RANGE_WRITE|
SYNC_FILE_RANGE_WAIT_AFTER);
if (err == 0) {
written = written_buffered;
invalidate_mapping_pages(mapping,
pos >> PAGE_CACHE_SHIFT,
endbyte >> PAGE_CACHE_SHIFT);
} else {
/*
* We don't know how much we wrote, so just return
* the number of bytes which were direct-written
*/
}
} else {
written = generic_file_buffered_write(iocb, iov, nr_segs,
pos, ppos, count, written);
}
out:
current->backing_dev_info = NULL;
return written ? written : err;
Expand Down

0 comments on commit 56b39c4

Please sign in to comment.