#define LIBRGW_FILE_VER_MAJOR 1
#define LIBRGW_FILE_VER_MINOR 1
-#define LIBRGW_FILE_VER_EXTRA 2
+#define LIBRGW_FILE_VER_EXTRA 3
#define LIBRGW_FILE_VERSION(maj, min, extra) ((maj << 16) + (min << 8) + extra)
#define LIBRGW_FILE_VERSION_CODE LIBRGW_FILE_VERSION(LIBRGW_FILE_VER_MAJOR, LIBRGW_FILE_VER_MINOR, LIBRGW_FILE_VER_EXTRA)
* object types
*/
enum rgw_fh_type {
- RGW_FS_TYPE_FILE = 0,
+ RGW_FS_TYPE_NIL = 0,
+ RGW_FS_TYPE_FILE,
RGW_FS_TYPE_DIRECTORY,
};
#define RGW_LOOKUP_FLAG_NONE 0x0000
#define RGW_LOOKUP_FLAG_CREATE 0x0001
#define RGW_LOOKUP_FLAG_RCB 0x0002 /* readdir callback hint */
+#define RGW_LOOKUP_FLAG_DIR 0x0004
+#define RGW_LOOKUP_FLAG_FILE 0x0008
+
+#define RGW_LOOKUP_TYPE_FLAGS \
+ (RGW_LOOKUP_FLAG_DIR|RGW_LOOKUP_FLAG_FILE)
int rgw_lookup(struct rgw_fs *rgw_fs,
struct rgw_file_handle *parent_fh, const char *path,
/*
read directory content
*/
-typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset);
+typedef bool (*rgw_readdir_cb)(const char *name, void *arg, uint64_t offset,
+ uint32_t flags);
#define RGW_READDIR_FLAG_NONE 0x0000
#define RGW_READDIR_FLAG_DOTDOT 0x0001 /* send dot names */
LookupFHResult RGWLibFS::stat_leaf(RGWFileHandle* parent,
const char *path,
+ enum rgw_fh_type type,
uint32_t flags)
{
/* find either-of <object_name>, <object_name/>, only one of
switch (ix) {
case 0:
{
+ /* type hint */
+ if (type == RGW_FS_TYPE_DIRECTORY)
+ continue;
+
RGWStatObjRequest req(cct, get_user(),
parent->bucket_name(), obj_path,
RGWStatObjRequest::FLAG_NONE);
case 1:
{
/* try dir form */
+ /* type hint */
+ if (type == RGW_FS_TYPE_FILE)
+ continue;
+
obj_path += "/";
RGWStatObjRequest req(cct, get_user(),
parent->bucket_name(), obj_path,
if ((rc == 0) &&
(req.get_ret() == 0)) {
if (req.matched) {
- // we need rgw object's key name equal to file name, if not return NULL
+ /* we need rgw object's key name equal to file name, if
+ * not return NULL */
if ((flags & RGWFileHandle::FLAG_EXACT_MATCH) &&
!req.exact_matched) {
lsubdout(get_context(), rgw, 15)
if ((*offset == 0) &&
(flags & RGW_READDIR_FLAG_DOTDOT)) {
/* send '.' and '..' with their NFS-defined offsets */
- rcb(".", cb_arg, 1);
- rcb("..", cb_arg, 2);
+ rcb(".", cb_arg, 1, RGW_LOOKUP_FLAG_DIR);
+ rcb("..", cb_arg, 2, RGW_LOOKUP_FLAG_DIR);
}
if (is_root()) {
}
} else {
/* lookup in a readdir callback */
+ enum rgw_fh_type fh_type = fh_type_of(flags);
+
uint32_t sl_flags = (flags & RGW_LOOKUP_FLAG_RCB)
? RGWFileHandle::FLAG_NONE
: RGWFileHandle::FLAG_EXACT_MATCH;
- fhr = fs->stat_leaf(parent, path, sl_flags);
+
+ fhr = fs->stat_leaf(parent, path, fh_type, sl_flags);
if (! get<0>(fhr)) {
if (! (flags & RGW_LOOKUP_FLAG_CREATE))
return -ENOENT;
return static_cast<RGWFileHandle*>(fh->fh_private);
}
+ static inline enum rgw_fh_type fh_type_of(uint32_t flags) {
+ enum rgw_fh_type fh_type;
+ switch(flags & RGW_LOOKUP_TYPE_FLAGS)
+ {
+ case RGW_LOOKUP_FLAG_DIR:
+ fh_type = RGW_FS_TYPE_DIRECTORY;
+ break;
+ case RGW_LOOKUP_FLAG_FILE:
+ fh_type = RGW_FS_TYPE_FILE;
+ break;
+ default:
+ fh_type = RGW_FS_TYPE_NIL;
+ };
+ return fh_type;
+ }
+
typedef std::tuple<RGWFileHandle*, uint32_t> LookupFHResult;
typedef std::tuple<RGWFileHandle*, int> MkObjResult;
const char *path, uint32_t flags);
LookupFHResult stat_leaf(RGWFileHandle* parent, const char *path,
- uint32_t flags);
+ enum rgw_fh_type type = RGW_FS_TYPE_NIL,
+ uint32_t flags = RGWFileHandle::FLAG_NONE);
int read(RGWFileHandle* rgw_fh, uint64_t offset, size_t length,
size_t* bytes_read, void* buffer, uint32_t flags);
/* update traversal cache */
rgw_fh->add_marker(off, rgw_obj_key{marker.data(), ""},
RGW_FS_TYPE_DIRECTORY);
- rcb(name.data(), cb_arg, off);
+ rcb(name.data(), cb_arg, off, RGW_LOOKUP_FLAG_DIR);
return 0;
}
*offset = off;
/* update traversal cache */
rgw_fh->add_marker(off, marker, type);
- rcb(name.data(), cb_arg, off); // XXX has to be legit C-style string
+ rcb(name.data(), cb_arg, off,
+ (type == RGW_FS_TYPE_DIRECTORY) ?
+ RGW_LOOKUP_FLAG_DIR :
+ RGW_LOOKUP_FLAG_FILE);
return 0;
}
}
extern "C" {
- static bool r1_cb(const char* name, void *arg, uint64_t offset) {
+ static bool r1_cb(const char* name, void *arg, uint64_t offset,
+ uint32_t flags) {
// don't need arg--it would point to fids1
fids1.push_back(fid_type(name, offset, nullptr /* handle */));
return true; /* XXX ? */
}
extern "C" {
- static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+ static bool r2_cb(const char* name, void *arg, uint64_t offset,
+ uint32_t flags) {
std::vector<fid_type>& obj_vector = *(static_cast<std::vector<fid_type>*>(arg));
obj_vector.push_back(fid_type(name, offset, nullptr));
return true; /* XXX ? */
}
extern "C" {
- static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+ static bool r2_cb(const char* name, void *arg, uint64_t offset,
+ uint32_t flags) {
// don't need arg--it would point to fids
fids.push_back(fid_type(name, offset, nullptr));
return true; /* XXX ? */
}
extern "C" {
- static bool r1_cb(const char* name, void *arg, uint64_t offset) {
+ static bool r1_cb(const char* name, void *arg, uint64_t offset,
+ uint32_t flags) {
struct rgw_file_handle* parent_fh
= static_cast<struct rgw_file_handle*>(arg);
RGWFileHandle* rgw_fh = get_rgwfh(parent_fh);
<< " bucket=" << rgw_fh->bucket_name()
<< " dir=" << rgw_fh->full_object_name()
<< " called back name=" << name
+ << " flags=" << flags
<< dendl;
string name_str{name};
if (! ((name_str == ".") ||
}
extern "C" {
- static bool r2_cb(const char* name, void *arg, uint64_t offset) {
+ static bool r2_cb(const char* name, void *arg, uint64_t offset,
+ uint32_t flags) {
dirent_vec& dvec =
*(static_cast<dirent_vec*>(arg));
lsubdout(cct, rgw, 10) << __func__
<< " dir=" << marker_dir
<< " iv count=" << dvec.count
<< " called back name=" << name
+ << " flags=" << flags
<< dendl;
string name_str{name};
if (! ((name_str == ".") ||