Whamcloud - gitweb
LU-16837 llite: handle unknown layout component
[fs/lustre-release.git] / lustre / llite / acl.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/llite/acl.c
33  *
34  * Author: Peter Braam <braam@clusterfs.com>
35  * Author: Phil Schwan <phil@clusterfs.com>
36  * Author: Andreas Dilger <adilger@clusterfs.com>
37  */
38
39 #include "llite_internal.h"
40
41 struct posix_acl *ll_get_acl(
42  #ifdef HAVE_ACL_WITH_DENTRY
43         struct mnt_idmap *map, struct dentry *dentry, int type)
44  #elif defined HAVE_GET_ACL_RCU_ARG
45         struct inode *inode, int type, bool rcu)
46  #else
47         struct inode *inode, int type)
48  #endif /* HAVE_GET_ACL_RCU_ARG */
49 {
50 #ifdef HAVE_ACL_WITH_DENTRY
51         struct inode *inode = dentry->d_inode;
52 #endif
53         struct ll_inode_info *lli = ll_i2info(inode);
54         struct posix_acl *acl = NULL;
55         ENTRY;
56
57 #ifdef HAVE_GET_ACL_RCU_ARG
58         if (rcu)
59                 return ERR_PTR(-ECHILD);
60 #endif
61
62         read_lock(&lli->lli_lock);
63         /* VFS' acl_permission_check->check_acl will release the refcount */
64         acl = posix_acl_dup(lli->lli_posix_acl);
65         read_unlock(&lli->lli_lock);
66
67         RETURN(acl);
68 }
69
70 #ifdef HAVE_IOP_SET_ACL
71 int ll_set_acl(struct mnt_idmap *map,
72 #ifdef HAVE_ACL_WITH_DENTRY
73                struct dentry *dentry,
74 #else
75                struct inode *inode,
76 #endif
77                struct posix_acl *acl, int type)
78 {
79 #ifdef HAVE_ACL_WITH_DENTRY
80         struct inode *inode = dentry->d_inode;
81 #endif
82         struct ll_sb_info *sbi = ll_i2sbi(inode);
83         struct ptlrpc_request *req = NULL;
84         const char *name = NULL;
85         char *value = NULL;
86         size_t value_size = 0;
87         int rc = 0;
88         ENTRY;
89
90         switch (type) {
91         case ACL_TYPE_ACCESS:
92                 name = XATTR_NAME_POSIX_ACL_ACCESS;
93                 if (acl)
94                         rc = posix_acl_update_mode(map, inode,
95                                                    &inode->i_mode, &acl);
96                 break;
97
98         case ACL_TYPE_DEFAULT:
99                 name = XATTR_NAME_POSIX_ACL_DEFAULT;
100                 if (!S_ISDIR(inode->i_mode))
101                         rc = acl ? -EACCES : 0;
102                 break;
103
104         default:
105                 rc = -EINVAL;
106                 break;
107         }
108         if (rc)
109                 return rc;
110
111         if (acl) {
112                 value_size = posix_acl_xattr_size(acl->a_count);
113                 value = kmalloc(value_size, GFP_NOFS);
114                 if (value == NULL)
115                         GOTO(out, rc = -ENOMEM);
116
117                 rc = posix_acl_to_xattr(&init_user_ns, acl, value, value_size);
118                 if (rc < 0)
119                         GOTO(out_value, rc);
120         }
121
122         rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
123                          value ? OBD_MD_FLXATTR : OBD_MD_FLXATTRRM,
124                          name, value, value_size, 0, 0, &req);
125         if (!rc)
126                 ll_i2info(inode)->lli_synced_to_mds = false;
127
128         ptlrpc_req_finished(req);
129 out_value:
130         kfree(value);
131 out:
132         if (rc)
133                 forget_cached_acl(inode, type);
134         else
135                 set_cached_acl(inode, type, acl);
136         RETURN(rc);
137 }
138 #endif /* HAVE_IOP_SET_ACL */