statvfs.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2021, Justin Mietzner <sw1tchbl4d3@sw1tchbl4d3.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/FileSystem/Custody.h>
  7. #include <Kernel/FileSystem/FileDescription.h>
  8. #include <Kernel/FileSystem/VirtualFileSystem.h>
  9. #include <Kernel/Process.h>
  10. namespace Kernel {
  11. KResultOr<FlatPtr> Process::do_statvfs(String path, statvfs* buf)
  12. {
  13. auto custody_or_error = VFS::the().resolve_path(path, current_directory(), nullptr, 0);
  14. if (custody_or_error.is_error())
  15. return custody_or_error.error();
  16. auto& custody = custody_or_error.value();
  17. auto& inode = custody->inode();
  18. auto& fs = inode.fs();
  19. statvfs kernelbuf = {};
  20. kernelbuf.f_bsize = static_cast<u64>(fs.block_size());
  21. kernelbuf.f_frsize = fs.fragment_size();
  22. kernelbuf.f_blocks = fs.total_block_count();
  23. kernelbuf.f_bfree = fs.free_block_count();
  24. // FIXME: Implement "available blocks" into Filesystem
  25. kernelbuf.f_bavail = fs.free_block_count();
  26. kernelbuf.f_files = fs.total_inode_count();
  27. kernelbuf.f_ffree = fs.free_inode_count();
  28. kernelbuf.f_favail = fs.free_inode_count(); // FIXME: same as f_bavail
  29. kernelbuf.f_fsid = 0; // FIXME: Implement "Filesystem ID" into Filesystem
  30. kernelbuf.f_namemax = 255;
  31. Custody* current_custody = custody;
  32. while (current_custody) {
  33. VFS::the().for_each_mount([&kernelbuf, &current_custody](auto& mount) {
  34. if (current_custody) {
  35. if (&current_custody->inode() == &mount.guest()) {
  36. int mountflags = mount.flags();
  37. int flags = 0;
  38. if (mountflags & MS_RDONLY)
  39. flags = flags | ST_RDONLY;
  40. if (mountflags & MS_NOSUID)
  41. flags = flags | ST_NOSUID;
  42. kernelbuf.f_flag = flags;
  43. current_custody = nullptr;
  44. }
  45. }
  46. });
  47. if (current_custody) {
  48. current_custody = current_custody->parent();
  49. }
  50. }
  51. if (!copy_to_user(buf, &kernelbuf))
  52. return EFAULT;
  53. return 0;
  54. }
  55. KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
  56. {
  57. REQUIRE_PROMISE(rpath);
  58. Syscall::SC_statvfs_params params;
  59. if (!copy_from_user(&params, user_params))
  60. return EFAULT;
  61. auto path = get_syscall_path_argument(params.path);
  62. if (path.is_error())
  63. return path.error();
  64. return do_statvfs(path.value()->view(), params.buf);
  65. }
  66. KResultOr<FlatPtr> Process::sys$fstatvfs(int fd, statvfs* buf)
  67. {
  68. REQUIRE_PROMISE(stdio);
  69. auto description = file_description(fd);
  70. if (!description)
  71. return EBADF;
  72. return do_statvfs(description->absolute_path(), buf);
  73. }
  74. }