atomic<uint32_t> RGWLibFS::fs_inst;
+LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
+ const char *path,
+ uint32_t flags)
+{
+ /* find either-of <object_name>, <object_name/>, only one of
+ * which can exist; atomicity? */
+ RGWLibFS* fs = parent->get_fs();
+ LookupFHResult fhr{nullptr, 0};
+ std::string object_name{path};
+
+ for (auto ix : { 0, 1 }) {
+ ignore(ix);
+ RGWStatObjRequest req(cct, fs->get_user(),
+ parent->bucket_name(), object_name,
+ RGWStatObjRequest::FLAG_NONE);
+ int rc = librgw.get_fe()->execute_req(&req);
+ if ((rc == 0) &&
+ (req.get_ret() == 0)) {
+ fhr = fs->lookup_fh(parent, path);
+ break;
+ }
+ object_name += "/";
+ }
+ return fhr;
+} /* RGWLibFS::stat_leaf */
+
/* librgw */
extern "C" {
}
RGWFileHandle* rgw_fh;
+ LookupFHResult fhr;
if (parent->is_root()) {
/* special: lookup on root itself */
} else {
/* name lookup in root--for now) just get a handle */
/* XXX RGWStatBucket? */
- LookupFHResult fhr = fs->lookup_fh(parent, path);
+ fhr = fs->lookup_fh(parent, path);
rgw_fh = get<0>(fhr);
if (! rgw_fh)
return -ENOMEM;
}
} else {
- /* XXX need to stat either-of <object_name>, <object_name/>,
- * only one of which can exist; atomicity? */
- std::string object_name{path};
- RGWStatObjRequest req(cct, fs->get_user(),
- parent->bucket_name(), object_name,
- RGWStatObjRequest::FLAG_NONE);
-
- int rc = librgw.get_fe()->execute_req(&req);
- if (((rc != 0) ||
- (req.get_ret() != 0)) &&
- (! (flags & RGW_LOOKUP_FLAG_CREATE)))
- return -ENOENT;
-
- LookupFHResult fhr = fs->lookup_fh(parent, path);
+ fhr = fs->stat_leaf(parent, path, RGWFileHandle::FLAG_NONE);
+ if (! get<0>(fhr)) {
+ if (! (flags & RGW_LOOKUP_FLAG_CREATE))
+ return -ENOENT;
+ else
+ fhr = fs->lookup_fh(parent, path, RGWFileHandle::FLAG_CREATE);
+ }
rgw_fh = get<0>(fhr);
-
- if (! rgw_fh)
- return -ENOENT;
} /* !root */
struct rgw_file_handle *rfh = rgw_fh->get_fh();
namespace rgw {
+ template <typename T>
+ static inline void ignore(T &&) {}
+
+
namespace bi = boost::intrusive;
class RGWLibFS;
{
struct rgw_file_handle fh;
mutable std::atomic<uint64_t> refcnt;
+ std::mutex mtx;
RGWLibFS* fs;
RGWFHRef parent;
/* const */ std::string name; /* XXX file or bucket name */
static constexpr uint32_t FLAG_ROOT = 0x0002;
static constexpr uint32_t FLAG_CREATE = 0x0004;
static constexpr uint32_t FLAG_PSEUDO = 0x0008;
+ static constexpr uint32_t FLAG_LOCK = 0x0010;
friend class RGWLibFS;
struct rgw_file_handle* get_fh() { return &fh; }
+ RGWLibFS* get_fs() { return fs; }
+
int stat(struct stat *st) {
/* partial Unix attrs */
memset(st, 0, sizeof(struct stat));
fhk /* key */, lat /* serializer */,
RGWFileHandle::FHCache::FLAG_LOCK);
/* LATCHED */
- if (! fh) {
+ if ((! fh) &&
+ (cflags & RGWFileHandle::FLAG_CREATE)) {
fh = new RGWFileHandle(this, get_inst(), parent, fhk, sname);
intrusive_ptr_add_ref(fh); /* sentinel ref */
fh_cache.insert_latched(fh, lat,
- RGWFileHandle::FHCache::FLAG_NONE);
+ RGWFileHandle::FHCache::FLAG_NONE);
if (cflags & RGWFileHandle::FLAG_PSEUDO)
fh->set_pseudo();
get<1>(fhr) = RGWFileHandle::FLAG_CREATE;
}
+
intrusive_ptr_add_ref(fh); /* call path/handle ref */
lat.lock->unlock(); /* !LATCHED */
return fhr;
}
+ LookupFHResult stat_leaf(RGWFileHandle* parent,
+ const char *path,
+ uint32_t flags);
+
/* find or create an RGWFileHandle */
RGWFileHandle* lookup_handle(struct rgw_fh_hk fh_hk) {