mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
vfs_shadow_copy2: implement readdir()
RN: shadow_copy2 fails listing snapshotted dirs with shadow:fixinodes BUG: https://bugzilla.samba.org/show_bug.cgi?id=15035 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Thu Mar 31 18:47:42 UTC 2022 on sn-devel-184
This commit is contained in:
parent
ba9c5ba8ec
commit
9fa67ba8ee
@ -1 +0,0 @@
|
||||
^samba3.blackbox.shadow_copy_torture.fix inodes when listing directory\(fileserver\)
|
@ -3331,6 +3331,96 @@ static int shadow_copy2_connect(struct vfs_handle_struct *handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dirent *shadow_copy2_readdir(vfs_handle_struct *handle,
|
||||
struct files_struct *dirfsp,
|
||||
DIR *dirp,
|
||||
SMB_STRUCT_STAT *sbuf)
|
||||
{
|
||||
struct shadow_copy2_private *priv = NULL;
|
||||
struct dirent *ent = NULL;
|
||||
struct smb_filename atname;
|
||||
struct smb_filename *full_fname = NULL;
|
||||
time_t timestamp = 0;
|
||||
char *stripped = NULL;
|
||||
char *conv = NULL;
|
||||
char *abspath = NULL;
|
||||
bool converted = false;
|
||||
|
||||
SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
|
||||
return NULL);
|
||||
|
||||
ent = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, sbuf);
|
||||
if (ent == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (sbuf == NULL) {
|
||||
return ent;
|
||||
}
|
||||
if (ISDOT(dirfsp->fsp_name->base_name) && ISDOTDOT(ent->d_name)) {
|
||||
return ent;
|
||||
}
|
||||
|
||||
atname = (struct smb_filename) {
|
||||
.base_name = ent->d_name,
|
||||
.twrp = dirfsp->fsp_name->twrp,
|
||||
.flags = dirfsp->fsp_name->flags,
|
||||
};
|
||||
|
||||
full_fname = full_path_from_dirfsp_atname(talloc_tos(),
|
||||
dirfsp,
|
||||
&atname);
|
||||
if (full_fname == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!shadow_copy2_strip_snapshot_converted(talloc_tos(),
|
||||
handle,
|
||||
full_fname,
|
||||
×tamp,
|
||||
&stripped,
|
||||
&converted)) {
|
||||
TALLOC_FREE(full_fname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (timestamp == 0 && !converted) {
|
||||
/* Not a snapshot path, no need for convert_sbuf() */
|
||||
TALLOC_FREE(stripped);
|
||||
TALLOC_FREE(full_fname);
|
||||
return ent;
|
||||
}
|
||||
|
||||
if (timestamp == 0) {
|
||||
abspath = make_path_absolute(talloc_tos(),
|
||||
priv,
|
||||
full_fname->base_name);
|
||||
TALLOC_FREE(full_fname);
|
||||
if (abspath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
conv = shadow_copy2_convert(talloc_tos(),
|
||||
handle,
|
||||
stripped,
|
||||
timestamp);
|
||||
TALLOC_FREE(stripped);
|
||||
if (conv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
abspath = make_path_absolute(talloc_tos(), priv, conv);
|
||||
TALLOC_FREE(conv);
|
||||
if (abspath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
convert_sbuf(handle, abspath, sbuf);
|
||||
|
||||
TALLOC_FREE(abspath);
|
||||
return ent;
|
||||
}
|
||||
|
||||
static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
|
||||
.connect_fn = shadow_copy2_connect,
|
||||
.disk_free_fn = shadow_copy2_disk_free,
|
||||
@ -3362,6 +3452,7 @@ static struct vfs_fn_pointers vfs_shadow_copy2_fns = {
|
||||
.pwrite_recv_fn = shadow_copy2_pwrite_recv,
|
||||
.connectpath_fn = shadow_copy2_connectpath,
|
||||
.parent_pathname_fn = shadow_copy2_parent_pathname,
|
||||
.readdir_fn = shadow_copy2_readdir,
|
||||
};
|
||||
|
||||
static_decl_vfs;
|
||||
|
Loading…
Reference in New Issue
Block a user