Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Compare file prefix only.
[simgrid.git] / src / surf / FileImpl.cpp
1 /* Copyright (c) 2017. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "src/surf/FileImpl.hpp"
8 #include "src/surf/StorageImpl.hpp"
9
10 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_file, surf, "Logging specific to the SURF file module");
11 namespace simgrid {
12 namespace surf {
13
14 FileImpl::FileImpl(sg_storage_t st, std::string path, std::string mount) : path_(path), mount_point_(mount)
15 {
16   XBT_DEBUG("\tOpen file '%s'", path.c_str());
17   location_ = st->getImpl();
18   std::map<std::string, sg_size_t>* content = location_->getContent();
19   // if file does not exist create an empty file
20   auto sz = content->find(path);
21   if (sz != content->end()) {
22     size_ = sz->second;
23   } else {
24     size_ = 0;
25     content->insert({path, size_});
26     XBT_DEBUG("File '%s' was not found, file created.", path.c_str());
27   }
28 }
29
30 Action* FileImpl::read(sg_size_t size)
31 {
32   XBT_DEBUG("READ %s on disk '%s'", cname(), location_->cname());
33   if (current_position_ + size > size_) {
34     if (current_position_ > size_) {
35       size = 0;
36     } else {
37       size = size_ - current_position_;
38     }
39     current_position_ = size_;
40   } else
41     current_position_ += size;
42
43   return location_->read(size);
44 }
45
46 Action* FileImpl::write(sg_size_t size)
47 {
48   XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu'", cname(), location_->cname(), size, size_);
49
50   StorageAction* action = location_->write(size);
51   action->file_         = this;
52   /* Substract the part of the file that might disappear from the used sized on the storage element */
53   location_->usedSize_ -= (size_ - current_position_);
54   // If the storage is full before even starting to write
55   if (location_->usedSize_ >= location_->getSize()) {
56     action->setState(Action::State::failed);
57   }
58   return action;
59 }
60
61 int FileImpl::seek(sg_offset_t offset, int origin)
62 {
63   switch (origin) {
64     case SEEK_SET:
65       current_position_ = offset;
66       return 0;
67     case SEEK_CUR:
68       current_position_ += offset;
69       return 0;
70     case SEEK_END:
71       current_position_ = size_ + offset;
72       return 0;
73     default:
74       return -1;
75   }
76 }
77
78 int FileImpl::unlink()
79 {
80   /* Check if the file is on this storage */
81   if (location_->getContent()->find(path_) == location_->getContent()->end()) {
82     XBT_WARN("File %s is not on disk %s. Impossible to unlink", cname(), location_->cname());
83     return -1;
84   } else {
85     XBT_DEBUG("UNLINK %s on disk '%s'", cname(), location_->cname());
86     location_->usedSize_ -= size_;
87
88     // Remove the file from storage
89     location_->getContent()->erase(path_);
90
91     return 0;
92   }
93 }
94
95 void FileImpl::move(std::string fullpath)
96 {
97   /* Check if the new full path is on the same mount point */
98   if (not strncmp(mount_point_.c_str(), fullpath.c_str(), mount_point_.size())) {
99     std::map<std::string, sg_size_t>* content = location_->getContent();
100     auto sz = content->find(path_);
101     if (sz != content->end()) { // src file exists
102       sg_size_t new_size = sz->second;
103       content->erase(path_);
104       std::string path = fullpath.substr(mount_point_.length(), fullpath.length());
105       content->insert({path.c_str(), new_size});
106       XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath.c_str(), new_size);
107     } else {
108       XBT_WARN("File %s doesn't exist", path_.c_str());
109     }
110   } else {
111     XBT_WARN("New full path %s is not on the same mount point: %s.", fullpath.c_str(), mount_point_.c_str());
112   }
113 }
114 }
115 }