nfs-ganesha 1.4
|
00001 /* 00002 * 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 License 00011 * as published by the Free Software Foundation; either version 3 of 00012 * the License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, but 00015 * 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 00022 * 02110-1301 USA 00023 * 00024 * --------------------------------------- 00025 */ 00026 00036 #ifndef _CACHE_INODE_H 00037 #define _CACHE_INODE_H 00038 00039 #include <unistd.h> 00040 #include <sys/types.h> 00041 #include <sys/param.h> 00042 #include <time.h> 00043 #include <pthread.h> 00044 00045 00046 #include "abstract_mem.h" 00047 #include "HashData.h" 00048 #include "HashTable.h" 00049 #include "avltree.h" 00050 #include "generic_weakref.h" 00051 #include "fsal.h" 00052 #include "log.h" 00053 #include "config_parsing.h" 00054 #include "nfs23.h" 00055 #include "nfs4.h" 00056 #ifdef _USE_NLM 00057 #include "nlm4.h" 00058 #endif 00059 #include "nlm_list.h" 00060 #ifdef _USE_NFS4_ACL 00061 #include "nfs4_acls.h" 00062 #endif /* _USE_NFS4_ACL */ 00063 00064 extern hash_table_t *fh_to_cache_entry_ht; /*< Global hash table for 00065 servicing lookups by 00066 fsal_handle_t. */ 00067 00068 /* Forward references */ 00069 typedef struct cache_entry_t cache_entry_t; 00070 00071 static const size_t FILEHANDLE_MAX_LEN_V2 = 32; /*< Maximum size of NFSv2 handle */ 00072 static const size_t FILEHANDLE_MAX_LEN_V3 = 64; /*< Maximum size of NFSv3 handle */ 00073 static const size_t FILEHANDLE_MAX_LEN_V4 = 128; /*< Maximum size of NFSv4 handle */ 00074 00075 static const size_t CACHE_INODE_UNSTABLE_BUFFERSIZE = 00076 100*1024*1024; /*< Size for Ganesha unstable write buffers*/ 00077 00083 typedef enum cache_inode_expire_type__ 00084 { 00085 CACHE_INODE_EXPIRE = 0, /*< Data expire when they have been refreshed 00086 less recently than grace period 00087 for their type allows. */ 00088 CACHE_INODE_EXPIRE_NEVER = 1, /*< Data never expire based on time. */ 00089 CACHE_INODE_EXPIRE_IMMEDIATE = 2 /*< Data are always treated as 00090 expired. */ 00091 } cache_inode_expire_type_t; 00092 00097 typedef enum cache_inode_stability__ { 00098 CACHE_INODE_UNSAFE_WRITE_TO_FS_BUFFER = 0, 00099 CACHE_INODE_SAFE_WRITE_TO_FS = 1, 00100 CACHE_INODE_UNSAFE_WRITE_TO_GANESHA_BUFFER = 2 00101 } cache_inode_stability_t; 00102 00103 00108 typedef struct cache_inode_lru__ 00109 { 00110 struct glist_head q; /*< Link in the physical deque impelmenting a 00111 portion of the logical LRU. */ 00112 pthread_mutex_t mtx; /*< Mutex protecting this entry with regard to 00113 LRU operations. */ 00114 int64_t refcount; /*< Reference count. This is signed to make 00115 mistakes easy to see. */ 00116 uint32_t pin_refcnt; /*< Unpin it only if this goes down to zero */ 00117 uint32_t flags; /*< Flags for details of this entry's status, such 00118 as whether it is pinned and whetehr it's in L1 00119 or L2. */ 00120 uint32_t lane; /*< The lane in which an entry currently resides, so 00121 we can lock the deque and decrement the correct 00122 counter when moving or deleting the entry. */ 00123 } cache_inode_lru_t; 00124 00129 typedef struct cache_inode_parameter__ 00130 { 00131 hash_parameter_t hparam; /*< Parameter used for hashtable initialization */ 00132 #ifdef _USE_NLM 00133 hash_parameter_t cookie_param; /*< Parameters used for lock cookie hash table 00134 initialization */ 00135 #endif 00136 fsal_attrib_mask_t attrmask; /*< FSAL attributes to be used in FSAL */ 00137 cache_inode_expire_type_t expire_type_attr; /*< Cache inode expiration type 00138 for attributes */ 00139 cache_inode_expire_type_t expire_type_link; /*< Cache inode expiration type 00140 for symbolic links */ 00141 cache_inode_expire_type_t expire_type_dirent; /*< Cache inode expiration type 00142 for directory entries */ 00143 time_t grace_period_attr; /*< Cached attributes grace period */ 00144 time_t grace_period_link; /*< Cached link grace period */ 00145 time_t grace_period_dirent; /*< Cached dirent grace period */ 00146 bool_t getattr_dir_invalidation; /*< Use getattr as for directory 00147 invalidation */ 00148 bool_t use_test_access; /*< Is FSAL_test_access to be used? */ 00149 bool_t use_fsal_hash; /*< Do we rely on FSAL to hash handle or not? */ 00150 } cache_inode_parameter_t; 00151 00152 extern cache_inode_parameter_t cache_inode_params; 00157 typedef struct cache_inode_opened_file__ 00158 { 00159 fsal_file_t fd; /*< FSAL specific object representing a given file 00160 open. */ 00161 fsal_openflags_t openflags; /*< Flags showing whether the file is 00162 open for reading, writing, or both. */ 00163 } cache_inode_opened_file_t; 00164 00168 typedef enum cache_inode_file_type__ 00169 { 00170 UNASSIGNED = 1, /*< No filetype at all. */ 00171 REGULAR_FILE = 2, /*< Regular file (can be opened, read, written) */ 00172 CHARACTER_FILE = 3, /*< Character special device file */ 00173 BLOCK_FILE = 4, /*< Block special device file */ 00174 SYMBOLIC_LINK = 5, /*< Symbolic link */ 00175 SOCKET_FILE = 6, /*< Unix domain socket. */ 00176 FIFO_FILE = 7, /*< FIFO or 'named pipe' */ 00177 DIRECTORY = 8, /*< A directory */ 00178 FS_JUNCTION = 9, /*< A directory-like node leading from one 00179 filesystem to another */ 00180 RECYCLED = 10 /*< This entry has been recycled */ 00181 } cache_inode_file_type_t; 00182 00188 typedef enum io_direction__ 00189 { 00190 CACHE_INODE_READ = 1, /*< Reading */ 00191 CACHE_INODE_WRITE = 2 /*< Writing */ 00192 } cache_inode_io_direction_t; 00193 00199 typedef enum cache_inode_dirent_op__ 00200 { 00201 CACHE_INODE_DIRENT_OP_LOOKUP = 1, /*< Look up a name */ 00202 CACHE_INODE_DIRENT_OP_REMOVE = 2, /*< Remove a name */ 00203 CACHE_INODE_DIRENT_OP_RENAME = 3 /*< Rename node */ 00204 } cache_inode_dirent_op_t; 00205 00206 typedef enum cache_inode_avl_which__ 00207 { CACHE_INODE_AVL_NAMES = 1, 00208 CACHE_INODE_AVL_COOKIES = 2, 00209 CACHE_INODE_AVL_BOTH = 3 00210 } cache_inode_avl_which_t; 00211 00212 /* Flags set on cache_entry_t::flags*/ 00213 00214 static const uint32_t CACHE_INODE_TRUST_ATTRS 00215 = 0x00000001; /*< Trust stored attributes */ 00216 static const uint32_t CACHE_INODE_TRUST_CONTENT 00217 = 0x00000002; /*< Trust inode content (for the moment, directory and 00218 symlink) */ 00219 static const uint32_t CACHE_INODE_DIR_POPULATED 00220 = 0x00000004; /*< The directory has been populated (negative lookups 00221 are meaningful) */ 00222 00227 struct cache_inode_symlink__ 00228 { 00229 fsal_path_t content; /*< Content of the link */ 00230 }; 00231 00237 typedef struct cache_inode_unstable_data__ 00238 { 00239 caddr_t buffer; /*< Pointer in memory */ 00240 uint64_t offset; /*< Offset (relative to the start of the file) */ 00241 uint32_t length; /*< Length */ 00242 } cache_inode_unstable_data_t; 00243 00248 /* The ref counted share reservation state. 00249 * 00250 * Each field represents the count of instances of that flag being present 00251 * in a v3 or v4 share reservation. 00252 * 00253 * There is a separate count of v4 deny write flags so that they can be 00254 * enforced against v3 writes (v3 deny writes can not be enforced against 00255 * v3 writes because there is no connection between the share reservation 00256 * and the write operation). v3 reads will always be allowed. 00257 */ 00258 typedef struct cache_inode_share__ 00259 { 00260 unsigned int share_access_read; 00261 unsigned int share_access_write; 00262 unsigned int share_deny_read; 00263 unsigned int share_deny_write; 00264 unsigned int share_deny_write_v4; 00265 } cache_inode_share_t; 00266 00274 #define DIR_ENTRY_FLAG_NONE 0x0000 00275 #define DIR_ENTRY_FLAG_DELETED 0x0001 00276 00277 typedef struct cache_inode_dir_entry__ 00278 { 00279 struct avltree_node node_hk; /*< AVL node in tree */ 00280 struct { 00281 uint64_t k; /*< Integer cookie */ 00282 uint32_t p; /*< Number of probes, an efficiency metric */ 00283 } hk; 00284 gweakref_t entry; /*< Weak reference pointing to the cache entry */ 00285 fsal_name_t name; /*< The filename */ 00286 uint64_t fsal_cookie; /*< The cookie returned by the FSAL. */ 00287 uint32_t flags; /*< Flags */ 00288 } cache_inode_dir_entry_t; 00289 00336 struct cache_entry_t 00337 { 00338 fsal_handle_t handle; /*< The FSAL Handle */ 00339 struct fsal_handle_desc fh_desc; /*< Points to handle. Adds size, 00340 len for hash table etc. */ 00341 gweakref_t weakref; /*< A weakref for this entry (pointer and generation 00342 number.) The generation number is the only 00343 interesting part, but this way the weakref 00344 can be easily stashed somewhere. */ 00345 cache_inode_file_type_t type; /*< The type of the entry */ 00346 uint32_t flags; /*< Flags for this entry */ 00347 time_t change_time; /*< The time of the last operation ganesha knows 00348 about. We can ue this for change_info4, but 00349 atomic MUST BE SET TO FALSE. Don't use it 00350 for anything else (servicing getattr, 00351 etc.) */ 00352 time_t attr_time; /*< Time at which we last refreshed attributes. */ 00353 cache_inode_lru_t lru; /*< New style LRU link */ 00354 pthread_rwlock_t attr_lock; /*< Reader-writer lock for attributes */ 00355 fsal_attrib_list_t attributes; /*< The FSAL Attributes */ 00356 pthread_rwlock_t state_lock; /*< This is separated out from the 00357 content lock, since there are 00358 state oerations that don't affect 00359 anything guarded by content (for 00360 example, a layout return or 00361 request has no effect on a cached 00362 file handle) and the content lock 00363 may be released and reacquired 00364 several times in an operation that 00365 should not see changes i state. */ 00366 struct glist_head state_list; /*< Pointers for state list */ 00367 pthread_rwlock_t content_lock; /*< Lock on type-specific cached 00368 content. See locking discipline 00369 for details. */ 00370 union cache_inode_fsobj__ 00371 { 00372 struct cache_inode_file__ 00373 { 00374 cache_inode_opened_file_t open_fd;/*< Cached fsal_file_t for 00375 optimized access */ 00376 struct glist_head lock_list; /*< Pointers for lock list */ 00377 #ifdef _USE_NLM 00378 struct glist_head nlm_share_list; 00379 #endif 00380 cache_inode_unstable_data_t 00381 unstable_data; /*< Unstable data, for use with WRITE/COMMIT */ 00382 cache_inode_share_t share_state; /*< Share reservation state for 00383 this file. */ 00384 } file; /*< REGULAR_FILE data */ 00385 00386 struct cache_inode_symlink__ *symlink; /*< SYMLINK data */ 00387 00388 struct cache_inode_dir__ 00389 { 00390 bool_t root; /*< Marks this as the root directory of an export */ 00391 uint32_t nbactive; /*< Number of known active children */ 00392 char *referral; /*< NULL is not a referral. If not, this a 00393 'referral string' */ 00394 gweakref_t parent; /*< The parent of this directory 00395 ('..') */ 00396 struct { 00397 struct avltree t; 00398 struct avltree c; 00399 uint32_t collisions; 00400 } avl; 00401 } dir; /*< DIRECTORY data */ 00402 } object; /*< Filetype specific data, discriminated by the type 00403 field. Note that data for special files is in 00404 attributes.rawdev */ 00405 }; 00406 00407 typedef struct cache_inode_file__ cache_inode_file_t; 00408 typedef struct cache_inode_symlink__ cache_inode_symlink_t; 00409 typedef union cache_inode_fsobj__ cache_inode_fsobj_t; 00410 00415 typedef struct cache_inode_fsal_data__ 00416 { 00417 struct fsal_handle_desc fh_desc; 00418 } cache_inode_fsal_data_t; 00419 00424 extern pool_t *cache_inode_entry_pool; /*< Cache entries pool */ 00425 extern pool_t *cache_inode_symlink_pool; /*< Pool for SYMLINK data */ 00426 extern pool_t *cache_inode_dir_entry_pool; /*< Cached dir entry pool */ 00427 00432 typedef struct cache_inode_gc_policy__ 00433 { 00434 uint32_t entries_hwmark; /*< High water mark for cache entries */ 00435 uint32_t entries_lwmark; /*< Low water mark for cache_entries */ 00436 uint32_t lru_run_interval; /*< Interval in seconds between runs of 00437 the LRU cleaner thread */ 00438 bool_t use_fd_cache; /*< Do we cache fd or not? */ 00439 uint32_t fd_limit_percent; /*< The percentage of the system-imposed 00440 maximum of file descriptors at which 00441 Ganesha will deny requests. */ 00442 uint32_t fd_hwmark_percent; /*< The percentage of the system-imposed 00443 maximum of file descriptors above 00444 which Ganesha will make greater 00445 efforts at reaping. */ 00446 uint32_t fd_lwmark_percent; /*< The percentage of the system-imposed 00447 maximum of file descriptors below 00448 which Ganesha will not reap file 00449 descriptonot reap file 00450 descriptorsrs. */ 00451 uint32_t reaper_work; /*< Roughly, the amount of work to do on each 00452 pass through the thread under normal 00453 conditions. (Ideally, a multipel of the 00454 number of lanes.) */ 00455 uint32_t biggest_window; /*< The largest window (as a percentage of 00456 the system-imposed limit on FDs) of 00457 work that we will do in extremis. */ 00458 uint32_t required_progress; /*< Percentage of progress toward the 00459 high water mark required in in a 00460 pass through the thread when in 00461 extremis. */ 00462 uint32_t futility_count; /*< Number of failures to approach the high 00463 watermark before we disable caching, 00464 when in extremis. */ 00465 } cache_inode_gc_policy_t; 00466 00467 extern cache_inode_gc_policy_t cache_inode_gc_policy; 00468 00473 typedef union cache_inode_create_arg__ 00474 { 00475 fsal_path_t link_content; /*< Content of a symbolic link */ 00476 fsal_dev_t dev_spec; /*< Major/minor numbers for a device file */ 00477 bool_t newly_created_dir; /*< True if this directory has just been 00478 created, rather than pre-existing and 00479 loaded into the cache. */ 00480 } cache_inode_create_arg_t; 00481 00482 /* 00483 * Flags 00484 */ 00485 static const uint32_t CACHE_INODE_FLAG_NONE = 0x00; /*< The null flag */ 00486 static const uint32_t CACHE_INODE_FLAG_CREATE = 0x01; /*< Indicate that this 00487 inode newly 00488 created, rather 00489 than just being 00490 loaded into the 00491 cache */ 00492 static const uint32_t CACHE_INODE_FLAG_LOCK = 0x02; /*< Instruct the called 00493 function to take a 00494 lock on the entry */ 00495 static const uint32_t CACHE_INODE_FLAG_ATTR_HOLD = 0x04; /*< For a function 00496 called with the 00497 attribute lock 00498 held, do not 00499 release the 00500 attribute lock 00501 before 00502 returning */ 00503 static const uint32_t CACHE_INODE_FLAG_CONTENT_HOLD = 0x08; /*< For a 00504 function 00505 called with 00506 the content 00507 lock held, do 00508 not release 00509 the content 00510 lock before 00511 returning */ 00512 static const uint32_t CACHE_INODE_FLAG_ATTR_HAVE = 0x10; /*< For a function, 00513 indicates that 00514 the attribute 00515 lock is held */ 00516 static const uint32_t CACHE_INODE_FLAG_CONTENT_HAVE = 0x20; /*< For a 00517 function, 00518 indicates 00519 that the 00520 content lock 00521 is held */ 00522 static const uint32_t CACHE_INODE_FLAG_REALLYCLOSE = 0x80; /*< Close a file 00523 even with 00524 caching 00525 enabled */ 00526 /* 00527 * Flags to cache_inode_invalidate 00528 */ 00529 static const uint32_t CACHE_INODE_INVALIDATE_CLEARBITS = 0x01; 00530 static const uint32_t CACHE_INODE_INVALIDATE_CLOSE = 0x02; 00531 00532 /* 00533 * Prototypes for the functions 00534 */ 00535 00536 /* 00537 * Possible errors 00538 */ 00539 typedef enum cache_inode_status_t 00540 { 00541 CACHE_INODE_SUCCESS = 0, 00542 CACHE_INODE_MALLOC_ERROR = 1, 00543 CACHE_INODE_POOL_MUTEX_INIT_ERROR = 2, 00544 CACHE_INODE_GET_NEW_LRU_ENTRY = 3, 00545 CACHE_INODE_UNAPPROPRIATED_KEY = 4, 00546 CACHE_INODE_INIT_ENTRY_FAILED = 5, 00547 CACHE_INODE_FSAL_ERROR = 6, 00548 CACHE_INODE_LRU_ERROR = 7, 00549 CACHE_INODE_HASH_SET_ERROR = 8, 00550 CACHE_INODE_NOT_A_DIRECTORY = 9, 00551 CACHE_INODE_INCONSISTENT_ENTRY = 10, 00552 CACHE_INODE_BAD_TYPE = 11, 00553 CACHE_INODE_ENTRY_EXISTS = 12, 00554 CACHE_INODE_DIR_NOT_EMPTY = 13, 00555 CACHE_INODE_NOT_FOUND = 14, 00556 CACHE_INODE_INVALID_ARGUMENT = 15, 00557 CACHE_INODE_INSERT_ERROR = 16, 00558 CACHE_INODE_HASH_TABLE_ERROR = 17, 00559 CACHE_INODE_FSAL_EACCESS = 18, 00560 CACHE_INODE_IS_A_DIRECTORY = 19, 00561 CACHE_INODE_FSAL_EPERM = 20, 00562 CACHE_INODE_NO_SPACE_LEFT = 21, 00563 CACHE_INODE_CACHE_CONTENT_ERROR = 22, 00564 CACHE_INODE_CACHE_CONTENT_EXISTS = 23, 00565 CACHE_INODE_CACHE_CONTENT_EMPTY = 24, 00566 CACHE_INODE_READ_ONLY_FS = 25, 00567 CACHE_INODE_IO_ERROR = 26, 00568 CACHE_INODE_FSAL_ESTALE = 27, 00569 CACHE_INODE_FSAL_ERR_SEC = 28, 00570 CACHE_INODE_STATE_CONFLICT = 29, 00571 CACHE_INODE_QUOTA_EXCEEDED = 30, 00572 CACHE_INODE_DEAD_ENTRY = 31, 00573 CACHE_INODE_ASYNC_POST_ERROR = 32, 00574 CACHE_INODE_NOT_SUPPORTED = 33, 00575 CACHE_INODE_STATE_ERROR = 34, 00576 CACHE_INODE_DELAY = 35, 00577 CACHE_INODE_NAME_TOO_LONG = 36, 00578 CACHE_INODE_BAD_COOKIE = 40, 00579 CACHE_INODE_FILE_BIG = 41, 00580 CACHE_INODE_KILLED = 42, 00581 CACHE_INODE_FILE_OPEN = 43, 00582 } cache_inode_status_t; 00583 00596 typedef bool_t(*cache_inode_readdir_cb_t)( 00597 void *opaque, 00598 char *name, 00599 fsal_handle_t *handle, 00600 fsal_attrib_list_t *attrs, 00601 uint64_t cookie); 00602 00603 const char *cache_inode_err_str(cache_inode_status_t err); 00604 00605 void cache_inode_clean_entry(cache_entry_t *entry); 00606 int cache_inode_compare_key_fsal(hash_buffer_t *buff1, hash_buffer_t *buff2); 00607 void cache_inode_release_symlink(cache_entry_t *entry); 00608 00609 hash_table_t *cache_inode_init(cache_inode_parameter_t param, 00610 cache_inode_status_t * status); 00611 00612 cache_entry_t *cache_inode_get(cache_inode_fsal_data_t *fsdata, 00613 fsal_attrib_list_t *attr, 00614 fsal_op_context_t *context, 00615 cache_entry_t *associated, 00616 cache_inode_status_t *status); 00617 void cache_inode_put(cache_entry_t *entry); 00618 00619 cache_inode_status_t cache_inode_access_sw(cache_entry_t *entry, 00620 fsal_accessflags_t access_type, 00621 fsal_op_context_t *context, 00622 cache_inode_status_t *status, 00623 bool_t use_mutex); 00624 cache_inode_status_t cache_inode_access_no_mutex( 00625 cache_entry_t *entry, 00626 fsal_accessflags_t access_type, 00627 fsal_op_context_t *context, 00628 cache_inode_status_t *status); 00629 cache_inode_status_t cache_inode_access(cache_entry_t *entry, 00630 fsal_accessflags_t access_type, 00631 fsal_op_context_t *context, 00632 cache_inode_status_t *status); 00633 00634 fsal_file_t *cache_inode_fd(cache_entry_t *entry); 00635 00636 bool_t is_open_for_read(cache_entry_t *entry); 00637 bool_t is_open_for_write(cache_entry_t *entry); 00638 00639 cache_inode_status_t cache_inode_open(cache_entry_t *entry, 00640 fsal_openflags_t openflags, 00641 fsal_op_context_t *context, 00642 uint32_t flags, 00643 cache_inode_status_t *status); 00644 cache_inode_status_t cache_inode_close(cache_entry_t *entry, 00645 uint32_t flags, 00646 cache_inode_status_t *status); 00647 00648 cache_entry_t *cache_inode_create(cache_entry_t *entry_parent, 00649 fsal_name_t *name, 00650 cache_inode_file_type_t type, 00651 fsal_accessmode_t mode, 00652 cache_inode_create_arg_t *create_arg, 00653 fsal_attrib_list_t *attr, 00654 fsal_op_context_t *context, 00655 cache_inode_status_t *status); 00656 00657 cache_inode_status_t cache_inode_getattr(cache_entry_t *entry, 00658 fsal_attrib_list_t *attr, 00659 fsal_op_context_t *context, 00660 cache_inode_status_t *status); 00661 00662 cache_entry_t *cache_inode_lookup_impl(cache_entry_t *entry_parent, 00663 fsal_name_t *name, 00664 fsal_op_context_t *context, 00665 cache_inode_status_t *status); 00666 cache_entry_t *cache_inode_lookup(cache_entry_t *entry_parent, 00667 fsal_name_t *name, 00668 fsal_attrib_list_t *attr, 00669 fsal_op_context_t *context, 00670 cache_inode_status_t *status); 00671 00672 cache_entry_t *cache_inode_lookupp_impl(cache_entry_t *entry, 00673 fsal_op_context_t *context, 00674 cache_inode_status_t *status); 00675 cache_entry_t *cache_inode_lookupp(cache_entry_t *entry, 00676 fsal_op_context_t *context, 00677 cache_inode_status_t *status); 00678 00679 00680 cache_inode_status_t cache_inode_readlink(cache_entry_t *entry, 00681 fsal_path_t *link_content, 00682 fsal_op_context_t *context, 00683 cache_inode_status_t *status); 00684 00685 cache_inode_status_t cache_inode_link(cache_entry_t *entry_src, 00686 cache_entry_t *entry_dir_dest, 00687 fsal_name_t *link_name, 00688 fsal_attrib_list_t *attr, 00689 fsal_op_context_t *context, 00690 cache_inode_status_t *status); 00691 00692 cache_inode_status_t cache_inode_remove(cache_entry_t *entry, 00693 fsal_name_t *node_name, 00694 fsal_attrib_list_t *attr, 00695 fsal_op_context_t *context, 00696 cache_inode_status_t *status); 00697 cache_inode_status_t cache_inode_remove_impl(cache_entry_t *entry, 00698 fsal_name_t *name, 00699 fsal_op_context_t *context, 00700 cache_inode_status_t *status, 00701 uint32_t flags); 00702 00703 cache_inode_status_t cache_inode_clean_internal( 00704 cache_entry_t *to_remove_entry); 00705 00706 cache_inode_status_t cache_inode_operate_cached_dirent( 00707 cache_entry_t *entry_parent, 00708 fsal_name_t *name, 00709 fsal_name_t *newname, 00710 cache_inode_dirent_op_t dirent_op); 00711 00712 cache_inode_status_t cache_inode_remove_cached_dirent( 00713 cache_entry_t *entry_parent, 00714 fsal_name_t *name, 00715 cache_inode_status_t *status); 00716 00717 cache_inode_status_t cache_inode_rename_cached_dirent( 00718 cache_entry_t *entry_parent, 00719 fsal_name_t *oldname, 00720 fsal_name_t *newname, 00721 cache_inode_status_t *status); 00722 00723 cache_inode_status_t cache_inode_rename(cache_entry_t *entry, 00724 fsal_name_t *oldname, 00725 cache_entry_t *entry_dirdest, 00726 fsal_name_t *newname, 00727 fsal_attrib_list_t *attr_src, 00728 fsal_attrib_list_t *attr_dst, 00729 fsal_op_context_t *context, 00730 cache_inode_status_t *status); 00731 00732 cache_inode_status_t cache_inode_setattr(cache_entry_t *entry, 00733 fsal_attrib_list_t *attr, 00734 fsal_op_context_t *context, 00735 cache_inode_status_t *status); 00736 00737 cache_inode_status_t 00738 cache_inode_truncate_impl(cache_entry_t *entry, 00739 fsal_size_t length, 00740 fsal_attrib_list_t *attr, 00741 fsal_op_context_t *context, 00742 cache_inode_status_t *status); 00743 cache_inode_status_t cache_inode_truncate( 00744 cache_entry_t *entry, 00745 fsal_size_t length, 00746 fsal_attrib_list_t *attr, 00747 fsal_op_context_t *context, 00748 cache_inode_status_t *status); 00749 00750 cache_inode_status_t cache_inode_error_convert(fsal_status_t fsal_status); 00751 00752 cache_entry_t *cache_inode_new_entry(cache_inode_fsal_data_t *fsdata, 00753 fsal_attrib_list_t *attr, 00754 cache_inode_file_type_t type, 00755 cache_inode_create_arg_t *create_arg, 00756 cache_inode_status_t *status); 00757 00758 cache_inode_status_t cache_inode_add_data_cache(cache_entry_t *entry, 00759 fsal_op_context_t *context, 00760 cache_inode_status_t *status); 00761 cache_inode_status_t cache_inode_release_data_cache( 00762 cache_entry_t *entry, 00763 fsal_op_context_t *context, 00764 cache_inode_status_t *status); 00765 00766 cache_inode_status_t cache_inode_rdwr(cache_entry_t *entry, 00767 cache_inode_io_direction_t io_direction, 00768 uint64_t offset, 00769 size_t io_size, 00770 size_t *bytes_moved, 00771 void *buffer, 00772 bool_t *eof, 00773 fsal_op_context_t *context, 00774 cache_inode_stability_t stable, 00775 cache_inode_status_t *status); 00776 00777 static inline cache_inode_status_t 00778 cache_inode_read(cache_entry_t *entry, 00779 uint64_t offset, 00780 size_t io_size, 00781 size_t *bytes_moved, 00782 void *buffer, 00783 bool_t *eof, 00784 fsal_op_context_t *context, 00785 cache_inode_stability_t stable, 00786 cache_inode_status_t *status) 00787 { 00788 return cache_inode_rdwr(entry, CACHE_INODE_READ, offset, io_size, 00789 bytes_moved, buffer, eof, context, 00790 stable, status); 00791 } 00792 00793 static inline cache_inode_status_t 00794 cache_inode_write(cache_entry_t *entry, 00795 uint64_t offset, 00796 size_t io_size, 00797 size_t *bytes_moved, 00798 void *buffer, 00799 bool_t *eof, 00800 fsal_op_context_t *context, 00801 cache_inode_stability_t stable, 00802 cache_inode_status_t *status) 00803 { 00804 return cache_inode_rdwr(entry, CACHE_INODE_WRITE, offset, io_size, 00805 bytes_moved, buffer, eof, context, 00806 stable, status); 00807 } 00808 00809 cache_inode_status_t cache_inode_commit(cache_entry_t *entry, 00810 uint64_t offset, 00811 size_t count, 00812 cache_inode_stability_t stability, 00813 fsal_op_context_t *context, 00814 cache_inode_status_t *status); 00815 00816 cache_inode_status_t cache_inode_readdir_populate( 00817 cache_entry_t *directory, 00818 fsal_op_context_t *context, 00819 cache_inode_status_t *status); 00820 cache_inode_status_t cache_inode_readdir(cache_entry_t *directory, 00821 uint64_t cookie, 00822 unsigned int *nbfound, 00823 bool_t *eod_met, 00824 fsal_op_context_t *context, 00825 cache_inode_readdir_cb_t cb, 00826 void *cb_opaque, 00827 cache_inode_status_t *status); 00828 00829 cache_inode_status_t cache_inode_add_cached_dirent( 00830 cache_entry_t *parent, 00831 fsal_name_t *name, 00832 cache_entry_t *entry, 00833 cache_inode_dir_entry_t **dir_entry, 00834 cache_inode_status_t *status); 00835 cache_entry_t *cache_inode_make_root(cache_inode_fsal_data_t *fsdata, 00836 fsal_op_context_t *context, 00837 cache_inode_status_t *status); 00838 00839 cache_inode_status_t cache_inode_check_trust(cache_entry_t *entry, 00840 fsal_op_context_t *context); 00841 00842 cache_inode_file_type_t cache_inode_fsal_type_convert(fsal_nodetype_t type); 00843 00844 int cache_inode_types_are_rename_compatible(cache_entry_t *src, 00845 cache_entry_t *dest); 00846 00847 void cache_inode_print_dir(cache_entry_t *cache_entry_root); 00848 00849 cache_inode_status_t cache_inode_statfs(cache_entry_t *entry, 00850 fsal_dynamicfsinfo_t *dynamicinfo, 00851 fsal_op_context_t *context, 00852 cache_inode_status_t *status); 00853 00854 cache_inode_status_t cache_inode_is_dir_empty(cache_entry_t *entry); 00855 cache_inode_status_t cache_inode_is_dir_empty_WithLock(cache_entry_t *entry); 00856 00857 cache_inode_status_t cache_inode_invalidate_all_cached_dirent( 00858 cache_entry_t *entry, 00859 cache_inode_status_t *status); 00860 00861 void cache_inode_release_dirents(cache_entry_t *entry, 00862 cache_inode_avl_which_t which); 00863 00864 void cache_inode_kill_entry(cache_entry_t *entry); 00865 00866 cache_inode_status_t cache_inode_invalidate( 00867 cache_inode_fsal_data_t *fsal_data, 00868 cache_inode_status_t *status, 00869 uint32_t flags); 00870 00871 /* Parsing functions */ 00872 cache_inode_status_t cache_inode_read_conf_hash_parameter( 00873 config_file_t in_config, 00874 cache_inode_parameter_t *pparam); 00875 cache_inode_status_t cache_inode_read_conf_parameter( 00876 config_file_t in_config, 00877 cache_inode_parameter_t *pparam); 00878 cache_inode_status_t cache_inode_read_conf_gc_policy( 00879 config_file_t in_config, 00880 cache_inode_gc_policy_t *ppolicy); 00881 void cache_inode_print_conf_hash_parameter(FILE *output, 00882 cache_inode_parameter_t *param); 00883 void cache_inode_print_conf_parameter( 00884 FILE *output, 00885 cache_inode_parameter_t *param); 00886 void cache_inode_print_conf_gc_policy(FILE *output, 00887 cache_inode_gc_policy_t *gcpolicy); 00888 void cache_inode_expire_to_str(cache_inode_expire_type_t type, 00889 time_t value, 00890 char *out); 00891 inline bool_t cache_inode_file_holds_state(cache_entry_t *entry); 00892 00893 inline int cache_inode_set_time_current(fsal_time_t *ptime); 00894 00895 /* Hash functions for hashtables and RBT */ 00896 uint32_t cache_inode_fsal_hash_func(hash_parameter_t *p_hparam, 00897 hash_buffer_t *buffclef); 00898 uint64_t cache_inode_fsal_rbt_func(hash_parameter_t *p_hparam, 00899 hash_buffer_t *buffclef); 00900 int cache_inode_fsal_rbt_both(hash_parameter_t *p_hparam, 00901 hash_buffer_t *buffclef, 00902 uint32_t *phashval, 00903 uint64_t *prbtval); 00904 int display_key(hash_buffer_t *pbuff, char *str); 00905 int display_not_implemented(hash_buffer_t *pbuff, 00906 char *str); 00907 int display_value(hash_buffer_t *pbuff, char *str); 00908 00919 static inline void 00920 cache_inode_fixup_md(cache_entry_t *entry) 00921 { 00922 /* Set the refresh time for the cache entry */ 00923 entry->attr_time = time(NULL); 00924 /* TODO: This should really be changed to use sub-second time 00925 resolution when it's available. */ 00926 entry->change_time = entry->attributes.chgtime.seconds; 00927 /* Almost certainly not necessary */ 00928 entry->type = cache_inode_fsal_type_convert(entry->attributes.type); 00929 /* We have just loaded the attributes from the FSAL. */ 00930 entry->flags |= CACHE_INODE_TRUST_ATTRS; 00931 } 00932 00944 static inline cache_inode_status_t 00945 cache_inode_refresh_attrs(cache_entry_t *entry, 00946 fsal_op_context_t *context) 00947 { 00948 fsal_status_t fsal_status = {ERR_FSAL_NO_ERROR, 0}; 00949 cache_inode_status_t cache_status = CACHE_INODE_SUCCESS; 00950 00951 #ifdef _USE_NFS4_ACL 00952 if (entry->attributes.acl) { 00953 fsal_acl_status_t acl_status = 0; 00954 00955 nfs4_acl_release_entry(entry->attributes.acl, &acl_status); 00956 if (acl_status != NFS_V4_ACL_SUCCESS) { 00957 LogEvent(COMPONENT_CACHE_INODE, 00958 "Failed to release old acl, status=%d", 00959 acl_status); 00960 } 00961 entry->attributes.acl = NULL; 00962 } 00963 #endif /* _USE_NFS4_ACL */ 00964 00965 memset(&entry->attributes, 0, sizeof(fsal_attrib_list_t)); 00966 entry->attributes.asked_attributes = cache_inode_params.attrmask; 00967 00968 /* I assume this function will go away in the Lieb 00969 Rearchitecture. */ 00970 fsal_status = FSAL_getattrs_descriptor(cache_inode_fd(entry), 00971 &entry->handle, 00972 context, 00973 &entry->attributes); 00974 if (FSAL_IS_ERROR(fsal_status) && 00975 (fsal_status.major == ERR_FSAL_NOT_OPENED)) { 00976 fsal_status = FSAL_getattrs(&entry->handle, 00977 context, 00978 &entry->attributes); 00979 } 00980 if (FSAL_IS_ERROR(fsal_status)) { 00981 cache_inode_kill_entry(entry); 00982 cache_status 00983 = cache_inode_error_convert(fsal_status); 00984 goto out; 00985 } 00986 00987 cache_inode_fixup_md(entry); 00988 00989 cache_status = CACHE_INODE_SUCCESS; 00990 00991 out: 00992 return cache_status; 00993 } 00994 01005 static inline changeid4 01006 cache_inode_get_changeid4(cache_entry_t *entry) 01007 { 01008 return (changeid4) entry->change_time; 01009 } 01010 01028 static inline cache_inode_status_t 01029 cache_inode_lock_trust_attrs(cache_entry_t *entry, 01030 fsal_op_context_t *context) 01031 { 01032 cache_inode_status_t cache_status = CACHE_INODE_SUCCESS; 01033 01034 01035 pthread_rwlock_rdlock(&entry->attr_lock); 01036 /* Do we need to refresh? */ 01037 if (!(entry->flags & CACHE_INODE_TRUST_ATTRS) || 01038 FSAL_TEST_MASK(entry->attributes.asked_attributes, 01039 FSAL_ATTR_RDATTR_ERR)) { 01040 pthread_rwlock_unlock(&entry->attr_lock); 01041 pthread_rwlock_wrlock(&entry->attr_lock); 01042 /* Has someone else done it for us? */ 01043 if (!(entry->flags & CACHE_INODE_TRUST_ATTRS) || 01044 FSAL_TEST_MASK(entry->attributes.asked_attributes, 01045 FSAL_ATTR_RDATTR_ERR)) { 01046 /* Release the lock on error */ 01047 if ((cache_status = 01048 cache_inode_refresh_attrs(entry, 01049 context)) 01050 != CACHE_INODE_SUCCESS) { 01051 pthread_rwlock_unlock(&entry->attr_lock); 01052 } 01053 } 01054 } 01055 01056 return cache_status; 01057 } 01058 01059 #endif /* _CACHE_INODE_H */