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 LUSTREFSAL_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 = -1; 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 00122 char msg[1024]; 00123 00124 msg[0] = '\0'; 00125 00126 if((local_flags & O_RDONLY) == O_RDONLY) 00127 strcat(msg, "O_RDONLY "); 00128 00129 if((local_flags & O_WRONLY) == O_WRONLY) 00130 strcat(msg, "O_WRONLY "); 00131 00132 if((local_flags & O_TRUNC) == O_TRUNC) 00133 strcat(msg, "O_TRUNC "); 00134 00135 if((local_flags & O_CREAT) == O_CREAT) 00136 strcat(msg, "O_CREAT "); 00137 00138 if((local_flags & O_EXCL) == O_EXCL) 00139 strcat(msg, "O_EXCL "); 00140 00141 LogFullDebug(COMPONENT_FSAL, "Openning local file %s with flags: %s", 00142 p_local_path->path, msg); 00143 00144 } 00145 00146 local_fd = open(p_local_path->path, local_flags); 00147 errsv = errno; 00148 00149 if(local_fd == -1) 00150 { 00151 Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_rcp); 00152 } 00153 00154 /* call FSAL_open with the correct flags */ 00155 00156 if(to_fs) 00157 { 00158 fs_flags = FSAL_O_WRONLY | FSAL_O_TRUNC; 00159 00160 /* invalid flags for local to filesystem */ 00161 00162 if(((transfer_opt & FSAL_RCP_LOCAL_CREAT) == FSAL_RCP_LOCAL_CREAT) 00163 || ((transfer_opt & FSAL_RCP_LOCAL_EXCL) == FSAL_RCP_LOCAL_EXCL)) 00164 { 00165 /* clean & return */ 00166 close(local_fd); 00167 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_rcp); 00168 } 00169 } 00170 else 00171 { 00172 fs_flags = FSAL_O_RDONLY; 00173 } 00174 00175 if (isFullDebug(COMPONENT_FSAL)) 00176 { 00177 00178 char msg[1024]; 00179 00180 msg[0] = '\0'; 00181 00182 if((fs_flags & FSAL_O_RDONLY) == FSAL_O_RDONLY) 00183 strcat(msg, "FSAL_O_RDONLY "); 00184 00185 if((fs_flags & FSAL_O_WRONLY) == FSAL_O_WRONLY) 00186 strcat(msg, "FSAL_O_WRONLY "); 00187 00188 if((fs_flags & FSAL_O_TRUNC) == FSAL_O_TRUNC) 00189 strcat(msg, "FSAL_O_TRUNC "); 00190 00191 LogFullDebug(COMPONENT_FSAL, "Openning FSAL file with flags: %s", msg); 00192 00193 } 00194 00195 st = LUSTREFSAL_open(filehandle, p_context, fs_flags, &fs_fd, NULL); 00196 00197 if(FSAL_IS_ERROR(st)) 00198 { 00199 /* clean & return */ 00200 close(local_fd); 00201 Return(st.major, st.minor, INDEX_FSAL_rcp); 00202 } 00203 00204 LogFullDebug(COMPONENT_FSAL, 00205 "Allocating IO buffer of size %llu", 00206 (unsigned long long)RCP_BUFFER_SIZE); 00207 00208 /* Allocates buffer */ 00209 00210 IObuffer = gsh_malloc(RCP_BUFFER_SIZE); 00211 00212 if(IObuffer == NULL) 00213 { 00214 /* clean & return */ 00215 close(local_fd); 00216 LUSTREFSAL_close(&fs_fd); 00217 Return(ERR_FSAL_NOMEM, ENOMEM, INDEX_FSAL_rcp); 00218 } 00219 00220 /* read/write loop */ 00221 00222 while(!eof) 00223 { 00224 /* initialize error code */ 00225 st = FSAL_STATUS_NO_ERROR; 00226 00227 LogFullDebug(COMPONENT_FSAL, "Read a block from source"); 00228 00229 /* read */ 00230 00231 if(to_fs) /* from local filesystem */ 00232 { 00233 local_size = read(local_fd, IObuffer, RCP_BUFFER_SIZE); 00234 00235 if(local_size == -1) 00236 { 00237 st.major = ERR_FSAL_IO; 00238 st.minor = errno; 00239 break; /* exit loop */ 00240 } 00241 00242 eof = (local_size == 0); 00243 00244 } 00245 else /* from FSAL filesystem */ 00246 { 00247 fs_size = 0; 00248 st = LUSTREFSAL_read(&fs_fd, NULL, RCP_BUFFER_SIZE, IObuffer, &fs_size, &eof); 00249 00250 if(FSAL_IS_ERROR(st)) 00251 break; /* exit loop */ 00252 00253 LogFullDebug(COMPONENT_FSAL, "Size read from source: %llu", 00254 (unsigned long long)fs_size); 00255 00256 } 00257 00258 /* write (if not eof) */ 00259 00260 if(!eof || ((!to_fs) && (fs_size > 0))) 00261 { 00262 LogFullDebug(COMPONENT_FSAL, "Write a block to destination"); 00263 00264 if(to_fs) /* to FSAL filesystem */ 00265 { 00266 00267 st = LUSTREFSAL_write(&fs_fd, p_context, NULL, local_size, IObuffer, &fs_size); 00268 00269 if(FSAL_IS_ERROR(st)) 00270 break; /* exit loop */ 00271 00272 } 00273 else /* to local filesystem */ 00274 { 00275 00276 local_size = write(local_fd, IObuffer, fs_size); 00277 00278 LogFullDebug(COMPONENT_FSAL, "Size written to target: %llu", 00279 (unsigned long long)local_size); 00280 00281 if(local_size == -1) 00282 { 00283 st.major = ERR_FSAL_IO; 00284 st.minor = errno; 00285 break; /* exit loop */ 00286 } 00287 00288 } /* if to_fs */ 00289 00290 } /* if eof */ 00291 else 00292 LogFullDebug(COMPONENT_FSAL, "End of source file reached"); 00293 00294 } /* while !eof */ 00295 00296 /* Clean */ 00297 00298 gsh_free(IObuffer); 00299 close(local_fd); 00300 LUSTREFSAL_close(&fs_fd); 00301 00302 /* return status. */ 00303 00304 Return(st.major, st.minor, INDEX_FSAL_rcp); 00305 00306 }