summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-entry-ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-entry-ops.c')
-rw-r--r--xlators/storage/posix/src/posix-entry-ops.c3944
1 files changed, 2145 insertions, 1799 deletions
diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c
index 4d7ed5be7c8..8cc3ccf8c00 100644
--- a/xlators/storage/posix/src/posix-entry-ops.c
+++ b/xlators/storage/posix/src/posix-entry-ops.c
@@ -26,7 +26,6 @@
#include <signal.h>
#include <sys/uio.h>
#include <unistd.h>
-#include <ftw.h>
#ifndef GF_BSD_HOST_OS
#include <alloca.h>
@@ -36,30 +35,26 @@
#include <fcntl.h>
#endif /* HAVE_LINKAT */
-#include "glusterfs.h"
-#include "checksum.h"
-#include "dict.h"
-#include "logging.h"
+#include <glusterfs/dict.h>
+#include <glusterfs/logging.h>
#include "posix.h"
#include "posix-handle.h"
-#include "xlator.h"
-#include "defaults.h"
-#include "common-utils.h"
-#include "compat-errno.h"
-#include "compat.h"
-#include "byte-order.h"
-#include "syscall.h"
-#include "statedump.h"
-#include "locking.h"
-#include "timer.h"
+#include <glusterfs/compat-errno.h>
+#include <glusterfs/compat.h>
+#include <glusterfs/byte-order.h>
+#include <glusterfs/syscall.h>
+#include <glusterfs/statedump.h>
+#include <glusterfs/locking.h>
+#include <glusterfs/timer.h>
#include "glusterfs3-xdr.h"
-#include "hashfn.h"
#include "posix-aio.h"
-#include "glusterfs-acl.h"
+#include <glusterfs/glusterfs-acl.h>
#include "posix-messages.h"
-#include "events.h"
+#include "posix-metadata.h"
+#include <glusterfs/events.h>
#include "posix-gfid-path.h"
-#include "compat-uuid.h"
+#include <glusterfs/compat-uuid.h>
+#include <glusterfs/syncop.h>
extern char *marker_xattrs[];
#define ALIGN_SIZE 4096
@@ -67,17 +62,21 @@ extern char *marker_xattrs[];
#undef HAVE_SET_FSID
#ifdef HAVE_SET_FSID
-#define DECLARE_OLD_FS_ID_VAR uid_t old_fsuid; gid_t old_fsgid;
+#define DECLARE_OLD_FS_ID_VAR \
+ uid_t old_fsuid; \
+ gid_t old_fsgid;
-#define SET_FS_ID(uid, gid) do { \
- old_fsuid = setfsuid (uid); \
- old_fsgid = setfsgid (gid); \
- } while (0)
+#define SET_FS_ID(uid, gid) \
+ do { \
+ old_fsuid = setfsuid(uid); \
+ old_fsgid = setfsgid(gid); \
+ } while (0)
-#define SET_TO_OLD_FS_ID() do { \
- setfsuid (old_fsuid); \
- setfsgid (old_fsgid); \
- } while (0)
+#define SET_TO_OLD_FS_ID() \
+ do { \
+ setfsuid(old_fsuid); \
+ setfsgid(old_fsgid); \
+ } while (0)
#else
@@ -87,2064 +86,2411 @@ extern char *marker_xattrs[];
#endif
-/* Setting microseconds or nanoseconds depending on what's supported:
- The passed in `tv` can be
- struct timespec
- if supported (better, because it supports nanosecond resolution) or
- struct timeval
- otherwise. */
-#if HAVE_UTIMENSAT
-#define SET_TIMESPEC_NSEC_OR_TIMEVAL_USEC(tv, nanosecs) \
- tv.tv_nsec = nanosecs
-#define PATH_SET_TIMESPEC_OR_TIMEVAL(path, tv) \
- (sys_utimensat (AT_FDCWD, path, tv, AT_SYMLINK_NOFOLLOW))
-#else
-#define SET_TIMESPEC_NSEC_OR_TIMEVAL_USEC(tv, nanosecs) \
- tv.tv_usec = nanosecs / 1000
-#define PATH_SET_TIMESPEC_OR_TIMEVAL(path, tv) \
- (lutimes (path, tv))
-#endif
-
-gf_boolean_t
-posix_symlinks_match (xlator_t *this, loc_t *loc, uuid_t gfid)
+static gf_boolean_t
+posix_symlinks_match(xlator_t *this, loc_t *loc, uuid_t gfid)
{
- struct posix_private *priv = NULL;
- char linkname_actual[PATH_MAX] = {0,};
- char linkname_expected[PATH_MAX] = {0};
- char *dir_handle = NULL;
- ssize_t len = 0;
- size_t handle_size = 0;
- gf_boolean_t ret = _gf_false;
-
- priv = this->private;
- handle_size = POSIX_GFID_HANDLE_SIZE(priv->base_path_length);
- dir_handle = alloca0 (handle_size);
-
- snprintf (linkname_expected, handle_size, "../../%02x/%02x/%s/%s",
- loc->pargfid[0], loc->pargfid[1], uuid_utoa (loc->pargfid),
- loc->name);
-
- MAKE_HANDLE_GFID_PATH (dir_handle, this, gfid, NULL);
- len = sys_readlink (dir_handle, linkname_actual, PATH_MAX);
- if (len < 0)
- goto out;
- linkname_actual[len] = '\0';
-
- if (!strncmp (linkname_actual, linkname_expected, handle_size))
- ret = _gf_true;
+ struct posix_private *priv = NULL;
+ char linkname_actual[PATH_MAX] = {
+ 0,
+ };
+ char linkname_expected[PATH_MAX] = {0};
+ char *dir_handle = NULL;
+ ssize_t len = 0;
+ size_t handle_size = 0;
+ gf_boolean_t ret = _gf_false;
+
+ priv = this->private;
+ handle_size = POSIX_GFID_HANDLE_SIZE(priv->base_path_length);
+ dir_handle = alloca0(handle_size);
+
+ snprintf(linkname_expected, PATH_MAX, "../../%02x/%02x/%s/%s",
+ loc->pargfid[0], loc->pargfid[1], uuid_utoa(loc->pargfid),
+ loc->name);
+
+ MAKE_HANDLE_GFID_PATH(dir_handle, this, gfid);
+ len = sys_readlink(dir_handle, linkname_actual, PATH_MAX);
+ if (len < 0 || len == PATH_MAX) {
+ if (len == PATH_MAX) {
+ errno = EINVAL;
+ }
+
+ if (errno != ENOENT) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "readlink[%s] failed", dir_handle);
+ }
+ goto out;
+ }
+ linkname_actual[len] = '\0';
+
+ if (!strcmp(linkname_actual, linkname_expected))
+ ret = _gf_true;
out:
- return ret;
+ return ret;
}
-dict_t*
-posix_dict_set_nlink (dict_t *req, dict_t *res, int32_t nlink)
+static dict_t *
+posix_dict_set_nlink(dict_t *req, dict_t *res, int32_t nlink)
{
- int ret = -1;
+ int ret = -1;
- if (req == NULL || !dict_get (req, GF_REQUEST_LINK_COUNT_XDATA))
- goto out;
+ if (req == NULL || !dict_get_sizen(req, GF_REQUEST_LINK_COUNT_XDATA))
+ goto out;
- if (res == NULL)
- res = dict_new ();
- if (res == NULL)
- goto out;
+ if (res == NULL)
+ res = dict_new();
+ if (res == NULL)
+ goto out;
- ret = dict_set_uint32 (res, GF_RESPONSE_LINK_COUNT_XDATA, nlink);
- if (ret == -1)
- gf_msg ("posix", GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
- "Failed to set GF_RESPONSE_LINK_COUNT_XDATA");
+ ret = dict_set_uint32(res, GF_RESPONSE_LINK_COUNT_XDATA, nlink);
+ if (ret == -1)
+ gf_msg("posix", GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
+ "Failed to set GF_RESPONSE_LINK_COUNT_XDATA");
out:
- return res;
+ return res;
}
/* Regular fops */
int32_t
-posix_lookup (call_frame_t *frame, xlator_t *this,
- loc_t *loc, dict_t *xdata)
+posix_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
{
- struct iatt buf = {0, };
- int32_t op_ret = -1;
- int32_t entry_ret = 0;
- int32_t op_errno = 0;
- dict_t * xattr = NULL;
- char * real_path = NULL;
- char * par_path = NULL;
- char *gfid_path = NULL;
- uuid_t gfid = {0};
- struct iatt postparent = {0,};
- struct stat statbuf = {0};
- int32_t gfidless = 0;
- char *pgfid_xattr_key = NULL;
- int32_t nlink_samepgfid = 0;
- struct posix_private *priv = NULL;
- posix_inode_ctx_t *ctx = NULL;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (loc, out);
-
- priv = this->private;
-
- /* The Hidden directory should be for housekeeping purpose and it
- should not get any gfid on it */
- if (__is_root_gfid (loc->pargfid) && loc->name
- && (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) {
- gf_msg (this->name, GF_LOG_WARNING, EPERM,
- P_MSG_LOOKUP_NOT_PERMITTED, "Lookup issued on %s,"
- " which is not permitted", GF_HIDDEN_PATH);
- op_errno = EPERM;
- op_ret = -1;
- goto out;
- }
-
- op_ret = dict_get_int32 (xdata, GF_GFIDLESS_LOOKUP, &gfidless);
+ struct iatt buf = {
+ 0,
+ };
+ int32_t op_ret = -1;
+ int32_t entry_ret = 0;
+ int32_t op_errno = 0;
+ dict_t *xattr = NULL;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ char *gfid_path = NULL;
+ uuid_t gfid = {0};
+ struct iatt postparent = {
+ 0,
+ };
+ struct stat statbuf = {0};
+ int32_t gfidless = 0;
+ char *pgfid_xattr_key = NULL;
+ int32_t nlink_samepgfid = 0;
+ struct posix_private *priv = NULL;
+ posix_inode_ctx_t *ctx = NULL;
+ int ret = 0;
+ int dfd = -1;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(loc, out);
+ VALIDATE_OR_GOTO(this->private, out);
+
+ priv = this->private;
+
+ /* The Hidden directory should be for housekeeping purpose and it
+ should not get any gfid on it */
+ if (__is_root_gfid(loc->pargfid) && loc->name &&
+ (strcmp(loc->name, GF_HIDDEN_PATH) == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_LOOKUP_NOT_PERMITTED,
+ "Lookup issued on %s,"
+ " which is not permitted",
+ GF_HIDDEN_PATH);
+ op_errno = EPERM;
op_ret = -1;
- if (gf_uuid_is_null (loc->pargfid) || (loc->name == NULL)) {
- /* nameless lookup */
- MAKE_INODE_HANDLE (real_path, this, loc, &buf);
- } else {
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf);
-
- if (gf_uuid_is_null (loc->inode->gfid)) {
- op_ret = posix_gfid_heal (this, real_path, loc, xdata);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
- MAKE_ENTRY_HANDLE (real_path, par_path, this,
- loc, &buf);
- }
- }
+ goto out;
+ }
- op_errno = errno;
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) && loc->name &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_LOOKUP_NOT_PERMITTED,
+ "Lookup issued on .attribute,"
+ " which is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif /* __NetBSD__ */
- if (op_ret == -1) {
- if (op_errno != ENOENT) {
- gf_msg (this->name, GF_LOG_WARNING, op_errno,
- P_MSG_LSTAT_FAILED,
- "lstat on %s failed",
- real_path ? real_path : "null");
- }
- if (loc_is_nameless(loc)) {
- if (!op_errno)
- op_errno = ESTALE;
- loc_gfid (loc, gfid);
- MAKE_HANDLE_ABSPATH (gfid_path, this, gfid);
- op_ret = sys_lstat(gfid_path, &statbuf);
- if (op_ret == 0 && statbuf.st_nlink == 1) {
- gf_msg (this->name, GF_LOG_WARNING, ESTALE,
- P_MSG_HANDLE_DELETE, "Found stale gfid "
- "handle %s, removing it.", gfid_path);
- posix_handle_unset (this, gfid, NULL);
- }
- }
- entry_ret = -1;
- goto parent;
+ op_ret = dict_get_int32_sizen(xdata, GF_GFIDLESS_LOOKUP, &gfidless);
+ op_ret = -1;
+ if (gf_uuid_is_null(loc->pargfid) || (loc->name == NULL)) {
+ /* nameless lookup */
+ MAKE_INODE_HANDLE(real_path, this, loc, &buf);
+ } else {
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &buf);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
+ if (gf_uuid_is_null(loc->inode->gfid)) {
+ op_ret = posix_gfid_heal(this, real_path, loc, xdata);
+ if (op_ret < 0) {
+ op_errno = -op_ret;
+ op_ret = -1;
+ goto out;
+ }
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &buf);
}
+ }
+
+ op_errno = errno;
- if (xdata && (op_ret == 0)) {
- xattr = posix_xattr_fill (this, real_path, loc, NULL, -1, xdata,
- &buf);
+ if (op_ret == -1) {
+ if (op_errno != ENOENT) {
+ gf_msg(this->name, GF_LOG_WARNING, op_errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_path ? real_path : "null");
}
+ entry_ret = -1;
+ if (loc_is_nameless(loc)) {
+ if (!op_errno)
+ op_errno = ESTALE;
+ loc_gfid(loc, gfid);
+ MAKE_HANDLE_ABSPATH_FD(gfid_path, this, gfid, dfd);
+ ret = sys_fstatat(dfd, gfid_path, &statbuf, 0);
+ if (ret == 0 && ((statbuf.st_mode & S_IFMT) == S_IFDIR))
+ /*Don't unset if it was a symlink to a dir.*/
+ goto parent;
+ ret = sys_fstatat(dfd, gfid_path, &statbuf, AT_SYMLINK_NOFOLLOW);
+ if (ret == 0 && statbuf.st_nlink == 1) {
+ gf_msg(this->name, GF_LOG_WARNING, op_errno,
+ P_MSG_HANDLE_DELETE,
+ "Found stale gfid "
+ "handle %s, removing it.",
+ gfid_path);
+ posix_handle_unset(this, gfid, NULL);
+ }
+ }
+ goto parent;
+ }
+
+ if (xdata && (op_ret == 0)) {
+ xattr = posix_xattr_fill(this, real_path, loc, NULL, -1, xdata, &buf);
+
+ posix_cs_maintenance(this, NULL, loc, NULL, &buf, real_path, xdata,
+ &xattr, _gf_true);
+
+ if (dict_get_sizen(xdata, GF_CLEAN_WRITE_PROTECTION)) {
+ ret = sys_lremovexattr(real_path, GF_PROTECT_FROM_EXTERNAL_WRITES);
+ if (ret == -1 && (errno != ENODATA && errno != ENOATTR))
+ gf_msg(this->name, GF_LOG_ERROR, P_MSG_XATTR_NOT_REMOVED, errno,
+ "removexattr failed. key %s path %s",
+ GF_PROTECT_FROM_EXTERNAL_WRITES, loc->path);
+ }
+ }
+
+ posix_update_iatt_buf(&buf, -1, real_path, xdata);
+ if (priv->update_pgfid_nlinks) {
+ if (!gf_uuid_is_null(loc->pargfid) && !IA_ISDIR(buf.ia_type)) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+
+ op_ret = posix_inode_ctx_get_all(loc->inode, this, &ctx);
+ if (op_ret < 0) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- if (priv->update_pgfid_nlinks) {
- if (!gf_uuid_is_null (loc->pargfid) && !IA_ISDIR (buf.ia_type)) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
- PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
-
- op_ret = posix_inode_ctx_get_all (loc->inode, this,
- &ctx);
- if (op_ret < 0) {
- op_errno = ENOMEM;
- goto out;
- }
-
- pthread_mutex_lock (&ctx->pgfid_lock);
- {
- SET_PGFID_XATTR_IF_ABSENT (real_path,
- pgfid_xattr_key,
- nlink_samepgfid,
- XATTR_CREATE, op_ret,
- this, unlock);
- }
-unlock:
- pthread_mutex_unlock (&ctx->pgfid_lock);
- }
+ pthread_mutex_lock(&ctx->pgfid_lock);
+ {
+ SET_PGFID_XATTR_IF_ABSENT(real_path, pgfid_xattr_key,
+ nlink_samepgfid, XATTR_CREATE, op_ret,
+ this, unlock);
+ }
+ unlock:
+ pthread_mutex_unlock(&ctx->pgfid_lock);
}
+ }
parent:
- if (par_path) {
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_LSTAT_FAILED, "post-operation lstat on"
- " parent %s failed", par_path);
- if (op_errno == ENOENT)
- /* If parent directory is missing in a lookup,
- errno should be ESTALE (bad handle) and not
- ENOENT (missing entry)
- */
- op_errno = ESTALE;
- goto out;
- }
+ if (par_path) {
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path,
+ &postparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on"
+ " parent %s failed",
+ par_path);
+ if (op_errno == ENOENT)
+ /* If parent directory is missing in a lookup,
+ errno should be ESTALE (bad handle) and not
+ ENOENT (missing entry)
+ */
+ op_errno = ESTALE;
+ goto out;
}
+ }
- op_ret = entry_ret;
+ op_ret = entry_ret;
out:
- if (!op_ret && !gfidless && gf_uuid_is_null (buf.ia_gfid)) {
- gf_msg (this->name, GF_LOG_ERROR, ENODATA, P_MSG_NULL_GFID,
- "buf->ia_gfid is null for "
- "%s", (real_path) ? real_path: "");
- op_ret = -1;
- op_errno = ENODATA;
- }
+ if (!op_ret && !gfidless && gf_uuid_is_null(buf.ia_gfid)) {
+ gf_msg(this->name, GF_LOG_ERROR, ENODATA, P_MSG_NULL_GFID,
+ "buf->ia_gfid is null for "
+ "%s",
+ (real_path) ? real_path : "");
+ op_ret = -1;
+ op_errno = ENODATA;
+ }
- if (op_ret == 0)
- op_errno = 0;
- STACK_UNWIND_STRICT (lookup, frame, op_ret, op_errno,
- (loc)?loc->inode:NULL, &buf, xattr, &postparent);
+ if (op_ret == 0)
+ op_errno = 0;
+ STACK_UNWIND_STRICT(lookup, frame, op_ret, op_errno,
+ (loc) ? loc->inode : NULL, &buf, xattr, &postparent);
- if (xattr)
- dict_unref (xattr);
+ if (xattr)
+ dict_unref(xattr);
- return 0;
+ return 0;
}
-int
-posix_mknod (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, dev_t dev, mode_t umask, dict_t *xdata)
+static int32_t
+posix_set_gfid2path_xattr(xlator_t *this, const char *path, uuid_t pgfid,
+ const char *bname)
{
- int tmp_fd = 0;
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_path = 0;
- char *par_path = 0;
- struct iatt stbuf = { 0, };
- struct posix_private *priv = NULL;
- gid_t gid = 0;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- uuid_t uuid_req = {0,};
- int32_t nlink_samepgfid = 0;
- char *pgfid_xattr_key = NULL;
- gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
- gf_boolean_t linked = _gf_false;
- gf_loglevel_t level = GF_LOG_NONE;
- mode_t mode_bit = 0;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (loc, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
- out);
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
-
- mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
- mode = posix_override_umask (mode, mode_bit);
-
- gid = frame->root->gid;
-
- SET_FS_ID (frame->root->uid, gid);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
+ char xxh64[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ char pgfid_bname[1024] = {
+ 0,
+ };
+ char *key = NULL;
+ const size_t key_size = GFID2PATH_XATTR_KEY_PREFIX_LENGTH +
+ GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ int ret = 0;
+ int len;
+
+ len = snprintf(pgfid_bname, sizeof(pgfid_bname), "%s/%s", uuid_utoa(pgfid),
+ bname);
+ gf_xxh64_wrapper((unsigned char *)pgfid_bname, len,
+ GF_XXHSUM64_DEFAULT_SEED, xxh64);
+ key = alloca(key_size);
+ snprintf(key, key_size, GFID2PATH_XATTR_KEY_PREFIX "%s", xxh64);
+
+ ret = sys_lsetxattr(path, key, pgfid_bname, len, XATTR_CREATE);
+ if (ret == -1) {
+ gf_msg(this->name, GF_LOG_WARNING, errno, P_MSG_PGFID_OP,
+ "setting gfid2path xattr failed on %s: key = %s ", path, key);
+ }
+
+ return ret;
+}
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent of %s failed",
- real_path);
- goto out;
- }
+int
+posix_mknod(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ dev_t dev, mode_t umask, dict_t *xdata)
+{
+ int tmp_fd = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ char *par_path = 0;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ uuid_t uuid_req = {
+ 0,
+ };
+ int32_t nlink_samepgfid = 0;
+ char *pgfid_xattr_key = NULL;
+ gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
+ gf_boolean_t linked = _gf_false;
+ gf_loglevel_t level = GF_LOG_NONE;
+ mode_t mode_bit = 0;
+ posix_inode_ctx_t *ctx = NULL;
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(loc, out);
+
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+ GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xdata, op_ret, op_errno,
+ uuid_req, out);
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, NULL);
+
+ mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
+ mode = posix_override_umask(mode, mode_bit);
+
+ gid = frame->root->gid;
+
+ SET_FS_ID(frame->root->uid, gid);
+ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- if (preparent.ia_prot.sgid) {
- gid = preparent.ia_gid;
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent of %s failed", real_path);
+ goto out;
+ }
+
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
+
+ /* Check if the 'gfid' already exists, because this mknod may be an
+ internal call from distribute for creating 'linkfile', and that
+ linkfile may be for a hardlinked file */
+ if (dict_get_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
+ dict_del_sizen(xdata, GLUSTERFS_INTERNAL_FOP_KEY);
+ /* trash xlator did not bring the uuid_via the call
+ * to GFID_NULL_CHECK_AND_GOTO() above.
+ * Fetch it explicitly here.
+ */
+ if (frame->root->pid == GF_SERVER_PID_TRASH) {
+ op_ret = dict_get_gfuuid(xdata, "gfid-req", &uuid_req);
+ if (op_ret) {
+ gf_msg_debug(this->name, 0,
+ "failed to get the gfid from dict for %s",
+ loc->path);
+ goto real_op;
+ }
}
- /* Check if the 'gfid' already exists, because this mknod may be an
- internal call from distribute for creating 'linkfile', and that
- linkfile may be for a hardlinked file */
- if (dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
- dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY);
- op_ret = dict_get_gfuuid (xdata, "gfid-req", &uuid_req);
- if (op_ret) {
- gf_msg_debug (this->name, 0, "failed to get the gfid from "
- "dict for %s", loc->path);
- goto real_op;
- }
- op_ret = posix_create_link_if_gfid_exists (this, uuid_req,
- real_path,
- loc->inode->table);
- if (!op_ret) {
- linked = _gf_true;
- goto post_op;
- }
+ op_ret = posix_create_link_if_gfid_exists(this, uuid_req, real_path,
+ loc->inode->table);
+ if (!op_ret) {
+ linked = _gf_true;
+ goto post_op;
}
+ }
real_op:
#ifdef __NetBSD__
- if (S_ISFIFO(mode))
- op_ret = mkfifo (real_path, mode);
- else
+ if (S_ISFIFO(mode))
+ op_ret = mkfifo(real_path, mode);
+ else
#endif /* __NetBSD__ */
- op_ret = sys_mknod (real_path, mode, dev);
+ op_ret = sys_mknod(real_path, mode, dev);
- if (op_ret == -1) {
- op_errno = errno;
- if ((op_errno == EINVAL) && S_ISREG (mode)) {
- /* Over Darwin, mknod with (S_IFREG|mode)
- doesn't work */
- tmp_fd = sys_creat (real_path, mode);
- if (tmp_fd == -1) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_CREATE_FAILED, "create failed on"
- "%s", real_path);
- goto out;
- }
- sys_close (tmp_fd);
- } else {
- if (op_errno == EEXIST)
- level = GF_LOG_DEBUG;
- else
- level = GF_LOG_ERROR;
- gf_msg (this->name, level, errno, P_MSG_MKNOD_FAILED,
- "mknod on %s failed", real_path);
- goto out;
- }
+ if (op_ret == -1) {
+ op_errno = errno;
+ if ((op_errno == EINVAL) && S_ISREG(mode)) {
+ /* Over Darwin, mknod with (S_IFREG|mode)
+ doesn't work */
+ tmp_fd = sys_creat(real_path, mode);
+ if (tmp_fd == -1) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_CREATE_FAILED,
+ "create failed on"
+ "%s",
+ real_path);
+ goto out;
+ }
+ sys_close(tmp_fd);
+ } else {
+ if (op_errno == EEXIST)
+ level = GF_LOG_DEBUG;
+ else
+ level = GF_LOG_ERROR;
+ gf_msg(this->name, level, errno, P_MSG_MKNOD_FAILED,
+ "mknod on %s failed", real_path);
+ goto out;
}
+ }
- entry_created = _gf_true;
+ entry_created = _gf_true;
#ifndef HAVE_SET_FSID
- op_ret = sys_lchown (real_path, frame->root->uid, gid);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LCHOWN_FAILED,
- "lchown on %s failed", real_path);
- goto out;
- }
+ op_ret = sys_lchown(real_path, frame->root->uid, gid);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LCHOWN_FAILED,
+ "lchown on %s failed", real_path);
+ goto out;
+ }
#endif
post_op:
- op_ret = posix_acl_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_ACL_FAILED,
- "setting ACLs on %s failed", real_path);
- }
-
- if (priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
-
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
+ op_ret = posix_acl_xattr_set(this, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, 0, P_MSG_ACL_FAILED,
+ "setting ACLs on %s failed", real_path);
+ }
+
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ op_ret = posix_inode_ctx_get_all(loc->inode, this, &ctx);
+ if (op_ret < 0) {
+ op_errno = ENOMEM;
+ goto out;
}
- if (priv->gfid2path) {
- posix_set_gfid2path_xattr (this, real_path, loc->pargfid,
- loc->name);
- }
+ pthread_mutex_lock(&ctx->pgfid_lock);
+ {
+ LINK_MODIFY_PGFID_XATTR(real_path, pgfid_xattr_key, nlink_samepgfid,
+ 0, op_ret, this, unlock);
+ }
+ unlock:
+ pthread_mutex_unlock(&ctx->pgfid_lock);
+ }
+
+ if (priv->gfid2path) {
+ posix_set_gfid2path_xattr(this, real_path, loc->pargfid, loc->name);
+ }
+
+ op_ret = posix_entry_create_xattr_set(this, loc, real_path, xdata);
+ if (op_ret) {
+ if (errno != EEXIST)
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
+ "setting xattrs on %s failed", real_path);
+ else
+ gf_msg_debug(this->name, 0, "setting xattrs on %s failed",
+ real_path);
+ }
-ignore:
- op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
+ if (!linked) {
+ op_ret = posix_gfid_set(this, real_path, loc, xdata, frame->root->pid,
+ &op_errno);
if (op_ret) {
- if (errno != EEXIST)
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_XATTR_FAILED,
- "setting xattrs on %s failed", real_path);
- else
- gf_msg_debug (this->name, 0,
- "setting xattrs on %s failed", real_path);
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED,
+ "setting gfid on %s failed", real_path);
+ goto out;
+ } else {
+ gfid_set = _gf_true;
}
+ }
- if (!linked) {
- op_ret = posix_gfid_set (this, real_path, loc, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED,
- "setting gfid on %s failed", real_path);
- } else {
- gfid_set = _gf_true;
- }
- }
+ op_ret = posix_pstat(this, loc->inode, NULL, real_path, &stbuf, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_MKNOD_FAILED,
+ "mknod on %s failed", real_path);
+ goto out;
+ }
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_MKNOD_FAILED,
- "mknod on %s failed", real_path);
- goto out;
- }
+ posix_set_ctime(frame, this, real_path, -1, loc->inode, &stbuf);
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- op_ret = 0;
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
-out:
- SET_TO_OLD_FS_ID ();
+ op_ret = 0;
- if (op_ret < 0) {
- if (entry_created) {
- if (S_ISREG (mode))
- sys_unlink (real_path);
- else
- sys_rmdir (real_path);
- }
+out:
+ SET_TO_OLD_FS_ID();
- if (gfid_set)
- posix_gfid_unset (this, xdata);
+ if (op_ret < 0) {
+ if (entry_created) {
+ if (S_ISREG(mode))
+ sys_unlink(real_path);
+ else
+ sys_rmdir(real_path);
}
- STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno,
- (loc)?loc->inode:NULL, &stbuf, &preparent,
- &postparent, NULL);
+ if (gfid_set)
+ posix_gfid_unset(this, xdata);
+ }
- return 0;
+ STACK_UNWIND_STRICT(mknod, frame, op_ret, op_errno,
+ (loc) ? loc->inode : NULL, &stbuf, &preparent,
+ &postparent, NULL);
+
+ return 0;
}
int
-posix_mkdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, mode_t mode, mode_t umask, dict_t *xdata)
+posix_mkdir(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_path = NULL, *gfid_path = NULL;
- char *par_path = NULL, *xattr_name = NULL;
- struct iatt stbuf = {0, };
- struct posix_private *priv = NULL;
- gid_t gid = 0;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
- uuid_t uuid_req = {0,};
- ssize_t size = 0;
- dict_t *xdata_rsp = NULL;
- void *disk_xattr = NULL;
- data_t *arg_data = NULL;
- char pgfid[GF_UUID_BUF_SIZE] = {0};
- char value_buf[4096] = {0,};
- gf_boolean_t have_val = _gf_false;
- mode_t mode_bit = 0;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (loc, out);
-
- /* The Hidden directory should be for housekeeping purpose and it
- should not get created from a user request */
- if (__is_root_gfid (loc->pargfid) &&
- (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) {
- gf_msg (this->name, GF_LOG_WARNING, EPERM,
- P_MSG_MKDIR_NOT_PERMITTED, "mkdir issued on %s, which"
- "is not permitted", GF_HIDDEN_PATH);
- op_errno = EPERM;
- op_ret = -1;
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL, *gfid_path = NULL;
+ char *par_path = NULL, *xattr_name = NULL;
+ int xattr_name_len;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
+ uuid_t uuid_req = {
+ 0,
+ };
+ ssize_t size = 0;
+ dict_t *xdata_rsp = NULL;
+ char *disk_xattr = NULL;
+ data_t *arg_data = NULL;
+ char pgfid[GF_UUID_BUF_SIZE] = {0};
+ mode_t mode_bit = 0;
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(loc, out);
+
+ /* The Hidden directory should be for housekeeping purpose and it
+ should not get created from a user request */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, GF_HIDDEN_PATH) == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_MKDIR_NOT_PERMITTED,
+ "mkdir issued on %s, which"
+ "is not permitted",
+ GF_HIDDEN_PATH);
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
- out);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_MKDIR_NOT_PERMITTED,
+ "mkdir issued on .attribute, which"
+ "is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+ GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xdata, op_ret, op_errno,
+ uuid_req, out);
+ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out);
- if (loc->parent)
- gf_uuid_unparse (loc->parent->gfid, pgfid);
- else
- gf_uuid_unparse (loc->pargfid, pgfid);
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, NULL);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- gid = frame->root->gid;
+ gid = frame->root->gid;
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
+ op_ret = posix_pstat(this, loc->inode, NULL, real_path, &stbuf, _gf_false);
- SET_FS_ID (frame->root->uid, gid);
+ SET_FS_ID(frame->root->uid, gid);
- mode_bit = (priv->create_directory_mask & mode)
- | priv->force_directory_mode;
- mode = posix_override_umask (mode, mode_bit);
+ mode_bit = (priv->create_directory_mask & mode) |
+ priv->force_directory_mode;
+ mode = posix_override_umask(mode, mode_bit);
- if (xdata) {
- op_ret = dict_get_gfuuid (xdata, "gfid-req", &uuid_req);
- if (!op_ret && !gf_uuid_compare (stbuf.ia_gfid, uuid_req)) {
- op_ret = -1;
- op_errno = EEXIST;
- goto out;
- }
+ if (xdata) {
+ if (!gf_uuid_compare(stbuf.ia_gfid, uuid_req)) {
+ op_ret = -1;
+ op_errno = EEXIST;
+ goto out;
}
+ }
- if (!gf_uuid_is_null (uuid_req)) {
- op_ret = posix_istat (this, uuid_req, NULL, &stbuf);
- if ((op_ret == 0) && IA_ISDIR (stbuf.ia_type)) {
- size = posix_handle_path (this, uuid_req, NULL, NULL,
- 0);
- if (size > 0)
- gfid_path = alloca (size);
-
- if (gfid_path)
- posix_handle_path (this, uuid_req, NULL,
- gfid_path, size);
-
- if (frame->root->pid != GF_CLIENT_PID_SELF_HEALD) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- P_MSG_DIR_OF_SAME_ID, "mkdir (%s): "
- "gfid (%s) is already associated with "
- "directory (%s). Hence, both "
- "directories will share same gfid and "
- "this can lead to inconsistencies.",
- loc->path, uuid_utoa (uuid_req),
- gfid_path ? gfid_path : "<NULL>");
-
- gf_event (EVENT_POSIX_SAME_GFID, "gfid=%s;"
- "path=%s;newpath=%s;brick=%s:%s",
- uuid_utoa (uuid_req),
- gfid_path ? gfid_path : "<NULL>",
- loc->path, priv->hostname,
- priv->base_path);
- }
- if (!posix_symlinks_match (this, loc, uuid_req))
- /* For afr selfheal of dir renames, we need to
- * remove the old symlink in order for
- * posix_gfid_set to set the symlink to the
- * new dir.*/
- posix_handle_unset (this, stbuf.ia_gfid, NULL);
- }
- } else if (frame->root->pid != GF_SERVER_PID_TRASH) {
+ if (!gf_uuid_is_null(uuid_req)) {
+ op_ret = posix_istat(this, loc->inode, uuid_req, NULL, &stbuf);
+ if ((op_ret == 0) && IA_ISDIR(stbuf.ia_type)) {
+ gfid_path = alloca(PATH_MAX);
+ size = posix_handle_path(this, uuid_req, NULL, gfid_path, PATH_MAX);
+ if (size <= 0) {
+ op_errno = ESTALE;
op_ret = -1;
- op_errno = EPERM;
- gf_msg_callingfn (this->name, GF_LOG_WARNING, op_errno,
- P_MSG_NULL_GFID, "mkdir (%s): is issued without "
- "gfid-req %p", loc->path, xdata);
goto out;
- }
-
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
+ }
+
+ if (frame->root->pid != GF_CLIENT_PID_SELF_HEALD) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_DIR_OF_SAME_ID,
+ "mkdir (%s): "
+ "gfid (%s) is already associated with "
+ "directory (%s). Hence, both "
+ "directories will share same gfid and "
+ "this can lead to inconsistencies.",
+ loc->path, uuid_utoa(uuid_req),
+ gfid_path ? gfid_path : "<NULL>");
+
+ gf_event(EVENT_POSIX_SAME_GFID,
+ "gfid=%s;"
+ "path=%s;newpath=%s;brick=%s:%s",
+ uuid_utoa(uuid_req), gfid_path ? gfid_path : "<NULL>",
+ loc->path, priv->hostname, priv->base_path);
+ }
+ if (!posix_symlinks_match(this, loc, uuid_req))
+ /* For afr selfheal of dir renames, we need to
+ * remove the old symlink in order for
+ * posix_gfid_set to set the symlink to the
+ * new dir.*/
+ posix_handle_unset(this, stbuf.ia_gfid, NULL);
+ }
+ } else if (frame->root->pid != GF_SERVER_PID_TRASH) {
+ op_ret = -1;
+ op_errno = EPERM;
+ gf_msg_callingfn(this->name, GF_LOG_WARNING, op_errno, P_MSG_NULL_GFID,
+ "mkdir (%s): is issued without "
+ "gfid-req %p",
+ loc->path, xdata);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
+
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ mode |= S_ISGID;
+ }
+
+ op_ret = dict_get_str_sizen(xdata, GF_PREOP_PARENT_KEY, &xattr_name);
+ if (xattr_name != NULL) {
+ xattr_name_len = strlen(xattr_name);
+ arg_data = dict_getn(xdata, xattr_name, xattr_name_len);
+ if (arg_data) {
+ if (loc->parent)
+ gf_uuid_unparse(loc->parent->gfid, pgfid);
+ else
+ gf_uuid_unparse(loc->pargfid, pgfid);
+
+ size = 256;
+ disk_xattr = GF_MALLOC(size + 1, gf_posix_mt_char);
+ if (!disk_xattr) {
+ op_ret = -1;
op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_path);
+ gf_msg(this->name, GF_LOG_ERROR, errno,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): GF_MALLOC failed during"
+ " preop of mkdir (%s)",
+ pgfid, loc->name, real_path);
+ goto out;
+ }
+ disk_xattr[size] = '\0';
+
+ size = sys_lgetxattr(par_path, xattr_name, disk_xattr, size);
+ if (size == -1) {
+ if (disk_xattr) {
+ GF_FREE(disk_xattr);
+ disk_xattr = NULL;
+ }
+ if (errno != ERANGE) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): getxattr failed during"
+ " preop of mkdir (%s).",
+ pgfid, loc->name, real_path);
+ goto out;
+ }
+ gf_msg(this->name, GF_LOG_INFO, errno, P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): getxattr on key "
+ "(%s) path (%s) failed due to "
+ " buffer overflow",
+ pgfid, loc->name, xattr_name, par_path);
+ size = sys_lgetxattr(par_path, xattr_name, NULL, 0);
+ if (size == -1) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): getxattr on key (%s)"
+ " path (%s) failed ",
+ pgfid, loc->name, xattr_name, par_path);
+ goto out;
+ }
+ disk_xattr = GF_MALLOC(size + 1, gf_posix_mt_char);
+ if (!disk_xattr) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): GF_MALLOC failed during"
+ " preop of mkdir (%s)",
+ pgfid, loc->name, real_path);
+ goto out;
+ }
+ disk_xattr[size] = '\0';
+ size = sys_lgetxattr(par_path, xattr_name, disk_xattr, size);
+ if (size == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): getxattr on "
+ " key (%s) path (%s) failed "
+ "(%s)",
+ pgfid, loc->name, xattr_name, par_path,
+ strerror(errno));
+ goto out;
+ }
+ }
+ if ((arg_data->len != size) ||
+ (memcmp(arg_data->data, disk_xattr, size))) {
+ gf_msg(this->name, GF_LOG_INFO, EIO, P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): failing preop of "
+ "mkdir (%s) as on-disk"
+ " xattr value differs from argument "
+ "value for key %s",
+ pgfid, loc->name, real_path, xattr_name);
+ op_ret = -1;
+ op_errno = EIO;
+
+ xdata_rsp = dict_new();
+ if (xdata_rsp == NULL) {
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM,
+ P_MSG_PREOP_CHECK_FAILED,
+ "mkdir (%s/%s): "
+ "dict allocation failed",
+ pgfid, loc->name);
+ op_errno = ENOMEM;
+ goto out;
+ }
+
+ op_errno = dict_set_int8(xdata_rsp, GF_PREOP_CHECK_FAILED, 1);
+ if (op_errno < 0)
+ op_errno = errno;
goto out;
- }
+ }
- if (preparent.ia_prot.sgid) {
- gid = preparent.ia_gid;
- mode |= S_ISGID;
+ dict_deln(xdata, xattr_name, xattr_name_len);
}
- op_ret = dict_get_str (xdata, GF_PREOP_PARENT_KEY, &xattr_name);
- if (xattr_name != NULL) {
- arg_data = dict_get (xdata, xattr_name);
- if (arg_data) {
- size = sys_lgetxattr (par_path, xattr_name, value_buf,
- sizeof(value_buf) - 1);
- if (size >= 0) {
- have_val = _gf_true;
- } else {
- if (errno == ERANGE) {
- gf_msg (this->name, GF_LOG_INFO, errno,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): getxattr on key "
- "(%s) path (%s) failed due to "
- " buffer overflow", pgfid,
- loc->name, xattr_name,
- par_path);
- size = sys_lgetxattr (par_path,
- xattr_name, NULL,
- 0);
- }
- if (size < 0) {
- op_ret = -1;
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): getxattr on key (%s)"
- " path (%s) failed ", pgfid,
- loc->name, xattr_name,
- par_path);
- goto out;
- }
- }
- disk_xattr = alloca (size);
- if (disk_xattr == NULL) {
- op_ret = -1;
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): alloca failed during"
- " preop of mkdir (%s)", pgfid,
- loc->name, real_path);
- goto out;
- }
- if (have_val) {
- memcpy (disk_xattr, value_buf, size);
- } else {
- size = sys_lgetxattr (par_path, xattr_name,
- disk_xattr, size);
- if (size < 0) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): getxattr on "
- " key (%s) path (%s) failed "
- "(%s)", pgfid, loc->name,
- xattr_name, par_path,
- strerror (errno));
- goto out;
- }
- }
- if ((arg_data->len != size)
- || (memcmp (arg_data->data, disk_xattr, size))) {
- gf_msg (this->name, GF_LOG_INFO, EIO,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): failing preop of "
- "mkdir (%s) as on-disk"
- " xattr value differs from argument "
- "value for key %s", pgfid, loc->name,
- real_path, xattr_name);
- op_ret = -1;
- op_errno = EIO;
-
- xdata_rsp = dict_new ();
- if (xdata_rsp == NULL) {
- gf_msg (this->name, GF_LOG_ERROR,
- ENOMEM,
- P_MSG_PREOP_CHECK_FAILED,
- "mkdir (%s/%s): "
- "dict allocation failed", pgfid,
- loc->name);
- op_errno = ENOMEM;
- goto out;
- }
-
- op_errno = dict_set_int8 (xdata_rsp,
- GF_PREOP_CHECK_FAILED, 1);
- goto out;
- }
-
- dict_del (xdata, xattr_name);
- }
+ dict_del_sizen(xdata, GF_PREOP_PARENT_KEY);
+ }
- dict_del (xdata, GF_PREOP_PARENT_KEY);
- }
-
- op_ret = sys_mkdir (real_path, mode);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_MKDIR_FAILED,
- "mkdir of %s failed", real_path);
- goto out;
- }
+ op_ret = sys_mkdir(real_path, mode);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_MKDIR_FAILED,
+ "mkdir of %s failed", real_path);
+ goto out;
+ }
- entry_created = _gf_true;
+ entry_created = _gf_true;
#ifndef HAVE_SET_FSID
- op_ret = sys_chown (real_path, frame->root->uid, gid);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_CHOWN_FAILED,
- "chown on %s failed", real_path);
- goto out;
- }
+ op_ret = sys_chown(real_path, frame->root->uid, gid);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_CHOWN_FAILED,
+ "chown on %s failed", real_path);
+ goto out;
+ }
#endif
- op_ret = posix_acl_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
- "setting ACLs on %s failed ", real_path);
- }
-
- op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
- "setting xattrs on %s failed", real_path);
- }
+ op_ret = posix_acl_xattr_set(this, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
+ "setting ACLs on %s failed ", real_path);
+ }
+
+ op_ret = posix_entry_create_xattr_set(this, loc, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
+ "setting xattrs on %s failed", real_path);
+ }
+
+ op_ret = posix_gfid_set(this, real_path, loc, xdata, frame->root->pid,
+ &op_errno);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED,
+ "setting gfid on %s failed", real_path);
+ goto out;
+ } else {
+ gfid_set = _gf_true;
+ }
+
+ op_ret = posix_pstat(this, loc->inode, NULL, real_path, &stbuf, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_path);
+ goto out;
+ }
- op_ret = posix_gfid_set (this, real_path, loc, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED,
- "setting gfid on %s failed", real_path);
- } else {
- gfid_set = _gf_true;
- }
+ posix_set_ctime(frame, this, real_path, -1, loc->inode, &stbuf);
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat on %s failed", real_path);
- goto out;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent of %s failed", real_path);
+ goto out;
+ }
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent of %s failed",
- real_path);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
- op_ret = 0;
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- if (op_ret < 0) {
- if (entry_created)
- sys_rmdir (real_path);
+ if (disk_xattr)
+ GF_FREE(disk_xattr);
- if (gfid_set)
- posix_gfid_unset (this, xdata);
- }
+ if (op_ret < 0) {
+ if (entry_created)
+ sys_rmdir(real_path);
- STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno,
- (loc)?loc->inode:NULL, &stbuf, &preparent,
- &postparent, xdata_rsp);
+ if (gfid_set)
+ posix_gfid_unset(this, xdata);
+ }
- if (xdata_rsp)
- dict_unref (xdata_rsp);
+ STACK_UNWIND_STRICT(mkdir, frame, op_ret, op_errno,
+ (loc) ? loc->inode : NULL, &stbuf, &preparent,
+ &postparent, xdata_rsp);
- return 0;
+ if (xdata_rsp)
+ dict_unref(xdata_rsp);
+
+ return 0;
}
-int
-posix_add_unlink_to_ctx (inode_t *inode, xlator_t *this, char *unlink_path)
+static int
+posix_add_unlink_to_ctx(inode_t *inode, xlator_t *this, char *unlink_path)
{
- uint64_t ctx = GF_UNLINK_FALSE;
- int ret = 0;
-
- if (!unlink_path) {
- gf_msg (this->name, GF_LOG_ERROR, ENOMEM,
- P_MSG_UNLINK_FAILED,
- "Creation of unlink entry failed for gfid: %s",
- unlink_path);
- ret = -1;
- goto out;
- }
-
- ctx = GF_UNLINK_TRUE;
- ret = posix_inode_ctx_set_unlink_flag (inode, this, ctx);
- if (ret < 0) {
- goto out;
- }
+ uint64_t ctx = GF_UNLINK_FALSE;
+ int ret = 0;
+
+ if (!unlink_path) {
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM, P_MSG_UNLINK_FAILED,
+ "Creation of unlink entry failed");
+ ret = -1;
+ goto out;
+ }
+
+ ctx = GF_UNLINK_TRUE;
+ ret = posix_inode_ctx_set_unlink_flag(inode, this, ctx);
+ if (ret < 0) {
+ goto out;
+ }
out:
- return ret;
+ return ret;
}
-int32_t
-posix_move_gfid_to_unlink (xlator_t *this, uuid_t gfid, loc_t *loc)
+static int32_t
+posix_move_gfid_to_unlink(xlator_t *this, uuid_t gfid, loc_t *loc)
{
- char *unlink_path = NULL;
- char *gfid_path = NULL;
- int ret = 0;
- struct posix_private *priv_posix = NULL;
-
- priv_posix = (struct posix_private *) this->private;
-
- MAKE_HANDLE_GFID_PATH (gfid_path, this, gfid, NULL);
-
- POSIX_GET_FILE_UNLINK_PATH (priv_posix->base_path,
- loc->inode->gfid, unlink_path);
- if (!unlink_path) {
- ret = -1;
- goto out;
- }
- gf_msg_debug (this->name, 0,
- "Moving gfid: %s to unlink_path : %s",
- gfid_path, unlink_path);
- ret = sys_rename (gfid_path, unlink_path);
- if (ret < 0) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_UNLINK_FAILED,
- "Creation of unlink entry failed for gfid: %s",
- unlink_path);
- goto out;
- }
- ret = posix_add_unlink_to_ctx (loc->inode, this, unlink_path);
- if (ret < 0)
- goto out;
+ char *unlink_path = NULL;
+ char *gfid_path = NULL;
+ int ret = -1;
+ struct posix_private *priv_posix = NULL;
+
+ priv_posix = (struct posix_private *)this->private;
+
+ MAKE_HANDLE_GFID_PATH(gfid_path, this, gfid);
+
+ POSIX_GET_FILE_UNLINK_PATH(priv_posix->base_path, loc->inode->gfid,
+ unlink_path);
+ if (!unlink_path) {
+ ret = -1;
+ goto out;
+ }
+ gf_msg_debug(this->name, 0, "Moving gfid: %s to unlink_path : %s",
+ gfid_path, unlink_path);
+ ret = sys_rename(gfid_path, unlink_path);
+ if (ret < 0) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_UNLINK_FAILED,
+ "Creation of unlink entry failed for gfid: %s", unlink_path);
+ goto out;
+ }
+ ret = posix_add_unlink_to_ctx(loc->inode, this, unlink_path);
+ if (ret < 0)
+ goto out;
out:
- return ret;
+ return ret;
}
-int32_t
-posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path,
- struct iatt *stbuf, int32_t *op_errno,
- loc_t *loc, gf_boolean_t get_link_count,
- dict_t *rsp_dict)
+static int32_t
+posix_unlink_gfid_handle_and_entry(call_frame_t *frame, xlator_t *this,
+ const char *real_path, struct iatt *stbuf,
+ int32_t *op_errno, loc_t *loc,
+ gf_boolean_t get_link_count,
+ dict_t *rsp_dict)
{
- int32_t ret = 0;
- struct iatt prebuf = {0,};
- gf_boolean_t locked = _gf_false;
-
- /* Unlink the gfid_handle_first */
- if (stbuf && stbuf->ia_nlink == 1) {
-
- LOCK (&loc->inode->lock);
-
- if (loc->inode->fd_count == 0) {
- UNLOCK (&loc->inode->lock);
- ret = posix_handle_unset (this, stbuf->ia_gfid, NULL);
- } else {
- UNLOCK (&loc->inode->lock);
- ret = posix_move_gfid_to_unlink (this, stbuf->ia_gfid,
- loc);
- }
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_UNLINK_FAILED, "unlink of gfid handle "
- "failed for path:%s with gfid %s",
- real_path, uuid_utoa (stbuf->ia_gfid));
- }
- }
-
- if (get_link_count) {
- LOCK (&loc->inode->lock);
- locked = _gf_true;
- ret = posix_pstat (this, loc->gfid, real_path, &prebuf);
- if (ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_LSTAT_FAILED, "lstat on %s failed",
- real_path);
- goto err;
- }
- }
-
- /* Unlink the actual file */
- ret = sys_unlink (real_path);
- if (ret == -1) {
- if (op_errno)
- *op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_UNLINK_FAILED,
- "unlink of %s failed", real_path);
- goto err;
- }
-
- if (locked) {
- UNLOCK (&loc->inode->lock);
- locked = _gf_false;
- }
-
- ret = dict_set_uint32 (rsp_dict, GET_LINK_COUNT, prebuf.ia_nlink);
- if (ret)
- gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
- "failed to set "GET_LINK_COUNT" for %s", real_path);
-
- return 0;
+ int32_t ret = 0;
+ struct iatt prebuf = {
+ 0,
+ };
+ gf_boolean_t locked = _gf_false;
+ gf_boolean_t update_ctime = _gf_false;
+
+ /* Unlink the gfid_handle_first */
+ if (stbuf && stbuf->ia_nlink == 1) {
+ LOCK(&loc->inode->lock);
+
+ if (loc->inode->fd_count == 0) {
+ UNLOCK(&loc->inode->lock);
+ ret = posix_handle_unset(this, stbuf->ia_gfid, NULL);
+ } else {
+ UNLOCK(&loc->inode->lock);
+ ret = posix_move_gfid_to_unlink(this, stbuf->ia_gfid, loc);
+ }
+ if (ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_UNLINK_FAILED,
+ "unlink of gfid handle "
+ "failed for path:%s with gfid %s",
+ real_path, uuid_utoa(stbuf->ia_gfid));
+ }
+ } else {
+ update_ctime = _gf_true;
+ }
+
+ if (get_link_count) {
+ LOCK(&loc->inode->lock);
+ locked = _gf_true;
+ /* Since this stat is to get link count and not for time
+ * attributes, intentionally passing inode as NULL
+ */
+ ret = posix_pstat(this, NULL, loc->gfid, real_path, &prebuf, _gf_true);
+ if (ret) {
+ UNLOCK(&loc->inode->lock);
+ locked = _gf_false;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_path);
+ goto err;
+ }
+ }
+
+ /* Unlink the actual file */
+ ret = sys_unlink(real_path);
+
+ if (locked) {
+ UNLOCK(&loc->inode->lock);
+ locked = _gf_false;
+ }
+
+ if (ret == -1) {
+ if (op_errno)
+ *op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_UNLINK_FAILED,
+ "unlink of %s failed", real_path);
+ goto err;
+ }
+
+ if (update_ctime) {
+ posix_set_ctime(frame, this, NULL, -1, loc->inode, stbuf);
+ }
+
+ ret = dict_set_uint32(rsp_dict, GET_LINK_COUNT, prebuf.ia_nlink);
+ if (ret)
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
+ "failed to set " GET_LINK_COUNT " for %s", real_path);
+
+ return 0;
err:
- if (locked) {
- UNLOCK (&loc->inode->lock);
- locked = _gf_false;
- }
- return -1;
+ if (locked) {
+ UNLOCK(&loc->inode->lock);
+ locked = _gf_false;
+ }
+ return -1;
}
-gf_boolean_t
-posix_skip_non_linkto_unlink (dict_t *xdata, loc_t *loc, char *key,
- const char *linkto_xattr, struct iatt *stbuf,
- const char *real_path)
+static gf_boolean_t
+posix_skip_non_linkto_unlink(dict_t *xdata, loc_t *loc, char *key,
+ const int keylen, const char *linkto_xattr,
+ struct iatt *stbuf, const char *real_path)
{
- gf_boolean_t skip_unlink = _gf_false;
- gf_boolean_t is_dht_linkto_file = _gf_false;
- int unlink_if_linkto = 0;
- ssize_t xattr_size = -1;
- int op_ret = -1;
-
- op_ret = dict_get_int32 (xdata, key,
- &unlink_if_linkto);
+ gf_boolean_t skip_unlink = _gf_false;
+ gf_boolean_t is_dht_linkto_file = _gf_false;
+ int unlink_if_linkto = 0;
+ ssize_t xattr_size = -1;
+ int op_ret = -1;
- if (!op_ret && unlink_if_linkto) {
+ op_ret = dict_get_int32n(xdata, key, keylen, &unlink_if_linkto);
- is_dht_linkto_file = IS_DHT_LINKFILE_MODE (stbuf);
- if (!is_dht_linkto_file)
- return _gf_true;
+ if (!op_ret && unlink_if_linkto) {
+ is_dht_linkto_file = IS_DHT_LINKFILE_MODE(stbuf);
+ if (!is_dht_linkto_file)
+ return _gf_true;
- LOCK (&loc->inode->lock);
+ LOCK(&loc->inode->lock);
- xattr_size = sys_lgetxattr (real_path, linkto_xattr, NULL, 0);
+ xattr_size = sys_lgetxattr(real_path, linkto_xattr, NULL, 0);
- if (xattr_size <= 0)
- skip_unlink = _gf_true;
+ UNLOCK(&loc->inode->lock);
- UNLOCK (&loc->inode->lock);
+ if (xattr_size <= 0)
+ skip_unlink = _gf_true;
- gf_msg ("posix", GF_LOG_INFO, 0, P_MSG_XATTR_STATUS,
- "linkto_xattr status: %"PRIu32" for %s", skip_unlink,
- real_path);
- }
- return skip_unlink;
+ gf_msg("posix", GF_LOG_INFO, 0, P_MSG_XATTR_STATUS,
+ "linkto_xattr status: %" PRIu32 " for %s", skip_unlink,
+ real_path);
+ }
+ return skip_unlink;
+}
+static int32_t
+posix_remove_gfid2path_xattr(xlator_t *this, const char *path, uuid_t pgfid,
+ const char *bname)
+{
+ char xxh64[GF_XXH64_DIGEST_LENGTH * 2 + 1] = {
+ 0,
+ };
+ char pgfid_bname[1024] = {
+ 0,
+ };
+ int ret = 0;
+ char *key = NULL;
+ const size_t key_size = GFID2PATH_XATTR_KEY_PREFIX_LENGTH +
+ GF_XXH64_DIGEST_LENGTH * 2 + 1;
+ int len;
+
+ len = snprintf(pgfid_bname, sizeof(pgfid_bname), "%s/%s", uuid_utoa(pgfid),
+ bname);
+ gf_xxh64_wrapper((unsigned char *)pgfid_bname, len,
+ GF_XXHSUM64_DEFAULT_SEED, xxh64);
+ key = alloca(key_size);
+ snprintf(key, key_size, GFID2PATH_XATTR_KEY_PREFIX "%s", xxh64);
+
+ ret = sys_lremovexattr(path, key);
+ if (ret == -1) {
+ gf_msg(this->name, GF_LOG_WARNING, errno, P_MSG_PGFID_OP,
+ "removing gfid2path xattr failed on %s: key = %s", path, key);
+ }
+
+ return ret;
}
int32_t
-posix_unlink (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int xflag, dict_t *xdata)
+posix_unlink(call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag,
+ dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_path = NULL;
- char *par_path = NULL;
- int32_t fd = -1;
- struct iatt stbuf = {0,};
- struct iatt postbuf = {0,};
- struct posix_private *priv = NULL;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- char *pgfid_xattr_key = NULL;
- int32_t nlink_samepgfid = 0;
- int32_t check_open_fd = 0;
- int32_t skip_unlink = 0;
- int32_t fdstat_requested = 0;
- dict_t *unwind_dict = NULL;
- void *uuid = NULL;
- char uuid_str[GF_UUID_BUF_SIZE] = {0};
- char gfid_str[GF_UUID_BUF_SIZE] = {0};
- gf_boolean_t get_link_count = _gf_false;
- posix_inode_ctx_t *ctx = NULL;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (loc, out);
-
- SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
-
- priv = this->private;
-
- op_ret = dict_get_ptr (xdata, TIER_LINKFILE_GFID, &uuid);
-
- if (!op_ret && gf_uuid_compare (uuid, stbuf.ia_gfid)) {
- op_errno = ENOENT;
- op_ret = -1;
- gf_uuid_unparse (uuid, uuid_str);
- gf_uuid_unparse (stbuf.ia_gfid, gfid_str);
- gf_msg_debug (this->name, op_errno, "Mismatch in gfid for path "
- "%s. Aborting the unlink. loc->gfid = %s, "
- "stbuf->ia_gfid = %s", real_path,
- uuid_str, gfid_str);
- goto out;
- }
-
- op_ret = dict_get_int32 (xdata, DHT_SKIP_OPEN_FD_UNLINK,
- &check_open_fd);
-
- if (!op_ret && check_open_fd) {
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ int32_t fd = -1;
+ int ret = -1;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct iatt postbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ char *pgfid_xattr_key = NULL;
+ int32_t nlink_samepgfid = 0;
+ int32_t check_open_fd = 0;
+ int32_t skip_unlink = 0;
+ int32_t fdstat_requested = 0;
+ dict_t *unwind_dict = NULL;
+ gf_boolean_t get_link_count = _gf_false;
+ posix_inode_ctx_t *ctx = NULL;
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(this->private, out);
+ VALIDATE_OR_GOTO(loc, out);
+
+ SET_FS_ID(frame->root->uid, frame->root->gid);
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- LOCK (&loc->inode->lock);
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- if (loc->inode->fd_count) {
- skip_unlink = 1;
- }
+ priv = this->private;
- UNLOCK (&loc->inode->lock);
+ op_ret = dict_get_int32_sizen(xdata, DHT_SKIP_OPEN_FD_UNLINK,
+ &check_open_fd);
- gf_msg (this->name, GF_LOG_INFO, 0, P_MSG_KEY_STATUS_INFO,
- "open-fd-key-status: %"PRIu32" for %s", skip_unlink,
- real_path);
+ if (!op_ret && check_open_fd) {
+ LOCK(&loc->inode->lock);
- if (skip_unlink) {
- op_ret = -1;
- op_errno = EBUSY;
- goto out;
- }
- }
- /*
- * If either of the function return true, skip_unlink.
- * If first first function itself return true,
- * we don't need to call second function, skip unlink.
- */
- skip_unlink = posix_skip_non_linkto_unlink (xdata, loc,
- DHT_SKIP_NON_LINKTO_UNLINK,
- DHT_LINKTO, &stbuf,
- real_path);
- skip_unlink = skip_unlink || posix_skip_non_linkto_unlink (xdata, loc,
- TIER_SKIP_NON_LINKTO_UNLINK,
- TIER_LINKTO, &stbuf,
- real_path);
- if (skip_unlink) {
- op_ret = -1;
- op_errno = EBUSY;
- goto out;
+ if (loc->inode->fd_count) {
+ skip_unlink = 1;
}
- if (IA_ISREG (loc->inode->ia_type) &&
- xdata && dict_get (xdata, DHT_IATT_IN_XDATA_KEY)) {
- fdstat_requested = 1;
- }
+ UNLOCK(&loc->inode->lock);
- if (fdstat_requested ||
- (priv->background_unlink && IA_ISREG (loc->inode->ia_type))) {
- fd = sys_open (real_path, O_RDONLY, 0);
- if (fd == -1) {
- op_ret = -1;
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_OPEN_FAILED,
- "open of %s failed", real_path);
- goto out;
- }
- }
+ gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_KEY_STATUS_INFO,
+ "open-fd-key-status: %" PRIu32 " for %s", skip_unlink,
+ real_path);
- if (priv->update_pgfid_nlinks && (stbuf.ia_nlink > 1)) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- op_ret = posix_inode_ctx_get_all (loc->inode, this, &ctx);
- if (op_ret < 0) {
- op_errno = ENOMEM;
- goto out;
- }
- pthread_mutex_lock (&ctx->pgfid_lock);
- {
- UNLINK_MODIFY_PGFID_XATTR (real_path, pgfid_xattr_key,
- nlink_samepgfid, 0, op_ret,
- this, unlock);
- }
- unlock:
- pthread_mutex_unlock (&ctx->pgfid_lock);
-
- if (op_ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- P_MSG_XATTR_FAILED, "modification of "
- "parent gfid xattr failed (path:%s gfid:%s)",
- real_path, uuid_utoa (loc->inode->gfid));
- if (op_errno != ENOATTR)
- /* Allow unlink if pgfid xattr is not set. */
- goto out;
- }
+ if (skip_unlink) {
+ op_ret = -1;
+ op_errno = EBUSY;
+ goto out;
+ }
+ }
+ /*
+ * If either of the function return true, skip_unlink.
+ * If first first function itself return true,
+ * we don't need to call second function, skip unlink.
+ */
+ skip_unlink = posix_skip_non_linkto_unlink(
+ xdata, loc, DHT_SKIP_NON_LINKTO_UNLINK,
+ SLEN(DHT_SKIP_NON_LINKTO_UNLINK), DHT_LINKTO, &stbuf, real_path);
+ if (skip_unlink) {
+ op_ret = -1;
+ op_errno = EBUSY;
+ goto out;
+ }
+
+ if (IA_ISREG(loc->inode->ia_type) && xdata &&
+ dict_get_sizen(xdata, DHT_IATT_IN_XDATA_KEY)) {
+ fdstat_requested = 1;
+ }
+
+ if (fdstat_requested ||
+ (priv->background_unlink && IA_ISREG(loc->inode->ia_type))) {
+ fd = sys_open(real_path, O_RDONLY, 0);
+ if (fd == -1) {
+ op_ret = -1;
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_OPEN_FAILED,
+ "open of %s failed", real_path);
+ goto out;
+ }
+ }
+
+ if (priv->update_pgfid_nlinks && (stbuf.ia_nlink > 1)) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ op_ret = posix_inode_ctx_get_all(loc->inode, this, &ctx);
+ if (op_ret < 0) {
+ op_errno = ENOMEM;
+ goto out;
}
-
- if (priv->gfid2path && (stbuf.ia_nlink > 1)) {
- op_ret = posix_remove_gfid2path_xattr (this, real_path,
- loc->pargfid,
- loc->name);
- if (op_ret < 0) {
- /* Allow unlink if pgfid xattr is not set. */
- if (errno != ENOATTR)
- goto out;
- }
+ pthread_mutex_lock(&ctx->pgfid_lock);
+ {
+ UNLINK_MODIFY_PGFID_XATTR(real_path, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret, this, unlock);
}
+ unlock:
+ pthread_mutex_unlock(&ctx->pgfid_lock);
- unwind_dict = dict_new ();
- if (!unwind_dict) {
- op_errno = -ENOMEM;
- op_ret = -1;
+ if (op_ret < 0) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED,
+ "modification of "
+ "parent gfid xattr failed (path:%s gfid:%s)",
+ real_path, uuid_utoa(loc->inode->gfid));
+ if (op_errno != ENOATTR)
+ /* Allow unlink if pgfid xattr is not set. */
goto out;
}
+ }
- if (xdata && dict_get (xdata, GET_LINK_COUNT))
- get_link_count = _gf_true;
- op_ret = posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf,
- &op_errno, loc,
- get_link_count,
- unwind_dict);
- if (op_ret == -1) {
+ if (priv->gfid2path && (stbuf.ia_nlink > 1)) {
+ op_ret = posix_remove_gfid2path_xattr(this, real_path, loc->pargfid,
+ loc->name);
+ if (op_ret < 0) {
+ /* Allow unlink if pgfid xattr is not set. */
+ if (errno != ENOATTR)
goto out;
}
+ }
- if (fdstat_requested) {
- op_ret = posix_fdstat (this, fd, &postbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_FSTAT_FAILED, "post operation "
- "fstat failed on fd=%d", fd);
- goto out;
- }
- op_ret = posix_set_iatt_in_dict (unwind_dict, &postbuf);
- }
+ unwind_dict = dict_new();
+ if (!unwind_dict) {
+ op_errno = ENOMEM;
+ op_ret = -1;
+ goto out;
+ }
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
+ if (xdata && dict_get_sizen(xdata, GF_GET_FILE_BLOCK_COUNT)) {
+ ret = dict_set_uint64(unwind_dict, GF_GET_FILE_BLOCK_COUNT,
+ stbuf.ia_blocks);
+ if (ret)
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
+ "Failed to set %s in rsp dict", GF_GET_FILE_BLOCK_COUNT);
+ }
+
+ if (xdata && dict_get_sizen(xdata, GET_LINK_COUNT))
+ get_link_count = _gf_true;
+ op_ret = posix_unlink_gfid_handle_and_entry(frame, this, real_path, &stbuf,
+ &op_errno, loc, get_link_count,
+ unwind_dict);
+ if (op_ret == -1) {
+ goto out;
+ }
+
+ if (fdstat_requested) {
+ op_ret = posix_fdstat(this, loc->inode, fd, &postbuf);
if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_path);
- goto out;
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED,
+ "post operation "
+ "fstat failed on fd=%d",
+ fd);
+ goto out;
+ }
+ op_ret = posix_set_iatt_in_dict(unwind_dict, NULL, &postbuf);
+ if (op_ret == -1) {
+ op_errno = ENOMEM;
+ gf_msg(this->name, GF_LOG_ERROR, ENOMEM, P_MSG_DICT_SET_FAILED,
+ "failed to set fdstat in dict");
}
+ }
+
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- unwind_dict = posix_dict_set_nlink (xdata, unwind_dict, stbuf.ia_nlink);
- op_ret = 0;
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
+
+ unwind_dict = posix_dict_set_nlink(xdata, unwind_dict, stbuf.ia_nlink);
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
- &preparent, &postparent, unwind_dict);
+ STACK_UNWIND_STRICT(unlink, frame, op_ret, op_errno, &preparent,
+ &postparent, unwind_dict);
- if (fd != -1) {
- sys_close (fd);
- }
+ if (fd != -1) {
+ sys_close(fd);
+ }
- /* unref unwind_dict*/
- if (unwind_dict) {
- dict_unref (unwind_dict);
- }
+ /* unref unwind_dict*/
+ if (unwind_dict) {
+ dict_unref(unwind_dict);
+ }
- return 0;
+ return 0;
}
-
int
-posix_rmdir (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int flags, dict_t *xdata)
+posix_rmdir(call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
+ dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_path = NULL;
- char *par_path = NULL;
- char *gfid_str = NULL;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- struct iatt stbuf = {0,};
- struct posix_private *priv = NULL;
- char tmp_path[PATH_MAX] = {0,};
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (loc, out);
-
- SET_FS_ID (frame->root->uid, frame->root->gid);
-
- /* The Hidden directory should be for housekeeping purpose and it
- should not get deleted from inside process */
- if (__is_root_gfid (loc->pargfid) &&
- (strcmp (loc->name, GF_HIDDEN_PATH) == 0)) {
- gf_msg (this->name, GF_LOG_WARNING, EPERM,
- P_MSG_RMDIR_NOT_PERMITTED, "rmdir issued on %s, which"
- "is not permitted", GF_HIDDEN_PATH);
- op_errno = EPERM;
- op_ret = -1;
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ char *gfid_str = NULL;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ char tmp_path[PATH_MAX] = {
+ 0,
+ };
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(loc, out);
+
+ SET_FS_ID(frame->root->uid, frame->root->gid);
+
+ /* The Hidden directory should be for housekeeping purpose and it
+ should not get deleted from inside process */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, GF_HIDDEN_PATH) == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_RMDIR_NOT_PERMITTED,
+ "rmdir issued on %s, which"
+ "is not permitted",
+ GF_HIDDEN_PATH);
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
- priv = this->private;
+#ifdef __NetBSD__
+ /* Same for NetBSD's .attribute directory */
+ if (__is_root_gfid(loc->pargfid) &&
+ (strcmp(loc->name, ".attribute") == 0)) {
+ gf_msg(this->name, GF_LOG_WARNING, EPERM, P_MSG_RMDIR_NOT_PERMITTED,
+ "rmdir issued on .attribute, which"
+ "is not permitted");
+ op_errno = EPERM;
+ op_ret = -1;
+ goto out;
+ }
+#endif
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ priv = this->private;
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- if (flags) {
- gfid_str = uuid_utoa (stbuf.ia_gfid);
-
- op_ret = sys_mkdir (priv->trash_path, 0755);
- if (errno != EEXIST && op_ret == -1) {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_MKDIR_FAILED,
- "mkdir of %s failed", priv->trash_path);
- } else {
- (void) snprintf (tmp_path, sizeof(tmp_path), "%s/%s",
- priv->trash_path, gfid_str);
- gf_msg_debug (this->name, 0,
- "Moving %s to %s", real_path, tmp_path);
- op_ret = sys_rename (real_path, tmp_path);
- pthread_cond_signal (&priv->janitor_cond);
- }
- } else {
- op_ret = sys_rmdir (real_path);
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
op_errno = errno;
-
- if (op_ret == 0) {
- if (posix_symlinks_match (this, loc, stbuf.ia_gfid))
- posix_handle_unset (this, stbuf.ia_gfid, NULL);
- }
-
- if (op_errno == EEXIST)
- /* Solaris sets errno = EEXIST instead of ENOTEMPTY */
- op_errno = ENOTEMPTY;
-
- /* No need to log a common error as ENOTEMPTY */
- if (op_ret == -1 && op_errno != ENOTEMPTY) {
- gf_msg (this->name, GF_LOG_ERROR, op_errno, P_MSG_RMDIR_FAILED,
- "rmdir of %s failed", real_path);
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
+
+ if (flags) {
+ op_ret = sys_mkdir(priv->trash_path, 0755);
+ if (errno != EEXIST && op_ret == -1) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_MKDIR_FAILED,
+ "mkdir of %s failed", priv->trash_path);
+ } else {
+ gfid_str = uuid_utoa(stbuf.ia_gfid);
+ (void)snprintf(tmp_path, sizeof(tmp_path), "%s/%s",
+ priv->trash_path, gfid_str);
+ gf_msg_debug(this->name, 0, "Moving %s to %s", real_path, tmp_path);
+ op_ret = sys_rename(real_path, tmp_path);
+ }
+ } else {
+ op_ret = sys_rmdir(real_path);
+ }
+ op_errno = errno;
+
+ if (op_ret == 0) {
+ if (posix_symlinks_match(this, loc, stbuf.ia_gfid))
+ posix_handle_unset(this, stbuf.ia_gfid, NULL);
+ }
+
+ if (op_errno == EEXIST)
+ /* Solaris sets errno = EEXIST instead of ENOTEMPTY */
+ op_errno = ENOTEMPTY;
+
+ /* No need to log a common error as ENOTEMPTY */
+ if (op_ret == -1 && op_errno != ENOTEMPTY) {
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, P_MSG_RMDIR_FAILED,
+ "rmdir of %s failed", real_path);
+ }
+
+ if (op_ret == -1) {
+ if (op_errno == ENOTEMPTY) {
+ gf_msg_debug(this->name, 0, "%s on %s failed",
+ (flags) ? "rename" : "rmdir", real_path);
+ } else {
+ gf_msg(this->name, GF_LOG_ERROR, op_errno,
+ P_MSG_DIR_OPERATION_FAILED, "%s on %s failed",
+ (flags) ? "rename" : "rmdir", real_path);
}
+ goto out;
+ }
- if (op_ret == -1) {
- if (op_errno == ENOTEMPTY) {
- gf_msg_debug (this->name, 0, "%s on %s failed", (flags)
- ? "rename" : "rmdir", real_path);
- } else {
- gf_msg (this->name, GF_LOG_ERROR, op_errno,
- P_MSG_DIR_OPERATION_FAILED, "%s on %s failed",
- (flags) ? "rename" : "rmdir", real_path);
- }
- goto out;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent of %s failed", par_path);
+ goto out;
+ }
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent of %s failed",
- par_path);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
- &preparent, &postparent, NULL);
+ STACK_UNWIND_STRICT(rmdir, frame, op_ret, op_errno, &preparent, &postparent,
+ NULL);
- return 0;
+ return 0;
}
-
int
-posix_symlink (call_frame_t *frame, xlator_t *this,
- const char *linkname, loc_t *loc, mode_t umask, dict_t *xdata)
+posix_symlink(call_frame_t *frame, xlator_t *this, const char *linkname,
+ loc_t *loc, mode_t umask, dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char * real_path = 0;
- char * par_path = 0;
- struct iatt stbuf = { 0, };
- struct posix_private *priv = NULL;
- gid_t gid = 0;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- char *pgfid_xattr_key = NULL;
- int32_t nlink_samepgfid = 0;
- gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (linkname, out);
- VALIDATE_OR_GOTO (loc, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
- out);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
-
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
-
- gid = frame->root->gid;
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = 0;
+ char *par_path = 0;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ gid_t gid = 0;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ char *pgfid_xattr_key = NULL;
+ int32_t nlink_samepgfid = 0;
+ gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
+ uuid_t uuid_req = {
+ 0,
+ };
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(linkname, out);
+ VALIDATE_OR_GOTO(loc, out);
+
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+ GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xdata, op_ret, op_errno,
+ uuid_req, out);
+ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out);
+
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
+
+ gid = frame->root->gid;
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- SET_FS_ID (frame->root->uid, gid);
+ SET_FS_ID(frame->root->uid, gid);
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- if (preparent.ia_prot.sgid) {
- gid = preparent.ia_gid;
- }
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
- op_ret = sys_symlink (linkname, real_path);
+ op_ret = sys_symlink(linkname, real_path);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_SYMLINK_FAILED,
- "symlink of %s --> %s failed",
- real_path, linkname);
- goto out;
- }
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_SYMLINK_FAILED,
+ "symlink of %s --> %s failed", real_path, linkname);
+ goto out;
+ }
- entry_created = _gf_true;
+ entry_created = _gf_true;
+
+ posix_set_ctime(frame, this, real_path, -1, loc->inode, &stbuf);
#ifndef HAVE_SET_FSID
- op_ret = sys_lchown (real_path, frame->root->uid, gid);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LCHOWN_FAILED,
- "lchown failed on %s", real_path);
- goto out;
- }
+ op_ret = sys_lchown(real_path, frame->root->uid, gid);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LCHOWN_FAILED,
+ "lchown failed on %s", real_path);
+ goto out;
+ }
#endif
- op_ret = posix_acl_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
- "setting ACLs on %s failed", real_path);
- }
-
- if (priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
- }
-
- if (priv->gfid2path) {
- posix_set_gfid2path_xattr (this, real_path, loc->pargfid,
- loc->name);
- }
+ op_ret = posix_acl_xattr_set(this, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
+ "setting ACLs on %s failed", real_path);
+ }
+
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ nlink_samepgfid = 1;
+ SET_PGFID_XATTR(real_path, pgfid_xattr_key, nlink_samepgfid,
+ XATTR_CREATE, op_ret, this, ignore);
+ }
+
+ if (priv->gfid2path) {
+ posix_set_gfid2path_xattr(this, real_path, loc->pargfid, loc->name);
+ }
ignore:
- op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
- "setting xattrs on %s failed ", real_path);
- }
-
- op_ret = posix_gfid_set (this, real_path, loc, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED,
- "setting gfid on %s failed", real_path);
- } else {
- gfid_set = _gf_true;
- }
-
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat failed on %s", real_path);
- goto out;
- }
+ op_ret = posix_entry_create_xattr_set(this, loc, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
+ "setting xattrs on %s failed ", real_path);
+ }
+
+ op_ret = posix_gfid_set(this, real_path, loc, xdata, frame->root->pid,
+ &op_errno);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED,
+ "setting gfid on %s failed", real_path);
+ goto out;
+ } else {
+ gfid_set = _gf_true;
+ }
+
+ op_ret = posix_pstat(this, loc->inode, NULL, real_path, &stbuf, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat failed on %s", real_path);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
- op_ret = 0;
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- if (op_ret < 0) {
- if (entry_created)
- sys_unlink (real_path);
+ if (op_ret < 0) {
+ if (entry_created)
+ sys_unlink(real_path);
- if (gfid_set)
- posix_gfid_unset (this, xdata);
- }
+ if (gfid_set)
+ posix_gfid_unset(this, xdata);
+ }
- STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno,
- (loc)?loc->inode:NULL, &stbuf, &preparent,
- &postparent, NULL);
+ STACK_UNWIND_STRICT(symlink, frame, op_ret, op_errno,
+ (loc) ? loc->inode : NULL, &stbuf, &preparent,
+ &postparent, NULL);
- return 0;
+ return 0;
}
-
int
-posix_rename (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+posix_rename(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_oldpath = NULL;
- char *real_newpath = NULL;
- char *par_oldpath = NULL;
- char *par_newpath = NULL;
- struct iatt stbuf = {0, };
- struct posix_private *priv = NULL;
- char was_present = 1;
- struct iatt preoldparent = {0, };
- struct iatt postoldparent = {0, };
- struct iatt prenewparent = {0, };
- struct iatt postnewparent = {0, };
- char olddirid[64];
- char newdirid[64];
- uuid_t victim = {0};
- int was_dir = 0;
- int nlink = 0;
- char *pgfid_xattr_key = NULL;
- int32_t nlink_samepgfid = 0;
- char *gfid_path = NULL;
- dict_t *unwind_dict = NULL;
- gf_boolean_t locked = _gf_false;
- gf_boolean_t get_link_count = _gf_false;
- posix_inode_ctx_t *ctx_old = NULL;
- posix_inode_ctx_t *ctx_new = NULL;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (oldloc, out);
- VALIDATE_OR_GOTO (newloc, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
-
- SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_ENTRY_HANDLE (real_oldpath, par_oldpath, this, oldloc, NULL);
- if (!real_oldpath || !par_oldpath) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_oldpath = NULL;
+ char *real_newpath = NULL;
+ char *par_oldpath = NULL;
+ char *par_newpath = NULL;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ char was_present = 1;
+ struct iatt preoldparent = {
+ 0,
+ };
+ struct iatt postoldparent = {
+ 0,
+ };
+ struct iatt prenewparent = {
+ 0,
+ };
+ struct iatt postnewparent = {
+ 0,
+ };
+ char olddirid[64];
+ char newdirid[64];
+ uuid_t victim = {0};
+ int was_dir = 0;
+ int nlink = 0;
+ char *pgfid_xattr_key = NULL;
+ int32_t nlink_samepgfid = 0;
+ char *gfid_path = NULL;
+ dict_t *unwind_dict = NULL;
+ gf_boolean_t locked = _gf_false;
+ gf_boolean_t get_link_count = _gf_false;
+ posix_inode_ctx_t *ctx_old = NULL;
+ posix_inode_ctx_t *ctx_new = NULL;
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(oldloc, out);
+ VALIDATE_OR_GOTO(newloc, out);
+
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+
+ SET_FS_ID(frame->root->uid, frame->root->gid);
+ MAKE_ENTRY_HANDLE(real_oldpath, par_oldpath, this, oldloc, NULL);
+ if (!real_oldpath || !par_oldpath) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf);
- if (!real_newpath || !par_newpath) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ MAKE_ENTRY_HANDLE(real_newpath, par_newpath, this, newloc, &stbuf);
+ if (!real_newpath || !par_newpath) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- unwind_dict = dict_new ();
- if (!unwind_dict) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
+ unwind_dict = dict_new();
+ if (!unwind_dict) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
- op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &preoldparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_oldpath);
- goto out;
- }
+ op_ret = posix_pstat(this, oldloc->parent, oldloc->pargfid, par_oldpath,
+ &preoldparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_oldpath);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, newloc->parent, newloc->pargfid, par_newpath,
+ &prenewparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent of %s failed", par_newpath);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, newloc->inode, NULL, real_newpath, &stbuf,
+ _gf_false);
+ if ((op_ret == -1) && (errno == ENOENT)) {
+ was_present = 0;
+ } else {
+ gf_uuid_copy(victim, stbuf.ia_gfid);
+ if (IA_ISDIR(stbuf.ia_type))
+ was_dir = 1;
+ nlink = stbuf.ia_nlink;
+ }
+
+ if (was_present && IA_ISDIR(stbuf.ia_type) && !newloc->inode) {
+ gf_msg(this->name, GF_LOG_WARNING, EEXIST, P_MSG_DIR_FOUND,
+ "found directory at %s while expecting ENOENT", real_newpath);
+ op_ret = -1;
+ op_errno = EEXIST;
+ goto out;
+ }
+
+ if (was_present && IA_ISDIR(stbuf.ia_type) &&
+ gf_uuid_compare(newloc->inode->gfid, stbuf.ia_gfid)) {
+ gf_msg(this->name, GF_LOG_WARNING, EEXIST, P_MSG_DIR_FOUND,
+ "found directory %s at %s while renaming %s",
+ uuid_utoa_r(newloc->inode->gfid, olddirid), real_newpath,
+ uuid_utoa_r(stbuf.ia_gfid, newdirid));
+ op_ret = -1;
+ op_errno = EEXIST;
+ goto out;
+ }
- op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &prenewparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent of %s failed",
- par_newpath);
- goto out;
- }
+ op_ret = posix_inode_ctx_get_all(oldloc->inode, this, &ctx_old);
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
- op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
- if ((op_ret == -1) && (errno == ENOENT)){
- was_present = 0;
- } else {
- gf_uuid_copy (victim, stbuf.ia_gfid);
- if (IA_ISDIR (stbuf.ia_type))
- was_dir = 1;
- nlink = stbuf.ia_nlink;
+ if (newloc->inode) {
+ op_ret = posix_inode_ctx_get_all(newloc->inode, this, &ctx_new);
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
+
+ if (IA_ISDIR(oldloc->inode->ia_type))
+ posix_handle_unset(this, oldloc->inode->gfid, NULL);
+
+ pthread_mutex_lock(&ctx_old->pgfid_lock);
+ {
+ if (!IA_ISDIR(oldloc->inode->ia_type) && priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ oldloc->pargfid);
+ UNLINK_MODIFY_PGFID_XATTR(real_oldpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret, this, unlock);
+ }
+
+ if ((xdata) && (dict_get(xdata, GET_LINK_COUNT)) && (real_newpath) &&
+ (was_present) && ctx_new) {
+ pthread_mutex_lock(&ctx_new->pgfid_lock);
+ locked = _gf_true;
+ get_link_count = _gf_true;
+ op_ret = posix_pstat(this, newloc->inode, newloc->gfid,
+ real_newpath, &stbuf, _gf_false);
+ if ((op_ret == -1) && (errno != ENOENT)) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_newpath);
+ goto unlock;
+ }
}
- if (was_present && IA_ISDIR(stbuf.ia_type) && !newloc->inode) {
- gf_msg (this->name, GF_LOG_WARNING, EEXIST, P_MSG_DIR_FOUND,
- "found directory at %s while expecting ENOENT",
- real_newpath);
- op_ret = -1;
- op_errno = EEXIST;
- goto out;
+ op_ret = sys_rename(real_oldpath, real_newpath);
+ if (op_ret == -1) {
+ op_errno = errno;
+ if (op_errno == ENOTEMPTY) {
+ gf_msg_debug(this->name, 0,
+ "rename of %s to"
+ " %s failed: %s",
+ real_oldpath, real_newpath, strerror(op_errno));
+ } else {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_RENAME_FAILED,
+ "rename of %s to %s failed", real_oldpath, real_newpath);
+ }
+
+ if (priv->update_pgfid_nlinks &&
+ !IA_ISDIR(oldloc->inode->ia_type)) {
+ LINK_MODIFY_PGFID_XATTR(real_oldpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret, this,
+ unlock);
+ }
+
+ goto unlock;
}
- if (was_present && IA_ISDIR(stbuf.ia_type) &&
- gf_uuid_compare (newloc->inode->gfid, stbuf.ia_gfid)) {
- gf_msg (this->name, GF_LOG_WARNING, EEXIST, P_MSG_DIR_FOUND,
- "found directory %s at %s while renaming %s",
- uuid_utoa_r (newloc->inode->gfid, olddirid),
- real_newpath,
- uuid_utoa_r (stbuf.ia_gfid, newdirid));
- op_ret = -1;
- op_errno = EEXIST;
- goto out;
+ if (locked) {
+ pthread_mutex_unlock(&ctx_new->pgfid_lock);
+ locked = _gf_false;
}
- op_ret = posix_inode_ctx_get_all (oldloc->inode, this, &ctx_old);
- if (op_ret < 0) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
+ if ((get_link_count) &&
+ (dict_set_uint32(unwind_dict, GET_LINK_COUNT, stbuf.ia_nlink)))
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
+ "failed to set " GET_LINK_COUNT " for %s", real_newpath);
- if (newloc->inode) {
- op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx_new);
- if (op_ret < 0) {
- op_ret = -1;
- op_errno = ENOMEM;
- goto out;
- }
+ if (!IA_ISDIR(oldloc->inode->ia_type) && priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ newloc->pargfid);
+ LINK_MODIFY_PGFID_XATTR(real_newpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret, this, unlock);
}
- if (IA_ISDIR (oldloc->inode->ia_type))
- posix_handle_unset (this, oldloc->inode->gfid, NULL);
-
- pthread_mutex_lock (&ctx_old->pgfid_lock);
- {
- if (!IA_ISDIR (oldloc->inode->ia_type)
- && priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
- PGFID_XATTR_KEY_PREFIX,
- oldloc->pargfid);
- UNLINK_MODIFY_PGFID_XATTR (real_oldpath,
- pgfid_xattr_key,
- nlink_samepgfid, 0,
- op_ret,
- this, unlock);
- }
-
- if ((xdata) && (dict_get (xdata, GET_LINK_COUNT))
- && (real_newpath) && (was_present)) {
- pthread_mutex_lock (&ctx_new->pgfid_lock);
- locked = _gf_true;
- get_link_count = _gf_true;
- op_ret = posix_pstat (this, newloc->gfid, real_newpath,
- &stbuf);
- if ((op_ret == -1) && (errno != ENOENT)) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_LSTAT_FAILED,
- "lstat on %s failed", real_newpath);
- goto unlock;
- }
- }
-
- op_ret = sys_rename (real_oldpath, real_newpath);
- if (op_ret == -1) {
- op_errno = errno;
- if (op_errno == ENOTEMPTY) {
- gf_msg_debug (this->name, 0, "rename of %s to"
- " %s failed: %s", real_oldpath,
- real_newpath,
- strerror (op_errno));
- } else {
- gf_msg (this->name, GF_LOG_ERROR, errno,
- P_MSG_RENAME_FAILED,
- "rename of %s to %s failed",
- real_oldpath, real_newpath);
- }
-
- if (priv->update_pgfid_nlinks
- && !IA_ISDIR (oldloc->inode->ia_type)) {
- LINK_MODIFY_PGFID_XATTR (real_oldpath,
- pgfid_xattr_key,
- nlink_samepgfid, 0,
- op_ret,
- this, unlock);
- }
-
- goto unlock;
- }
-
- if (locked) {
- pthread_mutex_unlock (&ctx_new->pgfid_lock);
- locked = _gf_false;
- }
-
- if ((get_link_count) &&
- (dict_set_uint32 (unwind_dict, GET_LINK_COUNT,
- stbuf.ia_nlink)))
- gf_msg (this->name, GF_LOG_WARNING, 0,
- P_MSG_SET_XDATA_FAIL, "failed to set "
- GET_LINK_COUNT" for %s", real_newpath);
-
- if (!IA_ISDIR (oldloc->inode->ia_type)
- && priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
- PGFID_XATTR_KEY_PREFIX,
- newloc->pargfid);
- LINK_MODIFY_PGFID_XATTR (real_newpath,
- pgfid_xattr_key,
- nlink_samepgfid, 0,
- op_ret,
- this, unlock);
- }
-
- if (!IA_ISDIR (oldloc->inode->ia_type) && priv->gfid2path) {
- MAKE_HANDLE_ABSPATH (gfid_path, this,
- oldloc->inode->gfid);
+ if (!IA_ISDIR(oldloc->inode->ia_type) && priv->gfid2path) {
+ MAKE_HANDLE_ABSPATH(gfid_path, this, oldloc->inode->gfid);
- posix_remove_gfid2path_xattr (this, gfid_path,
- oldloc->pargfid,
- oldloc->name);
- posix_set_gfid2path_xattr (this, gfid_path,
- newloc->pargfid,
- newloc->name);
- }
+ posix_remove_gfid2path_xattr(this, gfid_path, oldloc->pargfid,
+ oldloc->name);
+ posix_set_gfid2path_xattr(this, gfid_path, newloc->pargfid,
+ newloc->name);
}
+ }
unlock:
- if (locked) {
- pthread_mutex_unlock (&ctx_new->pgfid_lock);
- locked = _gf_false;
- }
- pthread_mutex_unlock (&ctx_old->pgfid_lock);
-
- if (op_ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED,
- "modification of "
- "parent gfid xattr failed (gfid:%s)",
- uuid_utoa (oldloc->inode->gfid));
- goto out;
- }
-
- if (was_dir)
- posix_handle_unset (this, victim, NULL);
-
- if (was_present && !was_dir && nlink == 1)
- posix_handle_unset (this, victim, NULL);
-
- if (IA_ISDIR (oldloc->inode->ia_type)) {
- posix_handle_soft (this, real_newpath, newloc,
- oldloc->inode->gfid, NULL);
- }
+ if (locked) {
+ pthread_mutex_unlock(&ctx_new->pgfid_lock);
+ locked = _gf_false;
+ }
+ pthread_mutex_unlock(&ctx_old->pgfid_lock);
+
+ if (op_ret < 0) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED,
+ "modification of "
+ "parent gfid xattr failed (gfid:%s)",
+ uuid_utoa(oldloc->inode->gfid));
+ goto out;
+ }
+
+ if (was_dir)
+ posix_handle_unset(this, victim, NULL);
+
+ if (was_present && !was_dir && nlink == 1)
+ posix_handle_unset(this, victim, NULL);
+
+ if (IA_ISDIR(oldloc->inode->ia_type)) {
+ posix_handle_soft(this, real_newpath, newloc, oldloc->inode->gfid,
+ NULL);
+ }
+
+ op_ret = posix_pstat(this, newloc->inode, NULL, real_newpath, &stbuf,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_newpath);
+ goto out;
+ }
+
+ /* Since the same inode is later used and dst inode is not present,
+ * update ctime on source inode. It can't use old path because it
+ * doesn't exist and xattr has to be stored on disk */
+ posix_set_ctime(frame, this, real_newpath, -1, oldloc->inode, &stbuf);
+
+ op_ret = posix_pstat(this, oldloc->parent, oldloc->pargfid, par_oldpath,
+ &postoldparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_oldpath);
+ goto out;
+ }
- op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat on %s failed", real_newpath);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_oldpath, -1, oldloc->parent,
+ &postoldparent);
- op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &postoldparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_oldpath);
- goto out;
- }
+ op_ret = posix_pstat(this, newloc->parent, newloc->pargfid, par_newpath,
+ &postnewparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_newpath);
+ goto out;
+ }
- op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postnewparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_newpath);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_newpath, -1, newloc->parent,
+ &postnewparent);
- if (was_present)
- unwind_dict = posix_dict_set_nlink (xdata, unwind_dict, nlink);
- op_ret = 0;
+ if (was_present)
+ unwind_dict = posix_dict_set_nlink(xdata, unwind_dict, nlink);
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- STACK_UNWIND_STRICT (rename, frame, op_ret, op_errno, &stbuf,
- &preoldparent, &postoldparent,
- &prenewparent, &postnewparent, unwind_dict);
+ STACK_UNWIND_STRICT(rename, frame, op_ret, op_errno, &stbuf, &preoldparent,
+ &postoldparent, &prenewparent, &postnewparent,
+ unwind_dict);
- if (unwind_dict)
- dict_unref (unwind_dict);
+ if (unwind_dict)
+ dict_unref(unwind_dict);
- return 0;
+ return 0;
}
-
int
-posix_link (call_frame_t *frame, xlator_t *this,
- loc_t *oldloc, loc_t *newloc, dict_t *xdata)
+posix_link(call_frame_t *frame, xlator_t *this, loc_t *oldloc, loc_t *newloc,
+ dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_oldpath = 0;
- char *real_newpath = 0;
- char *par_newpath = 0;
- struct iatt stbuf = {0, };
- struct posix_private *priv = NULL;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- int32_t nlink_samepgfid = 0;
- char *pgfid_xattr_key = NULL;
- gf_boolean_t entry_created = _gf_false;
- posix_inode_ctx_t *ctx = NULL;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (oldloc, out);
- VALIDATE_OR_GOTO (newloc, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
-
- SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_INODE_HANDLE (real_oldpath, this, oldloc, &stbuf);
- if (!real_oldpath) {
- op_errno = errno;
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_oldpath = 0;
+ char *real_newpath = 0;
+ char *par_newpath = 0;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_private *priv = NULL;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+ int32_t nlink_samepgfid = 0;
+ char *pgfid_xattr_key = NULL;
+ gf_boolean_t entry_created = _gf_false;
+ posix_inode_ctx_t *ctx = NULL;
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(oldloc, out);
+ VALIDATE_OR_GOTO(newloc, out);
+
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out);
+
+ SET_FS_ID(frame->root->uid, frame->root->gid);
+ MAKE_INODE_HANDLE(real_oldpath, this, oldloc, &stbuf);
+ if (!real_oldpath) {
+ op_errno = errno;
+ goto out;
+ }
- if (priv->max_hardlinks && stbuf.ia_nlink >= priv->max_hardlinks) {
- op_ret = -1;
- op_errno = EMLINK;
- gf_log (this->name, GF_LOG_ERROR,
- "hardlink failed: %s exceeds max link count (%u/%u).",
- real_oldpath, stbuf.ia_nlink, priv->max_hardlinks);
- goto out;
- }
+ if (priv->max_hardlinks && stbuf.ia_nlink >= priv->max_hardlinks) {
+ op_ret = -1;
+ op_errno = EMLINK;
+ gf_log(this->name, GF_LOG_ERROR,
+ "hardlink failed: %s exceeds max link count (%u/%u).",
+ real_oldpath, stbuf.ia_nlink, priv->max_hardlinks);
+ goto out;
+ }
+
+ MAKE_ENTRY_HANDLE(real_newpath, par_newpath, this, newloc, &stbuf);
+ if (!real_newpath || !par_newpath) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf);
- if (!real_newpath || !par_newpath) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
+ op_ret = posix_pstat(this, newloc->parent, newloc->pargfid, par_newpath,
+ &preparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat failed: %s", par_newpath);
+ goto out;
+ }
- op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat failed: %s", par_newpath);
- goto out;
- }
+ op_ret = sys_link(real_oldpath, real_newpath);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LINK_FAILED,
+ "link %s to %s failed", real_oldpath, real_newpath);
+ goto out;
+ }
- op_ret = sys_link (real_oldpath, real_newpath);
+ entry_created = _gf_true;
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LINK_FAILED,
- "link %s to %s failed",
- real_oldpath, real_newpath);
- goto out;
- }
+ op_ret = posix_pstat(this, newloc->inode, NULL, real_newpath, &stbuf,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_newpath);
+ goto out;
+ }
- entry_created = _gf_true;
+ posix_set_ctime(frame, this, real_newpath, -1, newloc->inode, &stbuf);
- op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat on %s failed", real_newpath);
- goto out;
- }
+ op_ret = posix_pstat(this, newloc->parent, newloc->pargfid, par_newpath,
+ &postparent, _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "lstat failed: %s", par_newpath);
+ goto out;
+ }
- op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "lstat failed: %s", par_newpath);
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_newpath, -1, newloc->parent,
+ &postparent);
- if (priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- newloc->pargfid);
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ newloc->pargfid);
- op_ret = posix_inode_ctx_get_all (newloc->inode, this, &ctx);
- if (op_ret < 0) {
- op_errno = ENOMEM;
- goto out;
- }
+ op_ret = posix_inode_ctx_get_all(newloc->inode, this, &ctx);
+ if (op_ret < 0) {
+ op_errno = ENOMEM;
+ goto out;
+ }
- pthread_mutex_lock (&ctx->pgfid_lock);
- {
- LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key,
- nlink_samepgfid, 0, op_ret,
- this, unlock);
- }
- unlock:
- pthread_mutex_unlock (&ctx->pgfid_lock);
-
- if (op_ret < 0) {
- gf_msg (this->name, GF_LOG_WARNING, 0,
- P_MSG_XATTR_FAILED, "modification of "
- "parent gfid xattr failed (path:%s gfid:%s)",
- real_newpath, uuid_utoa (newloc->inode->gfid));
- goto out;
- }
+ pthread_mutex_lock(&ctx->pgfid_lock);
+ {
+ LINK_MODIFY_PGFID_XATTR(real_newpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret, this, unlock);
}
+ unlock:
+ pthread_mutex_unlock(&ctx->pgfid_lock);
- if (priv->gfid2path) {
- if (stbuf.ia_nlink <= MAX_GFID2PATH_LINK_SUP) {
- op_ret = posix_set_gfid2path_xattr (this, real_newpath,
- newloc->pargfid,
- newloc->name);
- if (op_ret) {
- op_errno = errno;
- goto out;
- }
- } else {
- gf_msg (this->name, GF_LOG_INFO, 0,
- P_MSG_XATTR_NOTSUP, "Link count exceeded. "
- "gfid2path xattr not set (path:%s gfid:%s)",
- real_newpath, uuid_utoa (newloc->inode->gfid));
- }
+ if (op_ret < 0) {
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_XATTR_FAILED,
+ "modification of "
+ "parent gfid xattr failed (path:%s gfid:%s)",
+ real_newpath, uuid_utoa(newloc->inode->gfid));
+ goto out;
+ }
+ }
+
+ if (priv->gfid2path) {
+ if (stbuf.ia_nlink <= MAX_GFID2PATH_LINK_SUP) {
+ op_ret = posix_set_gfid2path_xattr(this, real_newpath,
+ newloc->pargfid, newloc->name);
+ if (op_ret) {
+ op_errno = errno;
+ goto out;
+ }
+ } else {
+ gf_msg(this->name, GF_LOG_INFO, 0, P_MSG_XATTR_NOTSUP,
+ "Link count exceeded. "
+ "gfid2path xattr not set (path:%s gfid:%s)",
+ real_newpath, uuid_utoa(newloc->inode->gfid));
}
+ }
- op_ret = 0;
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- STACK_UNWIND_STRICT (link, frame, op_ret, op_errno,
- (oldloc)?oldloc->inode:NULL, &stbuf, &preparent,
- &postparent, NULL);
+ STACK_UNWIND_STRICT(link, frame, op_ret, op_errno,
+ (oldloc) ? oldloc->inode : NULL, &stbuf, &preparent,
+ &postparent, NULL);
- if (op_ret < 0) {
- if (entry_created)
- sys_unlink (real_newpath);
- }
+ if (op_ret < 0) {
+ if (entry_created)
+ sys_unlink(real_newpath);
+ }
- return 0;
+ return 0;
}
int
-posix_create (call_frame_t *frame, xlator_t *this,
- loc_t *loc, int32_t flags, mode_t mode,
- mode_t umask, fd_t *fd, dict_t *xdata)
+posix_create(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
+ mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- int32_t _fd = -1;
- int _flags = 0;
- char * real_path = NULL;
- char * par_path = NULL;
- struct iatt stbuf = {0, };
- struct posix_fd * pfd = NULL;
- struct posix_private * priv = NULL;
- char was_present = 1;
-
- gid_t gid = 0;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
-
- int nlink_samepgfid = 0;
- char * pgfid_xattr_key = NULL;
- gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
- mode_t mode_bit = 0;
-
- DECLARE_OLD_FS_ID_VAR;
-
- VALIDATE_OR_GOTO (frame, out);
- VALIDATE_OR_GOTO (this, out);
- VALIDATE_OR_GOTO (this->private, out);
- VALIDATE_OR_GOTO (loc, out);
- VALIDATE_OR_GOTO (fd, out);
-
- priv = this->private;
- VALIDATE_OR_GOTO (priv, out);
- GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
- out);
- DISK_SPACE_CHECK_AND_GOTO (frame, priv, xdata, op_ret, op_errno, out);
-
- MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
-
- gid = frame->root->gid;
-
- SET_FS_ID (frame->root->uid, gid);
- if (!real_path || !par_path) {
- op_ret = -1;
- op_errno = ESTALE;
- goto out;
- }
-
- op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "pre-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ int32_t _fd = -1;
+ int _flags = 0;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct posix_fd *pfd = NULL;
+ struct posix_private *priv = NULL;
+ char was_present = 1;
+
+ gid_t gid = 0;
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+
+ int nlink_samepgfid = 0;
+ char *pgfid_xattr_key = NULL;
+ gf_boolean_t entry_created = _gf_false, gfid_set = _gf_false;
+ mode_t mode_bit = 0;
+ uuid_t uuid_req = {
+ 0,
+ };
+
+ dict_t *xdata_rsp = dict_ref(xdata);
+
+ DECLARE_OLD_FS_ID_VAR;
+
+ VALIDATE_OR_GOTO(frame, out);
+ VALIDATE_OR_GOTO(this, out);
+ VALIDATE_OR_GOTO(this->private, out);
+ VALIDATE_OR_GOTO(loc, out);
+ VALIDATE_OR_GOTO(fd, out);
+
+ priv = this->private;
+ VALIDATE_OR_GOTO(priv, out);
+ GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xdata, op_ret, op_errno,
+ uuid_req, out);
+ DISK_SPACE_CHECK_AND_GOTO(frame, priv, xdata, op_ret, op_errno, out);
+
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
+
+ gid = frame->root->gid;
+
+ SET_FS_ID(frame->root->uid, gid);
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
- if (preparent.ia_prot.sgid) {
- gid = preparent.ia_gid;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
+
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
+
+ if (!flags) {
+ _flags = O_CREAT | O_RDWR | O_EXCL;
+ } else {
+ _flags = flags | O_CREAT;
+ }
+
+ op_ret = posix_pstat(this, loc->inode, NULL, real_path, &stbuf, _gf_false);
+ if ((op_ret == -1) && (errno == ENOENT)) {
+ was_present = 0;
+ }
+
+ if (!was_present) {
+ if (posix_is_layout_stale(xdata, par_path, this)) {
+ op_ret = -1;
+ op_errno = EIO;
+ if (!xdata_rsp) {
+ xdata_rsp = dict_new();
+ if (!xdata_rsp) {
+ op_errno = ENOMEM;
+ goto out;
+ }
+ }
- if (!flags) {
- _flags = O_CREAT | O_RDWR | O_EXCL;
- }
- else {
- _flags = flags | O_CREAT;
- }
+ if (dict_set_int32_sizen(xdata_rsp, GF_PREOP_CHECK_FAILED, 1) ==
+ -1) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_DICT_SET_FAILED,
+ "setting key %s in dict failed", GF_PREOP_CHECK_FAILED);
+ }
- op_ret = posix_pstat (this, NULL, real_path, &stbuf);
- if ((op_ret == -1) && (errno == ENOENT)) {
- was_present = 0;
+ goto out;
}
+ }
- if (priv->o_direct)
- _flags |= O_DIRECT;
+ if (priv->o_direct)
+ _flags |= O_DIRECT;
- mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
- mode = posix_override_umask (mode, mode_bit);
- _fd = sys_open (real_path, _flags, mode);
-
- if (_fd == -1) {
- op_errno = errno;
- op_ret = -1;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_OPEN_FAILED,
- "open on %s failed", real_path);
- goto out;
- }
+ mode_bit = (priv->create_mask & mode) | priv->force_create_mode;
+ mode = posix_override_umask(mode, mode_bit);
+ _fd = sys_open(real_path, _flags, mode);
- if ((_flags & O_CREAT) && (_flags & O_EXCL)) {
- entry_created = _gf_true;
- }
+ if (_fd == -1) {
+ op_errno = errno;
+ op_ret = -1;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_OPEN_FAILED,
+ "open on %s failed", real_path);
+ goto out;
+ }
+ if ((_flags & O_CREAT) && (_flags & O_EXCL)) {
+ entry_created = _gf_true;
+ }
- if (was_present)
- goto fill_stat;
+ if (was_present)
+ goto fill_stat;
#ifndef HAVE_SET_FSID
- op_ret = sys_chown (real_path, frame->root->uid, gid);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_CHOWN_FAILED,
- "chown on %s failed", real_path);
- }
+ op_ret = sys_chown(real_path, frame->root->uid, gid);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_CHOWN_FAILED,
+ "chown on %s failed", real_path);
+ }
#endif
- op_ret = posix_acl_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
- "setting ACLs on %s failed", real_path);
- }
-
- if (priv->update_pgfid_nlinks) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
- }
-
- if (priv->gfid2path) {
- posix_set_gfid2path_xattr (this, real_path, loc->pargfid,
- loc->name);
- }
+ op_ret = posix_acl_xattr_set(this, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_ACL_FAILED,
+ "setting ACLs on %s failed", real_path);
+ }
+
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ nlink_samepgfid = 1;
+ SET_PGFID_XATTR(real_path, pgfid_xattr_key, nlink_samepgfid,
+ XATTR_CREATE, op_ret, this, ignore);
+ }
+
+ if (priv->gfid2path) {
+ posix_set_gfid2path_xattr(this, real_path, loc->pargfid, loc->name);
+ }
ignore:
- op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
- "setting xattrs on %s failed ", real_path);
- }
+ op_ret = posix_entry_create_xattr_set(this, loc, real_path, xdata);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
+ "setting xattrs on %s failed ", real_path);
+ }
fill_stat:
- op_ret = posix_gfid_set (this, real_path, loc, xdata);
- if (op_ret) {
- gf_msg (this->name, GF_LOG_ERROR, 0, P_MSG_GFID_FAILED,
- "setting gfid on %s failed", real_path);
- } else {
- gfid_set = _gf_true;
- }
+ op_ret = posix_gfid_set(this, real_path, loc, xdata, frame->root->pid,
+ &op_errno);
+ if (op_ret) {
+ gf_msg(this->name, GF_LOG_ERROR, op_errno, P_MSG_GFID_FAILED,
+ "setting gfid on %s failed", real_path);
+ goto out;
+ } else {
+ gfid_set = _gf_true;
+ }
+
+ op_ret = posix_fdstat(this, loc->inode, _fd, &stbuf);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED,
+ "fstat on %d failed", _fd);
+ goto out;
+ }
- op_ret = posix_fdstat (this, _fd, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED,
- "fstat on %d failed", _fd);
- goto out;
- }
+ posix_set_ctime(frame, this, real_path, -1, loc->inode, &stbuf);
- op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
- if (op_ret == -1) {
- op_errno = errno;
- gf_msg (this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
- "post-operation lstat on parent %s failed",
- par_path);
- goto out;
- }
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret == -1) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
- op_ret = -1;
- pfd = GF_CALLOC (1, sizeof (*pfd), gf_posix_mt_posix_fd);
- if (!pfd) {
- op_errno = errno;
- goto out;
- }
+ posix_set_parent_ctime(frame, this, par_path, -1, loc->parent, &postparent);
- pfd->flags = flags;
- pfd->fd = _fd;
+ op_ret = -1;
+ pfd = GF_CALLOC(1, sizeof(*pfd), gf_posix_mt_posix_fd);
+ if (!pfd) {
+ op_errno = errno;
+ goto out;
+ }
- op_ret = fd_ctx_set (fd, this, (uint64_t)(long)pfd);
- if (op_ret)
- gf_msg (this->name, GF_LOG_WARNING, 0,
- P_MSG_FD_PATH_SETTING_FAILED,
- "failed to set the fd context path=%s fd=%p",
- real_path, fd);
+ pfd->flags = flags;
+ pfd->fd = _fd;
- LOCK (&priv->lock);
- {
- priv->nr_files++;
- }
- UNLOCK (&priv->lock);
+ op_ret = fd_ctx_set(fd, this, (uint64_t)(long)pfd);
+ if (op_ret)
+ gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_FD_PATH_SETTING_FAILED,
+ "failed to set the fd context path=%s fd=%p", real_path, fd);
- op_ret = 0;
+ op_ret = 0;
out:
- SET_TO_OLD_FS_ID ();
+ SET_TO_OLD_FS_ID();
- if (op_ret < 0) {
- if (_fd != -1)
- sys_close (_fd);
+ if (op_ret < 0) {
+ if (_fd != -1)
+ sys_close(_fd);
- if (entry_created)
- sys_unlink (real_path);
+ if (entry_created)
+ sys_unlink(real_path);
- if (gfid_set)
- posix_gfid_unset (this, xdata);
- }
+ if (gfid_set)
+ posix_gfid_unset(this, xdata);
+ }
+
+ STACK_UNWIND_STRICT(create, frame, op_ret, op_errno, fd,
+ (loc) ? loc->inode : NULL, &stbuf, &preparent,
+ &postparent, xdata_rsp);
+
+ if (xdata_rsp)
+ dict_unref(xdata_rsp);
- STACK_UNWIND_STRICT (create, frame, op_ret, op_errno,
- fd, (loc)?loc->inode:NULL, &stbuf, &preparent,
- &postparent, xdata);
+ return 0;
+}
+
+/* TODO: Ensure atomocity of put, and rollback in case of failure
+ * One of the ways, is to perform put in the hidden directory
+ * and rename it to the specified location, if the put was successful
+ */
+int32_t
+posix_put(call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
+ mode_t umask, uint32_t flags, struct iovec *vector, int32_t count,
+ off_t offset, struct iobref *iobref, dict_t *xattr, dict_t *xdata)
+{
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ fd_t *fd = NULL;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ struct iatt stbuf = {
+ 0,
+ };
+ struct iatt preparent = {
+ 0,
+ };
+ struct iatt postparent = {
+ 0,
+ };
+
+ MAKE_ENTRY_HANDLE(real_path, par_path, this, loc, &stbuf);
+
+ if (!real_path || !par_path) {
+ op_ret = -1;
+ op_errno = ESTALE;
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &preparent,
+ _gf_false);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "pre-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
+ fd = fd_create(loc->inode, getpid());
+ if (!fd) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+ fd->flags = flags;
+
+ /* No xlators are expected below posix, but we cannot still call
+ * sys_create() directly here, as posix_create does many other things like
+ * chmod, setxattr etc. along with sys_create(). But we cannot also directly
+ * call posix_create() as it calls STACK_UNWIND. Hence using syncop()
+ */
+ op_ret = syncop_create(this, loc, flags, mode, fd, &stbuf, xdata, NULL);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_CREATE_FAILED,
+ "create of %s failed", loc->path);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, loc->parent, loc->pargfid, par_path, &postparent,
+ _gf_false);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on parent %s failed", par_path);
+ goto out;
+ }
+
+ op_ret = syncop_writev(this, fd, vector, count, offset, iobref, flags, NULL,
+ NULL, xdata, NULL);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_WRITE_FAILED,
+ "write on file %s failed", loc->path);
+ goto out;
+ }
+
+ op_ret = syncop_fsetxattr(this, fd, xattr, flags, xdata, NULL);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_XATTR_FAILED,
+ "setxattr on file %s failed", loc->path);
+ goto out;
+ }
+
+ op_ret = syncop_flush(this, fd, xdata, NULL);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_CLOSE_FAILED,
+ "setxattr on file %s failed", loc->path);
+ goto out;
+ }
+
+ op_ret = posix_pstat(this, loc->inode, loc->gfid, real_path, &stbuf,
+ _gf_false);
+ if (op_ret < 0) {
+ op_errno = errno;
+ gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_LSTAT_FAILED,
+ "post-operation lstat on %s failed", real_path);
+ goto out;
+ }
+out:
+ STACK_UNWIND_STRICT(put, frame, op_ret, op_errno, loc->inode, &stbuf,
+ &preparent, &postparent, NULL);
- return 0;
+ return 0;
}