diff options
author | Jan Blunck <jblunck@suse.de> | 2008-02-14 22:34:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-15 00:13:33 -0500 |
commit | 4ac9137858e08a19f29feac4e1f4df7c268b0ba5 (patch) | |
tree | f5b5d84fd12fcc2b0ba0e7ce1a79ff381ad8f5dd /fs/namei.c | |
parent | c5e725f33b733a77de622e91b6ba5645fcf070be (diff) |
Embed a struct path into struct nameidata instead of nd->{dentry,mnt}
This is the central patch of a cleanup series. In most cases there is no good
reason why someone would want to use a dentry for itself. This series reflects
that fact and embeds a struct path into nameidata.
Together with the other patches of this series
- it enforced the correct order of getting/releasing the reference count on
<dentry,vfsmount> pairs
- it prepares the VFS for stacking support since it is essential to have a
struct path in every place where the stack can be traversed
- it reduces the overall code size:
without patch series:
text data bss dec hex filename
5321639 858418 715768 6895825 6938d1 vmlinux
with patch series:
text data bss dec hex filename
5320026 858418 715768 6894212 693284 vmlinux
This patch:
Switch from nd->{dentry,mnt} to nd->path.{dentry,mnt} everywhere.
[akpm@linux-foundation.org: coding-style fixes]
[akpm@linux-foundation.org: fix cifs]
[akpm@linux-foundation.org: fix smack]
Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Acked-by: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 220 |
1 files changed, 112 insertions, 108 deletions
diff --git a/fs/namei.c b/fs/namei.c index 3ed4d7576d6d..c9b05a71c39c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -231,7 +231,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
231 | struct vfsmount *mnt = NULL; | 231 | struct vfsmount *mnt = NULL; |
232 | 232 | ||
233 | if (nd) | 233 | if (nd) |
234 | mnt = nd->mnt; | 234 | mnt = nd->path.mnt; |
235 | 235 | ||
236 | if (mask & MAY_WRITE) { | 236 | if (mask & MAY_WRITE) { |
237 | umode_t mode = inode->i_mode; | 237 | umode_t mode = inode->i_mode; |
@@ -296,7 +296,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
296 | */ | 296 | */ |
297 | int vfs_permission(struct nameidata *nd, int mask) | 297 | int vfs_permission(struct nameidata *nd, int mask) |
298 | { | 298 | { |
299 | return permission(nd->dentry->d_inode, mask, nd); | 299 | return permission(nd->path.dentry->d_inode, mask, nd); |
300 | } | 300 | } |
301 | 301 | ||
302 | /** | 302 | /** |
@@ -364,8 +364,8 @@ int deny_write_access(struct file * file) | |||
364 | 364 | ||
365 | void path_release(struct nameidata *nd) | 365 | void path_release(struct nameidata *nd) |
366 | { | 366 | { |
367 | dput(nd->dentry); | 367 | dput(nd->path.dentry); |
368 | mntput(nd->mnt); | 368 | mntput(nd->path.mnt); |
369 | } | 369 | } |
370 | 370 | ||
371 | /** | 371 | /** |
@@ -530,15 +530,15 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
530 | 530 | ||
531 | read_lock(&fs->lock); | 531 | read_lock(&fs->lock); |
532 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 532 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
533 | nd->mnt = mntget(fs->altrootmnt); | 533 | nd->path.mnt = mntget(fs->altrootmnt); |
534 | nd->dentry = dget(fs->altroot); | 534 | nd->path.dentry = dget(fs->altroot); |
535 | read_unlock(&fs->lock); | 535 | read_unlock(&fs->lock); |
536 | if (__emul_lookup_dentry(name,nd)) | 536 | if (__emul_lookup_dentry(name,nd)) |
537 | return 0; | 537 | return 0; |
538 | read_lock(&fs->lock); | 538 | read_lock(&fs->lock); |
539 | } | 539 | } |
540 | nd->mnt = mntget(fs->rootmnt); | 540 | nd->path.mnt = mntget(fs->rootmnt); |
541 | nd->dentry = dget(fs->root); | 541 | nd->path.dentry = dget(fs->root); |
542 | read_unlock(&fs->lock); | 542 | read_unlock(&fs->lock); |
543 | return 1; | 543 | return 1; |
544 | } | 544 | } |
@@ -581,17 +581,17 @@ fail: | |||
581 | static inline void dput_path(struct path *path, struct nameidata *nd) | 581 | static inline void dput_path(struct path *path, struct nameidata *nd) |
582 | { | 582 | { |
583 | dput(path->dentry); | 583 | dput(path->dentry); |
584 | if (path->mnt != nd->mnt) | 584 | if (path->mnt != nd->path.mnt) |
585 | mntput(path->mnt); | 585 | mntput(path->mnt); |
586 | } | 586 | } |
587 | 587 | ||
588 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | 588 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) |
589 | { | 589 | { |
590 | dput(nd->dentry); | 590 | dput(nd->path.dentry); |
591 | if (nd->mnt != path->mnt) | 591 | if (nd->path.mnt != path->mnt) |
592 | mntput(nd->mnt); | 592 | mntput(nd->path.mnt); |
593 | nd->mnt = path->mnt; | 593 | nd->path.mnt = path->mnt; |
594 | nd->dentry = path->dentry; | 594 | nd->path.dentry = path->dentry; |
595 | } | 595 | } |
596 | 596 | ||
597 | static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) | 597 | static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) |
@@ -603,7 +603,7 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata | |||
603 | touch_atime(path->mnt, dentry); | 603 | touch_atime(path->mnt, dentry); |
604 | nd_set_link(nd, NULL); | 604 | nd_set_link(nd, NULL); |
605 | 605 | ||
606 | if (path->mnt != nd->mnt) { | 606 | if (path->mnt != nd->path.mnt) { |
607 | path_to_nameidata(path, nd); | 607 | path_to_nameidata(path, nd); |
608 | dget(dentry); | 608 | dget(dentry); |
609 | } | 609 | } |
@@ -733,37 +733,37 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
733 | 733 | ||
734 | while(1) { | 734 | while(1) { |
735 | struct vfsmount *parent; | 735 | struct vfsmount *parent; |
736 | struct dentry *old = nd->dentry; | 736 | struct dentry *old = nd->path.dentry; |
737 | 737 | ||
738 | read_lock(&fs->lock); | 738 | read_lock(&fs->lock); |
739 | if (nd->dentry == fs->root && | 739 | if (nd->path.dentry == fs->root && |
740 | nd->mnt == fs->rootmnt) { | 740 | nd->path.mnt == fs->rootmnt) { |
741 | read_unlock(&fs->lock); | 741 | read_unlock(&fs->lock); |
742 | break; | 742 | break; |
743 | } | 743 | } |
744 | read_unlock(&fs->lock); | 744 | read_unlock(&fs->lock); |
745 | spin_lock(&dcache_lock); | 745 | spin_lock(&dcache_lock); |
746 | if (nd->dentry != nd->mnt->mnt_root) { | 746 | if (nd->path.dentry != nd->path.mnt->mnt_root) { |
747 | nd->dentry = dget(nd->dentry->d_parent); | 747 | nd->path.dentry = dget(nd->path.dentry->d_parent); |
748 | spin_unlock(&dcache_lock); | 748 | spin_unlock(&dcache_lock); |
749 | dput(old); | 749 | dput(old); |
750 | break; | 750 | break; |
751 | } | 751 | } |
752 | spin_unlock(&dcache_lock); | 752 | spin_unlock(&dcache_lock); |
753 | spin_lock(&vfsmount_lock); | 753 | spin_lock(&vfsmount_lock); |
754 | parent = nd->mnt->mnt_parent; | 754 | parent = nd->path.mnt->mnt_parent; |
755 | if (parent == nd->mnt) { | 755 | if (parent == nd->path.mnt) { |
756 | spin_unlock(&vfsmount_lock); | 756 | spin_unlock(&vfsmount_lock); |
757 | break; | 757 | break; |
758 | } | 758 | } |
759 | mntget(parent); | 759 | mntget(parent); |
760 | nd->dentry = dget(nd->mnt->mnt_mountpoint); | 760 | nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint); |
761 | spin_unlock(&vfsmount_lock); | 761 | spin_unlock(&vfsmount_lock); |
762 | dput(old); | 762 | dput(old); |
763 | mntput(nd->mnt); | 763 | mntput(nd->path.mnt); |
764 | nd->mnt = parent; | 764 | nd->path.mnt = parent; |
765 | } | 765 | } |
766 | follow_mount(&nd->mnt, &nd->dentry); | 766 | follow_mount(&nd->path.mnt, &nd->path.dentry); |
767 | } | 767 | } |
768 | 768 | ||
769 | /* | 769 | /* |
@@ -774,8 +774,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
774 | static int do_lookup(struct nameidata *nd, struct qstr *name, | 774 | static int do_lookup(struct nameidata *nd, struct qstr *name, |
775 | struct path *path) | 775 | struct path *path) |
776 | { | 776 | { |
777 | struct vfsmount *mnt = nd->mnt; | 777 | struct vfsmount *mnt = nd->path.mnt; |
778 | struct dentry *dentry = __d_lookup(nd->dentry, name); | 778 | struct dentry *dentry = __d_lookup(nd->path.dentry, name); |
779 | 779 | ||
780 | if (!dentry) | 780 | if (!dentry) |
781 | goto need_lookup; | 781 | goto need_lookup; |
@@ -788,7 +788,7 @@ done: | |||
788 | return 0; | 788 | return 0; |
789 | 789 | ||
790 | need_lookup: | 790 | need_lookup: |
791 | dentry = real_lookup(nd->dentry, name, nd); | 791 | dentry = real_lookup(nd->path.dentry, name, nd); |
792 | if (IS_ERR(dentry)) | 792 | if (IS_ERR(dentry)) |
793 | goto fail; | 793 | goto fail; |
794 | goto done; | 794 | goto done; |
@@ -825,7 +825,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
825 | if (!*name) | 825 | if (!*name) |
826 | goto return_reval; | 826 | goto return_reval; |
827 | 827 | ||
828 | inode = nd->dentry->d_inode; | 828 | inode = nd->path.dentry->d_inode; |
829 | if (nd->depth) | 829 | if (nd->depth) |
830 | lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); | 830 | lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); |
831 | 831 | ||
@@ -873,7 +873,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
873 | if (this.name[1] != '.') | 873 | if (this.name[1] != '.') |
874 | break; | 874 | break; |
875 | follow_dotdot(nd); | 875 | follow_dotdot(nd); |
876 | inode = nd->dentry->d_inode; | 876 | inode = nd->path.dentry->d_inode; |
877 | /* fallthrough */ | 877 | /* fallthrough */ |
878 | case 1: | 878 | case 1: |
879 | continue; | 879 | continue; |
@@ -882,8 +882,9 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
882 | * See if the low-level filesystem might want | 882 | * See if the low-level filesystem might want |
883 | * to use its own hash.. | 883 | * to use its own hash.. |
884 | */ | 884 | */ |
885 | if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { | 885 | if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { |
886 | err = nd->dentry->d_op->d_hash(nd->dentry, &this); | 886 | err = nd->path.dentry->d_op->d_hash(nd->path.dentry, |
887 | &this); | ||
887 | if (err < 0) | 888 | if (err < 0) |
888 | break; | 889 | break; |
889 | } | 890 | } |
@@ -905,7 +906,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
905 | if (err) | 906 | if (err) |
906 | goto return_err; | 907 | goto return_err; |
907 | err = -ENOENT; | 908 | err = -ENOENT; |
908 | inode = nd->dentry->d_inode; | 909 | inode = nd->path.dentry->d_inode; |
909 | if (!inode) | 910 | if (!inode) |
910 | break; | 911 | break; |
911 | err = -ENOTDIR; | 912 | err = -ENOTDIR; |
@@ -933,13 +934,14 @@ last_component: | |||
933 | if (this.name[1] != '.') | 934 | if (this.name[1] != '.') |
934 | break; | 935 | break; |
935 | follow_dotdot(nd); | 936 | follow_dotdot(nd); |
936 | inode = nd->dentry->d_inode; | 937 | inode = nd->path.dentry->d_inode; |
937 | /* fallthrough */ | 938 | /* fallthrough */ |
938 | case 1: | 939 | case 1: |
939 | goto return_reval; | 940 | goto return_reval; |
940 | } | 941 | } |
941 | if (nd->dentry->d_op && nd->dentry->d_op->d_hash) { | 942 | if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { |
942 | err = nd->dentry->d_op->d_hash(nd->dentry, &this); | 943 | err = nd->path.dentry->d_op->d_hash(nd->path.dentry, |
944 | &this); | ||
943 | if (err < 0) | 945 | if (err < 0) |
944 | break; | 946 | break; |
945 | } | 947 | } |
@@ -952,7 +954,7 @@ last_component: | |||
952 | err = do_follow_link(&next, nd); | 954 | err = do_follow_link(&next, nd); |
953 | if (err) | 955 | if (err) |
954 | goto return_err; | 956 | goto return_err; |
955 | inode = nd->dentry->d_inode; | 957 | inode = nd->path.dentry->d_inode; |
956 | } else | 958 | } else |
957 | path_to_nameidata(&next, nd); | 959 | path_to_nameidata(&next, nd); |
958 | err = -ENOENT; | 960 | err = -ENOENT; |
@@ -980,11 +982,12 @@ return_reval: | |||
980 | * We bypassed the ordinary revalidation routines. | 982 | * We bypassed the ordinary revalidation routines. |
981 | * We may need to check the cached dentry for staleness. | 983 | * We may need to check the cached dentry for staleness. |
982 | */ | 984 | */ |
983 | if (nd->dentry && nd->dentry->d_sb && | 985 | if (nd->path.dentry && nd->path.dentry->d_sb && |
984 | (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { | 986 | (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { |
985 | err = -ESTALE; | 987 | err = -ESTALE; |
986 | /* Note: we do not d_invalidate() */ | 988 | /* Note: we do not d_invalidate() */ |
987 | if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) | 989 | if (!nd->path.dentry->d_op->d_revalidate( |
990 | nd->path.dentry, nd)) | ||
988 | break; | 991 | break; |
989 | } | 992 | } |
990 | return_base: | 993 | return_base: |
@@ -1011,20 +1014,20 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1011 | int result; | 1014 | int result; |
1012 | 1015 | ||
1013 | /* make sure the stuff we saved doesn't go away */ | 1016 | /* make sure the stuff we saved doesn't go away */ |
1014 | dget(save.dentry); | 1017 | dget(save.path.dentry); |
1015 | mntget(save.mnt); | 1018 | mntget(save.path.mnt); |
1016 | 1019 | ||
1017 | result = __link_path_walk(name, nd); | 1020 | result = __link_path_walk(name, nd); |
1018 | if (result == -ESTALE) { | 1021 | if (result == -ESTALE) { |
1019 | *nd = save; | 1022 | *nd = save; |
1020 | dget(nd->dentry); | 1023 | dget(nd->path.dentry); |
1021 | mntget(nd->mnt); | 1024 | mntget(nd->path.mnt); |
1022 | nd->flags |= LOOKUP_REVAL; | 1025 | nd->flags |= LOOKUP_REVAL; |
1023 | result = __link_path_walk(name, nd); | 1026 | result = __link_path_walk(name, nd); |
1024 | } | 1027 | } |
1025 | 1028 | ||
1026 | dput(save.dentry); | 1029 | dput(save.path.dentry); |
1027 | mntput(save.mnt); | 1030 | mntput(save.path.mnt); |
1028 | 1031 | ||
1029 | return result; | 1032 | return result; |
1030 | } | 1033 | } |
@@ -1044,9 +1047,10 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1044 | if (path_walk(name, nd)) | 1047 | if (path_walk(name, nd)) |
1045 | return 0; /* something went wrong... */ | 1048 | return 0; /* something went wrong... */ |
1046 | 1049 | ||
1047 | if (!nd->dentry->d_inode || S_ISDIR(nd->dentry->d_inode->i_mode)) { | 1050 | if (!nd->path.dentry->d_inode || |
1048 | struct dentry *old_dentry = nd->dentry; | 1051 | S_ISDIR(nd->path.dentry->d_inode->i_mode)) { |
1049 | struct vfsmount *old_mnt = nd->mnt; | 1052 | struct dentry *old_dentry = nd->path.dentry; |
1053 | struct vfsmount *old_mnt = nd->path.mnt; | ||
1050 | struct qstr last = nd->last; | 1054 | struct qstr last = nd->last; |
1051 | int last_type = nd->last_type; | 1055 | int last_type = nd->last_type; |
1052 | struct fs_struct *fs = current->fs; | 1056 | struct fs_struct *fs = current->fs; |
@@ -1057,19 +1061,19 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1057 | */ | 1061 | */ |
1058 | nd->last_type = LAST_ROOT; | 1062 | nd->last_type = LAST_ROOT; |
1059 | read_lock(&fs->lock); | 1063 | read_lock(&fs->lock); |
1060 | nd->mnt = mntget(fs->rootmnt); | 1064 | nd->path.mnt = mntget(fs->rootmnt); |
1061 | nd->dentry = dget(fs->root); | 1065 | nd->path.dentry = dget(fs->root); |
1062 | read_unlock(&fs->lock); | 1066 | read_unlock(&fs->lock); |
1063 | if (path_walk(name, nd) == 0) { | 1067 | if (path_walk(name, nd) == 0) { |
1064 | if (nd->dentry->d_inode) { | 1068 | if (nd->path.dentry->d_inode) { |
1065 | dput(old_dentry); | 1069 | dput(old_dentry); |
1066 | mntput(old_mnt); | 1070 | mntput(old_mnt); |
1067 | return 1; | 1071 | return 1; |
1068 | } | 1072 | } |
1069 | path_release(nd); | 1073 | path_release(nd); |
1070 | } | 1074 | } |
1071 | nd->dentry = old_dentry; | 1075 | nd->path.dentry = old_dentry; |
1072 | nd->mnt = old_mnt; | 1076 | nd->path.mnt = old_mnt; |
1073 | nd->last = last; | 1077 | nd->last = last; |
1074 | nd->last_type = last_type; | 1078 | nd->last_type = last_type; |
1075 | } | 1079 | } |
@@ -1089,8 +1093,8 @@ void set_fs_altroot(void) | |||
1089 | goto set_it; | 1093 | goto set_it; |
1090 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); | 1094 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); |
1091 | if (!err) { | 1095 | if (!err) { |
1092 | mnt = nd.mnt; | 1096 | mnt = nd.path.mnt; |
1093 | dentry = nd.dentry; | 1097 | dentry = nd.path.dentry; |
1094 | } | 1098 | } |
1095 | set_it: | 1099 | set_it: |
1096 | write_lock(&fs->lock); | 1100 | write_lock(&fs->lock); |
@@ -1121,20 +1125,20 @@ static int do_path_lookup(int dfd, const char *name, | |||
1121 | if (*name=='/') { | 1125 | if (*name=='/') { |
1122 | read_lock(&fs->lock); | 1126 | read_lock(&fs->lock); |
1123 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 1127 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { |
1124 | nd->mnt = mntget(fs->altrootmnt); | 1128 | nd->path.mnt = mntget(fs->altrootmnt); |
1125 | nd->dentry = dget(fs->altroot); | 1129 | nd->path.dentry = dget(fs->altroot); |
1126 | read_unlock(&fs->lock); | 1130 | read_unlock(&fs->lock); |
1127 | if (__emul_lookup_dentry(name,nd)) | 1131 | if (__emul_lookup_dentry(name,nd)) |
1128 | goto out; /* found in altroot */ | 1132 | goto out; /* found in altroot */ |
1129 | read_lock(&fs->lock); | 1133 | read_lock(&fs->lock); |
1130 | } | 1134 | } |
1131 | nd->mnt = mntget(fs->rootmnt); | 1135 | nd->path.mnt = mntget(fs->rootmnt); |
1132 | nd->dentry = dget(fs->root); | 1136 | nd->path.dentry = dget(fs->root); |
1133 | read_unlock(&fs->lock); | 1137 | read_unlock(&fs->lock); |
1134 | } else if (dfd == AT_FDCWD) { | 1138 | } else if (dfd == AT_FDCWD) { |
1135 | read_lock(&fs->lock); | 1139 | read_lock(&fs->lock); |
1136 | nd->mnt = mntget(fs->pwdmnt); | 1140 | nd->path.mnt = mntget(fs->pwdmnt); |
1137 | nd->dentry = dget(fs->pwd); | 1141 | nd->path.dentry = dget(fs->pwd); |
1138 | read_unlock(&fs->lock); | 1142 | read_unlock(&fs->lock); |
1139 | } else { | 1143 | } else { |
1140 | struct dentry *dentry; | 1144 | struct dentry *dentry; |
@@ -1154,17 +1158,17 @@ static int do_path_lookup(int dfd, const char *name, | |||
1154 | if (retval) | 1158 | if (retval) |
1155 | goto fput_fail; | 1159 | goto fput_fail; |
1156 | 1160 | ||
1157 | nd->mnt = mntget(file->f_path.mnt); | 1161 | nd->path.mnt = mntget(file->f_path.mnt); |
1158 | nd->dentry = dget(dentry); | 1162 | nd->path.dentry = dget(dentry); |
1159 | 1163 | ||
1160 | fput_light(file, fput_needed); | 1164 | fput_light(file, fput_needed); |
1161 | } | 1165 | } |
1162 | 1166 | ||
1163 | retval = path_walk(name, nd); | 1167 | retval = path_walk(name, nd); |
1164 | out: | 1168 | out: |
1165 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && | 1169 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && |
1166 | nd->dentry->d_inode)) | 1170 | nd->path.dentry->d_inode)) |
1167 | audit_inode(name, nd->dentry); | 1171 | audit_inode(name, nd->path.dentry); |
1168 | out_fail: | 1172 | out_fail: |
1169 | return retval; | 1173 | return retval; |
1170 | 1174 | ||
@@ -1198,13 +1202,13 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, | |||
1198 | nd->flags = flags; | 1202 | nd->flags = flags; |
1199 | nd->depth = 0; | 1203 | nd->depth = 0; |
1200 | 1204 | ||
1201 | nd->mnt = mntget(mnt); | 1205 | nd->path.mnt = mntget(mnt); |
1202 | nd->dentry = dget(dentry); | 1206 | nd->path.dentry = dget(dentry); |
1203 | 1207 | ||
1204 | retval = path_walk(name, nd); | 1208 | retval = path_walk(name, nd); |
1205 | if (unlikely(!retval && !audit_dummy_context() && nd->dentry && | 1209 | if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && |
1206 | nd->dentry->d_inode)) | 1210 | nd->path.dentry->d_inode)) |
1207 | audit_inode(name, nd->dentry); | 1211 | audit_inode(name, nd->path.dentry); |
1208 | 1212 | ||
1209 | return retval; | 1213 | return retval; |
1210 | 1214 | ||
@@ -1323,10 +1327,10 @@ static struct dentry *lookup_hash(struct nameidata *nd) | |||
1323 | { | 1327 | { |
1324 | int err; | 1328 | int err; |
1325 | 1329 | ||
1326 | err = permission(nd->dentry->d_inode, MAY_EXEC, nd); | 1330 | err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); |
1327 | if (err) | 1331 | if (err) |
1328 | return ERR_PTR(err); | 1332 | return ERR_PTR(err); |
1329 | return __lookup_hash(&nd->last, nd->dentry, nd); | 1333 | return __lookup_hash(&nd->last, nd->path.dentry, nd); |
1330 | } | 1334 | } |
1331 | 1335 | ||
1332 | static int __lookup_one_len(const char *name, struct qstr *this, | 1336 | static int __lookup_one_len(const char *name, struct qstr *this, |
@@ -1585,7 +1589,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1585 | 1589 | ||
1586 | int may_open(struct nameidata *nd, int acc_mode, int flag) | 1590 | int may_open(struct nameidata *nd, int acc_mode, int flag) |
1587 | { | 1591 | { |
1588 | struct dentry *dentry = nd->dentry; | 1592 | struct dentry *dentry = nd->path.dentry; |
1589 | struct inode *inode = dentry->d_inode; | 1593 | struct inode *inode = dentry->d_inode; |
1590 | int error; | 1594 | int error; |
1591 | 1595 | ||
@@ -1606,7 +1610,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1606 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | 1610 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { |
1607 | flag &= ~O_TRUNC; | 1611 | flag &= ~O_TRUNC; |
1608 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | 1612 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { |
1609 | if (nd->mnt->mnt_flags & MNT_NODEV) | 1613 | if (nd->path.mnt->mnt_flags & MNT_NODEV) |
1610 | return -EACCES; | 1614 | return -EACCES; |
1611 | 1615 | ||
1612 | flag &= ~O_TRUNC; | 1616 | flag &= ~O_TRUNC; |
@@ -1668,14 +1672,14 @@ static int open_namei_create(struct nameidata *nd, struct path *path, | |||
1668 | int flag, int mode) | 1672 | int flag, int mode) |
1669 | { | 1673 | { |
1670 | int error; | 1674 | int error; |
1671 | struct dentry *dir = nd->dentry; | 1675 | struct dentry *dir = nd->path.dentry; |
1672 | 1676 | ||
1673 | if (!IS_POSIXACL(dir->d_inode)) | 1677 | if (!IS_POSIXACL(dir->d_inode)) |
1674 | mode &= ~current->fs->umask; | 1678 | mode &= ~current->fs->umask; |
1675 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); | 1679 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
1676 | mutex_unlock(&dir->d_inode->i_mutex); | 1680 | mutex_unlock(&dir->d_inode->i_mutex); |
1677 | dput(nd->dentry); | 1681 | dput(nd->path.dentry); |
1678 | nd->dentry = path->dentry; | 1682 | nd->path.dentry = path->dentry; |
1679 | if (error) | 1683 | if (error) |
1680 | return error; | 1684 | return error; |
1681 | /* Don't check for write permission, don't truncate */ | 1685 | /* Don't check for write permission, don't truncate */ |
@@ -1742,11 +1746,11 @@ int open_namei(int dfd, const char *pathname, int flag, | |||
1742 | if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) | 1746 | if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len]) |
1743 | goto exit; | 1747 | goto exit; |
1744 | 1748 | ||
1745 | dir = nd->dentry; | 1749 | dir = nd->path.dentry; |
1746 | nd->flags &= ~LOOKUP_PARENT; | 1750 | nd->flags &= ~LOOKUP_PARENT; |
1747 | mutex_lock(&dir->d_inode->i_mutex); | 1751 | mutex_lock(&dir->d_inode->i_mutex); |
1748 | path.dentry = lookup_hash(nd); | 1752 | path.dentry = lookup_hash(nd); |
1749 | path.mnt = nd->mnt; | 1753 | path.mnt = nd->path.mnt; |
1750 | 1754 | ||
1751 | do_last: | 1755 | do_last: |
1752 | error = PTR_ERR(path.dentry); | 1756 | error = PTR_ERR(path.dentry); |
@@ -1851,10 +1855,10 @@ do_link: | |||
1851 | __putname(nd->last.name); | 1855 | __putname(nd->last.name); |
1852 | goto exit; | 1856 | goto exit; |
1853 | } | 1857 | } |
1854 | dir = nd->dentry; | 1858 | dir = nd->path.dentry; |
1855 | mutex_lock(&dir->d_inode->i_mutex); | 1859 | mutex_lock(&dir->d_inode->i_mutex); |
1856 | path.dentry = lookup_hash(nd); | 1860 | path.dentry = lookup_hash(nd); |
1857 | path.mnt = nd->mnt; | 1861 | path.mnt = nd->path.mnt; |
1858 | __putname(nd->last.name); | 1862 | __putname(nd->last.name); |
1859 | goto do_last; | 1863 | goto do_last; |
1860 | } | 1864 | } |
@@ -1867,13 +1871,13 @@ do_link: | |||
1867 | * Simple function to lookup and return a dentry and create it | 1871 | * Simple function to lookup and return a dentry and create it |
1868 | * if it doesn't exist. Is SMP-safe. | 1872 | * if it doesn't exist. Is SMP-safe. |
1869 | * | 1873 | * |
1870 | * Returns with nd->dentry->d_inode->i_mutex locked. | 1874 | * Returns with nd->path.dentry->d_inode->i_mutex locked. |
1871 | */ | 1875 | */ |
1872 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) | 1876 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) |
1873 | { | 1877 | { |
1874 | struct dentry *dentry = ERR_PTR(-EEXIST); | 1878 | struct dentry *dentry = ERR_PTR(-EEXIST); |
1875 | 1879 | ||
1876 | mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 1880 | mutex_lock_nested(&nd->path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
1877 | /* | 1881 | /* |
1878 | * Yucky last component or no last component at all? | 1882 | * Yucky last component or no last component at all? |
1879 | * (foo/., foo/.., /////) | 1883 | * (foo/., foo/.., /////) |
@@ -1952,19 +1956,19 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1952 | dentry = lookup_create(&nd, 0); | 1956 | dentry = lookup_create(&nd, 0); |
1953 | error = PTR_ERR(dentry); | 1957 | error = PTR_ERR(dentry); |
1954 | 1958 | ||
1955 | if (!IS_POSIXACL(nd.dentry->d_inode)) | 1959 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
1956 | mode &= ~current->fs->umask; | 1960 | mode &= ~current->fs->umask; |
1957 | if (!IS_ERR(dentry)) { | 1961 | if (!IS_ERR(dentry)) { |
1958 | switch (mode & S_IFMT) { | 1962 | switch (mode & S_IFMT) { |
1959 | case 0: case S_IFREG: | 1963 | case 0: case S_IFREG: |
1960 | error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); | 1964 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); |
1961 | break; | 1965 | break; |
1962 | case S_IFCHR: case S_IFBLK: | 1966 | case S_IFCHR: case S_IFBLK: |
1963 | error = vfs_mknod(nd.dentry->d_inode,dentry,mode, | 1967 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, |
1964 | new_decode_dev(dev)); | 1968 | new_decode_dev(dev)); |
1965 | break; | 1969 | break; |
1966 | case S_IFIFO: case S_IFSOCK: | 1970 | case S_IFIFO: case S_IFSOCK: |
1967 | error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); | 1971 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); |
1968 | break; | 1972 | break; |
1969 | case S_IFDIR: | 1973 | case S_IFDIR: |
1970 | error = -EPERM; | 1974 | error = -EPERM; |
@@ -1974,7 +1978,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1974 | } | 1978 | } |
1975 | dput(dentry); | 1979 | dput(dentry); |
1976 | } | 1980 | } |
1977 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 1981 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
1978 | path_release(&nd); | 1982 | path_release(&nd); |
1979 | out: | 1983 | out: |
1980 | putname(tmp); | 1984 | putname(tmp); |
@@ -2029,12 +2033,12 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2029 | if (IS_ERR(dentry)) | 2033 | if (IS_ERR(dentry)) |
2030 | goto out_unlock; | 2034 | goto out_unlock; |
2031 | 2035 | ||
2032 | if (!IS_POSIXACL(nd.dentry->d_inode)) | 2036 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
2033 | mode &= ~current->fs->umask; | 2037 | mode &= ~current->fs->umask; |
2034 | error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); | 2038 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
2035 | dput(dentry); | 2039 | dput(dentry); |
2036 | out_unlock: | 2040 | out_unlock: |
2037 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 2041 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2038 | path_release(&nd); | 2042 | path_release(&nd); |
2039 | out: | 2043 | out: |
2040 | putname(tmp); | 2044 | putname(tmp); |
@@ -2133,15 +2137,15 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2133 | error = -EBUSY; | 2137 | error = -EBUSY; |
2134 | goto exit1; | 2138 | goto exit1; |
2135 | } | 2139 | } |
2136 | mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 2140 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
2137 | dentry = lookup_hash(&nd); | 2141 | dentry = lookup_hash(&nd); |
2138 | error = PTR_ERR(dentry); | 2142 | error = PTR_ERR(dentry); |
2139 | if (IS_ERR(dentry)) | 2143 | if (IS_ERR(dentry)) |
2140 | goto exit2; | 2144 | goto exit2; |
2141 | error = vfs_rmdir(nd.dentry->d_inode, dentry); | 2145 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); |
2142 | dput(dentry); | 2146 | dput(dentry); |
2143 | exit2: | 2147 | exit2: |
2144 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 2148 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2145 | exit1: | 2149 | exit1: |
2146 | path_release(&nd); | 2150 | path_release(&nd); |
2147 | exit: | 2151 | exit: |
@@ -2209,7 +2213,7 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2209 | error = -EISDIR; | 2213 | error = -EISDIR; |
2210 | if (nd.last_type != LAST_NORM) | 2214 | if (nd.last_type != LAST_NORM) |
2211 | goto exit1; | 2215 | goto exit1; |
2212 | mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT); | 2216 | mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); |
2213 | dentry = lookup_hash(&nd); | 2217 | dentry = lookup_hash(&nd); |
2214 | error = PTR_ERR(dentry); | 2218 | error = PTR_ERR(dentry); |
2215 | if (!IS_ERR(dentry)) { | 2219 | if (!IS_ERR(dentry)) { |
@@ -2219,11 +2223,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2219 | inode = dentry->d_inode; | 2223 | inode = dentry->d_inode; |
2220 | if (inode) | 2224 | if (inode) |
2221 | atomic_inc(&inode->i_count); | 2225 | atomic_inc(&inode->i_count); |
2222 | error = vfs_unlink(nd.dentry->d_inode, dentry); | 2226 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); |
2223 | exit2: | 2227 | exit2: |
2224 | dput(dentry); | 2228 | dput(dentry); |
2225 | } | 2229 | } |
2226 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 2230 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2227 | if (inode) | 2231 | if (inode) |
2228 | iput(inode); /* truncate the inode here */ | 2232 | iput(inode); /* truncate the inode here */ |
2229 | exit1: | 2233 | exit1: |
@@ -2300,10 +2304,10 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2300 | if (IS_ERR(dentry)) | 2304 | if (IS_ERR(dentry)) |
2301 | goto out_unlock; | 2305 | goto out_unlock; |
2302 | 2306 | ||
2303 | error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); | 2307 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); |
2304 | dput(dentry); | 2308 | dput(dentry); |
2305 | out_unlock: | 2309 | out_unlock: |
2306 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 2310 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2307 | path_release(&nd); | 2311 | path_release(&nd); |
2308 | out: | 2312 | out: |
2309 | putname(to); | 2313 | putname(to); |
@@ -2389,16 +2393,16 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2389 | if (error) | 2393 | if (error) |
2390 | goto out; | 2394 | goto out; |
2391 | error = -EXDEV; | 2395 | error = -EXDEV; |
2392 | if (old_nd.mnt != nd.mnt) | 2396 | if (old_nd.path.mnt != nd.path.mnt) |
2393 | goto out_release; | 2397 | goto out_release; |
2394 | new_dentry = lookup_create(&nd, 0); | 2398 | new_dentry = lookup_create(&nd, 0); |
2395 | error = PTR_ERR(new_dentry); | 2399 | error = PTR_ERR(new_dentry); |
2396 | if (IS_ERR(new_dentry)) | 2400 | if (IS_ERR(new_dentry)) |
2397 | goto out_unlock; | 2401 | goto out_unlock; |
2398 | error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); | 2402 | error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); |
2399 | dput(new_dentry); | 2403 | dput(new_dentry); |
2400 | out_unlock: | 2404 | out_unlock: |
2401 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 2405 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
2402 | out_release: | 2406 | out_release: |
2403 | path_release(&nd); | 2407 | path_release(&nd); |
2404 | out: | 2408 | out: |
@@ -2578,15 +2582,15 @@ static int do_rename(int olddfd, const char *oldname, | |||
2578 | goto exit1; | 2582 | goto exit1; |
2579 | 2583 | ||
2580 | error = -EXDEV; | 2584 | error = -EXDEV; |
2581 | if (oldnd.mnt != newnd.mnt) | 2585 | if (oldnd.path.mnt != newnd.path.mnt) |
2582 | goto exit2; | 2586 | goto exit2; |
2583 | 2587 | ||
2584 | old_dir = oldnd.dentry; | 2588 | old_dir = oldnd.path.dentry; |
2585 | error = -EBUSY; | 2589 | error = -EBUSY; |
2586 | if (oldnd.last_type != LAST_NORM) | 2590 | if (oldnd.last_type != LAST_NORM) |
2587 | goto exit2; | 2591 | goto exit2; |
2588 | 2592 | ||
2589 | new_dir = newnd.dentry; | 2593 | new_dir = newnd.path.dentry; |
2590 | if (newnd.last_type != LAST_NORM) | 2594 | if (newnd.last_type != LAST_NORM) |
2591 | goto exit2; | 2595 | goto exit2; |
2592 | 2596 | ||