diff options
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r-- | xlators/storage/posix/src/posix.c | 730 |
1 files changed, 292 insertions, 438 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index cf5d855fede..5257633cec1 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -101,13 +101,12 @@ posix_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req) { struct iatt buf = {0, }; - char * real_path = NULL; int32_t op_ret = -1; int32_t entry_ret = 0; int32_t op_errno = 0; dict_t * xattr = NULL; - char * pathdup = NULL; - char * parentpath = NULL; + char * real_path = NULL; + char * par_path = NULL; struct iatt postparent = {0,}; VALIDATE_OR_GOTO (frame, out); @@ -115,18 +114,23 @@ posix_lookup (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); VALIDATE_OR_GOTO (loc->path, out); - MAKE_REAL_PATH (real_path, this, loc->path); + if (uuid_is_null (loc->pargfid)) { + /* nameless lookup */ + MAKE_INODE_HANDLE (real_path, this, loc, &buf); + } else { + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf); - posix_gfid_set (this, real_path, xattr_req); + if (uuid_is_null (loc->inode->gfid)) + posix_gfid_set (this, real_path, loc, xattr_req); + } - op_ret = posix_lstat_with_gfid (this, real_path, &buf); op_errno = errno; if (op_ret == -1) { if (op_errno != ENOENT) { gf_log (this->name, GF_LOG_ERROR, "lstat on %s failed: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); } entry_ret = -1; @@ -139,27 +143,19 @@ posix_lookup (call_frame_t *frame, xlator_t *this, } parent: - if (loc->parent) { - pathdup = gf_strdup (real_path); - GF_VALIDATE_OR_GOTO (this->name, pathdup, out); - - parentpath = dirname (pathdup); - - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + if (par_path) { + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } } op_ret = entry_ret; out: - if (pathdup) - GF_FREE (pathdup); - if (xattr) dict_ref (xattr); @@ -177,10 +173,10 @@ int32_t posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) { struct iatt buf = {0,}; - char * real_path = NULL; int32_t op_ret = -1; int32_t op_errno = 0; struct posix_private *priv = NULL; + char *real_path = NULL; DECLARE_OLD_FS_ID_VAR; @@ -192,13 +188,13 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc) VALIDATE_OR_GOTO (priv, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); - op_ret = posix_lstat_with_gfid (this, real_path, &buf); + MAKE_INODE_HANDLE (real_path, this, loc, &buf); + if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "lstat on %s failed: %s", loc->path, + "lstat on %s failed: %s", real_path, strerror (op_errno)); goto out; } @@ -328,9 +324,8 @@ posix_setattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, &statpre); - op_ret = posix_lstat_with_gfid (this, real_path, &statpre); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -384,7 +379,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this, } } - op_ret = posix_lstat_with_gfid (this, real_path, &statpost); + op_ret = posix_pstat (this, loc->gfid, real_path, &statpost); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -456,7 +451,6 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this, struct iatt statpre = {0,}; struct iatt statpost = {0,}; struct posix_fd *pfd = NULL; - uint64_t tmp_pfd = 0; int32_t ret = -1; DECLARE_OLD_FS_ID_VAR; @@ -467,16 +461,15 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (fd, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_DEBUG, "pfd is NULL from fd=%p", fd); goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; - op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpre); + op_ret = posix_fdstat (this, pfd->fd, &statpre); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -531,7 +524,7 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this, } } - op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpost); + op_ret = posix_fdstat (this, pfd->fd, &statpost); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -570,7 +563,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (fd, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, NULL); dir = opendir (real_path); @@ -578,7 +571,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this, op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "opendir failed on %s: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } @@ -587,7 +580,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this, op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "dirfd() failed on %s: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } @@ -599,16 +592,12 @@ posix_opendir (call_frame_t *frame, xlator_t *this, pfd->dir = dir; pfd->fd = dirfd (dir); - pfd->path = gf_strdup (real_path); - if (!pfd->path) { - goto out; - } op_ret = fd_ctx_set (fd, this, (uint64_t)(long)pfd); if (op_ret) gf_log (this->name, GF_LOG_WARNING, "failed to set the fd context path=%s fd=%p", - loc->path, fd); + real_path, fd); op_ret = 0; @@ -619,8 +608,6 @@ out: dir = NULL; } if (pfd) { - if (pfd->path) - GF_FREE (pfd->path); GF_FREE (pfd); pfd = NULL; } @@ -654,19 +641,12 @@ posix_releasedir (xlator_t *this, pfd = (struct posix_fd *)(long)tmp_pfd; if (!pfd->dir) { gf_log (this->name, GF_LOG_WARNING, - "pfd->dir is NULL for fd=%p path=%s", - fd, pfd->path ? pfd->path : "<NULL>"); + "pfd->dir is NULL for fd=%p", fd); goto out; } priv = this->private; - if (!pfd->path) { - gf_log (this->name, GF_LOG_WARNING, - "pfd->path was NULL. fd=%p pfd=%p", - fd, pfd); - } - pthread_mutex_lock (&priv->janitor_lock); { INIT_LIST_HEAD (&pfd->list); @@ -686,7 +666,6 @@ posix_readlink (call_frame_t *frame, xlator_t *this, { char * dest = NULL; int32_t op_ret = -1; - int32_t lstat_ret = -1; int32_t op_errno = 0; char * real_path = NULL; struct iatt stbuf = {0,}; @@ -699,29 +678,25 @@ posix_readlink (call_frame_t *frame, xlator_t *this, dest = alloca (size + 1); - MAKE_REAL_PATH (real_path, this, loc->path); - - op_ret = readlink (real_path, dest, size); + MAKE_INODE_HANDLE (real_path, this, loc, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "readlink on %s failed: %s", loc->path, + "lstat on %s failed: %s", real_path, strerror (op_errno)); goto out; } - dest[op_ret] = 0; - - lstat_ret = posix_lstat_with_gfid (this, real_path, &stbuf); - if (lstat_ret == -1) { - op_ret = -1; + op_ret = readlink (real_path, dest, size); + if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "lstat on %s failed: %s", loc->path, + "readlink on %s failed: %s", real_path, strerror (op_errno)); goto out; } + dest[op_ret] = 0; out: SET_TO_OLD_FS_ID (); @@ -739,14 +714,13 @@ posix_mknod (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; char *real_path = 0; + char *par_path = 0; struct iatt stbuf = { 0, }; char was_present = 1; struct posix_private *priv = NULL; gid_t gid = 0; - char *pathdup = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; - char *parentpath = NULL; DECLARE_OLD_FS_ID_VAR; @@ -757,32 +731,25 @@ posix_mknod (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL); gid = frame->root->gid; - op_ret = setgid_override (this, real_path, &gid); - if (op_ret < 0) { - op_errno = -op_ret; - op_ret = -1; - goto out; - } - SET_FS_ID (frame->root->uid, gid); - pathdup = gf_strdup (real_path); - GF_VALIDATE_OR_GOTO (this->name, pathdup, out); - parentpath = dirname (pathdup); - - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } + if (preparent.ia_prot.sgid) { + gid = preparent.ia_gid; + } + #ifdef __NetBSD__ if (S_ISFIFO(mode)) op_ret = mkfifo (real_path, mode); @@ -799,23 +766,23 @@ posix_mknod (call_frame_t *frame, xlator_t *this, if (tmp_fd == -1) { gf_log (this->name, GF_LOG_ERROR, "create failed on %s: %s", - loc->path, strerror (errno)); + real_path, strerror (errno)); goto out; } close (tmp_fd); } else { gf_log (this->name, GF_LOG_ERROR, - "mknod on %s failed: %s", loc->path, + "mknod on %s failed: %s", real_path, strerror (op_errno)); goto out; } } - op_ret = posix_gfid_set (this, real_path, params); + op_ret = posix_gfid_set (this, real_path, loc, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting gfid on %s failed", loc->path); + "setting gfid on %s failed", real_path); } #ifndef HAVE_SET_FSID @@ -823,7 +790,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this, if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "lchown on %s failed: %s", loc->path, + "lchown on %s failed: %s", real_path, strerror (op_errno)); goto out; } @@ -832,41 +799,38 @@ posix_mknod (call_frame_t *frame, xlator_t *this, op_ret = posix_acl_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting ACLs on %s failed (%s)", loc->path, + "setting ACLs on %s failed (%s)", real_path, strerror (errno)); } op_ret = posix_entry_create_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting xattrs on %s failed (%s)", loc->path, + "setting xattrs on %s failed (%s)", real_path, strerror (errno)); } - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); + op_ret = posix_pstat (this, NULL, real_path, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "mknod on %s failed: %s", loc->path, + "mknod on %s failed: %s", real_path, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } op_ret = 0; out: - if (pathdup) - GF_FREE (pathdup); - SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno, @@ -879,6 +843,7 @@ out: return 0; } + int posix_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, dict_t *params) @@ -886,12 +851,11 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; char *real_path = NULL; + char *par_path = NULL; struct iatt stbuf = {0, }; char was_present = 1; struct posix_private *priv = NULL; gid_t gid = 0; - char *pathdup = NULL; - char *parentpath = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; @@ -904,51 +868,44 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL); gid = frame->root->gid; - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); + op_ret = posix_pstat (this, NULL, real_path, &stbuf); if ((op_ret == -1) && (errno == ENOENT)) { was_present = 0; } - op_ret = setgid_override (this, real_path, &gid); - if (op_ret < 0) { - op_errno = -op_ret; - op_ret = -1; - goto out; - } - SET_FS_ID (frame->root->uid, gid); - pathdup = gf_strdup (real_path); - if (!pathdup) - goto out; - - parentpath = dirname (pathdup); - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } + if (preparent.ia_prot.sgid) { + gid = preparent.ia_gid; + mode |= S_ISGID; + } + op_ret = mkdir (real_path, mode); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "mkdir of %s failed: %s", loc->path, + "mkdir of %s failed: %s", real_path, strerror (op_errno)); goto out; } - op_ret = posix_gfid_set (this, real_path, params); + op_ret = posix_gfid_set (this, real_path, loc, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting gfid on %s failed", loc->path); + "setting gfid on %s failed", real_path); } #ifndef HAVE_SET_FSID @@ -956,7 +913,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "chown on %s failed: %s", loc->path, + "chown on %s failed: %s", real_path, strerror (op_errno)); goto out; } @@ -965,41 +922,38 @@ posix_mkdir (call_frame_t *frame, xlator_t *this, op_ret = posix_acl_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting ACLs on %s failed (%s)", loc->path, + "setting ACLs on %s failed (%s)", real_path, strerror (errno)); } op_ret = posix_entry_create_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting xattrs on %s failed (%s)", loc->path, + "setting xattrs on %s failed (%s)", real_path, strerror (errno)); } - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); + op_ret = posix_pstat (this, NULL, real_path, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "lstat on %s failed: %s", loc->path, + "lstat on %s failed: %s", real_path, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } op_ret = 0; out: - if (pathdup) - GF_FREE (pathdup); - SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno, @@ -1020,9 +974,9 @@ posix_unlink (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; char *real_path = NULL; - char *pathdup = NULL; - char *parentpath = NULL; + char *par_path = NULL; int32_t fd = -1; + struct iatt stbuf; struct posix_private *priv = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; @@ -1034,23 +988,20 @@ posix_unlink (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); - - pathdup = gf_strdup (real_path); - if (!pathdup) - goto out; - - parentpath = dirname (pathdup); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } + if (stbuf.ia_nlink == 1) + posix_handle_unset (this, stbuf.ia_gfid, NULL); + priv = this->private; if (priv->background_unlink) { if (IA_ISREG (loc->inode->ia_type)) { @@ -1059,7 +1010,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this, op_ret = -1; op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "open of %s failed: %s", loc->path, + "open of %s failed: %s", real_path, strerror (op_errno)); goto out; } @@ -1070,26 +1021,23 @@ posix_unlink (call_frame_t *frame, xlator_t *this, if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "unlink of %s failed: %s", loc->path, + "unlink of %s failed: %s", real_path, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } op_ret = 0; out: - if (pathdup) - GF_FREE (pathdup); - SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno, @@ -1110,10 +1058,10 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; char * real_path = NULL; - char * pathdup = NULL; - char * parentpath = NULL; + char * par_path = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; + struct iatt stbuf; struct posix_private *priv = NULL; DECLARE_OLD_FS_ID_VAR; @@ -1125,20 +1073,14 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, priv = this->private; SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); - - pathdup = gf_strdup (real_path); - if (!pathdup) - goto out; - - parentpath = dirname (pathdup); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } @@ -1155,6 +1097,10 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, } op_errno = errno; + if (op_ret == 0) { + posix_handle_unset (this, stbuf.ia_gfid, NULL); + } + if (op_errno == EEXIST) /* Solaris sets errno = EEXIST instead of ENOTEMPTY */ op_errno = ENOTEMPTY; @@ -1162,7 +1108,7 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, /* No need to log a common error as ENOTEMPTY */ if (op_ret == -1 && op_errno != ENOTEMPTY) { gf_log (this->name, GF_LOG_ERROR, - "rmdir of %s failed: %s", loc->path, + "rmdir of %s failed: %s", real_path, strerror (op_errno)); } @@ -1170,23 +1116,20 @@ posix_rmdir (call_frame_t *frame, xlator_t *this, gf_log (this->name, (op_errno == ENOTEMPTY) ? GF_LOG_DEBUG : GF_LOG_ERROR, "%s on %s failed", (flags) ? "rename" : "rmdir", - loc->path); + real_path); goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + par_path, strerror (op_errno)); goto out; } out: - if (pathdup) - GF_FREE (pathdup); - SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno, @@ -1203,12 +1146,11 @@ posix_symlink (call_frame_t *frame, xlator_t *this, 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; char was_present = 1; - char *pathdup = NULL; - char *parentpath = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; @@ -1222,52 +1164,43 @@ posix_symlink (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); if ((op_ret == -1) && (errno == ENOENT)){ was_present = 0; } - gid = frame->root->gid; - - op_ret = setgid_override (this, real_path, &gid); - if (op_ret < 0) { - op_errno = -op_ret; - op_ret = -1; - goto out; - } - SET_FS_ID (frame->root->uid, gid); - pathdup = gf_strdup (real_path); - if (!pathdup) - goto out; - parentpath = dirname (pathdup); + gid = frame->root->gid; - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } + if (preparent.ia_prot.sgid) { + gid = preparent.ia_gid; + } + op_ret = symlink (linkname, real_path); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "symlink of %s --> %s failed: %s", - loc->path, linkname, strerror (op_errno)); + real_path, linkname, strerror (op_errno)); goto out; } - op_ret = posix_gfid_set (this, real_path, params); + op_ret = posix_gfid_set (this, real_path, loc, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting gfid on %s failed", loc->path); + "setting gfid on %s failed", real_path); } #ifndef HAVE_SET_FSID @@ -1276,7 +1209,7 @@ posix_symlink (call_frame_t *frame, xlator_t *this, op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "lchown failed on %s: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } #endif @@ -1284,41 +1217,38 @@ posix_symlink (call_frame_t *frame, xlator_t *this, op_ret = posix_acl_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting ACLs on %s failed (%s)", loc->path, + "setting ACLs on %s failed (%s)", real_path, strerror (errno)); } op_ret = posix_entry_create_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting xattrs on %s failed (%s)", loc->path, + "setting xattrs on %s failed (%s)", real_path, strerror (errno)); } - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); + op_ret = posix_pstat (this, NULL, real_path, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } op_ret = 0; out: - if (pathdup) - GF_FREE (pathdup); - SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, @@ -1340,19 +1270,20 @@ posix_rename (call_frame_t *frame, xlator_t *this, 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; - char *oldpathdup = NULL; - char *oldparentpath = NULL; - char *newpathdup = NULL; - char *newparentpath = NULL; 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; + int was_dir; + int nlink; DECLARE_OLD_FS_ID_VAR; @@ -1365,42 +1296,35 @@ posix_rename (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (priv, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_oldpath, this, oldloc->path); - MAKE_REAL_PATH (real_newpath, this, newloc->path); - - oldpathdup = gf_strdup (real_oldpath); - if (!oldpathdup) - goto out; + MAKE_ENTRY_HANDLE (real_oldpath, par_oldpath, this, oldloc, NULL); + MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf); - oldparentpath = dirname (oldpathdup); - - op_ret = posix_lstat_with_gfid (this, oldparentpath, &preoldparent); + op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &preoldparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - oldloc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_oldpath, strerror (op_errno)); goto out; } - newpathdup = gf_strdup (real_newpath); - if (!newpathdup) - goto out; - - newparentpath = dirname (newpathdup); - - op_ret = posix_lstat_with_gfid (this, newparentpath, &prenewparent); + op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &prenewparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "pre-operation lstat on parent of %s failed: %s", - newloc->path, strerror (op_errno)); + par_newpath, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf); + op_ret = posix_pstat (this, NULL, real_newpath, &stbuf); if ((op_ret == -1) && (errno == ENOENT)){ was_present = 0; + } else { + 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) { @@ -1424,17 +1348,32 @@ posix_rename (call_frame_t *frame, xlator_t *this, goto out; } + if (IA_ISDIR (oldloc->inode->ia_type)) { + posix_handle_unset (this, oldloc->inode->gfid, NULL); + } + op_ret = sys_rename (real_oldpath, real_newpath); if (op_ret == -1) { op_errno = errno; gf_log (this->name, (op_errno == ENOTEMPTY ? GF_LOG_DEBUG : GF_LOG_ERROR), "rename of %s to %s failed: %s", - oldloc->path, newloc->path, strerror (op_errno)); + real_oldpath, real_newpath, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf); + if (was_dir) + posix_handle_unset (this, victim, NULL); + + if (was_present && !was_dir && nlink == 2) + 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, NULL, real_newpath, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -1443,33 +1382,27 @@ posix_rename (call_frame_t *frame, xlator_t *this, goto out; } - op_ret = posix_lstat_with_gfid (this, oldparentpath, &postoldparent); + op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &postoldparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - oldloc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_oldpath, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, newparentpath, &postnewparent); + op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postnewparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - newloc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_newpath, strerror (op_errno)); goto out; } op_ret = 0; out: - if (oldpathdup) - GF_FREE (oldpathdup); - - if (newpathdup) - GF_FREE (newpathdup); - SET_TO_OLD_FS_ID (); @@ -1493,11 +1426,10 @@ posix_link (call_frame_t *frame, xlator_t *this, 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; char was_present = 1; - char *newpathdup = NULL; - char *newparentpath = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; @@ -1512,26 +1444,18 @@ posix_link (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (priv, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_oldpath, this, oldloc->path); - MAKE_REAL_PATH (real_newpath, this, newloc->path); + MAKE_INODE_HANDLE (real_oldpath, this, oldloc, &stbuf); - op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf); + MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf); if ((op_ret == -1) && (errno == ENOENT)) { was_present = 0; } - newpathdup = gf_strdup (real_newpath); - if (!newpathdup) { - op_errno = ENOMEM; - goto out; - } - - newparentpath = dirname (newpathdup); - op_ret = posix_lstat_with_gfid (this, newparentpath, &preparent); + op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s", - newparentpath, strerror (op_errno)); + par_newpath, strerror (op_errno)); goto out; } @@ -1551,11 +1475,11 @@ posix_link (call_frame_t *frame, xlator_t *this, op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "link %s to %s failed: %s", - oldloc->path, newloc->path, strerror (op_errno)); + real_oldpath, real_newpath, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf); + op_ret = posix_pstat (this, NULL, real_newpath, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -1564,19 +1488,17 @@ posix_link (call_frame_t *frame, xlator_t *this, goto out; } - op_ret = posix_lstat_with_gfid (this, newparentpath, &postparent); + op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s", - newparentpath, strerror (op_errno)); + par_newpath, strerror (op_errno)); goto out; } op_ret = 0; out: - if (newpathdup) - GF_FREE (newpathdup); SET_TO_OLD_FS_ID (); STACK_UNWIND_STRICT (link, frame, op_ret, op_errno, @@ -1611,14 +1533,13 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) VALIDATE_OR_GOTO (priv, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); - op_ret = posix_lstat_with_gfid (this, real_path, &prebuf); + MAKE_INODE_HANDLE (real_path, this, loc, &prebuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "pre-operation lstat on %s failed: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } @@ -1627,11 +1548,11 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset) op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "truncate on %s failed: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } - op_ret = posix_lstat_with_gfid (this, real_path, &postbuf); + op_ret = posix_pstat (this, loc->gfid, real_path, &postbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "lstat on %s failed: %s", @@ -1651,7 +1572,7 @@ out: } -int32_t +int posix_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags, mode_t mode, fd_t *fd, dict_t *params) @@ -1661,14 +1582,13 @@ posix_create (call_frame_t *frame, xlator_t *this, 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; - char *pathdup = NULL; - char *parentpath = NULL; struct iatt preparent = {0,}; struct iatt postparent = {0,}; @@ -1683,33 +1603,25 @@ posix_create (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf); gid = frame->root->gid; - op_ret = setgid_override (this, real_path, &gid); - if (op_ret < 0) { - op_errno = -op_ret; - op_ret = -1; - goto out; - } - SET_FS_ID (frame->root->uid, gid); - pathdup = gf_strdup (real_path); - if (!pathdup) - goto out; - - parentpath = dirname (pathdup); - op_ret = posix_lstat_with_gfid (this, parentpath, &preparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "pre-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "pre-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } + if (preparent.ia_prot.sgid) { + gid = preparent.ia_gid; + } + if (!flags) { _flags = O_CREAT | O_RDWR | O_EXCL; } @@ -1717,7 +1629,7 @@ posix_create (call_frame_t *frame, xlator_t *this, _flags = flags | O_CREAT; } - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); + op_ret = posix_pstat (this, NULL, real_path, &stbuf); if ((op_ret == -1) && (errno == ENOENT)) { was_present = 0; } @@ -1731,15 +1643,15 @@ posix_create (call_frame_t *frame, xlator_t *this, op_errno = errno; op_ret = -1; gf_log (this->name, GF_LOG_ERROR, - "open on %s failed: %s", loc->path, + "open on %s failed: %s", real_path, strerror (op_errno)); goto out; } - op_ret = posix_gfid_set (this, real_path, params); + op_ret = posix_gfid_set (this, real_path, loc, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting gfid on %s failed", loc->path); + "setting gfid on %s failed", real_path); } #ifndef HAVE_SET_FSID @@ -1755,18 +1667,18 @@ posix_create (call_frame_t *frame, xlator_t *this, op_ret = posix_acl_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting ACLs on %s failed (%s)", loc->path, + "setting ACLs on %s failed (%s)", real_path, strerror (errno)); } op_ret = posix_entry_create_xattr_set (this, real_path, params); if (op_ret) { gf_log (this->name, GF_LOG_ERROR, - "setting xattrs on %s failed (%s)", loc->path, + "setting xattrs on %s failed (%s)", real_path, strerror (errno)); } - op_ret = posix_fstat_with_gfid (this, _fd, &stbuf); + op_ret = posix_fdstat (this, _fd, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -1774,12 +1686,12 @@ posix_create (call_frame_t *frame, xlator_t *this, goto out; } - op_ret = posix_lstat_with_gfid (this, parentpath, &postparent); + op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, - "post-operation lstat on parent of %s failed: %s", - loc->path, strerror (op_errno)); + "post-operation lstat on parent %s failed: %s", + par_path, strerror (op_errno)); goto out; } @@ -1797,7 +1709,7 @@ posix_create (call_frame_t *frame, xlator_t *this, if (op_ret) gf_log (this->name, GF_LOG_WARNING, "failed to set the fd context path=%s fd=%p", - loc->path, fd); + real_path, fd); LOCK (&priv->lock); { @@ -1808,8 +1720,6 @@ posix_create (call_frame_t *frame, xlator_t *this, op_ret = 0; out: - if (pathdup) - GF_FREE (pathdup); SET_TO_OLD_FS_ID (); if ((-1 == op_ret) && (_fd != -1)) { @@ -1837,7 +1747,6 @@ posix_open (call_frame_t *frame, xlator_t *this, int32_t _fd = -1; struct posix_fd *pfd = NULL; struct posix_private *priv = NULL; - gid_t gid = 0; struct iatt stbuf = {0, }; DECLARE_OLD_FS_ID_VAR; @@ -1851,22 +1760,13 @@ posix_open (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, &stbuf); - op_ret = setgid_override (this, real_path, &gid); - if (op_ret < 0) { - op_errno = -op_ret; - op_ret = -1; - goto out; - } - - SET_FS_ID (frame->root->uid, gid); + SET_FS_ID (frame->root->uid, frame->root->gid); if (priv->o_direct) flags |= O_DIRECT; - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); - _fd = open (real_path, flags, 0); if (_fd == -1) { op_ret = -1; @@ -1891,30 +1791,7 @@ posix_open (call_frame_t *frame, xlator_t *this, if (op_ret) gf_log (this->name, GF_LOG_WARNING, "failed to set the fd context path=%s fd=%p", - loc->path, fd); - -#ifndef HAVE_SET_FSID - if (flags & O_CREAT) { - op_ret = chown (real_path, frame->root->uid, gid); - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, - "chown on %s failed: %s", - real_path, strerror (op_errno)); - goto out; - } - } -#endif - - if (flags & O_CREAT) { - op_ret = posix_lstat_with_gfid (this, real_path, &stbuf); - if (op_ret == -1) { - op_errno = errno; - gf_log (this->name, GF_LOG_ERROR, "lstat on (%s) " - "failed: %s", real_path, strerror (op_errno)); - goto out; - } - } + real_path, fd); LOCK (&priv->lock); { @@ -1945,7 +1822,6 @@ int posix_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t offset) { - uint64_t tmp_pfd = 0; int32_t op_ret = -1; int32_t op_errno = 0; int _fd = -1; @@ -1965,14 +1841,13 @@ posix_readv (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, "pfd is NULL from fd=%p", fd); goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; if (!size) { op_errno = EINVAL; @@ -2014,7 +1889,7 @@ posix_readv (call_frame_t *frame, xlator_t *this, * we read from */ - op_ret = posix_fstat_with_gfid (this, _fd, &stbuf); + op_ret = posix_fdstat (this, _fd, &stbuf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -2142,7 +2017,6 @@ posix_writev (call_frame_t *frame, xlator_t *this, struct iatt postop = {0,}; int ret = -1; - uint64_t tmp_pfd = 0; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -2154,18 +2028,17 @@ posix_writev (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (priv, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL from fd=%p", fd); op_errno = -ret; goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; - op_ret = posix_fstat_with_gfid (this, _fd, &preop); + op_ret = posix_fdstat (this, _fd, &preop); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -2201,7 +2074,7 @@ posix_writev (call_frame_t *frame, xlator_t *this, fsync (_fd); } - ret = posix_fstat_with_gfid (this, _fd, &postop); + ret = posix_fdstat (this, _fd, &postop); if (ret == -1) { op_ret = -1; op_errno = errno; @@ -2235,7 +2108,7 @@ posix_statfs (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); VALIDATE_OR_GOTO (this->private, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, NULL); priv = this->private; @@ -2273,13 +2146,13 @@ posix_flush (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; int ret = -1; - uint64_t tmp_pfd = 0; + struct posix_fd *pfd = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (fd, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, @@ -2310,7 +2183,7 @@ posix_release (xlator_t *this, priv = this->private; - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = fd_ctx_del (fd, this, &tmp_pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL from fd=%p", fd); @@ -2352,7 +2225,6 @@ posix_fsync (call_frame_t *frame, xlator_t *this, int _fd = -1; struct posix_fd * pfd = NULL; int ret = -1; - uint64_t tmp_pfd = 0; struct iatt preop = {0,}; struct iatt postop = {0,}; @@ -2370,18 +2242,17 @@ posix_fsync (call_frame_t *frame, xlator_t *this, goto out; #endif - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, "pfd not found in fd's ctx"); goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; - op_ret = posix_fstat_with_gfid (this, _fd, &preop); + op_ret = posix_fdstat (this, _fd, &preop); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_WARNING, @@ -2411,7 +2282,7 @@ posix_fsync (call_frame_t *frame, xlator_t *this, } } - op_ret = posix_fstat_with_gfid (this, _fd, &postop); + op_ret = posix_fdstat (this, _fd, &postop); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_WARNING, @@ -2450,7 +2321,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); VALIDATE_OR_GOTO (dict, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, NULL); dict_del (dict, GFID_XATTR_KEY); @@ -2506,13 +2377,13 @@ posix_getxattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc, out); SET_FS_ID (frame->root->uid, frame->root->gid); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, NULL); priv = this->private; if (loc->inode && IA_ISDIR(loc->inode->ia_type) && name && ZR_FILE_CONTENT_REQUEST(name)) { - ret = posix_get_file_contents (this, real_path, name, + ret = posix_get_file_contents (this, loc->gfid, &name[15], &file_contents); if (ret < 0) { op_errno = -ret; @@ -2677,7 +2548,6 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, { int32_t op_ret = -1; int32_t op_errno = ENOENT; - uint64_t tmp_pfd = 0; struct posix_fd * pfd = NULL; int _fd = -1; int32_t list_offset = 0; @@ -2697,14 +2567,13 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this, SET_FS_ID (frame->root->uid, frame->root->gid); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, "pfd is NULL from fd=%p", fd); goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; @@ -2832,7 +2701,6 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; struct posix_fd * pfd = NULL; - uint64_t tmp_pfd = 0; int _fd = -1; data_pair_t * trav = NULL; int ret = -1; @@ -2845,14 +2713,13 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (fd, out); VALIDATE_OR_GOTO (dict, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, "pfd is NULL from fd=%p", fd); goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; dict_del (dict, GFID_XATTR_KEY); @@ -2889,13 +2756,14 @@ posix_removexattr (call_frame_t *frame, xlator_t *this, DECLARE_OLD_FS_ID_VAR; + MAKE_INODE_HANDLE (real_path, this, loc, NULL); + if (!strcmp (GFID_XATTR_KEY, name)) { gf_log (this->name, GF_LOG_WARNING, "Remove xattr called" - " on gfid for file %s", loc->path); + " on gfid for file %s", real_path); goto out; } - MAKE_REAL_PATH (real_path, this, loc->path); SET_FS_ID (frame->root->uid, frame->root->gid); @@ -2904,7 +2772,7 @@ posix_removexattr (call_frame_t *frame, xlator_t *this, op_errno = errno; if (op_errno != ENOATTR && op_errno != EPERM) gf_log (this->name, GF_LOG_ERROR, - "removexattr on %s (for %s): %s", loc->path, + "removexattr on %s (for %s): %s", real_path, name, strerror (op_errno)); goto out; } @@ -2926,13 +2794,13 @@ posix_fsyncdir (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; int ret = -1; - uint64_t tmp_pfd = 0; + struct posix_fd *pfd = NULL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (fd, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, @@ -3006,7 +2874,6 @@ do_xattrop (call_frame_t *frame, xlator_t *this, int ret = 0; int _fd = -1; - uint64_t tmp_pfd = 0; struct posix_fd *pfd = NULL; data_pair_t *trav = NULL; @@ -3021,7 +2888,7 @@ do_xattrop (call_frame_t *frame, xlator_t *this, trav = xattr->members_list; if (fd) { - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "failed to get pfd from fd=%p", @@ -3030,15 +2897,14 @@ do_xattrop (call_frame_t *frame, xlator_t *this, op_errno = EBADFD; goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; } - if (loc && loc->path) - MAKE_REAL_PATH (real_path, this, loc->path); + if (loc && !uuid_is_null (loc->gfid)) + MAKE_INODE_HANDLE (real_path, this, loc, NULL); - if (loc) { - path = gf_strdup (loc->path); + if (real_path) { + path = gf_strdup (real_path); inode = loc->inode; } else if (fd) { inode = fd->inode; @@ -3207,13 +3073,13 @@ posix_access (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (loc, out); - MAKE_REAL_PATH (real_path, this, loc->path); + MAKE_INODE_HANDLE (real_path, this, loc, NULL); op_ret = access (real_path, mask & 07); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "access failed on %s: %s", - loc->path, strerror (op_errno)); + real_path, strerror (op_errno)); goto out; } op_ret = 0; @@ -3237,7 +3103,6 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, struct iatt postop = {0,}; struct posix_fd *pfd = NULL; int ret = -1; - uint64_t tmp_pfd = 0; struct posix_private *priv = NULL; DECLARE_OLD_FS_ID_VAR; @@ -3250,18 +3115,17 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL, fd=%p", fd); op_errno = -ret; goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; - op_ret = posix_fstat_with_gfid (this, _fd, &preop); + op_ret = posix_fdstat (this, _fd, &preop); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -3280,7 +3144,7 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this, goto out; } - op_ret = posix_fstat_with_gfid (this, _fd, &postop); + op_ret = posix_fdstat (this, _fd, &postop); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, @@ -3309,7 +3173,6 @@ posix_fstat (call_frame_t *frame, xlator_t *this, int32_t op_errno = 0; struct iatt buf = {0,}; struct posix_fd *pfd = NULL; - uint64_t tmp_pfd = 0; int ret = -1; struct posix_private *priv = NULL; @@ -3323,18 +3186,17 @@ posix_fstat (call_frame_t *frame, xlator_t *this, priv = this->private; VALIDATE_OR_GOTO (priv, out); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL, fd=%p", fd); op_errno = -ret; goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; _fd = pfd->fd; - op_ret = posix_fstat_with_gfid (this, _fd, &buf); + op_ret = posix_fdstat (this, _fd, &buf); if (op_ret == -1) { op_errno = errno; gf_log (this->name, GF_LOG_ERROR, "fstat failed on fd=%p: %s", @@ -3425,18 +3287,17 @@ posix_fentrylk (call_frame_t *frame, xlator_t *this, int -__posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries, - const char *real_path, const char *base_path) +posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size, + gf_dirent_t *entries) { off_t in_case = -1; size_t filled = 0; - int ret = 0; int count = 0; + char entrybuf[sizeof(struct dirent) + 256 + 8]; struct dirent *entry = NULL; int32_t this_size = -1; gf_dirent_t *this_entry = NULL; - char hidden_path[PATH_MAX] = {0, }; - struct stat statbuf = {0, }; + uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; if (!off) { rewinddir (dir); @@ -3455,7 +3316,8 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries, } errno = 0; - entry = readdir (dir); + entry = NULL; + readdir_r (dir, (struct dirent *)entrybuf, &entry); if (!entry) { if (errno == EBADF) { @@ -3467,7 +3329,7 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries, break; } - if ((!strcmp (real_path, base_path)) + if ((uuid_compare (fd->inode->gfid, rootgfid) == 0) && (!strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR))) continue; @@ -3480,19 +3342,15 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries, * when the cluster/dht xlator decides to distribute * exended attribute backing file accross storage servers. */ - if ((!strcmp(real_path, base_path)) + if ((uuid_compare (fd->inode->gfid, rootgfid) == 0) && (!strcmp(entry->d_name, ".attribute"))) continue; #endif /* __NetBSD__ */ - if ((!strcmp (real_path, base_path)) + if ((uuid_compare (fd->inode->gfid, rootgfid) == 0) && (!strncmp (GF_HIDDEN_PATH, entry->d_name, strlen (GF_HIDDEN_PATH)))) { - snprintf (hidden_path, PATH_MAX, "%s/%s", real_path, - entry->d_name); - ret = lstat (hidden_path, &statbuf); - if (!ret && S_ISDIR (statbuf.st_mode)) - continue; + continue; } this_size = max (sizeof (gf_dirent_t), @@ -3533,7 +3391,6 @@ int32_t posix_do_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, off_t off, int whichop) { - uint64_t tmp_pfd = 0; struct posix_fd *pfd = NULL; DIR *dir = NULL; int ret = -1; @@ -3541,14 +3398,12 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, int32_t op_ret = -1; int32_t op_errno = 0; gf_dirent_t entries; - char *real_path = NULL; - int real_path_len = -1; - char *entry_path = NULL; - int entry_path_len = -1; struct iatt stbuf = {0, }; - char base_path[PATH_MAX] = {0,}; gf_dirent_t *tmp_entry = NULL; - +#ifdef IGNORE_READDIRP_ATTRS + uuid_t gfid; + ia_type_t entry_type = 0; +#endif VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); @@ -3556,38 +3411,13 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, INIT_LIST_HEAD (&entries.list); - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL, fd=%p", fd); op_errno = -ret; goto out; } - pfd = (struct posix_fd *)(long)tmp_pfd; - if (!pfd->path) { - op_errno = EBADFD; - gf_log (this->name, GF_LOG_WARNING, - "pfd does not have path set (possibly file " - "fd, fd=%p)", fd); - goto out; - } - - real_path = pfd->path; - real_path_len = strlen (real_path); - - entry_path_len = real_path_len + NAME_MAX; - entry_path = alloca (entry_path_len); - - strncpy(base_path, POSIX_BASE_PATH(this), sizeof(base_path)); - base_path[strlen(base_path)] = '/'; - - if (!entry_path) { - op_errno = errno; - goto out; - } - - strncpy (entry_path, real_path, entry_path_len); - entry_path[real_path_len] = '/'; dir = pfd->dir; @@ -3598,23 +3428,30 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this, goto out; } - - LOCK (&fd->lock); - { - count = __posix_fill_readdir (dir, off, size, &entries, - real_path, base_path); - - } - UNLOCK (&fd->lock); + count = posix_fill_readdir (fd, dir, off, size, &entries); /* pick ENOENT to indicate EOF */ op_errno = errno; if (whichop == GF_FOP_READDIRP) { list_for_each_entry (tmp_entry, &entries.list, list) { - strcpy (entry_path + real_path_len + 1, - tmp_entry->d_name); - posix_lstat_with_gfid (this, entry_path, &stbuf); +#ifdef IGNORE_READDIRP_ATTRS + ret = inode_grep_for_gfid (fd->inode->table, fd->inode, + tmp_entry->d_name, gfid, + &entry_type); + if (ret == 0) { + memset (&stbuf, 0, sizeof (stbuf)); + uuid_copy (stbuf.ia_gfid, gfid); + posix_fill_ino_from_gfid (this, &stbuf); + stbuf.ia_type = entry_type; + } else { + posix_istat (this, fd->inode->gfid, + tmp_entry->d_name, &stbuf); + } +#else + posix_istat (this, fd->inode->gfid, + tmp_entry->d_name, &stbuf); +#endif if (stbuf.ia_ino) tmp_entry->d_ino = stbuf.ia_ino; tmp_entry->d_stat = stbuf; @@ -3690,7 +3527,6 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, char *buf = NULL; int _fd = -1; - uint64_t tmp_pfd = 0; struct posix_fd *pfd = NULL; @@ -3714,14 +3550,13 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, goto out; } - ret = fd_ctx_get (fd, this, &tmp_pfd); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { gf_log (this->name, GF_LOG_WARNING, "pfd is NULL, fd=%p", fd); op_errno = -ret; goto out; } - pfd = (struct posix_fd *)(long) tmp_pfd; _fd = pfd->fd; @@ -3809,6 +3644,7 @@ init (xlator_t *this) uuid_t old_uuid = {0,}; uuid_t dict_uuid = {0,}; uuid_t gfid = {0,}; + uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; dir_data = dict_get (this->options, "directory"); @@ -3949,6 +3785,16 @@ init (xlator_t *this) "%s: failed to fetch gfid (%s)", dir_data->data, strerror (errno)); goto out; + } else { + /* First time volume, set the GFID */ + ret = sys_lsetxattr (dir_data->data, "trusted.gfid", rootgfid, + 16, XATTR_CREATE); + if (ret) { + gf_log (this->name, GF_LOG_ERROR, + "%s: failed to set gfid (%s)", + dir_data->data, strerror (errno)); + goto out; + } } op_ret = sys_lgetxattr (dir_data->data, "system.posix_acl_access", @@ -4096,6 +3942,14 @@ init (xlator_t *this) #endif this->private = (void *)_private; + op_ret = posix_handle_init (this); + if (op_ret == -1) { + gf_log (this->name, GF_LOG_ERROR, + "Posix handle setup failed"); + ret = -1; + goto out; + } + pthread_mutex_init (&_private->janitor_lock, NULL); pthread_cond_init (&_private->janitor_cond, NULL); INIT_LIST_HEAD (&_private->janitor_fds); |