diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 | 
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 | 
| commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
| tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /fs/ocfs2/acl.c | |
| parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
| parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) | |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
	Documentation/feature-removal-schedule.txt
	net/ipv6/netfilter/ip6t_REJECT.c
	net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'fs/ocfs2/acl.c')
| -rw-r--r-- | fs/ocfs2/acl.c | 78 | 
1 files changed, 73 insertions, 5 deletions
| diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 0501974bedd0..e13fc9e8fcdc 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> | 
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> | 
| 24 | #include <linux/slab.h> | ||
| 24 | #include <linux/string.h> | 25 | #include <linux/string.h> | 
| 25 | 26 | ||
| 26 | #define MLOG_MASK_PREFIX ML_INODE | 27 | #define MLOG_MASK_PREFIX ML_INODE | 
| @@ -30,6 +31,8 @@ | |||
| 30 | #include "alloc.h" | 31 | #include "alloc.h" | 
| 31 | #include "dlmglue.h" | 32 | #include "dlmglue.h" | 
| 32 | #include "file.h" | 33 | #include "file.h" | 
| 34 | #include "inode.h" | ||
| 35 | #include "journal.h" | ||
| 33 | #include "ocfs2_fs.h" | 36 | #include "ocfs2_fs.h" | 
| 34 | 37 | ||
| 35 | #include "xattr.h" | 38 | #include "xattr.h" | 
| @@ -166,6 +169,60 @@ static struct posix_acl *ocfs2_get_acl(struct inode *inode, int type) | |||
| 166 | } | 169 | } | 
| 167 | 170 | ||
| 168 | /* | 171 | /* | 
| 172 | * Helper function to set i_mode in memory and disk. Some call paths | ||
| 173 | * will not have di_bh or a journal handle to pass, in which case it | ||
| 174 | * will create it's own. | ||
| 175 | */ | ||
| 176 | static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, | ||
| 177 | handle_t *handle, umode_t new_mode) | ||
| 178 | { | ||
| 179 | int ret, commit_handle = 0; | ||
| 180 | struct ocfs2_dinode *di; | ||
| 181 | |||
| 182 | if (di_bh == NULL) { | ||
| 183 | ret = ocfs2_read_inode_block(inode, &di_bh); | ||
| 184 | if (ret) { | ||
| 185 | mlog_errno(ret); | ||
| 186 | goto out; | ||
| 187 | } | ||
| 188 | } else | ||
| 189 | get_bh(di_bh); | ||
| 190 | |||
| 191 | if (handle == NULL) { | ||
| 192 | handle = ocfs2_start_trans(OCFS2_SB(inode->i_sb), | ||
| 193 | OCFS2_INODE_UPDATE_CREDITS); | ||
| 194 | if (IS_ERR(handle)) { | ||
| 195 | ret = PTR_ERR(handle); | ||
| 196 | mlog_errno(ret); | ||
| 197 | goto out_brelse; | ||
| 198 | } | ||
| 199 | |||
| 200 | commit_handle = 1; | ||
| 201 | } | ||
| 202 | |||
| 203 | di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 204 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, | ||
| 205 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 206 | if (ret) { | ||
| 207 | mlog_errno(ret); | ||
| 208 | goto out_commit; | ||
| 209 | } | ||
| 210 | |||
| 211 | inode->i_mode = new_mode; | ||
| 212 | di->i_mode = cpu_to_le16(inode->i_mode); | ||
| 213 | |||
| 214 | ocfs2_journal_dirty(handle, di_bh); | ||
| 215 | |||
| 216 | out_commit: | ||
| 217 | if (commit_handle) | ||
| 218 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | ||
| 219 | out_brelse: | ||
| 220 | brelse(di_bh); | ||
| 221 | out: | ||
| 222 | return ret; | ||
| 223 | } | ||
| 224 | |||
| 225 | /* | ||
| 169 | * Set the access or default ACL of an inode. | 226 | * Set the access or default ACL of an inode. | 
| 170 | */ | 227 | */ | 
| 171 | static int ocfs2_set_acl(handle_t *handle, | 228 | static int ocfs2_set_acl(handle_t *handle, | 
| @@ -193,9 +250,14 @@ static int ocfs2_set_acl(handle_t *handle, | |||
| 193 | if (ret < 0) | 250 | if (ret < 0) | 
| 194 | return ret; | 251 | return ret; | 
| 195 | else { | 252 | else { | 
| 196 | inode->i_mode = mode; | ||
| 197 | if (ret == 0) | 253 | if (ret == 0) | 
| 198 | acl = NULL; | 254 | acl = NULL; | 
| 255 | |||
| 256 | ret = ocfs2_acl_set_mode(inode, di_bh, | ||
| 257 | handle, mode); | ||
| 258 | if (ret) | ||
| 259 | return ret; | ||
| 260 | |||
| 199 | } | 261 | } | 
| 200 | } | 262 | } | 
| 201 | break; | 263 | break; | 
| @@ -283,6 +345,7 @@ int ocfs2_init_acl(handle_t *handle, | |||
| 283 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 345 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 
| 284 | struct posix_acl *acl = NULL; | 346 | struct posix_acl *acl = NULL; | 
| 285 | int ret = 0; | 347 | int ret = 0; | 
| 348 | mode_t mode; | ||
| 286 | 349 | ||
| 287 | if (!S_ISLNK(inode->i_mode)) { | 350 | if (!S_ISLNK(inode->i_mode)) { | 
| 288 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { | 351 | if (osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) { | 
| @@ -291,12 +354,17 @@ int ocfs2_init_acl(handle_t *handle, | |||
| 291 | if (IS_ERR(acl)) | 354 | if (IS_ERR(acl)) | 
| 292 | return PTR_ERR(acl); | 355 | return PTR_ERR(acl); | 
| 293 | } | 356 | } | 
| 294 | if (!acl) | 357 | if (!acl) { | 
| 295 | inode->i_mode &= ~current_umask(); | 358 | mode = inode->i_mode & ~current_umask(); | 
| 359 | ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode); | ||
| 360 | if (ret) { | ||
| 361 | mlog_errno(ret); | ||
| 362 | goto cleanup; | ||
| 363 | } | ||
| 364 | } | ||
| 296 | } | 365 | } | 
| 297 | if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { | 366 | if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { | 
| 298 | struct posix_acl *clone; | 367 | struct posix_acl *clone; | 
| 299 | mode_t mode; | ||
| 300 | 368 | ||
| 301 | if (S_ISDIR(inode->i_mode)) { | 369 | if (S_ISDIR(inode->i_mode)) { | 
| 302 | ret = ocfs2_set_acl(handle, inode, di_bh, | 370 | ret = ocfs2_set_acl(handle, inode, di_bh, | 
| @@ -313,7 +381,7 @@ int ocfs2_init_acl(handle_t *handle, | |||
| 313 | mode = inode->i_mode; | 381 | mode = inode->i_mode; | 
| 314 | ret = posix_acl_create_masq(clone, &mode); | 382 | ret = posix_acl_create_masq(clone, &mode); | 
| 315 | if (ret >= 0) { | 383 | if (ret >= 0) { | 
| 316 | inode->i_mode = mode; | 384 | ret = ocfs2_acl_set_mode(inode, di_bh, handle, mode); | 
| 317 | if (ret > 0) { | 385 | if (ret > 0) { | 
| 318 | ret = ocfs2_set_acl(handle, inode, | 386 | ret = ocfs2_set_acl(handle, inode, | 
| 319 | di_bh, ACL_TYPE_ACCESS, | 387 | di_bh, ACL_TYPE_ACCESS, | 
