From: Greg Kroah-Hartman Date: Wed, 19 Mar 2014 22:36:00 +0000 (+0000) Subject: 3.4-stable patches X-Git-Tag: v3.4.84~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=94d1cdb9370c3f812e2adefb0f6daa0240e953eb;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: ocfs2-fix-quota-file-corruption.patch ocfs2-syncs-the-wrong-range.patch --- diff --git a/queue-3.4/ocfs2-fix-quota-file-corruption.patch b/queue-3.4/ocfs2-fix-quota-file-corruption.patch new file mode 100644 index 00000000000..f3afbe465dd --- /dev/null +++ b/queue-3.4/ocfs2-fix-quota-file-corruption.patch @@ -0,0 +1,88 @@ +From 15c34a760630ca2c803848fba90ca0646a9907dd Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Mon, 3 Mar 2014 15:38:32 -0800 +Subject: ocfs2: fix quota file corruption + +From: Jan Kara + +commit 15c34a760630ca2c803848fba90ca0646a9907dd upstream. + +Global quota files are accessed from different nodes. Thus we cannot +cache offset of quota structure in the quota file after we drop our node +reference count to it because after that moment quota structure may be +freed and reallocated elsewhere by a different node resulting in +corruption of quota file. + +Fix the problem by clearing dq_off when we are releasing dquot structure. +We also remove the DB_READ_B handling because it is useless - +DQ_ACTIVE_B is set iff DQ_READ_B is set. + +Signed-off-by: Jan Kara +Cc: Goldwyn Rodrigues +Cc: Joel Becker +Reviewed-by: Mark Fasheh +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/quota_global.c | 27 +++++++++++++++++---------- + fs/ocfs2/quota_local.c | 4 ---- + 2 files changed, 17 insertions(+), 14 deletions(-) + +--- a/fs/ocfs2/quota_global.c ++++ b/fs/ocfs2/quota_global.c +@@ -712,6 +712,12 @@ static int ocfs2_release_dquot(struct dq + */ + if (status < 0) + mlog_errno(status); ++ /* ++ * Clear dq_off so that we search for the structure in quota file next ++ * time we acquire it. The structure might be deleted and reallocated ++ * elsewhere by another node while our dquot structure is on freelist. ++ */ ++ dquot->dq_off = 0; + clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); + out_trans: + ocfs2_commit_trans(osb, handle); +@@ -750,16 +756,17 @@ static int ocfs2_acquire_dquot(struct dq + status = ocfs2_lock_global_qf(info, 1); + if (status < 0) + goto out; +- if (!test_bit(DQ_READ_B, &dquot->dq_flags)) { +- status = ocfs2_qinfo_lock(info, 0); +- if (status < 0) +- goto out_dq; +- status = qtree_read_dquot(&info->dqi_gi, dquot); +- ocfs2_qinfo_unlock(info, 0); +- if (status < 0) +- goto out_dq; +- } +- set_bit(DQ_READ_B, &dquot->dq_flags); ++ status = ocfs2_qinfo_lock(info, 0); ++ if (status < 0) ++ goto out_dq; ++ /* ++ * We always want to read dquot structure from disk because we don't ++ * know what happened with it while it was on freelist. ++ */ ++ status = qtree_read_dquot(&info->dqi_gi, dquot); ++ ocfs2_qinfo_unlock(info, 0); ++ if (status < 0) ++ goto out_dq; + + OCFS2_DQUOT(dquot)->dq_use_count++; + OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; +--- a/fs/ocfs2/quota_local.c ++++ b/fs/ocfs2/quota_local.c +@@ -1300,10 +1300,6 @@ int ocfs2_local_release_dquot(handle_t * + ocfs2_journal_dirty(handle, od->dq_chunk->qc_headerbh); + + out: +- /* Clear the read bit so that next time someone uses this +- * dquot he reads fresh info from disk and allocates local +- * dquot structure */ +- clear_bit(DQ_READ_B, &dquot->dq_flags); + return status; + } + diff --git a/queue-3.4/ocfs2-syncs-the-wrong-range.patch b/queue-3.4/ocfs2-syncs-the-wrong-range.patch new file mode 100644 index 00000000000..0a63a44d668 --- /dev/null +++ b/queue-3.4/ocfs2-syncs-the-wrong-range.patch @@ -0,0 +1,40 @@ +From 1b56e98990bcdbb20b9fab163654b9315bf158e8 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 10 Feb 2014 15:18:55 -0500 +Subject: ocfs2 syncs the wrong range... + +From: Al Viro + +commit 1b56e98990bcdbb20b9fab163654b9315bf158e8 upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/file.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -2389,8 +2389,8 @@ out_dio: + + if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || + ((file->f_flags & O_DIRECT) && !direct_io)) { +- ret = filemap_fdatawrite_range(file->f_mapping, pos, +- pos + count - 1); ++ ret = filemap_fdatawrite_range(file->f_mapping, *ppos, ++ *ppos + count - 1); + if (ret < 0) + written = ret; + +@@ -2403,8 +2403,8 @@ out_dio: + } + + if (!ret) +- ret = filemap_fdatawait_range(file->f_mapping, pos, +- pos + count - 1); ++ ret = filemap_fdatawait_range(file->f_mapping, *ppos, ++ *ppos + count - 1); + } + + /* diff --git a/queue-3.4/series b/queue-3.4/series new file mode 100644 index 00000000000..81e4552c978 --- /dev/null +++ b/queue-3.4/series @@ -0,0 +1,2 @@ +ocfs2-fix-quota-file-corruption.patch +ocfs2-syncs-the-wrong-range.patch