diff options
Diffstat (limited to 'xlators/features/snapview-server')
3 files changed, 122 insertions, 33 deletions
diff --git a/xlators/features/snapview-server/src/snapview-server-helpers.c b/xlators/features/snapview-server/src/snapview-server-helpers.c index 92ffdf512ef..0303f4d6df6 100644 --- a/xlators/features/snapview-server/src/snapview-server-helpers.c +++ b/xlators/features/snapview-server/src/snapview-server-helpers.c @@ -335,6 +335,21 @@ out:  }  void +svs_uuid_generate (uuid_t gfid, char *snapname, uuid_t origin_gfid) +{ +        unsigned char md5_sum[MD5_DIGEST_LENGTH] = {0}; +        char          ino_string[NAME_MAX + 32]  = ""; +        int           ret                        = 0; + +        GF_ASSERT (snapname); + +        ret = snprintf (ino_string, sizeof (ino_string), "%s%s", +                        snapname, uuid_utoa(origin_gfid)); +        MD5((unsigned char *)ino_string, strlen(ino_string), md5_sum); +        gf_uuid_copy (gfid, md5_sum); +} + +void  svs_fill_ino_from_gfid (struct iatt *buf)  {          uint64_t  temp_ino = 0; diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c index ed30cb8e09d..95e8d3ca5f4 100644 --- a/xlators/features/snapview-server/src/snapview-server.c +++ b/xlators/features/snapview-server/src/snapview-server.c @@ -261,9 +261,23 @@ svs_lookup_snapshot (xlator_t *this, loc_t *loc, struct iatt *buf,          memcpy (&inode_ctx->buf, buf, sizeof (*buf));          svs_iatt_fill (parent->gfid, postparent); +        SVS_STRDUP (inode_ctx->snapname, loc->name); +        if (!inode_ctx->snapname) { +                op_ret = -1; +                *op_errno = ENOMEM; +                goto out; +        }          op_ret = 0;  out: +        if (op_ret) { +                if (object) +                        glfs_h_close (object); + +                if (inode_ctx) +                        inode_ctx->object = NULL; +        } +          return op_ret;  } @@ -279,7 +293,7 @@ svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,          struct stat     statbuf                         = {0, };          svs_inode_t    *inode_ctx                       = NULL;          glfs_object_t  *parent_object                   = NULL; -        uuid_t          gfid; +        uuid_t          gfid                            = {0, };          GF_VALIDATE_OR_GOTO ("snapview-server", this, out);          GF_VALIDATE_OR_GOTO (this->name, loc, out); @@ -303,6 +317,14 @@ svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,                  goto out;          } +        if (gf_uuid_is_null(object->gfid)) { +                gf_log (this->name, GF_LOG_DEBUG, "gfid from glfs handle is " +                        "NULL for entry %s (path: %s)", loc->name, loc->path); +                op_ret = -1; +                *op_errno = errno; +                goto out; +        } +          inode_ctx = svs_inode_ctx_get_or_new (this, loc->inode);          if (!inode_ctx) {                  gf_log (this->name, GF_LOG_ERROR, "failed to " @@ -314,7 +336,7 @@ svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,          if (gf_uuid_is_null (loc->gfid) &&              gf_uuid_is_null (loc->inode->gfid)) -                gf_uuid_generate (gfid); +                svs_uuid_generate (gfid, parent_ctx->snapname, object->gfid);          else {                  if (!gf_uuid_is_null (loc->inode->gfid))                          gf_uuid_copy (gfid, loc->inode->gfid); @@ -331,9 +353,26 @@ svs_lookup_entry (xlator_t *this, loc_t *loc, struct iatt *buf,          memcpy (&inode_ctx->buf, buf, sizeof (*buf));          svs_iatt_fill (parent->gfid, postparent); +        if (IA_ISDIR (buf->ia_type)) { +                SVS_STRDUP (inode_ctx->snapname, parent_ctx->snapname); +                if (!inode_ctx->snapname) { +                        op_ret = -1; +                        *op_errno = ENOMEM; +                        goto out; +                } +        } +          op_ret = 0;  out: +        if (op_ret) { +                if (object) +                        glfs_h_close (object); + +                if (inode_ctx) +                        inode_ctx->object = NULL; +        } +          return op_ret;  } @@ -812,9 +851,10 @@ svs_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,                  size = glfs_h_getxattrs (fs, object, name, NULL, 0);                  if (size == -1) { -                        gf_log (this->name, GF_LOG_ERROR, "getxattr " -                                "on %s failed (key: %s)", loc->name, -                                name); +                        gf_log (this->name, +                                errno == ENODATA?GF_LOG_DEBUG:GF_LOG_ERROR, +                                "getxattr on %s failed (key: %s) with %s", +                                loc->path, name, strerror(errno));                          op_ret = -1;                          op_errno = errno;                          goto out; @@ -1158,9 +1198,11 @@ svs_forget  (xlator_t *this, inode_t *inode)          }          inode_ctx = (svs_inode_t *)value; +        if (!inode_ctx) +                goto out; -        if (inode_ctx->object) -                glfs_h_close (inode_ctx->object); +        if (inode_ctx->snapname) +                GF_FREE (inode_ctx->snapname);          GF_FREE (inode_ctx); @@ -1358,38 +1400,51 @@ svs_readdirp_fill (xlator_t *this, inode_t *parent, svs_inode_t *parent_ctx,                          gf_uuid_copy (entry->d_stat.ia_gfid, buf.ia_gfid);                  }          } else { -                inode = inode_new (parent->table); -                entry->inode = inode; -                gf_uuid_generate (random_gfid); -                gf_uuid_copy (buf.ia_gfid, random_gfid); -                svs_fill_ino_from_gfid (&buf); -                entry->d_ino = buf.ia_ino; - -                /* If inode context allocation fails, then do not send the -                   inode for that particular entry as part of readdirp -                   response. Fuse and protocol/server will link the inodes -                   in readdirp only if the entry contains inode in it. -                */ -                inode_ctx = svs_inode_ctx_get_or_new (this, inode); -                if (!inode_ctx) { -                        gf_log (this->name, GF_LOG_ERROR, "failed to allocate " -                                "inode context for %s", entry->d_name); -                        inode_unref (entry->inode); -                        entry->inode = NULL; -                        goto out; -                } -                  if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) { +                        inode = inode_new (parent->table); +                        entry->inode = inode; + +                        /* If inode context allocation fails, then do not send +                         * the inode for that particular entry as part of +                         * readdirp response. Fuse and protocol/server will link +                         * the inodes in readdirp only if the entry contains +                         * inode in it. +                         */ +                        inode_ctx = svs_inode_ctx_get_or_new (this, inode); +                        if (!inode_ctx) { +                                gf_log (this->name, GF_LOG_ERROR, "failed to " +                                        "allocate inode context for %s", +                                        entry->d_name); +                                inode_unref (entry->inode); +                                entry->inode = NULL; +                                goto out; +                        } + +                        /* Generate virtual gfid for SNAPSHOT dir and +                         * update the statbuf +                         */ +                        gf_uuid_generate (random_gfid); +                        gf_uuid_copy (buf.ia_gfid, random_gfid); +                        svs_fill_ino_from_gfid (&buf);                          buf.ia_type = IA_IFDIR; -                        inode_ctx->buf = buf; +                        entry->d_ino = buf.ia_ino;                          entry->d_stat = buf; +                        inode_ctx->buf = buf;                          inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE;                  } else { -                        gf_uuid_copy (entry->d_stat.ia_gfid, buf.ia_gfid); -                        entry->d_stat.ia_ino = buf.ia_ino; -                        inode_ctx->buf = entry->d_stat; -                        inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE; +                        /* For files under snapshot world do not set +                         * entry->inode and reset statbuf (except ia_ino), +                         * so that FUSE/Kernel will send an explicit lookup. +                         * entry->d_stat contains the statbuf information +                         * of original file, so for NFS not to cache this +                         * information and to send explicit lookup, it is +                         * required to reset the statbuf. +                         * Virtual gfid for these files will be generated in the +                         * first lookup. +                         */ +                        buf.ia_ino = entry->d_ino; +                        entry->d_stat = buf;                  }          } diff --git a/xlators/features/snapview-server/src/snapview-server.h b/xlators/features/snapview-server/src/snapview-server.h index c80d3456c30..f9249f9d828 100644 --- a/xlators/features/snapview-server/src/snapview-server.h +++ b/xlators/features/snapview-server/src/snapview-server.h @@ -105,6 +105,17 @@                  }                                                       \          } while(0); +#define SVS_STRDUP(dst, src)                                            \ +        do {                                                            \ +                if (dst && strcmp (src, dst)) {                         \ +                        GF_FREE (dst);                                  \ +                        dst = NULL;                                     \ +                }                                                       \ +                                                                        \ +                if (!dst)                                               \ +                        dst = gf_strdup (src);                          \ +        } while (0) +  int  svs_mgmt_submit_request (void *req, call_frame_t *frame,                           glusterfs_ctx_t *ctx, @@ -133,6 +144,11 @@ struct svs_inode {             from where the entry point was entered is saved.          */          uuid_t pargfid; + +        /* This is used to generate gfid for all sub files/dirs under this +         * snapshot +         */ +        char *snapname;          struct iatt buf;  };  typedef struct svs_inode svs_inode_t; @@ -194,6 +210,9 @@ svs_fd_t *  svs_fd_ctx_get_or_new (xlator_t *this, fd_t *fd);  void +svs_uuid_generate (uuid_t gfid, char *snapname, uuid_t origin_gfid); + +void  svs_fill_ino_from_gfid (struct iatt *buf);  void  | 
