diff options
| -rw-r--r-- | xlators/features/snapview-client/src/snapview-client.c | 59 | ||||
| -rw-r--r-- | xlators/features/snapview-server/src/snapview-server.c | 53 | 
2 files changed, 112 insertions, 0 deletions
diff --git a/xlators/features/snapview-client/src/snapview-client.c b/xlators/features/snapview-client/src/snapview-client.c index 8351922af24..2f304aa7d3f 100644 --- a/xlators/features/snapview-client/src/snapview-client.c +++ b/xlators/features/snapview-client/src/snapview-client.c @@ -498,6 +498,64 @@ out:          return 0;  } +int32_t +svc_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, +            dict_t *xdata) +{ +        xlator_t      *subvolume  = NULL; +        int32_t        ret        = -1; +        int            inode_type = -1; +        int32_t        op_ret     = -1; +        int32_t        op_errno   = EINVAL; +        gf_boolean_t   wind       = _gf_false; +        svc_private_t  *priv      = NULL; +        const char     *path      = NULL; +        int             path_len  = -1; +        int             snap_len  = -1; +        loc_t           root_loc  = {0,}; +        loc_t          *temp_loc  = NULL; + +        GF_VALIDATE_OR_GOTO ("svc", this, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        GF_VALIDATE_OR_GOTO (this->name, loc, out); +        GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + +        priv = this->private; +        SVC_GET_SUBVOL_FROM_CTX (this, op_ret, op_errno, inode_type, ret, +                                 loc->inode, subvolume, out); +        path_len = strlen (loc->path); +        snap_len = strlen (priv->path); +        temp_loc = loc; + +        if (path_len >= snap_len && inode_type == VIRTUAL_INODE) { +                path = &loc->path[path_len - snap_len]; +                if (!strcmp (path, priv->path)) { +                        /* +                         * statfs call for virtual snap directory. +                         * Sent the fops to parent volume by removing +                         * virtual directory from path +                         */ +                        subvolume = FIRST_CHILD (this); +                        root_loc.path = "/"; +                        gf_uuid_clear(root_loc.gfid); +                        root_loc.gfid[15] = 1; +                        root_loc.inode = loc->inode->table->root; +                        root_loc.inode->ia_type = IA_IFDIR; +                        temp_loc = &root_loc; +                } +        } + +        STACK_WIND_TAIL (frame, subvolume, subvolume->fops->statfs, +                         temp_loc, xdata); + +        wind = _gf_true; +out: +        if (!wind) +                SVC_STACK_UNWIND (statfs, frame, op_ret, op_errno, +                                  NULL, NULL); +        return 0; +} +  /* should all the fops be handled like lookup is supposed to be     handled? i.e just based on inode type decide where the call should     be sent and in the call back update the contexts. @@ -2303,6 +2361,7 @@ struct xlator_fops fops = {          .opendir       = svc_opendir,          .stat          = svc_stat,          .fstat         = svc_fstat, +        .statfs        = svc_statfs,          .rmdir         = svc_rmdir,          .rename        = svc_rename,          .mkdir         = svc_mkdir, diff --git a/xlators/features/snapview-server/src/snapview-server.c b/xlators/features/snapview-server/src/snapview-server.c index 035dd54d1f9..3415ce0d671 100644 --- a/xlators/features/snapview-server/src/snapview-server.c +++ b/xlators/features/snapview-server/src/snapview-server.c @@ -1800,6 +1800,58 @@ out:  }  int32_t +svs_statfs (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ +        svs_private_t *priv         = NULL; +        struct statvfs buf          = {0, }; +        int32_t        op_errno     = EINVAL; +        int32_t        op_ret       = -1; +        svs_inode_t   *inode_ctx    = NULL; +        glfs_t        *fs           = NULL; +        glfs_object_t *object       = NULL; +        int            ret          = -1; + +        GF_VALIDATE_OR_GOTO ("snap-view-daemon", this, out); +        GF_VALIDATE_OR_GOTO (this->name, frame, out); +        GF_VALIDATE_OR_GOTO (this->name, loc, out); +        GF_VALIDATE_OR_GOTO (this->name, loc->inode, out); + +        priv = this->private; + +        /* Instead of doing the check of whether it is a entry point directory +           or not by checking the name of the entry and then deciding what +           to do, just check the inode context and decide what to be done. +        */ +        inode_ctx = svs_inode_ctx_get (this, loc->inode); +        if (!inode_ctx) { +                gf_log (this->name, GF_LOG_ERROR, "inode context not found for" +                        " %s", uuid_utoa (loc->inode->gfid)); +                op_ret = -1; +                op_errno = EINVAL; +                goto out; +        } + +        SVS_GET_INODE_CTX_INFO(inode_ctx, fs, object, this, loc, op_ret, +                               op_errno, out); + +        ret = glfs_h_statfs (fs, object, &buf); +        if (ret) { +                gf_log (this->name, GF_LOG_ERROR, "glfs_h_statvfs on %s " +                        "(gfid: %s) failed", loc->name, +                        uuid_utoa (loc->inode->gfid)); +                op_ret = -1; +                op_errno = errno; +                goto out; +        } +        op_ret = ret; + +out: +        STACK_UNWIND_STRICT (statfs, frame, op_ret, op_errno, &buf, xdata); +        return 0; +} + + +int32_t  svs_open (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,            fd_t *fd, dict_t *xdata)  { @@ -2218,6 +2270,7 @@ fini (xlator_t *this)  struct xlator_fops fops = {          .lookup     = svs_lookup,          .stat       = svs_stat, +        .statfs     = svs_statfs,          .opendir    = svs_opendir,          .readdirp   = svs_readdirp,          .readdir    = svs_readdir,  | 
