diff options
author | Ralph Boehme <slow@samba.org> | 2017-05-23 17:44:16 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2017-08-14 10:50:10 +0200 |
commit | b559efc42bb736b12c5fac4e92d4301486f48f3d (patch) | |
tree | 339e512487f77d6a8741ec67b08f67f4eb418dbe | |
parent | 379dbb5fe8c05d6bea0d332e0395bb07c0c5b07a (diff) | |
download | samba-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.c | 73 |
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, |