mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-23 14:13:58 +08:00
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: ocfs2: Handle O_DIRECT when writing to a refcounted cluster.
This commit is contained in:
commit
6307daad84
@ -1772,7 +1772,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
|
|||||||
loff_t *ppos,
|
loff_t *ppos,
|
||||||
size_t count,
|
size_t count,
|
||||||
int appending,
|
int appending,
|
||||||
int *direct_io)
|
int *direct_io,
|
||||||
|
int *has_refcount)
|
||||||
{
|
{
|
||||||
int ret = 0, meta_level = 0;
|
int ret = 0, meta_level = 0;
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
@ -1833,6 +1834,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
|
|||||||
saved_pos,
|
saved_pos,
|
||||||
count,
|
count,
|
||||||
&meta_level);
|
&meta_level);
|
||||||
|
if (has_refcount)
|
||||||
|
*has_refcount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1856,6 +1859,10 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_refcount && *has_refcount == 1) {
|
||||||
|
*direct_io = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Allowing concurrent direct writes means
|
* Allowing concurrent direct writes means
|
||||||
* i_size changes wouldn't be synchronized, so
|
* i_size changes wouldn't be synchronized, so
|
||||||
@ -1899,7 +1906,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
|
|||||||
loff_t pos)
|
loff_t pos)
|
||||||
{
|
{
|
||||||
int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
|
int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
|
||||||
int can_do_direct;
|
int can_do_direct, has_refcount = 0;
|
||||||
ssize_t written = 0;
|
ssize_t written = 0;
|
||||||
size_t ocount; /* original count */
|
size_t ocount; /* original count */
|
||||||
size_t count; /* after file limit checks */
|
size_t count; /* after file limit checks */
|
||||||
@ -1942,7 +1949,7 @@ relock:
|
|||||||
can_do_direct = direct_io;
|
can_do_direct = direct_io;
|
||||||
ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos,
|
ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos,
|
||||||
iocb->ki_left, appending,
|
iocb->ki_left, appending,
|
||||||
&can_do_direct);
|
&can_do_direct, &has_refcount);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
goto out;
|
goto out;
|
||||||
@ -2006,14 +2013,16 @@ out_dio:
|
|||||||
/* buffered aio wouldn't have proper lock coverage today */
|
/* buffered aio wouldn't have proper lock coverage today */
|
||||||
BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
|
BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));
|
||||||
|
|
||||||
if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode)) {
|
if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode) ||
|
||||||
|
(file->f_flags & O_DIRECT && has_refcount)) {
|
||||||
ret = filemap_fdatawrite_range(file->f_mapping, pos,
|
ret = filemap_fdatawrite_range(file->f_mapping, pos,
|
||||||
pos + count - 1);
|
pos + count - 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
written = ret;
|
written = ret;
|
||||||
|
|
||||||
if (!ret && (old_size != i_size_read(inode) ||
|
if (!ret && (old_size != i_size_read(inode) ||
|
||||||
old_clusters != OCFS2_I(inode)->ip_clusters)) {
|
old_clusters != OCFS2_I(inode)->ip_clusters ||
|
||||||
|
has_refcount)) {
|
||||||
ret = jbd2_journal_force_commit(osb->journal->j_journal);
|
ret = jbd2_journal_force_commit(osb->journal->j_journal);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
written = ret;
|
written = ret;
|
||||||
@ -2062,7 +2071,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos,
|
ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos,
|
||||||
sd->total_len, 0, NULL);
|
sd->total_len, 0, NULL, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user