[PATCHES] vfs_gpfs: Implement new dos_attributes vfs functions

Jeremy Allison jra at samba.org
Fri Apr 1 17:26:29 UTC 2016


On Thu, Mar 31, 2016 at 03:20:55PM -0700, Christof Schmitt wrote:
> On Thu, Mar 31, 2016 at 01:40:28PM -0700, Jeremy Allison wrote:
> > NAK. The get path needs fixing.
> > 
> > I know this *sucks*, but the dos_mode()
> > function does the filename dot-path -> HIDDEN
> > attribute mapping *before* calling:
> > 
> > SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &result);
> > 
> > so that means that inside your version of
> > VFS_GET_DOS_ATTRIBUTES you can't just overwrite
> > 
> > *presult = XXXX;
> > 
> > as it may already have FILE_ATTRIBUTE_HIDDEN set.
> > 
> > You have to do:
> > 
> > *presult |= XXXX;
> > 
> > instead.
> 
> Right. Sorry for missing this. Fixed in the attached patches.

No worries - LGTM. Pushed !

> From 2f2abceda5791e1218db4b3a6b9c2dccf2f5f776 Mon Sep 17 00:00:00 2001
> From: Christof Schmitt <cs at samba.org>
> Date: Tue, 22 Mar 2016 22:38:11 -0700
> Subject: [PATCH 1/3] gpfswrap: Add wrapper for gpfs_set_winattrs
> 
> Signed-off-by: Christof Schmitt <cs at samba.org>
> ---
>  lib/util/gpfswrap.c | 13 +++++++++++++
>  lib/util/gpfswrap.h |  1 +
>  2 files changed, 14 insertions(+)
> 
> diff --git a/lib/util/gpfswrap.c b/lib/util/gpfswrap.c
> index 4c74105..0632ee2 100644
> --- a/lib/util/gpfswrap.c
> +++ b/lib/util/gpfswrap.c
> @@ -29,6 +29,8 @@ static int (*gpfs_get_realfilename_path_fn)(char *pathname, char *filenamep,
>  					    int *len);
>  static int (*gpfs_set_winattrs_path_fn)(char *pathname, int flags,
>  					struct gpfs_winattr *attrs);
> +static int (*gpfs_set_winattrs_fn)(int fd, int flags,
> +				   struct gpfs_winattr *attrs);
>  static int (*gpfs_get_winattrs_path_fn)(char *pathname,
>  					struct gpfs_winattr *attrs);
>  static int (*gpfs_get_winattrs_fn)(int fd, struct gpfs_winattr *attrs);
> @@ -63,6 +65,7 @@ int gpfswrap_init(void)
>  	gpfs_putacl_fn		      = dlsym(l, "gpfs_putacl");
>  	gpfs_get_realfilename_path_fn = dlsym(l, "gpfs_get_realfilename_path");
>  	gpfs_set_winattrs_path_fn     = dlsym(l, "gpfs_set_winattrs_path");
> +	gpfs_set_winattrs_fn	      = dlsym(l, "gpfs_set_winattrs");
>  	gpfs_get_winattrs_path_fn     = dlsym(l, "gpfs_get_winattrs_path");
>  	gpfs_get_winattrs_fn	      = dlsym(l, "gpfs_get_winattrs");
>  	gpfs_prealloc_fn	      = dlsym(l, "gpfs_prealloc");
> @@ -140,6 +143,16 @@ int gpfswrap_set_winattrs_path(char *pathname, int flags,
>  	return gpfs_set_winattrs_path_fn(pathname, flags, attrs);
>  }
>  
> +int gpfswrap_set_winattrs(int fd, int flags, struct gpfs_winattr *attrs)
> +{
> +	if (gpfs_set_winattrs_fn == NULL) {
> +		errno = ENOSYS;
> +		return -1;
> +	}
> +
> +	return gpfs_set_winattrs_fn(fd, flags, attrs);
> +}
> +
>  int gpfswrap_get_winattrs_path(char *pathname, struct gpfs_winattr *attrs)
>  {
>  	if (gpfs_get_winattrs_path_fn == NULL) {
> diff --git a/lib/util/gpfswrap.h b/lib/util/gpfswrap.h
> index 25b1ba8..1c9c64f 100644
> --- a/lib/util/gpfswrap.h
> +++ b/lib/util/gpfswrap.h
> @@ -34,6 +34,7 @@ int gpfswrap_putacl(char *pathname, int flags, void *acl);
>  int gpfswrap_get_realfilename_path(char *pathname, char *filenamep, int *len);
>  int gpfswrap_set_winattrs_path(char *pathname, int flags,
>  			       struct gpfs_winattr *attrs);
> +int gpfswrap_set_winattrs(int fd, int flags, struct gpfs_winattr *attrs);
>  int gpfswrap_get_winattrs_path(char *pathname, struct gpfs_winattr *attrs);
>  int gpfswrap_get_winattrs(int fd, struct gpfs_winattr *attrs);
>  int gpfswrap_prealloc(int fd, gpfs_off64_t start, gpfs_off64_t bytes);
> -- 
> 1.8.3.1
> 
> 
> From eeb1d6a538e507989d10fd500e8c62a20f91a2e7 Mon Sep 17 00:00:00 2001
> From: Christof Schmitt <cs at samba.org>
> Date: Tue, 22 Mar 2016 22:39:11 -0700
> Subject: [PATCH 2/3] vfs_gpfs: Implement new dos_attributes vfs functions
> 
> Signed-off-by: Christof Schmitt <cs at samba.org>
> ---
>  source3/modules/vfs_gpfs.c | 184 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 184 insertions(+)
> 
> diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
> index 04d89f4..42dc4e8 100644
> --- a/source3/modules/vfs_gpfs.c
> +++ b/source3/modules/vfs_gpfs.c
> @@ -1449,6 +1449,186 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t
>  		 return rc;
>  }
>  
> +static uint32_t vfs_gpfs_winattrs_to_dosmode(unsigned int winattrs)
> +{
> +	uint32_t dosmode = 0;
> +
> +	if (winattrs & GPFS_WINATTR_ARCHIVE){
> +		dosmode |= FILE_ATTRIBUTE_ARCHIVE;
> +	}
> +	if (winattrs & GPFS_WINATTR_HIDDEN){
> +		dosmode |= FILE_ATTRIBUTE_HIDDEN;
> +	}
> +	if (winattrs & GPFS_WINATTR_SYSTEM){
> +		dosmode |= FILE_ATTRIBUTE_SYSTEM;
> +	}
> +	if (winattrs & GPFS_WINATTR_READONLY){
> +		dosmode |= FILE_ATTRIBUTE_READONLY;
> +	}
> +	if (winattrs & GPFS_WINATTR_SPARSE_FILE) {
> +		dosmode |= FILE_ATTRIBUTE_SPARSE;
> +	}
> +
> +	return dosmode;
> +}
> +
> +static unsigned int vfs_gpfs_dosmode_to_winattrs(uint32_t dosmode)
> +{
> +	unsigned int winattrs = 0;
> +
> +	if (dosmode & FILE_ATTRIBUTE_ARCHIVE){
> +		winattrs |= GPFS_WINATTR_ARCHIVE;
> +	}
> +	if (dosmode & FILE_ATTRIBUTE_HIDDEN){
> +		winattrs |= GPFS_WINATTR_HIDDEN;
> +	}
> +	if (dosmode & FILE_ATTRIBUTE_SYSTEM){
> +		winattrs |= GPFS_WINATTR_SYSTEM;
> +	}
> +	if (dosmode & FILE_ATTRIBUTE_READONLY){
> +		winattrs |= GPFS_WINATTR_READONLY;
> +	}
> +	if (dosmode & FILE_ATTRIBUTE_SPARSE) {
> +		winattrs |= GPFS_WINATTR_SPARSE_FILE;
> +	}
> +
> +	return winattrs;
> +}
> +
> +static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle,
> +					    struct smb_filename *smb_fname,
> +					    uint32_t *dosmode)
> +{
> +	struct gpfs_config_data *config;
> +	struct gpfs_winattr attrs = { };
> +	int ret;
> +
> +	SMB_VFS_HANDLE_GET_DATA(handle, config,
> +				struct gpfs_config_data,
> +				return NT_STATUS_INTERNAL_ERROR);
> +
> +	if (!config->winattr) {
> +		return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
> +						       smb_fname, dosmode);
> +	}
> +
> +	ret = gpfswrap_get_winattrs_path(smb_fname->base_name, &attrs);
> +	if (ret == -1 && errno == ENOSYS) {
> +		return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname,
> +						       dosmode);
> +	}
> +
> +	if (ret == -1) {
> +		DBG_WARNING("Getting winattrs failed for %s: %s\n",
> +			    smb_fname->base_name, strerror(errno));
> +		return map_nt_error_from_unix(errno);
> +	}
> +
> +	*dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
> +
> +	return NT_STATUS_OK;
> +}
> +
> +static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
> +					     struct files_struct *fsp,
> +					     uint32_t *dosmode)
> +{
> +	struct gpfs_config_data *config;
> +	struct gpfs_winattr attrs = { };
> +	int ret;
> +
> +	SMB_VFS_HANDLE_GET_DATA(handle, config,
> +				struct gpfs_config_data,
> +				return NT_STATUS_INTERNAL_ERROR);
> +
> +	if (!config->winattr) {
> +		return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
> +	}
> +
> +	ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs);
> +	if (ret == -1 && errno == ENOSYS) {
> +		return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
> +	}
> +
> +	if (ret == -1) {
> +		DBG_WARNING("Getting winattrs failed for %s: %s\n",
> +			    fsp->fsp_name->base_name, strerror(errno));
> +		return map_nt_error_from_unix(errno);
> +	}
> +
> +	*dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
> +
> +	return NT_STATUS_OK;
> +}
> +
> +static NTSTATUS vfs_gpfs_set_dos_attributes(struct vfs_handle_struct *handle,
> +					   const struct smb_filename *smb_fname,
> +					   uint32_t dosmode)
> +{
> +	struct gpfs_config_data *config;
> +	struct gpfs_winattr attrs = { };
> +	int ret;
> +
> +	SMB_VFS_HANDLE_GET_DATA(handle, config,
> +				struct gpfs_config_data,
> +				return NT_STATUS_INTERNAL_ERROR);
> +
> +	if (!config->winattr) {
> +		return SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
> +						       smb_fname, dosmode);
> +	}
> +
> +	attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode);
> +	ret = gpfswrap_set_winattrs_path(smb_fname->base_name,
> +					 GPFS_WINATTR_SET_ATTRS, &attrs);
> +
> +	if (ret == -1 && errno == ENOSYS) {
> +		return SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
> +						       smb_fname, dosmode);
> +	}
> +
> +	if (ret == -1) {
> +		DBG_WARNING("Setting winattrs failed for %s: %s\n",
> +			    smb_fname->base_name, strerror(errno));
> +		return map_nt_error_from_unix(errno);
> +	}
> +
> +	return NT_STATUS_OK;
> +}
> +
> +static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
> +					     struct files_struct *fsp,
> +					     uint32_t dosmode)
> +{
> +	struct gpfs_config_data *config;
> +	struct gpfs_winattr attrs = { };
> +	int ret;
> +
> +	SMB_VFS_HANDLE_GET_DATA(handle, config,
> +				struct gpfs_config_data,
> +				return NT_STATUS_INTERNAL_ERROR);
> +
> +	if (!config->winattr) {
> +		return SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
> +	}
> +
> +	attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode);
> +	ret = gpfswrap_set_winattrs(fsp->fh->fd,
> +				    GPFS_WINATTR_SET_ATTRS, &attrs);
> +
> +	if (ret == -1 && errno == ENOSYS) {
> +		return SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
> +	}
> +
> +	if (ret == -1) {
> +		DBG_WARNING("Setting winattrs failed for %s: %s\n",
> +			    fsp->fsp_name->base_name, strerror(errno));
> +		return map_nt_error_from_unix(errno);
> +	}
> +
> +	return NT_STATUS_OK;
> +}
> +
>  static int gpfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
>                             const char *name, const void *value, size_t size,  int flags){
>  	struct xattr_DOSATTRIB dosattrib;
> @@ -2485,6 +2665,10 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
>  	.kernel_flock_fn = vfs_gpfs_kernel_flock,
>  	.linux_setlease_fn = vfs_gpfs_setlease,
>  	.get_real_filename_fn = vfs_gpfs_get_real_filename,
> +	.get_dos_attributes_fn = vfs_gpfs_get_dos_attributes,
> +	.fget_dos_attributes_fn = vfs_gpfs_fget_dos_attributes,
> +	.set_dos_attributes_fn = vfs_gpfs_set_dos_attributes,
> +	.fset_dos_attributes_fn = vfs_gpfs_fset_dos_attributes,
>  	.fget_nt_acl_fn = gpfsacl_fget_nt_acl,
>  	.get_nt_acl_fn = gpfsacl_get_nt_acl,
>  	.fset_nt_acl_fn = gpfsacl_fset_nt_acl,
> -- 
> 1.8.3.1
> 
> 
> From 7382d14bc1fbe7b92b6b9ae9f58bcfb0669712ee Mon Sep 17 00:00:00 2001
> From: Christof Schmitt <cs at samba.org>
> Date: Tue, 22 Mar 2016 22:43:49 -0700
> Subject: [PATCH 3/3] vfs_gpfs: Remove xattr functions
> 
> The xattr functions intercepted only the calls from dosmode. With the
> implementation of the dos_attribute interface, the xattr codepaths never
> get called and can be removed.
> 
> Signed-off-by: Christof Schmitt <cs at samba.org>
> ---
>  source3/modules/vfs_gpfs.c | 160 ---------------------------------------------
>  1 file changed, 160 deletions(-)
> 
> diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
> index 42dc4e8..42a3c72 100644
> --- a/source3/modules/vfs_gpfs.c
> +++ b/source3/modules/vfs_gpfs.c
> @@ -22,7 +22,6 @@
>  
>  #include "includes.h"
>  #include "smbd/smbd.h"
> -#include "librpc/gen_ndr/ndr_xattr.h"
>  #include "include/smbprofile.h"
>  #include "modules/non_posix_acls.h"
>  #include "libcli/security/security.h"
> @@ -1629,163 +1628,6 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
>  	return NT_STATUS_OK;
>  }
>  
> -static int gpfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
> -                           const char *name, const void *value, size_t size,  int flags){
> -	struct xattr_DOSATTRIB dosattrib;
> -        enum ndr_err_code ndr_err;
> -        DATA_BLOB blob;
> -        unsigned int dosmode=0;
> -        struct gpfs_winattr attrs;
> -        int ret = 0;
> -	struct gpfs_config_data *config;
> -
> -	SMB_VFS_HANDLE_GET_DATA(handle, config,
> -				struct gpfs_config_data,
> -				return -1);
> -
> -	if (!config->winattr) {
> -		DEBUG(10, ("gpfs_set_xattr:name is %s -> next\n",name));
> -		return SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags);
> -	}
> -
> -        DEBUG(10, ("gpfs_set_xattr: %s \n",path));
> -
> -        /* Only handle DOS Attributes */
> -        if (strcmp(name,SAMBA_XATTR_DOS_ATTRIB) != 0){
> -		DEBUG(5, ("gpfs_set_xattr:name is %s\n",name));
> -		return SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags);
> -        }
> -
> -	blob.data = discard_const_p(uint8_t, value);
> -	blob.length = size;
> -
> -	ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
> -			(ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);
> -
> -	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
> -		DEBUG(1, ("gpfs_set_xattr: bad ndr decode "
> -			  "from EA on file %s: Error = %s\n",
> -			  path, ndr_errstr(ndr_err)));
> -		return false;
> -	}
> -
> -	if (dosattrib.version != 3) {
> -		DEBUG(1, ("gpfs_set_xattr: expected dosattrib version 3, got "
> -			  "%d\n", (int)dosattrib.version));
> -		return false;
> -	}
> -	if (!(dosattrib.info.info3.valid_flags & XATTR_DOSINFO_ATTRIB)) {
> -		DEBUG(10, ("gpfs_set_xattr: XATTR_DOSINFO_ATTRIB not "
> -			   "valid, ignoring\n"));
> -		return true;
> -	}
> -
> -	dosmode = dosattrib.info.info3.attrib;
> -
> -        attrs.winAttrs = 0;
> -        /*Just map RD_ONLY, ARCHIVE, SYSTEM HIDDEN and SPARSE. Ignore the others*/
> -        if (dosmode & FILE_ATTRIBUTE_ARCHIVE){
> -                attrs.winAttrs |= GPFS_WINATTR_ARCHIVE;
> -        }
> -        if (dosmode & FILE_ATTRIBUTE_HIDDEN){
> -                        attrs.winAttrs |= GPFS_WINATTR_HIDDEN;
> -                }
> -        if (dosmode & FILE_ATTRIBUTE_SYSTEM){
> -                        attrs.winAttrs |= GPFS_WINATTR_SYSTEM;
> -                }
> -        if (dosmode & FILE_ATTRIBUTE_READONLY){
> -                        attrs.winAttrs |= GPFS_WINATTR_READONLY;
> -        }
> -        if (dosmode & FILE_ATTRIBUTE_SPARSE) {
> -		attrs.winAttrs |= GPFS_WINATTR_SPARSE_FILE;
> -	}
> -
> -
> -	ret = gpfswrap_set_winattrs_path(discard_const_p(char, path),
> -					 GPFS_WINATTR_SET_ATTRS, &attrs);
> -        if ( ret == -1){
> -		if (errno == ENOSYS) {
> -			return SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
> -						     size, flags);
> -		}
> -
> -                DEBUG(1, ("gpfs_set_xattr:Set GPFS attributes failed %d\n",ret));
> -                return -1;
> -        }
> -
> -        DEBUG(10, ("gpfs_set_xattr:Set attributes: 0x%x\n",attrs.winAttrs));
> -        return 0;
> -}
> -
> -static ssize_t gpfs_get_xattr(struct vfs_handle_struct *handle,  const char *path,
> -                              const char *name, void *value, size_t size){
> -        char *attrstr = value;
> -        unsigned int dosmode = 0;
> -        struct gpfs_winattr attrs;
> -        int ret = 0;
> -	struct gpfs_config_data *config;
> -
> -	SMB_VFS_HANDLE_GET_DATA(handle, config,
> -				struct gpfs_config_data,
> -				return -1);
> -
> -	if (!config->winattr) {
> -		DEBUG(10, ("gpfs_get_xattr:name is %s -> next\n",name));
> -		return SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size);
> -	}
> -
> -        DEBUG(10, ("gpfs_get_xattr: %s \n",path));
> -
> -        /* Only handle DOS Attributes */
> -        if (strcmp(name,SAMBA_XATTR_DOS_ATTRIB) != 0){
> -		DEBUG(5, ("gpfs_get_xattr:name is %s\n",name));
> -                return SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size);
> -        }
> -
> -	ret = gpfswrap_get_winattrs_path(discard_const_p(char, path), &attrs);
> -        if ( ret == -1){
> -		int dbg_lvl;
> -
> -		if (errno == ENOSYS) {
> -			return SMB_VFS_NEXT_GETXATTR(handle, path, name, value,
> -						     size);
> -		}
> -
> -		if (errno != EPERM && errno != EACCES) {
> -			dbg_lvl = 1;
> -		} else {
> -			dbg_lvl = 5;
> -		}
> -		DEBUG(dbg_lvl, ("gpfs_get_xattr: Get GPFS attributes failed: "
> -			      "%d (%s)\n", ret, strerror(errno)));
> -                return -1;
> -        }
> -
> -        DEBUG(10, ("gpfs_get_xattr:Got attributes: 0x%x\n",attrs.winAttrs));
> -
> -        /*Just map RD_ONLY, ARCHIVE, SYSTEM, HIDDEN and SPARSE. Ignore the others*/
> -        if (attrs.winAttrs & GPFS_WINATTR_ARCHIVE){
> -                dosmode |= FILE_ATTRIBUTE_ARCHIVE;
> -        }
> -        if (attrs.winAttrs & GPFS_WINATTR_HIDDEN){
> -                dosmode |= FILE_ATTRIBUTE_HIDDEN;
> -        }
> -        if (attrs.winAttrs & GPFS_WINATTR_SYSTEM){
> -                dosmode |= FILE_ATTRIBUTE_SYSTEM;
> -        }
> -        if (attrs.winAttrs & GPFS_WINATTR_READONLY){
> -                dosmode |= FILE_ATTRIBUTE_READONLY;
> -        }
> -        if (attrs.winAttrs & GPFS_WINATTR_SPARSE_FILE) {
> -		dosmode |= FILE_ATTRIBUTE_SPARSE;
> -	}
> -
> -        snprintf(attrstr, size, "0x%2.2x",
> -		 (unsigned int)(dosmode & SAMBA_ATTRIBUTES_MASK));
> -        DEBUG(10, ("gpfs_get_xattr: returning %s\n",attrstr));
> -        return 4;
> -}
> -
>  #if defined(HAVE_FSTATAT)
>  static int stat_with_capability(struct vfs_handle_struct *handle,
>  				struct smb_filename *smb_fname, int flag)
> @@ -2682,8 +2524,6 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
>  	.chmod_fn = vfs_gpfs_chmod,
>  	.fchmod_fn = vfs_gpfs_fchmod,
>  	.close_fn = vfs_gpfs_close,
> -	.setxattr_fn = gpfs_set_xattr,
> -	.getxattr_fn = gpfs_get_xattr,
>  	.stat_fn = vfs_gpfs_stat,
>  	.fstat_fn = vfs_gpfs_fstat,
>  	.lstat_fn = vfs_gpfs_lstat,
> -- 
> 1.8.3.1
> 




More information about the samba-technical mailing list