| @@ -184,6 +184,20 @@ int vfs_fstat(int fd, struct kstat *stat) · 183 unmodified lines |
| 184 | return error; | 184 | return error; |
| 185 | } | 185 | } |
| 186 | | 186 | |
| | 187 | int getname_statx_lookup_flags(int flags) |
| | 188 | { |
| | 189 | int lookup_flags = 0; |
| | 190 | |
| | 191 | if (!(flags & AT_SYMLINK_NOFOLLOW)) |
| | 192 | lookup_flags |= LOOKUP_FOLLOW; |
| | 193 | if (!(flags & AT_NO_AUTOMOUNT)) |
| | 194 | lookup_flags |= LOOKUP_AUTOMOUNT; |
| | 195 | if (flags & AT_EMPTY_PATH) |
| | 196 | lookup_flags |= LOOKUP_EMPTY; |
| | 197 | |
| | 198 | return lookup_flags; |
| | 199 | } |
| | 200 | |
| 187 | /** | 201 | /** |
| 188 | * vfs_statx - Get basic and extra attributes by filename | 202 | * vfs_statx - Get basic and extra attributes by filename |
| 189 | * @dfd: A file descriptor representing the base dir for a relative filename | 203 | * @dfd: A file descriptor representing the base dir for a relative filename |
| @@ -199,26 +213,19 @@ int vfs_fstat(int fd, struct kstat *stat) · 9 unmodified lines |
| 199 | * | 213 | * |
| 200 | * 0 will be returned on success, and a -ve error code if unsuccessful. | 214 | * 0 will be returned on success, and a -ve error code if unsuccessful. |
| 201 | */ | 215 | */ |
| 202 | static int vfs_statx(int dfd, const char __user *filename, int flags, | 216 | static int vfs_statx(int dfd, struct filename *filename, int flags, |
| 203 | struct kstat *stat, u32 request_mask) | 217 | struct kstat *stat, u32 request_mask) |
| 204 | { | 218 | { |
| 205 | struct path path; | 219 | struct path path; |
| 206 | unsigned lookup_flags = 0; | 220 | unsigned int lookup_flags = getname_statx_lookup_flags(flags); |
| 207 | int error; | 221 | int error; |
| 208 | | 222 | |
| 209 | if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH | | 223 | if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH | |
| 210 | AT_STATX_SYNC_TYPE)) | 224 | AT_STATX_SYNC_TYPE)) |
| 211 | return -EINVAL; | 225 | return -EINVAL; |
| 212 | | 226 | |
| 213 | if (!(flags & AT_SYMLINK_NOFOLLOW)) | | |
| 214 | lookup_flags |= LOOKUP_FOLLOW; | | |
| 215 | if (!(flags & AT_NO_AUTOMOUNT)) | | |
| 216 | lookup_flags |= LOOKUP_AUTOMOUNT; | | |
| 217 | if (flags & AT_EMPTY_PATH) | | |
| 218 | lookup_flags |= LOOKUP_EMPTY; | | |
| 219 | | | |
| 220 | retry: | 227 | retry: |
| 221 | error = user_path_at(dfd, filename, lookup_flags, &path); | 228 | error = filename_lookup(dfd, filename, lookup_flags, &path, NULL); |
| 222 | if (error) | 229 | if (error) |
| 223 | goto out; | 230 | goto out; |
| 224 | | 231 | |
| @@ -240,8 +247,15 @@ out: · 15 unmodified lines |
| 240 | int vfs_fstatat(int dfd, const char __user *filename, | 247 | int vfs_fstatat(int dfd, const char __user *filename, |
| 241 | struct kstat *stat, int flags) | 248 | struct kstat *stat, int flags) |
| 242 | { | 249 | { |
| 243 | return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT, | 250 | int ret; |
| 244 | stat, STATX_BASIC_STATS); | 251 | int statx_flags = flags | AT_NO_AUTOMOUNT; |
| | 252 | struct filename *name; |
| | 253 | |
| | 254 | name = getname_flags(filename, getname_statx_lookup_flags(statx_flags), NULL); |
| | 255 | ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS); |
| | 256 | putname(name); |
| | 257 | |
| | 258 | return ret; |
| 245 | } | 259 | } |
| 246 | | 260 | |
| 247 | #ifdef __ARCH_WANT_OLD_STAT | 261 | #ifdef __ARCH_WANT_OLD_STAT |
| @@ -602,7 +616,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer) · 354 unmodified lines |
| 602 | return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 616 | return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
| 603 | } | 617 | } |
| 604 | | 618 | |
| 605 | int do_statx(int dfd, const char __user *filename, unsigned flags, | 619 | int do_statx(int dfd, struct filename *filename, unsigned int flags, |
| 606 | unsigned int mask, struct statx __user *buffer) | 620 | unsigned int mask, struct statx __user *buffer) |
| 607 | { | 621 | { |
| 608 | struct kstat stat; | 622 | struct kstat stat; |
| @@ -636,7 +650,14 @@ SYSCALL_DEFINE5(statx, · 27 unmodified lines |
| 636 | unsigned int, mask, | 650 | unsigned int, mask, |
| 637 | struct statx __user *, buffer) | 651 | struct statx __user *, buffer) |
| 638 | { | 652 | { |
| 639 | return do_statx(dfd, filename, flags, mask, buffer); | 653 | int ret; |
| | 654 | struct filename *name; |
| | 655 | |
| | 656 | name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL); |
| | 657 | ret = do_statx(dfd, name, flags, mask, buffer); |
| | 658 | putname(name); |
| | 659 | |
| | 660 | return ret; |
| 640 | } | 661 | } |
| 641 | | 662 | |
| 642 | #ifdef CONFIG_COMPAT | 663 | #ifdef CONFIG_COMPAT |