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 statfs_by_dentry(struct dentry
*dentry
, struct kstatfs
*buf
)
14 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
;
27 int vfs_statfs(struct path
*path
, struct kstatfs
*buf
)
29 return statfs_by_dentry(path
->dentry
, buf
);
31 EXPORT_SYMBOL(vfs_statfs
);
33 static int do_statfs_native(struct path
*path
, struct statfs
*buf
)
38 retval
= vfs_statfs(path
, &st
);
42 if (sizeof(*buf
) == sizeof(st
))
43 memcpy(buf
, &st
, sizeof(st
));
45 if (sizeof buf
->f_blocks
== 4) {
46 if ((st
.f_blocks
| st
.f_bfree
| st
.f_bavail
|
47 st
.f_bsize
| st
.f_frsize
) &
48 0xffffffff00000000ULL
)
51 * f_files and f_ffree may be -1; it's okay to stuff
54 if (st
.f_files
!= -1 &&
55 (st
.f_files
& 0xffffffff00000000ULL
))
57 if (st
.f_ffree
!= -1 &&
58 (st
.f_ffree
& 0xffffffff00000000ULL
))
62 buf
->f_type
= st
.f_type
;
63 buf
->f_bsize
= st
.f_bsize
;
64 buf
->f_blocks
= st
.f_blocks
;
65 buf
->f_bfree
= st
.f_bfree
;
66 buf
->f_bavail
= st
.f_bavail
;
67 buf
->f_files
= st
.f_files
;
68 buf
->f_ffree
= st
.f_ffree
;
69 buf
->f_fsid
= st
.f_fsid
;
70 buf
->f_namelen
= st
.f_namelen
;
71 buf
->f_frsize
= st
.f_frsize
;
72 memset(buf
->f_spare
, 0, sizeof(buf
->f_spare
));
77 static int do_statfs64(struct path
*path
, struct statfs64
*buf
)
82 retval
= vfs_statfs(path
, &st
);
86 if (sizeof(*buf
) == sizeof(st
))
87 memcpy(buf
, &st
, sizeof(st
));
89 buf
->f_type
= st
.f_type
;
90 buf
->f_bsize
= st
.f_bsize
;
91 buf
->f_blocks
= st
.f_blocks
;
92 buf
->f_bfree
= st
.f_bfree
;
93 buf
->f_bavail
= st
.f_bavail
;
94 buf
->f_files
= st
.f_files
;
95 buf
->f_ffree
= st
.f_ffree
;
96 buf
->f_fsid
= st
.f_fsid
;
97 buf
->f_namelen
= st
.f_namelen
;
98 buf
->f_frsize
= st
.f_frsize
;
99 memset(buf
->f_spare
, 0, sizeof(buf
->f_spare
));
104 SYSCALL_DEFINE2(statfs
, const char __user
*, pathname
, struct statfs __user
*, buf
)
109 error
= user_path(pathname
, &path
);
112 error
= do_statfs_native(&path
, &tmp
);
113 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
120 SYSCALL_DEFINE3(statfs64
, const char __user
*, pathname
, size_t, sz
, struct statfs64 __user
*, buf
)
125 if (sz
!= sizeof(*buf
))
127 error
= user_path(pathname
, &path
);
130 error
= do_statfs64(&path
, &tmp
);
131 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
138 SYSCALL_DEFINE2(fstatfs
, unsigned int, fd
, struct statfs __user
*, buf
)
148 error
= do_statfs_native(&file
->f_path
, &tmp
);
149 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
156 SYSCALL_DEFINE3(fstatfs64
, unsigned int, fd
, size_t, sz
, struct statfs64 __user
*, buf
)
162 if (sz
!= sizeof(*buf
))
169 error
= do_statfs64(&file
->f_path
, &tmp
);
170 if (!error
&& copy_to_user(buf
, &tmp
, sizeof(tmp
)))
177 SYSCALL_DEFINE2(ustat
, unsigned, dev
, struct ustat __user
*, ubuf
)
179 struct super_block
*s
;
184 s
= user_get_super(new_decode_dev(dev
));
188 err
= statfs_by_dentry(s
->s_root
, &sbuf
);
193 memset(&tmp
,0,sizeof(struct ustat
));
194 tmp
.f_tfree
= sbuf
.f_bfree
;
195 tmp
.f_tinode
= sbuf
.f_ffree
;
197 return copy_to_user(ubuf
, &tmp
, sizeof(struct ustat
)) ? -EFAULT
: 0;
This page took 0.034009 seconds and 5 git commands to generate.