|
|
a3470f |
From 91cfe700849856245f58a8c0ee98c0fd1e9d47f6 Mon Sep 17 00:00:00 2001
|
|
|
a3470f |
From: Kotresh HR <khiremat@redhat.com>
|
|
|
a3470f |
Date: Mon, 28 May 2018 03:05:26 -0400
|
|
|
a3470f |
Subject: [PATCH 304/305] cluster/dht: Fix rename journal in changelog
|
|
|
a3470f |
|
|
|
a3470f |
With patch [1], renames are journalled only
|
|
|
a3470f |
on cached subvolume. The dht sends the special
|
|
|
a3470f |
key on the cached subvolume so that the changelog
|
|
|
a3470f |
journals the rename. With single distribute
|
|
|
a3470f |
sub-volume, the key is not being set. This patch
|
|
|
a3470f |
fixes the same.
|
|
|
a3470f |
|
|
|
a3470f |
[1] https://review.gluster.org/10410
|
|
|
a3470f |
|
|
|
a3470f |
Backport of:
|
|
|
a3470f |
> Patch: https://review.gluster.org/20093/
|
|
|
a3470f |
> fixes: bz#1583018
|
|
|
a3470f |
> Change-Id: Ic2e35b40535916fa506a714f257ba325e22d0961
|
|
|
a3470f |
> Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
a3470f |
|
|
|
a3470f |
BUG: 1583047
|
|
|
a3470f |
Change-Id: Ic2e35b40535916fa506a714f257ba325e22d0961
|
|
|
a3470f |
Signed-off-by: Kotresh HR <khiremat@redhat.com>
|
|
|
a3470f |
Reviewed-on: https://code.engineering.redhat.com/gerrit/142601
|
|
|
a3470f |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
a3470f |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
a3470f |
---
|
|
|
a3470f |
tests/basic/changelog/changelog-rename.t | 44 ++++++
|
|
|
a3470f |
tests/utils/changelogparser.py | 234 +++++++++++++++++++++++++++++++
|
|
|
a3470f |
tests/volume.rc | 7 +
|
|
|
a3470f |
xlators/cluster/dht/src/dht-rename.c | 11 ++
|
|
|
a3470f |
4 files changed, 296 insertions(+)
|
|
|
a3470f |
create mode 100644 tests/basic/changelog/changelog-rename.t
|
|
|
a3470f |
create mode 100644 tests/utils/changelogparser.py
|
|
|
a3470f |
|
|
|
a3470f |
diff --git a/tests/basic/changelog/changelog-rename.t b/tests/basic/changelog/changelog-rename.t
|
|
|
a3470f |
new file mode 100644
|
|
|
a3470f |
index 0000000..9a0ef52
|
|
|
a3470f |
--- /dev/null
|
|
|
a3470f |
+++ b/tests/basic/changelog/changelog-rename.t
|
|
|
a3470f |
@@ -0,0 +1,44 @@
|
|
|
a3470f |
+#!/bin/bash
|
|
|
a3470f |
+. $(dirname $0)/../../include.rc
|
|
|
a3470f |
+. $(dirname $0)/../../volume.rc
|
|
|
a3470f |
+cleanup;
|
|
|
a3470f |
+
|
|
|
a3470f |
+CHANGELOG_PATH_0="$B0/${V0}0/.glusterfs/changelogs"
|
|
|
a3470f |
+ROLLOVER_TIME=30
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST glusterd
|
|
|
a3470f |
+TEST pidof glusterd
|
|
|
a3470f |
+TEST $CLI volume create $V0 $H0:$B0/${V0}0
|
|
|
a3470f |
+TEST $CLI volume set $V0 changelog.changelog on
|
|
|
a3470f |
+TEST $CLI volume set $V0 changelog.rollover-time $ROLLOVER_TIME
|
|
|
a3470f |
+TEST $CLI volume start $V0
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0;
|
|
|
a3470f |
+touch $M0/file1
|
|
|
a3470f |
+mv $M0/file1 $M0/rn_file1
|
|
|
a3470f |
+mkdir $M0/dir1
|
|
|
a3470f |
+mv $M0/dir1 $M0/rn_dir1
|
|
|
a3470f |
+
|
|
|
a3470f |
+EXPECT "2" check_changelog_op ${CHANGELOG_PATH_0} "RENAME"
|
|
|
a3470f |
+
|
|
|
a3470f |
+cleanup;
|
|
|
a3470f |
+
|
|
|
a3470f |
+#####Test on multiple subvolume#####
|
|
|
a3470f |
+#==========================================#
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST glusterd
|
|
|
a3470f |
+TEST pidof glusterd
|
|
|
a3470f |
+TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1}
|
|
|
a3470f |
+TEST $CLI volume set $V0 changelog.changelog on
|
|
|
a3470f |
+TEST $CLI volume set $V0 changelog.rollover-time $ROLLOVER_TIME
|
|
|
a3470f |
+TEST $CLI volume start $V0
|
|
|
a3470f |
+
|
|
|
a3470f |
+TEST $GFS --volfile-id=$V0 --volfile-server=$H0 $M0;
|
|
|
a3470f |
+touch $M0/gluster_file
|
|
|
a3470f |
+mv $M0/gluster_file $M0/rn_gluster_file
|
|
|
a3470f |
+mkdir $M0/dir1
|
|
|
a3470f |
+mv $M0/dir1 $M0/rn_dir1
|
|
|
a3470f |
+
|
|
|
a3470f |
+EXPECT "2" check_changelog_op ${CHANGELOG_PATH_0} "RENAME"
|
|
|
a3470f |
+
|
|
|
a3470f |
+cleanup;
|
|
|
a3470f |
diff --git a/tests/utils/changelogparser.py b/tests/utils/changelogparser.py
|
|
|
a3470f |
new file mode 100644
|
|
|
a3470f |
index 0000000..e173e52
|
|
|
a3470f |
--- /dev/null
|
|
|
a3470f |
+++ b/tests/utils/changelogparser.py
|
|
|
a3470f |
@@ -0,0 +1,234 @@
|
|
|
a3470f |
+#!/usr/bin/env python
|
|
|
a3470f |
+# -*- coding: utf-8 -*-
|
|
|
a3470f |
+"""
|
|
|
a3470f |
+Why?
|
|
|
a3470f |
+
|
|
|
a3470f |
+Converts this
|
|
|
a3470f |
+
|
|
|
a3470f |
+GlusterFS Changelog | version: v1.1 | encoding : 2
|
|
|
a3470f |
+E0b99ef11-4b79-4cd0-9730-b5a0e8c4a8c0^@4^@16877^@0^@0^@00000000-0000-0000-0000-
|
|
|
a3470f |
+000000000001/dir1^@Ec5250af6-720e-4bfe-b938-827614304f39^@23^@33188^@0^@0^@0b99
|
|
|
a3470f |
+ef11-4b79-4cd0-9730-b5a0e8c4a8c0/hello.txt^@Dc5250af6-720e-4bfe-b938-827614304f
|
|
|
a3470f |
+39^@Dc5250af6-720e-4bfe-b938-827614304f39^@
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+to human readable :)
|
|
|
a3470f |
+
|
|
|
a3470f |
+E 0b99ef11-4b79-4cd0-9730-b5a0e8c4a8c0 MKDIR 16877 0 000000000-0000-0000-0000
|
|
|
a3470f |
+ -000000000001/dir1
|
|
|
a3470f |
+E c5250af6-720e-4bfe-b938-827614304f39 CREATE 33188 0 0 0b99ef11-4b79-4cd0-9730
|
|
|
a3470f |
+ -b5a0e8c4a8c0/hello.txt
|
|
|
a3470f |
+D c5250af6-720e-4bfe-b938-827614304f39
|
|
|
a3470f |
+D c5250af6-720e-4bfe-b938-827614304f39
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+"""
|
|
|
a3470f |
+import sys
|
|
|
a3470f |
+import codecs
|
|
|
a3470f |
+
|
|
|
a3470f |
+ENTRY = 'E'
|
|
|
a3470f |
+META = 'M'
|
|
|
a3470f |
+DATA = 'D'
|
|
|
a3470f |
+SEP = "\x00"
|
|
|
a3470f |
+
|
|
|
a3470f |
+GF_FOP = [
|
|
|
a3470f |
+ "NULL", "STAT", "READLINK", "MKNOD", "MKDIR", "UNLINK",
|
|
|
a3470f |
+ "RMDIR", "SYMLINK", "RENAME", "LINK", "TRUNCATE", "OPEN",
|
|
|
a3470f |
+ "READ", "WRITE", "STATFS", "FLUSH", "FSYNC", "SETXATTR",
|
|
|
a3470f |
+ "GETXATTR", "REMOVEXATTR", "OPENDIR", "FSYNCDIR", "ACCESS",
|
|
|
a3470f |
+ "CREATE", "FTRUNCATE", "FSTAT", "LK", "LOOKUP", "READDIR",
|
|
|
a3470f |
+ "INODELK", "FINODELK", "ENTRYLK", "FENTRYLK", "XATTROP",
|
|
|
a3470f |
+ "FXATTROP", "FSETXATTR", "FGETXATTR", "RCHECKSUM", "SETATTR",
|
|
|
a3470f |
+ "FSETATTR", "READDIRP", "GETSPEC", "FORGET", "RELEASE",
|
|
|
a3470f |
+ "RELEASEDIR", "FREMOVEXATTR", "FALLOCATE", "DISCARD", "ZEROFILL"]
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+class NumTokens_V11(object):
|
|
|
a3470f |
+ E = 7
|
|
|
a3470f |
+ M = 3
|
|
|
a3470f |
+ D = 2
|
|
|
a3470f |
+ NULL = 3
|
|
|
a3470f |
+ MKNOD = 7
|
|
|
a3470f |
+ MKDIR = 7
|
|
|
a3470f |
+ UNLINK = 4
|
|
|
a3470f |
+ RMDIR = 4
|
|
|
a3470f |
+ SYMLINK = 4
|
|
|
a3470f |
+ RENAME = 5
|
|
|
a3470f |
+ LINK = 4
|
|
|
a3470f |
+ SETXATTR = 3
|
|
|
a3470f |
+ REMOVEXATTR = 3
|
|
|
a3470f |
+ CREATE = 7
|
|
|
a3470f |
+ SETATTR = 3
|
|
|
a3470f |
+ FTRUNCATE = 3
|
|
|
a3470f |
+ FXATTROP = 3
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+class NumTokens_V12(NumTokens_V11):
|
|
|
a3470f |
+ UNLINK = 5
|
|
|
a3470f |
+ RMDIR = 5
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+class Version:
|
|
|
a3470f |
+ V11 = "v1.1"
|
|
|
a3470f |
+ V12 = "v1.2"
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+class Record(object):
|
|
|
a3470f |
+ def __init__(self, **kwargs):
|
|
|
a3470f |
+ self.ts = kwargs.get("ts", None)
|
|
|
a3470f |
+ self.fop_type = kwargs.get("fop_type", None)
|
|
|
a3470f |
+ self.gfid = kwargs.get("gfid", None)
|
|
|
a3470f |
+ self.path = kwargs.get("path", None)
|
|
|
a3470f |
+ self.fop = kwargs.get("fop", None)
|
|
|
a3470f |
+ self.path1 = kwargs.get("path1", None)
|
|
|
a3470f |
+ self.path2 = kwargs.get("path2", None)
|
|
|
a3470f |
+ self.mode = kwargs.get("mode", None)
|
|
|
a3470f |
+ self.uid = kwargs.get("uid", None)
|
|
|
a3470f |
+ self.gid = kwargs.get("gid", None)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def create_mknod_mkdir(self, **kwargs):
|
|
|
a3470f |
+ self.path = kwargs.get("path", None)
|
|
|
a3470f |
+ self.fop = kwargs.get("fop", None)
|
|
|
a3470f |
+ self.mode = kwargs.get("mode", None)
|
|
|
a3470f |
+ self.uid = kwargs.get("uid", None)
|
|
|
a3470f |
+ self.gid = kwargs.get("gid", None)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def metadata(self, **kwargs):
|
|
|
a3470f |
+ self.fop = kwargs.get("fop", None)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def rename(self, **kwargs):
|
|
|
a3470f |
+ self.fop = kwargs.get("fop", None)
|
|
|
a3470f |
+ self.path1 = kwargs.get("path1", None)
|
|
|
a3470f |
+ self.path2 = kwargs.get("path2", None)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def link_symlink_unlink_rmdir(self, **kwargs):
|
|
|
a3470f |
+ self.path = kwargs.get("path", None)
|
|
|
a3470f |
+ self.fop = kwargs.get("fop", None)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def __unicode__(self):
|
|
|
a3470f |
+ if self.fop_type == "D":
|
|
|
a3470f |
+ return u"{ts} {fop_type} {gfid}".format(**self.__dict__)
|
|
|
a3470f |
+ elif self.fop_type == "M":
|
|
|
a3470f |
+ return u"{ts} {fop_type} {gfid} {fop}".format(**self.__dict__)
|
|
|
a3470f |
+ elif self.fop_type == "E":
|
|
|
a3470f |
+ if self.fop in ["CREATE", "MKNOD", "MKDIR"]:
|
|
|
a3470f |
+ return (u"{ts} {fop_type} {gfid} {fop} "
|
|
|
a3470f |
+ u"{path} {mode} {uid} {gid}".format(**self.__dict__))
|
|
|
a3470f |
+ elif self.fop == "RENAME":
|
|
|
a3470f |
+ return (u"{ts} {fop_type} {gfid} {fop} "
|
|
|
a3470f |
+ u"{path1} {path2}".format(**self.__dict__))
|
|
|
a3470f |
+ elif self.fop in ["LINK", "SYMLINK", "UNLINK", "RMDIR"]:
|
|
|
a3470f |
+ return (u"{ts} {fop_type} {gfid} {fop} "
|
|
|
a3470f |
+ u"{path}".format(**self.__dict__))
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ return repr(self.__dict__)
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ return repr(self.__dict__)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ def __str__(self):
|
|
|
a3470f |
+ return unicode(self).encode('utf-8')
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+def get_num_tokens(data, tokens, version=Version.V11):
|
|
|
a3470f |
+ if version == Version.V11:
|
|
|
a3470f |
+ cls_numtokens = NumTokens_V11
|
|
|
a3470f |
+ elif version == Version.V12:
|
|
|
a3470f |
+ cls_numtokens = NumTokens_V12
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ sys.stderr.write("Unknown Changelog Version\n")
|
|
|
a3470f |
+ sys.exit(1)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if data[tokens[0]] in [ENTRY, META]:
|
|
|
a3470f |
+ if len(tokens) >= 3:
|
|
|
a3470f |
+ return getattr(cls_numtokens, GF_FOP[int(data[tokens[2]])])
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ return None
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ return getattr(cls_numtokens, data[tokens[0]])
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+def process_record(data, tokens, changelog_ts, callback):
|
|
|
a3470f |
+ if data[tokens[0]] in [ENTRY, META]:
|
|
|
a3470f |
+ try:
|
|
|
a3470f |
+ tokens[2] = GF_FOP[int(data[tokens[2]])]
|
|
|
a3470f |
+ except ValueError:
|
|
|
a3470f |
+ tokens[2] = "NULL"
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if not changelog_ts:
|
|
|
a3470f |
+ ts1 = int(changelog_ts)
|
|
|
a3470f |
+ else:
|
|
|
a3470f |
+ ts1=""
|
|
|
a3470f |
+ record = Record(ts=ts1, fop_type=data[tokens[0]],
|
|
|
a3470f |
+ gfid=data[tokens[1]])
|
|
|
a3470f |
+ if data[tokens[0]] == META:
|
|
|
a3470f |
+ record.metadata(fop=tokens[2])
|
|
|
a3470f |
+ elif data[tokens[0]] == ENTRY:
|
|
|
a3470f |
+ if tokens[2] in ["CREATE", "MKNOD", "MKDIR"]:
|
|
|
a3470f |
+ record.create_mknod_mkdir(fop=tokens[2],
|
|
|
a3470f |
+ path=data[tokens[6]],
|
|
|
a3470f |
+ mode=int(data[tokens[3]]),
|
|
|
a3470f |
+ uid=int(data[tokens[4]]),
|
|
|
a3470f |
+ gid=int(data[tokens[5]]))
|
|
|
a3470f |
+ elif tokens[2] == "RENAME":
|
|
|
a3470f |
+ record.rename(fop=tokens[2],
|
|
|
a3470f |
+ path1=data[tokens[3]],
|
|
|
a3470f |
+ path2=data[tokens[4]])
|
|
|
a3470f |
+ if tokens[2] in ["LINK", "SYMLINK", "UNLINK", "RMDIR"]:
|
|
|
a3470f |
+ record.link_symlink_unlink_rmdir(fop=tokens[2],
|
|
|
a3470f |
+ path=data[tokens[3]])
|
|
|
a3470f |
+ callback(record)
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+def default_callback(record):
|
|
|
a3470f |
+ sys.stdout.write(u"{0}\n".format(record))
|
|
|
a3470f |
+
|
|
|
a3470f |
+
|
|
|
a3470f |
+def parse(filename, callback=default_callback):
|
|
|
a3470f |
+ data = None
|
|
|
a3470f |
+ tokens = []
|
|
|
a3470f |
+ changelog_ts = filename.rsplit(".")[-1]
|
|
|
a3470f |
+ with codecs.open(filename, mode="rb", encoding="utf-8") as f:
|
|
|
a3470f |
+ # GlusterFS Changelog | version: v1.1 | encoding : 2
|
|
|
a3470f |
+ header = f.readline()
|
|
|
a3470f |
+ version = header.split()[4]
|
|
|
a3470f |
+
|
|
|
a3470f |
+ data = f.readline()
|
|
|
a3470f |
+
|
|
|
a3470f |
+ slice_start = 0
|
|
|
a3470f |
+ in_record = False
|
|
|
a3470f |
+
|
|
|
a3470f |
+ prev_char = ""
|
|
|
a3470f |
+ next_char = ""
|
|
|
a3470f |
+ for i, c in enumerate(data):
|
|
|
a3470f |
+ next_char = ""
|
|
|
a3470f |
+ if len(data) >= (i + 2):
|
|
|
a3470f |
+ next_char = data[i+1]
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if not in_record and c in [ENTRY, META, DATA]:
|
|
|
a3470f |
+ tokens.append(slice(slice_start, i+1))
|
|
|
a3470f |
+ slice_start = i+1
|
|
|
a3470f |
+ in_record = True
|
|
|
a3470f |
+ continue
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if c == SEP and ((prev_char != SEP and next_char == SEP) or
|
|
|
a3470f |
+ (prev_char == SEP and next_char != SEP) or
|
|
|
a3470f |
+ (prev_char != SEP and next_char != SEP)):
|
|
|
a3470f |
+ tokens.append(slice(slice_start, i))
|
|
|
a3470f |
+ slice_start = i+1
|
|
|
a3470f |
+
|
|
|
a3470f |
+ num_tokens = get_num_tokens(data, tokens, version)
|
|
|
a3470f |
+
|
|
|
a3470f |
+ if num_tokens == len(tokens):
|
|
|
a3470f |
+ process_record(data, tokens, changelog_ts, callback)
|
|
|
a3470f |
+ in_record = False
|
|
|
a3470f |
+ tokens = []
|
|
|
a3470f |
+
|
|
|
a3470f |
+ prev_char = c
|
|
|
a3470f |
+
|
|
|
a3470f |
+ # process last record
|
|
|
a3470f |
+ if slice_start < (len(data) - 1):
|
|
|
a3470f |
+ tokens.append(slice(slice_start, len(data)))
|
|
|
a3470f |
+ process_record(data, tokens, changelog_ts, callback)
|
|
|
a3470f |
+ tokens = []
|
|
|
a3470f |
+
|
|
|
a3470f |
+parse(sys.argv[1])
|
|
|
a3470f |
diff --git a/tests/volume.rc b/tests/volume.rc
|
|
|
a3470f |
index f9e16c5..bba7e4e 100644
|
|
|
a3470f |
--- a/tests/volume.rc
|
|
|
a3470f |
+++ b/tests/volume.rc
|
|
|
a3470f |
@@ -865,3 +865,10 @@ function get_mount_lru_size_value {
|
|
|
a3470f |
rm -f $statedump
|
|
|
a3470f |
echo $val
|
|
|
a3470f |
}
|
|
|
a3470f |
+
|
|
|
a3470f |
+function check_changelog_op {
|
|
|
a3470f |
+ local clog_path=$1
|
|
|
a3470f |
+ local op=$2
|
|
|
a3470f |
+
|
|
|
a3470f |
+ $PYTHON $(dirname $0)/../../utils/changelogparser.py ${clog_path}/CHANGELOG | grep $op | wc -l
|
|
|
a3470f |
+}
|
|
|
a3470f |
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
|
|
|
a3470f |
index d311ac6..1d0c2bb 100644
|
|
|
a3470f |
--- a/xlators/cluster/dht/src/dht-rename.c
|
|
|
a3470f |
+++ b/xlators/cluster/dht/src/dht-rename.c
|
|
|
a3470f |
@@ -1948,6 +1948,7 @@ dht_rename (call_frame_t *frame, xlator_t *this,
|
|
|
a3470f |
dht_conf_t *conf = NULL;
|
|
|
a3470f |
char gfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
a3470f |
char newgfid[GF_UUID_BUF_SIZE] = {0};
|
|
|
a3470f |
+ gf_boolean_t free_xdata = _gf_false;
|
|
|
a3470f |
|
|
|
a3470f |
VALIDATE_OR_GOTO (frame, err);
|
|
|
a3470f |
VALIDATE_OR_GOTO (this, err);
|
|
|
a3470f |
@@ -1957,7 +1958,17 @@ dht_rename (call_frame_t *frame, xlator_t *this,
|
|
|
a3470f |
conf = this->private;
|
|
|
a3470f |
|
|
|
a3470f |
if (conf->subvolume_cnt == 1) {
|
|
|
a3470f |
+ if (!IA_ISDIR (oldloc->inode->ia_type)) {
|
|
|
a3470f |
+ if (!xdata) {
|
|
|
a3470f |
+ free_xdata = _gf_true;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
+ DHT_CHANGELOG_TRACK_AS_RENAME(xdata, oldloc, newloc);
|
|
|
a3470f |
+ }
|
|
|
a3470f |
default_rename (frame, this, oldloc, newloc, xdata);
|
|
|
a3470f |
+ if (free_xdata && xdata) {
|
|
|
a3470f |
+ dict_unref(xdata);
|
|
|
a3470f |
+ xdata = NULL;
|
|
|
a3470f |
+ }
|
|
|
a3470f |
return 0;
|
|
|
a3470f |
}
|
|
|
a3470f |
|
|
|
a3470f |
--
|
|
|
a3470f |
1.8.3.1
|
|
|
a3470f |
|