You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
2.3 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "func_create_ff.hpp"
  2. #include "fileinfo.hpp"
  3. #include "fs_acl.hpp"
  4. #include "fs_info.hpp"
  5. #include "fs_open.hpp"
  6. #include "fs_openat.hpp"
  7. #include "func_open_create_utils.hpp"
  8. #include "ugid.hpp"
  9. #include <errno.h>
  10. Func2::CreateFF::CreateFF()
  11. {
  12. }
  13. Func2::CreateFF::~CreateFF()
  14. {
  15. }
  16. namespace l
  17. {
  18. static
  19. int
  20. create(Branches2 &branches_,
  21. fs::Path const &fusepath_,
  22. mode_t const mode_,
  23. mode_t const umask_,
  24. fuse_file_info_t *ffi_)
  25. {
  26. int rv;
  27. mode_t mode;
  28. FileInfo *fi;
  29. fs::info_t info;
  30. fs::Path fullpath;
  31. mode = mode_;
  32. for(auto &tier : branches_)
  33. {
  34. for(auto &branch : tier)
  35. {
  36. if(branch.mode != +Branch2::Mode::RW)
  37. continue;
  38. rv = fs::info(branch.path,&info);
  39. if(rv == -1)
  40. continue;
  41. if(info.readonly)
  42. continue;
  43. if(info.spaceavail < branch.min_free_space)
  44. continue;
  45. fullpath = branch.path / fusepath_;
  46. if(!fs::acl::dir_has_defaults(fullpath))
  47. mode &= ~umask_;
  48. rv = fs::openat(branch.fd,fusepath_,ffi_->flags,mode);
  49. if((rv == -1) && (errno == ENOENT))
  50. {
  51. branches_.clonepath(branch.path,fusepath_);
  52. rv = fs::openat(branch.fd,fusepath_,ffi_->flags,mode);
  53. }
  54. if((rv == -1) && (errno == EROFS))
  55. {
  56. branch.mode = Branch2::Mode::RO;
  57. continue;
  58. }
  59. fi = new FileInfo(rv,fusepath_.string().c_str(),ffi_->direct_io);
  60. ffi_->fh = reinterpret_cast<uint64_t>(fi);
  61. return 0;
  62. }
  63. }
  64. return rv;
  65. }
  66. }
  67. int
  68. Func2::CreateFF::operator()(Branches2 &branches_,
  69. fs::Path const &fusepath_,
  70. mode_t const mode_,
  71. fuse_file_info_t *ffi_)
  72. {
  73. int rv;
  74. Config::Read cfg;
  75. fuse_context const *fc = fuse_get_context();
  76. ugid::Set const ugid(fc->uid,fc->gid);
  77. utils::cfg_to_ffi_flags(cfg,fc->pid,ffi_);
  78. if(cfg->writeback_cache)
  79. utils::tweak_flags_writeback_cache(&ffi_->flags);
  80. ffi_->noflush = !utils::calculate_flush(cfg->flushonclose,ffi_->flags);
  81. rv = l::create(branches_,fusepath_,mode_,fc->umask,ffi_);
  82. return rv;
  83. }