statvfs.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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/VirtualFileSystem.h>
  8. #include <Kernel/Process.h>
  9. namespace Kernel {
  10. KResultOr<FlatPtr> Process::do_statvfs(String path, statvfs* buf)
  11. {
  12. auto custody_or_error = VirtualFileSystem::the().resolve_path(path, current_directory(), nullptr, 0);
  13. if (custody_or_error.is_error())
  14. return custody_or_error.error();
  15. auto& custody = custody_or_error.value();
  16. auto& inode = custody->inode();
  17. auto& fs = inode.fs();
  18. statvfs kernelbuf = {};
  19. kernelbuf.f_bsize = static_cast<u64>(fs.block_size());
  20. kernelbuf.f_frsize = fs.fragment_size();
  21. kernelbuf.f_blocks = fs.total_block_count();
  22. kernelbuf.f_bfree = fs.free_block_count();
  23. // FIXME: Implement "available blocks" into Filesystem
  24. kernelbuf.f_bavail = fs.free_block_count();
  25. kernelbuf.f_files = fs.total_inode_count();
  26. kernelbuf.f_ffree = fs.free_inode_count();
  27. kernelbuf.f_favail = fs.free_inode_count(); // FIXME: same as f_bavail
  28. kernelbuf.f_fsid = 0; // FIXME: Implement "Filesystem ID" into Filesystem
  29. kernelbuf.f_namemax = 255;
  30. Custody* current_custody = custody;
  31. while (current_custody) {
  32. VirtualFileSystem::the().for_each_mount([&kernelbuf, &current_custody](auto& mount) {
  33. if (current_custody) {
  34. if (&current_custody->inode() == &mount.guest()) {
  35. int mountflags = mount.flags();
  36. int flags = 0;
  37. if (mountflags & MS_RDONLY)
  38. flags = flags | ST_RDONLY;
  39. if (mountflags & MS_NOSUID)
  40. flags = flags | ST_NOSUID;
  41. kernelbuf.f_flag = flags;
  42. current_custody = nullptr;
  43. }
  44. }
  45. });
  46. if (current_custody) {
  47. current_custody = current_custody->parent();
  48. }
  49. }
  50. if (!copy_to_user(buf, &kernelbuf))
  51. return EFAULT;
  52. return 0;
  53. }
  54. KResultOr<FlatPtr> Process::sys$statvfs(Userspace<const Syscall::SC_statvfs_params*> user_params)
  55. {
  56. VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
  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. VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
  69. REQUIRE_PROMISE(stdio);
  70. auto description = fds().file_description(fd);
  71. if (!description)
  72. return EBADF;
  73. return do_statvfs(description->absolute_path(), buf);
  74. }
  75. }