]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
client: avoid multiple calls to path_walk
authorPatrick Donnelly <pdonnell@ibm.com>
Tue, 11 Mar 2025 14:28:01 +0000 (10:28 -0400)
committerPatrick Donnelly <pdonnell@ibm.com>
Mon, 17 Mar 2025 19:43:24 +0000 (15:43 -0400)
When we wrap a dname after a path walk, we cannot do another path walk.
Originally this method was setup to permit that but with (upcoming) encryption
it cannot work. The dname from the path_walk is in the encrypted namespace so
we cannot do another lookup in a second path_walk.

Signed-off-by: Patrick Donnelly <pdonnell@ibm.com>
(cherry picked from commit af8d267e5f8123eaf3cb311b7d608025468429f9)

src/client/Client.cc
src/client/Client.h

index 63fc0dec0030fba8f675ab398680c90de9690372..674a2a606367fa02bc7bb66b10d839699c185fd5 100644 (file)
@@ -7873,7 +7873,13 @@ int Client::do_mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPe
   if (r < 0) {
     return r;
   }
-  return _mkdir(dirinode.get(), relpath, mode, perm, 0, {}, std::move(alternate_name));
+
+  walk_dentry_result wdr;
+  if (int rc = path_walk(dirinode, filepath(relpath), &wdr, perm, {.require_target = false}); rc < 0) {
+    return rc;
+  }
+
+  return _mkdir(wdr, mode, perm, 0, {}, std::move(alternate_name));
 }
 
 int Client::mkdirs(const char *relpath, mode_t mode, const UserPerm& perms)
@@ -7895,7 +7901,7 @@ int Client::mkdirs(const char *relpath, mode_t mode, const UserPerm& perms)
     if (int rc = path_walk(cwd, path, &wdr, perms, {.followsym = false}); rc < 0) {
       if (rc == -ENOENT) {
         InodeRef in;
-        rc = _mkdir(wdr.diri.get(), wdr.dname.c_str(), mode, perms, &in);
+        rc = _mkdir(wdr, mode, perms, &in);
         switch (rc) {
           case 0:
           case EEXIST:
@@ -12988,12 +12994,15 @@ int Client::mksnap(const char *relpath, const char *name, const UserPerm& perm,
     return -ENOTCONN;
 
   std::scoped_lock l(client_lock);
-  InodeRef in;
-  if (int rc = path_walk(cwd, filepath(relpath), &in, perm, {}); rc < 0) {
+  walk_dentry_result wdr;
+  if (int rc = path_walk(cwd, filepath(relpath), &wdr, perm, {}); rc < 0) {
     return rc;
   }
-  auto snapdir = open_snapdir(in.get());
-  return _mkdir(snapdir.get(), name, mode, perm, nullptr, metadata);
+  auto snapdir = open_snapdir(wdr.target);
+  if (int rc = path_walk(std::move(snapdir), filepath(name), &wdr, perm, {.require_target = false}); rc < 0) {
+    return rc;
+  }
+  return _mkdir(wdr, mode, perm, nullptr, metadata);
 }
 
 int Client::rmsnap(const char *relpath, const char *name, const UserPerm& perms, bool check_perms)
@@ -14806,18 +14815,15 @@ int Client::_create(const walk_dentry_result& wdr, int flags, mode_t mode,
   return res;
 }
 
-int Client::_mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm,
+int Client::_mkdir(const walk_dentry_result& wdr, mode_t mode, const UserPerm& perm,
                   InodeRef *inp, const std::map<std::string, std::string> &metadata,
                    std::string alternate_name)
 {
-  ldout(cct, 8) << "_mkdir(" << dir->ino << " " << name << ", 0" << oct
-               << mode << dec << ", uid " << perm.uid()
+  ldout(cct, 8) << "_mkdir(" << wdr << ", 0o" << std::oct << mode << std::dec
+               << ", uid " << perm.uid()
                << ", gid " << perm.gid() << ")" << dendl;
 
-  walk_dentry_result wdr;
-  if (int rc = path_walk(dir, filepath(name), &wdr, perm, {.require_target = false}); rc < 0) {
-    return rc;
-  } else if (rc == 0 && wdr.target) {
+  if (wdr.target) {
     return -EEXIST;
   }
 
@@ -14896,8 +14902,13 @@ int Client::ll_mkdir(Inode *parent, const char *name, mode_t mode,
 
   std::scoped_lock lock(client_lock);
 
+  walk_dentry_result wdr;
+  if (int rc = path_walk(parent, filepath(name), &wdr, perm, {.require_target = false}); rc < 0) {
+    return rc;
+  }
+
   InodeRef in;
-  int r = _mkdir(parent, name, mode, perm, &in);
+  int r = _mkdir(wdr, mode, perm, &in);
   if (r == 0) {
     fill_stat(in, attr);
     _ll_get(in.get());
@@ -14927,8 +14938,13 @@ int Client::ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out,
 
   std::scoped_lock lock(client_lock);
 
+  walk_dentry_result wdr;
+  if (int rc = path_walk(parent, filepath(name), &wdr, perms, {.require_target = false}); rc < 0) {
+    return rc;
+  }
+
   InodeRef in;
-  int r = _mkdir(parent, name, mode, perms, &in);
+  int r = _mkdir(wdr, mode, perms, &in);
   if (r == 0) {
     fill_statx(in, statx_to_mask(flags, want), stx);
     _ll_get(in.get());
index 0f2cbb172c6b29499b4d21440af325e8fcdba790..2337d9a027e90b6812f9d54cb0ca44d472561cf1 100644 (file)
@@ -1683,7 +1683,7 @@ private:
   int _link(Inode *diri_from, const char* path_from, Inode* diri_to, const char* path_to, const UserPerm& perm, std::string alternate_name);
   int _unlink(Inode *dir, const char *name, const UserPerm& perm);
   int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, const UserPerm& perm, std::string alternate_name);
-  int _mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm,
+  int _mkdir(const walk_dentry_result& wdr, mode_t mode, const UserPerm& perm,
             InodeRef *inp = 0, const std::map<std::string, std::string> &metadata={},
              std::string alternate_name="");
   int _rmdir(Inode *dir, const char *name, const UserPerm& perms, bool check_perms=true);