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 #include <unistd.h> 00019 #include "fsal.h" 00020 #include "fsal_internal.h" 00021 #include "fsal_convert.h" 00022 #include "abstract_mem.h" 00023 00057 fsal_status_t HPSSFSAL_rcp(hpssfsal_handle_t * filehandle, /* IN */ 00058 hpssfsal_op_context_t * p_context, /* IN */ 00059 fsal_path_t * p_local_path, /* IN */ 00060 fsal_rcpflag_t transfer_opt /* IN */ 00061 ) 00062 { 00063 00064 int local_fd; 00065 int local_flags; 00066 00067 hpssfsal_file_t fs_fd; 00068 fsal_openflags_t fs_flags; 00069 00070 fsal_status_t st = FSAL_STATUS_NO_ERROR; 00071 00072 /* default buffer size for RCP: 1MB */ 00073 #define RCP_BUFFER_SIZE 1048576 00074 caddr_t IObuffer; 00075 00076 int to_local = FALSE; 00077 int to_fs = FALSE; 00078 00079 int eof = FALSE; 00080 00081 ssize_t local_size = 0; 00082 fsal_size_t fs_size; 00083 00084 /* sanity checks. */ 00085 00086 if(!filehandle || !p_context || !p_local_path) 00087 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_rcp); 00088 00089 to_local = ((transfer_opt & FSAL_RCP_FS_TO_LOCAL) == FSAL_RCP_FS_TO_LOCAL); 00090 to_fs = ((transfer_opt & FSAL_RCP_LOCAL_TO_FS) == FSAL_RCP_LOCAL_TO_FS); 00091 00092 if(to_local) 00093 LogFullDebug(COMPONENT_FSAL, 00094 "FSAL_rcp: FSAL -> local file (%s)", p_local_path->path); 00095 if(to_fs) 00096 LogFullDebug(COMPONENT_FSAL, 00097 "FSAL_rcp: local file -> FSAL (%s)", p_local_path->path); 00098 00099 /* must give the sens of transfert (exactly one) */ 00100 00101 if((!to_local && !to_fs) || (to_local && to_fs)) 00102 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); 00103 00104 /* first, open local file with the correct flags */ 00105 00106 if(to_fs) 00107 { 00108 local_flags = O_RDONLY; 00109 } 00110 else 00111 { 00112 local_flags = O_WRONLY | O_TRUNC; 00113 00114 if((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) 00115 local_flags |= O_CREAT; 00116 00117 if((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL) 00118 local_flags |= O_EXCL; 00119 00120 } 00121 00122 if(isFullDebug(COMPONENT_FSAL)) 00123 { 00124 00125 char msg[1024]; 00126 00127 msg[0] = '\0'; 00128 00129 if((local_flags & O_RDONLY) == O_RDONLY) 00130 strcat(msg, "O_RDONLY "); 00131 00132 if((local_flags & O_WRONLY) == O_WRONLY) 00133 strcat(msg, "O_WRONLY "); 00134 00135 if((local_flags & O_TRUNC) == O_TRUNC) 00136 strcat(msg, "O_TRUNC "); 00137 00138 if((local_flags & O_CREAT) == O_CREAT) 00139 strcat(msg, "O_CREAT "); 00140 00141 if((local_flags & O_EXCL) == O_EXCL) 00142 strcat(msg, "O_EXCL "); 00143 00144 LogFullDebug(COMPONENT_FSAL, "Openning local file %s with flags: %s", 00145 p_local_path->path, msg); 00146 00147 } 00148 00149 local_fd = open(p_local_path->path, local_flags, 0644); 00150 00151 if(local_fd == -1) 00152 { 00153 Return(hpss2fsal_error(errno), errno, INDEX_FSAL_rcp); 00154 } 00155 00156 /* call FSAL_open with the correct flags */ 00157 00158 if(to_fs) 00159 { 00160 fs_flags = FSAL_O_WRONLY | FSAL_O_TRUNC; 00161 00162 /* invalid flags for local to filesystem */ 00163 00164 if(((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) 00165 || ((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL)) 00166 { 00167 /* clean & return */ 00168 close(local_fd); 00169 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); 00170 } 00171 } 00172 else 00173 { 00174 fs_flags = FSAL_O_RDONLY; 00175 } 00176 00177 if(isFullDebug(COMPONENT_FSAL)) 00178 { 00179 00180 char msg[1024]; 00181 00182 msg[0] = '\0'; 00183 00184 if((fs_flags & FSAL_O_RDONLY) == FSAL_O_RDONLY) 00185 strcat(msg, "FSAL_O_RDONLY "); 00186 00187 if((fs_flags & FSAL_O_WRONLY) == FSAL_O_WRONLY) 00188 strcat(msg, "FSAL_O_WRONLY "); 00189 00190 if((fs_flags & FSAL_O_TRUNC) == FSAL_O_TRUNC) 00191 strcat(msg, "FSAL_O_TRUNC "); 00192 00193 LogFullDebug(COMPONENT_FSAL, "Openning FSAL file with flags: %s", msg); 00194 00195 } 00196 00197 st = HPSSFSAL_open(filehandle, p_context, fs_flags, &fs_fd, NULL); 00198 00199 if(FSAL_IS_ERROR(st)) 00200 { 00201 /* clean & return */ 00202 close(local_fd); 00203 Return(st.major, st.minor, INDEX_FSAL_rcp); 00204 } 00205 LogFullDebug(COMPONENT_FSAL, 00206 "Allocating IO buffer of size %llu", 00207 (unsigned long long)RCP_BUFFER_SIZE); 00208 00209 /* Allocates buffer */ 00210 00211 IObuffer = gsh_malloc(RCP_BUFFER_SIZE); 00212 00213 if(IObuffer == NULL) 00214 { 00215 /* clean & return */ 00216 close(local_fd); 00217 HPSSFSAL_close(&fs_fd); 00218 Return(ERR_FSAL_NOMEM, ENOMEM, INDEX_FSAL_rcp); 00219 } 00220 00221 /* read/write loop */ 00222 00223 while(!eof) 00224 { 00225 /* initialize error code */ 00226 st = FSAL_STATUS_NO_ERROR; 00227 00228 LogFullDebug(COMPONENT_FSAL, "Read a block from source"); 00229 00230 /* read */ 00231 00232 if(to_fs) /* from local filesystem */ 00233 { 00234 local_size = read(local_fd, IObuffer, RCP_BUFFER_SIZE); 00235 00236 if(local_size == -1) 00237 { 00238 st.major = ERR_FSAL_IO; 00239 st.minor = errno; 00240 break; /* exit loop */ 00241 } 00242 00243 eof = (local_size == 0); 00244 00245 } 00246 else /* from FSAL filesystem */ 00247 { 00248 fs_size = 0; 00249 st = HPSSFSAL_read(&fs_fd, NULL, RCP_BUFFER_SIZE, IObuffer, &fs_size, &eof); 00250 00251 if(FSAL_IS_ERROR(st)) 00252 break; /* exit loop */ 00253 00254 } 00255 00256 /* write (if not eof) */ 00257 00258 if(!eof || ((!to_fs) && (fs_size > 0))) 00259 { 00260 LogFullDebug(COMPONENT_FSAL, "Write a block to destination"); 00261 00262 if(to_fs) /* to FSAL filesystem */ 00263 { 00264 00265 st = HPSSFSAL_write(&fs_fd, p_context, NULL, local_size, IObuffer, &fs_size); 00266 00267 if(FSAL_IS_ERROR(st)) 00268 break; /* exit loop */ 00269 00270 } 00271 else /* to local filesystem */ 00272 { 00273 00274 local_size = write(local_fd, IObuffer, fs_size); 00275 00276 if(local_size == -1) 00277 { 00278 st.major = ERR_FSAL_IO; 00279 st.minor = errno; 00280 break; /* exit loop */ 00281 } 00282 00283 } /* if to_fs */ 00284 00285 } /* if eof */ 00286 else 00287 LogFullDebug(COMPONENT_FSAL, "End of source file reached"); 00288 00289 } /* while !eof */ 00290 00291 /* Clean */ 00292 00293 gsh_free(IObuffer); 00294 close(local_fd); 00295 HPSSFSAL_close(&fs_fd); 00296 00297 /* return status. */ 00298 00299 Return(st.major, st.minor, INDEX_FSAL_rcp); 00300 }