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