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 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 00038 #ifndef _SAL_DATA_H 00039 #define _SAL_DATA_H 00040 00041 #include <unistd.h> 00042 #include <sys/types.h> 00043 #include <sys/param.h> 00044 #include <time.h> 00045 #include <pthread.h> 00046 00047 #include "cache_inode.h" 00048 #include "abstract_mem.h" 00049 #include "RW_Lock.h" 00050 #include "HashData.h" 00051 #include "HashTable.h" 00052 #include "fsal.h" 00053 #include "fsal_types.h" 00054 #include "log.h" 00055 #include "config_parsing.h" 00056 #include "nfs_core.h" 00057 #include "nfs23.h" 00058 #include "nfs4.h" 00059 #include "nfs_proto_functions.h" 00060 #ifdef _USE_NLM 00061 #include "nlm4.h" 00062 #endif /* _USE_NLM */ 00063 #ifdef _USE_9P 00064 #include "9p.h" 00065 #endif /* _USE_9P*/ 00066 #include "nlm_list.h" 00067 #ifdef _PNFS_MDS 00068 #include "fsal_pnfs.h" 00069 #endif /* _PNFS_MDS */ 00070 00071 /* Indicate if state code must support blocking locks 00072 * NLM supports blocking locks 00073 * Eventually NFS v4.1 will support blocking locks 00074 */ 00075 #ifdef _USE_NLM 00076 #define _USE_BLOCKING_LOCKS 00077 #endif /* _USE_NLM */ 00078 00079 #define STATE_LOCK_OFFSET_EOF 0xFFFFFFFFFFFFFFFFLL 00080 00081 /* Forward references to types */ 00082 typedef struct state_nfs4_owner_t state_nfs4_owner_t; 00083 typedef struct state_owner_t state_owner_t; 00084 typedef struct state_t state_t; 00085 typedef struct nfs_argop4_state nfs_argop4_state; 00086 typedef struct state_lock_entry_t state_lock_entry_t; 00087 typedef struct state_async_queue_t state_async_queue_t; 00088 typedef struct nfs_client_record_t nfs_client_record_t; 00089 #ifdef _USE_NLM 00090 typedef struct state_nlm_client_t state_nlm_client_t; 00091 typedef struct state_nlm_share_t state_nlm_share_t; 00092 #endif /* _USE_NLM */ 00093 #ifdef _USE_BLOCKING_LOCKS 00094 typedef struct state_cookie_entry_t state_cookie_entry_t; 00095 typedef struct state_block_data_t state_block_data_t; 00096 #endif /* _USE_BLOCKING_LOCKS */ 00097 #ifdef _PNFS_MDS 00098 typedef struct state_layout_segment_t state_layout_segment_t; 00099 #endif /* _PNFS_MDS */ 00100 00101 /****************************************************************************** 00102 * 00103 * NFSv4.1 Session data 00104 * 00105 ******************************************************************************/ 00106 00107 #define NFS41_SESSION_PER_CLIENT 3 00108 #define NFS41_NB_SLOTS 3 00109 #define NFS41_DRC_SIZE 32768 00110 00111 typedef struct nfs41_session_slot__ 00112 { 00113 sequenceid4 sequence; 00114 pthread_mutex_t lock; 00115 COMPOUND4res_extended cached_result; 00116 unsigned int cache_used; 00117 } nfs41_session_slot_t; 00118 00119 struct nfs41_session__ 00120 { 00121 clientid4 clientid; 00122 nfs_client_id_t * pclientid_record; 00123 uint32_t sequence; 00124 uint32_t session_flags; 00125 char session_id[NFS4_SESSIONID_SIZE]; 00126 channel_attrs4 fore_channel_attrs; 00127 channel_attrs4 back_channel_attrs; 00128 nfs41_session_slot_t slots[NFS41_NB_SLOTS]; 00129 }; 00130 00131 /****************************************************************************** 00132 * 00133 * NFSv4 State data 00134 * 00135 ******************************************************************************/ 00136 00137 typedef enum state_type_t 00138 { 00139 STATE_TYPE_NONE = 0, 00140 STATE_TYPE_SHARE = 1, 00141 STATE_TYPE_DELEG = 2, 00142 STATE_TYPE_LOCK = 4, 00143 STATE_TYPE_LAYOUT = 5 00144 } state_type_t; 00145 00146 typedef struct state_share__ 00147 { 00148 char share_oexcl_verifier[8]; 00149 unsigned int share_access; 00150 unsigned int share_deny; 00151 struct glist_head share_lockstates; 00152 unsigned int share_access_prev; 00153 unsigned int share_deny_prev; 00154 } state_share_t; 00155 00156 typedef struct state_lock_t 00157 { 00158 state_t * popenstate; 00159 struct glist_head state_locklist; 00160 struct glist_head state_sharelist; 00161 } state_lock_t; 00162 00163 typedef struct state_deleg__ 00164 { 00165 unsigned int nothing; 00166 } state_deleg_t; 00167 00168 typedef struct state_layout__ 00169 { 00170 #ifdef _PNFS_MDS 00171 layouttype4 state_layout_type; 00172 bool_t state_return_on_close; 00173 struct glist_head state_segments; 00174 #else /* !_PNFS_MDS */ 00175 int nothing; 00176 #endif /* !_PNFS_MDS */ 00177 } state_layout_t; 00178 00179 typedef union state_data_t 00180 { 00181 state_share_t share; 00182 state_lock_t lock; 00183 state_deleg_t deleg; 00184 state_layout_t layout; 00185 } state_data_t; 00186 00187 /* The value 12 is fixed by RFC3530 */ 00188 #define OTHERSIZE 12 00189 00190 extern char all_zero[OTHERSIZE]; 00191 extern char all_one[OTHERSIZE]; 00192 00193 struct state_t 00194 { 00195 struct glist_head state_list; 00196 struct glist_head state_owner_list; 00197 struct glist_head state_export_list; 00198 exportlist_t * state_pexport; 00199 state_owner_t * state_powner; 00200 cache_entry_t * state_pentry; 00201 state_type_t state_type; 00202 state_data_t state_data; 00203 u_int32_t state_seqid; 00204 char stateid_other[OTHERSIZE]; 00205 }; 00206 00207 /****************************************************************************** 00208 * 00209 * NFS Owner data 00210 * 00211 ******************************************************************************/ 00212 00213 typedef struct state_nfs4_owner_name_t 00214 { 00215 clientid4 son_clientid; 00216 unsigned int son_owner_len; 00217 char son_owner_val[MAXNAMLEN]; 00218 bool_t son_islock; 00219 } state_nfs4_owner_name_t; 00220 00221 typedef enum state_owner_type_t 00222 { 00223 STATE_LOCK_OWNER_UNKNOWN, 00224 #ifdef _USE_NLM 00225 STATE_LOCK_OWNER_NLM, 00226 #endif /* _USE_NLM */ 00227 #ifdef _USE_9P 00228 STATE_LOCK_OWNER_9P, 00229 #endif /* _USE_9P */ 00230 STATE_OPEN_OWNER_NFSV4, 00231 STATE_LOCK_OWNER_NFSV4, 00232 STATE_CLIENTID_OWNER_NFSV4 00233 } state_owner_type_t; 00234 00235 #ifdef _USE_NLM 00236 typedef enum care_t 00237 { 00238 CARE_NOT, 00239 CARE_NO_MONITOR, 00240 CARE_MONITOR 00241 } care_t; 00242 00243 typedef struct state_nsm_client_t 00244 { 00245 pthread_mutex_t ssc_mutex; 00246 struct glist_head ssc_lock_list; 00247 struct glist_head ssc_share_list; 00248 sockaddr_t ssc_client_addr; 00249 int ssc_refcount; 00250 bool_t ssc_monitored; 00251 int ssc_nlm_caller_name_len; 00252 char * ssc_nlm_caller_name; 00253 } state_nsm_client_t; 00254 00255 struct state_nlm_client_t 00256 { 00257 pthread_mutex_t slc_mutex; 00258 state_nsm_client_t * slc_nsm_client; 00259 xprt_type_t slc_client_type; 00260 int slc_refcount; 00261 int slc_nlm_caller_name_len; 00262 char slc_nlm_caller_name[LM_MAXSTRLEN+1]; 00263 CLIENT * slc_callback_clnt; 00264 }; 00265 00266 typedef struct state_nlm_owner_t 00267 { 00268 state_nlm_client_t * so_client; 00269 int32_t so_nlm_svid; 00270 struct glist_head so_nlm_shares; 00271 } state_nlm_owner_t; 00272 #endif /* _USE_NLM */ 00273 00274 #ifdef _USE_9P 00275 typedef struct state_9p_owner_t 00276 { 00277 u32 proc_id ; 00278 struct sockaddr_storage client_addr ; 00279 } state_9p_owner_t ; 00280 #endif /* _USE_9P */ 00281 00282 struct nfs_argop4_state 00283 { 00284 nfs_opnum4 argop; 00285 union 00286 { 00287 CLOSE4args opclose; 00288 LOCK4args oplock; 00289 LOCKU4args oplocku; 00290 OPEN4args opopen; 00291 OPEN_CONFIRM4args opopen_confirm; 00292 OPEN_DOWNGRADE4args opopen_downgrade; 00293 } nfs_argop4_u; 00294 }; 00295 00296 struct state_nfs4_owner_t 00297 { 00298 clientid4 so_clientid; 00299 nfs_client_id_t * so_pclientid; 00300 unsigned int so_confirmed; 00301 seqid4 so_seqid; 00302 uint32_t so_counter; 00303 nfs_argop4_state so_args; 00304 cache_entry_t * so_last_pentry; 00305 nfs_resop4 so_resp; 00306 state_owner_t * so_related_owner; 00307 struct glist_head so_state_list; 00308 struct glist_head so_perclient; 00309 }; 00310 00311 /* Undistinguished lock owner type */ 00312 struct state_owner_t 00313 { 00314 state_owner_type_t so_type; 00315 struct glist_head so_lock_list; 00316 pthread_mutex_t so_mutex; 00317 int so_refcount; 00318 int so_owner_len; 00319 char so_owner_val[NFS4_OPAQUE_LIMIT]; /* big enough for all owners */ 00320 union 00321 { 00322 state_nfs4_owner_t so_nfs4_owner; 00323 #ifdef _USE_NLM 00324 state_nlm_owner_t so_nlm_owner; 00325 #endif /* _USE_NLM */ 00326 #ifdef _USE_9P 00327 state_9p_owner_t so_9p_owner; 00328 #endif 00329 } so_owner; 00330 }; 00331 00332 extern state_owner_t unknown_owner; 00333 00334 /****************************************************************************** 00335 * 00336 * NFSv4 Clientid data 00337 * 00338 ******************************************************************************/ 00339 00340 typedef enum nfs_clientid_confirm_state__ 00341 { 00342 UNCONFIRMED_CLIENT_ID, 00343 CONFIRMED_CLIENT_ID, 00344 EXPIRED_CLIENT_ID 00345 } nfs_clientid_confirm_state_t; 00346 00347 /* client ID errors */ 00348 #define CLIENT_ID_SUCCESS 0 00349 #define CLIENT_ID_INSERT_MALLOC_ERROR 1 00350 #define CLIENT_ID_NOT_FOUND 2 00351 #define CLIENT_ID_INVALID_ARGUMENT 3 00352 #define CLIENT_ID_STATE_ERROR 4 00353 00354 struct nfs_client_id_t 00355 { 00356 clientid4 cid_clientid; 00357 verifier4 cid_verifier; 00358 verifier4 cid_incoming_verifier; 00359 time_t cid_last_renew; 00360 nfs_clientid_confirm_state_t cid_confirmed; 00361 nfs_client_cred_t cid_credential; 00362 sockaddr_t cid_client_addr; 00363 int cid_allow_reclaim; 00364 char * cid_recov_dir; 00365 nfs_client_record_t * cid_client_record; 00366 struct glist_head cid_openowners; 00367 struct glist_head cid_lockowners; 00368 pthread_mutex_t cid_mutex; 00369 struct { 00370 char cid_client_r_addr[SOCK_NAME_MAX]; /* supplied univ. address */ 00371 gsh_addr_t cid_addr; 00372 uint32_t cid_program; 00373 union { 00374 struct { 00375 struct rpc_call_channel cb_chan; 00376 uint32_t cb_callback_ident; 00377 } v40; 00378 } cb_u; 00379 } cid_cb; 00380 #ifdef _USE_NFS4_1 00381 char cid_server_owner[MAXNAMLEN]; 00382 char cid_server_scope[MAXNAMLEN]; 00383 unsigned int cid_nb_session; 00384 nfs41_session_slot_t cid_create_session_slot; 00385 unsigned cid_create_session_sequence; 00386 #endif 00387 state_owner_t cid_owner; 00388 int32_t cid_refcount; 00389 int cid_lease_reservations; 00390 }; 00391 00392 struct nfs_client_record_t 00393 { 00394 /* The cr_mutex should never be acquired while holding a cid_mutex */ 00395 char cr_client_val[NFS4_OPAQUE_LIMIT]; 00396 int cr_client_val_len; 00397 int32_t cr_refcount; 00398 pthread_mutex_t cr_mutex; 00399 nfs_client_id_t * cr_pconfirmed_id; 00400 nfs_client_id_t * cr_punconfirmed_id; 00401 }; 00402 00403 extern hash_table_t * ht_confirmed_client_id; 00404 extern hash_table_t * ht_unconfirmed_client_id; 00405 00406 00407 /****************************************************************************** 00408 * 00409 * Possible Errors from SAL Code 00410 * 00411 ******************************************************************************/ 00412 00413 typedef enum state_status_t 00414 { 00415 STATE_SUCCESS = 0, 00416 STATE_MALLOC_ERROR = 1, 00417 STATE_POOL_MUTEX_INIT_ERROR = 2, 00418 STATE_GET_NEW_LRU_ENTRY = 3, 00419 STATE_UNAPPROPRIATED_KEY = 4, 00420 STATE_INIT_ENTRY_FAILED = 5, 00421 STATE_FSAL_ERROR = 6, 00422 STATE_LRU_ERROR = 7, 00423 STATE_HASH_SET_ERROR = 8, 00424 STATE_NOT_A_DIRECTORY = 9, 00425 STATE_INCONSISTENT_ENTRY = 10, 00426 STATE_BAD_TYPE = 11, 00427 STATE_ENTRY_EXISTS = 12, 00428 STATE_DIR_NOT_EMPTY = 13, 00429 STATE_NOT_FOUND = 14, 00430 STATE_INVALID_ARGUMENT = 15, 00431 STATE_INSERT_ERROR = 16, 00432 STATE_HASH_TABLE_ERROR = 17, 00433 STATE_FSAL_EACCESS = 18, 00434 STATE_IS_A_DIRECTORY = 19, 00435 STATE_FSAL_EPERM = 20, 00436 STATE_NO_SPACE_LEFT = 21, 00437 STATE_CACHE_CONTENT_ERROR = 22, 00438 STATE_CACHE_CONTENT_EXISTS = 23, 00439 STATE_CACHE_CONTENT_EMPTY = 24, 00440 STATE_READ_ONLY_FS = 25, 00441 STATE_IO_ERROR = 26, 00442 STATE_FSAL_ESTALE = 27, 00443 STATE_FSAL_ERR_SEC = 28, 00444 STATE_STATE_CONFLICT = 29, 00445 STATE_QUOTA_EXCEEDED = 30, 00446 STATE_DEAD_ENTRY = 31, 00447 STATE_ASYNC_POST_ERROR = 32, 00448 STATE_NOT_SUPPORTED = 33, 00449 STATE_STATE_ERROR = 34, 00450 STATE_FSAL_DELAY = 35, 00451 STATE_NAME_TOO_LONG = 36, 00452 STATE_LOCK_CONFLICT = 37, 00453 STATE_LOCK_BLOCKED = 38, 00454 STATE_LOCK_DEADLOCK = 39, 00455 STATE_BAD_COOKIE = 40, 00456 STATE_FILE_BIG = 41, 00457 STATE_GRACE_PERIOD = 42, 00458 STATE_CACHE_INODE_ERR = 43, 00459 STATE_SIGNAL_ERROR = 44, 00460 STATE_KILLED = 45, 00461 STATE_FILE_OPEN = 46, 00462 } state_status_t; 00463 00464 /****************************************************************************** 00465 * 00466 * Lock Data 00467 * 00468 ******************************************************************************/ 00469 00470 typedef enum state_blocking_t 00471 { 00472 STATE_NON_BLOCKING, 00473 STATE_NLM_BLOCKING, 00474 STATE_NFSV4_BLOCKING, 00475 STATE_GRANTING, 00476 STATE_CANCELED 00477 } state_blocking_t; 00478 00479 /* The granted call back is responsible for acquiring a reference to 00480 * the lock entry if needed. 00481 * 00482 * NB: this is always defined to avoid conditional function prototype 00483 */ 00484 typedef state_status_t (*granted_callback_t)(cache_entry_t * pentry, 00485 state_lock_entry_t * lock_entry, 00486 state_status_t * pstatus); 00487 00488 #ifdef _USE_BLOCKING_LOCKS 00489 00490 typedef bool_t (*block_data_to_fsal_context_t)(state_block_data_t * block_data, 00491 fsal_op_context_t * fsal_context); 00492 00493 typedef struct state_nlm_block_data_t 00494 { 00495 sockaddr_t sbd_nlm_hostaddr; 00496 netobj sbd_nlm_fh; 00497 char sbd_nlm_fh_buf[MAX_NETOBJ_SZ]; 00498 } state_nlm_block_data_t; 00499 00500 /* List of all locks blocked in FSAL */ 00501 struct glist_head state_blocked_locks; 00502 00503 /* List of all async blocking locks notified by FSAL but not processed */ 00504 struct glist_head state_notified_locks; 00505 00506 /* Mutex to protect above lists */ 00507 pthread_mutex_t blocked_locks_mutex; 00508 00509 typedef enum state_grant_type_t 00510 { 00511 STATE_GRANT_NONE, 00512 STATE_GRANT_INTERNAL, 00513 STATE_GRANT_FSAL, 00514 STATE_GRANT_FSAL_AVAILABLE 00515 } state_grant_type_t; 00516 00517 struct state_block_data_t 00518 { 00519 struct glist_head sbd_list; 00520 state_grant_type_t sbd_grant_type; 00521 granted_callback_t sbd_granted_callback; 00522 state_cookie_entry_t * sbd_blocked_cookie; 00523 state_lock_entry_t * sbd_lock_entry; 00524 block_data_to_fsal_context_t sbd_block_data_to_fsal_context; 00525 struct user_credentials sbd_credential; 00526 union 00527 { 00528 #ifdef _USE_NLM 00529 state_nlm_block_data_t sbd_nlm_block_data; 00530 #endif /* _USE_NLM */ 00531 void * sbd_v4_block_data; 00532 } sbd_block_data; 00533 }; 00534 #else /* !_USE_BLOCKING_LOCKS */ 00535 typedef void state_block_data_t; 00536 #endif /* !_USE_BLOCKING_LOCKS */ 00537 00538 struct state_lock_entry_t 00539 { 00540 struct glist_head sle_list; 00541 struct glist_head sle_owner_locks; 00542 struct glist_head sle_locks; 00543 #ifdef _DEBUG_MEMLEAKS 00544 struct glist_head sle_all_locks; 00545 #endif /* _DEBUG_MEMLEAKS */ 00546 struct glist_head sle_export_locks; 00547 exportlist_t * sle_pexport; 00548 cache_entry_t * sle_pentry; 00549 state_block_data_t * sle_block_data; 00550 state_owner_t * sle_owner; 00551 state_t * sle_state; 00552 state_blocking_t sle_blocked; 00553 int sle_ref_count; 00554 fsal_lock_param_t sle_lock; 00555 pthread_mutex_t sle_mutex; 00556 }; 00557 00558 #ifdef _PNFS_MDS 00559 struct state_layout_segment_t 00560 { 00561 struct glist_head sls_state_segments; 00562 state_t * sls_state; 00563 struct pnfs_segment sls_segment; 00564 void * sls_fsal_data; 00565 pthread_mutex_t sls_mutex; 00566 }; 00567 #endif /* _PNFS_MDS */ 00568 00569 #ifdef _USE_NLM 00570 #define sle_client_locks sle_locks 00571 #endif /* _USE_NLM */ 00572 #define sle_state_locks sle_locks 00573 00574 #ifdef _USE_BLOCKING_LOCKS 00575 /* 00576 * Management of lce_refcount: 00577 * 00578 * state_add_grant_cookie creates a reference. 00579 * state_find_grant gets a reference 00580 * state_complete_grant always releases 1 reference 00581 * it releases a 2nd reference when the call instance 00582 * is the first to actually try and complete the grant 00583 * state_release_grant always releases 1 reference 00584 * it releases a 2nd reference when the call instance 00585 * is the first to actually try and release the grant 00586 * state_cancel_grant calls cancel_blocked_lock, which will release 00587 * the initial reference 00588 * cancel_blocked_lock releases 1 reference if cookie exists 00589 * called by state_cancel_grant 00590 * also called by unlock, cancel, sm_notify 00591 */ 00592 struct state_cookie_entry_t 00593 { 00594 cache_entry_t * sce_pentry; 00595 state_lock_entry_t * sce_lock_entry; 00596 void * sce_pcookie; 00597 int sce_cookie_size; 00598 }; 00599 00600 /* 00601 * Structures for state async processing 00602 * 00603 */ 00604 typedef void (state_async_func_t) (state_async_queue_t * arg); 00605 00606 #ifdef _USE_NLM 00607 typedef struct state_nlm_async_data_t 00608 { 00609 state_nlm_client_t * nlm_async_host; 00610 void * nlm_async_key; 00611 union 00612 { 00613 nfs_res_t nlm_async_res; 00614 nlm4_testargs nlm_async_grant; 00615 } nlm_async_args; 00616 } state_nlm_async_data_t; 00617 #endif /* _USE_NLM */ 00618 00619 typedef struct state_async_block_data_t 00620 { 00621 state_lock_entry_t * state_async_lock_entry; 00622 } state_async_block_data_t; 00623 00624 struct state_async_queue_t 00625 { 00626 struct glist_head state_async_glist; 00627 state_async_func_t * state_async_func; 00628 union 00629 { 00630 #ifdef _USE_NLM 00631 state_nlm_async_data_t state_nlm_async_data; 00632 #endif /* _USE_NLM */ 00633 void * state_no_data; 00634 } state_async_data; 00635 }; 00636 #endif /* _USE_BLOCKING_LOCKS */ 00637 00638 typedef struct nfs_grace_start 00639 { 00640 int event; 00641 ushort nodeid; 00642 void * ipaddr; 00643 } nfs_grace_start_t; 00644 00645 /* Memory pools */ 00646 00647 extern pool_t *state_owner_pool; /*< Pool for NFSv4 files's open owner */ 00648 extern pool_t *state_nfs4_owner_name_pool; /*< Pool for NFSv4 files's open_owner */ 00649 extern pool_t *state_v4_pool; /*< Pool for NFSv4 files's states */ 00650 00651 struct state_nlm_share_t 00652 { 00653 struct glist_head sns_share_per_file; 00654 struct glist_head sns_share_per_owner; 00655 struct glist_head sns_share_per_client; 00656 state_owner_t * sns_powner; 00657 cache_entry_t * sns_pentry; 00658 exportlist_t * sns_pexport; 00659 int sns_access; 00660 int sns_deny; 00661 }; 00662 00663 #endif /* _SAL_DATA_H */