statfs.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #include <linux/syscalls.h>
  2. #include <linux/export.h>
  3. #include <linux/fs.h>
  4. #include <linux/file.h>
  5. #include <linux/mount.h>
  6. #include <linux/namei.h>
  7. #include <linux/statfs.h>
  8. #include <linux/security.h>
  9. #include <linux/uaccess.h>
  10. #include "internal.h"
  11. static int flags_by_mnt(int mnt_flags)
  12. {
  13. int flags = 0;
  14. if (mnt_flags & MNT_READONLY)
  15. flags |= ST_RDONLY;
  16. if (mnt_flags & MNT_NOSUID)
  17. flags |= ST_NOSUID;
  18. if (mnt_flags & MNT_NODEV)
  19. flags |= ST_NODEV;
  20. if (mnt_flags & MNT_NOEXEC)
  21. flags |= ST_NOEXEC;
  22. if (mnt_flags & MNT_NOATIME)
  23. flags |= ST_NOATIME;
  24. if (mnt_flags & MNT_NODIRATIME)
  25. flags |= ST_NODIRATIME;
  26. if (mnt_flags & MNT_RELATIME)
  27. flags |= ST_RELATIME;
  28. return flags;
  29. }
  30. static int flags_by_sb(int s_flags)
  31. {
  32. int flags = 0;
  33. if (s_flags & MS_SYNCHRONOUS)
  34. flags |= ST_SYNCHRONOUS;
  35. if (s_flags & MS_MANDLOCK)
  36. flags |= ST_MANDLOCK;
  37. return flags;
  38. }
  39. static int calculate_f_flags(struct vfsmount *mnt)
  40. {
  41. return ST_VALID | flags_by_mnt(mnt->mnt_flags) |
  42. flags_by_sb(mnt->mnt_sb->s_flags);
  43. }
  44. static int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf)
  45. {
  46. int retval;
  47. if (!dentry->d_sb->s_op->statfs)
  48. return -ENOSYS;
  49. memset(buf, 0, sizeof(*buf));
  50. retval = security_sb_statfs(dentry);
  51. if (retval)
  52. return retval;
  53. retval = dentry->d_sb->s_op->statfs(dentry, buf);
  54. if (retval == 0 && buf->f_frsize == 0)
  55. buf->f_frsize = buf->f_bsize;
  56. return retval;
  57. }
  58. int vfs_statfs(struct path *path, struct kstatfs *buf)
  59. {
  60. int error;
  61. error = statfs_by_dentry(path->dentry, buf);
  62. if (!error)
  63. buf->f_flags = calculate_f_flags(path->mnt);
  64. return error;
  65. }
  66. EXPORT_SYMBOL(vfs_statfs);
  67. int user_statfs(const char __user *pathname, struct kstatfs *st)
  68. {
  69. struct path path;
  70. int error;
  71. unsigned int lookup_flags = LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT;
  72. retry:
  73. error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
  74. if (!error) {
  75. error = vfs_statfs(&path, st);
  76. path_put(&path);
  77. if (retry_estale(error, lookup_flags)) {
  78. lookup_flags |= LOOKUP_REVAL;
  79. goto retry;
  80. }
  81. }
  82. return error;
  83. }
  84. int fd_statfs(int fd, struct kstatfs *st)
  85. {
  86. struct fd f = fdget_raw(fd);
  87. int error = -EBADF;
  88. if (f.file) {
  89. error = vfs_statfs(&f.file->f_path, st);
  90. fdput(f);
  91. }
  92. return error;
  93. }
  94. static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
  95. {
  96. struct statfs buf;
  97. if (sizeof(buf) == sizeof(*st))
  98. memcpy(&buf, st, sizeof(*st));
  99. else {
  100. if (sizeof buf.f_blocks == 4) {
  101. if ((st->f_blocks | st->f_bfree | st->f_bavail |
  102. st->f_bsize | st->f_frsize) &
  103. 0xffffffff00000000ULL)
  104. return -EOVERFLOW;
  105. /*
  106. * f_files and f_ffree may be -1; it's okay to stuff
  107. * that into 32 bits
  108. */
  109. if (st->f_files != -1 &&
  110. (st->f_files & 0xffffffff00000000ULL))
  111. return -EOVERFLOW;
  112. if (st->f_ffree != -1 &&
  113. (st->f_ffree & 0xffffffff00000000ULL))
  114. return -EOVERFLOW;
  115. }
  116. buf.f_type = st->f_type;
  117. buf.f_bsize = st->f_bsize;
  118. buf.f_blocks = st->f_blocks;
  119. buf.f_bfree = st->f_bfree;
  120. buf.f_bavail = st->f_bavail;
  121. buf.f_files = st->f_files;
  122. buf.f_ffree = st->f_ffree;
  123. buf.f_fsid = st->f_fsid;
  124. buf.f_namelen = st->f_namelen;
  125. buf.f_frsize = st->f_frsize;
  126. buf.f_flags = st->f_flags;
  127. memset(buf.f_spare, 0, sizeof(buf.f_spare));
  128. }
  129. if (copy_to_user(p, &buf, sizeof(buf)))
  130. return -EFAULT;
  131. return 0;
  132. }
  133. static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
  134. {
  135. struct statfs64 buf;
  136. if (sizeof(buf) == sizeof(*st))
  137. memcpy(&buf, st, sizeof(*st));
  138. else {
  139. buf.f_type = st->f_type;
  140. buf.f_bsize = st->f_bsize;
  141. buf.f_blocks = st->f_blocks;
  142. buf.f_bfree = st->f_bfree;
  143. buf.f_bavail = st->f_bavail;
  144. buf.f_files = st->f_files;
  145. buf.f_ffree = st->f_ffree;
  146. buf.f_fsid = st->f_fsid;
  147. buf.f_namelen = st->f_namelen;
  148. buf.f_frsize = st->f_frsize;
  149. buf.f_flags = st->f_flags;
  150. memset(buf.f_spare, 0, sizeof(buf.f_spare));
  151. }
  152. if (copy_to_user(p, &buf, sizeof(buf)))
  153. return -EFAULT;
  154. return 0;
  155. }
  156. SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf)
  157. {
  158. struct kstatfs st;
  159. int error = user_statfs(pathname, &st);
  160. if (!error)
  161. error = do_statfs_native(&st, buf);
  162. return error;
  163. }
  164. SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf)
  165. {
  166. struct kstatfs st;
  167. int error;
  168. if (sz != sizeof(*buf))
  169. return -EINVAL;
  170. error = user_statfs(pathname, &st);
  171. if (!error)
  172. error = do_statfs64(&st, buf);
  173. return error;
  174. }
  175. SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf)
  176. {
  177. struct kstatfs st;
  178. int error = fd_statfs(fd, &st);
  179. if (!error)
  180. error = do_statfs_native(&st, buf);
  181. return error;
  182. }
  183. SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf)
  184. {
  185. struct kstatfs st;
  186. int error;
  187. if (sz != sizeof(*buf))
  188. return -EINVAL;
  189. error = fd_statfs(fd, &st);
  190. if (!error)
  191. error = do_statfs64(&st, buf);
  192. return error;
  193. }
  194. int vfs_ustat(dev_t dev, struct kstatfs *sbuf)
  195. {
  196. struct super_block *s = user_get_super(dev);
  197. int err;
  198. if (!s)
  199. return -EINVAL;
  200. err = statfs_by_dentry(s->s_root, sbuf);
  201. drop_super(s);
  202. return err;
  203. }
  204. SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf)
  205. {
  206. struct ustat tmp;
  207. struct kstatfs sbuf;
  208. int err = vfs_ustat(new_decode_dev(dev), &sbuf);
  209. if (err)
  210. return err;
  211. memset(&tmp,0,sizeof(struct ustat));
  212. tmp.f_tfree = sbuf.f_bfree;
  213. tmp.f_tinode = sbuf.f_ffree;
  214. return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0;
  215. }