summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/basic/open-fd-snap-delete.t74
-rw-r--r--xlators/features/snapview-server/src/snapview-server-helpers.c35
-rw-r--r--xlators/features/snapview-server/src/snapview-server.c109
-rw-r--r--xlators/features/snapview-server/src/snapview-server.h6
4 files changed, 194 insertions, 30 deletions
diff --git a/tests/basic/open-fd-snap-delete.t b/tests/basic/open-fd-snap-delete.t
new file mode 100644
index 00000000000..a9f47cac19d
--- /dev/null
+++ b/tests/basic/open-fd-snap-delete.t
@@ -0,0 +1,74 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+. $(dirname $0)/../snapshot.rc
+. $(dirname $0)/../fileio.rc
+
+cleanup;
+
+TEST init_n_bricks 3;
+TEST setup_lvm 3;
+
+# start glusterd
+TEST glusterd;
+
+TEST pidof glusterd;
+
+TEST $CLI volume create $V0 $H0:$L1 $H0:$L2 $H0:$L3;
+TEST $CLI volume set $V0 nfs.disable false
+
+
+TEST $CLI volume start $V0;
+
+TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0;
+
+for i in {1..10} ; do echo "file" > $M0/file$i ; done
+
+# Create file and directory
+TEST touch $M0/f1
+TEST mkdir $M0/dir
+
+TEST $CLI snapshot config activate-on-create enable
+TEST $CLI volume set $V0 features.uss enable;
+
+for i in {1..10} ; do echo "file" > $M0/dir/file$i ; done
+
+TEST $CLI snapshot create snap1 $V0 no-timestamp;
+
+for i in {11..20} ; do echo "file" > $M0/file$i ; done
+for i in {11..20} ; do echo "file" > $M0/dir/file$i ; done
+
+TEST $CLI snapshot create snap2 $V0 no-timestamp;
+
+TEST fd1=`fd_available`
+TEST fd_open $fd1 'r' $M0/.snaps/snap2/dir/file11;
+TEST fd_cat $fd1
+
+TEST $CLI snapshot delete snap2;
+
+TEST ! fd_cat $fd1;
+
+# the return value of this command (i.e. fd_close) depetends
+# mainly on how the release operation on a file descriptor is
+# handled in snapview-server process. As of now snapview-server
+# returns 0 for the release operation. And it is similar to how
+# posix xlator does. So, as of now the expectation is to receive
+# success for the close operation.
+TEST fd_close $fd1;
+
+# This check is mainly to ensure that the snapshot daemon
+# (snapd) is up and running. If it is not running, the following
+# stat would receive ENOTCONN.
+
+TEST stat $M0/.snaps/snap1/dir/file1
+
+TEST $CLI snapshot delete snap1;
+
+TEST rm -rf $M0/*;
+
+TEST $CLI volume stop $V0;
+
+TEST $CLI volume delete $V0;
+
+cleanup
diff --git a/xlators/features/snapview-server/src/snapview-server-helpers.c b/xlators/features/snapview-server/src/snapview-server-helpers.c
index 6f305dbc2fb..091feb59180 100644
--- a/xlators/features/snapview-server/src/snapview-server-helpers.c
+++ b/xlators/features/snapview-server/src/snapview-server-helpers.c
@@ -595,3 +595,38 @@ svs_get_latest_snapshot (xlator_t *this)
out:
return fs;
}
+
+glfs_t *
+svs_inode_ctx_glfs_mapping (xlator_t *this, svs_inode_t *inode_ctx)
+{
+ glfs_t *fs = NULL;
+
+ GF_VALIDATE_OR_GOTO ("svs", this, out);
+ GF_VALIDATE_OR_GOTO (this->name, inode_ctx, out);
+
+ fs = inode_ctx->fs;
+
+ SVS_CHECK_VALID_SNAPSHOT_HANDLE (fs, this);
+
+out:
+ return fs;
+}
+
+glfs_t *
+svs_inode_glfs_mapping (xlator_t *this, inode_t *inode)
+{
+ svs_inode_t *inode_ctx = NULL;
+ glfs_t *fs = NULL;
+
+ inode_ctx = svs_inode_ctx_get (this, inode);
+ if (!inode_ctx) {
+ gf_log (this->name, GF_LOG_ERROR, "inode context not found for"
+ " the inode %s", uuid_utoa (inode->gfid));
+ goto out;
+ }
+
+ fs = svs_inode_ctx_glfs_mapping (this, inode_ctx);
+
+out:
+ return fs;
+}
diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c
index 9e109e213c9..ed56937aa7c 100644
--- a/xlators/features/snapview-server/src/snapview-server.c
+++ b/xlators/features/snapview-server/src/snapview-server.c
@@ -543,7 +543,6 @@ svs_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
svs_inode_t *parent_ctx = NULL;
int32_t ret = -1;
inode_t *parent = NULL;
- snap_dirent_t *dirent = NULL;
gf_boolean_t entry_point_key = _gf_false;
gf_boolean_t entry_point = _gf_false;
call_stack_t *root = NULL;
@@ -592,13 +591,6 @@ svs_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
inode_ctx = svs_inode_ctx_get (this, loc->inode);
- /* Initialize latest snapshot, which is used for nameless lookups */
- dirent = svs_get_latest_snap_entry (this);
-
- if (dirent && !dirent->fs) {
- svs_initialise_snapshot_volume (this, dirent->name, NULL);
- }
-
if (xdata && !inode_ctx) {
ret = dict_get_str_boolean (xdata, "entry-point", _gf_false);
if (ret == -1) {
@@ -996,6 +988,17 @@ svs_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, const char *name,
goto out;
}
+ if (!(svs_inode_ctx_glfs_mapping (this, inode_ctx))) {
+ gf_log (this->name, GF_LOG_ERROR, "glfs instance "
+ "instance %p to which the inode %s belongs"
+ "to does not exist. That snapshot might have"
+ "been deleted or deactivated", inode_ctx->fs,
+ uuid_utoa (fd->inode->gfid));
+ op_ret = -1;
+ op_errno = EBADF;
+ goto out;
+ }
+
sfd = svs_fd_ctx_get_or_new (this, fd);
if (!sfd) {
gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
@@ -1130,9 +1133,12 @@ out:
int32_t
svs_releasedir (xlator_t *this, fd_t *fd)
{
- svs_fd_t *sfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = 0;
+ svs_fd_t *sfd = NULL;
+ uint64_t tmp_pfd = 0;
+ int ret = 0;
+ svs_inode_t *svs_inode = NULL;
+ glfs_t *fs = NULL;
+ inode_t *inode = NULL;
GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
GF_VALIDATE_OR_GOTO (this->name, fd, out);
@@ -1144,13 +1150,24 @@ svs_releasedir (xlator_t *this, fd_t *fd)
goto out;
}
- sfd = (svs_fd_t *)(long)tmp_pfd;
- if (sfd->fd) {
- ret = glfs_closedir (sfd->fd);
- if (ret)
- gf_log (this->name, GF_LOG_WARNING, "failed to close "
- "the glfd for directory %s",
- uuid_utoa (fd->inode->gfid));
+
+ inode = fd->inode;
+
+ svs_inode = svs_inode_ctx_get (this, inode);
+ if (svs_inode) {
+ fs = svs_inode->fs; /* should inode->lock be held for this? */
+ SVS_CHECK_VALID_SNAPSHOT_HANDLE (fs, this);
+ if (fs) {
+ sfd = (svs_fd_t *)(long)tmp_pfd;
+ if (sfd->fd) {
+ ret = glfs_closedir (sfd->fd);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to close the glfd"
+ "for directory %s",
+ uuid_utoa (fd->inode->gfid));
+ }
+ }
}
GF_FREE (sfd);
@@ -1209,9 +1226,12 @@ out:
int32_t
svs_release (xlator_t *this, fd_t *fd)
{
- svs_fd_t *sfd = NULL;
- uint64_t tmp_pfd = 0;
- int ret = 0;
+ svs_fd_t *sfd = NULL;
+ uint64_t tmp_pfd = 0;
+ int ret = 0;
+ inode_t *inode = NULL;
+ svs_inode_t *svs_inode = NULL;
+ glfs_t *fs = NULL;
GF_VALIDATE_OR_GOTO ("snapview-server", this, out);
GF_VALIDATE_OR_GOTO (this->name, fd, out);
@@ -1223,13 +1243,22 @@ svs_release (xlator_t *this, fd_t *fd)
goto out;
}
- sfd = (svs_fd_t *)(long)tmp_pfd;
- if (sfd->fd) {
- ret = glfs_close (sfd->fd);
- if (ret) {
- gf_log (this->name, GF_LOG_ERROR, "failed to close "
- "the glfd for %s",
- uuid_utoa (fd->inode->gfid));
+ inode = fd->inode;
+
+ svs_inode = svs_inode_ctx_get (this, inode);
+ if (svs_inode) {
+ fs = svs_inode->fs; /* should inode->lock be held for this? */
+ SVS_CHECK_VALID_SNAPSHOT_HANDLE (fs, this);
+ if (fs) {
+ sfd = (svs_fd_t *)(long)tmp_pfd;
+ if (sfd->fd) {
+ ret = glfs_close (sfd->fd);
+ if (ret)
+ gf_log (this->name, GF_LOG_ERROR,
+ "failed to close "
+ "the glfd for %s",
+ uuid_utoa (fd->inode->gfid));
+ }
}
}
@@ -1893,8 +1922,18 @@ 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 {
+ } else {
+ if (!(svs_inode_ctx_glfs_mapping (this, inode_ctx))) {
+ gf_log (this->name, GF_LOG_ERROR, "glfs instance "
+ "instance %p to which the inode %s belongs "
+ "to does not exist. That snapshot might have "
+ "been deleted or deactivated", inode_ctx->fs,
+ uuid_utoa (fd->inode->gfid));
+ op_ret = -1;
+ op_errno = EBADF;
+ goto out;
+ }
+
sfd = svs_fd_ctx_get_or_new (this, fd);
if (!sfd) {
gf_log (this->name, GF_LOG_ERROR, "failed to get the "
@@ -2084,6 +2123,16 @@ svs_readv (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (!svs_inode_glfs_mapping (this, fd->inode)) {
+ gf_log (this->name, GF_LOG_ERROR, "glfs instance to "
+ "which the inode %s receiving read request belongs, "
+ "does not exist anymore",
+ uuid_utoa (fd->inode->gfid));
+ op_ret = -1;
+ op_errno = EBADF; /* should this be some other error? */
+ goto out;
+ }
+
sfd = svs_fd_ctx_get_or_new (this, fd);
if (!sfd) {
gf_log (this->name, GF_LOG_ERROR, "failed to get the fd "
diff --git a/xlators/features/snapview-server/src/snapview-server.h b/xlators/features/snapview-server/src/snapview-server.h
index bacb6275607..a805c7435bd 100644
--- a/xlators/features/snapview-server/src/snapview-server.h
+++ b/xlators/features/snapview-server/src/snapview-server.h
@@ -242,4 +242,10 @@ int32_t
svs_get_handle (xlator_t *this, loc_t *loc, svs_inode_t *inode_ctx,
int32_t *op_errno);
+glfs_t *
+svs_inode_glfs_mapping (xlator_t *this, inode_t *inode);
+
+glfs_t *
+svs_inode_ctx_glfs_mapping (xlator_t *this, svs_inode_t *inode_ctx);
+
#endif /* __SNAP_VIEW_H__ */