From: Matt Benjamin Date: Tue, 11 Jul 2017 23:30:12 +0000 (-0400) Subject: rgw_file: permit dirent offset computation X-Git-Tag: v12.1.2~225^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e121fd04d652d4b6949c96b93a24b1032a1e9575;p=ceph.git rgw_file: permit dirent offset computation The new dirent chunking feature in nfs-ganesha 2.5 includes an optimization inspired by RGW NFS, and avoids invalidating modified dirs when the underlying FSAL can project the offset of a name in it's parent directory, independent of other entries (e.g., if offset is a stable hash). Signed-off-by: Matt Benjamin --- diff --git a/src/include/rados/rgw_file.h b/src/include/rados/rgw_file.h index add86df471de..95ca603c9653 100644 --- a/src/include/rados/rgw_file.h +++ b/src/include/rados/rgw_file.h @@ -27,7 +27,7 @@ extern "C" { #define LIBRGW_FILE_VER_MAJOR 1 #define LIBRGW_FILE_VER_MINOR 1 -#define LIBRGW_FILE_VER_EXTRA 3 +#define LIBRGW_FILE_VER_EXTRA 4 #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) @@ -217,6 +217,14 @@ int rgw_readdir(struct rgw_fs *rgw_fs, rgw_readdir_cb rcb, void *cb_arg, bool *eof, uint32_t flags); +/* project offset of dirent name */ +#define RGW_DIRENT_OFFSET_FLAG_NONE 0x0000 + +int rgw_dirent_offset(struct rgw_fs *rgw_fs, + struct rgw_file_handle *parent_fh, + const char *name, int64_t *offset, + uint32_t flags); + /* get unix attributes for object */ diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index ca8a5c4b4b87..344c29bb4196 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1796,6 +1796,22 @@ int rgw_readdir(struct rgw_fs *rgw_fs, return rc; } +/* project offset of dirent name */ +int rgw_dirent_offset(struct rgw_fs *rgw_fs, + struct rgw_file_handle *parent_fh, + const char *name, int64_t *offset, + uint32_t flags) +{ + RGWFileHandle* parent = get_rgwfh(parent_fh); + if ((! parent)) { + /* bad parent */ + return -EINVAL; + } + std::string sname{name}; + int rc = parent->offset_of(sname, offset, flags); + return rc; +} + /* read data from file */ diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index b93b59284093..374e55200a11 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -504,6 +504,14 @@ namespace rgw { return nullptr; } + int offset_of(const std::string& name, int64_t *offset, uint32_t flags) { + if (unlikely(! is_dir())) { + return -EINVAL; + } + *offset = XXH64(name.c_str(), name.length(), fh_key::seed); + return 0; + } + bool is_open() const { return flags & FLAG_OPEN; } bool is_root() const { return flags & FLAG_ROOT; } bool is_bucket() const { return flags & FLAG_BUCKET; }