summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/basic/uss.t36
-rw-r--r--xlators/features/snapview-server/src/snapview-server.c20
-rw-r--r--xlators/features/snapview-server/src/snapview-server.h27
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;