Commit c1ad1e3c authored by Ryan Ding's avatar Ryan Ding Committed by Linus Torvalds

ocfs2: add ocfs2_write_type_t type to identify the caller of write

Patchset: fix ocfs2 direct io code patch to support sparse file and data
ordering semantics

The idea is to use buffer io(more precisely use the interface
ocfs2_write_begin_nolock & ocfs2_write_end_nolock) to do the zero work
beyond block size.  And clear UNWRITTEN flag until direct io data has
been written to disk, which can prevent data corruption when system
crashed during direct write.

And we will also archive a better performance: eg.  dd direct write new
file with block size 4KB: before this patchset:
  2.5 MB/s
after this patchset:
  66.4 MB/s

This patch (of 8):

To support direct io in ocfs2_write_begin_nolock &
ocfs2_write_end_nolock.

Remove unused args filp & flags.  Add new arg type.  The type is one of
buffer/direct/mmap.  Indicate 3 way to perform write.  buffer/mmap type
has implemented.  direct type will be implemented later.
Signed-off-by: default avatarRyan Ding <ryan.ding@oracle.com>
Reviewed-by: default avatarJunxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <joseph.qi@huawei.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9e13f1f9
...@@ -1224,6 +1224,9 @@ struct ocfs2_write_ctxt { ...@@ -1224,6 +1224,9 @@ struct ocfs2_write_ctxt {
/* First cluster allocated in a nonsparse extend */ /* First cluster allocated in a nonsparse extend */
u32 w_first_new_cpos; u32 w_first_new_cpos;
/* Type of caller. Must be one of buffer, mmap, direct. */
ocfs2_write_type_t w_type;
struct ocfs2_write_cluster_desc w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE]; struct ocfs2_write_cluster_desc w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
/* /*
...@@ -1319,7 +1322,8 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) ...@@ -1319,7 +1322,8 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp, static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
struct ocfs2_super *osb, loff_t pos, struct ocfs2_super *osb, loff_t pos,
unsigned len, struct buffer_head *di_bh) unsigned len, ocfs2_write_type_t type,
struct buffer_head *di_bh)
{ {
u32 cend; u32 cend;
struct ocfs2_write_ctxt *wc; struct ocfs2_write_ctxt *wc;
...@@ -1334,6 +1338,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp, ...@@ -1334,6 +1338,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp,
wc->w_clen = cend - wc->w_cpos + 1; wc->w_clen = cend - wc->w_cpos + 1;
get_bh(di_bh); get_bh(di_bh);
wc->w_di_bh = di_bh; wc->w_di_bh = di_bh;
wc->w_type = type;
if (unlikely(PAGE_CACHE_SHIFT > osb->s_clustersize_bits)) if (unlikely(PAGE_CACHE_SHIFT > osb->s_clustersize_bits))
wc->w_large_pages = 1; wc->w_large_pages = 1;
...@@ -2077,9 +2082,8 @@ static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb, ...@@ -2077,9 +2082,8 @@ static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb,
return ret; return ret;
} }
int ocfs2_write_begin_nolock(struct file *filp, int ocfs2_write_begin_nolock(struct address_space *mapping,
struct address_space *mapping, loff_t pos, unsigned len, ocfs2_write_type_t type,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata, struct page **pagep, void **fsdata,
struct buffer_head *di_bh, struct page *mmap_page) struct buffer_head *di_bh, struct page *mmap_page)
{ {
...@@ -2096,7 +2100,7 @@ int ocfs2_write_begin_nolock(struct file *filp, ...@@ -2096,7 +2100,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
int try_free = 1, ret1; int try_free = 1, ret1;
try_again: try_again:
ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, type, di_bh);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
return ret; return ret;
...@@ -2153,7 +2157,7 @@ int ocfs2_write_begin_nolock(struct file *filp, ...@@ -2153,7 +2157,7 @@ int ocfs2_write_begin_nolock(struct file *filp,
(unsigned long long)OCFS2_I(inode)->ip_blkno, (unsigned long long)OCFS2_I(inode)->ip_blkno,
(long long)i_size_read(inode), (long long)i_size_read(inode),
le32_to_cpu(di->i_clusters), le32_to_cpu(di->i_clusters),
pos, len, flags, mmap_page, pos, len, type, mmap_page,
clusters_to_alloc, extents_to_split); clusters_to_alloc, extents_to_split);
/* /*
...@@ -2323,8 +2327,8 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping, ...@@ -2323,8 +2327,8 @@ static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
*/ */
down_write(&OCFS2_I(inode)->ip_alloc_sem); down_write(&OCFS2_I(inode)->ip_alloc_sem);
ret = ocfs2_write_begin_nolock(file, mapping, pos, len, flags, pagep, ret = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_BUFFER,
fsdata, di_bh, NULL); pagep, fsdata, di_bh, NULL);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out_fail; goto out_fail;
......
...@@ -47,9 +47,14 @@ int ocfs2_write_end_nolock(struct address_space *mapping, ...@@ -47,9 +47,14 @@ int ocfs2_write_end_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied, loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata); struct page *page, void *fsdata);
int ocfs2_write_begin_nolock(struct file *filp, typedef enum {
struct address_space *mapping, OCFS2_WRITE_BUFFER = 0,
loff_t pos, unsigned len, unsigned flags, OCFS2_WRITE_DIRECT,
OCFS2_WRITE_MMAP,
} ocfs2_write_type_t;
int ocfs2_write_begin_nolock(struct address_space *mapping,
loff_t pos, unsigned len, ocfs2_write_type_t type,
struct page **pagep, void **fsdata, struct page **pagep, void **fsdata,
struct buffer_head *di_bh, struct page *mmap_page); struct buffer_head *di_bh, struct page *mmap_page);
......
...@@ -104,8 +104,8 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, ...@@ -104,8 +104,8 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh,
if (page->index == last_index) if (page->index == last_index)
len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; len = ((size - 1) & ~PAGE_CACHE_MASK) + 1;
ret = ocfs2_write_begin_nolock(file, mapping, pos, len, 0, &locked_page, ret = ocfs2_write_begin_nolock(mapping, pos, len, OCFS2_WRITE_MMAP,
&fsdata, di_bh, page); &locked_page, &fsdata, di_bh, page);
if (ret) { if (ret) {
if (ret != -ENOSPC) if (ret != -ENOSPC)
mlog_errno(ret); mlog_errno(ret);
......
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