If a loop exists in directories due to a symlink: /a/b/c -> /a
We now return -ELOOP from path_walk() instead of looping forever.
Signed-off-by: Sam Lang <sam.lang@inktank.com>
ldout(cct, 10) << "path_walk " << path << dendl;
+ set<Inode*,Inode::Compare> visited;
unsigned i=0;
while (i < path.depth() && cur) {
const string &dname = path[i];
// 'directory' symlinks.
if (next && next->is_symlink()) {
if (i < path.depth() - 1) {
+ // check for loops
+ if(visited.find(next) != visited.end()) {
+ // already hit this one, return error
+ return -ELOOP;
+ }
+ visited.insert(next);
+
// dir symlink
// replace consumed components of path with symlink dir target
filepath resolved(next->symlink.c_str());
vinodeno_t vino() { return vinodeno_t(ino, snapid); }
+ struct Compare {
+ bool operator() (Inode* const & left, Inode* const & right) {
+ if (left->ino.val < right->ino.val) {
+ return (left->snapid.val < right->snapid.val);
+ }
+ return false;
+ }
+ };
bool check_mode(uid_t uid, gid_t gid, gid_t *sgids, int sgid_count, uint32_t flags);