1
0
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:
Volker Lendecke 2013-12-06 14:34:05 +00:00 committed by Stefan Metzmacher
parent 7a06b1661c
commit 5baa7402ba
3 changed files with 60 additions and 15 deletions

View File

@ -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;
}

View File

@ -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)

View File

@ -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 */