diff options
| author | vmallika <vmallika@redhat.com> | 2016-02-10 06:39:22 +0530 | 
|---|---|---|
| committer | Rajesh Joseph <rjoseph@redhat.com> | 2016-03-10 02:43:24 -0800 | 
| commit | e0f71288d95469d7ae82473ef273c6ba43250a36 (patch) | |
| tree | 3ec70fe1e5d6ece778ff3175b55db7470231a5e7 /xlators | |
| parent | ecf6243bc435a00f3dd2495524cd6e48e2d56f72 (diff) | |
uss/gluster: generate gfid for snapshot files from snapname and gfid
If 'a' and 'b' are hardlinks, we need to generate a virtual
gfid for these files so that the inode number for 'a' and 'b'
are same.
Generate gfid as below:
gfid_of_a = MD5(snapname + back_end_gfid(a))
if '/dir1/a' and '/dir2/b' are hardlinks, then inode number should be
same for
all below files:
/mnt/.snaps/snap1/dir1/a
/mnt/.snaps/snap1/dir2/b
/mnt/dir1/.snaps/snap1/a
/mnt/dir2/.snaps/snap1/b
Change-Id: Ifda793455610e554f3f1e4cbb90d44c02cda4b0f
BUG: 1171703
Signed-off-by: vmallika <vmallika@redhat.com>
Reviewed-on: http://review.gluster.org/9255
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Diffstat (limited to 'xlators')
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 38ca7ae6342..dd2e891a849 100644 --- a/xlators/features/snapview-server/src/snapview-server-helpers.c +++ b/xlators/features/snapview-server/src/snapview-server-helpers.c @@ -330,6 +330,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 f209edd2e94..338d5bd2f75 100644 --- a/xlators/features/snapview-server/src/snapview-server.c +++ b/xlators/features/snapview-server/src/snapview-server.c @@ -256,9 +256,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;  } @@ -274,7 +288,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); @@ -298,6 +312,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 " @@ -309,7 +331,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); @@ -326,9 +348,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;  } @@ -807,9 +846,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; @@ -1153,9 +1193,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); @@ -1353,38 +1395,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 a682aeed33e..a12319fa9b2 100644 --- a/xlators/features/snapview-server/src/snapview-server.h +++ b/xlators/features/snapview-server/src/snapview-server.h @@ -100,6 +100,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, @@ -128,6 +139,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; @@ -189,6 +205,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  | 
