1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 1991, 1992 Linus Torvalds
8 #include <linux/export.h>
10 #include <linux/errno.h>
11 #include <linux/file.h>
12 #include <linux/highuid.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>
21 #include <linux/uaccess.h>
22 #include <asm/unistd.h>
28 * generic_fillattr - Fill in the basic attributes from the inode struct
29 * @inode: Inode to use as the source
30 * @stat: Where to fill in the attributes
32 * Fill in the basic attributes in the kstat structure from data that's to be
33 * found on the VFS inode structure. This is the default if no getattr inode
34 * operation is supplied.
36 void generic_fillattr(struct inode
*inode
, struct kstat
*stat
)
38 stat
->dev
= inode
->i_sb
->s_dev
;
39 stat
->ino
= inode
->i_ino
;
40 stat
->mode
= inode
->i_mode
;
41 stat
->nlink
= inode
->i_nlink
;
42 stat
->uid
= inode
->i_uid
;
43 stat
->gid
= inode
->i_gid
;
44 stat
->rdev
= inode
->i_rdev
;
45 stat
->size
= i_size_read(inode
);
46 stat
->atime
= inode
->i_atime
;
47 stat
->mtime
= inode
->i_mtime
;
48 stat
->ctime
= inode
->i_ctime
;
49 stat
->blksize
= i_blocksize(inode
);
50 stat
->blocks
= inode
->i_blocks
;
52 EXPORT_SYMBOL(generic_fillattr
);
55 * vfs_getattr_nosec - getattr without security checks
56 * @path: file to get attributes from
57 * @stat: structure to return attributes in
58 * @request_mask: STATX_xxx flags indicating what the caller wants
59 * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
61 * Get attributes without calling security_inode_getattr.
63 * Currently the only caller other than vfs_getattr is internal to the
64 * filehandle lookup code, which uses only the inode number and returns no
65 * attributes to any user. Any other code probably wants vfs_getattr.
67 int vfs_getattr_nosec(const struct path
*path
, struct kstat
*stat
,
68 u32 request_mask
, unsigned int query_flags
)
70 struct inode
*inode
= d_backing_inode(path
->dentry
);
72 memset(stat
, 0, sizeof(*stat
));
73 stat
->result_mask
|= STATX_BASIC_STATS
;
74 query_flags
&= KSTAT_QUERY_FLAGS
;
76 /* allow the fs to override these if it really wants to */
77 /* SB_NOATIME means filesystem supplies dummy atime value */
78 if (inode
->i_sb
->s_flags
& SB_NOATIME
)
79 stat
->result_mask
&= ~STATX_ATIME
;
80 if (IS_AUTOMOUNT(inode
))
81 stat
->attributes
|= STATX_ATTR_AUTOMOUNT
;
84 stat
->attributes
|= STATX_ATTR_DAX
;
86 if (inode
->i_op
->getattr
)
87 return inode
->i_op
->getattr(path
, stat
, request_mask
,
90 generic_fillattr(inode
, stat
);
93 EXPORT_SYMBOL(vfs_getattr_nosec
);
96 * vfs_getattr - Get the enhanced basic attributes of a file
97 * @path: The file of interest
98 * @stat: Where to return the statistics
99 * @request_mask: STATX_xxx flags indicating what the caller wants
100 * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
102 * Ask the filesystem for a file's attributes. The caller must indicate in
103 * request_mask and query_flags to indicate what they want.
105 * If the file is remote, the filesystem can be forced to update the attributes
106 * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can
107 * suppress the update by passing AT_STATX_DONT_SYNC.
109 * Bits must have been set in request_mask to indicate which attributes the
110 * caller wants retrieving. Any such attribute not requested may be returned
111 * anyway, but the value may be approximate, and, if remote, may not have been
112 * synchronised with the server.
114 * 0 will be returned on success, and a -ve error code if unsuccessful.
116 int vfs_getattr(const struct path
*path
, struct kstat
*stat
,
117 u32 request_mask
, unsigned int query_flags
)
121 retval
= security_inode_getattr(path
);
124 return vfs_getattr_nosec(path
, stat
, request_mask
, query_flags
);
126 EXPORT_SYMBOL(vfs_getattr
);
129 * vfs_statx_fd - Get the enhanced basic attributes by file descriptor
130 * @fd: The file descriptor referring to the file of interest
131 * @stat: The result structure to fill in.
132 * @request_mask: STATX_xxx flags indicating what the caller wants
133 * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
135 * This function is a wrapper around vfs_getattr(). The main difference is
136 * that it uses a file descriptor to determine the file location.
138 * 0 will be returned on success, and a -ve error code if unsuccessful.
140 int vfs_statx_fd(unsigned int fd
, struct kstat
*stat
,
141 u32 request_mask
, unsigned int query_flags
)
146 if (query_flags
& ~KSTAT_QUERY_FLAGS
)
151 error
= vfs_getattr(&f
.file
->f_path
, stat
,
152 request_mask
, query_flags
);
157 EXPORT_SYMBOL(vfs_statx_fd
);
159 static inline unsigned vfs_stat_set_lookup_flags(unsigned *lookup_flags
,
162 if ((flags
& ~(AT_SYMLINK_NOFOLLOW
| AT_NO_AUTOMOUNT
|
163 AT_EMPTY_PATH
| KSTAT_QUERY_FLAGS
)) != 0)
166 *lookup_flags
= LOOKUP_FOLLOW
| LOOKUP_AUTOMOUNT
;
167 if (flags
& AT_SYMLINK_NOFOLLOW
)
168 *lookup_flags
&= ~LOOKUP_FOLLOW
;
169 if (flags
& AT_NO_AUTOMOUNT
)
170 *lookup_flags
&= ~LOOKUP_AUTOMOUNT
;
171 if (flags
& AT_EMPTY_PATH
)
172 *lookup_flags
|= LOOKUP_EMPTY
;
178 * vfs_statx - Get basic and extra attributes by filename
179 * @dfd: A file descriptor representing the base dir for a relative filename
180 * @filename: The name of the file of interest
181 * @flags: Flags to control the query
182 * @stat: The result structure to fill in.
183 * @request_mask: STATX_xxx flags indicating what the caller wants
185 * This function is a wrapper around vfs_getattr(). The main difference is
186 * that it uses a filename and base directory to determine the file location.
187 * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink
188 * at the given name from being referenced.
190 * 0 will be returned on success, and a -ve error code if unsuccessful.
192 int vfs_statx(int dfd
, const char __user
*filename
, int flags
,
193 struct kstat
*stat
, u32 request_mask
)
197 unsigned lookup_flags
;
199 if (vfs_stat_set_lookup_flags(&lookup_flags
, flags
))
202 error
= user_path_at(dfd
, filename
, lookup_flags
, &path
);
206 error
= vfs_getattr(&path
, stat
, request_mask
, flags
);
207 stat
->mnt_id
= real_mount(path
.mnt
)->mnt_id
;
208 stat
->result_mask
|= STATX_MNT_ID
;
209 if (path
.mnt
->mnt_root
== path
.dentry
)
210 stat
->attributes
|= STATX_ATTR_MOUNT_ROOT
;
211 stat
->attributes_mask
|= STATX_ATTR_MOUNT_ROOT
;
213 if (retry_estale(error
, lookup_flags
)) {
214 lookup_flags
|= LOOKUP_REVAL
;
220 EXPORT_SYMBOL(vfs_statx
);
223 #ifdef __ARCH_WANT_OLD_STAT
226 * For backward compatibility? Maybe this should be moved
227 * into arch/i386 instead?
229 static int cp_old_stat(struct kstat
*stat
, struct __old_kernel_stat __user
* statbuf
)
231 static int warncount
= 5;
232 struct __old_kernel_stat tmp
;
236 printk(KERN_WARNING
"VFS: Warning: %s using old stat() call. Recompile your binary.\n",
238 } else if (warncount
< 0) {
239 /* it's laughable, but... */
243 memset(&tmp
, 0, sizeof(struct __old_kernel_stat
));
244 tmp
.st_dev
= old_encode_dev(stat
->dev
);
245 tmp
.st_ino
= stat
->ino
;
246 if (sizeof(tmp
.st_ino
) < sizeof(stat
->ino
) && tmp
.st_ino
!= stat
->ino
)
248 tmp
.st_mode
= stat
->mode
;
249 tmp
.st_nlink
= stat
->nlink
;
250 if (tmp
.st_nlink
!= stat
->nlink
)
252 SET_UID(tmp
.st_uid
, from_kuid_munged(current_user_ns(), stat
->uid
));
253 SET_GID(tmp
.st_gid
, from_kgid_munged(current_user_ns(), stat
->gid
));
254 tmp
.st_rdev
= old_encode_dev(stat
->rdev
);
255 #if BITS_PER_LONG == 32
256 if (stat
->size
> MAX_NON_LFS
)
259 tmp
.st_size
= stat
->size
;
260 tmp
.st_atime
= stat
->atime
.tv_sec
;
261 tmp
.st_mtime
= stat
->mtime
.tv_sec
;
262 tmp
.st_ctime
= stat
->ctime
.tv_sec
;
263 return copy_to_user(statbuf
,&tmp
,sizeof(tmp
)) ? -EFAULT
: 0;
266 SYSCALL_DEFINE2(stat
, const char __user
*, filename
,
267 struct __old_kernel_stat __user
*, statbuf
)
272 error
= vfs_stat(filename
, &stat
);
276 return cp_old_stat(&stat
, statbuf
);
279 SYSCALL_DEFINE2(lstat
, const char __user
*, filename
,
280 struct __old_kernel_stat __user
*, statbuf
)
285 error
= vfs_lstat(filename
, &stat
);
289 return cp_old_stat(&stat
, statbuf
);
292 SYSCALL_DEFINE2(fstat
, unsigned int, fd
, struct __old_kernel_stat __user
*, statbuf
)
295 int error
= vfs_fstat(fd
, &stat
);
298 error
= cp_old_stat(&stat
, statbuf
);
303 #endif /* __ARCH_WANT_OLD_STAT */
305 #ifdef __ARCH_WANT_NEW_STAT
307 #if BITS_PER_LONG == 32
308 # define choose_32_64(a,b) a
310 # define choose_32_64(a,b) b
313 #define valid_dev(x) choose_32_64(old_valid_dev(x),true)
314 #define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x)
316 #ifndef INIT_STRUCT_STAT_PADDING
317 # define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))
320 static int cp_new_stat(struct kstat
*stat
, struct stat __user
*statbuf
)
324 if (!valid_dev(stat
->dev
) || !valid_dev(stat
->rdev
))
326 #if BITS_PER_LONG == 32
327 if (stat
->size
> MAX_NON_LFS
)
331 INIT_STRUCT_STAT_PADDING(tmp
);
332 tmp
.st_dev
= encode_dev(stat
->dev
);
333 tmp
.st_ino
= stat
->ino
;
334 if (sizeof(tmp
.st_ino
) < sizeof(stat
->ino
) && tmp
.st_ino
!= stat
->ino
)
336 tmp
.st_mode
= stat
->mode
;
337 tmp
.st_nlink
= stat
->nlink
;
338 if (tmp
.st_nlink
!= stat
->nlink
)
340 SET_UID(tmp
.st_uid
, from_kuid_munged(current_user_ns(), stat
->uid
));
341 SET_GID(tmp
.st_gid
, from_kgid_munged(current_user_ns(), stat
->gid
));
342 tmp
.st_rdev
= encode_dev(stat
->rdev
);
343 tmp
.st_size
= stat
->size
;
344 tmp
.st_atime
= stat
->atime
.tv_sec
;
345 tmp
.st_mtime
= stat
->mtime
.tv_sec
;
346 tmp
.st_ctime
= stat
->ctime
.tv_sec
;
347 #ifdef STAT_HAVE_NSEC
348 tmp
.st_atime_nsec
= stat
->atime
.tv_nsec
;
349 tmp
.st_mtime_nsec
= stat
->mtime
.tv_nsec
;
350 tmp
.st_ctime_nsec
= stat
->ctime
.tv_nsec
;
352 tmp
.st_blocks
= stat
->blocks
;
353 tmp
.st_blksize
= stat
->blksize
;
354 return copy_to_user(statbuf
,&tmp
,sizeof(tmp
)) ? -EFAULT
: 0;
357 SYSCALL_DEFINE2(newstat
, const char __user
*, filename
,
358 struct stat __user
*, statbuf
)
361 int error
= vfs_stat(filename
, &stat
);
365 return cp_new_stat(&stat
, statbuf
);
368 SYSCALL_DEFINE2(newlstat
, const char __user
*, filename
,
369 struct stat __user
*, statbuf
)
374 error
= vfs_lstat(filename
, &stat
);
378 return cp_new_stat(&stat
, statbuf
);
381 #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
382 SYSCALL_DEFINE4(newfstatat
, int, dfd
, const char __user
*, filename
,
383 struct stat __user
*, statbuf
, int, flag
)
388 error
= vfs_fstatat(dfd
, filename
, &stat
, flag
);
391 return cp_new_stat(&stat
, statbuf
);
395 SYSCALL_DEFINE2(newfstat
, unsigned int, fd
, struct stat __user
*, statbuf
)
398 int error
= vfs_fstat(fd
, &stat
);
401 error
= cp_new_stat(&stat
, statbuf
);
407 static int do_readlinkat(int dfd
, const char __user
*pathname
,
408 char __user
*buf
, int bufsiz
)
413 unsigned int lookup_flags
= LOOKUP_EMPTY
;
419 error
= user_path_at_empty(dfd
, pathname
, lookup_flags
, &path
, &empty
);
421 struct inode
*inode
= d_backing_inode(path
.dentry
);
423 error
= empty
? -ENOENT
: -EINVAL
;
425 * AFS mountpoints allow readlink(2) but are not symlinks
427 if (d_is_symlink(path
.dentry
) || inode
->i_op
->readlink
) {
428 error
= security_inode_readlink(path
.dentry
);
431 error
= vfs_readlink(path
.dentry
, buf
, bufsiz
);
435 if (retry_estale(error
, lookup_flags
)) {
436 lookup_flags
|= LOOKUP_REVAL
;
443 SYSCALL_DEFINE4(readlinkat
, int, dfd
, const char __user
*, pathname
,
444 char __user
*, buf
, int, bufsiz
)
446 return do_readlinkat(dfd
, pathname
, buf
, bufsiz
);
449 SYSCALL_DEFINE3(readlink
, const char __user
*, path
, char __user
*, buf
,
452 return do_readlinkat(AT_FDCWD
, path
, buf
, bufsiz
);
456 /* ---------- LFS-64 ----------- */
457 #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
459 #ifndef INIT_STRUCT_STAT64_PADDING
460 # define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))
463 static long cp_new_stat64(struct kstat
*stat
, struct stat64 __user
*statbuf
)
467 INIT_STRUCT_STAT64_PADDING(tmp
);
469 /* mips has weird padding, so we don't get 64 bits there */
470 tmp
.st_dev
= new_encode_dev(stat
->dev
);
471 tmp
.st_rdev
= new_encode_dev(stat
->rdev
);
473 tmp
.st_dev
= huge_encode_dev(stat
->dev
);
474 tmp
.st_rdev
= huge_encode_dev(stat
->rdev
);
476 tmp
.st_ino
= stat
->ino
;
477 if (sizeof(tmp
.st_ino
) < sizeof(stat
->ino
) && tmp
.st_ino
!= stat
->ino
)
479 #ifdef STAT64_HAS_BROKEN_ST_INO
480 tmp
.__st_ino
= stat
->ino
;
482 tmp
.st_mode
= stat
->mode
;
483 tmp
.st_nlink
= stat
->nlink
;
484 tmp
.st_uid
= from_kuid_munged(current_user_ns(), stat
->uid
);
485 tmp
.st_gid
= from_kgid_munged(current_user_ns(), stat
->gid
);
486 tmp
.st_atime
= stat
->atime
.tv_sec
;
487 tmp
.st_atime_nsec
= stat
->atime
.tv_nsec
;
488 tmp
.st_mtime
= stat
->mtime
.tv_sec
;
489 tmp
.st_mtime_nsec
= stat
->mtime
.tv_nsec
;
490 tmp
.st_ctime
= stat
->ctime
.tv_sec
;
491 tmp
.st_ctime_nsec
= stat
->ctime
.tv_nsec
;
492 tmp
.st_size
= stat
->size
;
493 tmp
.st_blocks
= stat
->blocks
;
494 tmp
.st_blksize
= stat
->blksize
;
495 return copy_to_user(statbuf
,&tmp
,sizeof(tmp
)) ? -EFAULT
: 0;
498 SYSCALL_DEFINE2(stat64
, const char __user
*, filename
,
499 struct stat64 __user
*, statbuf
)
502 int error
= vfs_stat(filename
, &stat
);
505 error
= cp_new_stat64(&stat
, statbuf
);
510 SYSCALL_DEFINE2(lstat64
, const char __user
*, filename
,
511 struct stat64 __user
*, statbuf
)
514 int error
= vfs_lstat(filename
, &stat
);
517 error
= cp_new_stat64(&stat
, statbuf
);
522 SYSCALL_DEFINE2(fstat64
, unsigned long, fd
, struct stat64 __user
*, statbuf
)
525 int error
= vfs_fstat(fd
, &stat
);
528 error
= cp_new_stat64(&stat
, statbuf
);
533 SYSCALL_DEFINE4(fstatat64
, int, dfd
, const char __user
*, filename
,
534 struct stat64 __user
*, statbuf
, int, flag
)
539 error
= vfs_fstatat(dfd
, filename
, &stat
, flag
);
542 return cp_new_stat64(&stat
, statbuf
);
544 #endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */
546 static noinline_for_stack
int
547 cp_statx(const struct kstat
*stat
, struct statx __user
*buffer
)
551 memset(&tmp
, 0, sizeof(tmp
));
553 tmp
.stx_mask
= stat
->result_mask
;
554 tmp
.stx_blksize
= stat
->blksize
;
555 tmp
.stx_attributes
= stat
->attributes
;
556 tmp
.stx_nlink
= stat
->nlink
;
557 tmp
.stx_uid
= from_kuid_munged(current_user_ns(), stat
->uid
);
558 tmp
.stx_gid
= from_kgid_munged(current_user_ns(), stat
->gid
);
559 tmp
.stx_mode
= stat
->mode
;
560 tmp
.stx_ino
= stat
->ino
;
561 tmp
.stx_size
= stat
->size
;
562 tmp
.stx_blocks
= stat
->blocks
;
563 tmp
.stx_attributes_mask
= stat
->attributes_mask
;
564 tmp
.stx_atime
.tv_sec
= stat
->atime
.tv_sec
;
565 tmp
.stx_atime
.tv_nsec
= stat
->atime
.tv_nsec
;
566 tmp
.stx_btime
.tv_sec
= stat
->btime
.tv_sec
;
567 tmp
.stx_btime
.tv_nsec
= stat
->btime
.tv_nsec
;
568 tmp
.stx_ctime
.tv_sec
= stat
->ctime
.tv_sec
;
569 tmp
.stx_ctime
.tv_nsec
= stat
->ctime
.tv_nsec
;
570 tmp
.stx_mtime
.tv_sec
= stat
->mtime
.tv_sec
;
571 tmp
.stx_mtime
.tv_nsec
= stat
->mtime
.tv_nsec
;
572 tmp
.stx_rdev_major
= MAJOR(stat
->rdev
);
573 tmp
.stx_rdev_minor
= MINOR(stat
->rdev
);
574 tmp
.stx_dev_major
= MAJOR(stat
->dev
);
575 tmp
.stx_dev_minor
= MINOR(stat
->dev
);
576 tmp
.stx_mnt_id
= stat
->mnt_id
;
578 return copy_to_user(buffer
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
581 int do_statx(int dfd
, const char __user
*filename
, unsigned flags
,
582 unsigned int mask
, struct statx __user
*buffer
)
587 if (mask
& STATX__RESERVED
)
589 if ((flags
& AT_STATX_SYNC_TYPE
) == AT_STATX_SYNC_TYPE
)
592 error
= vfs_statx(dfd
, filename
, flags
, &stat
, mask
);
596 return cp_statx(&stat
, buffer
);
600 * sys_statx - System call to get enhanced stats
601 * @dfd: Base directory to pathwalk from *or* fd to stat.
602 * @filename: File to stat or "" with AT_EMPTY_PATH
603 * @flags: AT_* flags to control pathwalk.
604 * @mask: Parts of statx struct actually required.
605 * @buffer: Result buffer.
607 * Note that fstat() can be emulated by setting dfd to the fd of interest,
608 * supplying "" as the filename and setting AT_EMPTY_PATH in the flags.
610 SYSCALL_DEFINE5(statx
,
611 int, dfd
, const char __user
*, filename
, unsigned, flags
,
613 struct statx __user
*, buffer
)
615 return do_statx(dfd
, filename
, flags
, mask
, buffer
);
619 static int cp_compat_stat(struct kstat
*stat
, struct compat_stat __user
*ubuf
)
621 struct compat_stat tmp
;
623 if (!old_valid_dev(stat
->dev
) || !old_valid_dev(stat
->rdev
))
626 memset(&tmp
, 0, sizeof(tmp
));
627 tmp
.st_dev
= old_encode_dev(stat
->dev
);
628 tmp
.st_ino
= stat
->ino
;
629 if (sizeof(tmp
.st_ino
) < sizeof(stat
->ino
) && tmp
.st_ino
!= stat
->ino
)
631 tmp
.st_mode
= stat
->mode
;
632 tmp
.st_nlink
= stat
->nlink
;
633 if (tmp
.st_nlink
!= stat
->nlink
)
635 SET_UID(tmp
.st_uid
, from_kuid_munged(current_user_ns(), stat
->uid
));
636 SET_GID(tmp
.st_gid
, from_kgid_munged(current_user_ns(), stat
->gid
));
637 tmp
.st_rdev
= old_encode_dev(stat
->rdev
);
638 if ((u64
) stat
->size
> MAX_NON_LFS
)
640 tmp
.st_size
= stat
->size
;
641 tmp
.st_atime
= stat
->atime
.tv_sec
;
642 tmp
.st_atime_nsec
= stat
->atime
.tv_nsec
;
643 tmp
.st_mtime
= stat
->mtime
.tv_sec
;
644 tmp
.st_mtime_nsec
= stat
->mtime
.tv_nsec
;
645 tmp
.st_ctime
= stat
->ctime
.tv_sec
;
646 tmp
.st_ctime_nsec
= stat
->ctime
.tv_nsec
;
647 tmp
.st_blocks
= stat
->blocks
;
648 tmp
.st_blksize
= stat
->blksize
;
649 return copy_to_user(ubuf
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
652 COMPAT_SYSCALL_DEFINE2(newstat
, const char __user
*, filename
,
653 struct compat_stat __user
*, statbuf
)
658 error
= vfs_stat(filename
, &stat
);
661 return cp_compat_stat(&stat
, statbuf
);
664 COMPAT_SYSCALL_DEFINE2(newlstat
, const char __user
*, filename
,
665 struct compat_stat __user
*, statbuf
)
670 error
= vfs_lstat(filename
, &stat
);
673 return cp_compat_stat(&stat
, statbuf
);
676 #ifndef __ARCH_WANT_STAT64
677 COMPAT_SYSCALL_DEFINE4(newfstatat
, unsigned int, dfd
,
678 const char __user
*, filename
,
679 struct compat_stat __user
*, statbuf
, int, flag
)
684 error
= vfs_fstatat(dfd
, filename
, &stat
, flag
);
687 return cp_compat_stat(&stat
, statbuf
);
691 COMPAT_SYSCALL_DEFINE2(newfstat
, unsigned int, fd
,
692 struct compat_stat __user
*, statbuf
)
695 int error
= vfs_fstat(fd
, &stat
);
698 error
= cp_compat_stat(&stat
, statbuf
);
703 /* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
704 void __inode_add_bytes(struct inode
*inode
, loff_t bytes
)
706 inode
->i_blocks
+= bytes
>> 9;
708 inode
->i_bytes
+= bytes
;
709 if (inode
->i_bytes
>= 512) {
711 inode
->i_bytes
-= 512;
714 EXPORT_SYMBOL(__inode_add_bytes
);
716 void inode_add_bytes(struct inode
*inode
, loff_t bytes
)
718 spin_lock(&inode
->i_lock
);
719 __inode_add_bytes(inode
, bytes
);
720 spin_unlock(&inode
->i_lock
);
723 EXPORT_SYMBOL(inode_add_bytes
);
725 void __inode_sub_bytes(struct inode
*inode
, loff_t bytes
)
727 inode
->i_blocks
-= bytes
>> 9;
729 if (inode
->i_bytes
< bytes
) {
731 inode
->i_bytes
+= 512;
733 inode
->i_bytes
-= bytes
;
736 EXPORT_SYMBOL(__inode_sub_bytes
);
738 void inode_sub_bytes(struct inode
*inode
, loff_t bytes
)
740 spin_lock(&inode
->i_lock
);
741 __inode_sub_bytes(inode
, bytes
);
742 spin_unlock(&inode
->i_lock
);
745 EXPORT_SYMBOL(inode_sub_bytes
);
747 loff_t
inode_get_bytes(struct inode
*inode
)
751 spin_lock(&inode
->i_lock
);
752 ret
= __inode_get_bytes(inode
);
753 spin_unlock(&inode
->i_lock
);
757 EXPORT_SYMBOL(inode_get_bytes
);
759 void inode_set_bytes(struct inode
*inode
, loff_t bytes
)
761 /* Caller is here responsible for sufficient locking
762 * (ie. inode->i_lock) */
763 inode
->i_blocks
= bytes
>> 9;
764 inode
->i_bytes
= bytes
& 511;
767 EXPORT_SYMBOL(inode_set_bytes
);