diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 16:32:10 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-11 16:32:10 -0500 |
commit | ddf1d6238dd13a3bd948e8fcb1109798ef0af49b (patch) | |
tree | daa25447e4b791b2868a0338f872975ec480862b /fs/xfs | |
parent | 32fb378437a1d716e72a442237d7ead1f435ecf0 (diff) | |
parent | 764a5c6b1fa4306dd7573c1d80914254909cd036 (diff) |
Merge branch 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs xattr updates from Al Viro:
"Andreas' xattr cleanup series.
It's a followup to his xattr work that went in last cycle; -0.5KLoC"
* 'work.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
xattr handlers: Simplify list operation
ocfs2: Replace list xattr handler operations
nfs: Move call to security_inode_listsecurity into nfs_listxattr
xfs: Change how listxattr generates synthetic attributes
tmpfs: listxattr should include POSIX ACL xattrs
tmpfs: Use xattr handler infrastructure
btrfs: Use xattr handler infrastructure
vfs: Distinguish between full xattr names and proper prefixes
posix acls: Remove duplicate xattr name definitions
gfs2: Remove gfs2_xattr_acl_chmod
vfs: Remove vfs_xattr_cmp
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_acl.c | 23 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.h | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_xattr.c | 143 |
3 files changed, 59 insertions, 111 deletions
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 6bb470fbb8e8..2d5df1f23bbc 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -252,29 +252,6 @@ xfs_set_mode(struct inode *inode, umode_t mode) | |||
252 | return error; | 252 | return error; |
253 | } | 253 | } |
254 | 254 | ||
255 | static int | ||
256 | xfs_acl_exists(struct inode *inode, unsigned char *name) | ||
257 | { | ||
258 | int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); | ||
259 | |||
260 | return (xfs_attr_get(XFS_I(inode), name, NULL, &len, | ||
261 | ATTR_ROOT|ATTR_KERNOVAL) == 0); | ||
262 | } | ||
263 | |||
264 | int | ||
265 | posix_acl_access_exists(struct inode *inode) | ||
266 | { | ||
267 | return xfs_acl_exists(inode, SGI_ACL_FILE); | ||
268 | } | ||
269 | |||
270 | int | ||
271 | posix_acl_default_exists(struct inode *inode) | ||
272 | { | ||
273 | if (!S_ISDIR(inode->i_mode)) | ||
274 | return 0; | ||
275 | return xfs_acl_exists(inode, SGI_ACL_DEFAULT); | ||
276 | } | ||
277 | |||
278 | int | 255 | int |
279 | xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) | 256 | xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
280 | { | 257 | { |
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 52f8255d6bdf..286fa89217f5 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h | |||
@@ -24,16 +24,12 @@ struct posix_acl; | |||
24 | #ifdef CONFIG_XFS_POSIX_ACL | 24 | #ifdef CONFIG_XFS_POSIX_ACL |
25 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); | 25 | extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); |
26 | extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); | 26 | extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); |
27 | extern int posix_acl_access_exists(struct inode *inode); | ||
28 | extern int posix_acl_default_exists(struct inode *inode); | ||
29 | #else | 27 | #else |
30 | static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) | 28 | static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) |
31 | { | 29 | { |
32 | return NULL; | 30 | return NULL; |
33 | } | 31 | } |
34 | # define xfs_set_acl NULL | 32 | # define xfs_set_acl NULL |
35 | # define posix_acl_access_exists(inode) 0 | ||
36 | # define posix_acl_default_exists(inode) 0 | ||
37 | #endif /* CONFIG_XFS_POSIX_ACL */ | 33 | #endif /* CONFIG_XFS_POSIX_ACL */ |
38 | 34 | ||
39 | extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags); | 35 | extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags); |
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 839b35ca21c6..110f1d7d86b0 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c | |||
@@ -39,9 +39,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, | |||
39 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 39 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
40 | int error, asize = size; | 40 | int error, asize = size; |
41 | 41 | ||
42 | if (strcmp(name, "") == 0) | ||
43 | return -EINVAL; | ||
44 | |||
45 | /* Convert Linux syscall to XFS internal ATTR flags */ | 42 | /* Convert Linux syscall to XFS internal ATTR flags */ |
46 | if (!size) { | 43 | if (!size) { |
47 | xflags |= ATTR_KERNOVAL; | 44 | xflags |= ATTR_KERNOVAL; |
@@ -84,9 +81,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, | |||
84 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); | 81 | struct xfs_inode *ip = XFS_I(d_inode(dentry)); |
85 | int error; | 82 | int error; |
86 | 83 | ||
87 | if (strcmp(name, "") == 0) | ||
88 | return -EINVAL; | ||
89 | |||
90 | /* Convert Linux syscall to XFS internal ATTR flags */ | 84 | /* Convert Linux syscall to XFS internal ATTR flags */ |
91 | if (flags & XATTR_CREATE) | 85 | if (flags & XATTR_CREATE) |
92 | xflags |= ATTR_CREATE; | 86 | xflags |= ATTR_CREATE; |
@@ -135,47 +129,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = { | |||
135 | NULL | 129 | NULL |
136 | }; | 130 | }; |
137 | 131 | ||
138 | static unsigned int xfs_xattr_prefix_len(int flags) | ||
139 | { | ||
140 | if (flags & XFS_ATTR_SECURE) | ||
141 | return sizeof("security"); | ||
142 | else if (flags & XFS_ATTR_ROOT) | ||
143 | return sizeof("trusted"); | ||
144 | else | ||
145 | return sizeof("user"); | ||
146 | } | ||
147 | |||
148 | static const char *xfs_xattr_prefix(int flags) | ||
149 | { | ||
150 | if (flags & XFS_ATTR_SECURE) | ||
151 | return xfs_xattr_security_handler.prefix; | ||
152 | else if (flags & XFS_ATTR_ROOT) | ||
153 | return xfs_xattr_trusted_handler.prefix; | ||
154 | else | ||
155 | return xfs_xattr_user_handler.prefix; | ||
156 | } | ||
157 | |||
158 | static int | 132 | static int |
159 | xfs_xattr_put_listent( | 133 | __xfs_xattr_put_listent( |
160 | struct xfs_attr_list_context *context, | 134 | struct xfs_attr_list_context *context, |
161 | int flags, | 135 | char *prefix, |
162 | unsigned char *name, | 136 | int prefix_len, |
163 | int namelen, | 137 | unsigned char *name, |
164 | int valuelen, | 138 | int namelen) |
165 | unsigned char *value) | ||
166 | { | 139 | { |
167 | unsigned int prefix_len = xfs_xattr_prefix_len(flags); | ||
168 | char *offset; | 140 | char *offset; |
169 | int arraytop; | 141 | int arraytop; |
170 | 142 | ||
171 | ASSERT(context->count >= 0); | 143 | if (!context->alist) |
172 | 144 | goto compute_size; | |
173 | /* | ||
174 | * Only show root namespace entries if we are actually allowed to | ||
175 | * see them. | ||
176 | */ | ||
177 | if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN)) | ||
178 | return 0; | ||
179 | 145 | ||
180 | arraytop = context->count + prefix_len + namelen + 1; | 146 | arraytop = context->count + prefix_len + namelen + 1; |
181 | if (arraytop > context->firstu) { | 147 | if (arraytop > context->firstu) { |
@@ -183,17 +149,19 @@ xfs_xattr_put_listent( | |||
183 | return 1; | 149 | return 1; |
184 | } | 150 | } |
185 | offset = (char *)context->alist + context->count; | 151 | offset = (char *)context->alist + context->count; |
186 | strncpy(offset, xfs_xattr_prefix(flags), prefix_len); | 152 | strncpy(offset, prefix, prefix_len); |
187 | offset += prefix_len; | 153 | offset += prefix_len; |
188 | strncpy(offset, (char *)name, namelen); /* real name */ | 154 | strncpy(offset, (char *)name, namelen); /* real name */ |
189 | offset += namelen; | 155 | offset += namelen; |
190 | *offset = '\0'; | 156 | *offset = '\0'; |
157 | |||
158 | compute_size: | ||
191 | context->count += prefix_len + namelen + 1; | 159 | context->count += prefix_len + namelen + 1; |
192 | return 0; | 160 | return 0; |
193 | } | 161 | } |
194 | 162 | ||
195 | static int | 163 | static int |
196 | xfs_xattr_put_listent_sizes( | 164 | xfs_xattr_put_listent( |
197 | struct xfs_attr_list_context *context, | 165 | struct xfs_attr_list_context *context, |
198 | int flags, | 166 | int flags, |
199 | unsigned char *name, | 167 | unsigned char *name, |
@@ -201,24 +169,55 @@ xfs_xattr_put_listent_sizes( | |||
201 | int valuelen, | 169 | int valuelen, |
202 | unsigned char *value) | 170 | unsigned char *value) |
203 | { | 171 | { |
204 | context->count += xfs_xattr_prefix_len(flags) + namelen + 1; | 172 | char *prefix; |
205 | return 0; | 173 | int prefix_len; |
206 | } | ||
207 | 174 | ||
208 | static int | 175 | ASSERT(context->count >= 0); |
209 | list_one_attr(const char *name, const size_t len, void *data, | ||
210 | size_t size, ssize_t *result) | ||
211 | { | ||
212 | char *p = data + *result; | ||
213 | 176 | ||
214 | *result += len; | 177 | if (flags & XFS_ATTR_ROOT) { |
215 | if (!size) | 178 | #ifdef CONFIG_XFS_POSIX_ACL |
216 | return 0; | 179 | if (namelen == SGI_ACL_FILE_SIZE && |
217 | if (*result > size) | 180 | strncmp(name, SGI_ACL_FILE, |
218 | return -ERANGE; | 181 | SGI_ACL_FILE_SIZE) == 0) { |
182 | int ret = __xfs_xattr_put_listent( | ||
183 | context, XATTR_SYSTEM_PREFIX, | ||
184 | XATTR_SYSTEM_PREFIX_LEN, | ||
185 | XATTR_POSIX_ACL_ACCESS, | ||
186 | strlen(XATTR_POSIX_ACL_ACCESS)); | ||
187 | if (ret) | ||
188 | return ret; | ||
189 | } else if (namelen == SGI_ACL_DEFAULT_SIZE && | ||
190 | strncmp(name, SGI_ACL_DEFAULT, | ||
191 | SGI_ACL_DEFAULT_SIZE) == 0) { | ||
192 | int ret = __xfs_xattr_put_listent( | ||
193 | context, XATTR_SYSTEM_PREFIX, | ||
194 | XATTR_SYSTEM_PREFIX_LEN, | ||
195 | XATTR_POSIX_ACL_DEFAULT, | ||
196 | strlen(XATTR_POSIX_ACL_DEFAULT)); | ||
197 | if (ret) | ||
198 | return ret; | ||
199 | } | ||
200 | #endif | ||
219 | 201 | ||
220 | strcpy(p, name); | 202 | /* |
221 | return 0; | 203 | * Only show root namespace entries if we are actually allowed to |
204 | * see them. | ||
205 | */ | ||
206 | if (!capable(CAP_SYS_ADMIN)) | ||
207 | return 0; | ||
208 | |||
209 | prefix = XATTR_TRUSTED_PREFIX; | ||
210 | prefix_len = XATTR_TRUSTED_PREFIX_LEN; | ||
211 | } else if (flags & XFS_ATTR_SECURE) { | ||
212 | prefix = XATTR_SECURITY_PREFIX; | ||
213 | prefix_len = XATTR_SECURITY_PREFIX_LEN; | ||
214 | } else { | ||
215 | prefix = XATTR_USER_PREFIX; | ||
216 | prefix_len = XATTR_USER_PREFIX_LEN; | ||
217 | } | ||
218 | |||
219 | return __xfs_xattr_put_listent(context, prefix, prefix_len, name, | ||
220 | namelen); | ||
222 | } | 221 | } |
223 | 222 | ||
224 | ssize_t | 223 | ssize_t |
@@ -227,7 +226,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) | |||
227 | struct xfs_attr_list_context context; | 226 | struct xfs_attr_list_context context; |
228 | struct attrlist_cursor_kern cursor = { 0 }; | 227 | struct attrlist_cursor_kern cursor = { 0 }; |
229 | struct inode *inode = d_inode(dentry); | 228 | struct inode *inode = d_inode(dentry); |
230 | int error; | ||
231 | 229 | ||
232 | /* | 230 | /* |
233 | * First read the regular on-disk attributes. | 231 | * First read the regular on-disk attributes. |
@@ -236,37 +234,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) | |||
236 | context.dp = XFS_I(inode); | 234 | context.dp = XFS_I(inode); |
237 | context.cursor = &cursor; | 235 | context.cursor = &cursor; |
238 | context.resynch = 1; | 236 | context.resynch = 1; |
239 | context.alist = data; | 237 | context.alist = size ? data : NULL; |
240 | context.bufsize = size; | 238 | context.bufsize = size; |
241 | context.firstu = context.bufsize; | 239 | context.firstu = context.bufsize; |
242 | 240 | context.put_listent = xfs_xattr_put_listent; | |
243 | if (size) | ||
244 | context.put_listent = xfs_xattr_put_listent; | ||
245 | else | ||
246 | context.put_listent = xfs_xattr_put_listent_sizes; | ||
247 | 241 | ||
248 | xfs_attr_list_int(&context); | 242 | xfs_attr_list_int(&context); |
249 | if (context.count < 0) | 243 | if (context.count < 0) |
250 | return -ERANGE; | 244 | return -ERANGE; |
251 | 245 | ||
252 | /* | ||
253 | * Then add the two synthetic ACL attributes. | ||
254 | */ | ||
255 | if (posix_acl_access_exists(inode)) { | ||
256 | error = list_one_attr(POSIX_ACL_XATTR_ACCESS, | ||
257 | strlen(POSIX_ACL_XATTR_ACCESS) + 1, | ||
258 | data, size, &context.count); | ||
259 | if (error) | ||
260 | return error; | ||
261 | } | ||
262 | |||
263 | if (posix_acl_default_exists(inode)) { | ||
264 | error = list_one_attr(POSIX_ACL_XATTR_DEFAULT, | ||
265 | strlen(POSIX_ACL_XATTR_DEFAULT) + 1, | ||
266 | data, size, &context.count); | ||
267 | if (error) | ||
268 | return error; | ||
269 | } | ||
270 | |||
271 | return context.count; | 246 | return context.count; |
272 | } | 247 | } |