Blame view
fs/xfs/xfs_xattr.c
6.13 KB
f9e09f095 [XFS] Use the gen... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* * Copyright (C) 2008 Christoph Hellwig. * Portions Copyright (C) 2000-2008 Silicon Graphics, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "xfs.h" |
a4fbe6ab1 xfs: decouple ino... |
20 |
#include "xfs_format.h" |
69432832f xfs: split out in... |
21 |
#include "xfs_log_format.h" |
239880ef6 xfs: decouple log... |
22 |
#include "xfs_trans_resv.h" |
570627875 xfs: unify direct... |
23 24 |
#include "xfs_mount.h" #include "xfs_da_format.h" |
f9e09f095 [XFS] Use the gen... |
25 26 27 28 |
#include "xfs_inode.h" #include "xfs_attr.h" #include "xfs_attr_leaf.h" #include "xfs_acl.h" |
f9e09f095 [XFS] Use the gen... |
29 30 31 |
#include <linux/posix_acl_xattr.h> #include <linux/xattr.h> |
f9e09f095 [XFS] Use the gen... |
32 |
static int |
b296821a7 xattr_handler: pa... |
33 34 |
xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, void *value, size_t size) |
f9e09f095 [XFS] Use the gen... |
35 |
{ |
d9a82a040 xattr handlers: P... |
36 |
int xflags = handler->flags; |
b296821a7 xattr_handler: pa... |
37 |
struct xfs_inode *ip = XFS_I(inode); |
f9e09f095 [XFS] Use the gen... |
38 |
int error, asize = size; |
f9e09f095 [XFS] Use the gen... |
39 40 41 42 43 |
/* Convert Linux syscall to XFS internal ATTR flags */ if (!size) { xflags |= ATTR_KERNOVAL; value = NULL; } |
2451337dd xfs: global error... |
44 |
error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags); |
f9e09f095 [XFS] Use the gen... |
45 46 47 48 |
if (error) return error; return asize; } |
47e1bf640 xfs: invalidate c... |
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
void xfs_forget_acl( struct inode *inode, const char *name, int xflags) { /* * Invalidate any cached ACLs if the user has bypassed the ACL * interface. We don't validate the content whatsoever so it is caller * responsibility to provide data in valid format and ensure i_mode is * consistent. */ if (xflags & ATTR_ROOT) { #ifdef CONFIG_XFS_POSIX_ACL if (!strcmp(name, SGI_ACL_FILE)) forget_cached_acl(inode, ACL_TYPE_ACCESS); else if (!strcmp(name, SGI_ACL_DEFAULT)) forget_cached_acl(inode, ACL_TYPE_DEFAULT); #endif } } |
f9e09f095 [XFS] Use the gen... |
70 |
static int |
593012268 switch xattr_hand... |
71 72 73 |
xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused, struct inode *inode, const char *name, const void *value, size_t size, int flags) |
f9e09f095 [XFS] Use the gen... |
74 |
{ |
5d2eb548b Merge branch 'for... |
75 |
int xflags = handler->flags; |
593012268 switch xattr_hand... |
76 |
struct xfs_inode *ip = XFS_I(inode); |
67d8e04e3 xfs: invalidate c... |
77 |
int error; |
f9e09f095 [XFS] Use the gen... |
78 |
|
f9e09f095 [XFS] Use the gen... |
79 80 81 82 83 84 85 |
/* Convert Linux syscall to XFS internal ATTR flags */ if (flags & XATTR_CREATE) xflags |= ATTR_CREATE; if (flags & XATTR_REPLACE) xflags |= ATTR_REPLACE; if (!value) |
2451337dd xfs: global error... |
86 |
return xfs_attr_remove(ip, (unsigned char *)name, xflags); |
67d8e04e3 xfs: invalidate c... |
87 |
error = xfs_attr_set(ip, (unsigned char *)name, |
a9273ca5c xfs: convert attr... |
88 |
(void *)value, size, xflags); |
47e1bf640 xfs: invalidate c... |
89 |
if (!error) |
593012268 switch xattr_hand... |
90 |
xfs_forget_acl(inode, name, xflags); |
67d8e04e3 xfs: invalidate c... |
91 92 |
return error; |
f9e09f095 [XFS] Use the gen... |
93 |
} |
46e58764f xfs: constify xat... |
94 |
static const struct xattr_handler xfs_xattr_user_handler = { |
f9e09f095 [XFS] Use the gen... |
95 |
.prefix = XATTR_USER_PREFIX, |
431547b3c sanitize xattr ha... |
96 97 98 |
.flags = 0, /* no flags implies user namespace */ .get = xfs_xattr_get, .set = xfs_xattr_set, |
f9e09f095 [XFS] Use the gen... |
99 |
}; |
46e58764f xfs: constify xat... |
100 |
static const struct xattr_handler xfs_xattr_trusted_handler = { |
f9e09f095 [XFS] Use the gen... |
101 |
.prefix = XATTR_TRUSTED_PREFIX, |
431547b3c sanitize xattr ha... |
102 103 104 |
.flags = ATTR_ROOT, .get = xfs_xattr_get, .set = xfs_xattr_set, |
f9e09f095 [XFS] Use the gen... |
105 |
}; |
46e58764f xfs: constify xat... |
106 |
static const struct xattr_handler xfs_xattr_security_handler = { |
f9e09f095 [XFS] Use the gen... |
107 |
.prefix = XATTR_SECURITY_PREFIX, |
431547b3c sanitize xattr ha... |
108 109 110 |
.flags = ATTR_SECURE, .get = xfs_xattr_get, .set = xfs_xattr_set, |
f9e09f095 [XFS] Use the gen... |
111 |
}; |
46e58764f xfs: constify xat... |
112 |
const struct xattr_handler *xfs_xattr_handlers[] = { |
f9e09f095 [XFS] Use the gen... |
113 114 115 |
&xfs_xattr_user_handler, &xfs_xattr_trusted_handler, &xfs_xattr_security_handler, |
ef14f0c15 xfs: use generic ... |
116 |
#ifdef CONFIG_XFS_POSIX_ACL |
2401dc297 xfs: use generic ... |
117 118 |
&posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, |
ef14f0c15 xfs: use generic ... |
119 |
#endif |
f9e09f095 [XFS] Use the gen... |
120 121 |
NULL }; |
f9e09f095 [XFS] Use the gen... |
122 |
static int |
5d92b75c7 xfs: Change how l... |
123 |
__xfs_xattr_put_listent( |
a9273ca5c xfs: convert attr... |
124 |
struct xfs_attr_list_context *context, |
5d92b75c7 xfs: Change how l... |
125 126 127 128 |
char *prefix, int prefix_len, unsigned char *name, int namelen) |
f9e09f095 [XFS] Use the gen... |
129 |
{ |
f9e09f095 [XFS] Use the gen... |
130 131 |
char *offset; int arraytop; |
5d92b75c7 xfs: Change how l... |
132 133 |
if (!context->alist) goto compute_size; |
f9e09f095 [XFS] Use the gen... |
134 135 136 137 |
arraytop = context->count + prefix_len + namelen + 1; if (arraytop > context->firstu) { context->count = -1; /* insufficient space */ |
791cc43b3 Make __xfs_xattr_... |
138 |
context->seen_enough = 1; |
2a6fba6d2 xfs: only return ... |
139 |
return 0; |
f9e09f095 [XFS] Use the gen... |
140 141 |
} offset = (char *)context->alist + context->count; |
5d92b75c7 xfs: Change how l... |
142 |
strncpy(offset, prefix, prefix_len); |
f9e09f095 [XFS] Use the gen... |
143 |
offset += prefix_len; |
a9273ca5c xfs: convert attr... |
144 |
strncpy(offset, (char *)name, namelen); /* real name */ |
f9e09f095 [XFS] Use the gen... |
145 146 |
offset += namelen; *offset = '\0'; |
5d92b75c7 xfs: Change how l... |
147 148 |
compute_size: |
f9e09f095 [XFS] Use the gen... |
149 150 151 152 153 |
context->count += prefix_len + namelen + 1; return 0; } static int |
5d92b75c7 xfs: Change how l... |
154 |
xfs_xattr_put_listent( |
a9273ca5c xfs: convert attr... |
155 156 157 158 |
struct xfs_attr_list_context *context, int flags, unsigned char *name, int namelen, |
e5bd12bfe xfs: don't pass v... |
159 |
int valuelen) |
f9e09f095 [XFS] Use the gen... |
160 |
{ |
5d92b75c7 xfs: Change how l... |
161 162 |
char *prefix; int prefix_len; |
f9e09f095 [XFS] Use the gen... |
163 |
|
5d92b75c7 xfs: Change how l... |
164 |
ASSERT(context->count >= 0); |
f9e09f095 [XFS] Use the gen... |
165 |
|
5d92b75c7 xfs: Change how l... |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
if (flags & XFS_ATTR_ROOT) { #ifdef CONFIG_XFS_POSIX_ACL if (namelen == SGI_ACL_FILE_SIZE && strncmp(name, SGI_ACL_FILE, SGI_ACL_FILE_SIZE) == 0) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, XATTR_POSIX_ACL_ACCESS, strlen(XATTR_POSIX_ACL_ACCESS)); if (ret) return ret; } else if (namelen == SGI_ACL_DEFAULT_SIZE && strncmp(name, SGI_ACL_DEFAULT, SGI_ACL_DEFAULT_SIZE) == 0) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, XATTR_POSIX_ACL_DEFAULT, strlen(XATTR_POSIX_ACL_DEFAULT)); if (ret) return ret; } #endif |
f9e09f095 [XFS] Use the gen... |
190 |
|
5d92b75c7 xfs: Change how l... |
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
/* * Only show root namespace entries if we are actually allowed to * see them. */ if (!capable(CAP_SYS_ADMIN)) return 0; prefix = XATTR_TRUSTED_PREFIX; prefix_len = XATTR_TRUSTED_PREFIX_LEN; } else if (flags & XFS_ATTR_SECURE) { prefix = XATTR_SECURITY_PREFIX; prefix_len = XATTR_SECURITY_PREFIX_LEN; } else { prefix = XATTR_USER_PREFIX; prefix_len = XATTR_USER_PREFIX_LEN; } return __xfs_xattr_put_listent(context, prefix, prefix_len, name, namelen); |
f9e09f095 [XFS] Use the gen... |
210 211 212 |
} ssize_t |
2a6fba6d2 xfs: only return ... |
213 214 215 216 |
xfs_vn_listxattr( struct dentry *dentry, char *data, size_t size) |
f9e09f095 [XFS] Use the gen... |
217 218 219 |
{ struct xfs_attr_list_context context; struct attrlist_cursor_kern cursor = { 0 }; |
2a6fba6d2 xfs: only return ... |
220 221 |
struct inode *inode = d_inode(dentry); int error; |
f9e09f095 [XFS] Use the gen... |
222 223 224 225 226 227 228 229 |
/* * First read the regular on-disk attributes. */ memset(&context, 0, sizeof(context)); context.dp = XFS_I(inode); context.cursor = &cursor; context.resynch = 1; |
5d92b75c7 xfs: Change how l... |
230 |
context.alist = size ? data : NULL; |
f9e09f095 [XFS] Use the gen... |
231 232 |
context.bufsize = size; context.firstu = context.bufsize; |
5d92b75c7 xfs: Change how l... |
233 |
context.put_listent = xfs_xattr_put_listent; |
f9e09f095 [XFS] Use the gen... |
234 |
|
2a6fba6d2 xfs: only return ... |
235 236 237 |
error = xfs_attr_list_int(&context); if (error) return error; |
f9e09f095 [XFS] Use the gen... |
238 239 |
if (context.count < 0) return -ERANGE; |
f9e09f095 [XFS] Use the gen... |
240 241 |
return context.count; } |