diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-08-22 11:22:11 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2016-09-01 05:12:00 -0400 |
commit | 0e585ccc13b3edbb187fb4f1b7cc9397f17d64a9 (patch) | |
tree | 092d1da4ee6fb40592629de0dde82942e4dde0f6 /fs/overlayfs | |
parent | 0c97be22f928b85110504c4bbb8574facb4bd0c0 (diff) |
ovl: Switch to generic_removexattr
Commit d837a49bd57f ("ovl: fix POSIX ACL setting") switches from
iop->setxattr from ovl_setxattr to generic_setxattr, so switch from
ovl_removexattr to generic_removexattr as well. As far as permission
checking goes, the same rules should apply in either case.
While doing that, rename ovl_setxattr to ovl_xattr_set to indicate that
this is not an iop->setxattr implementation and remove the unused inode
argument.
Move ovl_other_xattr_set above ovl_own_xattr_set so that they match the
order of handlers in ovl_xattr_handlers.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Fixes: d837a49bd57f ("ovl: fix POSIX ACL setting")
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/overlayfs')
-rw-r--r-- | fs/overlayfs/dir.c | 2 | ||||
-rw-r--r-- | fs/overlayfs/inode.c | 65 | ||||
-rw-r--r-- | fs/overlayfs/overlayfs.h | 6 | ||||
-rw-r--r-- | fs/overlayfs/super.c | 18 |
4 files changed, 33 insertions, 58 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index f485dd4288e4..791c6a209656 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c | |||
@@ -1006,7 +1006,7 @@ const struct inode_operations ovl_dir_inode_operations = { | |||
1006 | .setxattr = generic_setxattr, | 1006 | .setxattr = generic_setxattr, |
1007 | .getxattr = ovl_getxattr, | 1007 | .getxattr = ovl_getxattr, |
1008 | .listxattr = ovl_listxattr, | 1008 | .listxattr = ovl_listxattr, |
1009 | .removexattr = ovl_removexattr, | 1009 | .removexattr = generic_removexattr, |
1010 | .get_acl = ovl_get_acl, | 1010 | .get_acl = ovl_get_acl, |
1011 | .update_time = ovl_update_time, | 1011 | .update_time = ovl_update_time, |
1012 | }; | 1012 | }; |
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index f523511b324f..94bca710e6d2 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c | |||
@@ -198,25 +198,38 @@ bool ovl_is_private_xattr(const char *name) | |||
198 | sizeof(OVL_XATTR_PREFIX) - 1) == 0; | 198 | sizeof(OVL_XATTR_PREFIX) - 1) == 0; |
199 | } | 199 | } |
200 | 200 | ||
201 | int ovl_setxattr(struct dentry *dentry, struct inode *inode, | 201 | int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, |
202 | const char *name, const void *value, | 202 | size_t size, int flags) |
203 | size_t size, int flags) | ||
204 | { | 203 | { |
205 | int err; | 204 | int err; |
206 | struct dentry *upperdentry; | 205 | struct path realpath; |
206 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); | ||
207 | const struct cred *old_cred; | 207 | const struct cred *old_cred; |
208 | 208 | ||
209 | err = ovl_want_write(dentry); | 209 | err = ovl_want_write(dentry); |
210 | if (err) | 210 | if (err) |
211 | goto out; | 211 | goto out; |
212 | 212 | ||
213 | if (!value && !OVL_TYPE_UPPER(type)) { | ||
214 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); | ||
215 | if (err < 0) | ||
216 | goto out_drop_write; | ||
217 | } | ||
218 | |||
213 | err = ovl_copy_up(dentry); | 219 | err = ovl_copy_up(dentry); |
214 | if (err) | 220 | if (err) |
215 | goto out_drop_write; | 221 | goto out_drop_write; |
216 | 222 | ||
217 | upperdentry = ovl_dentry_upper(dentry); | 223 | if (!OVL_TYPE_UPPER(type)) |
224 | ovl_path_upper(dentry, &realpath); | ||
225 | |||
218 | old_cred = ovl_override_creds(dentry->d_sb); | 226 | old_cred = ovl_override_creds(dentry->d_sb); |
219 | err = vfs_setxattr(upperdentry, name, value, size, flags); | 227 | if (value) |
228 | err = vfs_setxattr(realpath.dentry, name, value, size, flags); | ||
229 | else { | ||
230 | WARN_ON(flags != XATTR_REPLACE); | ||
231 | err = vfs_removexattr(realpath.dentry, name); | ||
232 | } | ||
220 | revert_creds(old_cred); | 233 | revert_creds(old_cred); |
221 | 234 | ||
222 | out_drop_write: | 235 | out_drop_write: |
@@ -272,42 +285,6 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) | |||
272 | return res; | 285 | return res; |
273 | } | 286 | } |
274 | 287 | ||
275 | int ovl_removexattr(struct dentry *dentry, const char *name) | ||
276 | { | ||
277 | int err; | ||
278 | struct path realpath; | ||
279 | enum ovl_path_type type = ovl_path_real(dentry, &realpath); | ||
280 | const struct cred *old_cred; | ||
281 | |||
282 | err = ovl_want_write(dentry); | ||
283 | if (err) | ||
284 | goto out; | ||
285 | |||
286 | err = -ENODATA; | ||
287 | if (ovl_is_private_xattr(name)) | ||
288 | goto out_drop_write; | ||
289 | |||
290 | if (!OVL_TYPE_UPPER(type)) { | ||
291 | err = vfs_getxattr(realpath.dentry, name, NULL, 0); | ||
292 | if (err < 0) | ||
293 | goto out_drop_write; | ||
294 | |||
295 | err = ovl_copy_up(dentry); | ||
296 | if (err) | ||
297 | goto out_drop_write; | ||
298 | |||
299 | ovl_path_upper(dentry, &realpath); | ||
300 | } | ||
301 | |||
302 | old_cred = ovl_override_creds(dentry->d_sb); | ||
303 | err = vfs_removexattr(realpath.dentry, name); | ||
304 | revert_creds(old_cred); | ||
305 | out_drop_write: | ||
306 | ovl_drop_write(dentry); | ||
307 | out: | ||
308 | return err; | ||
309 | } | ||
310 | |||
311 | struct posix_acl *ovl_get_acl(struct inode *inode, int type) | 288 | struct posix_acl *ovl_get_acl(struct inode *inode, int type) |
312 | { | 289 | { |
313 | struct inode *realinode = ovl_inode_real(inode, NULL); | 290 | struct inode *realinode = ovl_inode_real(inode, NULL); |
@@ -393,7 +370,7 @@ static const struct inode_operations ovl_file_inode_operations = { | |||
393 | .setxattr = generic_setxattr, | 370 | .setxattr = generic_setxattr, |
394 | .getxattr = ovl_getxattr, | 371 | .getxattr = ovl_getxattr, |
395 | .listxattr = ovl_listxattr, | 372 | .listxattr = ovl_listxattr, |
396 | .removexattr = ovl_removexattr, | 373 | .removexattr = generic_removexattr, |
397 | .get_acl = ovl_get_acl, | 374 | .get_acl = ovl_get_acl, |
398 | .update_time = ovl_update_time, | 375 | .update_time = ovl_update_time, |
399 | }; | 376 | }; |
@@ -406,7 +383,7 @@ static const struct inode_operations ovl_symlink_inode_operations = { | |||
406 | .setxattr = generic_setxattr, | 383 | .setxattr = generic_setxattr, |
407 | .getxattr = ovl_getxattr, | 384 | .getxattr = ovl_getxattr, |
408 | .listxattr = ovl_listxattr, | 385 | .listxattr = ovl_listxattr, |
409 | .removexattr = ovl_removexattr, | 386 | .removexattr = generic_removexattr, |
410 | .update_time = ovl_update_time, | 387 | .update_time = ovl_update_time, |
411 | }; | 388 | }; |
412 | 389 | ||
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index f50c390683a3..5769aaf151a3 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h | |||
@@ -185,13 +185,11 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, | |||
185 | /* inode.c */ | 185 | /* inode.c */ |
186 | int ovl_setattr(struct dentry *dentry, struct iattr *attr); | 186 | int ovl_setattr(struct dentry *dentry, struct iattr *attr); |
187 | int ovl_permission(struct inode *inode, int mask); | 187 | int ovl_permission(struct inode *inode, int mask); |
188 | int ovl_setxattr(struct dentry *dentry, struct inode *inode, | 188 | int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value, |
189 | const char *name, const void *value, | 189 | size_t size, int flags); |
190 | size_t size, int flags); | ||
191 | ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, | 190 | ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, |
192 | const char *name, void *value, size_t size); | 191 | const char *name, void *value, size_t size); |
193 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); | 192 | ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); |
194 | int ovl_removexattr(struct dentry *dentry, const char *name); | ||
195 | struct posix_acl *ovl_get_acl(struct inode *inode, int type); | 193 | struct posix_acl *ovl_get_acl(struct inode *inode, int type); |
196 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); | 194 | int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); |
197 | int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); | 195 | int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); |
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index c35619195385..45a2eb0b4693 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c | |||
@@ -1018,21 +1018,13 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, | |||
1018 | 1018 | ||
1019 | posix_acl_release(acl); | 1019 | posix_acl_release(acl); |
1020 | 1020 | ||
1021 | return ovl_setxattr(dentry, inode, handler->name, value, size, flags); | 1021 | return ovl_xattr_set(dentry, handler->name, value, size, flags); |
1022 | 1022 | ||
1023 | out_acl_release: | 1023 | out_acl_release: |
1024 | posix_acl_release(acl); | 1024 | posix_acl_release(acl); |
1025 | return err; | 1025 | return err; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | static int ovl_other_xattr_set(const struct xattr_handler *handler, | ||
1029 | struct dentry *dentry, struct inode *inode, | ||
1030 | const char *name, const void *value, | ||
1031 | size_t size, int flags) | ||
1032 | { | ||
1033 | return ovl_setxattr(dentry, inode, name, value, size, flags); | ||
1034 | } | ||
1035 | |||
1036 | static int ovl_own_xattr_set(const struct xattr_handler *handler, | 1028 | static int ovl_own_xattr_set(const struct xattr_handler *handler, |
1037 | struct dentry *dentry, struct inode *inode, | 1029 | struct dentry *dentry, struct inode *inode, |
1038 | const char *name, const void *value, | 1030 | const char *name, const void *value, |
@@ -1041,6 +1033,14 @@ static int ovl_own_xattr_set(const struct xattr_handler *handler, | |||
1041 | return -EPERM; | 1033 | return -EPERM; |
1042 | } | 1034 | } |
1043 | 1035 | ||
1036 | static int ovl_other_xattr_set(const struct xattr_handler *handler, | ||
1037 | struct dentry *dentry, struct inode *inode, | ||
1038 | const char *name, const void *value, | ||
1039 | size_t size, int flags) | ||
1040 | { | ||
1041 | return ovl_xattr_set(dentry, name, value, size, flags); | ||
1042 | } | ||
1043 | |||
1044 | static const struct xattr_handler __maybe_unused | 1044 | static const struct xattr_handler __maybe_unused |
1045 | ovl_posix_acl_access_xattr_handler = { | 1045 | ovl_posix_acl_access_xattr_handler = { |
1046 | .name = XATTR_NAME_POSIX_ACL_ACCESS, | 1046 | .name = XATTR_NAME_POSIX_ACL_ACCESS, |