]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.12/ocfs2-set-i_mode-on-disk-during-acl-operations.patch
Remove duplicated commits
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.12 / ocfs2-set-i_mode-on-disk-during-acl-operations.patch
CommitLineData
85291088
GKH
1From fcefd25ac89239cb57fa198f125a79ff85468c75 Mon Sep 17 00:00:00 2001
2From: Mark Fasheh <mfasheh@suse.com>
3Date: Mon, 15 Mar 2010 15:39:00 -0700
4Subject: ocfs2: set i_mode on disk during acl operations
5
6From: Mark Fasheh <mfasheh@suse.com>
7
8commit fcefd25ac89239cb57fa198f125a79ff85468c75 upstream.
9
10ocfs2_set_acl() and ocfs2_init_acl() were setting i_mode on the in-memory
11inode, but never setting it on the disk copy. Thus, acls were some times not
12getting propagated between nodes. This patch fixes the issue by adding a
13helper function ocfs2_acl_set_mode() which does this the right way.
14ocfs2_set_acl() and ocfs2_init_acl() are then updated to call
15ocfs2_acl_set_mode().
16
17Signed-off-by: Mark Fasheh <mfasheh@suse.com>
18Signed-off-by: Joel Becker <joel.becker@oracle.com>
19Cc: maximilian attems <max@stro.at>
20Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
21
22---
23 fs/ocfs2/acl.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++----
24 1 file changed, 72 insertions(+), 5 deletions(-)
25
26--- a/fs/ocfs2/acl.c
27+++ b/fs/ocfs2/acl.c
28@@ -30,6 +30,8 @@
29 #include "alloc.h"
30 #include "dlmglue.h"
31 #include "file.h"
32+#include "inode.h"
33+#include "journal.h"
34 #include "ocfs2_fs.h"
35
36 #include "xattr.h"
37@@ -170,6 +172,60 @@ static struct posix_acl *ocfs2_get_acl(s
38 }
39
40 /*
41+ * Helper function to set i_mode in memory and disk. Some call paths
42+ * will not have di_bh or a journal handle to pass, in which case it
43+ * will create it's own.
44+ */
45+static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh,
46+ handle_t *handle, umode_t new_mode)
47+{
48+ int ret, commit_handle = 0;
49+ struct ocfs2_dinode *di;
50+
51+ if (di_bh == NULL) {
52+ ret = ocfs2_read_inode_block(inode, &di_bh);
53+ if (ret) {
54+ mlog_errno(ret);
55+ goto out;
56+ }
57+ } else
58+ get_bh(di_bh);
59+
60+ if (handle == NULL) {
61+ handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb),
62+ OCFS2_INODE_UPDATE_CREDITS);
63+ if (IS_ERR(handle)) {
64+ ret = PTR_ERR(handle);
65+ mlog_errno(ret);
66+ goto out_brelse;
67+ }
68+
69+ commit_handle = 1;
70+ }
71+
72+ di = (struct ocfs2_dinode *)di_bh->b_data;
73+ ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
74+ OCFS2_JOURNAL_ACCESS_WRITE);
75+ if (ret) {
76+ mlog_errno(ret);
77+ goto out_commit;
78+ }
79+
80+ inode->i_mode = new_mode;
81+ di->i_mode = cpu_to_le16(inode->i_mode);
82+
83+ ocfs2_journal_dirty(handle, di_bh);
84+
85+out_commit:
86+ if (commit_handle)
87+ ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
88+out_brelse:
89+ brelse(di_bh);
90+out:
91+ return ret;
92+}
93+
94+/*
95 * Set the access or default ACL of an inode.
96 */
97 static int ocfs2_set_acl(handle_t *handle,
98@@ -197,9 +253,14 @@ static int ocfs2_set_acl(handle_t *handl
99 if (ret < 0)
100 return ret;
101 else {
102- inode->i_mode = mode;
103 if (ret == 0)
104 acl = NULL;
105+
106+ ret = ocfs2_acl_set_mode(inode, di_bh,
107+ handle, mode);
108+ if (ret)
109+ return ret;
110+
111 }
112 }
113 break;
114@@ -287,6 +348,7 @@ int ocfs2_init_acl(handle_t *handle,
115 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
116 struct posix_acl *acl = NULL;
117 int ret = 0;
118+ mode_t mode;
119
120 if (!S_ISLNK(inode->i_mode)) {
121 if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) {
122@@ -295,12 +357,17 @@ int ocfs2_init_acl(handle_t *handle,
123 if (IS_ERR(acl))
124 return PTR_ERR(acl);
125 }
126- if (!acl)
127- inode->i_mode &= ~current_umask();
128+ if (!acl) {
129+ mode = inode->i_mode & ~current_umask();
130+ ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
131+ if (ret) {
132+ mlog_errno(ret);
133+ goto cleanup;
134+ }
135+ }
136 }
137 if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) {
138 struct posix_acl *clone;
139- mode_t mode;
140
141 if (S_ISDIR(inode->i_mode)) {
142 ret = ocfs2_set_acl(handle, inode, di_bh,
143@@ -317,7 +384,7 @@ int ocfs2_init_acl(handle_t *handle,
144 mode = inode->i_mode;
145 ret = posix_acl_create_masq(clone, &mode);
146 if (ret >= 0) {
147- inode->i_mode = mode;
148+ ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode);
149 if (ret > 0) {
150 ret = ocfs2_set_acl(handle, inode,
151 di_bh, ACL_TYPE_ACCESS,