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