nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2011) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 */ 00025 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif 00038 00039 #ifdef _SOLARIS 00040 #include "solaris_port.h" 00041 #endif 00042 00043 #include <stdio.h> 00044 #include <string.h> 00045 #include <pthread.h> 00046 #include <sys/stat.h> 00047 #include "nfs_core.h" 00048 #include "log.h" 00049 #include "cache_inode.h" 00050 #include "fsal.h" 00051 #include "9p.h" 00052 00053 00054 int _9p_xattrwalk( _9p_request_data_t * preq9p, 00055 void * pworker_data, 00056 u32 * plenout, 00057 char * preply) 00058 { 00059 char * cursor = preq9p->_9pmsg + _9P_HDR_SIZE + _9P_TYPE_SIZE ; 00060 00061 u16 * msgtag = NULL ; 00062 u32 * fid = NULL ; 00063 u32 * attrfid = NULL ; 00064 u16 * name_len ; 00065 char * name_str ; 00066 u64 attrsize = 0LL ; 00067 00068 fsal_status_t fsal_status ; 00069 fsal_name_t name; 00070 fsal_xattrent_t xattrs_tab[255]; 00071 int eod_met = FALSE; 00072 unsigned int nb_xattrs_read = 0; 00073 unsigned int i = 0 ; 00074 char * xattr_cursor = NULL ; 00075 unsigned int tmplen = 0 ; 00076 00077 _9p_fid_t * pfid = NULL ; 00078 _9p_fid_t * pxattrfid = NULL ; 00079 00080 if ( !preq9p || !pworker_data || !plenout || !preply ) 00081 return -1 ; 00082 00083 /* Get data */ 00084 _9p_getptr( cursor, msgtag, u16 ) ; 00085 _9p_getptr( cursor, fid, u32 ) ; 00086 _9p_getptr( cursor, attrfid, u32 ) ; 00087 00088 LogDebug( COMPONENT_9P, "TXATTRWALK: tag=%u fid=%u attrfid=%u" , 00089 (u32)*msgtag, *fid, *attrfid ) ; 00090 00091 _9p_getstr( cursor, name_len, name_str ) ; 00092 LogDebug( COMPONENT_9P, "TXATTRWALK (component): tag=%u fid=%u attrfid=%u name=%.*s", 00093 (u32)*msgtag, *fid, *attrfid, *name_len, name_str ) ; 00094 00095 if( *fid >= _9P_FID_PER_CONN ) 00096 return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; 00097 00098 if( *attrfid >= _9P_FID_PER_CONN ) 00099 return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; 00100 00101 pfid = &preq9p->pconn->fids[*fid] ; 00102 pxattrfid = &preq9p->pconn->fids[*attrfid] ; 00103 00104 /* Initiate xattr's fid by copying file's fid in it */ 00105 memcpy( (char *)pxattrfid, (char *)pfid, sizeof( _9p_fid_t ) ) ; 00106 00107 snprintf( name.name, FSAL_MAX_NAME_LEN, "%.*s", *name_len, name_str ) ; 00108 name.len = *name_len + 1 ; 00109 00110 if( ( pxattrfid->specdata.xattr.xattr_content = gsh_malloc( XATTR_BUFFERSIZE ) ) == NULL ) 00111 return _9p_rerror( preq9p, msgtag, ENOMEM, plenout, preply ) ; 00112 00113 if( *name_len == 0 ) 00114 { 00115 /* xattrwalk is used with an empty name, this is a listxattr request */ 00116 fsal_status = FSAL_ListXAttrs( &pxattrfid->pentry->handle, 00117 FSAL_XATTR_RW_COOKIE, /* Start with RW cookie, hiding RO ones */ 00118 &pxattrfid->fsal_op_context, 00119 xattrs_tab, 00120 100, /* for wanting of something smarter */ 00121 &nb_xattrs_read, 00122 &eod_met); 00123 00124 if(FSAL_IS_ERROR(fsal_status)) 00125 return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_inode_error_convert(fsal_status) ), plenout, preply ) ; 00126 00127 /* if all xattrent are not read, returns ERANGE as listxattr does */ 00128 if( eod_met != TRUE ) 00129 return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; 00130 00131 xattr_cursor = pxattrfid->specdata.xattr.xattr_content ; 00132 attrsize = 0LL ; 00133 for( i = 0 ; i < nb_xattrs_read ; i++ ) 00134 { 00135 tmplen = snprintf( xattr_cursor, MAXNAMLEN, "%s", xattrs_tab[i].xattr_name.name ) ; 00136 xattr_cursor[tmplen] = '\0' ; /* Just to be sure */ 00137 xattr_cursor += tmplen+1 ; /* Do not forget to take in account the '\0' at the end */ 00138 attrsize += tmplen+1 ; 00139 00140 /* Make sure not to go beyond the buffer */ 00141 if( attrsize > XATTR_BUFFERSIZE ) 00142 return _9p_rerror( preq9p, msgtag, ERANGE, plenout, preply ) ; 00143 } 00144 } 00145 else 00146 { 00147 /* xattrwalk has a non-empty name, use regular setxattr */ 00148 fsal_status = FSAL_GetXAttrIdByName( &pxattrfid->pentry->handle, 00149 &name, 00150 &pxattrfid->fsal_op_context, 00151 &pxattrfid->specdata.xattr.xattr_id); 00152 00153 if(FSAL_IS_ERROR(fsal_status)) 00154 return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_inode_error_convert(fsal_status) ), plenout, preply ) ; 00155 00156 fsal_status = FSAL_GetXAttrValueByName( &pxattrfid->pentry->handle, 00157 &name, 00158 &pxattrfid->fsal_op_context, 00159 pxattrfid->specdata.xattr.xattr_content, 00160 XATTR_BUFFERSIZE, 00161 &attrsize ); 00162 00163 if(FSAL_IS_ERROR(fsal_status)) 00164 return _9p_rerror( preq9p, msgtag, _9p_tools_errno( cache_inode_error_convert(fsal_status) ), plenout, preply ) ; 00165 00166 _9p_chomp_attr_value( pxattrfid->specdata.xattr.xattr_content, strlen( pxattrfid->specdata.xattr.xattr_content) ) ; 00167 00168 attrsize = strlen( pxattrfid->specdata.xattr.xattr_content ) ; 00169 } 00170 00171 /* Build the reply */ 00172 _9p_setinitptr( cursor, preply, _9P_RXATTRWALK ) ; 00173 _9p_setptr( cursor, msgtag, u16 ) ; 00174 00175 _9p_setvalue( cursor, attrsize, u64 ) ; /* No xattr for now */ 00176 00177 _9p_setendptr( cursor, preply ) ; 00178 _9p_checkbound( cursor, preply, plenout ) ; 00179 00180 LogDebug( COMPONENT_9P, "RXATTRWALK: tag=%u fid=%u attrfid=%u name=%.*s size=%llu", 00181 (u32)*msgtag, *fid, *attrfid, *name_len, name_str, (unsigned long long)attrsize ) ; 00182 00183 return 1 ; 00184 } /* _9p_xattrwalk */ 00185