]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs: add ceph_may_delete function
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Fri, 26 Feb 2021 08:32:38 +0000 (08:32 +0000)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Fri, 12 Mar 2021 14:39:48 +0000 (14:39 +0000)
We're adding a new libcephfs function: ceph_may_delete. It checks
if the mount permissions allow deleting a file or directory, without
actually deleting it.

This will allow us to drop the redundant permission checks at
ceph-dokan level, saving about 1500 LOC.

Note that the "DeleteFile" Dokan callback expects us to say if a
delete operation is allowed. The "Cleanup" callback is supposed
to perform the actual file or directory deletion.

Signed-off-by: Lucian Petrut <lpetrut@cloudbasesolutions.com>
(cherry picked from commit 439add6ff7db90ed0597611582354a7e938db5f4)

src/client/Client.cc
src/client/Client.h
src/include/cephfs/libcephfs.h
src/libcephfs.cc

index 8a6aab1c7d778e6adc0d9d04b54a18f5907dae55..c8a82085cf2765f6c822e773dc5ab9be3cd80d82 100644 (file)
@@ -5771,6 +5771,31 @@ out:
   return r;
 }
 
+int Client::may_delete(const char *relpath, const UserPerm& perms) {
+  ldout(cct, 20) << __func__ << " " << relpath << "; " << perms << dendl;
+
+  RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
+  if (!mref_reader.is_state_satisfied())
+    return -ENOTCONN;
+
+  filepath path(relpath);
+  string name = path.last_dentry();
+  path.pop_dentry();
+  InodeRef dir;
+
+  std::scoped_lock lock(client_lock);
+  int r = path_walk(path, &dir, perms);
+  if (r < 0)
+    return r;
+  if (cct->_conf->client_permissions) {
+    int r = may_delete(dir.get(), name.c_str(), perms);
+    if (r < 0)
+      return r;
+  }
+
+  return 0;
+}
+
 int Client::may_hardlink(Inode *in, const UserPerm& perms)
 {
   ldout(cct, 20) << __func__ << " " << *in << "; " << perms << dendl;
index 84e49e4f372706e2851bee029c7387765996cccd..fedeb027875cbaa87333e41de2c9c9c1fc82811a 100644 (file)
@@ -369,6 +369,7 @@ public:
   loff_t telldir(dir_result_t *dirp);
   void seekdir(dir_result_t *dirp, loff_t offset);
 
+  int may_delete(const char *relpath, const UserPerm& perms);
   int link(const char *existing, const char *newname, const UserPerm& perm, std::string alternate_name="");
   int unlink(const char *path, const UserPerm& perm);
   int rename(const char *from, const char *to, const UserPerm& perm, std::string alternate_name="");
index 40f13b713b75a0d9f5a6fe33889feef578acceb0..cef57bb1ec4fbd9ea43969325084cc2bece7ee3a 100644 (file)
@@ -746,6 +746,16 @@ int ceph_symlink(struct ceph_mount_info *cmount, const char *existing, const cha
  * @{
  */
 
+
+/**
+ * Checks if deleting a file, link or directory is allowed.
+ *
+ * @param cmount the ceph mount handle to use.
+ * @param path the path of the file, link or directory.
+ * @returns 0 on success or negative error code on failure.
+ */
+int ceph_may_delete(struct ceph_mount_info *cmount, const char *path);
+
 /**
  * Removes a file, link, or symbolic link.  If the file/link has multiple links to it, the
  * file will not disappear from the namespace until all references to it are removed.
index 261ee695499c63957a6db738d6b4f48f71965f91..fc3d0adc51e0100d7bc4babcf325fb17dda97873 100644 (file)
@@ -706,6 +706,13 @@ extern "C" void ceph_seekdir(struct ceph_mount_info *cmount, struct ceph_dir_res
   cmount->get_client()->seekdir(reinterpret_cast<dir_result_t*>(dirp), offset);
 }
 
+extern "C" int ceph_may_delete(struct ceph_mount_info *cmount, const char *path)
+{
+  if (!cmount->is_mounted())
+    return -ENOTCONN;
+  return cmount->get_client()->may_delete(path, cmount->default_perms);
+}
+
 extern "C" int ceph_link (struct ceph_mount_info *cmount, const char *existing,
                          const char *newname)
 {