summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix')
-rw-r--r--xlators/storage/posix/src/posix.c123
-rw-r--r--xlators/storage/posix/src/posix.h10
2 files changed, 116 insertions, 17 deletions
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index dc3a709cd26..bf5c188e5ca 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -1019,20 +1019,60 @@ out:
return 0;
}
+int32_t
+posix_unlink_gfid_handle_and_entry (xlator_t *this, const char *real_path,
+ struct iatt *stbuf, int32_t *op_errno)
+{
+ int32_t ret = 0;
+
+ /* Unlink the gfid_handle_first */
+
+ if (stbuf && stbuf->ia_nlink == 1) {
+ ret = posix_handle_unset (this, stbuf->ia_gfid, NULL);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "unlink of gfid handle failed for path:%s with"
+ "gfid %s with errno:%s", real_path,
+ uuid_utoa (stbuf->ia_gfid), strerror (errno));
+ }
+ }
+
+ /* Unlink the actual file */
+ ret = sys_unlink (real_path);
+ if (ret == -1) {
+ if (op_errno)
+ *op_errno = errno;
+
+ gf_log (this->name, GF_LOG_ERROR,
+ "unlink of %s failed: %s", real_path,
+ strerror (errno));
+ goto err;
+ }
+
+ return 0;
+
+err:
+ return -1;
+}
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,};
+ 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,};
+ int32_t unlink_if_linkto = 0;
+ int32_t check_open_fd = 0;
+ int32_t skip_unlink = 0;
+ ssize_t xattr_size = -1;
+ int32_t is_dht_linkto_file = 0;
DECLARE_OLD_FS_ID_VAR;
@@ -1052,10 +1092,62 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
goto out;
}
- if (stbuf.ia_nlink == 1)
- posix_handle_unset (this, stbuf.ia_gfid, NULL);
-
priv = this->private;
+
+ op_ret = dict_get_int32 (xdata, DHT_SKIP_OPEN_FD_UNLINK,
+ &check_open_fd);
+
+ if (!op_ret && check_open_fd) {
+
+ LOCK (&loc->inode->lock);
+
+ if (loc->inode->fd_count) {
+ skip_unlink = 1;
+ }
+
+ UNLOCK (&loc->inode->lock);
+
+ gf_log (this->name, GF_LOG_INFO, "open-fd-key-status: "
+ "%"PRIu32" for %s", skip_unlink, real_path);
+
+ if (skip_unlink) {
+ op_ret = -1;
+ op_errno = EBUSY;
+ goto out;
+ }
+ }
+
+
+ op_ret = dict_get_int32 (xdata, DHT_SKIP_NON_LINKTO_UNLINK,
+ &unlink_if_linkto);
+
+ if (!op_ret && unlink_if_linkto) {
+
+ LOCK (&loc->inode->lock);
+
+ xattr_size = sys_lgetxattr (real_path, LINKTO, NULL, 0);
+
+ if (xattr_size <= 0) {
+ skip_unlink = 1;
+ } else {
+ is_dht_linkto_file = IS_DHT_LINKFILE_MODE (&stbuf);
+ if (!is_dht_linkto_file)
+ skip_unlink = 1;
+ }
+
+ UNLOCK (&loc->inode->lock);
+
+ gf_log (this->name, GF_LOG_INFO, "linkto_xattr status: "
+ "%"PRIu32" for %s", skip_unlink, real_path);
+
+ if (skip_unlink) {
+ op_ret = -1;
+ op_errno = EBUSY;
+ goto out;
+ }
+ }
+
+
if (priv->background_unlink) {
if (IA_ISREG (loc->inode->ia_type)) {
fd = open (real_path, O_RDONLY);
@@ -1070,12 +1162,9 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = sys_unlink (real_path);
+ op_ret = posix_unlink_gfid_handle_and_entry (this, real_path, &stbuf,
+ &op_errno);
if (op_ret == -1) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "unlink of %s failed: %s", real_path,
- strerror (op_errno));
goto out;
}
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 58f445c699a..80121c08c8f 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -49,6 +49,16 @@
#include "posix-aio.h"
#endif
+#define VECTOR_SIZE 64 * 1024 /* vector size 64KB*/
+#define MAX_NO_VECT 1024
+
+#define LINKTO "trusted.glusterfs.dht.linkto"
+
+#define POSIX_GFID_HANDLE_SIZE(base_path_len) (base_path_len + SLEN("/") \
+ + SLEN(GF_HIDDEN_PATH) + SLEN("/") \
+ + SLEN("00/") \
+ + SLEN("00/") + SLEN(UUID0_STR) + 1) /* '\0' */;
+
/**
* posix_fd - internal structure common to file and directory fd's
*/