]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_file: set owner uid, gid, and Unix mode on new objects
authorMatt Benjamin <mbenjamin@redhat.com>
Wed, 23 Mar 2016 21:29:30 +0000 (17:29 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Sun, 27 Mar 2016 21:20:27 +0000 (17:20 -0400)
Unix attributes aren't current materialized, but a future change
will serialize them in a new object attribute.

Also moves create and mkdir into operations on RGWLibFS, which
better encapsulates the behavior.

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/include/rados/rgw_file.h
src/rgw/rgw_file.cc
src/rgw/rgw_file.h
src/test/librgw_file_aw.cc
src/test/librgw_file_cd.cc
src/test/librgw_file_nfsns.cc

index 5eaf291e4c365aab91169cbca07af010f1dfc207..4bb8a939d104c73ca18e61154f88735a314a2370 100644 (file)
@@ -128,15 +128,23 @@ int rgw_statfs(struct rgw_fs *rgw_fs,
               uint32_t flags);
 
 
+/* XXX (get|set)attr mask bits */
+#define RGW_SETATTR_MODE   1
+#define RGW_SETATTR_UID    2
+#define RGW_SETATTR_GID    4
+#define RGW_SETATTR_MTIME  8
+#define RGW_SETATTR_ATIME 16
+#define RGW_SETATTR_SIZE  32
+#define RGW_SETATTR_CTIME 64
+
 /*
   create file
 */
 #define RGW_CREATE_FLAG_NONE     0x0000
 
-int rgw_create(struct rgw_fs *rgw_fs,
-              struct rgw_file_handle *parent_fh,
-              const char *name, mode_t mode, struct stat *st,
-              struct rgw_file_handle **fh, uint32_t flags);
+int rgw_create(struct rgw_fs *rgw_fs, struct rgw_file_handle *parent_fh,
+             const char *name, struct stat *st, uint32_t mask,
+             struct rgw_file_handle **fh, uint32_t flags);
 
 /*
   create a new directory
@@ -145,7 +153,7 @@ int rgw_create(struct rgw_fs *rgw_fs,
 
 int rgw_mkdir(struct rgw_fs *rgw_fs,
              struct rgw_file_handle *parent_fh,
-             const char *name, mode_t mode, struct stat *st,
+             const char *name, struct stat *st, uint32_t mask,
              struct rgw_file_handle **fh, uint32_t flags);
 
 /*
@@ -180,15 +188,6 @@ int rgw_readdir(struct rgw_fs *rgw_fs,
                rgw_readdir_cb rcb, void *cb_arg, bool *eof,
                uint32_t flags);
 
-/* XXX (get|set)attr mask bits */
-#define RGW_SETATTR_MODE   1
-#define RGW_SETATTR_UID    2
-#define RGW_SETATTR_GID    4
-#define RGW_SETATTR_MTIME  8
-#define RGW_SETATTR_ATIME 16
-#define RGW_SETATTR_SIZE  32
-#define RGW_SETATTR_CTIME 64
-
 /*
    get unix attributes for object
 */
index 53f764f12715d3791d247ccc1c780fc3e5cb6963..c1b7305cb99ee049674660b376d4501f7cdaff87 100644 (file)
@@ -253,6 +253,125 @@ namespace rgw {
     return rc;
   } /* RGWLibFS::rename */
 
+  MkObjResult RGWLibFS::mkdir(RGWFileHandle* parent, const char *name,
+                             struct stat *st, uint32_t mask, uint32_t flags)
+  {
+    MkObjResult mkr{nullptr, -EINVAL};
+    int rc, rc2;
+
+    LookupFHResult fhr;
+    RGWFileHandle* rgw_fh = nullptr;
+
+    if (parent->is_root()) {
+      /* bucket */
+      string bname{name};
+      /* enforce S3 name restrictions */
+      rc = valid_s3_bucket_name(bname, false /* relaxed */);
+      if (rc != 0) {
+       rc = -EINVAL;
+       goto out;
+      }
+
+      string uri = "/" + bname; /* XXX get rid of URI some day soon */
+      RGWCreateBucketRequest req(get_context(), get_user(), uri);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      rc2 = req.get_ret();
+    } else {
+      /* create an object representing the directory */
+      buffer::list bl;
+      string dir_name = /* XXX get rid of this some day soon, too */
+       parent->relative_object_name();
+      /* creating objects w/leading '/' makes a mess */
+      if ((dir_name.size() > 0) &&
+         (dir_name.back() != '/'))
+       dir_name += "/";
+      dir_name += name;
+      dir_name += "/";
+      RGWPutObjRequest req(get_context(), get_user(), parent->bucket_name(),
+                         dir_name, bl);
+      rc = rgwlib.get_fe()->execute_req(&req);
+      rc2 = req.get_ret();
+    }
+
+    if ((rc == 0) &&
+       (rc2 == 0)) {
+      fhr = lookup_fh(parent, name,
+                     RGWFileHandle::FLAG_CREATE|
+                     RGWFileHandle::FLAG_DIRECTORY);
+      rgw_fh = get<0>(fhr);
+      if (rgw_fh) {
+       /* XXX unify timestamps */
+       rgw_fh->create_stat(st, mask);
+       rgw_fh->set_times(real_clock::now());
+       rgw_fh->stat(st);
+       get<0>(mkr) = rgw_fh;
+      } else
+       rc = -EIO;
+    }
+
+  out:
+    get<1>(mkr) = rc;
+
+    return mkr;
+  } /* RGWLibFS::mkdir */
+
+  MkObjResult RGWLibFS::create(RGWFileHandle* parent, const char *name,
+                             struct stat *st, uint32_t mask, uint32_t flags)
+  {
+    int rc, rc2;
+
+    using std::get;
+
+    rgw_file_handle *lfh;
+    rc = rgw_lookup(get_fs(), parent->get_fh(), name, &lfh,
+                   RGW_LOOKUP_FLAG_NONE);
+    if (! rc) {
+      /* conflict! */
+      rc = rgw_fh_rele(get_fs(), lfh, RGW_FH_RELE_FLAG_NONE);
+      return MkObjResult{nullptr, -EEXIST};
+    }
+
+    /* expand and check name */
+    std::string obj_name{parent->relative_object_name()};
+    if ((obj_name.size() > 0) &&
+       (obj_name.back() != '/'))
+      obj_name += "/";
+    obj_name += name;
+    if (! valid_s3_object_name(obj_name)) {
+      return MkObjResult{nullptr, -EINVAL};
+    }
+
+    /* create it */
+    buffer::list bl;
+    RGWPutObjRequest req(cct, get_user(), parent->bucket_name(), obj_name, bl);
+    MkObjResult mkr{nullptr, -EINVAL};
+
+    rc = rgwlib.get_fe()->execute_req(&req);
+    rc2 = req.get_ret();
+
+    if ((rc == 0) &&
+       (rc2 == 0)) {
+      /* XXX atomicity */
+      LookupFHResult fhr = lookup_fh(parent, name, RGWFileHandle::FLAG_CREATE);
+      RGWFileHandle* rgw_fh = get<0>(fhr);
+      if (rgw_fh) {
+       if (get<1>(fhr) & RGWFileHandle::FLAG_CREATE) {
+         /* fill in stat data */
+         rgw_fh->create_stat(st, mask);
+         rgw_fh->set_times(real_clock::now());
+         rgw_fh->open_for_create(); // XXX needed?
+       }
+       (void) rgw_fh->stat(st);
+       get<0>(mkr) = rgw_fh;
+      } else
+       rc = -EIO;
+    }
+
+    get<1>(mkr) = rc;
+
+    return mkr;
+  } /* RGWLibFS::create */
+
   int RGWLibFS::getattr(RGWFileHandle* rgw_fh, struct stat* st)
   {
     switch(rgw_fh->fh.fh_type) {
@@ -708,14 +827,15 @@ int rgw_statfs(struct rgw_fs *rgw_fs,
   generic create -- create an empty regular file
 */
 int rgw_create(struct rgw_fs *rgw_fs,
-              struct rgw_file_handle *parent_fh,
-              const char *name, mode_t mode, struct stat *st,
-              struct rgw_file_handle **fh, uint32_t flags)
+             struct rgw_file_handle *parent_fh,
+             const char *name, struct stat *st, uint32_t mask,
+             struct rgw_file_handle **fh, uint32_t flags)
 {
-  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
-  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
+  using std::get;
 
+  RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
   RGWFileHandle* parent = get_rgwfh(parent_fh);
+
   if ((! parent) ||
       (parent->is_root()) ||
       (parent->is_file())) {
@@ -723,124 +843,41 @@ int rgw_create(struct rgw_fs *rgw_fs,
     return -EINVAL;
   }
 
-  using std::get;
+  MkObjResult fhr = fs->create(parent, name, st, mask, flags);
+  RGWFileHandle *nfh = get<0>(fhr); // nullptr if !success
 
-  rgw_file_handle *lfh;
-  int rc = rgw_lookup(rgw_fs, parent_fh, name, &lfh,
-                     RGW_LOOKUP_FLAG_NONE);
-  if (! rc) {
-    /* conflict! */
-    rc = rgw_fh_rele(rgw_fs, lfh, RGW_FH_RELE_FLAG_NONE);
-    return -EEXIST;
-  } else {
-    /* expand and check name */
-    std::string obj_name{parent->relative_object_name()};
-    if ((obj_name.size() > 0) &&
-       (obj_name.back() != '/'))
-      obj_name += "/";
-    obj_name += name;
-    if (! valid_s3_object_name(obj_name)) {
-      return -EINVAL;
-    } else {
-      /* create it */
-      buffer::list bl;
-      RGWPutObjRequest req(cct, fs->get_user(), parent->bucket_name(),
-                          obj_name, bl);
-      rc = rgwlib.get_fe()->execute_req(&req);
-      int rc2 = req.get_ret();
-
-      if ((rc == 0) &&
-         (rc2 == 0)) {
-       /* XXX atomicity */
-       LookupFHResult fhr = fs->lookup_fh(parent, name,
-                                          RGWFileHandle::FLAG_CREATE);
-       RGWFileHandle* rgw_fh = get<0>(fhr);
-       if (rgw_fh) {
-         if (get<1>(fhr) & RGWFileHandle::FLAG_CREATE) {
-           /* fill in stat data */
-           rgw_fh->set_times(real_clock::now());
-           rgw_fh->open_for_create(); // XXX needed?
-         }
-         (void) rgw_fh->stat(st);
-         struct rgw_file_handle *rfh = rgw_fh->get_fh();
-         *fh = rfh;
-       } else
-         rc = -EIO;
-      }
-    }
-  }
+  if (nfh)
+    *fh = nfh->get_fh();
 
-  return rc;
-}
+  return get<1>(fhr);
+} /* rgw_create */
 
 /*
   create a new directory
 */
 int rgw_mkdir(struct rgw_fs *rgw_fs,
              struct rgw_file_handle *parent_fh,
-             const char *name, mode_t mode, struct stat *st,
+             const char *name, struct stat *st, uint32_t mask,
              struct rgw_file_handle **fh, uint32_t flags)
 {
-  int rc, rc2;
+  using std::get;
 
   RGWLibFS *fs = static_cast<RGWLibFS*>(rgw_fs->fs_private);
-  CephContext* cct = static_cast<CephContext*>(rgw_fs->rgw);
-
   RGWFileHandle* parent = get_rgwfh(parent_fh);
+
   if (! parent) {
     /* bad parent */
     return -EINVAL;
   }
 
-  LookupFHResult fhr;
-  RGWFileHandle* rgw_fh = nullptr;
+  MkObjResult fhr = fs->mkdir(parent, name, st, mask, flags);
+  RGWFileHandle *nfh = get<0>(fhr); // nullptr if !success
 
-  if (parent->is_root()) {
-    /* bucket */
-    string bname{name};
-    /* enforce S3 name restrictions */
-    rc = valid_s3_bucket_name(bname, false /* relaxed */);
-    if (rc != 0)
-      return -EINVAL;
-    string uri = "/" + bname; /* XXX get rid of URI some day soon */
-    RGWCreateBucketRequest req(cct, fs->get_user(), uri);
-    rc = rgwlib.get_fe()->execute_req(&req);
-    rc2 = req.get_ret();
-  } else {
-    /* create an object representing the directory */
-    buffer::list bl;
-    string dir_name = /* XXX get rid of this some day soon, too */
-      parent->relative_object_name();
-    /* creating objects w/leading '/' makes a mess */
-    if ((dir_name.size() > 0) &&
-       (dir_name.back() != '/'))
-      dir_name += "/";
-    dir_name += name;
-    dir_name += "/";
-    RGWPutObjRequest req(cct, fs->get_user(), parent->bucket_name(),
-                        dir_name, bl);
-    rc = rgwlib.get_fe()->execute_req(&req);
-    rc2 = req.get_ret();
-  }
-
-  if ((rc == 0) &&
-      (rc2 == 0)) {
-    fhr = fs->lookup_fh(parent, name,
-                       RGWFileHandle::FLAG_CREATE|
-                       RGWFileHandle::FLAG_DIRECTORY);
-    rgw_fh = get<0>(fhr);
-    if (rgw_fh) {
-      /* XXX unify timestamps */
-      rgw_fh->set_times(real_clock::now());
-      rgw_fh->stat(st);
-      struct rgw_file_handle *rfh = rgw_fh->get_fh();
-      *fh = rfh;
-    } else
-      rc = -EIO;
-  }
+  if (nfh)
+    *fh = nfh->get_fh();
 
-  return rc;
-}
+  return get<1>(fhr);
+} /* rgw_mkdir */
 
 /*
   rename object
@@ -1081,18 +1118,8 @@ int rgw_write(struct rgw_fs *rgw_fs,
   if (! rgw_fh->is_open())
     return -EPERM;
 
-  std::cout << __func__ << " before write of "
-           << length << " bytes at offset " << offset
-           << std::endl;
-
   rc = rgw_fh->write(offset, length, bytes_written, buffer);
 
-  std::cout << __func__ << " after write of "
-           << length << " bytes at offset " << offset
-           << " wrote " << *bytes_written
-           << " rc " << rc
-           << std::endl;
-
   return rc;
 }
 
index a6e06ded0499d3dffd55a10cd672f92bcb2d8d2b..26b97b405f2487879c9967a92594b8077cd634ae 100644 (file)
@@ -157,10 +157,14 @@ namespace rgw {
       uint64_t dev;
       size_t size;
       uint64_t nlink;
+      uint32_t owner_uid; /* XXX need Unix attr */
+      uint32_t owner_gid; /* XXX need Unix attr */
+      mode_t unix_mode;
       struct timespec ctime;
       struct timespec mtime;
       struct timespec atime;
-      state() : dev(0), size(0), nlink(1), ctime{0,0}, mtime{0,0}, atime{0,0} {}
+      state() : dev(0), size(0), nlink(1), owner_uid(0), owner_gid(0),
+               ctime{0,0}, mtime{0,0}, atime{0,0} {}
     } state;
 
     struct file {
@@ -224,10 +228,11 @@ namespace rgw {
        variant_type = directory();
        /* stat */
        state.dev = fs_inst;
+       state.unix_mode = RGW_RWXMODE|S_IFDIR;
        /* pointer to self */
        fh.fh_private = this;
       }
-    
+
     void init_rootfs(std::string& fsid, const std::string& object_name) {
       /* fh_key */
       fh.fh_hk.bucket = XXH64(fsid.c_str(), fsid.length(), fh_key::seed);
@@ -264,6 +269,19 @@ namespace rgw {
       /* save constant fhk */
       fh.fh_hk = fhk.fh_hk; /* XXX redundant in fh_hk */
 
+      /* stat */
+      state.dev = fs_inst;
+
+      switch (fh.fh_type) {
+      case RGW_FS_TYPE_DIRECTORY:
+       state.unix_mode = RGW_RWXMODE|S_IFDIR;
+       break;
+      case RGW_FS_TYPE_FILE:
+       state.unix_mode = RGW_RWMODE|S_IFREG;
+      default:
+       break;
+      }
+
       /* pointer to self */
       fh.fh_private = this;
     }
@@ -290,16 +308,41 @@ namespace rgw {
 
     RGWFileHandle* get_parent() { return parent; }
 
+    uint32_t get_owner_uid() const { return state.owner_uid; }
+    uint32_t get_owner_gid() const { return state.owner_gid; }
+
     struct timespec get_mtime() const { return state.mtime; }
 
-    int stat(struct stat *st) {
+    void create_stat(struct stat* st, uint32_t mask) {
+      if (mask & RGW_SETATTR_UID)
+       state.owner_uid = st->st_uid;
+
+      if (mask & RGW_SETATTR_GID)
+       state.owner_gid = st->st_gid;
+
+      if (mask & RGW_SETATTR_MODE)  {
+       switch (fh.fh_type) {
+       case RGW_FS_TYPE_DIRECTORY:
+         st->st_mode = state.unix_mode|S_IFDIR;
+         break;
+       case RGW_FS_TYPE_FILE:
+         st->st_mode = state.unix_mode|S_IFREG;
+      default:
+       break;
+       }
+      }
+    }
+
+    int stat(struct stat* st) {
       /* partial Unix attrs */
       memset(st, 0, sizeof(struct stat));
       st->st_dev = state.dev;
       st->st_ino = fh.fh_hk.object; // XXX
 
-      st->st_uid = 0; // XXX
-      st->st_gid = 0; // XXX
+      st->st_uid = state.owner_uid;
+      st->st_gid = state.owner_gid;
+
+      st->st_mode = state.unix_mode;
 
       st->st_atim = state.atime;
       st->st_mtim = state.mtime;
@@ -567,6 +610,7 @@ namespace rgw {
   }
 
   typedef std::tuple<RGWFileHandle*, uint32_t> LookupFHResult;
+  typedef std::tuple<RGWFileHandle*, int> MkObjResult;
 
   class RGWLibFS
   {
@@ -780,6 +824,12 @@ namespace rgw {
     int rename(RGWFileHandle* old_fh, RGWFileHandle* new_fh,
               const char *old_name, const char *new_name);
 
+    MkObjResult create(RGWFileHandle* parent, const char *name, struct stat *st,
+                     uint32_t mask, uint32_t flags);
+
+    MkObjResult mkdir(RGWFileHandle* parent, const char *name, struct stat *st,
+                     uint32_t mask, uint32_t flags);
+
     int unlink(RGWFileHandle* parent, const char *name);
 
     /* find existing RGWFileHandle */
index 2ae73b88c939280415c455f32f20a14feaa61afd..cf6f536111ae6f217ba4201ab647d5c6bf6ccb95 100644 (file)
@@ -37,6 +37,10 @@ namespace {
   string secret_key("");
   struct rgw_fs *fs = nullptr;
 
+  uint32_t owner_uid = 867;
+  uint32_t owner_gid = 5309;
+  uint32_t create_mask = RGW_SETATTR_UID | RGW_SETATTR_GID | RGW_SETATTR_MODE;
+
   bool do_create = false;
   bool do_delete = false;
   bool do_verify = false;
@@ -179,8 +183,13 @@ TEST(LibRGW, CREATE_BUCKET) {
   if (do_create) {
     struct stat st;
     struct rgw_file_handle *fh;
-    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st, &fh,
-                       RGW_MKDIR_FLAG_NONE);
+
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
+    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), &st, create_mask,
+                       &fh, RGW_MKDIR_FLAG_NONE);
     ASSERT_EQ(ret, 0);
   }
 }
index 4ec671fcda54148a51f868257e938f3e1c4c38e9..db8f91f9ca9c69f172f44ec6c94c86d5667d9bac 100644 (file)
@@ -33,6 +33,10 @@ namespace {
   string secret_key("");
   struct rgw_fs *fs = nullptr;
 
+  uint32_t owner_uid = 867;
+  uint32_t owner_gid = 5309;
+  uint32_t create_mask = RGW_SETATTR_UID | RGW_SETATTR_GID | RGW_SETATTR_MODE;
+
   bool do_create = false;
   bool do_delete = false;
   bool do_multi = false;
@@ -63,8 +67,13 @@ TEST(LibRGW, CREATE_BUCKET) {
   if (do_create) {
     struct stat st;
     struct rgw_file_handle *fh;
-    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st, &fh,
-                       RGW_MKDIR_FLAG_NONE);
+
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
+    int ret = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), &st, create_mask,
+                       &fh, RGW_MKDIR_FLAG_NONE);
     ASSERT_EQ(ret, 0);
   }
 }
@@ -82,10 +91,15 @@ TEST(LibRGW, CREATE_BUCKET_MULTI) {
     int ret;
     struct stat st;
     struct rgw_file_handle *fh;
+
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
     for (int ix = 0; ix < multi_cnt; ++ix) {
       string bn = bucket_name;
       bn += to_string(ix);
-      ret = rgw_mkdir(fs, fs->root_fh, bn.c_str(), 755, &st, &fh,
+      ret = rgw_mkdir(fs, fs->root_fh, bn.c_str(), &st, create_mask, &fh,
                      RGW_MKDIR_FLAG_NONE);
       ASSERT_EQ(ret, 0);
       std::cout << "created: " << bn << std::endl;
index 49f0ff5afc8fc6c2115bf310b984add266830123..3cfcea37840cc495556f79b9686ad6f11acc70e2 100644 (file)
@@ -44,6 +44,10 @@ namespace {
   struct rgw_fs *fs = nullptr;
   CephContext* cct = nullptr;
 
+  uint32_t owner_uid = 867;
+  uint32_t owner_gid = 5309;
+  uint32_t create_mask = RGW_SETATTR_UID | RGW_SETATTR_GID | RGW_SETATTR_MODE;
+
   string bucket_name("nfsroot");
   string dirs1_bucket_name("bdirs1");
   string readf_name("toyland");
@@ -191,8 +195,13 @@ TEST(LibRGW, SETUP_HIER1)
     if (! bucket_fh) {
       if (do_create) {
        struct stat st;
-       int rc = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), 755, &st,
-                          &bucket_fh, RGW_MKDIR_FLAG_NONE);
+
+       st.st_uid = owner_uid;
+       st.st_gid = owner_gid;
+       st.st_mode = 755;
+
+       int rc = rgw_mkdir(fs, fs->root_fh, bucket_name.c_str(), &st,
+                         create_mask, &bucket_fh, RGW_MKDIR_FLAG_NONE);
        ASSERT_EQ(rc, 0);
       }
     }
@@ -239,6 +248,10 @@ TEST(LibRGW, SETUP_DIRS1) {
     int rc;
     struct stat st;
 
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
     dirs1_b.parent_fh = fs->root_fh;
 
     (void) rgw_lookup(fs, dirs1_b.parent_fh, dirs1_bucket_name.c_str(),
@@ -246,8 +259,8 @@ TEST(LibRGW, SETUP_DIRS1) {
 
     if (! dirs1_b.fh) {
       if (do_create) {
-       rc = rgw_mkdir(fs, dirs1_b.parent_fh, dirs1_b.name.c_str(), 755, &st,
-                      &dirs1_b.fh, RGW_MKDIR_FLAG_NONE);
+       rc = rgw_mkdir(fs, dirs1_b.parent_fh, dirs1_b.name.c_str(), &st,
+                     create_mask, &dirs1_b.fh, RGW_MKDIR_FLAG_NONE);
        ASSERT_EQ(rc, 0);
       }
     }
@@ -266,7 +279,7 @@ TEST(LibRGW, SETUP_DIRS1) {
                        RGW_LOOKUP_FLAG_NONE);
       if (! dir.fh) {
        if (do_create) {
-         rc = rgw_mkdir(fs, dir.parent_fh, dir.name.c_str(), 755, &st,
+         rc = rgw_mkdir(fs, dir.parent_fh, dir.name.c_str(), &st, create_mask,
                         &dir.fh, RGW_MKDIR_FLAG_NONE);
          ASSERT_EQ(rc, 0);
        }
@@ -289,8 +302,8 @@ TEST(LibRGW, SETUP_DIRS1) {
 
        if (! sdir.fh) {
          if (do_create) {
-           rc = rgw_mkdir(fs, sdir.parent_fh, sdir.name.c_str(), 755,
-                          &st, &sdir.fh, RGW_MKDIR_FLAG_NONE);
+           rc = rgw_mkdir(fs, sdir.parent_fh, sdir.name.c_str(), &st,
+                         create_mask, &sdir.fh, RGW_MKDIR_FLAG_NONE);
            ASSERT_EQ(rc, 0);
          }
        }
@@ -352,6 +365,11 @@ TEST(LibRGW, RGW_CREATE_DIRS1) {
     if (do_create) {
       int rc;
       struct stat st;
+
+      st.st_uid = owner_uid;
+      st.st_gid = owner_gid;
+      st.st_mode = 644;
+
       for (auto& dirs_rec : dirs_vec) {
        /* create 1 more file in each sdir */
        obj_rec& dir = get<0>(dirs_rec);
@@ -360,8 +378,8 @@ TEST(LibRGW, RGW_CREATE_DIRS1) {
        (void) rgw_lookup(fs, sf.parent_fh, sf.name.c_str(), &sf.fh,
                          RGW_LOOKUP_FLAG_NONE);
        if (! sf.fh) {
-         rc = rgw_create(fs, sf.parent_fh, sf.name.c_str(), 644, &st, &sf.fh,
-                         RGW_CREATE_FLAG_NONE);
+         rc = rgw_create(fs, sf.parent_fh, sf.name.c_str(), &st, create_mask,
+                         &sf.fh, RGW_CREATE_FLAG_NONE);
          ASSERT_EQ(rc, 0);
        }
        sf.sync();
@@ -377,6 +395,11 @@ TEST(LibRGW, RGW_SETUP_RENAME1) {
     int rc;
     struct stat st;
     obj_vec ovec;
+
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
     for (int b_ix : {0, 1}) {
       std::string bname{"brename_" + to_string(b_ix)};
       obj_rec brec{bname, nullptr, nullptr, nullptr};
@@ -385,13 +408,16 @@ TEST(LibRGW, RGW_SETUP_RENAME1) {
       if (! brec.fh) {
        if (do_create) {
          struct stat st;
-         int rc = rgw_mkdir(fs, fs->root_fh, brec.name.c_str(), 755, &st,
-                            &brec.fh, RGW_MKDIR_FLAG_NONE);
+         int rc = rgw_mkdir(fs, fs->root_fh, brec.name.c_str(), &st,
+                           create_mask, &brec.fh, RGW_MKDIR_FLAG_NONE);
          ASSERT_EQ(rc, 0);
        }
       }
       ASSERT_NE(brec.fh, nullptr);
       brec.sync();
+
+      st.st_mode = 644; /* file mask */
+
       for (int f_ix : {0, 1}) {
        std::string rfname{"rfile_"};
        rfname += to_string(f_ix);
@@ -399,8 +425,8 @@ TEST(LibRGW, RGW_SETUP_RENAME1) {
        (void) rgw_lookup(fs, rf.parent_fh, rf.name.c_str(), &rf.fh,
                          RGW_LOOKUP_FLAG_NONE);
        if (! rf.fh) {
-         rc = rgw_create(fs, rf.parent_fh, rf.name.c_str(), 644, &st, &rf.fh,
-                         RGW_CREATE_FLAG_NONE);
+         rc = rgw_create(fs, rf.parent_fh, rf.name.c_str(), &st, create_mask,
+                         &rf.fh, RGW_CREATE_FLAG_NONE);
          ASSERT_EQ(rc, 0);
        }
        rf.sync();
@@ -796,9 +822,13 @@ TEST(LibRGW, MARKER1_SETUP_BUCKET) {
     struct stat st;
     int ret;
 
+    st.st_uid = owner_uid;
+    st.st_gid = owner_gid;
+    st.st_mode = 755;
+
     if (do_create) {
-      ret = rgw_mkdir(fs, bucket_fh, marker_dir.c_str(), 755, &st, &marker_fh,
-                     RGW_MKDIR_FLAG_NONE);
+      ret = rgw_mkdir(fs, bucket_fh, marker_dir.c_str(), &st, create_mask,
+                     &marker_fh, RGW_MKDIR_FLAG_NONE);
     } else {
       ret = rgw_lookup(fs, bucket_fh, marker_dir.c_str(), &marker_fh,
                       RGW_LOOKUP_FLAG_NONE);