The main optimization is to avoid non_widelink_open() for streams
opens based on the fact that all streams opens are relative to
fsp->base_fsp, which is a pathref fsp already.
Neither streams_xattr nor streams_depot referenced dirfsp for the
streams case. Make this more obvious in the callers by passing NULL
and asserting this: non-streams opens and streams opens are just
different things, streams-opens can and do reference a base fsp and
don't need the non_widelink_open logic.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
}
fd = SMB_VFS_NEXT_OPENAT(handle,
- fsp->conn->cwd_fsp,
+ NULL, /* opening a stream */
fsp->fsp_name,
fsp,
fio->flags,
}
SMB_ASSERT(fsp_is_alternate_stream(fsp));
+ SMB_ASSERT(dirfsp == NULL);
SMB_ASSERT(VALID_STAT(fsp->base_fsp->fsp_name->st));
create_it = (mode & O_CREAT);
}
SMB_ASSERT(fsp_is_alternate_stream(fsp));
+ SMB_ASSERT(dirfsp == NULL);
status = streams_xattr_get_name(handle, talloc_tos(),
smb_fname->stream_name, &xattr_name);
fd = SMB_VFS_OPENAT(
conn,
- dirfsp,
+ NULL, /* stream open is relative to fsp->base_fsp */
smb_fname,
fsp,
O_RDONLY|O_NONBLOCK|O_NOFOLLOW,
flags |= O_NOFOLLOW;
}
+ if (fsp_is_alternate_stream(fsp)) {
+ int fd;
+
+ SMB_ASSERT(is_named_stream(smb_fname));
+
+ fd = SMB_VFS_OPENAT(
+ conn,
+ NULL, /* stream open is relative to fsp->base_fsp */
+ smb_fname,
+ fsp,
+ flags,
+ mode);
+ if (fd == -1) {
+ status = map_nt_error_from_unix(errno);
+ }
+ fsp_set_fd(fsp, fd);
+
+ if (fd != -1) {
+ status = vfs_stat_fsp(fsp);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("vfs_stat_fsp failed: %s\n",
+ nt_errstr(status));
+ fd_close(fsp);
+ }
+ }
+
+ return status;
+ }
+
/*
* Only follow symlinks within a share
* definition.
goto fail;
}
+ TALLOC_FREE(fspcwd);
+
fsp->base_fsp = base_name->fsp;
}