]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Mar 2014 22:36:00 +0000 (22:36 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Mar 2014 22:36:00 +0000 (22:36 +0000)
added patches:
ocfs2-fix-quota-file-corruption.patch
ocfs2-syncs-the-wrong-range.patch

queue-3.4/ocfs2-fix-quota-file-corruption.patch [new file with mode: 0644]
queue-3.4/ocfs2-syncs-the-wrong-range.patch [new file with mode: 0644]
queue-3.4/series [new file with mode: 0644]

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 (file)
index 0000000..f3afbe4
--- /dev/null
@@ -0,0 +1,88 @@
+From 15c34a760630ca2c803848fba90ca0646a9907dd Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Mon, 3 Mar 2014 15:38:32 -0800
+Subject: ocfs2: fix quota file corruption
+
+From: Jan Kara <jack@suse.cz>
+
+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 <jack@suse.cz>
+Cc: Goldwyn Rodrigues <rgoldwyn@suse.de>
+Cc: Joel Becker <jlbec@evilplan.org>
+Reviewed-by: Mark Fasheh <mfasheh@suse.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..0a63a44
--- /dev/null
@@ -0,0 +1,40 @@
+From 1b56e98990bcdbb20b9fab163654b9315bf158e8 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Mon, 10 Feb 2014 15:18:55 -0500
+Subject: ocfs2 syncs the wrong range...
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 1b56e98990bcdbb20b9fab163654b9315bf158e8 upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..81e4552
--- /dev/null
@@ -0,0 +1,2 @@
+ocfs2-fix-quota-file-corruption.patch
+ocfs2-syncs-the-wrong-range.patch