1*7ed1ee61SAl Viro #include <linux/syscalls.h> 2*7ed1ee61SAl Viro #include <linux/module.h> 3*7ed1ee61SAl Viro #include <linux/fs.h> 4*7ed1ee61SAl Viro #include <linux/file.h> 5*7ed1ee61SAl Viro #include <linux/namei.h> 6*7ed1ee61SAl Viro #include <linux/statfs.h> 7*7ed1ee61SAl Viro #include <linux/security.h> 8*7ed1ee61SAl Viro #include <linux/uaccess.h> 9*7ed1ee61SAl Viro 10*7ed1ee61SAl Viro int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) 11*7ed1ee61SAl Viro { 12*7ed1ee61SAl Viro int retval = -ENODEV; 13*7ed1ee61SAl Viro 14*7ed1ee61SAl Viro if (dentry) { 15*7ed1ee61SAl Viro retval = -ENOSYS; 16*7ed1ee61SAl Viro if (dentry->d_sb->s_op->statfs) { 17*7ed1ee61SAl Viro memset(buf, 0, sizeof(*buf)); 18*7ed1ee61SAl Viro retval = security_sb_statfs(dentry); 19*7ed1ee61SAl Viro if (retval) 20*7ed1ee61SAl Viro return retval; 21*7ed1ee61SAl Viro retval = dentry->d_sb->s_op->statfs(dentry, buf); 22*7ed1ee61SAl Viro if (retval == 0 && buf->f_frsize == 0) 23*7ed1ee61SAl Viro buf->f_frsize = buf->f_bsize; 24*7ed1ee61SAl Viro } 25*7ed1ee61SAl Viro } 26*7ed1ee61SAl Viro return retval; 27*7ed1ee61SAl Viro } 28*7ed1ee61SAl Viro 29*7ed1ee61SAl Viro EXPORT_SYMBOL(vfs_statfs); 30*7ed1ee61SAl Viro 31*7ed1ee61SAl Viro static int vfs_statfs_native(struct dentry *dentry, struct statfs *buf) 32*7ed1ee61SAl Viro { 33*7ed1ee61SAl Viro struct kstatfs st; 34*7ed1ee61SAl Viro int retval; 35*7ed1ee61SAl Viro 36*7ed1ee61SAl Viro retval = vfs_statfs(dentry, &st); 37*7ed1ee61SAl Viro if (retval) 38*7ed1ee61SAl Viro return retval; 39*7ed1ee61SAl Viro 40*7ed1ee61SAl Viro if (sizeof(*buf) == sizeof(st)) 41*7ed1ee61SAl Viro memcpy(buf, &st, sizeof(st)); 42*7ed1ee61SAl Viro else { 43*7ed1ee61SAl Viro if (sizeof buf->f_blocks == 4) { 44*7ed1ee61SAl Viro if ((st.f_blocks | st.f_bfree | st.f_bavail | 45*7ed1ee61SAl Viro st.f_bsize | st.f_frsize) & 46*7ed1ee61SAl Viro 0xffffffff00000000ULL) 47*7ed1ee61SAl Viro return -EOVERFLOW; 48*7ed1ee61SAl Viro /* 49*7ed1ee61SAl Viro * f_files and f_ffree may be -1; it's okay to stuff 50*7ed1ee61SAl Viro * that into 32 bits 51*7ed1ee61SAl Viro */ 52*7ed1ee61SAl Viro if (st.f_files != -1 && 53*7ed1ee61SAl Viro (st.f_files & 0xffffffff00000000ULL)) 54*7ed1ee61SAl Viro return -EOVERFLOW; 55*7ed1ee61SAl Viro if (st.f_ffree != -1 && 56*7ed1ee61SAl Viro (st.f_ffree & 0xffffffff00000000ULL)) 57*7ed1ee61SAl Viro return -EOVERFLOW; 58*7ed1ee61SAl Viro } 59*7ed1ee61SAl Viro 60*7ed1ee61SAl Viro buf->f_type = st.f_type; 61*7ed1ee61SAl Viro buf->f_bsize = st.f_bsize; 62*7ed1ee61SAl Viro buf->f_blocks = st.f_blocks; 63*7ed1ee61SAl Viro buf->f_bfree = st.f_bfree; 64*7ed1ee61SAl Viro buf->f_bavail = st.f_bavail; 65*7ed1ee61SAl Viro buf->f_files = st.f_files; 66*7ed1ee61SAl Viro buf->f_ffree = st.f_ffree; 67*7ed1ee61SAl Viro buf->f_fsid = st.f_fsid; 68*7ed1ee61SAl Viro buf->f_namelen = st.f_namelen; 69*7ed1ee61SAl Viro buf->f_frsize = st.f_frsize; 70*7ed1ee61SAl Viro memset(buf->f_spare, 0, sizeof(buf->f_spare)); 71*7ed1ee61SAl Viro } 72*7ed1ee61SAl Viro return 0; 73*7ed1ee61SAl Viro } 74*7ed1ee61SAl Viro 75*7ed1ee61SAl Viro static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf) 76*7ed1ee61SAl Viro { 77*7ed1ee61SAl Viro struct kstatfs st; 78*7ed1ee61SAl Viro int retval; 79*7ed1ee61SAl Viro 80*7ed1ee61SAl Viro retval = vfs_statfs(dentry, &st); 81*7ed1ee61SAl Viro if (retval) 82*7ed1ee61SAl Viro return retval; 83*7ed1ee61SAl Viro 84*7ed1ee61SAl Viro if (sizeof(*buf) == sizeof(st)) 85*7ed1ee61SAl Viro memcpy(buf, &st, sizeof(st)); 86*7ed1ee61SAl Viro else { 87*7ed1ee61SAl Viro buf->f_type = st.f_type; 88*7ed1ee61SAl Viro buf->f_bsize = st.f_bsize; 89*7ed1ee61SAl Viro buf->f_blocks = st.f_blocks; 90*7ed1ee61SAl Viro buf->f_bfree = st.f_bfree; 91*7ed1ee61SAl Viro buf->f_bavail = st.f_bavail; 92*7ed1ee61SAl Viro buf->f_files = st.f_files; 93*7ed1ee61SAl Viro buf->f_ffree = st.f_ffree; 94*7ed1ee61SAl Viro buf->f_fsid = st.f_fsid; 95*7ed1ee61SAl Viro buf->f_namelen = st.f_namelen; 96*7ed1ee61SAl Viro buf->f_frsize = st.f_frsize; 97*7ed1ee61SAl Viro memset(buf->f_spare, 0, sizeof(buf->f_spare)); 98*7ed1ee61SAl Viro } 99*7ed1ee61SAl Viro return 0; 100*7ed1ee61SAl Viro } 101*7ed1ee61SAl Viro 102*7ed1ee61SAl Viro SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) 103*7ed1ee61SAl Viro { 104*7ed1ee61SAl Viro struct path path; 105*7ed1ee61SAl Viro int error; 106*7ed1ee61SAl Viro 107*7ed1ee61SAl Viro error = user_path(pathname, &path); 108*7ed1ee61SAl Viro if (!error) { 109*7ed1ee61SAl Viro struct statfs tmp; 110*7ed1ee61SAl Viro error = vfs_statfs_native(path.dentry, &tmp); 111*7ed1ee61SAl Viro if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 112*7ed1ee61SAl Viro error = -EFAULT; 113*7ed1ee61SAl Viro path_put(&path); 114*7ed1ee61SAl Viro } 115*7ed1ee61SAl Viro return error; 116*7ed1ee61SAl Viro } 117*7ed1ee61SAl Viro 118*7ed1ee61SAl Viro SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) 119*7ed1ee61SAl Viro { 120*7ed1ee61SAl Viro struct path path; 121*7ed1ee61SAl Viro long error; 122*7ed1ee61SAl Viro 123*7ed1ee61SAl Viro if (sz != sizeof(*buf)) 124*7ed1ee61SAl Viro return -EINVAL; 125*7ed1ee61SAl Viro error = user_path(pathname, &path); 126*7ed1ee61SAl Viro if (!error) { 127*7ed1ee61SAl Viro struct statfs64 tmp; 128*7ed1ee61SAl Viro error = vfs_statfs64(path.dentry, &tmp); 129*7ed1ee61SAl Viro if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 130*7ed1ee61SAl Viro error = -EFAULT; 131*7ed1ee61SAl Viro path_put(&path); 132*7ed1ee61SAl Viro } 133*7ed1ee61SAl Viro return error; 134*7ed1ee61SAl Viro } 135*7ed1ee61SAl Viro 136*7ed1ee61SAl Viro SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) 137*7ed1ee61SAl Viro { 138*7ed1ee61SAl Viro struct file *file; 139*7ed1ee61SAl Viro struct statfs tmp; 140*7ed1ee61SAl Viro int error; 141*7ed1ee61SAl Viro 142*7ed1ee61SAl Viro error = -EBADF; 143*7ed1ee61SAl Viro file = fget(fd); 144*7ed1ee61SAl Viro if (!file) 145*7ed1ee61SAl Viro goto out; 146*7ed1ee61SAl Viro error = vfs_statfs_native(file->f_path.dentry, &tmp); 147*7ed1ee61SAl Viro if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 148*7ed1ee61SAl Viro error = -EFAULT; 149*7ed1ee61SAl Viro fput(file); 150*7ed1ee61SAl Viro out: 151*7ed1ee61SAl Viro return error; 152*7ed1ee61SAl Viro } 153*7ed1ee61SAl Viro 154*7ed1ee61SAl Viro SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) 155*7ed1ee61SAl Viro { 156*7ed1ee61SAl Viro struct file *file; 157*7ed1ee61SAl Viro struct statfs64 tmp; 158*7ed1ee61SAl Viro int error; 159*7ed1ee61SAl Viro 160*7ed1ee61SAl Viro if (sz != sizeof(*buf)) 161*7ed1ee61SAl Viro return -EINVAL; 162*7ed1ee61SAl Viro 163*7ed1ee61SAl Viro error = -EBADF; 164*7ed1ee61SAl Viro file = fget(fd); 165*7ed1ee61SAl Viro if (!file) 166*7ed1ee61SAl Viro goto out; 167*7ed1ee61SAl Viro error = vfs_statfs64(file->f_path.dentry, &tmp); 168*7ed1ee61SAl Viro if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 169*7ed1ee61SAl Viro error = -EFAULT; 170*7ed1ee61SAl Viro fput(file); 171*7ed1ee61SAl Viro out: 172*7ed1ee61SAl Viro return error; 173*7ed1ee61SAl Viro } 174*7ed1ee61SAl Viro 175*7ed1ee61SAl Viro SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) 176*7ed1ee61SAl Viro { 177*7ed1ee61SAl Viro struct super_block *s; 178*7ed1ee61SAl Viro struct ustat tmp; 179*7ed1ee61SAl Viro struct kstatfs sbuf; 180*7ed1ee61SAl Viro int err; 181*7ed1ee61SAl Viro 182*7ed1ee61SAl Viro s = user_get_super(new_decode_dev(dev)); 183*7ed1ee61SAl Viro if (!s) 184*7ed1ee61SAl Viro return -EINVAL; 185*7ed1ee61SAl Viro 186*7ed1ee61SAl Viro err = vfs_statfs(s->s_root, &sbuf); 187*7ed1ee61SAl Viro drop_super(s); 188*7ed1ee61SAl Viro if (err) 189*7ed1ee61SAl Viro return err; 190*7ed1ee61SAl Viro 191*7ed1ee61SAl Viro memset(&tmp,0,sizeof(struct ustat)); 192*7ed1ee61SAl Viro tmp.f_tfree = sbuf.f_bfree; 193*7ed1ee61SAl Viro tmp.f_tinode = sbuf.f_ffree; 194*7ed1ee61SAl Viro 195*7ed1ee61SAl Viro return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; 196*7ed1ee61SAl Viro } 197