diff options
| author | M. Mohan Kumar <mohan@in.ibm.com> | 2012-11-29 21:46:05 +0530 | 
|---|---|---|
| committer | Vijay Bellur <vbellur@redhat.com> | 2012-11-29 09:35:43 -0800 | 
| commit | 2cc1fbf020798edee97d9f626a767ecec5deca69 (patch) | |
| tree | 2aebe94eae56668faa112f917ef763c267c8856a /xlators | |
| parent | ee968619cf936f0e25299beb1996abc27ed3dc72 (diff) | |
BD Backend: Open,read and related calls support for LV
BUG: 805138
Change-Id: I811c179d4244342537dbedb8a24fd2ec628942ed
Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com>
Reviewed-on: http://review.gluster.org/3552
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/storage/bd_map/src/bd_map.c | 271 | ||||
| -rw-r--r-- | xlators/storage/bd_map/src/bd_map.h | 1 | ||||
| -rw-r--r-- | xlators/storage/bd_map/src/bd_map_help.c | 19 | ||||
| -rw-r--r-- | xlators/storage/bd_map/src/bd_map_help.h | 5 | 
4 files changed, 296 insertions, 0 deletions
diff --git a/xlators/storage/bd_map/src/bd_map.c b/xlators/storage/bd_map/src/bd_map.c index e7a684c556d..29de9fc1d2d 100644 --- a/xlators/storage/bd_map/src/bd_map.c +++ b/xlators/storage/bd_map/src/bd_map.c @@ -34,6 +34,183 @@  /* Regular fops */ +int +bd_access (call_frame_t *frame, xlator_t *this, +                loc_t *loc, int32_t mask, dict_t *xdict) +{ +        int32_t   op_ret         = -1; +        int32_t   op_errno       = 0; +        char      path[PATH_MAX] = {0, }; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (loc, out); + +        sprintf (path, "/dev/mapper/%s", loc->path); +        op_ret = access (path, mask & 07); +        if (op_ret == -1) { +                op_errno = errno; +                gf_log (this->name, GF_LOG_ERROR, "access failed on %s: %s", +                                loc->path, strerror (op_errno)); +                goto out; +        } +        op_ret = 0; +out: +        STACK_UNWIND_STRICT (access, frame, op_ret, op_errno, NULL); + +        return 0; +} + +int32_t +bd_open (call_frame_t *frame, xlator_t *this, +                loc_t *loc, int32_t flags, fd_t *fd, dict_t *xdata) +{ +        int32_t         op_ret          = -1; +        int32_t         op_errno        = 0; +        int32_t         _fd             = -1; +        bd_fd_t         *bd_fd          = NULL; +        bd_entry_t      *lventry        = NULL; +        bd_priv_t       *priv           = NULL; +        char            *devpath        = NULL; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (this->private, out); +        VALIDATE_OR_GOTO (loc, out); +        VALIDATE_OR_GOTO (fd, out); + +        priv = this->private; +        VALIDATE_OR_GOTO (priv, out); + +        BD_ENTRY (priv, lventry, loc->path); +        if (!lventry) { +                op_errno = ENOENT; +                goto out; +        } + +        gf_asprintf (&devpath, "/dev/%s/%s", lventry->parent->name, +                      lventry->name); +        _fd = open (devpath, flags, 0); +        if (_fd == -1) { +                op_errno = errno; +                gf_log (this->name, GF_LOG_ERROR, +                                "open on %s: %s", devpath, strerror (op_errno)); +                goto out; +        } + +        bd_fd = GF_CALLOC (1, sizeof(*bd_fd), gf_bd_fd); +        if (!bd_fd) { +                op_errno = errno; +                goto out; +        } +        bd_fd->entry = lventry; +        bd_fd->fd = _fd; + +        op_ret = fd_ctx_set (fd, this, (uint64_t)(long)bd_fd); +        if (op_ret) { +                gf_log (this->name, GF_LOG_WARNING, +                                "failed to set the fd context path=%s fd=%p", +                                loc->name, fd); +                goto out; +        } + +        op_ret = 0; +out: +        if (op_ret == -1) { +                if (_fd != -1) +                        close (_fd); +                /* FIXME: Should we call fd_ctx_set with NULL? */ +                if (bd_fd) +                        GF_FREE (bd_fd); +                if (lventry) +                        BD_PUT_ENTRY (priv, lventry); +        } +        if (devpath) +                GF_FREE (devpath); + +        STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd, NULL); + +        return 0; +} + +int +bd_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, +                off_t offset, uint32_t flags, dict_t *xdata) +{ +        uint64_t        tmp_bd_fd  = 0; +        int32_t         op_ret     = -1; +        int32_t         op_errno   = 0; +        int             _fd        = -1; +        bd_priv_t       *priv      = NULL; +        struct iobuf    *iobuf     = NULL; +        struct iobref   *iobref    = NULL; +        struct iovec    vec        = {0, }; +        bd_fd_t         *bd_fd     = NULL; +        int             ret        = -1; +        struct iatt     stbuf      = {0, }; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); +        VALIDATE_OR_GOTO (this->private, out); + +        priv = this->private; +        VALIDATE_OR_GOTO (priv, out); + +        ret = fd_ctx_get (fd, this, &tmp_bd_fd); +        if (ret < 0) { +                op_errno = -EINVAL; +                gf_log (this->name, GF_LOG_WARNING, +                                "bd_fd is NULL from fd=%p", fd); +                goto out; +        } +        bd_fd = (bd_fd_t *)(long)tmp_bd_fd; +        if (!size) { +                op_errno = EINVAL; +                gf_log (this->name, GF_LOG_WARNING, "size=%"GF_PRI_SIZET, size); +                goto out; +        } +        iobuf = iobuf_get2 (this->ctx->iobuf_pool, size); +        if (!iobuf) { +                op_errno = ENOMEM; +                goto out; +        } +        _fd = bd_fd->fd; +        op_ret = pread (_fd, iobuf->ptr, size, offset); +        if (op_ret == -1) { +                op_errno = errno; +                gf_log (this->name, GF_LOG_ERROR, +                                "read failed on fd=%p: %s", fd, +                                strerror (op_errno)); +                goto out; +        } + +        vec.iov_base = iobuf->ptr; +        vec.iov_len = op_ret; + +        iobref = iobref_new (); +        iobref_add (iobref, iobuf); +        BD_ENTRY_UPDATE_ATIME (bd_fd->entry); + +        memcpy (&stbuf, bd_fd->entry->attr, sizeof(stbuf)); + +        /* Hack to notify higher layers of EOF. */ +        if (bd_fd->entry->size == 0) +                op_errno = ENOENT; +        else if ((offset + vec.iov_len) >= bd_fd->entry->size) +                op_errno = ENOENT; +        op_ret = vec.iov_len; +out: +        STACK_UNWIND_STRICT (readv, frame, op_ret, op_errno, +                        &vec, 1, &stbuf, iobref, NULL); + +        if (iobref) +                iobref_unref (iobref); +        if (iobuf) +                iobuf_unref (iobuf); +        return 0; +} +  int32_t  bd_lookup (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xattr_req)  { @@ -135,6 +312,39 @@ out:  }  int32_t +bd_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) +{ +        int            ret         = -1; +        int32_t        op_ret      = -1; +        int32_t        op_errno    = 0; +        uint64_t       tmp_bd_fd   = 0; +        struct iatt    buf         = {0, }; +        bd_fd_t        *bd_fd      = NULL; +        int            _fd         = -1; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); + +        ret = fd_ctx_get (fd, this, &tmp_bd_fd); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_WARNING, +                                "bd_fd is NULL, fd=%p", fd); +                op_errno = -EINVAL; +                goto out; +        } +        bd_fd = (bd_fd_t *)(long)tmp_bd_fd; +        _fd = bd_fd->fd; + +        memcpy (&buf, bd_fd->entry->attr, sizeof(buf)); +        op_ret = 0; + +out: +        STACK_UNWIND_STRICT (stat, frame, op_ret, op_errno, &buf, NULL); +        return 0; +} + +int32_t  bd_opendir (call_frame_t *frame, xlator_t *this,                 loc_t *loc, fd_t *fd, dict_t *xdata)  { @@ -290,6 +500,61 @@ out:          return 0;  } +int32_t +bd_release (xlator_t *this, fd_t *fd) +{ +        bd_fd_t      *bd_fd    = NULL; +        int          ret       = -1; +        uint64_t     tmp_bd_fd = 0; +        bd_priv_t    *priv     = NULL; + +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); + +        priv = this->private; +        VALIDATE_OR_GOTO (priv, out); + +        ret = fd_ctx_get (fd, this, &tmp_bd_fd); +        if (ret < 0) { +                gf_log (this->name, GF_LOG_WARNING, "bd_fd is NULL from fd=%p", +                                fd); +                goto out; +        } +        bd_fd = (bd_fd_t *) (long)tmp_bd_fd; +        close (bd_fd->fd); +        BD_PUT_ENTRY (priv, bd_fd->entry); + +        GF_FREE (bd_fd); +out: +        return 0; +} + +int32_t +bd_flush (call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdict) +{ +        int32_t     op_ret    = -1; +        int32_t     op_errno  = 0; +        int         ret       = -1; +        uint64_t    tmp_bd_fd = 0; + +        VALIDATE_OR_GOTO (frame, out); +        VALIDATE_OR_GOTO (this, out); +        VALIDATE_OR_GOTO (fd, out); + +        ret = fd_ctx_get (fd, this, &tmp_bd_fd); +        if (ret < 0) { +                op_errno = -EINVAL; +                gf_log (this->name, GF_LOG_WARNING, +                                "bd_fd is NULL on fd=%p", fd); +                goto out; +        } +        op_ret = 0; +out: +        STACK_UNWIND_STRICT (flush, frame, op_ret, op_errno, NULL); + +        return 0; +} +  int  __bd_fill_readdir (pthread_rwlock_t *bd_lock, bd_fd_t *bd_fd, off_t off,                  size_t size, gf_dirent_t *entries) @@ -881,10 +1146,16 @@ struct xlator_fops fops = {          .readdirp    = bd_readdirp,          .stat        = bd_stat,          .statfs      = bd_statfs, +        .open        = bd_open, +        .access      = bd_access, +        .flush       = bd_flush, +        .readv       = bd_readv, +        .fstat       = bd_fstat,  };  struct xlator_cbks cbks = {          .releasedir  = bd_releasedir, +        .release     = bd_release,  };  struct volume_options options[] = { diff --git a/xlators/storage/bd_map/src/bd_map.h b/xlators/storage/bd_map/src/bd_map.h index 974ec928899..936defbbb3a 100644 --- a/xlators/storage/bd_map/src/bd_map.h +++ b/xlators/storage/bd_map/src/bd_map.h @@ -64,6 +64,7 @@ typedef struct bd_entry {  typedef struct bd_fd {          bd_entry_t      *entry;          bd_entry_t      *p_entry; /* Parent entry */ +        int             fd;  } bd_fd_t;  typedef struct bd_priv { diff --git a/xlators/storage/bd_map/src/bd_map_help.c b/xlators/storage/bd_map/src/bd_map_help.c index 2b5c321f607..3576d705692 100644 --- a/xlators/storage/bd_map/src/bd_map_help.c +++ b/xlators/storage/bd_map/src/bd_map_help.c @@ -47,6 +47,25 @@ static void bd_entry_get_ino (uint64_t *inode)          UNLOCK (&inode_lk);  } +void bd_update_time (bd_entry_t *entry, int type) +{ +        struct timespec ts; + +        clock_gettime (CLOCK_REALTIME, &ts); +        if (type == 0) { +                entry->attr->ia_mtime = ts.tv_sec; +                entry->attr->ia_mtime_nsec = ts.tv_nsec; +                entry->attr->ia_atime = ts.tv_sec; +                entry->attr->ia_atime_nsec = ts.tv_nsec; +        } else if (type == 1) { +                entry->attr->ia_mtime = ts.tv_sec; +                entry->attr->ia_mtime_nsec = ts.tv_nsec; +        } else { +                entry->attr->ia_atime = ts.tv_sec; +                entry->attr->ia_atime_nsec = ts.tv_nsec; +        } +} +  static bd_entry_t *bd_entry_init (const char *name)  {          bd_entry_t *bdentry; diff --git a/xlators/storage/bd_map/src/bd_map_help.h b/xlators/storage/bd_map/src/bd_map_help.h index 997b8b7162e..46862f32847 100644 --- a/xlators/storage/bd_map/src/bd_map_help.h +++ b/xlators/storage/bd_map/src/bd_map_help.h @@ -47,6 +47,10 @@                  BD_UNLOCK (&priv->lock);        \          } while (0) +#define BD_ENTRY_UPDATE_TIME(bdentry)  bd_update_time (bdentry, 0) +#define BD_ENTRY_UPDATE_ATIME(bdentry) bd_update_time (bdentry, 2) +#define BD_ENTRY_UPDATE_MTIME(bdentry) bd_update_time (bdentry, 1) +  extern bd_entry_t *bd_rootp;  extern gf_lock_t inode_lk; @@ -59,5 +63,6 @@ bd_entry_t *bd_entry_get (const char *name);  void bd_entry_put (bd_entry_t *entry);  int bd_build_lv_list (bd_priv_t *priv, char *vg);  int bd_entry_cleanup (void); +void bd_update_time (bd_entry_t *entry, int type);  #endif  | 
