Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ovl: Move xattr support to new xattrs.c file

This moves the code from super.c and inode.c, and makes ovl_xattr_get/set()
static.

This is in preparation for doing more work on xattrs support.

Signed-off-by: Alexander Larsson <alexl@redhat.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>

+207 -196
+1 -1
fs/overlayfs/Makefile
··· 6 6 obj-$(CONFIG_OVERLAY_FS) += overlay.o 7 7 8 8 overlay-objs := super.o namei.o util.o inode.o file.o dir.o readdir.o \ 9 - copy_up.o export.o params.o 9 + copy_up.o export.o params.o xattrs.o
-122
fs/overlayfs/inode.c
··· 339 339 return p; 340 340 } 341 341 342 - bool ovl_is_private_xattr(struct super_block *sb, const char *name) 343 - { 344 - struct ovl_fs *ofs = OVL_FS(sb); 345 - 346 - if (ofs->config.userxattr) 347 - return strncmp(name, OVL_XATTR_USER_PREFIX, 348 - sizeof(OVL_XATTR_USER_PREFIX) - 1) == 0; 349 - else 350 - return strncmp(name, OVL_XATTR_TRUSTED_PREFIX, 351 - sizeof(OVL_XATTR_TRUSTED_PREFIX) - 1) == 0; 352 - } 353 - 354 - int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, 355 - const void *value, size_t size, int flags) 356 - { 357 - int err; 358 - struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 359 - struct dentry *upperdentry = ovl_i_dentry_upper(inode); 360 - struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); 361 - struct path realpath; 362 - const struct cred *old_cred; 363 - 364 - if (!value && !upperdentry) { 365 - ovl_path_lower(dentry, &realpath); 366 - old_cred = ovl_override_creds(dentry->d_sb); 367 - err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); 368 - revert_creds(old_cred); 369 - if (err < 0) 370 - goto out; 371 - } 372 - 373 - if (!upperdentry) { 374 - err = ovl_copy_up(dentry); 375 - if (err) 376 - goto out; 377 - 378 - realdentry = ovl_dentry_upper(dentry); 379 - } 380 - 381 - err = ovl_want_write(dentry); 382 - if (err) 383 - goto out; 384 - 385 - old_cred = ovl_override_creds(dentry->d_sb); 386 - if (value) { 387 - err = ovl_do_setxattr(ofs, realdentry, name, value, size, 388 - flags); 389 - } else { 390 - WARN_ON(flags != XATTR_REPLACE); 391 - err = ovl_do_removexattr(ofs, realdentry, name); 392 - } 393 - revert_creds(old_cred); 394 - ovl_drop_write(dentry); 395 - 396 - /* copy c/mtime */ 397 - ovl_copyattr(inode); 398 - out: 399 - return err; 400 - } 401 - 402 - int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, 403 - void *value, size_t size) 404 - { 405 - ssize_t res; 406 - const struct cred *old_cred; 407 - struct path realpath; 408 - 409 - ovl_i_path_real(inode, &realpath); 410 - old_cred = ovl_override_creds(dentry->d_sb); 411 - res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); 412 - revert_creds(old_cred); 413 - return res; 414 - } 415 - 416 - static bool ovl_can_list(struct super_block *sb, const char *s) 417 - { 418 - /* Never list private (.overlay) */ 419 - if (ovl_is_private_xattr(sb, s)) 420 - return false; 421 - 422 - /* List all non-trusted xattrs */ 423 - if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) 424 - return true; 425 - 426 - /* list other trusted for superuser only */ 427 - return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN); 428 - } 429 - 430 - ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 431 - { 432 - struct dentry *realdentry = ovl_dentry_real(dentry); 433 - ssize_t res; 434 - size_t len; 435 - char *s; 436 - const struct cred *old_cred; 437 - 438 - old_cred = ovl_override_creds(dentry->d_sb); 439 - res = vfs_listxattr(realdentry, list, size); 440 - revert_creds(old_cred); 441 - if (res <= 0 || size == 0) 442 - return res; 443 - 444 - /* filter out private xattrs */ 445 - for (s = list, len = res; len;) { 446 - size_t slen = strnlen(s, len) + 1; 447 - 448 - /* underlying fs providing us with an broken xattr list? */ 449 - if (WARN_ON(slen > len)) 450 - return -EIO; 451 - 452 - len -= slen; 453 - if (!ovl_can_list(dentry->d_sb, s)) { 454 - res -= slen; 455 - memmove(s, s + slen, len); 456 - } else { 457 - s += slen; 458 - } 459 - } 460 - 461 - return res; 462 - } 463 - 464 342 #ifdef CONFIG_FS_POSIX_ACL 465 343 /* 466 344 * Apply the idmapping of the layer to POSIX ACLs. The caller must pass a clone
+9 -9
fs/overlayfs/overlayfs.h
··· 699 699 unsigned int ovl_get_nlink(struct ovl_fs *ofs, struct dentry *lowerdentry, 700 700 struct dentry *upperdentry, 701 701 unsigned int fallback); 702 - int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 703 - struct iattr *attr); 704 - int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, 705 - struct kstat *stat, u32 request_mask, unsigned int flags); 706 702 int ovl_permission(struct mnt_idmap *idmap, struct inode *inode, 707 703 int mask); 708 - int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, 709 - const void *value, size_t size, int flags); 710 - int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, 711 - void *value, size_t size); 712 - ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); 713 704 714 705 #ifdef CONFIG_FS_POSIX_ACL 715 706 struct posix_acl *do_ovl_get_acl(struct mnt_idmap *idmap, ··· 837 846 { 838 847 return (!ovl_upper_mnt(ofs) || !ofs->workdir); 839 848 } 849 + 850 + /* xattr.c */ 851 + 852 + const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs); 853 + int ovl_setattr(struct mnt_idmap *idmap, struct dentry *dentry, 854 + struct iattr *attr); 855 + int ovl_getattr(struct mnt_idmap *idmap, const struct path *path, 856 + struct kstat *stat, u32 request_mask, unsigned int flags); 857 + ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
+1 -64
fs/overlayfs/super.c
··· 445 445 return ok; 446 446 } 447 447 448 - static int ovl_own_xattr_get(const struct xattr_handler *handler, 449 - struct dentry *dentry, struct inode *inode, 450 - const char *name, void *buffer, size_t size) 451 - { 452 - return -EOPNOTSUPP; 453 - } 454 - 455 - static int ovl_own_xattr_set(const struct xattr_handler *handler, 456 - struct mnt_idmap *idmap, 457 - struct dentry *dentry, struct inode *inode, 458 - const char *name, const void *value, 459 - size_t size, int flags) 460 - { 461 - return -EOPNOTSUPP; 462 - } 463 - 464 - static int ovl_other_xattr_get(const struct xattr_handler *handler, 465 - struct dentry *dentry, struct inode *inode, 466 - const char *name, void *buffer, size_t size) 467 - { 468 - return ovl_xattr_get(dentry, inode, name, buffer, size); 469 - } 470 - 471 - static int ovl_other_xattr_set(const struct xattr_handler *handler, 472 - struct mnt_idmap *idmap, 473 - struct dentry *dentry, struct inode *inode, 474 - const char *name, const void *value, 475 - size_t size, int flags) 476 - { 477 - return ovl_xattr_set(dentry, inode, name, value, size, flags); 478 - } 479 - 480 - static const struct xattr_handler ovl_own_trusted_xattr_handler = { 481 - .prefix = OVL_XATTR_TRUSTED_PREFIX, 482 - .get = ovl_own_xattr_get, 483 - .set = ovl_own_xattr_set, 484 - }; 485 - 486 - static const struct xattr_handler ovl_own_user_xattr_handler = { 487 - .prefix = OVL_XATTR_USER_PREFIX, 488 - .get = ovl_own_xattr_get, 489 - .set = ovl_own_xattr_set, 490 - }; 491 - 492 - static const struct xattr_handler ovl_other_xattr_handler = { 493 - .prefix = "", /* catch all */ 494 - .get = ovl_other_xattr_get, 495 - .set = ovl_other_xattr_set, 496 - }; 497 - 498 - static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = { 499 - &ovl_own_trusted_xattr_handler, 500 - &ovl_other_xattr_handler, 501 - NULL 502 - }; 503 - 504 - static const struct xattr_handler * const ovl_user_xattr_handlers[] = { 505 - &ovl_own_user_xattr_handler, 506 - &ovl_other_xattr_handler, 507 - NULL 508 - }; 509 - 510 448 static int ovl_setup_trap(struct super_block *sb, struct dentry *dir, 511 449 struct inode **ptrap, const char *name) 512 450 { ··· 1439 1501 cap_lower(cred->cap_effective, CAP_SYS_RESOURCE); 1440 1502 1441 1503 sb->s_magic = OVERLAYFS_SUPER_MAGIC; 1442 - sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers : 1443 - ovl_trusted_xattr_handlers; 1504 + sb->s_xattr = ovl_xattr_handlers(ofs); 1444 1505 sb->s_fs_info = ofs; 1445 1506 #ifdef CONFIG_FS_POSIX_ACL 1446 1507 sb->s_flags |= SB_POSIXACL;
+196
fs/overlayfs/xattrs.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/fs.h> 4 + #include <linux/xattr.h> 5 + #include "overlayfs.h" 6 + 7 + bool ovl_is_private_xattr(struct super_block *sb, const char *name) 8 + { 9 + struct ovl_fs *ofs = OVL_FS(sb); 10 + 11 + if (ofs->config.userxattr) 12 + return strncmp(name, OVL_XATTR_USER_PREFIX, 13 + sizeof(OVL_XATTR_USER_PREFIX) - 1) == 0; 14 + else 15 + return strncmp(name, OVL_XATTR_TRUSTED_PREFIX, 16 + sizeof(OVL_XATTR_TRUSTED_PREFIX) - 1) == 0; 17 + } 18 + 19 + static int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, 20 + const void *value, size_t size, int flags) 21 + { 22 + int err; 23 + struct ovl_fs *ofs = OVL_FS(dentry->d_sb); 24 + struct dentry *upperdentry = ovl_i_dentry_upper(inode); 25 + struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); 26 + struct path realpath; 27 + const struct cred *old_cred; 28 + 29 + if (!value && !upperdentry) { 30 + ovl_path_lower(dentry, &realpath); 31 + old_cred = ovl_override_creds(dentry->d_sb); 32 + err = vfs_getxattr(mnt_idmap(realpath.mnt), realdentry, name, NULL, 0); 33 + revert_creds(old_cred); 34 + if (err < 0) 35 + goto out; 36 + } 37 + 38 + if (!upperdentry) { 39 + err = ovl_copy_up(dentry); 40 + if (err) 41 + goto out; 42 + 43 + realdentry = ovl_dentry_upper(dentry); 44 + } 45 + 46 + err = ovl_want_write(dentry); 47 + if (err) 48 + goto out; 49 + 50 + old_cred = ovl_override_creds(dentry->d_sb); 51 + if (value) { 52 + err = ovl_do_setxattr(ofs, realdentry, name, value, size, 53 + flags); 54 + } else { 55 + WARN_ON(flags != XATTR_REPLACE); 56 + err = ovl_do_removexattr(ofs, realdentry, name); 57 + } 58 + revert_creds(old_cred); 59 + ovl_drop_write(dentry); 60 + 61 + /* copy c/mtime */ 62 + ovl_copyattr(inode); 63 + out: 64 + return err; 65 + } 66 + 67 + static int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, 68 + void *value, size_t size) 69 + { 70 + ssize_t res; 71 + const struct cred *old_cred; 72 + struct path realpath; 73 + 74 + ovl_i_path_real(inode, &realpath); 75 + old_cred = ovl_override_creds(dentry->d_sb); 76 + res = vfs_getxattr(mnt_idmap(realpath.mnt), realpath.dentry, name, value, size); 77 + revert_creds(old_cred); 78 + return res; 79 + } 80 + 81 + static bool ovl_can_list(struct super_block *sb, const char *s) 82 + { 83 + /* Never list private (.overlay) */ 84 + if (ovl_is_private_xattr(sb, s)) 85 + return false; 86 + 87 + /* List all non-trusted xattrs */ 88 + if (strncmp(s, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) 89 + return true; 90 + 91 + /* list other trusted for superuser only */ 92 + return ns_capable_noaudit(&init_user_ns, CAP_SYS_ADMIN); 93 + } 94 + 95 + ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) 96 + { 97 + struct dentry *realdentry = ovl_dentry_real(dentry); 98 + ssize_t res; 99 + size_t len; 100 + char *s; 101 + const struct cred *old_cred; 102 + 103 + old_cred = ovl_override_creds(dentry->d_sb); 104 + res = vfs_listxattr(realdentry, list, size); 105 + revert_creds(old_cred); 106 + if (res <= 0 || size == 0) 107 + return res; 108 + 109 + /* filter out private xattrs */ 110 + for (s = list, len = res; len;) { 111 + size_t slen = strnlen(s, len) + 1; 112 + 113 + /* underlying fs providing us with an broken xattr list? */ 114 + if (WARN_ON(slen > len)) 115 + return -EIO; 116 + 117 + len -= slen; 118 + if (!ovl_can_list(dentry->d_sb, s)) { 119 + res -= slen; 120 + memmove(s, s + slen, len); 121 + } else { 122 + s += slen; 123 + } 124 + } 125 + 126 + return res; 127 + } 128 + 129 + static int ovl_own_xattr_get(const struct xattr_handler *handler, 130 + struct dentry *dentry, struct inode *inode, 131 + const char *name, void *buffer, size_t size) 132 + { 133 + return -EOPNOTSUPP; 134 + } 135 + 136 + static int ovl_own_xattr_set(const struct xattr_handler *handler, 137 + struct mnt_idmap *idmap, 138 + struct dentry *dentry, struct inode *inode, 139 + const char *name, const void *value, 140 + size_t size, int flags) 141 + { 142 + return -EOPNOTSUPP; 143 + } 144 + 145 + static int ovl_other_xattr_get(const struct xattr_handler *handler, 146 + struct dentry *dentry, struct inode *inode, 147 + const char *name, void *buffer, size_t size) 148 + { 149 + return ovl_xattr_get(dentry, inode, name, buffer, size); 150 + } 151 + 152 + static int ovl_other_xattr_set(const struct xattr_handler *handler, 153 + struct mnt_idmap *idmap, 154 + struct dentry *dentry, struct inode *inode, 155 + const char *name, const void *value, 156 + size_t size, int flags) 157 + { 158 + return ovl_xattr_set(dentry, inode, name, value, size, flags); 159 + } 160 + 161 + static const struct xattr_handler ovl_own_trusted_xattr_handler = { 162 + .prefix = OVL_XATTR_TRUSTED_PREFIX, 163 + .get = ovl_own_xattr_get, 164 + .set = ovl_own_xattr_set, 165 + }; 166 + 167 + static const struct xattr_handler ovl_own_user_xattr_handler = { 168 + .prefix = OVL_XATTR_USER_PREFIX, 169 + .get = ovl_own_xattr_get, 170 + .set = ovl_own_xattr_set, 171 + }; 172 + 173 + static const struct xattr_handler ovl_other_xattr_handler = { 174 + .prefix = "", /* catch all */ 175 + .get = ovl_other_xattr_get, 176 + .set = ovl_other_xattr_set, 177 + }; 178 + 179 + static const struct xattr_handler * const ovl_trusted_xattr_handlers[] = { 180 + &ovl_own_trusted_xattr_handler, 181 + &ovl_other_xattr_handler, 182 + NULL 183 + }; 184 + 185 + static const struct xattr_handler * const ovl_user_xattr_handlers[] = { 186 + &ovl_own_user_xattr_handler, 187 + &ovl_other_xattr_handler, 188 + NULL 189 + }; 190 + 191 + const struct xattr_handler * const *ovl_xattr_handlers(struct ovl_fs *ofs) 192 + { 193 + return ofs->config.userxattr ? ovl_user_xattr_handlers : 194 + ovl_trusted_xattr_handlers; 195 + } 196 +