nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 00014 #ifdef HAVE_CONFIG_H 00015 #include "config.h" 00016 #endif 00017 00018 #ifdef _SOLARIS 00019 #include "solaris_port.h" 00020 #endif /* _SOLARIS */ 00021 00022 #include <string.h> 00023 #ifdef _USE_GSSRPC 00024 #include <gssrpc/rpc.h> 00025 #include <gssrpc/xdr.h> 00026 #else 00027 #include <rpc/rpc.h> 00028 #include <rpc/xdr.h> 00029 #endif 00030 #include "nfs4.h" 00031 00032 #include "fsal_internal.h" 00033 #include "fsal_convert.h" 00034 #include "fsal_common.h" 00035 00036 #include "nfs_proto_functions.h" 00037 #include "nfs_proto_tools.h" 00038 #include "fsal_nfsv4_macros.h" 00039 00067 fsal_status_t PROXYFSAL_truncate(fsal_handle_t * file_hdl, /* IN */ 00068 fsal_op_context_t * context, /* IN */ 00069 fsal_size_t length, /* IN */ 00070 fsal_file_t * file_descriptor, /* [IN|OUT] */ 00071 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00072 ) 00073 { 00074 00075 int rc; 00076 00077 COMPOUND4args argnfs4; 00078 COMPOUND4res resnfs4; 00079 nfs_fh4 nfs4fh; 00080 uint64_t fileid; 00081 fsal_status_t fsal_status; 00082 fsal_attrib_list_t open_attrs; 00083 bitmap4 inbitmap; 00084 bitmap4 convert_bitmap; 00085 uint32_t inbitmap_val[2]; 00086 uint32_t bitmap_res[2]; 00087 uint32_t bitmap_set[2]; 00088 uint32_t bitmap_conv_val[2]; 00089 proxyfsal_handle_t * filehandle = (proxyfsal_handle_t *)file_hdl; 00090 proxyfsal_op_context_t * p_context = (proxyfsal_op_context_t *)context; 00091 struct fsal_handle_desc fhd = { 00092 .len = sizeof(fileid), 00093 .start = (caddr_t)&fileid 00094 }; 00095 00096 #define FSAL_TRUNCATE_NB_OP_ALLOC 3 00097 nfs_argop4 argoparray[FSAL_TRUNCATE_NB_OP_ALLOC]; 00098 nfs_resop4 resoparray[FSAL_TRUNCATE_NB_OP_ALLOC]; 00099 00100 fsal_attrib_list_t fsal_attr_set; 00101 fattr4 fattr_set; 00102 fsal_proxy_internal_fattr_t fattr_internal; 00103 struct timeval timeout = TIMEOUTRPC; 00104 00105 /* sanity checks. 00106 * note : object_attributes is optional. 00107 */ 00108 if(!filehandle || !p_context) 00109 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); 00110 00111 if(filehandle->data.object_type_reminder != FSAL_TYPE_FILE) 00112 { 00113 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); 00114 } 00115 00116 if(file_descriptor) 00117 { 00118 /* First, we need to get the fileid on a filehandle base */ 00119 fsal_status = FSAL_DigestHandle(context->export_context, 00120 FSAL_DIGEST_FILEID4, file_hdl, &fhd); 00121 if(FSAL_IS_ERROR(fsal_status)) 00122 { 00123 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); 00124 } 00125 00126 /* Then we have of open the file by fileid */ 00127 open_attrs.asked_attributes = FSAL_ATTRS_POSIX; 00128 fsal_status = FSAL_open_by_fileid(file_hdl, 00129 fileid, 00130 context, FSAL_O_RDWR, file_descriptor, &open_attrs); 00131 if(FSAL_IS_ERROR(fsal_status)) 00132 { 00133 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); 00134 } 00135 } 00136 00137 /* Setup results structures */ 00138 argnfs4.argarray.argarray_val = argoparray; 00139 resnfs4.resarray.resarray_val = resoparray; 00140 fsal_internal_proxy_setup_fattr(&fattr_internal); 00141 argnfs4.minorversion = 0; 00142 /* argnfs4.tag.utf8string_val = "GANESHA NFSv4 Proxy: Truncate" ; */ 00143 argnfs4.tag.utf8string_val = NULL; 00144 argnfs4.tag.utf8string_len = 0; 00145 argnfs4.argarray.argarray_len = 0; 00146 00147 /* Get NFSv4 File handle */ 00148 if(fsal_internal_proxy_extract_fh(&nfs4fh, file_hdl) == FALSE) 00149 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate); 00150 00151 /* Get prepared for truncate */ 00152 fsal_attr_set.asked_attributes = FSAL_ATTR_SIZE; 00153 fsal_attr_set.filesize = length; 00154 00155 convert_bitmap.bitmap4_val = bitmap_conv_val; 00156 convert_bitmap.bitmap4_len = 2; 00157 00158 fsal_interval_proxy_fsalattr2bitmap4(&fsal_attr_set, &convert_bitmap); 00159 00160 if(nfs4_FSALattr_To_Fattr(NULL, /* no exportlist required here */ 00161 &fsal_attr_set, &fattr_set, NULL, /* no compound data required here */ 00162 NULL, /* No fh here, filehandle is not a settable attribute */ 00163 &convert_bitmap) == -1) 00164 Return(ERR_FSAL_INVAL, -1, INDEX_FSAL_truncate); 00165 00166 inbitmap.bitmap4_val = inbitmap_val; 00167 inbitmap.bitmap4_len = 2; 00168 fsal_internal_proxy_create_fattr_bitmap(&inbitmap); 00169 00170 #define FSAL_TRUNCATE_IDX_OP_PUTFH 0 00171 #define FSAL_TRUNCATE_IDX_OP_SETATTR 1 00172 #define FSAL_TRUNCATE_IDX_OP_GETATTR 2 00173 COMPOUNDV4_ARG_ADD_OP_PUTFH(argnfs4, nfs4fh); 00174 COMPOUNDV4_ARG_ADD_OP_SETATTR(argnfs4, fattr_set); 00175 COMPOUNDV4_ARG_ADD_OP_GETATTR(argnfs4, inbitmap); 00176 00177 /* For ATTR_SIZE, stateid is needed */ 00178 if(file_descriptor) 00179 { 00180 argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr. 00181 stateid.seqid = ((proxyfsal_file_t *)file_descriptor)->stateid.seqid; 00182 memcpy(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u. 00183 opsetattr.stateid.other, ((proxyfsal_file_t *)file_descriptor)->stateid.other, 12); 00184 } 00185 else 00186 { 00187 /* No file descriptor - use 'stateless' state_id of all-0s */ 00188 argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u.opsetattr. 00189 stateid.seqid = 0; 00190 memset(argnfs4.argarray.argarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_argop4_u. 00191 opsetattr.stateid.other, 0, 12); 00192 } 00193 00194 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00195 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_val = bitmap_res; 00196 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00197 GETATTR4res_u.resok4.obj_attributes.attrmask.bitmap4_len = 2; 00198 00199 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00200 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_val = 00201 (char *)&fattr_internal; 00202 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u.opgetattr. 00203 GETATTR4res_u.resok4.obj_attributes.attr_vals.attrlist4_len = 00204 sizeof(fattr_internal); 00205 00206 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr. 00207 attrsset.bitmap4_val = bitmap_set; 00208 resnfs4.resarray.resarray_val[FSAL_TRUNCATE_IDX_OP_SETATTR].nfs_resop4_u.opsetattr. 00209 attrsset.bitmap4_len = 2; 00210 00211 TakeTokenFSCall(); 00212 00213 COMPOUNDV4_EXECUTE(p_context, argnfs4, resnfs4, rc); 00214 nfs4_Fattr_Free(&fattr_set); 00215 if(rc != RPC_SUCCESS) 00216 { 00217 ReleaseTokenFSCall(); 00218 00219 Return(ERR_FSAL_IO, 0, INDEX_FSAL_truncate); 00220 } 00221 00222 ReleaseTokenFSCall(); 00223 00224 if(resnfs4.status != NFS4_OK) 00225 return fsal_internal_proxy_error_convert(resnfs4.status, INDEX_FSAL_truncate); 00226 00227 /* >> interpret error code << */ 00228 00229 /* >> Optionnaly retrieve post op attributes 00230 * If your filesystem truncate call can't return them, 00231 * you can proceed like this : << 00232 */ 00233 if(object_attributes) 00234 { 00235 if(nfs4_Fattr_To_FSAL_attr(object_attributes, 00236 &resnfs4.resarray. 00237 resarray_val[FSAL_TRUNCATE_IDX_OP_GETATTR].nfs_resop4_u. 00238 opgetattr.GETATTR4res_u.resok4.obj_attributes) != NFS4_OK) 00239 { 00240 FSAL_CLEAR_MASK(object_attributes->asked_attributes); 00241 FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00242 00243 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_truncate); 00244 } 00245 00246 } 00247 00248 if(file_descriptor) 00249 { 00250 /* Close the previously opened filedescriptor */ 00251 fsal_status = FSAL_close_by_fileid(file_descriptor, fileid); 00252 if(FSAL_IS_ERROR(fsal_status)) 00253 { 00254 Return(fsal_status.major, fsal_status.minor, INDEX_FSAL_truncate); 00255 } 00256 } 00257 00258 /* No error occured */ 00259 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate); 00260 }