aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xattr.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers3@gmail.com>2014-10-12 12:59:58 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-12 17:09:10 -0400
commit8cc431165d8fbda43634dd15ab17f76a151c39a8 (patch)
tree9f75709e432ec0beed0923e935b3d63d45b4b3e7 /fs/xattr.c
parent50b220bbe7092bbfe4406adfe3a216337a64655d (diff)
vfs: Deduplicate code shared by xattr system calls operating on paths
The following pairs of system calls dealing with extended attributes only differ in their behavior on whether the symbolic link is followed (when the named file is a symbolic link): - setxattr() and lsetxattr() - getxattr() and lgetxattr() - listxattr() and llistxattr() - removexattr() and lremovexattr() Despite this, the implementations all had duplicated code, so this commit redirects each of the above pairs of system calls to a corresponding function to which different lookup flags (LOOKUP_FOLLOW or 0) are passed. For me this reduced the stripped size of xattr.o from 8824 to 8248 bytes. Signed-off-by: Eric Biggers <ebiggers3@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/xattr.c')
-rw-r--r--fs/xattr.c116
1 files changed, 39 insertions, 77 deletions
diff --git a/fs/xattr.c b/fs/xattr.c
index c69e6d43a0d2..64e83efb742d 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -364,13 +364,12 @@ out:
364 return error; 364 return error;
365} 365}
366 366
367SYSCALL_DEFINE5(setxattr, const char __user *, pathname, 367static int path_setxattr(const char __user *pathname,
368 const char __user *, name, const void __user *, value, 368 const char __user *name, const void __user *value,
369 size_t, size, int, flags) 369 size_t size, int flags, unsigned int lookup_flags)
370{ 370{
371 struct path path; 371 struct path path;
372 int error; 372 int error;
373 unsigned int lookup_flags = LOOKUP_FOLLOW;
374retry: 373retry:
375 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 374 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
376 if (error) 375 if (error)
@@ -388,28 +387,18 @@ retry:
388 return error; 387 return error;
389} 388}
390 389
390SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
391 const char __user *, name, const void __user *, value,
392 size_t, size, int, flags)
393{
394 return path_setxattr(pathname, name, value, size, flags, LOOKUP_FOLLOW);
395}
396
391SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, 397SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
392 const char __user *, name, const void __user *, value, 398 const char __user *, name, const void __user *, value,
393 size_t, size, int, flags) 399 size_t, size, int, flags)
394{ 400{
395 struct path path; 401 return path_setxattr(pathname, name, value, size, flags, 0);
396 int error;
397 unsigned int lookup_flags = 0;
398retry:
399 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
400 if (error)
401 return error;
402 error = mnt_want_write(path.mnt);
403 if (!error) {
404 error = setxattr(path.dentry, name, value, size, flags);
405 mnt_drop_write(path.mnt);
406 }
407 path_put(&path);
408 if (retry_estale(error, lookup_flags)) {
409 lookup_flags |= LOOKUP_REVAL;
410 goto retry;
411 }
412 return error;
413} 402}
414 403
415SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, 404SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
@@ -481,12 +470,12 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
481 return error; 470 return error;
482} 471}
483 472
484SYSCALL_DEFINE4(getxattr, const char __user *, pathname, 473static ssize_t path_getxattr(const char __user *pathname,
485 const char __user *, name, void __user *, value, size_t, size) 474 const char __user *name, void __user *value,
475 size_t size, unsigned int lookup_flags)
486{ 476{
487 struct path path; 477 struct path path;
488 ssize_t error; 478 ssize_t error;
489 unsigned int lookup_flags = LOOKUP_FOLLOW;
490retry: 479retry:
491 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 480 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
492 if (error) 481 if (error)
@@ -500,23 +489,16 @@ retry:
500 return error; 489 return error;
501} 490}
502 491
492SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
493 const char __user *, name, void __user *, value, size_t, size)
494{
495 return path_getxattr(pathname, name, value, size, LOOKUP_FOLLOW);
496}
497
503SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, 498SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
504 const char __user *, name, void __user *, value, size_t, size) 499 const char __user *, name, void __user *, value, size_t, size)
505{ 500{
506 struct path path; 501 return path_getxattr(pathname, name, value, size, 0);
507 ssize_t error;
508 unsigned int lookup_flags = 0;
509retry:
510 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
511 if (error)
512 return error;
513 error = getxattr(path.dentry, name, value, size);
514 path_put(&path);
515 if (retry_estale(error, lookup_flags)) {
516 lookup_flags |= LOOKUP_REVAL;
517 goto retry;
518 }
519 return error;
520} 502}
521 503
522SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, 504SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
@@ -571,12 +553,11 @@ listxattr(struct dentry *d, char __user *list, size_t size)
571 return error; 553 return error;
572} 554}
573 555
574SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, 556static ssize_t path_listxattr(const char __user *pathname, char __user *list,
575 size_t, size) 557 size_t size, unsigned int lookup_flags)
576{ 558{
577 struct path path; 559 struct path path;
578 ssize_t error; 560 ssize_t error;
579 unsigned int lookup_flags = LOOKUP_FOLLOW;
580retry: 561retry:
581 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 562 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
582 if (error) 563 if (error)
@@ -590,23 +571,16 @@ retry:
590 return error; 571 return error;
591} 572}
592 573
574SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
575 size_t, size)
576{
577 return path_listxattr(pathname, list, size, LOOKUP_FOLLOW);
578}
579
593SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, 580SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
594 size_t, size) 581 size_t, size)
595{ 582{
596 struct path path; 583 return path_listxattr(pathname, list, size, 0);
597 ssize_t error;
598 unsigned int lookup_flags = 0;
599retry:
600 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
601 if (error)
602 return error;
603 error = listxattr(path.dentry, list, size);
604 path_put(&path);
605 if (retry_estale(error, lookup_flags)) {
606 lookup_flags |= LOOKUP_REVAL;
607 goto retry;
608 }
609 return error;
610} 584}
611 585
612SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) 586SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
@@ -640,12 +614,11 @@ removexattr(struct dentry *d, const char __user *name)
640 return vfs_removexattr(d, kname); 614 return vfs_removexattr(d, kname);
641} 615}
642 616
643SYSCALL_DEFINE2(removexattr, const char __user *, pathname, 617static int path_removexattr(const char __user *pathname,
644 const char __user *, name) 618 const char __user *name, unsigned int lookup_flags)
645{ 619{
646 struct path path; 620 struct path path;
647 int error; 621 int error;
648 unsigned int lookup_flags = LOOKUP_FOLLOW;
649retry: 622retry:
650 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 623 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
651 if (error) 624 if (error)
@@ -663,27 +636,16 @@ retry:
663 return error; 636 return error;
664} 637}
665 638
639SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
640 const char __user *, name)
641{
642 return path_removexattr(pathname, name, LOOKUP_FOLLOW);
643}
644
666SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, 645SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
667 const char __user *, name) 646 const char __user *, name)
668{ 647{
669 struct path path; 648 return path_removexattr(pathname, name, 0);
670 int error;
671 unsigned int lookup_flags = 0;
672retry:
673 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
674 if (error)
675 return error;
676 error = mnt_want_write(path.mnt);
677 if (!error) {
678 error = removexattr(path.dentry, name);
679 mnt_drop_write(path.mnt);
680 }
681 path_put(&path);
682 if (retry_estale(error, lookup_flags)) {
683 lookup_flags |= LOOKUP_REVAL;
684 goto retry;
685 }
686 return error;
687} 649}
688 650
689SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) 651SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)