os/chain_xattr: Remove all old xattr entry when overwrite the xattr.

Ceph use multiple xattrs to store the value of a single xattr which size
is larger than CHAIN_XATTR_MAX_BLOCK_LEN.
But when overwote the content of xattr in func
chain_setxattr/chain_fsetxattr, we don't know the size of previous
content of the xattr.
So we only try to remove until system return  -ENODATA.

Signed-off-by: Ma Jianpeng <jianpeng.ma@intel.com>
This commit is contained in:
Ma Jianpeng 2014-08-07 21:33:18 +08:00
parent 818f5b7038
commit 4f6d513366

View File

@ -252,13 +252,15 @@ int chain_setxattr(const char *fn, const char *name, const void *val, size_t siz
i++;
} while (size);
/* if we're exactly at a chunk size, remove the next one (if wasn't removed
before) */
if (ret >= 0 && chunk_size == CHAIN_XATTR_MAX_BLOCK_LEN) {
get_raw_xattr_name(name, i, raw_name, sizeof(raw_name));
int r = sys_removexattr(fn, raw_name);
if (r < 0 && r != -ENODATA)
ret = r;
if (ret >= 0 ) {
int r;
do {
get_raw_xattr_name(name, i, raw_name, sizeof(raw_name));
r = sys_removexattr(fn, raw_name);
if (r < 0 && r != -ENODATA)
ret = r;
i++;
} while (r != -ENODATA);
}
return ret;
@ -286,13 +288,15 @@ int chain_fsetxattr(int fd, const char *name, const void *val, size_t size)
i++;
} while (size);
/* if we're exactly at a chunk size, remove the next one (if wasn't removed
before) */
if (ret >= 0 && chunk_size == CHAIN_XATTR_MAX_BLOCK_LEN) {
get_raw_xattr_name(name, i, raw_name, sizeof(raw_name));
int r = sys_fremovexattr(fd, raw_name);
if (r < 0 && r != -ENODATA)
ret = r;
if (ret >= 0) {
int r;
do {
get_raw_xattr_name(name, i, raw_name, sizeof(raw_name));
r = sys_fremovexattr(fd, raw_name);
if (r < 0 && r != -ENODATA)
ret = r;
i++;
} while (r != -ENODATA);
}
return ret;