summaryrefslogtreecommitdiffstats
path: root/xlators/storage
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage')
-rw-r--r--xlators/storage/bd_map/src/bd_map.c271
-rw-r--r--xlators/storage/bd_map/src/bd_map.h1
-rw-r--r--xlators/storage/bd_map/src/bd_map_help.c19
-rw-r--r--xlators/storage/bd_map/src/bd_map_help.h5
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 e7a684c5..29de9fc1 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 974ec928..936defbb 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 2b5c321f..3576d705 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 997b8b71..46862f32 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