diff options
Diffstat (limited to 'fs/xattr.c')
-rw-r--r-- | fs/xattr.c | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index e21c119f4f99..3377dff18404 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -370,8 +370,9 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | |||
370 | { | 370 | { |
371 | struct path path; | 371 | struct path path; |
372 | int error; | 372 | int error; |
373 | 373 | unsigned int lookup_flags = LOOKUP_FOLLOW; | |
374 | error = user_path(pathname, &path); | 374 | retry: |
375 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
375 | if (error) | 376 | if (error) |
376 | return error; | 377 | return error; |
377 | error = mnt_want_write(path.mnt); | 378 | error = mnt_want_write(path.mnt); |
@@ -380,6 +381,10 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname, | |||
380 | mnt_drop_write(path.mnt); | 381 | mnt_drop_write(path.mnt); |
381 | } | 382 | } |
382 | path_put(&path); | 383 | path_put(&path); |
384 | if (retry_estale(error, lookup_flags)) { | ||
385 | lookup_flags |= LOOKUP_REVAL; | ||
386 | goto retry; | ||
387 | } | ||
383 | return error; | 388 | return error; |
384 | } | 389 | } |
385 | 390 | ||
@@ -389,8 +394,9 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | |||
389 | { | 394 | { |
390 | struct path path; | 395 | struct path path; |
391 | int error; | 396 | int error; |
392 | 397 | unsigned int lookup_flags = 0; | |
393 | error = user_lpath(pathname, &path); | 398 | retry: |
399 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
394 | if (error) | 400 | if (error) |
395 | return error; | 401 | return error; |
396 | error = mnt_want_write(path.mnt); | 402 | error = mnt_want_write(path.mnt); |
@@ -399,6 +405,10 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, | |||
399 | mnt_drop_write(path.mnt); | 405 | mnt_drop_write(path.mnt); |
400 | } | 406 | } |
401 | path_put(&path); | 407 | path_put(&path); |
408 | if (retry_estale(error, lookup_flags)) { | ||
409 | lookup_flags |= LOOKUP_REVAL; | ||
410 | goto retry; | ||
411 | } | ||
402 | return error; | 412 | return error; |
403 | } | 413 | } |
404 | 414 | ||
@@ -476,12 +486,17 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname, | |||
476 | { | 486 | { |
477 | struct path path; | 487 | struct path path; |
478 | ssize_t error; | 488 | ssize_t error; |
479 | 489 | unsigned int lookup_flags = LOOKUP_FOLLOW; | |
480 | error = user_path(pathname, &path); | 490 | retry: |
491 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
481 | if (error) | 492 | if (error) |
482 | return error; | 493 | return error; |
483 | error = getxattr(path.dentry, name, value, size); | 494 | error = getxattr(path.dentry, name, value, size); |
484 | path_put(&path); | 495 | path_put(&path); |
496 | if (retry_estale(error, lookup_flags)) { | ||
497 | lookup_flags |= LOOKUP_REVAL; | ||
498 | goto retry; | ||
499 | } | ||
485 | return error; | 500 | return error; |
486 | } | 501 | } |
487 | 502 | ||
@@ -490,12 +505,17 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, | |||
490 | { | 505 | { |
491 | struct path path; | 506 | struct path path; |
492 | ssize_t error; | 507 | ssize_t error; |
493 | 508 | unsigned int lookup_flags = 0; | |
494 | error = user_lpath(pathname, &path); | 509 | retry: |
510 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
495 | if (error) | 511 | if (error) |
496 | return error; | 512 | return error; |
497 | error = getxattr(path.dentry, name, value, size); | 513 | error = getxattr(path.dentry, name, value, size); |
498 | path_put(&path); | 514 | path_put(&path); |
515 | if (retry_estale(error, lookup_flags)) { | ||
516 | lookup_flags |= LOOKUP_REVAL; | ||
517 | goto retry; | ||
518 | } | ||
499 | return error; | 519 | return error; |
500 | } | 520 | } |
501 | 521 | ||
@@ -556,12 +576,17 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, | |||
556 | { | 576 | { |
557 | struct path path; | 577 | struct path path; |
558 | ssize_t error; | 578 | ssize_t error; |
559 | 579 | unsigned int lookup_flags = LOOKUP_FOLLOW; | |
560 | error = user_path(pathname, &path); | 580 | retry: |
581 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
561 | if (error) | 582 | if (error) |
562 | return error; | 583 | return error; |
563 | error = listxattr(path.dentry, list, size); | 584 | error = listxattr(path.dentry, list, size); |
564 | path_put(&path); | 585 | path_put(&path); |
586 | if (retry_estale(error, lookup_flags)) { | ||
587 | lookup_flags |= LOOKUP_REVAL; | ||
588 | goto retry; | ||
589 | } | ||
565 | return error; | 590 | return error; |
566 | } | 591 | } |
567 | 592 | ||
@@ -570,12 +595,17 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, | |||
570 | { | 595 | { |
571 | struct path path; | 596 | struct path path; |
572 | ssize_t error; | 597 | ssize_t error; |
573 | 598 | unsigned int lookup_flags = 0; | |
574 | error = user_lpath(pathname, &path); | 599 | retry: |
600 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
575 | if (error) | 601 | if (error) |
576 | return error; | 602 | return error; |
577 | error = listxattr(path.dentry, list, size); | 603 | error = listxattr(path.dentry, list, size); |
578 | path_put(&path); | 604 | path_put(&path); |
605 | if (retry_estale(error, lookup_flags)) { | ||
606 | lookup_flags |= LOOKUP_REVAL; | ||
607 | goto retry; | ||
608 | } | ||
579 | return error; | 609 | return error; |
580 | } | 610 | } |
581 | 611 | ||
@@ -615,8 +645,9 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | |||
615 | { | 645 | { |
616 | struct path path; | 646 | struct path path; |
617 | int error; | 647 | int error; |
618 | 648 | unsigned int lookup_flags = LOOKUP_FOLLOW; | |
619 | error = user_path(pathname, &path); | 649 | retry: |
650 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
620 | if (error) | 651 | if (error) |
621 | return error; | 652 | return error; |
622 | error = mnt_want_write(path.mnt); | 653 | error = mnt_want_write(path.mnt); |
@@ -625,6 +656,10 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname, | |||
625 | mnt_drop_write(path.mnt); | 656 | mnt_drop_write(path.mnt); |
626 | } | 657 | } |
627 | path_put(&path); | 658 | path_put(&path); |
659 | if (retry_estale(error, lookup_flags)) { | ||
660 | lookup_flags |= LOOKUP_REVAL; | ||
661 | goto retry; | ||
662 | } | ||
628 | return error; | 663 | return error; |
629 | } | 664 | } |
630 | 665 | ||
@@ -633,8 +668,9 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | |||
633 | { | 668 | { |
634 | struct path path; | 669 | struct path path; |
635 | int error; | 670 | int error; |
636 | 671 | unsigned int lookup_flags = 0; | |
637 | error = user_lpath(pathname, &path); | 672 | retry: |
673 | error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); | ||
638 | if (error) | 674 | if (error) |
639 | return error; | 675 | return error; |
640 | error = mnt_want_write(path.mnt); | 676 | error = mnt_want_write(path.mnt); |
@@ -643,6 +679,10 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, | |||
643 | mnt_drop_write(path.mnt); | 679 | mnt_drop_write(path.mnt); |
644 | } | 680 | } |
645 | path_put(&path); | 681 | path_put(&path); |
682 | if (retry_estale(error, lookup_flags)) { | ||
683 | lookup_flags |= LOOKUP_REVAL; | ||
684 | goto retry; | ||
685 | } | ||
646 | return error; | 686 | return error; |
647 | } | 687 | } |
648 | 688 | ||