diff options
Diffstat (limited to 'xlators/storage')
| -rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 3 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-helpers.c | 73 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-mem-types.h | 1 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 196 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.h | 26 | 
5 files changed, 276 insertions, 23 deletions
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index 9a521d019a4..5a8f180b9f4 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -16,6 +16,8 @@  #include <alloca.h>  #endif +#include "common-utils.h" +  #include "posix-handle.h"  #include "posix.h"  #include "xlator.h" @@ -447,7 +449,6 @@ out:          return len;  } -  int  posix_handle_init (xlator_t *this)  { 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; +} diff --git a/xlators/storage/posix/src/posix-mem-types.h b/xlators/storage/posix/src/posix-mem-types.h index 81752c17e78..b463c086be5 100644 --- a/xlators/storage/posix/src/posix-mem-types.h +++ b/xlators/storage/posix/src/posix-mem-types.h @@ -21,6 +21,7 @@ enum gf_posix_mem_types_ {          gf_posix_mt_posix_dev_t,          gf_posix_mt_trash_path,  	gf_posix_mt_paiocb, +        gf_posix_mt_inode_ctx_t,          gf_posix_mt_end  };  #endif diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index efb5f03bef1..86ac65a897d 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -101,10 +101,32 @@ int  posix_forget (xlator_t *this, inode_t *inode)  {          uint64_t tmp_cache = 0; -        if (!inode_ctx_del (inode, this, &tmp_cache)) -                dict_destroy ((dict_t *)(long)tmp_cache); +        int ret = 0; +        char *unlink_path = NULL; +        struct posix_private    *priv_posix = NULL; -        return 0; +        priv_posix = (struct posix_private *) this->private; + +        ret = inode_ctx_del (inode, this, &tmp_cache); +        if (ret < 0) { +                ret = 0; +                goto out; +        } +        if (tmp_cache == GF_UNLINK_TRUE) { +                POSIX_GET_FILE_UNLINK_PATH(priv_posix->base_path, +                                           inode->gfid, unlink_path); +                if (!unlink_path) { +                        gf_msg (this->name, GF_LOG_ERROR, ENOMEM, +                                P_MSG_UNLINK_FAILED, +                                "Failed to remove gfid :%s", +                                uuid_utoa (inode->gfid)); +                        ret = -1; +                        goto out; +                } +                ret = sys_unlink(unlink_path); +        } +out: +        return ret;  }  /* Regular fops */ @@ -1446,16 +1468,93 @@ out:          return 0;  } +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 (inode, this, ctx); +        if (ret < 0) { +                goto out; +        } + +out: +        return ret; +} + +int32_t +posix_move_gfid_to_unlink (xlator_t *this, uuid_t gfid, loc_t *loc) +{ +        char *unlink_path = NULL; +        char *gfid_path = NULL; +        struct stat  stbuf = {0, }; +        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; + +out: +        return ret; +} +  int32_t  posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path, -                                    struct iatt *stbuf, int32_t *op_errno) +                                    struct iatt *stbuf, int32_t *op_errno, +                                    loc_t *loc)  { -        int32_t             ret      =   0; +        int32_t                 ret    = 0; +        struct posix_private    *priv  = NULL; +        int fd_count = 0; -        /*  Unlink the gfid_handle_first */ +        priv = this->private; +        /*  Unlink the gfid_handle_first */          if (stbuf && stbuf->ia_nlink == 1) { -                ret = posix_handle_unset (this, stbuf->ia_gfid, NULL); + +                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 " @@ -1469,7 +1568,6 @@ posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *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; @@ -1623,7 +1721,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,          }          op_ret =  posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf, -                                                      &op_errno); +                                                      &op_errno, loc);          if (op_ret == -1) {                  goto out;          } @@ -6176,6 +6274,77 @@ out:  	return ret;  } +int32_t +posix_create_unlink_dir (xlator_t *this) { + +        char  *unlink_path = NULL; +        char  *landfill_path = NULL; +        struct posix_private *priv = NULL; +        struct stat           stbuf; +        int ret = -1; +        uuid_t                gfid = {0}; +        char                  gfid_str[64] = {0}; + +        priv = this->private; + +        unlink_path = alloca (strlen (priv->base_path) + 1 + +                              strlen (GF_UNLINK_PATH) + 1); +        sprintf (unlink_path, "%s/%s", priv->base_path, +                 GF_UNLINK_PATH); + +        gf_uuid_generate (gfid); +        uuid_utoa_r (gfid, gfid_str); + +        landfill_path = alloca (strlen (priv->base_path) + 1 + +                                strlen (GF_LANDFILL_PATH) + 1 + +                                strlen (gfid_str) + 1); +        sprintf (landfill_path, "%s/%s/%s", priv->base_path, +                 GF_LANDFILL_PATH, gfid_str); + +        ret = sys_stat (unlink_path, &stbuf); +        switch (ret) { +        case -1: +                if (errno != ENOENT) { +                        gf_msg (this->name, GF_LOG_ERROR, errno, +                                P_MSG_HANDLE_CREATE, +                                "Checking for %s failed", +                                unlink_path); +                        return -1; +                } +                break; +        case 0: +                if (!S_ISDIR (stbuf.st_mode)) { +                        gf_msg (this->name, GF_LOG_ERROR, 0, +                                P_MSG_HANDLE_CREATE, +                                "Not a directory: %s", +                                unlink_path); +                        return -1; +                } +                ret = sys_rename (unlink_path, landfill_path); +                if (ret) { +                        gf_msg (this->name, GF_LOG_ERROR, errno, +                                P_MSG_HANDLE_CREATE, +                                "Can not delete directory %s ", +                                unlink_path); +                        return -1; +                } +                break; +        default: +                break; +        } +        ret = sys_mkdir (unlink_path, 0600); +        if (ret) { +                gf_msg (this->name, GF_LOG_ERROR, errno, +                        P_MSG_HANDLE_CREATE, +                        "Creating directory %s failed", +                        unlink_path); +                return -1; +        } + +        return 0; +} + +  /**   * init - @@ -6587,6 +6756,15 @@ init (xlator_t *this)                  goto out;  	} +        op_ret = posix_create_unlink_dir (this); +        if (op_ret == -1) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        P_MSG_HANDLE_CREATE, +                        "Creation of unlink directory failed"); +                ret = -1; +                goto out; +        } +  	_private->aio_init_done = _gf_false;  	_private->aio_capable = _gf_false; diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 27006ff3beb..c48a77b4f0a 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -56,6 +56,8 @@                                                 + SLEN(GF_HIDDEN_PATH) + SLEN("/") \                                                 + SLEN("00/")            \                                                 + SLEN("00/") + SLEN(UUID0_STR) + 1) /* '\0' */; +#define GF_UNLINK_TRUE 0x0000000000000001 +#define GF_UNLINK_FALSE 0x0000000000000000  /**   * posix_fd - internal structure common to file and directory fd's @@ -184,14 +186,36 @@ typedef struct {          int32_t     op_errno;  } posix_xattr_filler_t; -  #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)  #define POSIX_BASE_PATH_LEN(this) (((struct posix_private *)this->private)->base_path_length)  #define POSIX_PATH_MAX(this) (((struct posix_private *)this->private)->path_max) +#define POSIX_GET_FILE_UNLINK_PATH(base_path, gfid, unlink_path)                           \ +        do {                                                                               \ +                int  path_len = 0;                                                         \ +                char gfid_str[64] = {0};                                                   \ +                uuid_utoa_r (gfid, gfid_str);                                              \ +                path_len = strlen (base_path) + 1 +                                        \ +                          strlen (GF_UNLINK_PATH) + 1 +                                    \ +                          strlen (gfid_str) + 1;                                           \ +                unlink_path = alloca (path_len);                                           \ +                if (!unlink_path) {                                                        \ +                        gf_msg ("posix", GF_LOG_ERROR, ENOMEM,                             \ +                                P_MSG_UNLINK_FAILED,                                       \ +                                "Failed to get unlink_path");                              \ +                        break;                                                             \ +                }                                                                          \ +                sprintf (unlink_path, "%s/%s/%s",                                          \ +                         base_path, GF_UNLINK_PATH, gfid_str);                             \ +         } while (0) + +  /* Helper functions */ +int posix_inode_ctx_get (inode_t *inode, xlator_t *this, uint64_t *ctx); +int posix_inode_ctx_set (inode_t *inode, xlator_t *this, uint64_t ctx); +  int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc,                      dict_t *xattr_req);  int posix_fdstat (xlator_t *this, int fd, struct iatt *stbuf_p);  | 
