nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00006 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 3 of the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with this library; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 * --------------------------------------- 00024 * 00025 * \File state_misc.c 00026 * \author $Author: deniel $ 00027 * \date $Date: 2006/01/05 15:14:51 $ 00028 * \version $Revision: 1.63 $ 00029 * \brief Some routines for management of the state abstraction layer, shared by other calls. 00030 * 00031 * state_misc.c : Some routines for management of the state abstraction layer, shared by other calls. 00032 * 00033 * 00034 */ 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif 00038 00039 #ifdef _SOLARIS 00040 #include "solaris_port.h" 00041 #endif /* _SOLARIS */ 00042 00043 #include <unistd.h> 00044 #include <sys/types.h> 00045 #include <sys/param.h> 00046 #include <time.h> 00047 #include <pthread.h> 00048 #include <string.h> 00049 #include <ctype.h> 00050 #include <assert.h> 00051 00052 #include "log.h" 00053 #include "HashData.h" 00054 #include "HashTable.h" 00055 #include "fsal.h" 00056 #include "sal_functions.h" 00057 #include "cache_inode_lru.h" 00058 00059 pool_t *state_owner_pool; /*< Pool for NFSv4 files's open owner */ 00060 pool_t *state_nfs4_owner_name_pool; /*< Pool for NFSv4 files's open_owner */ 00061 pool_t *state_v4_pool; /*< Pool for NFSv4 files's states */ 00062 00063 const char *state_err_str(state_status_t err) 00064 { 00065 switch(err) 00066 { 00067 case STATE_SUCCESS: return "STATE_SUCCESS"; 00068 case STATE_MALLOC_ERROR: return "STATE_MALLOC_ERROR"; 00069 case STATE_POOL_MUTEX_INIT_ERROR: return "STATE_POOL_MUTEX_INIT_ERROR"; 00070 case STATE_GET_NEW_LRU_ENTRY: return "STATE_GET_NEW_LRU_ENTRY"; 00071 case STATE_UNAPPROPRIATED_KEY: return "STATE_UNAPPROPRIATED_KEY"; 00072 case STATE_INIT_ENTRY_FAILED: return "STATE_INIT_ENTRY_FAILED"; 00073 case STATE_FSAL_ERROR: return "STATE_FSAL_ERROR"; 00074 case STATE_LRU_ERROR: return "STATE_LRU_ERROR"; 00075 case STATE_HASH_SET_ERROR: return "STATE_HASH_SET_ERROR"; 00076 case STATE_NOT_A_DIRECTORY: return "STATE_NOT_A_DIRECTORY"; 00077 case STATE_INCONSISTENT_ENTRY: return "STATE_INCONSISTENT_ENTRY"; 00078 case STATE_BAD_TYPE: return "STATE_BAD_TYPE"; 00079 case STATE_ENTRY_EXISTS: return "STATE_ENTRY_EXISTS"; 00080 case STATE_DIR_NOT_EMPTY: return "STATE_DIR_NOT_EMPTY"; 00081 case STATE_NOT_FOUND: return "STATE_NOT_FOUND"; 00082 case STATE_INVALID_ARGUMENT: return "STATE_INVALID_ARGUMENT"; 00083 case STATE_INSERT_ERROR: return "STATE_INSERT_ERROR"; 00084 case STATE_HASH_TABLE_ERROR: return "STATE_HASH_TABLE_ERROR"; 00085 case STATE_FSAL_EACCESS: return "STATE_FSAL_EACCESS"; 00086 case STATE_IS_A_DIRECTORY: return "STATE_IS_A_DIRECTORY"; 00087 case STATE_FSAL_EPERM: return "STATE_FSAL_EPERM"; 00088 case STATE_NO_SPACE_LEFT: return "STATE_NO_SPACE_LEFT"; 00089 case STATE_CACHE_CONTENT_ERROR: return "STATE_CACHE_CONTENT_ERROR"; 00090 case STATE_CACHE_CONTENT_EXISTS: return "STATE_CACHE_CONTENT_EXISTS"; 00091 case STATE_CACHE_CONTENT_EMPTY: return "STATE_CACHE_CONTENT_EMPTY"; 00092 case STATE_READ_ONLY_FS: return "STATE_READ_ONLY_FS"; 00093 case STATE_IO_ERROR: return "STATE_IO_ERROR"; 00094 case STATE_FSAL_ESTALE: return "STATE_FSAL_ESTALE"; 00095 case STATE_FSAL_ERR_SEC: return "STATE_FSAL_ERR_SEC"; 00096 case STATE_STATE_CONFLICT: return "STATE_STATE_CONFLICT"; 00097 case STATE_QUOTA_EXCEEDED: return "STATE_QUOTA_EXCEEDED"; 00098 case STATE_DEAD_ENTRY: return "STATE_DEAD_ENTRY"; 00099 case STATE_ASYNC_POST_ERROR: return "STATE_ASYNC_POST_ERROR"; 00100 case STATE_NOT_SUPPORTED: return "STATE_NOT_SUPPORTED"; 00101 case STATE_STATE_ERROR: return "STATE_STATE_ERROR"; 00102 case STATE_FSAL_DELAY: return "STATE_FSAL_DELAY"; 00103 case STATE_NAME_TOO_LONG: return "STATE_NAME_TOO_LONG"; 00104 case STATE_LOCK_CONFLICT: return "STATE_LOCK_CONFLICT"; 00105 case STATE_LOCK_BLOCKED: return "STATE_LOCK_BLOCKED"; 00106 case STATE_LOCK_DEADLOCK: return "STATE_LOCK_DEADLOCK"; 00107 case STATE_BAD_COOKIE: return "STATE_BAD_COOKIE"; 00108 case STATE_FILE_BIG: return "STATE_FILE_BIG"; 00109 case STATE_GRACE_PERIOD: return "STATE_GRACE_PERIOD"; 00110 case STATE_CACHE_INODE_ERR: return "STATE_CACHE_INODE_ERR"; 00111 case STATE_SIGNAL_ERROR: return "STATE_SIGNAL_ERROR"; 00112 case STATE_KILLED: return "STATE_KILLED"; 00113 case STATE_FILE_OPEN: return "STATE_FILE_OPEN"; 00114 } 00115 return "unknown"; 00116 } 00117 00118 state_status_t cache_inode_status_to_state_status(cache_inode_status_t status) 00119 { 00120 switch(status) 00121 { 00122 case CACHE_INODE_SUCCESS: return STATE_SUCCESS; 00123 case CACHE_INODE_MALLOC_ERROR: return STATE_MALLOC_ERROR; 00124 case CACHE_INODE_POOL_MUTEX_INIT_ERROR: return STATE_POOL_MUTEX_INIT_ERROR; 00125 case CACHE_INODE_GET_NEW_LRU_ENTRY: return STATE_GET_NEW_LRU_ENTRY; 00126 case CACHE_INODE_UNAPPROPRIATED_KEY: return STATE_UNAPPROPRIATED_KEY; 00127 case CACHE_INODE_INIT_ENTRY_FAILED: return STATE_INIT_ENTRY_FAILED; 00128 case CACHE_INODE_FSAL_ERROR: return STATE_FSAL_ERROR; 00129 case CACHE_INODE_LRU_ERROR: return STATE_LRU_ERROR; 00130 case CACHE_INODE_HASH_SET_ERROR: return STATE_HASH_SET_ERROR; 00131 case CACHE_INODE_NOT_A_DIRECTORY: return STATE_NOT_A_DIRECTORY; 00132 case CACHE_INODE_INCONSISTENT_ENTRY: return STATE_INCONSISTENT_ENTRY; 00133 case CACHE_INODE_BAD_TYPE: return STATE_BAD_TYPE; 00134 case CACHE_INODE_ENTRY_EXISTS: return STATE_ENTRY_EXISTS; 00135 case CACHE_INODE_DIR_NOT_EMPTY: return STATE_DIR_NOT_EMPTY; 00136 case CACHE_INODE_NOT_FOUND: return STATE_NOT_FOUND; 00137 case CACHE_INODE_INVALID_ARGUMENT: return STATE_INVALID_ARGUMENT; 00138 case CACHE_INODE_INSERT_ERROR: return STATE_INSERT_ERROR; 00139 case CACHE_INODE_HASH_TABLE_ERROR: return STATE_HASH_TABLE_ERROR; 00140 case CACHE_INODE_FSAL_EACCESS: return STATE_FSAL_EACCESS; 00141 case CACHE_INODE_IS_A_DIRECTORY: return STATE_IS_A_DIRECTORY; 00142 case CACHE_INODE_FSAL_EPERM: return STATE_FSAL_EPERM; 00143 case CACHE_INODE_NO_SPACE_LEFT: return STATE_NO_SPACE_LEFT; 00144 case CACHE_INODE_CACHE_CONTENT_ERROR: return STATE_CACHE_CONTENT_ERROR; 00145 case CACHE_INODE_CACHE_CONTENT_EXISTS: return STATE_CACHE_CONTENT_EXISTS; 00146 case CACHE_INODE_CACHE_CONTENT_EMPTY: return STATE_CACHE_CONTENT_EMPTY; 00147 case CACHE_INODE_READ_ONLY_FS: return STATE_READ_ONLY_FS; 00148 case CACHE_INODE_IO_ERROR: return STATE_IO_ERROR; 00149 case CACHE_INODE_FSAL_ESTALE: return STATE_FSAL_ESTALE; 00150 case CACHE_INODE_FSAL_ERR_SEC: return STATE_FSAL_ERR_SEC; 00151 case CACHE_INODE_STATE_CONFLICT: return STATE_STATE_CONFLICT; 00152 case CACHE_INODE_QUOTA_EXCEEDED: return STATE_QUOTA_EXCEEDED; 00153 case CACHE_INODE_DEAD_ENTRY: return STATE_DEAD_ENTRY; 00154 case CACHE_INODE_ASYNC_POST_ERROR: return STATE_ASYNC_POST_ERROR; 00155 case CACHE_INODE_NOT_SUPPORTED: return STATE_NOT_SUPPORTED; 00156 case CACHE_INODE_STATE_ERROR: return STATE_STATE_ERROR; 00157 case CACHE_INODE_DELAY: return STATE_FSAL_DELAY; 00158 case CACHE_INODE_NAME_TOO_LONG: return STATE_NAME_TOO_LONG; 00159 case CACHE_INODE_BAD_COOKIE: return STATE_BAD_COOKIE; 00160 case CACHE_INODE_FILE_BIG: return STATE_FILE_BIG; 00161 case CACHE_INODE_KILLED: return STATE_KILLED; 00162 case CACHE_INODE_FILE_OPEN: return STATE_FILE_OPEN; 00163 } 00164 return STATE_CACHE_INODE_ERR; 00165 } 00166 00178 state_status_t state_error_convert(fsal_status_t fsal_status) 00179 { 00180 switch (fsal_status.major) 00181 { 00182 case ERR_FSAL_NO_ERROR: 00183 return STATE_SUCCESS; 00184 00185 case ERR_FSAL_NOENT: 00186 return STATE_NOT_FOUND; 00187 00188 case ERR_FSAL_DELAY: 00189 case ERR_FSAL_ACCESS: 00190 /* EDELAY and EACCESS are documented by fcntl as 00191 * indicating lock conflict 00192 */ 00193 return STATE_LOCK_CONFLICT; 00194 00195 case ERR_FSAL_PERM: 00196 return STATE_FSAL_EPERM; 00197 00198 case ERR_FSAL_NOSPC: 00199 return STATE_NO_SPACE_LEFT; 00200 00201 case ERR_FSAL_ROFS: 00202 return STATE_READ_ONLY_FS; 00203 00204 case ERR_FSAL_IO: 00205 case ERR_FSAL_NXIO: 00206 return STATE_IO_ERROR; 00207 00208 case ERR_FSAL_STALE: 00209 case ERR_FSAL_BADHANDLE: 00210 case ERR_FSAL_FHEXPIRED: 00211 return STATE_FSAL_ESTALE; 00212 00213 case ERR_FSAL_INVAL: 00214 case ERR_FSAL_OVERFLOW: 00215 return STATE_INVALID_ARGUMENT; 00216 00217 case ERR_FSAL_SEC: 00218 return STATE_FSAL_ERR_SEC; 00219 00220 case ERR_FSAL_NOTSUPP: 00221 case ERR_FSAL_ATTRNOTSUPP: 00222 return STATE_NOT_SUPPORTED; 00223 00224 case ERR_FSAL_NOMEM: 00225 return STATE_MALLOC_ERROR; 00226 00227 case ERR_FSAL_DEADLOCK: 00228 return STATE_LOCK_DEADLOCK; 00229 00230 case ERR_FSAL_BADCOOKIE: 00231 return STATE_BAD_COOKIE; 00232 00233 case ERR_FSAL_NOT_OPENED: 00234 LogDebug(COMPONENT_STATE, 00235 "Conversion of ERR_FSAL_NOT_OPENED to STATE_FSAL_ERROR"); 00236 return STATE_FSAL_ERROR; 00237 00238 case ERR_FSAL_SYMLINK: 00239 case ERR_FSAL_ISDIR: 00240 case ERR_FSAL_BADTYPE: 00241 return STATE_BAD_TYPE; 00242 00243 case ERR_FSAL_FBIG: 00244 return STATE_FILE_BIG; 00245 00246 case ERR_FSAL_FILE_OPEN: 00247 return STATE_FILE_OPEN; 00248 00249 case ERR_FSAL_BLOCKED: 00250 return STATE_LOCK_BLOCKED; 00251 00252 case ERR_FSAL_DQUOT: 00253 case ERR_FSAL_NAMETOOLONG: 00254 case ERR_FSAL_EXIST: 00255 case ERR_FSAL_NOTEMPTY: 00256 case ERR_FSAL_NOTDIR: 00257 case ERR_FSAL_INTERRUPT: 00258 case ERR_FSAL_FAULT: 00259 case ERR_FSAL_NOT_INIT: 00260 case ERR_FSAL_ALREADY_INIT: 00261 case ERR_FSAL_BAD_INIT: 00262 case ERR_FSAL_NO_QUOTA: 00263 case ERR_FSAL_XDEV: 00264 case ERR_FSAL_MLINK: 00265 case ERR_FSAL_TOOSMALL: 00266 case ERR_FSAL_TIMEOUT: 00267 case ERR_FSAL_SERVERFAULT: 00268 /* These errors should be handled inside state (or should never be seen by state) */ 00269 LogDebug(COMPONENT_STATE, 00270 "Conversion of FSAL error %d,%d to STATE_FSAL_ERROR", 00271 fsal_status.major, fsal_status.minor); 00272 return STATE_FSAL_ERROR; 00273 } 00274 00275 /* We should never reach this line, this may produce a warning with certain compiler */ 00276 LogCrit(COMPONENT_STATE, 00277 "Default conversion to STATE_FSAL_ERROR for error %d, line %u should never be reached", 00278 fsal_status.major, __LINE__); 00279 return STATE_FSAL_ERROR; 00280 } /* state_error_convert */ 00281 00282 /* Error conversion routines */ 00292 nfsstat4 nfs4_Errno_state(state_status_t error) 00293 { 00294 nfsstat4 nfserror= NFS4ERR_INVAL; 00295 00296 switch (error) 00297 { 00298 case STATE_SUCCESS: 00299 nfserror = NFS4_OK; 00300 break; 00301 00302 case STATE_MALLOC_ERROR: 00303 nfserror = NFS4ERR_RESOURCE; 00304 break; 00305 00306 case STATE_POOL_MUTEX_INIT_ERROR: 00307 case STATE_GET_NEW_LRU_ENTRY: 00308 case STATE_INIT_ENTRY_FAILED: 00309 case STATE_CACHE_CONTENT_EXISTS: 00310 case STATE_CACHE_CONTENT_EMPTY: 00311 nfserror = NFS4ERR_SERVERFAULT; 00312 break; 00313 00314 case STATE_UNAPPROPRIATED_KEY: 00315 nfserror = NFS4ERR_BADHANDLE; 00316 break; 00317 00318 case STATE_BAD_TYPE: 00319 nfserror = NFS4ERR_INVAL; 00320 break; 00321 00322 case STATE_NOT_A_DIRECTORY: 00323 nfserror = NFS4ERR_NOTDIR; 00324 break; 00325 00326 case STATE_ENTRY_EXISTS: 00327 nfserror = NFS4ERR_EXIST; 00328 break; 00329 00330 case STATE_DIR_NOT_EMPTY: 00331 nfserror = NFS4ERR_NOTEMPTY; 00332 break; 00333 00334 case STATE_NOT_FOUND: 00335 nfserror = NFS4ERR_NOENT; 00336 break; 00337 00338 case STATE_FSAL_ERROR: 00339 case STATE_INSERT_ERROR: 00340 case STATE_LRU_ERROR: 00341 case STATE_HASH_SET_ERROR: 00342 nfserror = NFS4ERR_IO; 00343 break; 00344 00345 case STATE_FSAL_EACCESS: 00346 nfserror = NFS4ERR_ACCESS; 00347 break; 00348 00349 case STATE_FSAL_EPERM: 00350 case STATE_FSAL_ERR_SEC: 00351 nfserror = NFS4ERR_PERM; 00352 break; 00353 00354 case STATE_NO_SPACE_LEFT: 00355 nfserror = NFS4ERR_NOSPC; 00356 break; 00357 00358 case STATE_IS_A_DIRECTORY: 00359 nfserror = NFS4ERR_ISDIR; 00360 break; 00361 00362 case STATE_READ_ONLY_FS: 00363 nfserror = NFS4ERR_ROFS; 00364 break; 00365 00366 case STATE_IO_ERROR: 00367 nfserror = NFS4ERR_IO; 00368 break; 00369 00370 case STATE_FILE_OPEN: 00371 nfserror = NFS4ERR_FILE_OPEN; 00372 break; 00373 00374 case STATE_NAME_TOO_LONG: 00375 nfserror = NFS4ERR_NAMETOOLONG; 00376 break; 00377 00378 case STATE_KILLED: 00379 case STATE_DEAD_ENTRY: 00380 case STATE_FSAL_ESTALE: 00381 nfserror = NFS4ERR_STALE; 00382 break; 00383 00384 case STATE_STATE_CONFLICT: 00385 nfserror = NFS4ERR_SHARE_DENIED; 00386 break; 00387 00388 case STATE_QUOTA_EXCEEDED: 00389 nfserror = NFS4ERR_DQUOT; 00390 break; 00391 00392 case STATE_NOT_SUPPORTED: 00393 nfserror = NFS4ERR_NOTSUPP; 00394 break; 00395 00396 case STATE_FSAL_DELAY: 00397 nfserror = NFS4ERR_DELAY; 00398 break; 00399 00400 case STATE_FILE_BIG: 00401 nfserror = NFS4ERR_FBIG; 00402 break; 00403 00404 case STATE_LOCK_DEADLOCK: 00405 nfserror = NFS4ERR_DEADLOCK; 00406 break; 00407 00408 case STATE_LOCK_BLOCKED: 00409 case STATE_LOCK_CONFLICT: 00410 nfserror = NFS4ERR_DENIED; 00411 break; 00412 00413 case STATE_STATE_ERROR: 00414 nfserror = NFS4ERR_BAD_STATEID; 00415 break; 00416 00417 case STATE_BAD_COOKIE: 00418 nfserror = NFS4ERR_BAD_COOKIE; 00419 break; 00420 00421 case STATE_GRACE_PERIOD: 00422 nfserror = NFS4ERR_GRACE; 00423 break; 00424 00425 case STATE_INVALID_ARGUMENT: 00426 case STATE_CACHE_INODE_ERR: 00427 case STATE_INCONSISTENT_ENTRY: 00428 case STATE_HASH_TABLE_ERROR: 00429 case STATE_CACHE_CONTENT_ERROR: 00430 case STATE_ASYNC_POST_ERROR: 00431 case STATE_SIGNAL_ERROR: 00432 /* Should not occur */ 00433 nfserror = NFS4ERR_INVAL; 00434 break; 00435 } 00436 00437 return nfserror; 00438 } /* nfs4_Errno_state */ 00439 00449 nfsstat3 nfs3_Errno_state(state_status_t error) 00450 { 00451 nfsstat3 nfserror= NFS3ERR_INVAL; 00452 00453 switch (error) 00454 { 00455 case STATE_SUCCESS: 00456 nfserror = NFS3_OK; 00457 break; 00458 00459 case STATE_MALLOC_ERROR: 00460 case STATE_POOL_MUTEX_INIT_ERROR: 00461 case STATE_GET_NEW_LRU_ENTRY: 00462 case STATE_UNAPPROPRIATED_KEY: 00463 case STATE_INIT_ENTRY_FAILED: 00464 case STATE_CACHE_CONTENT_EXISTS: 00465 case STATE_CACHE_CONTENT_EMPTY: 00466 case STATE_INSERT_ERROR: 00467 case STATE_LRU_ERROR: 00468 case STATE_HASH_SET_ERROR: 00469 case STATE_FILE_OPEN: 00470 LogCrit(COMPONENT_NFSPROTO, 00471 "Error %u converted to NFS3ERR_IO but was set non-retryable", 00472 error); 00473 nfserror = NFS3ERR_IO; 00474 break; 00475 00476 case STATE_INVALID_ARGUMENT: 00477 nfserror = NFS3ERR_INVAL; 00478 break; 00479 00480 case STATE_FSAL_ERROR: 00481 case STATE_CACHE_CONTENT_ERROR: 00483 LogCrit(COMPONENT_NFSPROTO, 00484 "Error STATE_FSAL_ERROR converted to NFS3ERR_IO but was set non-retryable"); 00485 nfserror = NFS3ERR_IO; 00486 break; 00487 00488 case STATE_NOT_A_DIRECTORY: 00489 nfserror = NFS3ERR_NOTDIR; 00490 break; 00491 00492 case STATE_ENTRY_EXISTS: 00493 nfserror = NFS3ERR_EXIST; 00494 break; 00495 00496 case STATE_DIR_NOT_EMPTY: 00497 nfserror = NFS3ERR_NOTEMPTY; 00498 break; 00499 00500 case STATE_NOT_FOUND: 00501 nfserror = NFS3ERR_NOENT; 00502 break; 00503 00504 case STATE_FSAL_EACCESS: 00505 nfserror = NFS3ERR_ACCES; 00506 break; 00507 00508 case STATE_FSAL_EPERM: 00509 case STATE_FSAL_ERR_SEC: 00510 nfserror = NFS3ERR_PERM; 00511 break; 00512 00513 case STATE_NO_SPACE_LEFT: 00514 nfserror = NFS3ERR_NOSPC; 00515 break; 00516 00517 case STATE_IS_A_DIRECTORY: 00518 nfserror = NFS3ERR_ISDIR; 00519 break; 00520 00521 case STATE_READ_ONLY_FS: 00522 nfserror = NFS3ERR_ROFS; 00523 break; 00524 00525 case STATE_KILLED: 00526 case STATE_DEAD_ENTRY: 00527 case STATE_FSAL_ESTALE: 00528 nfserror = NFS3ERR_STALE; 00529 break; 00530 00531 case STATE_QUOTA_EXCEEDED: 00532 nfserror = NFS3ERR_DQUOT; 00533 break; 00534 00535 case STATE_BAD_TYPE: 00536 nfserror = NFS3ERR_BADTYPE; 00537 break; 00538 00539 case STATE_NOT_SUPPORTED: 00540 nfserror = NFS3ERR_NOTSUPP; 00541 break; 00542 00543 case STATE_FSAL_DELAY: 00544 nfserror = NFS3ERR_JUKEBOX; 00545 break; 00546 00547 case STATE_IO_ERROR: 00548 LogCrit(COMPONENT_NFSPROTO, 00549 "Error STATE_IO_ERROR converted to NFS3ERR_IO but was set non-retryable"); 00550 nfserror = NFS3ERR_IO; 00551 break; 00552 00553 case STATE_NAME_TOO_LONG: 00554 nfserror = NFS3ERR_NAMETOOLONG; 00555 break; 00556 00557 case STATE_FILE_BIG: 00558 nfserror = NFS3ERR_FBIG; 00559 break; 00560 00561 case STATE_BAD_COOKIE: 00562 nfserror = NFS3ERR_BAD_COOKIE; 00563 break; 00564 00565 case STATE_CACHE_INODE_ERR: 00566 case STATE_INCONSISTENT_ENTRY: 00567 case STATE_HASH_TABLE_ERROR: 00568 case STATE_STATE_CONFLICT: 00569 case STATE_ASYNC_POST_ERROR: 00570 case STATE_STATE_ERROR: 00571 case STATE_LOCK_CONFLICT: 00572 case STATE_LOCK_BLOCKED: 00573 case STATE_LOCK_DEADLOCK: 00574 case STATE_GRACE_PERIOD: 00575 case STATE_SIGNAL_ERROR: 00576 /* Should not occur */ 00577 LogDebug(COMPONENT_NFSPROTO, 00578 "Unexpected status for conversion = %s", 00579 state_err_str(error)); 00580 nfserror = NFS3ERR_INVAL; 00581 break; 00582 } 00583 00584 return nfserror; 00585 } /* nfs3_Errno_state */ 00586 00596 nfsstat2 nfs2_Errno_state(state_status_t error) 00597 { 00598 nfsstat2 nfserror= NFSERR_IO; 00599 00600 switch (error) 00601 { 00602 case STATE_SUCCESS: 00603 nfserror = NFS_OK; 00604 break; 00605 00606 case STATE_MALLOC_ERROR: 00607 case STATE_POOL_MUTEX_INIT_ERROR: 00608 case STATE_GET_NEW_LRU_ENTRY: 00609 case STATE_UNAPPROPRIATED_KEY: 00610 case STATE_INIT_ENTRY_FAILED: 00611 case STATE_BAD_TYPE: 00612 case STATE_CACHE_CONTENT_EXISTS: 00613 case STATE_CACHE_CONTENT_EMPTY: 00614 case STATE_INSERT_ERROR: 00615 case STATE_LRU_ERROR: 00616 case STATE_HASH_SET_ERROR: 00617 case STATE_INVALID_ARGUMENT: 00618 LogCrit(COMPONENT_NFSPROTO, 00619 "Error %u converted to NFSERR_IO but was set non-retryable", 00620 error); 00621 nfserror = NFSERR_IO; 00622 break; 00623 00624 case STATE_NOT_A_DIRECTORY: 00625 nfserror = NFSERR_NOTDIR; 00626 break; 00627 00628 case STATE_ENTRY_EXISTS: 00629 nfserror = NFSERR_EXIST; 00630 break; 00631 00632 case STATE_FSAL_ERROR: 00633 case STATE_CACHE_CONTENT_ERROR: 00634 LogCrit(COMPONENT_NFSPROTO, 00635 "Error STATE_FSAL_ERROR converted to NFSERR_IO but was set non-retryable"); 00636 nfserror = NFSERR_IO; 00637 break; 00638 00639 case STATE_DIR_NOT_EMPTY: 00640 nfserror = NFSERR_NOTEMPTY; 00641 break; 00642 00643 case STATE_NOT_FOUND: 00644 nfserror = NFSERR_NOENT; 00645 break; 00646 00647 case STATE_FSAL_EACCESS: 00648 nfserror = NFSERR_ACCES; 00649 break; 00650 00651 case STATE_NO_SPACE_LEFT: 00652 nfserror = NFSERR_NOSPC; 00653 break; 00654 00655 case STATE_FSAL_EPERM: 00656 case STATE_FSAL_ERR_SEC: 00657 nfserror = NFSERR_PERM; 00658 break; 00659 00660 case STATE_IS_A_DIRECTORY: 00661 nfserror = NFSERR_ISDIR; 00662 break; 00663 00664 case STATE_READ_ONLY_FS: 00665 nfserror = NFSERR_ROFS; 00666 break; 00667 00668 case STATE_KILLED: 00669 case STATE_DEAD_ENTRY: 00670 case STATE_FSAL_ESTALE: 00671 nfserror = NFSERR_STALE; 00672 break; 00673 00674 case STATE_QUOTA_EXCEEDED: 00675 nfserror = NFSERR_DQUOT; 00676 break; 00677 00678 case STATE_IO_ERROR: 00679 LogCrit(COMPONENT_NFSPROTO, 00680 "Error STATE_IO_ERROR converted to NFSERR_IO but was set non-retryable"); 00681 nfserror = NFSERR_IO; 00682 break; 00683 00684 case STATE_NAME_TOO_LONG: 00685 nfserror = NFSERR_NAMETOOLONG; 00686 break; 00687 00688 case STATE_CACHE_INODE_ERR: 00689 case STATE_INCONSISTENT_ENTRY: 00690 case STATE_HASH_TABLE_ERROR: 00691 case STATE_STATE_CONFLICT: 00692 case STATE_ASYNC_POST_ERROR: 00693 case STATE_STATE_ERROR: 00694 case STATE_LOCK_CONFLICT: 00695 case STATE_LOCK_BLOCKED: 00696 case STATE_LOCK_DEADLOCK: 00697 case STATE_NOT_SUPPORTED: 00698 case STATE_FSAL_DELAY: 00699 case STATE_BAD_COOKIE: 00700 case STATE_FILE_BIG: 00701 case STATE_GRACE_PERIOD: 00702 case STATE_SIGNAL_ERROR: 00703 case STATE_FILE_OPEN: 00704 /* Should not occur */ 00705 LogDebug(COMPONENT_NFSPROTO, 00706 "Unexpected conversion for status = %s", 00707 state_err_str(error)); 00708 nfserror = NFSERR_IO; 00709 break; 00710 } 00711 00712 return nfserror; 00713 } /* nfs2_Errno_state */ 00714 00715 const char * invalid_state_owner_type = "INVALID STATE OWNER TYPE"; 00716 00717 const char * state_owner_type_to_str(state_owner_type_t type) 00718 { 00719 switch(type) 00720 { 00721 case STATE_LOCK_OWNER_UNKNOWN: return "STATE_LOCK_OWNER_UNKNOWN"; 00722 #ifdef _USE_NLM 00723 case STATE_LOCK_OWNER_NLM: return "STATE_LOCK_OWNER_NLM"; 00724 #endif 00725 #ifdef _USE_9P 00726 case STATE_LOCK_OWNER_9P: return "STALE_LOCK_OWNER_9P"; 00727 #endif 00728 case STATE_OPEN_OWNER_NFSV4: return "STATE_OPEN_OWNER_NFSV4"; 00729 case STATE_LOCK_OWNER_NFSV4: return "STATE_LOCK_OWNER_NFSV4"; 00730 case STATE_CLIENTID_OWNER_NFSV4: return "STATE_CLIENTID_OWNER_NFSV4"; 00731 } 00732 return invalid_state_owner_type; 00733 } 00734 00735 int different_owners(state_owner_t *powner1, state_owner_t *powner2) 00736 { 00737 if(powner1 == NULL || powner2 == NULL) 00738 return 1; 00739 00740 /* Shortcut in case we actually are pointing to the same owner structure */ 00741 if(powner1 == powner2) 00742 return 0; 00743 00744 if(powner1->so_type != powner2->so_type) 00745 return 1; 00746 00747 switch(powner1->so_type) 00748 { 00749 #ifdef _USE_NLM 00750 case STATE_LOCK_OWNER_NLM: 00751 if(powner2->so_type != STATE_LOCK_OWNER_NLM) 00752 return 1; 00753 return compare_nlm_owner(powner1, powner2); 00754 #endif 00755 #ifdef _USE_9P 00756 case STATE_LOCK_OWNER_9P: 00757 if(powner2->so_type != STATE_LOCK_OWNER_9P) 00758 return 1; 00759 return compare_9p_owner(powner1, powner2); 00760 #endif 00761 case STATE_OPEN_OWNER_NFSV4: 00762 case STATE_LOCK_OWNER_NFSV4: 00763 case STATE_CLIENTID_OWNER_NFSV4: 00764 if(powner1->so_type != powner2->so_type) 00765 return 1; 00766 return compare_nfs4_owner(powner1, powner2); 00767 00768 case STATE_LOCK_OWNER_UNKNOWN: 00769 break; 00770 } 00771 00772 return 1; 00773 } 00774 00775 int DisplayOwner(state_owner_t *powner, char *buf) 00776 { 00777 if(powner != NULL) 00778 switch(powner->so_type) 00779 { 00780 #ifdef _USE_NLM 00781 case STATE_LOCK_OWNER_NLM: 00782 return display_nlm_owner(powner, buf); 00783 #endif 00784 #ifdef _USE_9P 00785 case STATE_LOCK_OWNER_9P: 00786 return display_9p_owner(powner, buf); 00787 #endif 00788 00789 case STATE_OPEN_OWNER_NFSV4: 00790 case STATE_LOCK_OWNER_NFSV4: 00791 case STATE_CLIENTID_OWNER_NFSV4: 00792 return display_nfs4_owner(powner, buf); 00793 00794 case STATE_LOCK_OWNER_UNKNOWN: 00795 return sprintf(buf, 00796 "%s powner=%p: refcount=%d", 00797 state_owner_type_to_str(powner->so_type), powner, powner->so_refcount); 00798 } 00799 00800 return sprintf(buf, "%s", invalid_state_owner_type); 00801 } 00802 00803 int Hash_dec_state_owner_ref(hash_buffer_t *buffval) 00804 { 00805 int rc; 00806 state_owner_t *powner = (state_owner_t *)(buffval->pdata); 00807 00808 P(powner->so_mutex); 00809 00810 powner->so_refcount--; 00811 00812 if(isFullDebug(COMPONENT_STATE)) 00813 { 00814 char str[HASHTABLE_DISPLAY_STRLEN]; 00815 00816 DisplayOwner(powner, str); 00817 LogFullDebug(COMPONENT_STATE, 00818 "Decrement refcount for {%s}", 00819 str); 00820 } 00821 00822 rc = powner->so_refcount; 00823 00824 V(powner->so_mutex); 00825 00826 return rc; 00827 } 00828 00829 void Hash_inc_state_owner_ref(hash_buffer_t *buffval) 00830 { 00831 state_owner_t *powner = (state_owner_t *)(buffval->pdata); 00832 00833 P(powner->so_mutex); 00834 powner->so_refcount++; 00835 00836 if(isFullDebug(COMPONENT_STATE)) 00837 { 00838 char str[HASHTABLE_DISPLAY_STRLEN]; 00839 00840 DisplayOwner(powner, str); 00841 LogFullDebug(COMPONENT_STATE, 00842 "Increment refcount for {%s}", 00843 str); 00844 } 00845 00846 V(powner->so_mutex); 00847 } 00848 00849 void inc_state_owner_ref_locked(state_owner_t *powner) 00850 { 00851 powner->so_refcount++; 00852 00853 if(isFullDebug(COMPONENT_STATE)) 00854 { 00855 char str[HASHTABLE_DISPLAY_STRLEN]; 00856 00857 DisplayOwner(powner, str); 00858 LogFullDebug(COMPONENT_STATE, 00859 "Increment refcount for {%s}", 00860 str); 00861 } 00862 00863 V(powner->so_mutex); 00864 } 00865 00866 void inc_state_owner_ref(state_owner_t *powner) 00867 { 00868 P(powner->so_mutex); 00869 00870 inc_state_owner_ref_locked(powner); 00871 } 00872 00873 void dec_state_owner_ref_locked(state_owner_t * powner) 00874 { 00875 bool_t remove = FALSE; 00876 char str[HASHTABLE_DISPLAY_STRLEN]; 00877 00878 if(isDebug(COMPONENT_STATE)) 00879 DisplayOwner(powner, str); 00880 00881 if(powner->so_refcount > 1) 00882 { 00883 powner->so_refcount--; 00884 00885 LogFullDebug(COMPONENT_STATE, 00886 "Decrement refcount for {%s}", 00887 str); 00888 } 00889 else 00890 { 00891 LogFullDebug(COMPONENT_STATE, 00892 "Refcount for {%s} is 1", 00893 str); 00894 remove = TRUE; 00895 } 00896 00897 V(powner->so_mutex); 00898 00899 if(remove) 00900 { 00901 switch(powner->so_type) 00902 { 00903 #ifdef _USE_NLM 00904 case STATE_LOCK_OWNER_NLM: 00905 remove_nlm_owner(powner, str); 00906 break; 00907 #endif 00908 #ifdef _USE_9P 00909 case STATE_LOCK_OWNER_9P: 00910 remove_9p_owner( powner, str); 00911 #endif 00912 case STATE_OPEN_OWNER_NFSV4: 00913 case STATE_LOCK_OWNER_NFSV4: 00914 case STATE_CLIENTID_OWNER_NFSV4: 00915 remove_nfs4_owner(powner, str); 00916 break; 00917 00918 case STATE_LOCK_OWNER_UNKNOWN: 00919 LogDebug(COMPONENT_STATE, 00920 "Unexpected removal of powner=%p: %s", 00921 powner, str); 00922 break; 00923 } 00924 } 00925 } 00926 00927 void dec_state_owner_ref(state_owner_t * powner) 00928 { 00929 P(powner->so_mutex); 00930 00931 dec_state_owner_ref_locked(powner); 00932 } 00933 00934 void state_wipe_file(cache_entry_t * pentry) 00935 { 00936 bool_t had_lock = FALSE; 00937 00938 /* 00939 * currently, only REGULAR files can have state; byte range locks and 00940 * stateid (for v4). In the future, 4.1, directories could have 00941 * delegations, which is state. At that point, we may need to modify 00942 * this routine to clear state on directories. 00943 */ 00944 if (pentry->type != REGULAR_FILE) 00945 return; 00946 00947 /* The state lock may have been acquired by the caller. */ 00948 if (pthread_rwlock_trywrlock(&pentry->state_lock)) 00949 { 00950 /* This thread already has some kind of lock, but we don't know 00951 if it's a write lock. */ 00952 had_lock = TRUE; 00953 pthread_rwlock_unlock(&pentry->state_lock); 00954 } 00955 pthread_rwlock_wrlock(&pentry->state_lock); 00956 state_lock_wipe(pentry); 00957 state_nfs4_state_wipe(pentry); 00958 if (!had_lock) 00959 { 00960 pthread_rwlock_unlock(&pentry->state_lock); 00961 } 00962 } 00963 00964 int DisplayOpaqueValue(char * value, int len, char * str) 00965 { 00966 unsigned int i = 0; 00967 char * strtmp = str; 00968 00969 if(value == NULL || len == 0) 00970 return sprintf(str, "(NULL)"); 00971 00972 strtmp += sprintf(strtmp, "(%d:", len); 00973 00974 assert(len > 0); 00975 00976 if(len < 0 || len > 1024) 00977 len = 1024; 00978 00979 for(i = 0; i < len; i++) 00980 if(!isprint(value[i])) 00981 break; 00982 00983 if(i == len) 00984 { 00985 memcpy(strtmp, value, len); 00986 strtmp += len; 00987 *strtmp = '\0'; 00988 } 00989 else 00990 { 00991 strtmp += sprintf(strtmp, "0x"); 00992 for(i = 0; i < len; i++) 00993 strtmp += sprintf(strtmp, "%02x", (unsigned char)value[i]); 00994 } 00995 00996 strtmp += sprintf(strtmp, ")"); 00997 00998 return strtmp - str; 00999 }