mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
smbd: Implement and use full_path_tos
Yes, this looks like a hack, but talloc_asprintf does show up high in profiles called from these routines Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
7a06b1661c
commit
5baa7402ba
@ -688,6 +688,45 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
|
||||
return fsp_set_smb_fname(to, from->fsp_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine improves performance for operations temporarily acting on a
|
||||
* full path. It is equivalent to the much more expensive
|
||||
*
|
||||
* talloc_asprintf(talloc_tos(), "%s/%s", dir, name)
|
||||
*
|
||||
* This actually does make a difference in metadata-heavy workloads (i.e. the
|
||||
* "standard" client.txt nbench run.
|
||||
*/
|
||||
|
||||
ssize_t full_path_tos(const char *dir, const char *name,
|
||||
char *tmpbuf, size_t tmpbuf_len,
|
||||
char **pdst, char **to_free)
|
||||
{
|
||||
size_t dirlen, namelen, len;
|
||||
char *dst;
|
||||
|
||||
dirlen = strlen(dir);
|
||||
namelen = strlen(name);
|
||||
len = dirlen + namelen + 1;
|
||||
|
||||
if (len < tmpbuf_len) {
|
||||
dst = tmpbuf;
|
||||
*to_free = NULL;
|
||||
} else {
|
||||
dst = talloc_array(talloc_tos(), char, len+1);
|
||||
if (dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*to_free = dst;
|
||||
}
|
||||
|
||||
memcpy(dst, dir, dirlen);
|
||||
dst[dirlen] = '/';
|
||||
memcpy(dst+dirlen+1, name, namelen+1);
|
||||
*pdst = dst;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a jenkins hash of a pathname on a connection.
|
||||
*/
|
||||
@ -695,23 +734,24 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
|
||||
NTSTATUS file_name_hash(connection_struct *conn,
|
||||
const char *name, uint32_t *p_name_hash)
|
||||
{
|
||||
char *fullpath = NULL;
|
||||
char tmpbuf[1024];
|
||||
char *fullpath, *to_free;
|
||||
size_t len;
|
||||
|
||||
/* Set the hash of the full pathname. */
|
||||
fullpath = talloc_asprintf(talloc_tos(),
|
||||
"%s/%s",
|
||||
conn->connectpath,
|
||||
name);
|
||||
if (!fullpath) {
|
||||
|
||||
len = full_path_tos(conn->connectpath, name, tmpbuf, sizeof(tmpbuf),
|
||||
&fullpath, &to_free);
|
||||
if (len == -1) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
*p_name_hash = hash(fullpath, talloc_get_size(fullpath), 0);
|
||||
*p_name_hash = hash(fullpath, len+1, 0);
|
||||
|
||||
DEBUG(10,("file_name_hash: %s hash 0x%x\n",
|
||||
fullpath,
|
||||
fullpath,
|
||||
(unsigned int)*p_name_hash ));
|
||||
|
||||
TALLOC_FREE(fullpath);
|
||||
TALLOC_FREE(to_free);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -418,19 +418,21 @@ void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
|
||||
const char *path)
|
||||
{
|
||||
struct notify_context *notify_ctx = conn->sconn->notify_ctx;
|
||||
char *fullpath;
|
||||
char *fullpath, *to_free;
|
||||
char tmpbuf[1024];
|
||||
ssize_t len;
|
||||
|
||||
if (path[0] == '.' && path[1] == '/') {
|
||||
path += 2;
|
||||
}
|
||||
fullpath = talloc_asprintf(talloc_tos(), "%s/%s", conn->connectpath,
|
||||
path);
|
||||
if (fullpath == NULL) {
|
||||
DEBUG(0, ("asprintf failed\n"));
|
||||
len = full_path_tos(conn->connectpath, path, tmpbuf, sizeof(tmpbuf),
|
||||
&fullpath, &to_free);
|
||||
if (len == -1) {
|
||||
DEBUG(0, ("full_path_tos failed\n"));
|
||||
return;
|
||||
}
|
||||
notify_trigger(notify_ctx, action, filter, fullpath);
|
||||
TALLOC_FREE(fullpath);
|
||||
TALLOC_FREE(to_free);
|
||||
}
|
||||
|
||||
static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
|
||||
|
@ -397,6 +397,9 @@ NTSTATUS file_name_hash(connection_struct *conn,
|
||||
const char *name, uint32_t *p_name_hash);
|
||||
NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
|
||||
const struct smb_filename *smb_fname_in);
|
||||
ssize_t full_path_tos(const char *dir, const char *name,
|
||||
char *tmpbuf, size_t tmpbuf_len,
|
||||
char **pdst, char **to_free);
|
||||
|
||||
/* The following definitions come from smbd/ipc.c */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user