summaryrefslogtreecommitdiffstats
path: root/xlators/features/snapview-server
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2014-10-09 17:32:48 +0530
committerVijay Bellur <vbellur@redhat.com>2014-10-28 00:08:10 -0700
commit1fa3e87db77bb379173723a5e75b361a8e192f09 (patch)
tree0001e771a1693a078680ead5ebd1cf053d349872 /xlators/features/snapview-server
parent2855dff243f20a78cd8cc4e7cd581a9c558b2e69 (diff)
features/snapview-server: check if the reference to the snapshot world is
correct before doing any fop The following operations might lead to problems: * Create a file on the glusterfs mount point * Create a snapshot (say "snap1") * Access the contents of the snapshot * Delete the file from the mount point * Delete the snapshot "snap1" * Create a new snapshot "snap1" Now accessing the new snapshot "snap1" gives problems. Because the inode and dentry created for snap1 would not be deleted upon the deletion of the snapshot (as deletion of snapshot is a gluster cli operation, not a fop). So next time upon creation of a new snap with same name, the previous inode and dentry itself will be used. But the inode context contains old information about the glfs_t instance and the handle in the gfapi world. Directly accessing them without proper check leads to ENOTCONN errors. Thus the glfs_t instance should be checked before accessing. If its wrong, then right instance should be obtained by doing the lookup. Change-Id: Idca0c8015ff632447cea206a4807d8ef968424fa BUG: 1151004 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/8917 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/features/snapview-server')
-rw-r--r--xlators/features/snapview-server/src/snapview-server.c20
-rw-r--r--xlators/features/snapview-server/src/snapview-server.h27
2 files changed, 39 insertions, 8 deletions
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;