summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix.c')
-rw-r--r--xlators/storage/posix/src/posix.c249
1 files changed, 186 insertions, 63 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index e63ca8d4..635d5f01 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -102,11 +102,16 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
char * par_path = NULL;
struct iatt postparent = {0,};
int32_t gfidless = 0;
+ char *pgfid_xattr_key = NULL;
+ struct posix_private *priv = NULL;
+ int32_t nlink_samepgfid = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
+ priv = this->private;
+
/* The Hidden directory should be for housekeeping purpose and it
should not get any gfid on it */
if (__is_root_gfid (loc->pargfid) && loc->name
@@ -152,6 +157,29 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
xdata, &buf);
}
+ if (priv->update_pgfid_nlinks && !uuid_is_null (loc->pargfid) &&
+ !IA_ISDIR (buf.ia_type)) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
+ PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+
+ LOCK (&loc->inode->lock);
+ {
+ nlink_samepgfid = 1;
+ /**
+ * This is in case where quota/update_nlinks enabled
+ * on a preexisting data. We're setting the the pgfid
+ * to '1' to continue with the normal pgfid xattr
+ * building as we don't know the exact no of hardlinks.
+ */
+ SET_PGFID_XATTR_IF_ABSENT (real_path, pgfid_xattr_key,
+ nlink_samepgfid,
+ XATTR_CREATE, op_ret,
+ this, unlock);
+ }
+ unlock:
+ UNLOCK (&loc->inode->lock);
+ }
parent:
if (par_path) {
op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
@@ -628,7 +656,7 @@ _posix_fallocate(call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t keep_siz
ret = posix_do_fallocate(frame, this, fd, flags, offset, len,
&statpre, &statpost);
- if (ret < 0)
+ if (ret < 0)
goto err;
STACK_UNWIND_STRICT(fallocate, frame, 0, 0, &statpre, &statpost, NULL);
@@ -650,7 +678,7 @@ posix_discard(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
ret = posix_do_fallocate(frame, this, fd, flags, offset, len,
&statpre, &statpost);
- if (ret < 0)
+ if (ret < 0)
goto err;
STACK_UNWIND_STRICT(discard, frame, 0, 0, &statpre, &statpost, NULL);
@@ -844,6 +872,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
mode_t st_mode = 0;
int32_t nlink_samepgfid = 0;
char *pgfid_xattr_key = NULL;
+ gf_boolean_t internal_fop = _gf_false;
DECLARE_OLD_FS_ID_VAR;
@@ -877,6 +906,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
internal call from distribute for creating 'linkfile', and that
linkfile may be for a hardlinked file */
if (dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
+ internal_fop = _gf_true;
dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY);
op_ret = dict_get_ptr (xdata, "gfid-req", &uuid_req);
if (op_ret) {
@@ -959,12 +989,27 @@ post_op:
strerror (errno));
}
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
-
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
+ /* If the mknod is due to distribute as an internal fop, then
+ the PGFID_XATTR is not needed, as the linkfile is used to
+ only get the actual subvolume of the file. Otherwise it is
+ difficult to keep the PGFID_XATTR of both the linkfile and
+ the original file in sync. Imagine this set of operations.
+ inode1: a, b are the links present in the same parent p1
+ Now, for the inode of a and b (inode1), pgfid.<p1> will be
+ set to 2. Now when b gets renamed to c which gets hashed to
+ a different subvolume, then mknod is called on the subvolume2
+ to create the linkfile. On that subvolume, posix_mknod will set
+ the PGFID_XATTR to 1 (which is not right).
+ */
+ if (!internal_fop && priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
+ PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ nlink_samepgfid = 1;
+ SET_PGFID_XATTR (real_path, pgfid_xattr_key,
+ nlink_samepgfid, XATTR_CREATE, op_ret,
+ this, ignore);
+ }
ignore:
op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
if (op_ret) {
@@ -1147,17 +1192,19 @@ int32_t
posix_unlink (call_frame_t *frame, xlator_t *this,
loc_t *loc, int xflag, dict_t *xdata)
{
- int32_t op_ret = -1;
- int32_t op_errno = 0;
- char *real_path = NULL;
- char *par_path = NULL;
- int32_t fd = -1;
- struct iatt stbuf = {0,};
- struct posix_private *priv = NULL;
- struct iatt preparent = {0,};
- struct iatt postparent = {0,};
- char *pgfid_xattr_key = NULL;
- int32_t nlink_samepgfid = 0;
+ int32_t op_ret = -1;
+ int32_t op_errno = 0;
+ char *real_path = NULL;
+ char *par_path = NULL;
+ int32_t fd = -1;
+ struct iatt stbuf = {0,};
+ struct posix_private *priv = NULL;
+ struct iatt preparent = {0,};
+ struct iatt postparent = {0,};
+ char *pgfid_xattr_key = NULL;
+ int32_t nlink_samepgfid = 0;
+ gf_boolean_t internal_fop = _gf_false;
+ gf_boolean_t update_pgfid_xattr = _gf_false;
DECLARE_OLD_FS_ID_VAR;
@@ -1195,13 +1242,21 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
}
}
- if (stbuf.ia_nlink > 1) {
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ internal_fop = (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY));
+ update_pgfid_xattr = (priv->update_pgfid_nlinks &&
+ stbuf.ia_nlink > 1 &&
+ !internal_fop);
+
+ if (update_pgfid_xattr) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
+ PGFID_XATTR_KEY_PREFIX,
loc->pargfid);
LOCK (&loc->inode->lock);
{
- UNLINK_MODIFY_PGFID_XATTR (real_path, pgfid_xattr_key,
- nlink_samepgfid, 0, op_ret,
+ UNLINK_MODIFY_PGFID_XATTR (real_path,
+ pgfid_xattr_key,
+ nlink_samepgfid, 0,
+ op_ret,
this, unlock);
}
unlock:
@@ -1221,6 +1276,30 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
gf_log (this->name, GF_LOG_ERROR,
"unlink of %s failed: %s", real_path,
strerror (op_errno));
+
+ if (update_pgfid_xattr) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
+ PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ LOCK (&loc->inode->lock);
+ {
+ LINK_MODIFY_PGFID_XATTR (real_path,
+ pgfid_xattr_key,
+ nlink_samepgfid,
+ 0, op_ret,
+ this, nolock);
+ }
+ nolock:
+ UNLOCK (&loc->inode->lock);
+
+ if (op_ret < 0)
+ gf_log (this->name, GF_LOG_WARNING,
+ "modification of parent gfid xattr "
+ "failed (path:%s gfid:%s)",
+ real_path,
+ uuid_utoa (loc->inode->gfid));
+ }
+
goto out;
}
@@ -1435,11 +1514,13 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
strerror (errno));
}
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ nlink_samepgfid = 1;
+ SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
+ XATTR_CREATE, op_ret, this, ignore);
+ }
ignore:
op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
if (op_ret) {
@@ -1507,6 +1588,8 @@ posix_rename (call_frame_t *frame, xlator_t *this,
int nlink = 0;
char *pgfid_xattr_key = NULL;
int32_t nlink_samepgfid = 0;
+ gf_boolean_t link_file = _gf_false;
+ gf_boolean_t update_pgfid_xattr = _gf_false;
DECLARE_OLD_FS_ID_VAR;
@@ -1574,17 +1657,24 @@ posix_rename (call_frame_t *frame, xlator_t *this,
if (IA_ISDIR (oldloc->inode->ia_type))
posix_handle_unset (this, oldloc->inode->gfid, NULL);
+ if (xdata && dict_get (xdata, GLUSTERFS_INTERNAL_FOP_KEY)) {
+ link_file = _gf_true;
+ dict_del (xdata, GLUSTERFS_INTERNAL_FOP_KEY);
+ }
+
LOCK (&oldloc->inode->lock);
{
- if (!IA_ISDIR (oldloc->inode->ia_type)) {
+ update_pgfid_xattr = (priv->update_pgfid_nlinks &&
+ !IA_ISDIR (oldloc->inode->ia_type) &&
+ !link_file);
+ if (update_pgfid_xattr) {
MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
PGFID_XATTR_KEY_PREFIX,
oldloc->pargfid);
UNLINK_MODIFY_PGFID_XATTR (real_oldpath,
pgfid_xattr_key,
nlink_samepgfid, 0,
- op_ret,
- this, unlock);
+ op_ret, this, unlock);
}
op_ret = sys_rename (real_oldpath, real_newpath);
@@ -1597,22 +1687,22 @@ posix_rename (call_frame_t *frame, xlator_t *this,
real_oldpath, real_newpath,
strerror (op_errno));
- LINK_MODIFY_PGFID_XATTR (real_oldpath,
- pgfid_xattr_key,
- nlink_samepgfid, 0,
- op_ret,
- this, unlock);
+ if (update_pgfid_xattr) {
+ LINK_MODIFY_PGFID_XATTR (real_oldpath,
+ pgfid_xattr_key,
+ nlink_samepgfid,
+ 0, op_ret, this,
+ unlock);
+ }
goto unlock;
}
- if (!IA_ISDIR (oldloc->inode->ia_type)) {
+ if (update_pgfid_xattr) {
MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
PGFID_XATTR_KEY_PREFIX,
newloc->pargfid);
- LINK_MODIFY_PGFID_XATTR (real_newpath,
- pgfid_xattr_key,
- nlink_samepgfid, 0,
- op_ret,
+ LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret,
this, unlock);
}
}
@@ -1762,25 +1852,26 @@ posix_link (call_frame_t *frame, xlator_t *this,
goto out;
}
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- newloc->pargfid);
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ newloc->pargfid);
- LOCK (&newloc->inode->lock);
- {
- LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key,
- nlink_samepgfid, 0, op_ret, this,
- unlock);
- }
-unlock:
- UNLOCK (&newloc->inode->lock);
+ LOCK (&newloc->inode->lock);
+ {
+ LINK_MODIFY_PGFID_XATTR (real_newpath, pgfid_xattr_key,
+ nlink_samepgfid, 0, op_ret,
+ this, unlock);
+ }
+ unlock:
+ UNLOCK (&newloc->inode->lock);
- if (op_ret < 0) {
- gf_log (this->name, GF_LOG_WARNING, "modification of "
- "parent gfid xattr failed (path:%s gfid:%s)",
- real_newpath, uuid_utoa (newloc->inode->gfid));
- goto out;
+ if (op_ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING, "modification of "
+ "parent gfid xattr failed (path:%s gfid:%s)",
+ real_newpath, uuid_utoa (newloc->inode->gfid));
+ goto out;
+ }
}
-
op_ret = 0;
out:
@@ -1961,11 +2052,13 @@ posix_create (call_frame_t *frame, xlator_t *this,
strerror (errno));
}
- MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
- loc->pargfid);
- nlink_samepgfid = 1;
- SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
- XATTR_CREATE, op_ret, this, ignore);
+ if (priv->update_pgfid_nlinks) {
+ MAKE_PGFID_XATTR_KEY (pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
+ loc->pargfid);
+ nlink_samepgfid = 1;
+ SET_PGFID_XATTR (real_path, pgfid_xattr_key, nlink_samepgfid,
+ XATTR_CREATE, op_ret, this, ignore);
+ }
ignore:
op_ret = posix_entry_create_xattr_set (this, real_path, xdata);
if (op_ret) {
@@ -3113,7 +3206,10 @@ int
posix_get_ancestry (xlator_t *this, const char *real_path, loc_t *loc,
dict_t *dict, int type, int32_t *op_errno, dict_t *xdata)
{
- int ret = -1;
+ int ret = -1;
+ struct posix_private *priv = NULL;
+
+ priv = this->private;
if (IA_ISDIR (loc->inode->ia_type)) {
ret = posix_get_ancestry_directory (this, real_path, loc, dict,
@@ -3305,6 +3401,11 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,
size = op_ret = posix_get_ancestry (this, real_path, loc, dict,
type, &op_errno, xdata);
+ if (op_ret < 0) {
+ op_ret = -1;
+ op_errno = ENODATA;
+ goto out;
+ }
goto done;
}
@@ -4908,6 +5009,9 @@ reconfigure (xlator_t *this, dict_t *options)
else
posix_aio_off (this);
+ GF_OPTION_RECONF ("update-pgfid-nlinks", priv->update_pgfid_nlinks,
+ options, bool, out);
+
GF_OPTION_RECONF ("node-uuid-pathinfo", priv->node_uuid_pathinfo,
options, bool, out);
@@ -5185,6 +5289,20 @@ init (xlator_t *this)
"for every open)");
}
+ tmp_data = dict_get (this->options, "update-pgfid-nlinks");
+ if (tmp_data) {
+ if (gf_string2boolean (tmp_data->data,
+ &_private->update_pgfid_nlinks) == -1) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR,
+ "wrong value provided for "
+ "'update-pgfid-nlinks'");
+ goto out;
+ }
+ gf_log (this->name, GF_LOG_DEBUG, "update-pgfid-nlinks is %s",
+ _private->update_pgfid_nlinks? "enabled": "disabled");
+ }
+
ret = dict_get_str (this->options, "glusterd-uuid", &guuid);
if (!ret) {
if (uuid_parse (guuid, _private->glusterd_uuid))
@@ -5475,5 +5593,10 @@ struct volume_options options[] = {
.description = "Num of usecs to wait for aggregating fsync"
" requests",
},
+ { .key = {"update-pgfid-nlinks"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "false",
+ .description = "Enable placeholders for gfid to path conversion"
+ },
{ .key = {NULL} }
};