diff options
author | Volker Lendecke <vl@samba.org> | 2013-12-06 14:34:05 +0000 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2013-12-14 11:21:32 +0100 |
commit | 5baa7402ba8eebd9b2ddc6b259ae9bb2852b4bb1 (patch) | |
tree | 15e03048d58e05fb65e19a9b4cbd5d7d0b2da6b1 /source3/smbd/files.c | |
parent | 7a06b1661c1423780f05bc35ea435003712ca4b5 (diff) | |
download | samba-5baa7402ba8eebd9b2ddc6b259ae9bb2852b4bb1.tar.gz samba-5baa7402ba8eebd9b2ddc6b259ae9bb2852b4bb1.tar.xz samba-5baa7402ba8eebd9b2ddc6b259ae9bb2852b4bb1.zip |
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>
Diffstat (limited to 'source3/smbd/files.c')
-rw-r--r-- | source3/smbd/files.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/source3/smbd/files.c b/source3/smbd/files.c index c64c84173c..ba24eda27f 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -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; } |