1
+ /* ***********************************************************************
2
+ * EOS - the CERN Disk Storage System *
3
+ * Copyright (C) 2018 CERN/Switzerland *
4
+ * *
5
+ * This program is free software: you can redistribute it and/or modify *
6
+ * it under the terms of the GNU General Public License as published by *
7
+ * the Free Software Foundation, either version 3 of the License, or *
8
+ * (at your option) any later version. *
9
+ * *
10
+ * This program is distributed in the hope that it will be useful, *
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
+ * GNU General Public License for more details. *
14
+ * *
15
+ * You should have received a copy of the GNU General Public License *
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.*
17
+ ************************************************************************/
18
+
19
+ // ------------------------------------------------------------------------------
20
+ // ! @author Georgios Bitzes <[email protected] >
21
+ // ! @brief Helper function to check if it's safe to rename a directory into
22
+ // ! another
23
+ // ------------------------------------------------------------------------------
24
+
25
+ #ifndef EOS_NS_RENAME_SAFETY_CHECK_HH
26
+ #define EOS_NS_RENAME_SAFETY_CHECK_HH
27
+
28
+ #include < iostream>
29
+ #include " namespace/interface/IContainerMD.hh"
30
+ #include " namespace/interface/IView.hh"
31
+ #include " namespace/Namespace.hh"
32
+ #include " common/Logging.hh"
33
+
34
+ EOSNSNAMESPACE_BEGIN
35
+
36
+ // ------------------------------------------------------------------------------
37
+ // Is it safe to make "source" directory a subdirectory of "target"?
38
+ // Assumes eosViewRWMutex is at-least read-locked when calling this function.
39
+ // ------------------------------------------------------------------------------
40
+ bool isSafeToRename (IView *view, IContainerMD *source, IContainerMD *target) {
41
+ if (source == target) return false ;
42
+
43
+ IContainerMDSvc *svc = view->getContainerMDSvc ();
44
+ IContainerMDPtr current = svc->getContainerMD (target->getParentId ());
45
+
46
+ size_t iterations = 0 ;
47
+ while (true ) {
48
+ iterations++;
49
+
50
+ if (iterations > 1024 ) {
51
+ std::string msg = SSTR (" potential loop when scanning parents of container "
52
+ << target->getId () << " - serious namespace corruption" );
53
+
54
+ eos_static_crit (" %s" , msg.c_str ());
55
+ throw_mdexception (EFAULT, msg);
56
+ }
57
+
58
+ if (current.get () == source) {
59
+ return false ; // Nope, sound alarm, this rename is not safe
60
+ }
61
+
62
+ if (current->getId () == source->getId ()) {
63
+ // Should not happen.
64
+ eos_static_crit (" %s" , SSTR (" Two containers with the same ID ended up with different objects in memory - " <<
65
+ current->getId () << " == " << source->getId () << " - " << current << " vs " << source));
66
+ return false ;
67
+ }
68
+
69
+ if (current->getId () == 1 ) {
70
+ // We've reached root, this rename looks safe.
71
+ return true ;
72
+ }
73
+
74
+ // Move up one step.
75
+ current = svc->getContainerMD (current->getParentId ());
76
+ }
77
+ }
78
+
79
+ EOSNSNAMESPACE_END
80
+
81
+ #endif
0 commit comments