nfs-ganesha 1.4
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 #include <string.h> 00005 #include "posixdb_internal.h" 00006 00007 fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn, /* IN */ 00008 posixfsal_handle_t * p_parent_directory_handle, /* IN/OUT */ 00009 fsal_name_t * p_objectname, /* IN */ 00010 fsal_path_t * p_path, /* OUT */ 00011 posixfsal_handle_t * 00012 p_handle /* OUT */ ) 00013 { 00014 PGresult *p_res; 00015 fsal_posixdb_status_t st; 00016 char handleid_str[MAX_HANDLEIDSTR_SIZE]; 00017 char handlets_str[MAX_HANDLETSSTR_SIZE]; 00018 const char *paramValues[3] = { handleid_str, handlets_str, p_objectname->name }; 00019 00020 /* sanity check */ 00021 if(!p_conn || !p_handle) 00022 { 00023 ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); 00024 } 00025 00026 CheckConn(p_conn); 00027 00028 LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name); 00029 00030 BeginTransaction(p_conn, p_res); 00031 /* lookup for the handle of the file */ 00032 if(p_parent_directory_handle && p_parent_directory_handle->data.id) 00033 { 00034 snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_parent_directory_handle->data.id); 00035 snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_parent_directory_handle->data.ts); 00036 p_res = PQexecPrepared(p_conn, "lookupHandleByName", 3, paramValues, NULL, NULL, 0); 00037 CheckResult(p_res); 00038 } 00039 else 00040 { 00041 // get root handle : 00042 p_res = PQexecPrepared(p_conn, "lookupRootHandle", 0, NULL, NULL, NULL, 0); 00043 CheckResult(p_res); 00044 } 00045 /* p_res contains : Parent.handleid, Parent.handlets, Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ 00046 00047 /* entry not found */ 00048 if(PQntuples(p_res) != 1) 00049 { 00050 PQclear(p_res); 00051 RollbackTransaction(p_conn, p_res); 00052 ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); 00053 } 00054 00055 p_handle->data.id = atoll(PQgetvalue(p_res, 0, 0)); 00056 p_handle->data.ts = atoi(PQgetvalue(p_res, 0, 1)); 00057 posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), PQgetvalue(p_res, 0, 2), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4), /* nlink */ 00058 PQgetvalue(p_res, 0, 5), /* ctime */ 00059 PQgetvalue(p_res, 0, 6) /* ftype */ 00060 ); 00061 PQclear(p_res); 00062 00063 /* Build the path of the object */ 00064 if(p_path && p_objectname) 00065 { 00066 /* build the path of the Parent */ 00067 st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path); 00068 if(st.major != ERR_FSAL_POSIXDB_NOERR) 00069 { 00070 RollbackTransaction(p_conn, p_res); 00071 return st; 00072 } 00073 00074 /* then concatenate the filename */ 00075 if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN)) 00076 { 00077 RollbackTransaction(p_conn, p_res); 00078 ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); 00079 } 00080 p_path->path[p_path->len] = '/'; 00081 strcpy(&p_path->path[p_path->len + 1], p_objectname->name); 00082 p_path->len += 1 + p_objectname->len; 00083 00084 /* add the the path to cache */ 00085 fsal_posixdb_CachePath(p_handle, p_path); 00086 } 00087 else 00088 { 00089 /* update handle if it was in cache */ 00090 fsal_posixdb_UpdateInodeCache(p_handle); 00091 } 00092 00093 EndTransaction(p_conn, p_res); 00094 00095 ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); 00096 } 00097 00098 fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn, /* IN */ 00099 posixfsal_handle_t * p_object_handle, /* IN/OUT */ 00100 fsal_path_t * p_paths, /* OUT */ 00101 int paths_size, /* IN */ 00102 int *p_count /* OUT */ ) 00103 { 00104 PGresult *p_res; 00105 fsal_posixdb_status_t st; 00106 char handleid_str[MAX_HANDLEIDSTR_SIZE]; 00107 char handlets_str[MAX_HANDLETSSTR_SIZE]; 00108 posixfsal_handle_t parent_directory_handle; 00109 int i_path; 00110 int toomanypaths = 0; 00111 const char *paramValues[2] = { handleid_str, handlets_str }; 00112 00113 /* sanity check */ 00114 if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0)) 00115 { 00116 ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0); 00117 } 00118 00119 CheckConn(p_conn); 00120 00121 LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id); 00122 00123 BeginTransaction(p_conn, p_res); 00124 00125 /* lookup for the handle of the file */ 00126 snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id); 00127 snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts); 00128 00129 if(!fsal_posixdb_GetInodeCache(p_object_handle)) 00130 { 00131 00132 p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0); 00133 CheckResult(p_res); 00134 /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype */ 00135 00136 LogDebug(COMPONENT_FSAL, "lookupHandle(%u,%u)", (unsigned int)p_object_handle->data.id, 00137 (unsigned int)p_object_handle->data.ts); 00138 00139 /* entry not found */ 00140 if(PQntuples(p_res) != 1) 00141 { 00142 LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", PQntuples(p_res)); 00143 RollbackTransaction(p_conn, p_res); 00144 ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); 00145 } 00146 00147 posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), PQgetvalue(p_res, 0, 0), PQgetvalue(p_res, 0, 1), PQgetvalue(p_res, 0, 2), /* nlink */ 00148 PQgetvalue(p_res, 0, 3), /* ctime */ 00149 PQgetvalue(p_res, 0, 4) /* ftype */ 00150 ); 00151 PQclear(p_res); 00152 00153 /* update the inode */ 00154 fsal_posixdb_UpdateInodeCache(p_object_handle); 00155 } 00156 00157 /* Build the paths of the object */ 00158 if(p_paths) 00159 { 00160 /* find all the paths to the object */ 00161 p_res = PQexecPrepared(p_conn, "lookupPaths", 2, paramValues, NULL, NULL, 0); 00162 CheckResult(p_res); 00163 /* p_res contains name, handleidparent, handletsparent */ 00164 *p_count = PQntuples(p_res); 00165 if(*p_count == 0) 00166 { 00167 RollbackTransaction(p_conn, p_res); 00168 ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0); 00169 } 00170 if(*p_count > paths_size) 00171 { 00172 toomanypaths = 1; 00173 00174 LogCrit(COMPONENT_FSAL, "Too many paths found for object %s.%s: found=%u, max=%d", 00175 handleid_str, handlets_str, *p_count, paths_size); 00176 00177 *p_count = paths_size; 00178 } 00179 00180 for(i_path = 0; i_path < *p_count; i_path++) 00181 { 00182 unsigned int tmp_len; 00183 00184 /* build the path of the parent directory */ 00185 parent_directory_handle.data.id = atoll(PQgetvalue(p_res, i_path, 1)); 00186 parent_directory_handle.data.ts = atoi(PQgetvalue(p_res, i_path, 2)); 00187 00188 st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle, 00189 &p_paths[i_path]); 00190 if(st.major != ERR_FSAL_POSIXDB_NOERR) 00191 { 00192 RollbackTransaction(p_conn, p_res); 00193 return st; 00194 } 00195 00196 tmp_len = p_paths[i_path].len; 00197 00198 if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/')) 00199 { 00200 /* then concatenate the name of the file */ 00201 /* but not concatenate '/' */ 00202 if((tmp_len + strlen(PQgetvalue(p_res, i_path, 0)) >= FSAL_MAX_PATH_LEN)) 00203 { 00204 RollbackTransaction(p_conn, p_res); 00205 ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); 00206 } 00207 strcpy(&p_paths[i_path].path[tmp_len], PQgetvalue(p_res, i_path, 0)); 00208 p_paths[i_path].len += strlen(PQgetvalue(p_res, i_path, 0)); 00209 00210 } 00211 else 00212 { 00213 /* then concatenate the name of the file */ 00214 if((tmp_len + 1 + strlen(PQgetvalue(p_res, i_path, 0)) >= 00215 FSAL_MAX_PATH_LEN)) 00216 { 00217 RollbackTransaction(p_conn, p_res); 00218 ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0); 00219 } 00220 p_paths[i_path].path[tmp_len] = '/'; 00221 strcpy(&p_paths[i_path].path[tmp_len + 1], PQgetvalue(p_res, i_path, 0)); 00222 p_paths[i_path].len += 1 + strlen(PQgetvalue(p_res, i_path, 0)); 00223 } 00224 00225 /* insert the object into cache */ 00226 fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]); 00227 00228 } 00229 PQclear(p_res); 00230 } 00231 00232 EndTransaction(p_conn, p_res); 00233 00234 ReturnCodeDB(toomanypaths ? ERR_FSAL_POSIXDB_TOOMANYPATHS : ERR_FSAL_POSIXDB_NOERR, 0); 00235 } 00236 00237 fsal_posixdb_status_t fsal_posixdb_getParentDirHandle(fsal_posixdb_conn * p_conn, /* IN */ 00238 posixfsal_handle_t * p_object_handle, /* IN */ 00239 posixfsal_handle_t * p_parent_directory_handle /* OUT */ 00240 ) 00241 { 00242 PGresult *p_res; 00243 char handleid_str[MAX_HANDLEIDSTR_SIZE]; 00244 char handlets_str[MAX_HANDLETSSTR_SIZE]; 00245 const char *paramValues[2] = { handleid_str, handlets_str }; 00246 00247 /* sanity check */ 00248 if(!p_conn || !p_parent_directory_handle || !p_object_handle) 00249 00250 CheckConn(p_conn); 00251 00252 /* no need to start a transaction, there is anly one query */ 00253 snprintf(handleid_str, MAX_HANDLEIDSTR_SIZE, "%lli", p_object_handle->data.id); 00254 snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts); 00255 p_res = PQexecPrepared(p_conn, "lookupPathsExt", 2, paramValues, NULL, NULL, 0); 00256 CheckResult(p_res); 00257 00258 /* entry not found */ 00259 if(!PQntuples(p_res)) 00260 { 00261 PQclear(p_res); 00262 ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0); 00263 } 00264 LogDebug(COMPONENT_FSAL, "lookupPathsExt"); 00265 00266 p_parent_directory_handle->data.id = atoll(PQgetvalue(p_res, 0, 1)); 00267 p_parent_directory_handle->data.ts = atoi(PQgetvalue(p_res, 0, 2)); 00268 posixdb_internal_fillFileinfoFromStrValues(&(p_parent_directory_handle->data.info), PQgetvalue(p_res, 0, 3), PQgetvalue(p_res, 0, 4), PQgetvalue(p_res, 0, 5), /* nlink */ 00269 PQgetvalue(p_res, 0, 6), /* ctime */ 00270 PQgetvalue(p_res, 0, 7) /* ftype */ 00271 ); 00272 00273 PQclear(p_res); 00274 00275 ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0); 00276 }