1 #include <linux/syscalls.h>
2 #include <linux/module.h>
4 #include <linux/file.h>
5 #include <linux/namei.h>
6 #include <linux/statfs.h>
7 #include <linux/security.h>
8 #include <linux/uaccess.h>
10 int vfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
16 if (dentry
->d_sb
->s_op
->statfs
) {
17 memset(buf
, 0, sizeof(*buf
));
18 retval
= security_sb_statfs(dentry
);
21 retval
= dentry
->d_sb
->s_op
->statfs(dentry
, buf
);
22 if (retval
== 0 && buf
->f_frsize
== 0)
23 buf
->f_frsize
= buf
->f_bsize
;
29 EXPORT_SYMBOL(vfs_statfs
);
31 static int vfs_statfs_native(struct dentry
*dentry
, struct statfs
*buf
)
36 retval
= vfs_statfs(dentry
, &st
);
40 if (sizeof(*buf
) == sizeof(st
))
41 memcpy(buf
, &st
, sizeof(st
));
43 if (sizeof buf
->f_blocks
== 4) {
44 if ((st
.f_blocks
| st
.f_bfree
| st
.f_bavail
|
45 st
.f_bsize
| st
.f_frsize
) &
46 0xffffffff00000000ULL
)
49 * f_files and f_ffree may be -1; it's okay to stuff
52 if (st
.f_files
!= -1 &&
53 (st
.f_files
& 0xffffffff00000000ULL
))
55 if (st
.f_ffree
!= -1 &&
56 (st
.f_ffree
& 0xffffffff00000000ULL
))
60 buf
->f_type
= st
.f_type
;
61 buf
->f_bsize
= st
.f_bsize
;
62 buf
->f_blocks
= st
.f_blocks
;
63 buf
->f_bfree
= st
.f_bfree
;
64 buf
->f_bavail
= st
.f_bavail
;
65 buf
->f_files
= st
.f_files
;
66 buf
->f_ffree
= st
.f_ffree
;
67 buf
->f_fsid
= st
.f_fsid
;
68 buf
->f_namelen
= st
.f_namelen
;
69 buf
->f_frsize
= st
.f_frsize
;
70 memset(buf
->f_spare
, 0, sizeof(buf
->f_spare
));
75 static int vfs_statfs64(struct dentry
*dentry
, struct statfs64
*buf
)
80 retval
= vfs_statfs(dentry
, &st
);
84 if (sizeof(*buf
) == sizeof(st
))
85 memcpy(buf
, &st
, sizeof(st
));
87 buf
->f_type
= st
.f_type
;
88 buf
->f_bsize
= st
.f_bsize
;
89 buf
->f_blocks
= st
.f_blocks
;
90 buf
->f_bfree
= st
.f_bfree
;
91 buf
->f_bavail
= st
.f_bavail
;
92 buf
->f_files
= st
.f_files
;
93 buf
->f_ffree
= st
.f_ffree
;
94 buf
->f_fsid
= st
.f_fsid
;
95 buf
->f_namelen
= st
.f_namelen
;
96 buf
->f_frsize
= st
.f_frsize
;
97 memset(buf
->f_spare
, 0, sizeof(buf
->f_spare
));
102 SYSCALL_DEFINE2(statfs
, const char __user
*, pathname
, struct statfs __user
*, buf
)
107 error
= user_path(pathname
, &path
);
110 error
= vfs_statfs_native(path
.dentry
, &tmp
);
111 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
118 SYSCALL_DEFINE3(statfs64
, const char __user
*, pathname
, size_t, sz
, struct statfs64 __user
*, buf
)
123 if (sz
!= sizeof(*buf
))
125 error
= user_path(pathname
, &path
);
128 error
= vfs_statfs64(path
.dentry
, &tmp
);
129 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
136 SYSCALL_DEFINE2(fstatfs
, unsigned int, fd
, struct statfs __user
*, buf
)
146 error
= vfs_statfs_native(file
->f_path
.dentry
, &tmp
);
147 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
154 SYSCALL_DEFINE3(fstatfs64
, unsigned int, fd
, size_t, sz
, struct statfs64 __user
*, buf
)
160 if (sz
!= sizeof(*buf
))
167 error
= vfs_statfs64(file
->f_path
.dentry
, &tmp
);
168 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
175 SYSCALL_DEFINE2(ustat
, unsigned, dev
, struct ustat __user
*, ubuf
)
177 struct super_block
*s
;
182 s
= user_get_super(new_decode_dev(dev
));
186 err
= vfs_statfs(s
->s_root
, &sbuf
);
191 memset(&tmp
,0,sizeof(struct ustat
));
192 tmp
.f_tfree
= sbuf
.f_bfree
;
193 tmp
.f_tinode
= sbuf
.f_ffree
;
195 return copy_to_user(ubuf
, &tmp
, sizeof(struct ustat
)) ? -EFAULT
: 0;