"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xlators/features/index/src/index.c" between
glusterfs-9.1.tar.gz and glusterfs-9.2.tar.gz

About: GlusterFS is a network/cluster filesystem. The storage server (or each in a cluster) runs glusterfsd and the clients use mount command or glusterfs client to mount the exported filesystem. Release series 9.x (latest version).

index.c  (glusterfs-9.1):index.c  (glusterfs-9.2)
skipping to change at line 14 skipping to change at line 14
This file is licensed to you under your choice of the GNU Lesser This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation. cases as published by the Free Software Foundation.
*/ */
#include "index.h" #include "index.h"
#include <glusterfs/options.h> #include <glusterfs/options.h>
#include "glusterfs3-xdr.h" #include "glusterfs3-xdr.h"
#include <glusterfs/syscall.h> #include <glusterfs/syscall.h>
#include <glusterfs/statedump.h>
#include <glusterfs/syncop.h> #include <glusterfs/syncop.h>
#include <glusterfs/common-utils.h> #include <glusterfs/common-utils.h>
#include "index-messages.h" #include "index-messages.h"
#include <ftw.h> #include <ftw.h>
#include <libgen.h> /* for dirname() */ #include <libgen.h> /* for dirname() */
#include <signal.h> #include <signal.h>
#define XATTROP_SUBDIR "xattrop" #define XATTROP_SUBDIR "xattrop"
#define DIRTY_SUBDIR "dirty" #define DIRTY_SUBDIR "dirty"
#define ENTRY_CHANGES_SUBDIR "entry-changes" #define ENTRY_CHANGES_SUBDIR "entry-changes"
skipping to change at line 425 skipping to change at line 426
*count = priv->pending_count; *count = priv->pending_count;
} }
UNLOCK(&priv->lock); UNLOCK(&priv->lock);
break; break;
default: default:
break; break;
} }
} }
static void static void
index_dec_link_count(index_priv_t *priv, index_xattrop_type_t type) index_update_link_count_cache(index_priv_t *priv, index_xattrop_type_t type,
int link_count_delta)
{ {
switch (type) { switch (type) {
case XATTROP: case XATTROP:
LOCK(&priv->lock); LOCK(&priv->lock);
{ {
priv->pending_count--; if (priv->pending_count >= 0) {
if (priv->pending_count == 0) if (link_count_delta == -1) {
priv->pending_count--; priv->pending_count--;
}
/*If this is the first xattrop, then pending_count needs to
* be updated for the next lstat/lookup with link-count
* xdata*/
if (priv->pending_count == 0) {
priv->pending_count--; /*Invalidate cache*/
}
}
} }
UNLOCK(&priv->lock); UNLOCK(&priv->lock);
break; break;
default: default:
break; break;
} }
} }
char * char *
index_get_subdir_from_type(index_xattrop_type_t type) index_get_subdir_from_type(index_xattrop_type_t type)
skipping to change at line 667 skipping to change at line 677
goto out; goto out;
} }
make_gfid_path(priv->index_basepath, subdir, gfid, gfid_path, make_gfid_path(priv->index_basepath, subdir, gfid, gfid_path,
sizeof(gfid_path)); sizeof(gfid_path));
ret = sys_stat(gfid_path, &st); ret = sys_stat(gfid_path, &st);
if (!ret) if (!ret)
goto out; goto out;
ret = index_link_to_base(this, gfid_path, subdir); ret = index_link_to_base(this, gfid_path, subdir);
if (ret == 0) {
index_update_link_count_cache(priv, type, 1);
}
out: out:
return ret; return ret;
} }
int int
index_del(xlator_t *this, uuid_t gfid, const char *subdir, int type) index_del(xlator_t *this, uuid_t gfid, const char *subdir, int type)
{ {
int32_t op_errno __attribute__((unused)) = 0; int32_t op_errno __attribute__((unused)) = 0;
index_priv_t *priv = NULL; index_priv_t *priv = NULL;
int ret = 0; int ret = 0;
skipping to change at line 720 skipping to change at line 733
if (ret && (errno != ENOENT)) { if (ret && (errno != ENOENT)) {
gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_DEL_FAILED, gf_msg(this->name, GF_LOG_ERROR, errno, INDEX_MSG_INDEX_DEL_FAILED,
"%s: failed to delete" "%s: failed to delete"
" from index", " from index",
gfid_path); gfid_path);
ret = -errno; ret = -errno;
goto out; goto out;
} }
index_dec_link_count(priv, type); /* If errno is ENOENT then ret won't be zero */
if (ret == 0) {
index_update_link_count_cache(priv, type, -1);
}
ret = 0; ret = 0;
out: out:
return ret; return ret;
} }
static gf_boolean_t static gf_boolean_t
_is_xattr_in_watchlist(dict_t *d, char *k, data_t *v, void *tmp) _is_xattr_in_watchlist(dict_t *d, char *k, data_t *v, void *tmp)
{ {
if (!strncmp(k, tmp, strlen(k))) if (!strncmp(k, tmp, strlen(k)))
return _gf_true; return _gf_true;
skipping to change at line 780 skipping to change at line 796
{ {
int idx = -1; int idx = -1;
int *zfilled = adata; int *zfilled = adata;
// zfilled array contains `state` for all types xattrs. // zfilled array contains `state` for all types xattrs.
// state : whether the gfid file of this file exists in // state : whether the gfid file of this file exists in
// corresponding xattr directory or not. // corresponding xattr directory or not.
idx = index_find_xattr_type(d, k, v); idx = index_find_xattr_type(d, k, v);
if (idx == -1) if (idx == -1)
return 0; return 0;
zfilled[idx] = 0;
/* If an xattr value is all-zero leave zfilled[idx] as -1 so that xattrop
* index add/del won't happen */
if (!memeqzero((const char *)v->data, v->len)) {
zfilled[idx] = 0;
}
return 0; return 0;
} }
static int static int
_check_key_is_zero_filled(dict_t *d, char *k, data_t *v, void *tmp) _check_key_is_zero_filled(dict_t *d, char *k, data_t *v, void *tmp)
{ {
int *zfilled = tmp; int *zfilled = tmp;
int idx = -1; int idx = -1;
idx = index_find_xattr_type(d, k, v); idx = index_find_xattr_type(d, k, v);
if (idx == -1) if (idx == -1)
return 0; return 0;
/* Along with checking that the value of a key is zero filled /* Along with checking that the value of a key is zero filled
* the key's corresponding index should be assigned * the key's corresponding index should be assigned
* appropriate value. * appropriate value.
* zfilled[idx] will be 0(false) if value not zero. * zfilled[idx] will be 0(false) if value not zero.
* will be 1(true) if value is zero. * will be 1(true) if value is zero.
*/ */
if (mem_0filled((const char *)v->data, v->len)) { if (!memeqzero((const char *)v->data, v->len)) {
zfilled[idx] = 0; zfilled[idx] = 0;
return 0; return 0;
} }
/* If zfilled[idx] was previously 0, it means at least /* If zfilled[idx] was previously 0, it means at least
* one xattr of its "kind" is non-zero. Keep its value * one xattr of its "kind" is non-zero. Keep its value
* the same. * the same.
*/ */
if (zfilled[idx]) if (zfilled[idx])
zfilled[idx] = 1; zfilled[idx] = 1;
skipping to change at line 1287 skipping to change at line 1308
index_local_t *local = NULL; index_local_t *local = NULL;
fop_xattrop_cbk_t x_cbk = NULL; fop_xattrop_cbk_t x_cbk = NULL;
local = frame->local; local = frame->local;
if (optype == GF_XATTROP_ADD_ARRAY) if (optype == GF_XATTROP_ADD_ARRAY)
x_cbk = index_xattrop_cbk; x_cbk = index_xattrop_cbk;
else else
x_cbk = index_xattrop64_cbk; x_cbk = index_xattrop64_cbk;
// In wind phase bring the gfid into index. This way if the brick crashes /* In wind phase bring the gfid into index. This way if the brick crashes
// just after posix performs xattrop before _cbk reaches index xlator * just after posix performs xattrop before _cbk reaches index xlator
// we will still have the gfid in index. * we will still have the gfid in index.
*/
memset(zfilled, -1, sizeof(zfilled)); memset(zfilled, -1, sizeof(zfilled));
/* Foreach xattr, set corresponding index of zfilled to 1 /* zfilled[index] = 0 implies the xattr's value is not zero filled
* zfilled[index] = 1 implies the xattr's value is zero filled * and should be added in its corresponding index subdir.
* and should be added in its corresponding subdir.
* *
* zfilled should be set to 1 only for those index that * zfilled should be set to 0 only for those index that
* exist in xattr variable. This is to distinguish * exist in xattr variable and xattr value non-zero. This is to distinguish
* between different types of volumes. * between different types of volumes.
* For e.g., if the check is not made, * For e.g., if the check is not made,
* zfilled[DIRTY] is set to 1 for EC volumes, * zfilled[DIRTY] is set to 0 for EC volumes,
* index file will be tried to create in indices/dirty dir * index file will be created in indices/dirty dir
* which doesn't exist for an EC volume. * which doesn't exist for an EC volume.
*/ */
ret = dict_foreach(xattr, index_fill_zero_array, zfilled); ret = dict_foreach(xattr, index_fill_zero_array, zfilled);
_index_action(this, local->inode, zfilled); _index_action(this, local->inode, zfilled);
if (xdata) if (xdata)
ret = index_entry_action(this, local->inode, xdata, ret = index_entry_action(this, local->inode, xdata,
GF_XATTROP_ENTRY_IN_KEY); GF_XATTROP_ENTRY_IN_KEY);
if (ret < 0) { if (ret < 0) {
x_cbk(frame, NULL, this, -1, -ret, NULL, NULL); x_cbk(frame, NULL, this, -1, -ret, NULL, NULL);
skipping to change at line 1964 skipping to change at line 1985
return 0; return 0;
} }
worker_enqueue(this, stub); worker_enqueue(this, stub);
return 0; return 0;
out: out:
STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this), STACK_WIND(frame, default_getxattr_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->getxattr, loc, name, xdata); FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
return 0; return 0;
} }
int64_t static int64_t
index_fetch_link_count(xlator_t *this, index_xattrop_type_t type) index_fetch_link_count(xlator_t *this, index_xattrop_type_t type)
{ {
index_priv_t *priv = this->private; index_priv_t *priv = this->private;
char *subdir = NULL; char *subdir = NULL;
struct stat lstatbuf = { struct stat lstatbuf = {
0, 0,
}; };
int ret = -1; int ret = -1;
int64_t count = -1; int64_t count = -1;
DIR *dirp = NULL; DIR *dirp = NULL;
skipping to change at line 2026 skipping to change at line 2047
count = lstatbuf.st_nlink - 1; count = lstatbuf.st_nlink - 1;
if (count == 0) if (count == 0)
continue; continue;
else else
break; break;
} }
} }
out: out:
if (dirp) if (dirp)
(void)sys_closedir(dirp); (void)sys_closedir(dirp);
return count; return count;
} }
dict_t * dict_t *
index_fill_link_count(xlator_t *this, dict_t *xdata) index_fill_link_count(xlator_t *this, dict_t *xdata)
{ {
int ret = -1; int ret = -1;
index_priv_t *priv = NULL; index_priv_t *priv = NULL;
int64_t count = -1; int64_t count = -1;
skipping to change at line 2137 skipping to change at line 2159
dict_unref(xdata); dict_unref(xdata);
return 0; return 0;
} }
int32_t int32_t
index_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata) index_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
{ {
int ret = -1; int ret = -1;
char *flag = NULL; char *flag = NULL;
ret = dict_get_str(xdata, "link-count", &flag); ret = dict_get_str_sizen(xdata, "link-count", &flag);
if ((ret == 0) && (strcmp(flag, GF_XATTROP_INDEX_COUNT) == 0)) { if ((ret == 0) && (strcmp(flag, GF_XATTROP_INDEX_COUNT) == 0)) {
STACK_WIND(frame, index_fstat_cbk, FIRST_CHILD(this), STACK_WIND(frame, index_fstat_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat, fd, xdata); FIRST_CHILD(this)->fops->fstat, fd, xdata);
} else { } else {
STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this), STACK_WIND(frame, default_fstat_cbk, FIRST_CHILD(this),
FIRST_CHILD(this)->fops->fstat, fd, xdata); FIRST_CHILD(this)->fops->fstat, fd, xdata);
} }
return 0; return 0;
} }
skipping to change at line 2314 skipping to change at line 2336
dict_unref(xattrs); dict_unref(xattrs);
GF_FREE(dup_watchlist); GF_FREE(dup_watchlist);
if (dummy) if (dummy)
data_unref(dummy); data_unref(dummy);
return ret; return ret;
} }
static int
index_priv_dump(xlator_t *this)
{
index_priv_t *priv = NULL;
char key_prefix[GF_DUMP_MAX_BUF_LEN];
priv = this->private;
snprintf(key_prefix, GF_DUMP_MAX_BUF_LEN, "%s.%s", this->type, this->name);
gf_proc_dump_add_section("%s", key_prefix);
gf_proc_dump_write("xattrop-pending-count", "%"PRId64, priv->pending_count);
return 0;
}
int32_t int32_t
mem_acct_init(xlator_t *this) mem_acct_init(xlator_t *this)
{ {
int ret = -1; int ret = -1;
ret = xlator_mem_acct_init(this, gf_index_mt_end + 1); ret = xlator_mem_acct_init(this, gf_index_mt_end + 1);
return ret; return ret;
} }
skipping to change at line 2644 skipping to change at line 2681
// interface functions follow // interface functions follow
.getxattr = index_getxattr, .getxattr = index_getxattr,
.lookup = index_lookup, .lookup = index_lookup,
.opendir = index_opendir, .opendir = index_opendir,
.readdir = index_readdir, .readdir = index_readdir,
.unlink = index_unlink, .unlink = index_unlink,
.rmdir = index_rmdir, .rmdir = index_rmdir,
.fstat = index_fstat, .fstat = index_fstat,
}; };
struct xlator_dumpops dumpops; struct xlator_dumpops dumpops = {
.priv = index_priv_dump,
};
struct xlator_cbks cbks = {.forget = index_forget, struct xlator_cbks cbks = {.forget = index_forget,
.release = index_release, .release = index_release,
.releasedir = index_releasedir}; .releasedir = index_releasedir};
struct volume_options options[] = { struct volume_options options[] = {
{.key = {"index-base"}, {.key = {"index-base"},
.type = GF_OPTION_TYPE_PATH, .type = GF_OPTION_TYPE_PATH,
.description = "path where the index files need to be stored", .description = "path where the index files need to be stored",
.default_value = "{{ brick.path }}/.glusterfs/indices"}, .default_value = "{{ brick.path }}/.glusterfs/indices"},
 End of changes. 16 change blocks. 
20 lines changed or deleted 59 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)