Skip to content

Commit 8cc4311

Browse files
ebiggersAl Viro
authored andcommitted
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 <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 50b220b commit 8cc4311

File tree

1 file changed

+39
-77
lines changed

1 file changed

+39
-77
lines changed

fs/xattr.c

Lines changed: 39 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,12 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
364364
return error;
365365
}
366366

367-
SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
368-
const char __user *, name, const void __user *, value,
369-
size_t, size, int, flags)
367+
static int path_setxattr(const char __user *pathname,
368+
const char __user *name, const void __user *value,
369+
size_t size, int flags, unsigned int lookup_flags)
370370
{
371371
struct path path;
372372
int error;
373-
unsigned int lookup_flags = LOOKUP_FOLLOW;
374373
retry:
375374
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
376375
if (error)
@@ -388,28 +387,18 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
388387
return error;
389388
}
390389

390+
SYSCALL_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+
391397
SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
392398
const char __user *, name, const void __user *, value,
393399
size_t, size, int, flags)
394400
{
395-
struct path path;
396-
int error;
397-
unsigned int lookup_flags = 0;
398-
retry:
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;
401+
return path_setxattr(pathname, name, value, size, flags, 0);
413402
}
414403

415404
SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
@@ -481,12 +470,12 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
481470
return error;
482471
}
483472

484-
SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
485-
const char __user *, name, void __user *, value, size_t, size)
473+
static ssize_t path_getxattr(const char __user *pathname,
474+
const char __user *name, void __user *value,
475+
size_t size, unsigned int lookup_flags)
486476
{
487477
struct path path;
488478
ssize_t error;
489-
unsigned int lookup_flags = LOOKUP_FOLLOW;
490479
retry:
491480
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
492481
if (error)
@@ -500,23 +489,16 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
500489
return error;
501490
}
502491

492+
SYSCALL_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+
503498
SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
504499
const char __user *, name, void __user *, value, size_t, size)
505500
{
506-
struct path path;
507-
ssize_t error;
508-
unsigned int lookup_flags = 0;
509-
retry:
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;
501+
return path_getxattr(pathname, name, value, size, 0);
520502
}
521503

522504
SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
@@ -571,12 +553,11 @@ listxattr(struct dentry *d, char __user *list, size_t size)
571553
return error;
572554
}
573555

574-
SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
575-
size_t, size)
556+
static ssize_t path_listxattr(const char __user *pathname, char __user *list,
557+
size_t size, unsigned int lookup_flags)
576558
{
577559
struct path path;
578560
ssize_t error;
579-
unsigned int lookup_flags = LOOKUP_FOLLOW;
580561
retry:
581562
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
582563
if (error)
@@ -590,23 +571,16 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
590571
return error;
591572
}
592573

574+
SYSCALL_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+
593580
SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
594581
size_t, size)
595582
{
596-
struct path path;
597-
ssize_t error;
598-
unsigned int lookup_flags = 0;
599-
retry:
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;
583+
return path_listxattr(pathname, list, size, 0);
610584
}
611585

612586
SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
@@ -640,12 +614,11 @@ removexattr(struct dentry *d, const char __user *name)
640614
return vfs_removexattr(d, kname);
641615
}
642616

643-
SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
644-
const char __user *, name)
617+
static int path_removexattr(const char __user *pathname,
618+
const char __user *name, unsigned int lookup_flags)
645619
{
646620
struct path path;
647621
int error;
648-
unsigned int lookup_flags = LOOKUP_FOLLOW;
649622
retry:
650623
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
651624
if (error)
@@ -663,27 +636,16 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
663636
return error;
664637
}
665638

639+
SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
640+
const char __user *, name)
641+
{
642+
return path_removexattr(pathname, name, LOOKUP_FOLLOW);
643+
}
644+
666645
SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
667646
const char __user *, name)
668647
{
669-
struct path path;
670-
int error;
671-
unsigned int lookup_flags = 0;
672-
retry:
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;
648+
return path_removexattr(pathname, name, 0);
687649
}
688650

689651
SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)

0 commit comments

Comments
 (0)