summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-handle.h
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2013-09-16 17:50:25 +0530
committerAnand Avati <avati@redhat.com>2013-11-26 10:22:40 -0800
commitd6dc8d0e9e2052818c9858f6b073a8bacc3fca88 (patch)
tree8226967de497a4ff75c5ba5e509b465322dd5fd5 /xlators/storage/posix/src/posix-handle.h
parent1d554b179f63a5a56ae447f2a5b0044c49ae2642 (diff)
posix: placeholders for GFID to path conversion
what? ===== The following is an attempt to generate the paths of a file when only its gfid is known. To find the path of a directory, the symlink handle to the directory maintained in the ".glusterfs" backend directory is read. The symlink handle is generated using the gfid of the directory. It (handle) contains the directory's name and parent gfid, which are used to recursively construct the absolute path as seen by the user from the mount point. A similar approach cannot be used for a regular file or a symbolic link since its hardlink handle, generated using its gfid, doesn't contain its parent gfid and basename. So xattrs are set to store the parent gfids and the number of hardlinks to a file or a symlink having the same parent gfid. When an user/application requests for the paths of a regular file or a symlink with multiple hardlinks, using the parent gfids stored in the xattrs, the paths of the parent directories are generated as mentioned earlier. The base names of the hardlinks (with the same parent gfid) are determined by matching the actual backend inode numbers of each entry in the parent directory with that of the hardlink handle. Xattr is set on a regular file, link, and symbolic link as follows, Xattr name : trusted.pgfid.<pargfidstr> Xattr value : <number of hardlinks to a regular file/symlink with the same parentgfid> If a regular file, hard link, symbolic link is created then an xattr in the above format is set in the backend. how to use? =========== This functionality can be used through getxattr interface. Two keys - glusterfs.ancestry.dentry and glusterfs.ancestry.path - enable usage of this functionality. A successful getxattr will have the result stored under same keys. Values will be, glusterfs.ancestry.dentry: -------------------------- A linked list of gf-dirent structures for all possible paths from root to this gfid. If there are multiple paths, the linked-list will be a series of paths one after another. Each path will be a series of dentries representing all components of the path. This key is primarily for internal usage within glusterfs. glusterfs.ancestry.path: ------------------------ A string containing all possible paths from root to this gfid. Multiple hardlinks of a file or a symlink are displayed as a colon seperated list (this could interfere with path components containing ':'). e.g. If there is a file "file1" in root directory with two hardlinks, "/dir2/link2tofile1" and "/dir1/link1tofile1", then [root@alpha gfsmntpt]# getfattr -n glusterfs.ancestry.path -e text file1 glusterfs.ancestry.path="/file1:/dir2/link2tofile1:/dir1/link1tofile1" Thanks Amar, Avati and Venky for the inputs. Original Author: Ramana Raja <rraja@redhat.com> BUG: 990028 Signed-off-by: Raghavendra G <rgowdapp@redhat.com> Change-Id: I0eaa9101e333e0c1f66ccefd9e95944dd4a27497 Reviewed-on: http://review.gluster.org/5951 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix-handle.h')
-rw-r--r--xlators/storage/posix/src/posix-handle.h96
1 files changed, 91 insertions, 5 deletions
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h
index f1163b72795..8874ca2655f 100644
--- a/xlators/storage/posix/src/posix-handle.h
+++ b/xlators/storage/posix/src/posix-handle.h
@@ -17,9 +17,86 @@
#include <sys/types.h>
#include "xlator.h"
+#include "gf-dirent.h"
+#define HANDLE_PFX ".glusterfs"
+#define TRASH_DIR "landfill"
-#define LOC_HAS_ABSPATH(loc) ((loc) && (loc->path) && (loc->path[0] == '/'))
+#define UUID0_STR "00000000-0000-0000-0000-000000000000"
+#define SLEN(str) (sizeof(str) - 1)
+
+#define LOC_HAS_ABSPATH(loc) (loc && (loc->path) && (loc->path[0] == '/'))
+
+#define MAKE_PGFID_XATTR_KEY(var, prefix, pgfid) do { \
+ var = alloca (strlen (prefix) + UUID_CANONICAL_FORM_LEN + 1); \
+ strcpy (var, prefix); \
+ strcat (var, uuid_utoa (pgfid)); \
+ } while (0)
+
+#define SET_PGFID_XATTR(path, key, value, flags, op_ret, this, label) do { \
+ value = hton32 (value); \
+ op_ret = sys_lsetxattr (path, key, &value, sizeof (value), \
+ flags); \
+ if (op_ret == -1) { \
+ op_errno = errno; \
+ gf_log (this->name, GF_LOG_WARNING, \
+ "setting xattr failed on %s: key = %s (%s)", \
+ path, key, strerror (op_errno)); \
+ goto label; \
+ } \
+ } while (0)
+
+
+#define REMOVE_PGFID_XATTR(path, key, op_ret, this, label) do { \
+ op_ret = sys_lremovexattr (path, key); \
+ if (op_ret == -1) { \
+ op_errno = errno; \
+ gf_log (this->name, GF_LOG_WARNING, "removing xattr " \
+ "failed on %s: key = %s (%s)", path, key, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ } while (0)
+
+/* should be invoked holding a lock */
+#define LINK_MODIFY_PGFID_XATTR(path, key, value, flags, op_ret, this, label) do { \
+ op_ret = sys_lgetxattr (path, key, &value, sizeof (value)); \
+ if (op_ret == -1) { \
+ op_errno = errno; \
+ if (op_errno == ENOATTR) { \
+ value = 1; \
+ } else { \
+ gf_log (this->name, GF_LOG_WARNING,"getting xattr " \
+ "failed on %s: key = %s (%s)", path, key, \
+ strerror (op_errno)); \
+ goto label; \
+ } \
+ } else { \
+ value = ntoh32 (value); \
+ value++; \
+ } \
+ SET_PGFID_XATTR (path, key, value, flags, op_ret, this, label); \
+ } while (0)
+
+/* should be invoked holding a lock */
+#define UNLINK_MODIFY_PGFID_XATTR(path, key, value, flags, op_ret, this, label) do { \
+ op_ret = sys_lgetxattr (path, key, &value, sizeof (value)); \
+ if (op_ret == -1) { \
+ op_errno = errno; \
+ gf_log (this->name, GF_LOG_WARNING, "getting xattr failed on " \
+ "%s: key = %s (%s)", path, key, strerror (op_errno)); \
+ goto label; \
+ } else { \
+ value = ntoh32 (value); \
+ value--; \
+ if (value > 0) { \
+ SET_PGFID_XATTR (path, key, value, flags, op_ret, \
+ this, label); \
+ } else { \
+ REMOVE_PGFID_XATTR (path, key, op_ret, this, label); \
+ } \
+ } \
+ } while (0)
#define MAKE_REAL_PATH(var, this, path) do { \
var = alloca (strlen (path) + POSIX_BASE_PATH_LEN(this) + 2); \
@@ -27,7 +104,6 @@
strcpy (&var[POSIX_BASE_PATH_LEN(this)], path); \
} while (0)
-
#define MAKE_HANDLE_PATH(var, this, gfid, base) do { \
int __len; \
__len = posix_handle_path (this, gfid, base, NULL, 0); \
@@ -61,12 +137,12 @@
#define MAKE_INODE_HANDLE(rpath, this, loc, iatt_p) do { \
if (uuid_is_null (loc->gfid)) { \
gf_log (this->name, GF_LOG_ERROR, \
- "null gfid for path %s", loc->path); \
+ "null gfid for path %s", (loc)->path); \
break; \
} \
if (LOC_HAS_ABSPATH (loc)) { \
- MAKE_REAL_PATH (rpath, this, loc->path); \
- op_ret = posix_pstat (this, loc->gfid, rpath, iatt_p); \
+ MAKE_REAL_PATH (rpath, this, (loc)->path); \
+ op_ret = posix_pstat (this, (loc)->gfid, rpath, iatt_p); \
break; \
} \
errno = 0; \
@@ -107,10 +183,20 @@
} while (0)
+#define POSIX_ANCESTRY_PATH (1 << 0)
+#define POSIX_ANCESTRY_DENTRY (1 << 1)
int
posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename, char *buf,
size_t len);
+
+int
+posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize,
+ gf_dirent_t *head, int type, uuid_t gfid,
+ const size_t handle_size,
+ const char *priv_base_path,
+ inode_table_t *table, inode_t **parent,
+ dict_t *xdata);
int
posix_handle_path_safe (xlator_t *this, uuid_t gfid, const char *basename,
char *buf, size_t len);