XRootD
Loading...
Searching...
No Matches
XrdPfcFsTraversal.cc
Go to the documentation of this file.
2#include "XrdPfcDirState.hh"
3#include "XrdPfc.hh"
4#include "XrdPfcTrace.hh"
5
6#include "XrdOuc/XrdOucEnv.hh"
7#include "XrdOss/XrdOssApi.hh"
8
9// #define TRACE_PURGE(x) std::cout << "PURGE " << x << "\n"
10#define TRACE_PURGE(x)
11
12using namespace XrdPfc;
13
14namespace
15{
16 XrdSysTrace* GetTrace() { return Cache::GetInstance().GetTrace(); }
17}
18
19const char *FsTraversal::m_traceID = "FsTraversal";
20
21//----------------------------------------------------------------------------
22
24 m_oss(oss), m_oss_at(oss)
25{}
26
29
31{
32 int ret = 0;
33 if (ossDF) {
34 ret = ossDF->Close();
35 delete ossDF;
36 }
37 ossDF = nullptr;
38 return ret;
39}
40
41//----------------------------------------------------------------------------
42
43bool FsTraversal::begin_traversal(DirState *root, const char *root_path)
44{
47
48 bool ret = begin_traversal(root_path);
49
50 return ret;
51}
52
53bool FsTraversal::begin_traversal(const char *root_path)
54{
55 static const char *trc_pfx = "FsTraversal::begin_traversal ";
56
57 assert(root_path && strlen(root_path) > 0 && root_path[0] == '/');
58
60 m_current_path = root_path;
61
62 XrdOssDF* dhp = m_oss.newDir("PfcFsTraversal");
63 if (dhp->Opendir(root_path, m_env) != XrdOssOK) {
64 delete dhp;
65 TRACE(Error, trc_pfx << "could not opendir [" << root_path << "], " << XrdSysE2T(errno));
66 return false;
67 }
68 m_dir_handle_stack.push_back(dhp);
69
70 TRACE_PURGE("FPurgeState::begin_traversal cur_path '" << m_current_path << "', rel_level=" << m_rel_dir_level);
71
73 return true;
74}
75
77{
78 TRACE_PURGE("FPurgeState::end_traversal reporting for '" << m_current_path << "', re_level=" << m_rel_dir_level);
79
80 for (auto &dhp : m_dir_handle_stack) {
81 dhp->Close();
82 delete dhp;
83 }
84 m_dir_handle_stack.clear();
85 m_current_path.clear();
86 m_current_dirs.clear();
87 m_current_files.clear();
88
89 m_rel_dir_level = -1;
90 m_root_dir_state = m_dir_state = nullptr;
91 m_maintain_dirstate = false;
92}
93
94//----------------------------------------------------------------------------
95
96bool FsTraversal::cd_down(const std::string &dir_name)
97{
98 static const char *trc_pfx = "FsTraversal::cd_down ";
99
100 XrdOssDF *dhp = 0;
101 if (m_oss_at.Opendir(*m_dir_handle_stack.back(), dir_name.c_str(), m_env, dhp) != XrdOssOK) {
102 delete dhp;
103 TRACE(Error, trc_pfx << "could not opendir [" << m_current_path << dir_name << "], " << XrdSysE2T(errno));
104 return false;
105 }
106 m_dir_handle_stack.push_back(dhp);
107
109 m_current_path.append(dir_name);
110 m_current_path.append("/");
111
113 m_dir_state = m_dir_state->find_dir(dir_name, true);
114
116 return true;
117}
118
120{
121 m_current_dirs.clear();
122 m_current_files.clear();
123
124 m_dir_handle_stack.back()->Close();
125 delete m_dir_handle_stack.back();
126 m_dir_handle_stack.pop_back();
127
129 m_dir_state = m_dir_state->get_parent();
130
131 m_current_path.erase(m_current_path.find_last_of('/', m_current_path.size() - 2) + 1);
133}
134
135//----------------------------------------------------------------------------
136
138{
139 static const char *trc_pfx = "FsTraversal::slurp_current_dir ";
140
141 XrdOssDF &dh = *m_dir_handle_stack.back();
142 slurp_dir_ll(dh, m_rel_dir_level, m_current_path.c_str(), trc_pfx);
143}
144
145//----------------------------------------------------------------------------
146
147void FsTraversal::slurp_dir_ll(XrdOssDF &dh, int dir_level, const char *path, const char *trc_pfx)
148{
149 // Low-level implementation of slurp dir.
150
151 char fname[256];
152 struct stat fstat;
153
154 dh.StatRet(&fstat);
155
156 const char *info_ext = Info::s_infoExtension;
157 const size_t info_ext_len = Info::s_infoExtensionLen;
158
159 m_current_dirs.clear();
160 m_current_files.clear();
161
162 while (true)
163 {
164 int rc = dh.Readdir(fname, 256);
165
166 if (rc == -ENOENT)
167 {
168 TRACE_PURGE(" Skipping ENOENT dir entry [" << fname << "].");
169 continue;
170 }
171 if (rc != XrdOssOK)
172 {
173 TRACE(Error, trc_pfx << "Readdir error at " << path << ", err " << XrdSysE2T(-rc) << ".");
174 break;
175 }
176
177 TRACE_PURGE(" Readdir [" << fname << "]");
178
179 if (fname[0] == 0)
180 {
181 TRACE_PURGE(" Finished reading dir [" << path << "]. Break loop.");
182 break;
183 }
184 if (fname[0] == '.' && (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0)))
185 {
186 TRACE_PURGE(" Skipping here or parent dir [" << fname << "]. Continue loop.");
187 continue;
188 }
189
190 if (S_ISDIR(fstat.st_mode))
191 {
192 if (dir_level == 0 && m_protected_top_dirs.find(fname) != m_protected_top_dirs.end())
193 {
194 // Skip protected top-directories.
195 continue;
196 }
197 m_current_dirs.push_back(fname);
198 }
199 else
200 {
201 size_t fname_len = strlen(fname);
202
203 if (fname_len > info_ext_len && strncmp(&fname[fname_len - info_ext_len], info_ext, info_ext_len) == 0)
204 {
205 // truncate ".cinfo" away
206 fname[fname_len - info_ext_len] = 0;
207 m_current_files[fname].set_cinfo(fstat);
208 }
209 else
210 {
211 m_current_files[fname].set_data(fstat);
212 }
213 }
214 }
215}
#define XrdOssOK
Definition XrdOss.hh:50
#define TRACE_PURGE(x)
#define fstat(a, b)
Definition XrdPosix.hh:62
#define stat(a, b)
Definition XrdPosix.hh:101
const char * XrdSysE2T(int errcode)
Definition XrdSysE2T.cc:104
#define TRACE(act, x)
Definition XrdTrace.hh:63
virtual int StatRet(struct stat *buff)
Definition XrdOss.hh:107
virtual int Opendir(const char *path, XrdOucEnv &env)
Definition XrdOss.hh:79
virtual int Readdir(char *buff, int blen)
Definition XrdOss.hh:92
virtual int Close(long long *retsz=0)=0
XrdSysTrace * GetTrace()
Definition XrdPfc.hh:283
static Cache & GetInstance()
Singleton access.
Definition XrdPfc.cc:132
std::vector< std::string > m_current_dirs
std::vector< XrdOssDF * > m_dir_handle_stack
int close_delete(XrdOssDF *&ossDF)
void slurp_dir_ll(XrdOssDF &dh, int dir_level, const char *path, const char *trc_pfx)
bool begin_traversal(DirState *root, const char *root_path)
std::set< std::string > m_protected_top_dirs
bool cd_down(const std::string &dir_name)
std::map< std::string, FilePairStat > m_current_files
static const char * m_traceID
static const char * s_infoExtension
static const size_t s_infoExtensionLen