diff options
| -rw-r--r-- | tests/basic/uss.t | 36 | ||||
| -rw-r--r-- | xlators/features/snapview-server/src/snapview-server.c | 20 | ||||
| -rw-r--r-- | xlators/features/snapview-server/src/snapview-server.h | 27 | 
3 files changed, 75 insertions, 8 deletions
diff --git a/tests/basic/uss.t b/tests/basic/uss.t index 04d4baf64a5..2ce78bb682b 100644 --- a/tests/basic/uss.t +++ b/tests/basic/uss.t @@ -274,4 +274,40 @@ function count_snaps  EXPECT_WITHIN 30 "5" count_snaps $M0; +# deletion of a snapshot and creation of a new snapshot with same name +# should not create problems. The data that was supposed to be present +# in the deleted snapshot need not be present in the new snapshot just +# because the name is same. Ex: +# 1) Create a file "aaa" +# 2) Create a snapshot snap6 +# 3) stat the file "aaa" in snap6 and it should succeed +# 4) delete the file "aaa" +# 5) Delete the snapshot snap6 +# 6) Create a snapshot snap6 +# 7) stat the file "aaa" in snap6 and it should fail now + +echo "aaa" > $M0/aaa; + +TEST $CLI snapshot create snap6 $V0 + +TEST ls $M0/.history; + +EXPECT_WITHIN 30 "6" count_snaps $M0; + +TEST stat $M0/.history/snap6/aaa + +TEST rm -f $M0/aaa; + +TEST $CLI snapshot delete snap6; + +TEST $CLI snapshot create snap6 $V0 + +TEST ls $M0/.history; + +EXPECT_WITHIN 30 "6" count_snaps $M0; + +TEST ls $M0/.history/snap6/; + +TEST ! stat $M0/.history/snap6/aaa; +  cleanup; diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c index a9c95850f3e..4bb8e3be8f3 100644 --- a/xlators/features/snapview-server/src/snapview-server.c +++ b/xlators/features/snapview-server/src/snapview-server.c @@ -254,7 +254,7 @@ svs_lookup_snapshot (xlator_t *this, loc_t *loc, struct iatt *buf,          iatt_from_stat (buf, &statbuf);          uuid_copy (buf->ia_gfid, gfid);          svs_fill_ino_from_gfid (buf); -        inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE; +        inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE;          inode_ctx->fs = fs;          inode_ctx->object = object;          memcpy (&inode_ctx->buf, buf, sizeof (*buf)); @@ -574,7 +574,8 @@ svs_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd,                  op_ret = 0;                  op_errno = 0;                  goto out; -        } else if (inode_ctx->type == SNAP_VIEW_VIRTUAL_INODE) { +        } +        else {                  SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,                                         op_errno, out); @@ -702,7 +703,8 @@ svs_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, const char *name,                  op_ret = -1;                  op_errno = EINVAL;                  goto out; -        } else if (inode_ctx->type == SNAP_VIEW_VIRTUAL_INODE) { +        } +        else {                  SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,                                         op_errno, out); @@ -832,8 +834,7 @@ svs_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,                  op_errno = EINVAL;                  goto out;          } - -        if (inode_ctx->type == SNAP_VIEW_VIRTUAL_INODE) { +        else {                  dict = dict_new ();                  if (!dict) {                          gf_log (this->name, GF_LOG_ERROR, "failed to " @@ -1270,16 +1271,17 @@ svs_readdirp_fill (xlator_t *this, inode_t *parent, svs_inode_t *parent_ctx,                          goto out;                  } -                inode_ctx->type = SNAP_VIEW_VIRTUAL_INODE;                  if (parent_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {                          buf.ia_type = IA_IFDIR;                          inode_ctx->buf = buf;                          entry->d_stat = buf; +                        inode_ctx->type = SNAP_VIEW_SNAPSHOT_INODE;                  } else {                          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;                  }          } @@ -1592,7 +1594,8 @@ svs_stat (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)          if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {                  svs_iatt_fill (loc->inode->gfid, &buf);                  op_ret = 0; -        } else if (inode_ctx->type == SNAP_VIEW_VIRTUAL_INODE) { +        } +        else {                  SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret,                                         op_errno, out); @@ -1655,7 +1658,8 @@ svs_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)          if (inode_ctx->type == SNAP_VIEW_ENTRY_POINT_INODE) {                  svs_iatt_fill (fd->inode->gfid, &buf);                  op_ret = 0; -        } else if (inode_ctx->type == SNAP_VIEW_VIRTUAL_INODE) { +        } +        else {                  sfd = svs_fd_ctx_get_or_new (this, fd);                  if (!sfd) {                          gf_log (this->name, GF_LOG_ERROR, "failed to get the " diff --git a/xlators/features/snapview-server/src/snapview-server.h b/xlators/features/snapview-server/src/snapview-server.h index 4b42aefcd98..47effb19758 100644 --- a/xlators/features/snapview-server/src/snapview-server.h +++ b/xlators/features/snapview-server/src/snapview-server.h @@ -53,11 +53,37 @@                  STACK_DESTROY (((call_frame_t *)_frame)->root);     \          } while (0) +#define SVS_CHECK_VALID_SNAPSHOT_HANDLE(fs, this)                       \ +        do {                                                            \ +                svs_private_t *_private = NULL;                         \ +                _private = this->private;                               \ +                int  i = 0;                                             \ +                gf_boolean_t found = _gf_false;                         \ +                LOCK (&_private->snaplist_lock);                        \ +                {                                                       \ +                        for (i = 0; i < _private->num_snaps; i++) {     \ +                                if (_private->dirents->fs && fs &&      \ +                                    _private->dirents->fs == fs) {      \ +                                        found = _gf_true;               \ +                                        break;                          \ +                                }                                       \ +                        }                                               \ +                }                                                       \ +                UNLOCK (&_private->snaplist_lock);                      \ +                                                                        \ +                if (!found)                                             \ +                        fs = NULL;                                      \ +        } while (0) +  #define SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, ret,   \                                 op_errno, label)                         \          do {                                                            \                  fs = inode_ctx->fs;                                     \                  object = inode_ctx->object;                             \ +                SVS_CHECK_VALID_SNAPSHOT_HANDLE (fs, this);             \ +                if (!fs)                                                \ +                        object = NULL;                                  \ +                                                                        \                  if (!fs || !object) {                                   \                          int32_t tmp = -1;                               \                          char    tmp_uuid[64];                           \ @@ -94,6 +120,7 @@ mgmt_get_snapinfo_cbk (struct rpc_req *req, struct iovec *iov,  typedef enum {          SNAP_VIEW_ENTRY_POINT_INODE = 0, +        SNAP_VIEW_SNAPSHOT_INODE,          SNAP_VIEW_VIRTUAL_INODE  } inode_type_t;  | 
