summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2017-05-23 17:44:16 +0200
committerKarolin Seeger <kseeger@samba.org>2017-08-14 10:50:10 +0200
commitb559efc42bb736b12c5fac4e92d4301486f48f3d (patch)
tree339e512487f77d6a8741ec67b08f67f4eb418dbe
parent379dbb5fe8c05d6bea0d332e0395bb07c0c5b07a (diff)
downloadsamba-b559efc42bb736b12c5fac4e92d4301486f48f3d.tar.gz
vfs_fruit: return fake pipe fd in fruit_open_meta_netatalk()
Do not open the basefile, that conflict with "kernel oplocks = yes". We just return a fake file fd based on dup'ing a pipe fd and ensure all VFS functions that go through vfs_fruit and work on the metadata stream can deal with it. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12791 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com> Reviewed-by: Volker Lendecke <vl@samba.org> (backported from commit 7583ee6e1c558067e4c7a7351085fcc0e4240366)
-rw-r--r--source3/modules/vfs_fruit.c73
1 files changed, 16 insertions, 57 deletions
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 8ed848ce481..bd3a49437f3 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -2684,56 +2684,24 @@ static int fruit_open_meta_netatalk(vfs_handle_struct *handle,
int flags,
mode_t mode)
{
- int rc = 0;
- struct smb_filename *smb_fname_base = NULL;
- int baseflags;
- int hostfd = -1;
+ int rc;
+ int fakefd = -1;
struct adouble *ad = NULL;
+ int fds[2];
DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
- /* Create an smb_filename with stream_name == NULL. */
- smb_fname_base = synthetic_smb_fname(talloc_tos(),
- smb_fname->base_name,
- NULL,
- NULL,
- smb_fname->flags);
-
- if (smb_fname_base == NULL) {
- errno = ENOMEM;
- rc = -1;
- goto exit;
- }
-
- /*
- * We use baseflags to turn off nasty side-effects when opening the
- * underlying file.
- */
- baseflags = flags;
- baseflags &= ~O_TRUNC;
- baseflags &= ~O_EXCL;
- baseflags &= ~O_CREAT;
-
- hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
- baseflags, mode);
-
/*
- * It is legit to open a stream on a directory, but the base
- * fd has to be read-only.
+ * Return a valid fd, but ensure any attempt to use it returns an error
+ * (EPIPE). All operations on the smb_fname or the fsp will use path
+ * based syscalls.
*/
- if ((hostfd == -1) && (errno == EISDIR)) {
- baseflags &= ~O_ACCMODE;
- baseflags |= O_RDONLY;
- hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
- baseflags, mode);
- }
-
- TALLOC_FREE(smb_fname_base);
-
- if (hostfd == -1) {
- rc = -1;
+ rc = pipe(fds);
+ if (rc != 0) {
goto exit;
}
+ fakefd = fds[0];
+ close(fds[1]);
if (flags & (O_CREAT | O_TRUNC)) {
/*
@@ -2746,10 +2714,7 @@ static int fruit_open_meta_netatalk(vfs_handle_struct *handle,
goto exit;
}
- fsp->fh->fd = hostfd;
-
- rc = ad_fset(ad, fsp);
- fsp->fh->fd = -1;
+ rc = ad_set(ad, fsp->fsp_name->base_name);
if (rc != 0) {
rc = -1;
goto exit;
@@ -2759,22 +2724,16 @@ static int fruit_open_meta_netatalk(vfs_handle_struct *handle,
}
exit:
- DEBUG(10, ("fruit_open meta rc=%d, fd=%d\n", rc, hostfd));
+ DEBUG(10, ("fruit_open meta rc=%d, fd=%d\n", rc, fakefd));
if (rc != 0) {
int saved_errno = errno;
- if (hostfd >= 0) {
- /*
- * BUGBUGBUG -- we would need to call
- * fd_close_posix here, but we don't have a
- * full fsp yet
- */
- fsp->fh->fd = hostfd;
- SMB_VFS_NEXT_CLOSE(handle, fsp);
+ if (fakefd >= 0) {
+ close(fakefd);
}
- hostfd = -1;
+ fakefd = -1;
errno = saved_errno;
}
- return hostfd;
+ return fakefd;
}
static int fruit_open_meta(vfs_handle_struct *handle,