From f6650f5d19ad90b8e1f392efbe211c4ffa0e70c0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 16 Nov 2009 09:49:23 +0100 Subject: s3: Do not talloc in readdir This is a hot codepath (called from the stat cache) --- source3/smbd/reply.c | 94 ++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 43 deletions(-) (limited to 'source3/smbd/reply.c') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b4e0f57400..ae88db7562 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2584,7 +2584,8 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, } else { struct smb_Dir *dir_hnd = NULL; long offset = 0; - char *dname = NULL; + const char *dname = NULL; + char *talloced = NULL; if ((dirtype & SAMBA_ATTRIBUTES_MASK) == aDIR) { status = NT_STATUS_OBJECT_NAME_INVALID; @@ -2620,27 +2621,27 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, status = NT_STATUS_NO_SUCH_FILE; while ((dname = ReadDirName(dir_hnd, &offset, - &smb_fname->st))) { + &smb_fname->st, &talloced))) { TALLOC_CTX *frame = talloc_stackframe(); if (!is_visible_file(conn, fname_dir, dname, &smb_fname->st, true)) { TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } /* Quick check for "." and ".." */ if (ISDOT(dname) || ISDOTDOT(dname)) { TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if(!mask_match(dname, fname_mask, conn->case_sensitive)) { TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -2653,7 +2654,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, TALLOC_FREE(dir_hnd); status = NT_STATUS_NO_MEMORY; TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); goto out; } @@ -2661,14 +2662,14 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); goto out; } status = do_unlink(conn, req, smb_fname, dirtype); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -2677,7 +2678,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, smb_fname->base_name)); TALLOC_FREE(frame); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); } TALLOC_FREE(dir_hnd); } @@ -5298,7 +5299,8 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, connection_struct *conn, struct smb_filename *smb_dname) { - char *dname = NULL; + const char *dname = NULL; + char *talloced = NULL; bool ret = True; long offset = 0; SMB_STRUCT_STAT st; @@ -5310,20 +5312,20 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, if(dir_hnd == NULL) return False; - while((dname = ReadDirName(dir_hnd, &offset, &st))) { + while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) { struct smb_filename *smb_dname_full = NULL; char *fullname = NULL; bool do_break = true; NTSTATUS status; if (ISDOT(dname) || ISDOTDOT(dname)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -5366,7 +5368,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, err_break: TALLOC_FREE(smb_dname_full); TALLOC_FREE(fullname); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); if (do_break) { ret = false; break; @@ -5420,7 +5422,8 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, * do a recursive delete) then fail the rmdir. */ SMB_STRUCT_STAT st; - char *dname = NULL; + const char *dname = NULL; + char *talloced = NULL; long dirpos = 0; struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, @@ -5431,23 +5434,24 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, goto err; } - while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) { + while ((dname = ReadDirName(dir_hnd, &dirpos, &st, + &talloced)) != NULL) { if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if(!IS_VETO_PATH(conn, dname)) { TALLOC_FREE(dir_hnd); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); errno = ENOTEMPTY; goto err; } - TALLOC_FREE(dname); + TALLOC_FREE(talloced); } /* We only have veto files/directories. @@ -5461,19 +5465,20 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, /* Do a recursive delete. */ RewindDir(dir_hnd,&dirpos); - while ((dname = ReadDirName(dir_hnd, &dirpos, &st))) { + while ((dname = ReadDirName(dir_hnd, &dirpos, &st, + &talloced)) != NULL) { struct smb_filename *smb_dname_full = NULL; char *fullname = NULL; bool do_break = true; NTSTATUS status; if (ISDOT(dname) || ISDOTDOT(dname)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -5518,7 +5523,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, err_break: TALLOC_FREE(fullname); TALLOC_FREE(smb_dname_full); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); if (do_break) break; } @@ -6131,7 +6136,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, int count=0; NTSTATUS status = NT_STATUS_OK; struct smb_Dir *dir_hnd = NULL; - char *dname = NULL; + const char *dname = NULL; + char *talloced = NULL; long offset = 0; int create_options = 0; bool posix_pathnames = lp_posix_pathnames(); @@ -6309,7 +6315,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, * - gentest fix. JRA */ - while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname_src->st))) { + while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname_src->st, + &talloced))) { files_struct *fsp = NULL; char *destname = NULL; bool sysdir_entry = False; @@ -6319,19 +6326,19 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, if (attrs & aDIR) { sysdir_entry = True; } else { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } } if (!is_visible_file(conn, fname_src_dir, dname, &smb_fname_src->st, false)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -6355,7 +6362,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, &destname)) { DEBUG(6, ("resolve_wildcards %s %s failed\n", smb_fname_src->base_name, destname)); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!destname) { @@ -6431,7 +6438,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, DEBUG(3,("rename_internals: doing rename on %s -> " "%s\n", smb_fname_str_dbg(smb_fname_src), smb_fname_str_dbg(smb_fname_src))); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); } TALLOC_FREE(dir_hnd); @@ -6440,7 +6447,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, } out: - TALLOC_FREE(dname); + TALLOC_FREE(talloced); TALLOC_FREE(fname_src_dir); TALLOC_FREE(fname_src_mask); return status; @@ -6905,7 +6912,8 @@ void reply_copy(struct smb_request *req) } } else { struct smb_Dir *dir_hnd = NULL; - char *dname = NULL; + const char *dname = NULL; + char *talloced = NULL; long offset = 0; /* @@ -6946,23 +6954,23 @@ void reply_copy(struct smb_request *req) /* Iterate over the src dir copying each entry to the dst. */ while ((dname = ReadDirName(dir_hnd, &offset, - &smb_fname_src->st))) { + &smb_fname_src->st, &talloced))) { char *destname = NULL; if (ISDOT(dname) || ISDOTDOT(dname)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, fname_src_dir, dname, &smb_fname_src->st, false)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } @@ -6976,7 +6984,7 @@ void reply_copy(struct smb_request *req) if (!smb_fname_src->base_name) { TALLOC_FREE(dir_hnd); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); reply_nterror(req, NT_STATUS_NO_MEMORY); goto out; } @@ -6984,12 +6992,12 @@ void reply_copy(struct smb_request *req) if (!resolve_wildcards(ctx, smb_fname_src->base_name, smb_fname_dst->base_name, &destname)) { - TALLOC_FREE(dname); + TALLOC_FREE(talloced); continue; } if (!destname) { TALLOC_FREE(dir_hnd); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); reply_nterror(req, NT_STATUS_NO_MEMORY); goto out; } @@ -7000,7 +7008,7 @@ void reply_copy(struct smb_request *req) status = check_name(conn, smb_fname_src->base_name); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); reply_nterror(req, status); goto out; } @@ -7008,7 +7016,7 @@ void reply_copy(struct smb_request *req) status = check_name(conn, smb_fname_dst->base_name); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(dir_hnd); - TALLOC_FREE(dname); + TALLOC_FREE(talloced); reply_nterror(req, status); goto out; } @@ -7024,7 +7032,7 @@ void reply_copy(struct smb_request *req) count++; } - TALLOC_FREE(dname); + TALLOC_FREE(talloced); } TALLOC_FREE(dir_hnd); } -- cgit