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.c99
1 files changed, 86 insertions, 13 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 6cd7df54909..b621580d3e6 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -1717,13 +1717,13 @@ out:
int32_t
posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path,
struct iatt *stbuf, int32_t *op_errno,
- loc_t *loc)
+ loc_t *loc, gf_boolean_t get_link_count,
+ dict_t *rsp_dict)
{
- int32_t ret = 0;
- struct posix_private *priv = NULL;
- int fd_count = 0;
-
- priv = this->private;
+ int fd_count = 0;
+ int32_t ret = 0;
+ struct iatt prebuf = {0,};
+ gf_boolean_t locked = _gf_false;
/* Unlink the gfid_handle_first */
if (stbuf && stbuf->ia_nlink == 1) {
@@ -1746,6 +1746,18 @@ posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path,
}
}
+ if (get_link_count) {
+ LOCK (&loc->inode->lock);
+ locked = _gf_true;
+ ret = posix_pstat (this, loc->gfid, real_path, &prebuf);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, errno,
+ P_MSG_LSTAT_FAILED, "lstat on %s failed",
+ real_path);
+ goto err;
+ }
+ }
+
/* Unlink the actual file */
ret = sys_unlink (real_path);
if (ret == -1) {
@@ -1756,9 +1768,23 @@ posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path,
goto err;
}
+ if (locked) {
+ UNLOCK (&loc->inode->lock);
+ locked = _gf_false;
+ }
+
+ ret = dict_set_uint32 (rsp_dict, GET_LINK_COUNT, prebuf.ia_nlink);
+ if (ret)
+ gf_msg (this->name, GF_LOG_WARNING, 0, P_MSG_SET_XDATA_FAIL,
+ "failed to set "GET_LINK_COUNT" for %s", real_path);
+
return 0;
err:
+ if (locked) {
+ UNLOCK (&loc->inode->lock);
+ locked = _gf_false;
+ }
return -1;
}
@@ -1849,6 +1875,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
void *uuid = NULL;
char uuid_str[GF_UUID_BUF_SIZE] = {0};
char gfid_str[GF_UUID_BUF_SIZE] = {0};
+ gf_boolean_t get_link_count = _gf_false;
DECLARE_OLD_FS_ID_VAR;
@@ -1972,18 +1999,23 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf,
- &op_errno, loc);
- if (op_ret == -1) {
- goto out;
- }
-
unwind_dict = dict_new ();
if (!unwind_dict) {
op_errno = -ENOMEM;
op_ret = -1;
goto out;
}
+
+ if (xdata && dict_get (xdata, GET_LINK_COUNT))
+ get_link_count = _gf_true;
+ op_ret = posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf,
+ &op_errno, loc,
+ get_link_count,
+ unwind_dict);
+ if (op_ret == -1) {
+ goto out;
+ }
+
if (fdstat_requested) {
op_ret = posix_fdstat (this, fd, &postbuf);
if (op_ret == -1) {
@@ -2307,6 +2339,8 @@ posix_rename (call_frame_t *frame, xlator_t *this,
char *pgfid_xattr_key = NULL;
int32_t nlink_samepgfid = 0;
dict_t *unwind_dict = NULL;
+ gf_boolean_t locked = _gf_false;
+ gf_boolean_t get_link_count = _gf_false;
DECLARE_OLD_FS_ID_VAR;
@@ -2333,6 +2367,13 @@ posix_rename (call_frame_t *frame, xlator_t *this,
goto out;
}
+ unwind_dict = dict_new ();
+ if (!unwind_dict) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ goto out;
+ }
+
op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &preoldparent);
if (op_ret == -1) {
op_errno = errno;
@@ -2399,6 +2440,22 @@ posix_rename (call_frame_t *frame, xlator_t *this,
this, unlock);
}
+ if ((xdata) && (dict_get (xdata, GET_LINK_COUNT))
+ && (real_newpath) && (was_present)) {
+ LOCK (&newloc->inode->lock);
+ locked = _gf_true;
+ get_link_count = _gf_true;
+ op_ret = posix_pstat (this, newloc->gfid, real_newpath,
+ &stbuf);
+ if ((op_ret == -1) && (errno != ENOENT)) {
+ op_errno = errno;
+ gf_msg (this->name, GF_LOG_ERROR, errno,
+ P_MSG_LSTAT_FAILED,
+ "lstat on %s failed", real_newpath);
+ goto unlock;
+ }
+ }
+
op_ret = sys_rename (real_oldpath, real_newpath);
if (op_ret == -1) {
op_errno = errno;
@@ -2426,6 +2483,18 @@ posix_rename (call_frame_t *frame, xlator_t *this,
goto unlock;
}
+ if (locked) {
+ UNLOCK (&newloc->inode->lock);
+ locked = _gf_false;
+ }
+
+ if ((get_link_count) &&
+ (dict_set_uint32 (unwind_dict, GET_LINK_COUNT,
+ stbuf.ia_nlink)))
+ gf_msg (this->name, GF_LOG_WARNING, 0,
+ P_MSG_SET_XDATA_FAIL, "failed to set "
+ GET_LINK_COUNT" for %s", real_newpath);
+
if (!IA_ISDIR (oldloc->inode->ia_type)
&& priv->update_pgfid_nlinks) {
MAKE_PGFID_XATTR_KEY (pgfid_xattr_key,
@@ -2439,6 +2508,10 @@ posix_rename (call_frame_t *frame, xlator_t *this,
}
}
unlock:
+ if (locked) {
+ UNLOCK (&newloc->inode->lock);
+ locked = _gf_false;
+ }
UNLOCK (&oldloc->inode->lock);
if (op_ret < 0) {
@@ -2487,7 +2560,7 @@ unlock:
}
if (was_present)
- unwind_dict = posix_dict_set_nlink (xdata, NULL, nlink);
+ unwind_dict = posix_dict_set_nlink (xdata, unwind_dict, nlink);
op_ret = 0;
out: