summaryrefslogtreecommitdiff
path: root/source3/smbd/vfs.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-11-16 09:49:23 +0100
committerVolker Lendecke <vl@samba.org>2009-11-18 23:16:13 +0100
commitf6650f5d19ad90b8e1f392efbe211c4ffa0e70c0 (patch)
tree6091c37e17a96edaaab867094b99bfe8c5aa456d /source3/smbd/vfs.c
parentaea3a8f50131744f8393d0179cd04a1b97982028 (diff)
downloadsamba-f6650f5d19ad90b8e1f392efbe211c4ffa0e70c0.tar.gz
s3: Do not talloc in readdir
This is a hot codepath (called from the stat cache)
Diffstat (limited to 'source3/smbd/vfs.c')
-rw-r--r--source3/smbd/vfs.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 668defa5701..1510bfcdd53 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -659,11 +659,13 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
A vfs_readdir wrapper which just returns the file name.
********************************************************************/
-char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
+const char *vfs_readdirname(connection_struct *conn, void *p,
+ SMB_STRUCT_STAT *sbuf, char **talloced)
{
SMB_STRUCT_DIRENT *ptr= NULL;
- char *dname = NULL;
- NTSTATUS result;
+ const char *dname;
+ char *translated;
+ NTSTATUS status;
if (!p)
return(NULL);
@@ -672,17 +674,8 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
if (!ptr)
return(NULL);
- dname = talloc_strdup(talloc_tos(), ptr->d_name);
- if (dname == NULL) {
- errno = ENOMEM;
- return NULL;
- }
- result = SMB_VFS_TRANSLATE_NAME(conn, &dname,
- vfs_translate_to_windows);
- if (!NT_STATUS_IS_OK(result)) {
- TALLOC_FREE(dname);
- return NULL;
- }
+ dname = ptr->d_name;
+
#ifdef NEXT2
if (telldir(p) < 0)
@@ -694,7 +687,17 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
dname = dname - 2;
#endif
- return(dname);
+ status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
+ talloc_tos(), &translated);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
+ *talloced = NULL;
+ return dname;
+ }
+ *talloced = translated;
+ if (!NT_STATUS_IS_OK(status)) {
+ return NULL;
+ }
+ return translated;
}
/*******************************************************************
@@ -1550,11 +1553,14 @@ void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
}
NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
- char **mapped_name,
- enum vfs_translate_direction direction)
+ const char *name,
+ enum vfs_translate_direction direction,
+ TALLOC_CTX *mem_ctx,
+ char **mapped_name)
{
VFS_FIND(translate_name);
- return handle->fns->translate_name(handle, mapped_name, direction);
+ return handle->fns->translate_name(handle, name, direction, mem_ctx,
+ mapped_name);
}
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,