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