|
|
233933 |
From 36b0bd86321436a951f225fcf2e921390ed8dc33 Mon Sep 17 00:00:00 2001
|
|
|
233933 |
From: Michael Adam <obnox@samba.org>
|
|
|
233933 |
Date: Thu, 20 Jun 2019 13:09:37 +0200
|
|
|
233933 |
Subject: [PATCH 223/255] change get_real_filename implementation to use
|
|
|
233933 |
ENOATTR instead of ENOENT
|
|
|
233933 |
|
|
|
233933 |
get_real_filename is implemented as a virtual extended attribute to help
|
|
|
233933 |
Samba implement the case-insensitive but case preserving SMB protocol
|
|
|
233933 |
more efficiently. It is implemented as a getxattr call on the parent directory
|
|
|
233933 |
with the virtual key of "get_real_filename:<entryname>" by looking for a
|
|
|
233933 |
spelling with different case for the provided file/dir name (<entryname>)
|
|
|
233933 |
and returning this correct spelling as a result if the entry is found.
|
|
|
233933 |
Originally (05aaec645a6262d431486eb5ac7cd702646cfcfb), the
|
|
|
233933 |
implementation used the ENOENT errno to return the authoritative answer
|
|
|
233933 |
that <entryname> does not exist in any case folding.
|
|
|
233933 |
|
|
|
233933 |
Now this implementation is actually a violation or misuse of the defined
|
|
|
233933 |
API for the getxattr call which returns ENOENT for the case that the dir
|
|
|
233933 |
that the call is made against does not exist and ENOATTR (or the synonym
|
|
|
233933 |
ENODATA) for the case that the xattr does not exist.
|
|
|
233933 |
|
|
|
233933 |
This was not a problem until the gluster fuse-bridge was changed
|
|
|
233933 |
to do map ENOENT to ESTALE in 59629f1da9dca670d5dcc6425f7f89b3e96b46bf,
|
|
|
233933 |
after which we the getxattr call for get_real_filename returned an
|
|
|
233933 |
ESTALE instead of ENOENT breaking the expectation in Samba.
|
|
|
233933 |
|
|
|
233933 |
It is an independent problem that ESTALE should not leak out to user
|
|
|
233933 |
space but is intended to trigger retries between fuse and gluster.
|
|
|
233933 |
But nevertheless, the semantics seem to be incorrect here and should
|
|
|
233933 |
be changed.
|
|
|
233933 |
|
|
|
233933 |
This patch changes the implementation of the get_real_filename virtual
|
|
|
233933 |
xattr to correctly return ENOATTR instead of ENOENT if the file/directory
|
|
|
233933 |
being looked up is not found.
|
|
|
233933 |
|
|
|
233933 |
The Samba glusterfs_fuse vfs module which takes advantage of the
|
|
|
233933 |
get_real_filename over a fuse mount will receive a corresponding change
|
|
|
233933 |
to map ENOATTR to ENOENT. Without this change, it will still work
|
|
|
233933 |
correctly, but the performance optimization for nonexisting files is
|
|
|
233933 |
lost. On the other hand side, this change removes the distinction
|
|
|
233933 |
between the old not-implemented case and the implemented case.
|
|
|
233933 |
So Samba changed to treat ENOATTR like ENOENT will not work correctly
|
|
|
233933 |
any more against old servers that don't implement get_real_filename.
|
|
|
233933 |
I.e. existing files will be reported as non-existing
|
|
|
233933 |
|
|
|
233933 |
Backport of https://review.gluster.org/c/glusterfs/+/22925
|
|
|
233933 |
|
|
|
233933 |
Change-Id: I971b427ab8410636d5d201157d9af70e0d075b67
|
|
|
233933 |
fixes: bz#1724089
|
|
|
233933 |
Signed-off-by: Michael Adam <obnox@samba.org>
|
|
|
233933 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/175012
|
|
|
233933 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
233933 |
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
233933 |
---
|
|
|
233933 |
xlators/cluster/dht/src/dht-common.c | 8 ++++----
|
|
|
233933 |
xlators/storage/posix/src/posix-inode-fd-ops.c | 4 ++--
|
|
|
233933 |
2 files changed, 6 insertions(+), 6 deletions(-)
|
|
|
233933 |
|
|
|
233933 |
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
|
|
|
233933 |
index 9a6ea5b..219b072 100644
|
|
|
233933 |
--- a/xlators/cluster/dht/src/dht-common.c
|
|
|
233933 |
+++ b/xlators/cluster/dht/src/dht-common.c
|
|
|
233933 |
@@ -4618,7 +4618,7 @@ dht_getxattr_get_real_filename_cbk(call_frame_t *frame, void *cookie,
|
|
|
233933 |
|
|
|
233933 |
LOCK(&frame->lock);
|
|
|
233933 |
{
|
|
|
233933 |
- if (local->op_errno == ENODATA || local->op_errno == EOPNOTSUPP) {
|
|
|
233933 |
+ if (local->op_errno == EOPNOTSUPP) {
|
|
|
233933 |
/* Nothing to do here, we have already found
|
|
|
233933 |
* a subvol which does not have the get_real_filename
|
|
|
233933 |
* optimization. If condition is for simple logic.
|
|
|
233933 |
@@ -4627,7 +4627,7 @@ dht_getxattr_get_real_filename_cbk(call_frame_t *frame, void *cookie,
|
|
|
233933 |
}
|
|
|
233933 |
|
|
|
233933 |
if (op_ret == -1) {
|
|
|
233933 |
- if (op_errno == ENODATA || op_errno == EOPNOTSUPP) {
|
|
|
233933 |
+ if (op_errno == EOPNOTSUPP) {
|
|
|
233933 |
/* This subvol does not have the optimization.
|
|
|
233933 |
* Better let the user know we don't support it.
|
|
|
233933 |
* Remove previous results if any.
|
|
|
233933 |
@@ -4655,7 +4655,7 @@ dht_getxattr_get_real_filename_cbk(call_frame_t *frame, void *cookie,
|
|
|
233933 |
goto post_unlock;
|
|
|
233933 |
}
|
|
|
233933 |
|
|
|
233933 |
- if (op_errno == ENOENT) {
|
|
|
233933 |
+ if (op_errno == ENOATTR) {
|
|
|
233933 |
/* Do nothing, our defaults are set to this.
|
|
|
233933 |
*/
|
|
|
233933 |
goto unlock;
|
|
|
233933 |
@@ -4723,7 +4723,7 @@ dht_getxattr_get_real_filename(call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
233933 |
cnt = local->call_cnt = layout->cnt;
|
|
|
233933 |
|
|
|
233933 |
local->op_ret = -1;
|
|
|
233933 |
- local->op_errno = ENOENT;
|
|
|
233933 |
+ local->op_errno = ENOATTR;
|
|
|
233933 |
|
|
|
233933 |
for (i = 0; i < cnt; i++) {
|
|
|
233933 |
subvol = layout->list[i].xlator;
|
|
|
233933 |
diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c
|
|
|
233933 |
index c949f68..ea3b69c 100644
|
|
|
233933 |
--- a/xlators/storage/posix/src/posix-inode-fd-ops.c
|
|
|
233933 |
+++ b/xlators/storage/posix/src/posix-inode-fd-ops.c
|
|
|
233933 |
@@ -2954,7 +2954,7 @@ posix_xattr_get_real_filename(call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
233933 |
(void)sys_closedir(fd);
|
|
|
233933 |
|
|
|
233933 |
if (!found)
|
|
|
233933 |
- return -ENOENT;
|
|
|
233933 |
+ return -ENOATTR;
|
|
|
233933 |
|
|
|
233933 |
ret = dict_set_dynstr(dict, (char *)key, found);
|
|
|
233933 |
if (ret) {
|
|
|
233933 |
@@ -3422,7 +3422,7 @@ posix_getxattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
|
|
|
233933 |
if (ret < 0) {
|
|
|
233933 |
op_ret = -1;
|
|
|
233933 |
op_errno = -ret;
|
|
|
233933 |
- if (op_errno == ENOENT) {
|
|
|
233933 |
+ if (op_errno == ENOATTR) {
|
|
|
233933 |
gf_msg_debug(this->name, 0,
|
|
|
233933 |
"Failed to get "
|
|
|
233933 |
"real filename (%s, %s)",
|
|
|
233933 |
--
|
|
|
233933 |
1.8.3.1
|
|
|
233933 |
|