summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-helpers.c
diff options
context:
space:
mode:
authorAshish Pandey <aspandey@redhat.com>2015-11-26 14:35:49 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-12-15 00:35:59 -0800
commitc4f6521dfe6a44cee2f61ae41fc26faaf785372d (patch)
tree2dc31b5470c7a1b3213deb4b544a2fb341c9c353 /xlators/storage/posix/src/posix-helpers.c
parentbe438f9aa70cce9d14d72d7cf8ddee89738db36c (diff)
storage/posix: Implement .unlink directory
Problem: For EC volume, If a file descriptor is open and file has been unlinked, any further write on that fd will fail. When a write request comes, EC internally reads some blocks using anonymous fd. This read will fail as the file has already been unlinked. Solution: To solve this issue, we are using .unlink directory to keep track of unlinked file. If a file is to be unlinked while its fd is open, move this to .unlink directory and unlink it from .glusterfs and real path. Once all the fd will be closed, remove this entry form .unlink directory. Change-Id: I8344edb0d340bdb883dc46458c16edbc336916b9 BUG: 1286029 Signed-off-by: Ashish Pandey <aspandey@redhat.com> Reviewed-on: http://review.gluster.org/12816 Reviewed-by: Krutika Dhananjay <kdhananj@redhat.com> Reviewed-by: Xavier Hernandez <xhernandez@datalab.es> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Pranith Kumar Karampuri <pkarampu@redhat.com>
Diffstat (limited to 'xlators/storage/posix/src/posix-helpers.c')
-rw-r--r--xlators/storage/posix/src/posix-helpers.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index 09552a30ec7..d6e1736bfd5 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -1604,7 +1604,6 @@ out:
return ret;
}
-
static int
__posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p)
{
@@ -1612,34 +1611,37 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p)
struct posix_fd *pfd = NULL;
int ret = -1;
char *real_path = NULL;
+ char *unlink_path = NULL;
int _fd = -1;
DIR *dir = NULL;
+ struct posix_private *priv = NULL;
+
+ priv = this->private;
+
ret = __fd_ctx_get (fd, this, &tmp_pfd);
if (ret == 0) {
pfd = (void *)(long) tmp_pfd;
- ret = 0;
+ goto out;
+ }
+ if (!fd_is_anonymous(fd)) {
+ gf_msg (this->name, GF_LOG_ERROR, 0,
+ P_MSG_READ_FAILED,
+ "Failed to get fd context for a non-anonymous fd, "
+ "file: %s, gfid: %s", real_path,
+ uuid_utoa (fd->inode->gfid));
goto out;
}
MAKE_HANDLE_PATH (real_path, this, fd->inode->gfid, NULL);
if (!real_path) {
gf_msg (this->name, GF_LOG_ERROR, 0,
- P_MSG_HANDLE_PATH_CREATE_FAILED,
+ P_MSG_READ_FAILED,
"Failed to create handle path (%s)",
uuid_utoa (fd->inode->gfid));
ret = -1;
goto out;
}
-
- if (!fd_is_anonymous(fd)) {
- gf_log (this->name, GF_LOG_ERROR,
- "Failed to get fd context for a non-anonymous fd, "
- "file: %s, gfid: %s", real_path,
- uuid_utoa (fd->inode->gfid));
- goto out;
- }
-
pfd = GF_CALLOC (1, sizeof (*pfd), gf_posix_mt_posix_fd);
if (!pfd) {
goto out;
@@ -1663,6 +1665,16 @@ __posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p)
if (fd->inode->ia_type == IA_IFREG) {
_fd = open (real_path, fd->flags);
if (_fd == -1) {
+ POSIX_GET_FILE_UNLINK_PATH (priv->base_path,
+ fd->inode->gfid,
+ unlink_path);
+ _fd = open (unlink_path, fd->flags);
+ }
+ if (_fd == -1) {
+ gf_msg (this->name, GF_LOG_ERROR, errno,
+ P_MSG_READ_FAILED,
+ "Failed to get anonymous "
+ "real_path: %s _fd = %d", real_path, _fd);
GF_FREE (pfd);
pfd = NULL;
goto out;
@@ -2164,3 +2176,40 @@ posix_fdget_objectsignature (int fd, dict_t *xattr)
error_return:
return -EINVAL;
}
+
+
+int
+posix_inode_ctx_get (inode_t *inode, xlator_t *this, uint64_t *ctx)
+{
+ int ret = -1;
+ uint64_t ctx_int = 0;
+
+ GF_VALIDATE_OR_GOTO (this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+
+ ret = inode_ctx_get (inode, this, &ctx_int);
+
+ if (ret)
+ return ret;
+
+ if (ctx)
+ *ctx = ctx_int;
+
+out:
+ return ret;
+}
+
+
+int
+posix_inode_ctx_set (inode_t *inode, xlator_t *this, uint64_t ctx)
+{
+ int ret = -1;
+
+ GF_VALIDATE_OR_GOTO (this->name, this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode, out);
+ GF_VALIDATE_OR_GOTO (this->name, ctx, out);
+
+ ret = inode_ctx_set (inode, this, &ctx);
+out:
+ return ret;
+}