aboutsummaryrefslogtreecommitdiffstats
path: root/fs/overlayfs
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-08-22 11:22:11 -0400
committerMiklos Szeredi <mszeredi@redhat.com>2016-09-01 05:12:00 -0400
commit0e585ccc13b3edbb187fb4f1b7cc9397f17d64a9 (patch)
tree092d1da4ee6fb40592629de0dde82942e4dde0f6 /fs/overlayfs
parent0c97be22f928b85110504c4bbb8574facb4bd0c0 (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.c2
-rw-r--r--fs/overlayfs/inode.c65
-rw-r--r--fs/overlayfs/overlayfs.h6
-rw-r--r--fs/overlayfs/super.c18
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
201int ovl_setxattr(struct dentry *dentry, struct inode *inode, 201int 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
222out_drop_write: 235out_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
275int 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);
305out_drop_write:
306 ovl_drop_write(dentry);
307out:
308 return err;
309}
310
311struct posix_acl *ovl_get_acl(struct inode *inode, int type) 288struct 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 */
186int ovl_setattr(struct dentry *dentry, struct iattr *attr); 186int ovl_setattr(struct dentry *dentry, struct iattr *attr);
187int ovl_permission(struct inode *inode, int mask); 187int ovl_permission(struct inode *inode, int mask);
188int ovl_setxattr(struct dentry *dentry, struct inode *inode, 188int 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);
191ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, 190ssize_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);
193ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); 192ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
194int ovl_removexattr(struct dentry *dentry, const char *name);
195struct posix_acl *ovl_get_acl(struct inode *inode, int type); 193struct posix_acl *ovl_get_acl(struct inode *inode, int type);
196int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); 194int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags);
197int ovl_update_time(struct inode *inode, struct timespec *ts, int flags); 195int 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
1023out_acl_release: 1023out_acl_release:
1024 posix_acl_release(acl); 1024 posix_acl_release(acl);
1025 return err; 1025 return err;
1026} 1026}
1027 1027
1028static 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
1036static int ovl_own_xattr_set(const struct xattr_handler *handler, 1028static 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
1036static 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
1044static const struct xattr_handler __maybe_unused 1044static const struct xattr_handler __maybe_unused
1045ovl_posix_acl_access_xattr_handler = { 1045ovl_posix_acl_access_xattr_handler = {
1046 .name = XATTR_NAME_POSIX_ACL_ACCESS, 1046 .name = XATTR_NAME_POSIX_ACL_ACCESS,