Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * linux/fs/stat.c
4 : : *
5 : : * Copyright (C) 1991, 1992 Linus Torvalds
6 : : */
7 : :
8 : : #include <linux/export.h>
9 : : #include <linux/mm.h>
10 : : #include <linux/errno.h>
11 : : #include <linux/file.h>
12 : : #include <linux/highuid.h>
13 : : #include <linux/fs.h>
14 : : #include <linux/namei.h>
15 : : #include <linux/security.h>
16 : : #include <linux/cred.h>
17 : : #include <linux/syscalls.h>
18 : : #include <linux/pagemap.h>
19 : : #include <linux/compat.h>
20 : :
21 : : #include <linux/uaccess.h>
22 : : #include <asm/unistd.h>
23 : :
24 : : /**
25 : : * generic_fillattr - Fill in the basic attributes from the inode struct
26 : : * @inode: Inode to use as the source
27 : : * @stat: Where to fill in the attributes
28 : : *
29 : : * Fill in the basic attributes in the kstat structure from data that's to be
30 : : * found on the VFS inode structure. This is the default if no getattr inode
31 : : * operation is supplied.
32 : : */
33 : 3 : void generic_fillattr(struct inode *inode, struct kstat *stat)
34 : : {
35 : 3 : stat->dev = inode->i_sb->s_dev;
36 : 3 : stat->ino = inode->i_ino;
37 : 3 : stat->mode = inode->i_mode;
38 : 3 : stat->nlink = inode->i_nlink;
39 : 3 : stat->uid = inode->i_uid;
40 : 3 : stat->gid = inode->i_gid;
41 : 3 : stat->rdev = inode->i_rdev;
42 : 3 : stat->size = i_size_read(inode);
43 : 3 : stat->atime = inode->i_atime;
44 : 3 : stat->mtime = inode->i_mtime;
45 : 3 : stat->ctime = inode->i_ctime;
46 : 3 : stat->blksize = i_blocksize(inode);
47 : 3 : stat->blocks = inode->i_blocks;
48 : 3 : }
49 : : EXPORT_SYMBOL(generic_fillattr);
50 : :
51 : : /**
52 : : * vfs_getattr_nosec - getattr without security checks
53 : : * @path: file to get attributes from
54 : : * @stat: structure to return attributes in
55 : : * @request_mask: STATX_xxx flags indicating what the caller wants
56 : : * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
57 : : *
58 : : * Get attributes without calling security_inode_getattr.
59 : : *
60 : : * Currently the only caller other than vfs_getattr is internal to the
61 : : * filehandle lookup code, which uses only the inode number and returns no
62 : : * attributes to any user. Any other code probably wants vfs_getattr.
63 : : */
64 : 3 : int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
65 : : u32 request_mask, unsigned int query_flags)
66 : : {
67 : 3 : struct inode *inode = d_backing_inode(path->dentry);
68 : :
69 : 3 : memset(stat, 0, sizeof(*stat));
70 : 3 : stat->result_mask |= STATX_BASIC_STATS;
71 : 3 : request_mask &= STATX_ALL;
72 : 3 : query_flags &= KSTAT_QUERY_FLAGS;
73 : :
74 : : /* allow the fs to override these if it really wants to */
75 : 3 : if (IS_NOATIME(inode))
76 : 3 : stat->result_mask &= ~STATX_ATIME;
77 : 3 : if (IS_AUTOMOUNT(inode))
78 : 0 : stat->attributes |= STATX_ATTR_AUTOMOUNT;
79 : :
80 : 3 : if (inode->i_op->getattr)
81 : 3 : return inode->i_op->getattr(path, stat, request_mask,
82 : : query_flags);
83 : :
84 : 3 : generic_fillattr(inode, stat);
85 : 3 : return 0;
86 : : }
87 : : EXPORT_SYMBOL(vfs_getattr_nosec);
88 : :
89 : : /*
90 : : * vfs_getattr - Get the enhanced basic attributes of a file
91 : : * @path: The file of interest
92 : : * @stat: Where to return the statistics
93 : : * @request_mask: STATX_xxx flags indicating what the caller wants
94 : : * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
95 : : *
96 : : * Ask the filesystem for a file's attributes. The caller must indicate in
97 : : * request_mask and query_flags to indicate what they want.
98 : : *
99 : : * If the file is remote, the filesystem can be forced to update the attributes
100 : : * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can
101 : : * suppress the update by passing AT_STATX_DONT_SYNC.
102 : : *
103 : : * Bits must have been set in request_mask to indicate which attributes the
104 : : * caller wants retrieving. Any such attribute not requested may be returned
105 : : * anyway, but the value may be approximate, and, if remote, may not have been
106 : : * synchronised with the server.
107 : : *
108 : : * 0 will be returned on success, and a -ve error code if unsuccessful.
109 : : */
110 : 3 : int vfs_getattr(const struct path *path, struct kstat *stat,
111 : : u32 request_mask, unsigned int query_flags)
112 : : {
113 : : int retval;
114 : :
115 : 3 : retval = security_inode_getattr(path);
116 : 3 : if (retval)
117 : : return retval;
118 : 3 : return vfs_getattr_nosec(path, stat, request_mask, query_flags);
119 : : }
120 : : EXPORT_SYMBOL(vfs_getattr);
121 : :
122 : : /**
123 : : * vfs_statx_fd - Get the enhanced basic attributes by file descriptor
124 : : * @fd: The file descriptor referring to the file of interest
125 : : * @stat: The result structure to fill in.
126 : : * @request_mask: STATX_xxx flags indicating what the caller wants
127 : : * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
128 : : *
129 : : * This function is a wrapper around vfs_getattr(). The main difference is
130 : : * that it uses a file descriptor to determine the file location.
131 : : *
132 : : * 0 will be returned on success, and a -ve error code if unsuccessful.
133 : : */
134 : 3 : int vfs_statx_fd(unsigned int fd, struct kstat *stat,
135 : : u32 request_mask, unsigned int query_flags)
136 : : {
137 : : struct fd f;
138 : : int error = -EBADF;
139 : :
140 : 3 : if (query_flags & ~KSTAT_QUERY_FLAGS)
141 : : return -EINVAL;
142 : :
143 : : f = fdget_raw(fd);
144 : 3 : if (f.file) {
145 : 3 : error = vfs_getattr(&f.file->f_path, stat,
146 : : request_mask, query_flags);
147 : : fdput(f);
148 : : }
149 : 3 : return error;
150 : : }
151 : : EXPORT_SYMBOL(vfs_statx_fd);
152 : :
153 : : /**
154 : : * vfs_statx - Get basic and extra attributes by filename
155 : : * @dfd: A file descriptor representing the base dir for a relative filename
156 : : * @filename: The name of the file of interest
157 : : * @flags: Flags to control the query
158 : : * @stat: The result structure to fill in.
159 : : * @request_mask: STATX_xxx flags indicating what the caller wants
160 : : *
161 : : * This function is a wrapper around vfs_getattr(). The main difference is
162 : : * that it uses a filename and base directory to determine the file location.
163 : : * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink
164 : : * at the given name from being referenced.
165 : : *
166 : : * 0 will be returned on success, and a -ve error code if unsuccessful.
167 : : */
168 : 3 : int vfs_statx(int dfd, const char __user *filename, int flags,
169 : : struct kstat *stat, u32 request_mask)
170 : : {
171 : : struct path path;
172 : : int error = -EINVAL;
173 : : unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
174 : :
175 : 3 : if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
176 : : AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
177 : : return -EINVAL;
178 : :
179 : 3 : if (flags & AT_SYMLINK_NOFOLLOW)
180 : : lookup_flags &= ~LOOKUP_FOLLOW;
181 : 3 : if (flags & AT_NO_AUTOMOUNT)
182 : 3 : lookup_flags &= ~LOOKUP_AUTOMOUNT;
183 : 3 : if (flags & AT_EMPTY_PATH)
184 : 3 : lookup_flags |= LOOKUP_EMPTY;
185 : :
186 : : retry:
187 : : error = user_path_at(dfd, filename, lookup_flags, &path);
188 : 3 : if (error)
189 : : goto out;
190 : :
191 : 3 : error = vfs_getattr(&path, stat, request_mask, flags);
192 : 3 : path_put(&path);
193 : 3 : if (retry_estale(error, lookup_flags)) {
194 : 0 : lookup_flags |= LOOKUP_REVAL;
195 : 0 : goto retry;
196 : : }
197 : : out:
198 : 3 : return error;
199 : : }
200 : : EXPORT_SYMBOL(vfs_statx);
201 : :
202 : :
203 : : #ifdef __ARCH_WANT_OLD_STAT
204 : :
205 : : /*
206 : : * For backward compatibility? Maybe this should be moved
207 : : * into arch/i386 instead?
208 : : */
209 : : static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
210 : : {
211 : : static int warncount = 5;
212 : : struct __old_kernel_stat tmp;
213 : :
214 : : if (warncount > 0) {
215 : : warncount--;
216 : : printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
217 : : current->comm);
218 : : } else if (warncount < 0) {
219 : : /* it's laughable, but... */
220 : : warncount = 0;
221 : : }
222 : :
223 : : memset(&tmp, 0, sizeof(struct __old_kernel_stat));
224 : : tmp.st_dev = old_encode_dev(stat->dev);
225 : : tmp.st_ino = stat->ino;
226 : : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
227 : : return -EOVERFLOW;
228 : : tmp.st_mode = stat->mode;
229 : : tmp.st_nlink = stat->nlink;
230 : : if (tmp.st_nlink != stat->nlink)
231 : : return -EOVERFLOW;
232 : : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
233 : : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
234 : : tmp.st_rdev = old_encode_dev(stat->rdev);
235 : : #if BITS_PER_LONG == 32
236 : : if (stat->size > MAX_NON_LFS)
237 : : return -EOVERFLOW;
238 : : #endif
239 : : tmp.st_size = stat->size;
240 : : tmp.st_atime = stat->atime.tv_sec;
241 : : tmp.st_mtime = stat->mtime.tv_sec;
242 : : tmp.st_ctime = stat->ctime.tv_sec;
243 : : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
244 : : }
245 : :
246 : : SYSCALL_DEFINE2(stat, const char __user *, filename,
247 : : struct __old_kernel_stat __user *, statbuf)
248 : : {
249 : : struct kstat stat;
250 : : int error;
251 : :
252 : : error = vfs_stat(filename, &stat);
253 : : if (error)
254 : : return error;
255 : :
256 : : return cp_old_stat(&stat, statbuf);
257 : : }
258 : :
259 : : SYSCALL_DEFINE2(lstat, const char __user *, filename,
260 : : struct __old_kernel_stat __user *, statbuf)
261 : : {
262 : : struct kstat stat;
263 : : int error;
264 : :
265 : : error = vfs_lstat(filename, &stat);
266 : : if (error)
267 : : return error;
268 : :
269 : : return cp_old_stat(&stat, statbuf);
270 : : }
271 : :
272 : : SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
273 : : {
274 : : struct kstat stat;
275 : : int error = vfs_fstat(fd, &stat);
276 : :
277 : : if (!error)
278 : : error = cp_old_stat(&stat, statbuf);
279 : :
280 : : return error;
281 : : }
282 : :
283 : : #endif /* __ARCH_WANT_OLD_STAT */
284 : :
285 : : #ifdef __ARCH_WANT_NEW_STAT
286 : :
287 : : #if BITS_PER_LONG == 32
288 : : # define choose_32_64(a,b) a
289 : : #else
290 : : # define choose_32_64(a,b) b
291 : : #endif
292 : :
293 : : #define valid_dev(x) choose_32_64(old_valid_dev(x),true)
294 : : #define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x)
295 : :
296 : : #ifndef INIT_STRUCT_STAT_PADDING
297 : : # define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))
298 : : #endif
299 : :
300 : 0 : static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
301 : : {
302 : : struct stat tmp;
303 : :
304 : 0 : if (!valid_dev(stat->dev) || !valid_dev(stat->rdev))
305 : : return -EOVERFLOW;
306 : : #if BITS_PER_LONG == 32
307 : 0 : if (stat->size > MAX_NON_LFS)
308 : : return -EOVERFLOW;
309 : : #endif
310 : :
311 : 0 : INIT_STRUCT_STAT_PADDING(tmp);
312 : 0 : tmp.st_dev = encode_dev(stat->dev);
313 : 0 : tmp.st_ino = stat->ino;
314 : 0 : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
315 : : return -EOVERFLOW;
316 : 0 : tmp.st_mode = stat->mode;
317 : 0 : tmp.st_nlink = stat->nlink;
318 : 0 : if (tmp.st_nlink != stat->nlink)
319 : : return -EOVERFLOW;
320 : 0 : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
321 : 0 : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
322 : 0 : tmp.st_rdev = encode_dev(stat->rdev);
323 : 0 : tmp.st_size = stat->size;
324 : 0 : tmp.st_atime = stat->atime.tv_sec;
325 : 0 : tmp.st_mtime = stat->mtime.tv_sec;
326 : 0 : tmp.st_ctime = stat->ctime.tv_sec;
327 : : #ifdef STAT_HAVE_NSEC
328 : 0 : tmp.st_atime_nsec = stat->atime.tv_nsec;
329 : 0 : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
330 : 0 : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
331 : : #endif
332 : 0 : tmp.st_blocks = stat->blocks;
333 : 0 : tmp.st_blksize = stat->blksize;
334 : 0 : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
335 : : }
336 : :
337 : 0 : SYSCALL_DEFINE2(newstat, const char __user *, filename,
338 : : struct stat __user *, statbuf)
339 : : {
340 : : struct kstat stat;
341 : : int error = vfs_stat(filename, &stat);
342 : :
343 : 0 : if (error)
344 : : return error;
345 : 0 : return cp_new_stat(&stat, statbuf);
346 : : }
347 : :
348 : 0 : SYSCALL_DEFINE2(newlstat, const char __user *, filename,
349 : : struct stat __user *, statbuf)
350 : : {
351 : : struct kstat stat;
352 : : int error;
353 : :
354 : : error = vfs_lstat(filename, &stat);
355 : 0 : if (error)
356 : : return error;
357 : :
358 : 0 : return cp_new_stat(&stat, statbuf);
359 : : }
360 : :
361 : : #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
362 : : SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
363 : : struct stat __user *, statbuf, int, flag)
364 : : {
365 : : struct kstat stat;
366 : : int error;
367 : :
368 : : error = vfs_fstatat(dfd, filename, &stat, flag);
369 : : if (error)
370 : : return error;
371 : : return cp_new_stat(&stat, statbuf);
372 : : }
373 : : #endif
374 : :
375 : 0 : SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
376 : : {
377 : : struct kstat stat;
378 : : int error = vfs_fstat(fd, &stat);
379 : :
380 : 0 : if (!error)
381 : 0 : error = cp_new_stat(&stat, statbuf);
382 : :
383 : 0 : return error;
384 : : }
385 : : #endif
386 : :
387 : 3 : static int do_readlinkat(int dfd, const char __user *pathname,
388 : : char __user *buf, int bufsiz)
389 : : {
390 : : struct path path;
391 : : int error;
392 : 3 : int empty = 0;
393 : : unsigned int lookup_flags = LOOKUP_EMPTY;
394 : :
395 : 3 : if (bufsiz <= 0)
396 : : return -EINVAL;
397 : :
398 : : retry:
399 : 3 : error = user_path_at_empty(dfd, pathname, lookup_flags, &path, &empty);
400 : 3 : if (!error) {
401 : 3 : struct inode *inode = d_backing_inode(path.dentry);
402 : :
403 : 3 : error = empty ? -ENOENT : -EINVAL;
404 : : /*
405 : : * AFS mountpoints allow readlink(2) but are not symlinks
406 : : */
407 : 3 : if (d_is_symlink(path.dentry) || inode->i_op->readlink) {
408 : 3 : error = security_inode_readlink(path.dentry);
409 : 3 : if (!error) {
410 : 3 : touch_atime(&path);
411 : 3 : error = vfs_readlink(path.dentry, buf, bufsiz);
412 : : }
413 : : }
414 : 3 : path_put(&path);
415 : 3 : if (retry_estale(error, lookup_flags)) {
416 : : lookup_flags |= LOOKUP_REVAL;
417 : : goto retry;
418 : : }
419 : : }
420 : 3 : return error;
421 : : }
422 : :
423 : 3 : SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
424 : : char __user *, buf, int, bufsiz)
425 : : {
426 : 3 : return do_readlinkat(dfd, pathname, buf, bufsiz);
427 : : }
428 : :
429 : 3 : SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,
430 : : int, bufsiz)
431 : : {
432 : 3 : return do_readlinkat(AT_FDCWD, path, buf, bufsiz);
433 : : }
434 : :
435 : :
436 : : /* ---------- LFS-64 ----------- */
437 : : #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
438 : :
439 : : #ifndef INIT_STRUCT_STAT64_PADDING
440 : : # define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))
441 : : #endif
442 : :
443 : 3 : static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
444 : : {
445 : : struct stat64 tmp;
446 : :
447 : 3 : INIT_STRUCT_STAT64_PADDING(tmp);
448 : : #ifdef CONFIG_MIPS
449 : : /* mips has weird padding, so we don't get 64 bits there */
450 : : tmp.st_dev = new_encode_dev(stat->dev);
451 : : tmp.st_rdev = new_encode_dev(stat->rdev);
452 : : #else
453 : 3 : tmp.st_dev = huge_encode_dev(stat->dev);
454 : 3 : tmp.st_rdev = huge_encode_dev(stat->rdev);
455 : : #endif
456 : 3 : tmp.st_ino = stat->ino;
457 : : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
458 : : return -EOVERFLOW;
459 : : #ifdef STAT64_HAS_BROKEN_ST_INO
460 : 3 : tmp.__st_ino = stat->ino;
461 : : #endif
462 : 3 : tmp.st_mode = stat->mode;
463 : 3 : tmp.st_nlink = stat->nlink;
464 : 3 : tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
465 : 3 : tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
466 : 3 : tmp.st_atime = stat->atime.tv_sec;
467 : 3 : tmp.st_atime_nsec = stat->atime.tv_nsec;
468 : 3 : tmp.st_mtime = stat->mtime.tv_sec;
469 : 3 : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
470 : 3 : tmp.st_ctime = stat->ctime.tv_sec;
471 : 3 : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
472 : 3 : tmp.st_size = stat->size;
473 : 3 : tmp.st_blocks = stat->blocks;
474 : 3 : tmp.st_blksize = stat->blksize;
475 : 3 : return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
476 : : }
477 : :
478 : 3 : SYSCALL_DEFINE2(stat64, const char __user *, filename,
479 : : struct stat64 __user *, statbuf)
480 : : {
481 : : struct kstat stat;
482 : : int error = vfs_stat(filename, &stat);
483 : :
484 : 3 : if (!error)
485 : 3 : error = cp_new_stat64(&stat, statbuf);
486 : :
487 : 3 : return error;
488 : : }
489 : :
490 : 3 : SYSCALL_DEFINE2(lstat64, const char __user *, filename,
491 : : struct stat64 __user *, statbuf)
492 : : {
493 : : struct kstat stat;
494 : : int error = vfs_lstat(filename, &stat);
495 : :
496 : 3 : if (!error)
497 : 3 : error = cp_new_stat64(&stat, statbuf);
498 : :
499 : 3 : return error;
500 : : }
501 : :
502 : 3 : SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
503 : : {
504 : : struct kstat stat;
505 : : int error = vfs_fstat(fd, &stat);
506 : :
507 : 3 : if (!error)
508 : 3 : error = cp_new_stat64(&stat, statbuf);
509 : :
510 : 3 : return error;
511 : : }
512 : :
513 : 3 : SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
514 : : struct stat64 __user *, statbuf, int, flag)
515 : : {
516 : : struct kstat stat;
517 : : int error;
518 : :
519 : : error = vfs_fstatat(dfd, filename, &stat, flag);
520 : 3 : if (error)
521 : : return error;
522 : 3 : return cp_new_stat64(&stat, statbuf);
523 : : }
524 : : #endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */
525 : :
526 : : static noinline_for_stack int
527 : 3 : cp_statx(const struct kstat *stat, struct statx __user *buffer)
528 : : {
529 : : struct statx tmp;
530 : :
531 : 3 : memset(&tmp, 0, sizeof(tmp));
532 : :
533 : 3 : tmp.stx_mask = stat->result_mask;
534 : 3 : tmp.stx_blksize = stat->blksize;
535 : 3 : tmp.stx_attributes = stat->attributes;
536 : 3 : tmp.stx_nlink = stat->nlink;
537 : 3 : tmp.stx_uid = from_kuid_munged(current_user_ns(), stat->uid);
538 : 3 : tmp.stx_gid = from_kgid_munged(current_user_ns(), stat->gid);
539 : 3 : tmp.stx_mode = stat->mode;
540 : 3 : tmp.stx_ino = stat->ino;
541 : 3 : tmp.stx_size = stat->size;
542 : 3 : tmp.stx_blocks = stat->blocks;
543 : 3 : tmp.stx_attributes_mask = stat->attributes_mask;
544 : 3 : tmp.stx_atime.tv_sec = stat->atime.tv_sec;
545 : 3 : tmp.stx_atime.tv_nsec = stat->atime.tv_nsec;
546 : 3 : tmp.stx_btime.tv_sec = stat->btime.tv_sec;
547 : 3 : tmp.stx_btime.tv_nsec = stat->btime.tv_nsec;
548 : 3 : tmp.stx_ctime.tv_sec = stat->ctime.tv_sec;
549 : 3 : tmp.stx_ctime.tv_nsec = stat->ctime.tv_nsec;
550 : 3 : tmp.stx_mtime.tv_sec = stat->mtime.tv_sec;
551 : 3 : tmp.stx_mtime.tv_nsec = stat->mtime.tv_nsec;
552 : 3 : tmp.stx_rdev_major = MAJOR(stat->rdev);
553 : 3 : tmp.stx_rdev_minor = MINOR(stat->rdev);
554 : 3 : tmp.stx_dev_major = MAJOR(stat->dev);
555 : 3 : tmp.stx_dev_minor = MINOR(stat->dev);
556 : :
557 : 3 : return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
558 : : }
559 : :
560 : : /**
561 : : * sys_statx - System call to get enhanced stats
562 : : * @dfd: Base directory to pathwalk from *or* fd to stat.
563 : : * @filename: File to stat or "" with AT_EMPTY_PATH
564 : : * @flags: AT_* flags to control pathwalk.
565 : : * @mask: Parts of statx struct actually required.
566 : : * @buffer: Result buffer.
567 : : *
568 : : * Note that fstat() can be emulated by setting dfd to the fd of interest,
569 : : * supplying "" as the filename and setting AT_EMPTY_PATH in the flags.
570 : : */
571 : 3 : SYSCALL_DEFINE5(statx,
572 : : int, dfd, const char __user *, filename, unsigned, flags,
573 : : unsigned int, mask,
574 : : struct statx __user *, buffer)
575 : : {
576 : : struct kstat stat;
577 : : int error;
578 : :
579 : 3 : if (mask & STATX__RESERVED)
580 : : return -EINVAL;
581 : 3 : if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
582 : : return -EINVAL;
583 : :
584 : 3 : error = vfs_statx(dfd, filename, flags, &stat, mask);
585 : 3 : if (error)
586 : : return error;
587 : :
588 : 3 : return cp_statx(&stat, buffer);
589 : : }
590 : :
591 : : #ifdef CONFIG_COMPAT
592 : : static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
593 : : {
594 : : struct compat_stat tmp;
595 : :
596 : : if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
597 : : return -EOVERFLOW;
598 : :
599 : : memset(&tmp, 0, sizeof(tmp));
600 : : tmp.st_dev = old_encode_dev(stat->dev);
601 : : tmp.st_ino = stat->ino;
602 : : if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
603 : : return -EOVERFLOW;
604 : : tmp.st_mode = stat->mode;
605 : : tmp.st_nlink = stat->nlink;
606 : : if (tmp.st_nlink != stat->nlink)
607 : : return -EOVERFLOW;
608 : : SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
609 : : SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
610 : : tmp.st_rdev = old_encode_dev(stat->rdev);
611 : : if ((u64) stat->size > MAX_NON_LFS)
612 : : return -EOVERFLOW;
613 : : tmp.st_size = stat->size;
614 : : tmp.st_atime = stat->atime.tv_sec;
615 : : tmp.st_atime_nsec = stat->atime.tv_nsec;
616 : : tmp.st_mtime = stat->mtime.tv_sec;
617 : : tmp.st_mtime_nsec = stat->mtime.tv_nsec;
618 : : tmp.st_ctime = stat->ctime.tv_sec;
619 : : tmp.st_ctime_nsec = stat->ctime.tv_nsec;
620 : : tmp.st_blocks = stat->blocks;
621 : : tmp.st_blksize = stat->blksize;
622 : : return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
623 : : }
624 : :
625 : : COMPAT_SYSCALL_DEFINE2(newstat, const char __user *, filename,
626 : : struct compat_stat __user *, statbuf)
627 : : {
628 : : struct kstat stat;
629 : : int error;
630 : :
631 : : error = vfs_stat(filename, &stat);
632 : : if (error)
633 : : return error;
634 : : return cp_compat_stat(&stat, statbuf);
635 : : }
636 : :
637 : : COMPAT_SYSCALL_DEFINE2(newlstat, const char __user *, filename,
638 : : struct compat_stat __user *, statbuf)
639 : : {
640 : : struct kstat stat;
641 : : int error;
642 : :
643 : : error = vfs_lstat(filename, &stat);
644 : : if (error)
645 : : return error;
646 : : return cp_compat_stat(&stat, statbuf);
647 : : }
648 : :
649 : : #ifndef __ARCH_WANT_STAT64
650 : : COMPAT_SYSCALL_DEFINE4(newfstatat, unsigned int, dfd,
651 : : const char __user *, filename,
652 : : struct compat_stat __user *, statbuf, int, flag)
653 : : {
654 : : struct kstat stat;
655 : : int error;
656 : :
657 : : error = vfs_fstatat(dfd, filename, &stat, flag);
658 : : if (error)
659 : : return error;
660 : : return cp_compat_stat(&stat, statbuf);
661 : : }
662 : : #endif
663 : :
664 : : COMPAT_SYSCALL_DEFINE2(newfstat, unsigned int, fd,
665 : : struct compat_stat __user *, statbuf)
666 : : {
667 : : struct kstat stat;
668 : : int error = vfs_fstat(fd, &stat);
669 : :
670 : : if (!error)
671 : : error = cp_compat_stat(&stat, statbuf);
672 : : return error;
673 : : }
674 : : #endif
675 : :
676 : : /* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
677 : 3 : void __inode_add_bytes(struct inode *inode, loff_t bytes)
678 : : {
679 : 3 : inode->i_blocks += bytes >> 9;
680 : 3 : bytes &= 511;
681 : 3 : inode->i_bytes += bytes;
682 : 3 : if (inode->i_bytes >= 512) {
683 : 0 : inode->i_blocks++;
684 : 0 : inode->i_bytes -= 512;
685 : : }
686 : 3 : }
687 : : EXPORT_SYMBOL(__inode_add_bytes);
688 : :
689 : 3 : void inode_add_bytes(struct inode *inode, loff_t bytes)
690 : : {
691 : : spin_lock(&inode->i_lock);
692 : : __inode_add_bytes(inode, bytes);
693 : : spin_unlock(&inode->i_lock);
694 : 3 : }
695 : :
696 : : EXPORT_SYMBOL(inode_add_bytes);
697 : :
698 : 0 : void __inode_sub_bytes(struct inode *inode, loff_t bytes)
699 : : {
700 : 3 : inode->i_blocks -= bytes >> 9;
701 : 3 : bytes &= 511;
702 : 3 : if (inode->i_bytes < bytes) {
703 : 0 : inode->i_blocks--;
704 : 0 : inode->i_bytes += 512;
705 : : }
706 : 3 : inode->i_bytes -= bytes;
707 : 0 : }
708 : :
709 : : EXPORT_SYMBOL(__inode_sub_bytes);
710 : :
711 : 3 : void inode_sub_bytes(struct inode *inode, loff_t bytes)
712 : : {
713 : : spin_lock(&inode->i_lock);
714 : : __inode_sub_bytes(inode, bytes);
715 : : spin_unlock(&inode->i_lock);
716 : 3 : }
717 : :
718 : : EXPORT_SYMBOL(inode_sub_bytes);
719 : :
720 : 0 : loff_t inode_get_bytes(struct inode *inode)
721 : : {
722 : : loff_t ret;
723 : :
724 : : spin_lock(&inode->i_lock);
725 : : ret = __inode_get_bytes(inode);
726 : : spin_unlock(&inode->i_lock);
727 : 0 : return ret;
728 : : }
729 : :
730 : : EXPORT_SYMBOL(inode_get_bytes);
731 : :
732 : 0 : void inode_set_bytes(struct inode *inode, loff_t bytes)
733 : : {
734 : : /* Caller is here responsible for sufficient locking
735 : : * (ie. inode->i_lock) */
736 : 0 : inode->i_blocks = bytes >> 9;
737 : 0 : inode->i_bytes = bytes & 511;
738 : 0 : }
739 : :
740 : : EXPORT_SYMBOL(inode_set_bytes);
|