Patch: S3-Add VFS Functions for setting and getting DOS Attributes

Christof Schmitt cs at samba.org
Wed Mar 23 21:36:12 UTC 2016


Richard,

see below for some comments when compiling this with --picky-developer
and implementing the callbacks in the gpfs module.

Christof

On Sun, Mar 20, 2016 at 03:53:19PM -0700, Richard Sharpe wrote:

> --- a/source3/include/vfs_macros.h
> +++ b/source3/include/vfs_macros.h
> @@ -397,6 +397,24 @@
>  #define SMB_VFS_NEXT_FSCTL(handle, fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \
>  	smb_vfs_call_fsctl((handle)->next, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len))
>  
> +#define SMB_VFS_SET_DOS_ATTRIBUTES(conn, smb_fname, attributes) \
> +	smb_vfs_call_set_dos_attributes((conn)->vfs_handles, (smb_fname), (attributes))
> +#define SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle, smb_fname, attributes) \
> +	smb_vfs_call_set_dos_attributes((handle)->next, (smb_fname), (attributes))
> +#define SMB_VFS_FSET_DOS_ATTRIBUTES(conn, fsp, attributes) \
> +	smb_vfs_call_fset_dos_attributes((conn)->vfs_handles, (fsp), (attributes))
> +#define SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, attributes) \
> +	smb_vfs_call_fset_dos_attributes((handle)->next, (fsp), (attributes))
> +
> +#define SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, attributes) \
> +	smb_vfs_call_get_dos_attributes((conn)->vfs_handles, (smb_fname), (attributes))
> +#define SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname, attributes) \
> +	smb_vfs_call_get_dos_attributes((handle)->next, (smb_fname), (attributes))
> +#define SMB_VFS_FGET_DOS_ATTRIBUTES(conn, fsp, attributes) \
> +	smb_vfs_call_fget_dos_attributes((conn)->vfs_handles, (fsp), (attributes))
> +#define SMB_VFS_FGET_NEXT_DOS_ATTRIBUTES(handle, fsp, attributes) \

This should probably by SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES for
consistency.

> +	smb_vfs_call_fget_dos_attrbutes((handle)->next, (fsp), (attributes))

Typo, this should be smb_vfs_call_fget_dos_attributes

> +
>  #define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
>  	smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num))
>  #define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
> diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
> index ea7dc2c..caefb5d 100644
> --- a/source3/modules/vfs_default.c
> +++ b/source3/modules/vfs_default.c
> @@ -1420,6 +1420,34 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
>  	return NT_STATUS_NOT_SUPPORTED;
>  }
>  
> +static bool vfswrap_set_dos_attributes(struct vfs_handle_struct *handle,
> +				       const struct smb_filename *smb_fname,
> +				       uint32_t dosmode)
> +{
> +	return set_ea_dos_attribute(handle->conn, smb_fname, dosmode);
> +}
> +
> +static bool vfswrap_fset_dos_attributes(struct vfs_handle_struct *handle,
> +					struct files_struct *fsp,
> +					uint32_t dosmode)
> +{
> +	return set_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
> +}
> +
> +static bool vfswrap_get_dos_attributes(struct vfs_handle_struct *handle,
> +				       const struct smb_filename *smb_fname,
> +				       uint32_t *dosmode)
> +{
> +	return get_ea_dos_attribute(handle->conn, smb_fname, dosmode);
> +}
> +
> +static bool vfswrap_fget_dos_attributes(struct vfs_handle_struct *handle,
> +					struct files_struct *fsp,
> +					uint32_t *dosmode)
> +{
> +	return get_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
> +}
> +
>  struct vfs_cc_state {
>  	off_t copied;
>  	uint8_t *buf;
> @@ -2641,6 +2669,10 @@ static struct vfs_fn_pointers vfs_default_fns = {
>  	.strict_unlock_fn = vfswrap_strict_unlock,
>  	.translate_name_fn = vfswrap_translate_name,
>  	.fsctl_fn = vfswrap_fsctl,
> +	.set_dos_attributes_fn = vfswrap_set_dos_attributes,
> +	.fset_dos_attributes_fn = vfswrap_fset_dos_attributes,
> +	.get_dos_attributes_fn = vfswrap_get_dos_attributes,
> +	.fget_dos_attributes_fn = vfswrap_fget_dos_attributes,
>  	.copy_chunk_send_fn = vfswrap_copy_chunk_send,
>  	.copy_chunk_recv_fn = vfswrap_copy_chunk_recv,
>  	.get_compression_fn = vfswrap_get_compression,
> diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
> index 60761c2..714d8d2 100644
> --- a/source3/smbd/dosmode.c
> +++ b/source3/smbd/dosmode.c
> @@ -27,7 +27,7 @@
>  #include "lib/param/loadparm.h"
>  
>  static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
> -				struct smb_filename *smb_fname,
> +				const struct smb_filename *smb_fname,
>  				files_struct **ret_fsp,
>  				bool *need_close);
>  
> @@ -257,9 +257,9 @@ static uint32_t dos_mode_from_sbuf(connection_struct *conn,
>   This can also pull the create time into the stat struct inside smb_fname.
>  ****************************************************************************/
>  
> -static bool get_ea_dos_attribute(connection_struct *conn,
> -				 struct smb_filename *smb_fname,
> -				 uint32_t *pattr)
> +bool get_ea_dos_attribute(connection_struct *conn,
> +			  const struct smb_filename *smb_fname,
> +			  uint32_t *pattr)
>  {
>  	struct xattr_DOSATTRIB dosattrib;
>  	enum ndr_err_code ndr_err;
> @@ -309,11 +309,12 @@ static bool get_ea_dos_attribute(connection_struct *conn,
>  		case 1:
>  			dosattr = dosattrib.info.info1.attrib;
>  			if (!null_nttime(dosattrib.info.info1.create_time)) {
> +				struct smb_filename *fname = discard_const(smb_fname);
>  				struct timespec create_time =
>  					nt_time_to_unix_timespec(
>  						dosattrib.info.info1.create_time);
>  
> -				update_stat_ex_create_time(&smb_fname->st,
> +				update_stat_ex_create_time(&fname->st,
>  							create_time);
>  
>  				DEBUG(10,("get_ea_dos_attribute: file %s case 1 "
> @@ -331,11 +332,12 @@ static bool get_ea_dos_attribute(connection_struct *conn,
>  			dosattr = dosattrib.info.info3.attrib;
>  			if ((dosattrib.info.info3.valid_flags & XATTR_DOSINFO_CREATE_TIME) &&
>  					!null_nttime(dosattrib.info.info3.create_time)) {
> +				struct smb_filename *fname = discard_const(smb_fname);
>  				struct timespec create_time =
>  					nt_time_to_unix_timespec(
>  						dosattrib.info.info3.create_time);
>  
> -				update_stat_ex_create_time(&smb_fname->st,
> +				update_stat_ex_create_time(&fname->st,
>  							create_time);
>  
>  				DEBUG(10,("get_ea_dos_attribute: file %s case 3 "
> @@ -368,9 +370,9 @@ static bool get_ea_dos_attribute(connection_struct *conn,
>   Also sets the create time.
>  ****************************************************************************/
>  
> -static bool set_ea_dos_attribute(connection_struct *conn,
> -				 struct smb_filename *smb_fname,
> -				 uint32_t dosmode)
> +bool set_ea_dos_attribute(connection_struct *conn,
> +			  const struct smb_filename *smb_fname,
> +			  uint32_t dosmode)
>  {
>  	struct xattr_DOSATTRIB dosattrib;
>  	enum ndr_err_code ndr_err;
> @@ -587,7 +589,7 @@ uint32_t dos_mode(connection_struct *conn, struct smb_filename *smb_fname)
>  	}
>  
>  	/* Get the DOS attributes from an EA by preference. */
> -	if (!get_ea_dos_attribute(conn, smb_fname, &result)) {
> +	if (!SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result)) {
>  		result |= dos_mode_from_sbuf(conn, smb_fname);
>  	}
>  
> @@ -698,7 +700,7 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
>  		 * Don't fall back to using UNIX modes. Finally
>  		 * follow the smb.conf manpage.
>  		 */
> -		if (!set_ea_dos_attribute(conn, smb_fname, dosmode)) {
> +		if (!SMB_VFS_SET_DOS_ATTRIBUTES(conn, smb_fname, dosmode)) {
>  			return -1;
>  		}
>  		if (!newfile) {
> @@ -893,8 +895,7 @@ NTSTATUS file_set_sparse(connection_struct *conn,
>  	}
>  
>  	/* Store the DOS attributes in an EA. */
> -	if (!set_ea_dos_attribute(conn, fsp->fsp_name,
> -				  new_dosmode)) {
> +	if (!SMB_VFS_FSET_DOS_ATTRIBUTES(conn, fsp, new_dosmode)) {
>  		if (errno == 0) {
>  			errno = EIO;
>  		}
> @@ -1074,7 +1075,7 @@ struct timespec get_change_timespec(connection_struct *conn,
>  ****************************************************************************/
>  
>  static NTSTATUS get_file_handle_for_metadata(connection_struct *conn,
> -				struct smb_filename *smb_fname,
> +				const struct smb_filename *smb_fname,
>  				files_struct **ret_fsp,
>  				bool *need_close)

This resulted in a compile error with --picky-developer for me:
get_file_handle_for_metadata calls SMB_VFS_CREATE_FILE and that takes
smb_fname without the const. Maybe it would be better to remove the
const from smb_fname again.




More information about the samba-technical mailing list