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

Jeremy Allison jra at samba.org
Mon Mar 21 01:02:22 UTC 2016


On Sun, Mar 20, 2016 at 03:53:19PM -0700, Richard Sharpe wrote:
> Hi folks,
> 
> Here is the patch for consideration.
> 
> I ran a make test on this and that seems to have succeeded.

Oh, ignore my previous complaint - this won't affect my
lp_posix_path() work...

This isn't a review (I'm still having my Sunday :-)
but I don't object to this going in before my lp_posix_pathname()
changes in case anyone reviews it before me :-).

> Richard Sharpe
> (何以解憂?唯有杜康。--曹操)

> From 7acb4eaf5236d8b833bc95f906ff0e12058cffb8 Mon Sep 17 00:00:00 2001
> From: Richard Sharpe <rsharpe at samba.org>
> Date: Sun, 20 Mar 2016 12:51:32 -0700
> Subject: [PATCH] S3: Add VFS functions for setting and getting DOS Attributes
>  and make Samba call them.
> 
> This will make it easier to support those systems and file systems that
> can store DOS attributes. It retains the original functionality if
> VFS functions providing these things are not provided.
> 
> Signed-off-by: Richard Sharpe <rsharpe at samba.org>
> ---
>  source3/include/vfs.h         | 28 ++++++++++++++++++++++++++++
>  source3/include/vfs_macros.h  | 18 ++++++++++++++++++
>  source3/modules/vfs_default.c | 32 ++++++++++++++++++++++++++++++++
>  source3/smbd/dosmode.c        | 29 +++++++++++++++--------------
>  source3/smbd/proto.h          |  8 ++++++++
>  source3/smbd/vfs.c            | 32 ++++++++++++++++++++++++++++++++
>  6 files changed, 133 insertions(+), 14 deletions(-)
> 
> diff --git a/source3/include/vfs.h b/source3/include/vfs.h
> index 1c6bc2f..f282f53 100644
> --- a/source3/include/vfs.h
> +++ b/source3/include/vfs.h
> @@ -776,6 +776,22 @@ struct vfs_fn_pointers {
>  			     uint32_t max_out_len,
>  			     uint32_t *out_len); 
>  
> +	bool (*set_dos_attributes_fn)(struct vfs_handle_struct *handle,
> +				      const struct smb_filename *smb_fname,
> +				      uint32_t dosmode);
> +
> +	bool (*fset_dos_attributes_fn)(struct vfs_handle_struct *hande,
> +				       struct files_struct *fsp,
> +				       uint32_t dosmode);
> +
> +	bool (*get_dos_attributes_fn)(struct vfs_handle_struct *handle,
> +				      const struct smb_filename *smb_fname,
> +				      uint32_t *dosmode);
> +
> +	bool (*fget_dos_attributes_fn)(struct vfs_handle_struct *handle,
> +				       struct files_struct *fsp,
> +				       uint32_t *dosmode);
> +
>  	/* NT ACL operations. */
>  
>  	NTSTATUS (*fget_nt_acl_fn)(struct vfs_handle_struct *handle,
> @@ -1196,6 +1212,18 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
>  			    uint8_t **_out_data,
>  			    uint32_t max_out_len,
>  			    uint32_t *out_len);
> +bool smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
> +				     const struct smb_filename *smb_fname,
> +				     uint32_t dosmode);
> +bool smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
> +				      struct files_struct *fsp,
> +				      uint32_t dosmode);
> +bool smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
> +				     const struct smb_filename *smb_fname,
> +				     uint32_t *dosmode);
> +bool smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
> +				      struct files_struct *fsp,
> +				      uint32_t *dosmode);
>  struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
>  						TALLOC_CTX *mem_ctx,
>  						struct tevent_context *ev,
> diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
> index 6059c2a..8d6086b 100644
> --- 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) \
> +	smb_vfs_call_fget_dos_attrbutes((handle)->next, (fsp), (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)
>  {
> diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
> index 776e91d..e0d0862 100644
> --- a/source3/smbd/proto.h
> +++ b/source3/smbd/proto.h
> @@ -278,6 +278,14 @@ bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime);
>  bool set_sticky_write_time_fsp(struct files_struct *fsp,
>  			       struct timespec mtime);
>  
> +bool set_ea_dos_attribute(connection_struct *conn,
> +			  const struct smb_filename *smb_fname,
> +			  uint32_t dosmode);
> +
> +bool get_ea_dos_attribute(connection_struct *conn,
> +			  const struct smb_filename *smb_fname,
> +			  uint32_t *pattr);
> +
>  NTSTATUS set_create_timespec_ea(connection_struct *conn,
>  				const struct smb_filename *smb_fname,
>  				struct timespec create_time);
> diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
> index a1154ae..5fbd6af 100644
> --- a/source3/smbd/vfs.c
> +++ b/source3/smbd/vfs.c
> @@ -2199,6 +2199,38 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
>  				     out_len);
>  }
>  
> +bool smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
> +				     const struct smb_filename *smb_fname,
> +				     uint32_t dosmode)
> +{
> +	VFS_FIND(set_dos_attributes);
> +	return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
> +}
> +
> +bool smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
> +				      struct files_struct *fsp,
> +				      uint32_t dosmode)
> +{
> +	VFS_FIND(set_dos_attributes);
> +	return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
> +}
> +
> +bool smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
> +				     const struct smb_filename *smb_fname,
> +				     uint32_t *dosmode)
> +{
> +	VFS_FIND(get_dos_attributes);
> +	return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
> +}
> +
> +bool smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
> +				      struct files_struct *fsp,
> +				      uint32_t *dosmode)
> +{
> +	VFS_FIND(fget_dos_attributes);
> +	return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
> +}
> +
>  struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
>  						TALLOC_CTX *mem_ctx,
>  						struct tevent_context *ev,
> -- 
> 2.4.3
> 




More information about the samba-technical mailing list