mirror of
https://github.com/samba-team/samba.git
synced 2025-03-20 22:50:26 +03:00
vfs_fruit: filter empty streams
First step in achieving macOS compliant behaviour wrt to empty streams: - hide empty streams in streaminfo - prevent opens of empty streams This means that we may carry 0-byte sized streams in our streams backend, but this shouldn't really hurt. The previous attempt of deleting the streams when an SMB setinfo eof to 0 request came in, turned out be a road into desaster. We could set delete-on-close on the stream, but that means we'd have to check for it for every write on a stream and checking the delete-on-close bits requires fetching the locking.tdb record, so this is expensive and I'd like to avoid that overhead. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13646 Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit ebfcf75e993b1a792db76b94aa898532e1c81eeb)
This commit is contained in:
parent
b0657faba4
commit
2807227349
@ -1,5 +1,2 @@
|
||||
^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion\(nt4_dc\)
|
||||
^samba3.vfs.fruit streams_depot.OS X AppleDouble file conversion without embedded xattr\(nt4_dc\)
|
||||
^samba3.vfs.fruit metadata_netatalk.setinfo eof stream\(nt4_dc\)
|
||||
^samba3.vfs.fruit metadata_stream.setinfo eof stream\(nt4_dc\)
|
||||
^samba3.vfs.fruit streams_depot.setinfo eof stream\(nt4_dc\)
|
||||
|
@ -5578,6 +5578,36 @@ static NTSTATUS fruit_streaminfo_rsrc(vfs_handle_struct *handle,
|
||||
return status;
|
||||
}
|
||||
|
||||
static void fruit_filter_empty_streams(unsigned int *pnum_streams,
|
||||
struct stream_struct **pstreams)
|
||||
{
|
||||
unsigned num_streams = *pnum_streams;
|
||||
struct stream_struct *streams = *pstreams;
|
||||
unsigned i = 0;
|
||||
|
||||
if (!global_fruit_config.nego_aapl) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i < num_streams) {
|
||||
struct smb_filename smb_fname = (struct smb_filename) {
|
||||
.stream_name = streams[i].name,
|
||||
};
|
||||
|
||||
if (is_ntfs_default_stream_smb_fname(&smb_fname)
|
||||
|| streams[i].size > 0)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
streams[i] = streams[num_streams - 1];
|
||||
num_streams--;
|
||||
}
|
||||
|
||||
*pnum_streams = num_streams;
|
||||
}
|
||||
|
||||
static NTSTATUS fruit_streaminfo(vfs_handle_struct *handle,
|
||||
struct files_struct *fsp,
|
||||
const struct smb_filename *smb_fname,
|
||||
@ -5599,6 +5629,8 @@ static NTSTATUS fruit_streaminfo(vfs_handle_struct *handle,
|
||||
return status;
|
||||
}
|
||||
|
||||
fruit_filter_empty_streams(pnum_streams, pstreams);
|
||||
|
||||
status = fruit_streaminfo_meta(handle, fsp, smb_fname,
|
||||
mem_ctx, pnum_streams, pstreams);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -5868,13 +5900,13 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle,
|
||||
* Cf the vfs_fruit torture tests in test_rfork_create().
|
||||
*/
|
||||
if (global_fruit_config.nego_aapl &&
|
||||
is_afpresource_stream(fsp->fsp_name) &&
|
||||
create_disposition == FILE_OPEN)
|
||||
create_disposition == FILE_OPEN &&
|
||||
smb_fname->st.st_ex_size == 0 &&
|
||||
is_ntfs_stream_smb_fname(smb_fname) &&
|
||||
!(is_ntfs_default_stream_smb_fname(smb_fname)))
|
||||
{
|
||||
if (fsp->fsp_name->st.st_ex_size == 0) {
|
||||
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto fail;
|
||||
}
|
||||
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (is_ntfs_stream_smb_fname(smb_fname)
|
||||
|
Loading…
x
Reference in New Issue
Block a user