diff options
| -rw-r--r-- | libglusterfs/src/common-utils.h | 25 | ||||
| -rw-r--r-- | libglusterfs/src/glusterfs.h | 1 | ||||
| -rw-r--r-- | xlators/cluster/dht/src/dht-rename.c | 82 | 
3 files changed, 108 insertions, 0 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index e8b5fc83591..c361405d5eb 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -130,6 +130,31 @@ enum _gf_xlator_ipc_targets {  typedef enum _gf_boolean gf_boolean_t;  typedef enum _gf_client_pid gf_client_pid_t;  typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t; + +/* The DHT file rename operation is not a straightforward rename. + * It involves creating linkto and linkfiles, and can unlink or rename the + * source file depending on the hashed and cached subvols for the source + * and target files. this makes it difficult for geo-rep to figure out that + * a rename operation has taken place. + * + * We now send a special key and the values of the source and target pargfids + * and basenames to indicate to changelog that the operation in question + * should be treated as a rename. We are explicitly filling and sending this + * as a binary value in the dictionary as the unlink op will not have the + * source file information. The lengths of the src and target basenames + * are used to calculate where to start reading the names in the structure. + * XFS allows a max of 255 chars for filenames but other file systems might + * not have such restrictions + */ +typedef struct dht_changelog_rename_info { +         uuid_t  old_pargfid; +         uuid_t  new_pargfid; +         int32_t oldname_len; +         int32_t newname_len; +         char    buffer[1]; + } dht_changelog_rename_info_t; + +  typedef int (*gf_cmp) (void *, void *);  void gf_global_variable_init(void); diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h index ba59e4d54db..3373ef6f7b8 100644 --- a/libglusterfs/src/glusterfs.h +++ b/libglusterfs/src/glusterfs.h @@ -140,6 +140,7 @@  #define GLUSTERFS_VERSION_XCHG_KEY     "glusterfs.version.xchg"  #define GLUSTERFS_INTERNAL_FOP_KEY  "glusterfs-internal-fop" +#define DHT_CHANGELOG_RENAME_OP_KEY   "changelog.rename-op"  #define ZR_FILE_CONTENT_STR     "glusterfs.file."  #define ZR_FILE_CONTENT_STRLEN 15 diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c index 0594945203e..4e4e9869685 100644 --- a/xlators/cluster/dht/src/dht-rename.c +++ b/xlators/cluster/dht/src/dht-rename.c @@ -319,6 +319,56 @@ err:                            NULL, NULL);          return 0;  } + + + +static int +dht_rename_track_for_changelog (xlator_t *this, dict_t *xattr, +                                loc_t *oldloc, loc_t *newloc) +{ +        int ret        = -1; +        dht_changelog_rename_info_t *info = NULL; +        char *name     = NULL; +        int len1       = 0; +        int len2       = 0; +        int size       = 0; + +        if (!xattr || !oldloc || !newloc || !this) +                return ret; + +        len1 = strlen (oldloc->name) + 1; +        len2 = strlen (newloc->name) + 1; +        size = sizeof (dht_changelog_rename_info_t) + len1 + len2; + +        info = GF_CALLOC (size, sizeof(char), gf_common_mt_char); +        if (!info) { +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        DHT_MSG_DICT_SET_FAILED, +                        "Failed to calloc memory"); +                return ret; +        } + +        gf_uuid_copy (info->old_pargfid, oldloc->pargfid); +        gf_uuid_copy (info->new_pargfid, newloc->pargfid); + +        info->oldname_len = len1; +        info->newname_len = len2; +        strncpy (info->buffer, oldloc->name, len1); +        name = info->buffer + len1; +        strncpy (name, newloc->name, len2); + +        ret = dict_set_bin (xattr, DHT_CHANGELOG_RENAME_OP_KEY, +                            info, size); +        if (ret) { +                gf_msg (this->name, GF_LOG_ERROR, 0, DHT_MSG_DICT_SET_FAILED, +                        "Failed to set dictionary value: key = %s," +                        " path = %s", DHT_CHANGELOG_RENAME_OP_KEY, +                        oldloc->name); +        } +        return ret; +} + +  #define DHT_MARK_FOP_INTERNAL(xattr) do {                                      \                  int tmp = -1;                                                  \                  if (!xattr) {                                                  \ @@ -354,6 +404,32 @@ err:                  }                                                              \          }while (0) + +#define DHT_CHANGELOG_TRACK_AS_RENAME(xattr, oldloc, newloc) do {            \ +                int tmp = -1;                                                \ +                if (!xattr) {                                                \ +                        xattr = dict_new ();                                 \ +                        if (!xattr) {                                        \ +                                gf_msg (this->name, GF_LOG_ERROR, 0,         \ +                                        DHT_MSG_DICT_SET_FAILED,             \ +                                        "Failed to create dictionary to "    \ +                                        "track rename");                     \ +                                break;                                       \ +                        }                                                    \ +                }                                                            \ +                                                                             \ +                tmp = dht_rename_track_for_changelog (this, xattr,           \ +                                oldloc, newloc);                             \ +                                                                             \ +                if (tmp) {                                                   \ +                        gf_msg (this->name, GF_LOG_ERROR, 0,                 \ +                                DHT_MSG_DICT_SET_FAILED,                     \ +                                "Failed to set dictionary value: key = %s,"  \ +                                " path = %s", DHT_CHANGELOG_RENAME_OP_KEY,   \ +                                (oldloc)->path);                             \ +                }                                                            \ +        } while (0) +  int  dht_rename_unlock_cbk (call_frame_t *frame, void *cookie,                         xlator_t *this, int32_t op_ret, int32_t op_errno, @@ -745,6 +821,8 @@ err:                          DHT_MARKER_DONT_ACCOUNT(xattr_new);                  } +                DHT_CHANGELOG_TRACK_AS_RENAME(xattr_new, &local->loc, +                                              &local->loc2);                  STACK_WIND (frame, dht_rename_unlink_cbk,                              src_cached, src_cached->fops->unlink,                              &local->loc, 0, xattr_new); @@ -831,6 +909,10 @@ dht_do_rename (call_frame_t *frame)                  DHT_MARKER_DONT_ACCOUNT(dict);          } +        if (rename_subvol == src_cached) { +                DHT_CHANGELOG_TRACK_AS_RENAME(dict, &local->loc, &local->loc2); +        } +          gf_msg_trace (this->name, 0,                        "renaming %s => %s (%s)",                        local->loc.path, local->loc2.path, rename_subvol->name);  | 
