1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2008, Christoph Hellwig
7 #include "xfs_shared.h"
8 #include "xfs_format.h"
9 #include "xfs_log_format.h"
10 #include "xfs_trans_resv.h"
11 #include "xfs_mount.h"
12 #include "xfs_inode.h"
13 #include "xfs_da_format.h"
14 #include "xfs_da_btree.h"
16 #include "xfs_trace.h"
17 #include "xfs_error.h"
19 #include "xfs_trans.h"
20 #include "xfs_xattr.h"
22 #include <linux/posix_acl_xattr.h>
26 * - all ACL updates are protected by inode->i_mutex, which is taken before
27 * calling into this file.
30 STATIC
struct posix_acl
*
33 const struct xfs_acl
*aclp
,
37 struct posix_acl_entry
*acl_e
;
38 struct posix_acl
*acl
;
39 const struct xfs_acl_entry
*ace
;
40 unsigned int count
, i
;
42 if (len
< sizeof(*aclp
)) {
43 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
, aclp
,
45 return ERR_PTR(-EFSCORRUPTED
);
48 count
= be32_to_cpu(aclp
->acl_cnt
);
49 if (count
> max_entries
|| XFS_ACL_SIZE(count
) != len
) {
50 XFS_CORRUPTION_ERROR(__func__
, XFS_ERRLEVEL_LOW
, mp
, aclp
,
52 return ERR_PTR(-EFSCORRUPTED
);
55 acl
= posix_acl_alloc(count
, GFP_KERNEL
);
57 return ERR_PTR(-ENOMEM
);
59 for (i
= 0; i
< count
; i
++) {
60 acl_e
= &acl
->a_entries
[i
];
61 ace
= &aclp
->acl_entry
[i
];
64 * The tag is 32 bits on disk and 16 bits in core.
66 * Because every access to it goes through the core
67 * format first this is not a problem.
69 acl_e
->e_tag
= be32_to_cpu(ace
->ae_tag
);
70 acl_e
->e_perm
= be16_to_cpu(ace
->ae_perm
);
72 switch (acl_e
->e_tag
) {
74 acl_e
->e_uid
= make_kuid(&init_user_ns
,
75 be32_to_cpu(ace
->ae_id
));
78 acl_e
->e_gid
= make_kgid(&init_user_ns
,
79 be32_to_cpu(ace
->ae_id
));
93 posix_acl_release(acl
);
94 return ERR_PTR(-EINVAL
);
98 xfs_acl_to_disk(struct xfs_acl
*aclp
, const struct posix_acl
*acl
)
100 const struct posix_acl_entry
*acl_e
;
101 struct xfs_acl_entry
*ace
;
104 aclp
->acl_cnt
= cpu_to_be32(acl
->a_count
);
105 for (i
= 0; i
< acl
->a_count
; i
++) {
106 ace
= &aclp
->acl_entry
[i
];
107 acl_e
= &acl
->a_entries
[i
];
109 ace
->ae_tag
= cpu_to_be32(acl_e
->e_tag
);
110 switch (acl_e
->e_tag
) {
112 ace
->ae_id
= cpu_to_be32(
113 from_kuid(&init_user_ns
, acl_e
->e_uid
));
116 ace
->ae_id
= cpu_to_be32(
117 from_kgid(&init_user_ns
, acl_e
->e_gid
));
120 ace
->ae_id
= cpu_to_be32(ACL_UNDEFINED_ID
);
124 ace
->ae_perm
= cpu_to_be16(acl_e
->e_perm
);
129 xfs_get_acl(struct inode
*inode
, int type
, bool rcu
)
131 struct xfs_inode
*ip
= XFS_I(inode
);
132 struct xfs_mount
*mp
= ip
->i_mount
;
133 struct posix_acl
*acl
= NULL
;
134 struct xfs_da_args args
= {
136 .attr_filter
= XFS_ATTR_ROOT
,
137 .valuelen
= XFS_ACL_MAX_SIZE(mp
),
142 return ERR_PTR(-ECHILD
);
144 trace_xfs_get_acl(ip
);
147 case ACL_TYPE_ACCESS
:
148 args
.name
= SGI_ACL_FILE
;
150 case ACL_TYPE_DEFAULT
:
151 args
.name
= SGI_ACL_DEFAULT
;
156 args
.namelen
= strlen(args
.name
);
159 * If the attribute doesn't exist make sure we have a negative cache
160 * entry, for any other error assume it is transient.
162 error
= xfs_attr_get(&args
);
164 acl
= xfs_acl_from_disk(mp
, args
.value
, args
.valuelen
,
165 XFS_ACL_MAX_ENTRIES(mp
));
166 } else if (error
!= -ENOATTR
) {
167 acl
= ERR_PTR(error
);
175 __xfs_set_acl(struct inode
*inode
, struct posix_acl
*acl
, int type
)
177 struct xfs_inode
*ip
= XFS_I(inode
);
178 struct xfs_da_args args
= {
180 .attr_filter
= XFS_ATTR_ROOT
,
185 case ACL_TYPE_ACCESS
:
186 args
.name
= SGI_ACL_FILE
;
188 case ACL_TYPE_DEFAULT
:
189 if (!S_ISDIR(inode
->i_mode
))
190 return acl
? -EACCES
: 0;
191 args
.name
= SGI_ACL_DEFAULT
;
196 args
.namelen
= strlen(args
.name
);
199 args
.valuelen
= XFS_ACL_SIZE(acl
->a_count
);
200 args
.value
= kvzalloc(args
.valuelen
, GFP_KERNEL
);
203 xfs_acl_to_disk(args
.value
, acl
);
204 error
= xfs_attr_change(&args
, XFS_ATTRUPDATE_UPSERT
);
207 error
= xfs_attr_change(&args
, XFS_ATTRUPDATE_REMOVE
);
209 * If the attribute didn't exist to start with that's fine.
211 if (error
== -ENOATTR
)
216 set_cached_acl(inode
, type
, acl
);
225 struct xfs_inode
*ip
= XFS_I(inode
);
226 struct xfs_mount
*mp
= ip
->i_mount
;
227 struct xfs_trans
*tp
;
230 error
= xfs_trans_alloc(mp
, &M_RES(mp
)->tr_ichange
, 0, 0, 0, &tp
);
234 xfs_ilock(ip
, XFS_ILOCK_EXCL
);
235 xfs_trans_ijoin(tp
, ip
, XFS_ILOCK_EXCL
);
236 inode
->i_mode
= mode
;
237 inode_set_ctime_current(inode
);
238 xfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
240 if (xfs_has_wsync(mp
))
241 xfs_trans_set_sync(tp
);
242 return xfs_trans_commit(tp
);
246 xfs_set_acl(struct mnt_idmap
*idmap
, struct dentry
*dentry
,
247 struct posix_acl
*acl
, int type
)
250 bool set_mode
= false;
252 struct inode
*inode
= d_inode(dentry
);
258 if (acl
->a_count
> XFS_ACL_MAX_ENTRIES(XFS_M(inode
->i_sb
)))
261 if (type
== ACL_TYPE_ACCESS
) {
262 error
= posix_acl_update_mode(idmap
, inode
, &mode
, &acl
);
270 * We set the mode after successfully updating the ACL xattr because the
271 * xattr update can fail at ENOSPC and we don't want to change the mode
272 * if the ACL update hasn't been applied.
274 error
= __xfs_set_acl(inode
, acl
, type
);
275 if (!error
&& set_mode
&& mode
!= inode
->i_mode
)
276 error
= xfs_acl_set_mode(inode
, mode
);
281 * Invalidate any cached ACLs if the user has bypassed the ACL interface.
282 * We don't validate the content whatsoever so it is caller responsibility to
283 * provide data in valid format and ensure i_mode is consistent.
290 if (!strcmp(name
, SGI_ACL_FILE
))
291 forget_cached_acl(inode
, ACL_TYPE_ACCESS
);
292 else if (!strcmp(name
, SGI_ACL_DEFAULT
))
293 forget_cached_acl(inode
, ACL_TYPE_DEFAULT
);