mirror of
https://github.com/samba-team/samba.git
synced 2025-01-21 18:04:06 +03:00
smbd: Streamline recursive_rmdir()
By factoring out recursive_rmdir_fsp() we can do the recursion using openat_pathref_fsp_lcomp(). This makes strace for a recursive directory removal look a *lot* cleaner. Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Pavel Filipenský <pfilipensky@samba.org>
This commit is contained in:
parent
663f03996c
commit
83f7129e58
@ -974,10 +974,9 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
static NTSTATUS recursive_rmdir_fsp(struct files_struct *fsp)
|
||||||
connection_struct *conn,
|
|
||||||
struct smb_filename *smb_dname)
|
|
||||||
{
|
{
|
||||||
|
struct connection_struct *conn = fsp->conn;
|
||||||
const char *dname = NULL;
|
const char *dname = NULL;
|
||||||
char *talloced = NULL;
|
char *talloced = NULL;
|
||||||
struct smb_Dir *dir_hnd = NULL;
|
struct smb_Dir *dir_hnd = NULL;
|
||||||
@ -985,14 +984,7 @@ NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
|||||||
int retval;
|
int retval;
|
||||||
NTSTATUS status = NT_STATUS_OK;
|
NTSTATUS status = NT_STATUS_OK;
|
||||||
|
|
||||||
SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
|
status = OpenDir_from_pathref(talloc_tos(), fsp, NULL, 0, &dir_hnd);
|
||||||
|
|
||||||
status = OpenDir(talloc_tos(),
|
|
||||||
conn,
|
|
||||||
smb_dname,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
&dir_hnd);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -1001,9 +993,6 @@ NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
|||||||
|
|
||||||
while ((dname = ReadDirName(dir_hnd, &talloced))) {
|
while ((dname = ReadDirName(dir_hnd, &talloced))) {
|
||||||
struct smb_filename *atname = NULL;
|
struct smb_filename *atname = NULL;
|
||||||
struct smb_filename *smb_dname_full = NULL;
|
|
||||||
char *fullname = NULL;
|
|
||||||
bool do_break = true;
|
|
||||||
int unlink_flags = 0;
|
int unlink_flags = 0;
|
||||||
|
|
||||||
if (ISDOT(dname) || ISDOTDOT(dname)) {
|
if (ISDOT(dname) || ISDOTDOT(dname)) {
|
||||||
@ -1011,56 +1000,56 @@ NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct the full name. */
|
atname = synthetic_smb_fname(talloc_tos(),
|
||||||
fullname = talloc_asprintf(ctx,
|
dname,
|
||||||
"%s/%s",
|
NULL,
|
||||||
smb_dname->base_name,
|
NULL,
|
||||||
dname);
|
dirfsp->fsp_name->twrp,
|
||||||
if (!fullname) {
|
dirfsp->fsp_name->flags);
|
||||||
|
TALLOC_FREE(talloced);
|
||||||
|
dname = NULL;
|
||||||
|
|
||||||
|
if (atname == NULL) {
|
||||||
status = NT_STATUS_NO_MEMORY;
|
status = NT_STATUS_NO_MEMORY;
|
||||||
goto err_break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
smb_dname_full = synthetic_smb_fname(talloc_tos(),
|
{
|
||||||
fullname,
|
struct name_compare_entry *veto_list = conn->veto_list;
|
||||||
NULL,
|
|
||||||
NULL,
|
/*
|
||||||
smb_dname->twrp,
|
* Sneaky hack to be able to open veto files
|
||||||
smb_dname->flags);
|
* with openat_pathref_fsp
|
||||||
if (smb_dname_full == NULL) {
|
*/
|
||||||
status = NT_STATUS_NO_MEMORY;
|
|
||||||
goto err_break;
|
conn->veto_list = NULL;
|
||||||
|
status = openat_pathref_fsp_lcomp(
|
||||||
|
dirfsp,
|
||||||
|
atname,
|
||||||
|
UCF_POSIX_PATHNAMES /* no ci fallback */);
|
||||||
|
conn->veto_list = veto_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
status = map_nt_error_from_unix(errno);
|
TALLOC_FREE(atname);
|
||||||
goto err_break;
|
if (NT_STATUS_EQUAL(status,
|
||||||
|
NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
|
||||||
|
/* race between readdir and unlink */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
|
if (atname->st.st_ex_mode & S_IFDIR) {
|
||||||
status = recursive_rmdir(ctx, conn, smb_dname_full);
|
status = recursive_rmdir_fsp(atname->fsp);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
goto err_break;
|
TALLOC_FREE(atname);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
unlink_flags = AT_REMOVEDIR;
|
unlink_flags = AT_REMOVEDIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = synthetic_pathref(talloc_tos(),
|
|
||||||
dirfsp,
|
|
||||||
dname,
|
|
||||||
NULL,
|
|
||||||
&smb_dname_full->st,
|
|
||||||
smb_dname_full->twrp,
|
|
||||||
smb_dname_full->flags,
|
|
||||||
&atname);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
goto err_break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_visible_fsp(atname->fsp)) {
|
if (!is_visible_fsp(atname->fsp)) {
|
||||||
TALLOC_FREE(smb_dname_full);
|
|
||||||
TALLOC_FREE(fullname);
|
|
||||||
TALLOC_FREE(talloced);
|
|
||||||
TALLOC_FREE(atname);
|
TALLOC_FREE(atname);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1071,25 +1060,34 @@ NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
|||||||
unlink_flags);
|
unlink_flags);
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
status = map_nt_error_from_unix(errno);
|
status = map_nt_error_from_unix(errno);
|
||||||
goto err_break;
|
TALLOC_FREE(atname);
|
||||||
}
|
|
||||||
|
|
||||||
/* Successful iteration. */
|
|
||||||
do_break = false;
|
|
||||||
|
|
||||||
err_break:
|
|
||||||
TALLOC_FREE(smb_dname_full);
|
|
||||||
TALLOC_FREE(fullname);
|
|
||||||
TALLOC_FREE(talloced);
|
|
||||||
TALLOC_FREE(atname);
|
|
||||||
if (do_break) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
TALLOC_FREE(atname);
|
||||||
|
}
|
||||||
|
|
||||||
TALLOC_FREE(dir_hnd);
|
TALLOC_FREE(dir_hnd);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
|
||||||
|
connection_struct *conn,
|
||||||
|
struct smb_filename *smb_dname)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
|
||||||
|
|
||||||
|
status = openat_pathref_fsp(conn->cwd_fsp, smb_dname);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = recursive_rmdir_fsp(smb_dname->fsp);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
The internals of the rmdir code - called elsewhere.
|
The internals of the rmdir code - called elsewhere.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user