2005-04-17 02:20:36 +04:00
/*
* Copyright ( c ) 2001 The Regents of the University of Michigan .
* All rights reserved .
*
* Kendrick Smith < kmsmith @ umich . edu >
* Andy Adamson < andros @ umich . edu >
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. Neither the name of the University nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED ` ` AS IS ' ' AND ANY EXPRESS OR IMPLIED
* WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR
* BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING
* NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
*/
# ifndef _NFSD4_STATE_H
# define _NFSD4_STATE_H
2010-06-07 02:37:16 +04:00
# include <linux/sunrpc/svc_xprt.h>
2009-12-03 21:28:59 +03:00
# include <linux/nfsd/nfsfh.h>
2009-12-05 03:36:06 +03:00
# include "nfsfh.h"
2005-04-17 02:20:36 +04:00
typedef struct {
u32 cl_boot ;
u32 cl_id ;
} clientid_t ;
typedef struct {
u32 so_boot ;
u32 so_stateownerid ;
u32 so_fileid ;
} stateid_opaque_t ;
typedef struct {
u32 si_generation ;
stateid_opaque_t si_opaque ;
} stateid_t ;
# define si_boot si_opaque.so_boot
# define si_stateownerid si_opaque.so_stateownerid
# define si_fileid si_opaque.so_fileid
2009-10-19 14:04:53 +04:00
# define STATEID_FMT "(%08x / %08x / %08x / %08x)"
# define STATEID_VAL(s) \
( s ) - > si_boot , \
( s ) - > si_stateownerid , \
( s ) - > si_fileid , \
( s ) - > si_generation
2010-02-18 19:27:24 +03:00
struct nfsd4_callback {
2010-06-01 02:21:37 +04:00
void * cb_op ;
struct nfs4_client * cb_clp ;
2011-01-11 00:44:41 +03:00
struct list_head cb_per_client ;
2010-06-01 02:21:37 +04:00
u32 cb_minorversion ;
2010-05-17 00:47:08 +04:00
struct rpc_message cb_msg ;
const struct rpc_call_ops * cb_ops ;
2010-03-03 22:52:55 +03:00
struct work_struct cb_work ;
2011-01-11 00:44:41 +03:00
bool cb_done ;
2010-02-18 19:27:24 +03:00
} ;
2005-04-17 02:20:36 +04:00
struct nfs4_delegation {
2005-06-24 09:04:17 +04:00
struct list_head dl_perfile ;
struct list_head dl_perclnt ;
2005-04-17 02:20:36 +04:00
struct list_head dl_recall_lru ; /* delegation recalled */
atomic_t dl_count ; /* ref count */
struct nfs4_client * dl_client ;
struct nfs4_file * dl_file ;
u32 dl_type ;
time_t dl_time ;
2009-05-02 03:50:00 +04:00
/* For recall: */
stateid_t dl_stateid ;
struct knfsd_fh dl_fh ;
2009-05-02 04:11:12 +04:00
int dl_retries ;
2010-02-18 19:27:24 +03:00
struct nfsd4_callback dl_recall ;
2005-04-17 02:20:36 +04:00
} ;
/* client delegation callback info */
2009-04-30 03:09:19 +04:00
struct nfs4_cb_conn {
2005-04-17 02:20:36 +04:00
/* SETCLIENTID info */
2009-08-14 20:57:57 +04:00
struct sockaddr_storage cb_addr ;
2010-12-15 08:09:01 +03:00
struct sockaddr_storage cb_saddr ;
2009-08-14 20:57:57 +04:00
size_t cb_addrlen ;
2010-10-20 01:31:50 +04:00
u32 cb_prog ; /* used only in 4.0 case;
per - session otherwise */
2009-06-16 05:20:53 +04:00
u32 cb_ident ; /* minorversion 0 only */
2010-03-08 20:37:27 +03:00
struct svc_xprt * cb_xprt ; /* minorversion 1 only */
2005-04-17 02:20:36 +04:00
} ;
2009-08-28 16:45:01 +04:00
/* Maximum number of slots per session. 160 is useful for long haul TCP */
# define NFSD_MAX_SLOTS_PER_SESSION 160
2009-04-03 09:28:28 +04:00
/* Maximum number of operations per session compound */
# define NFSD_MAX_OPS_PER_COMPOUND 16
2009-08-28 16:45:04 +04:00
/* Maximum session per slot cache size */
# define NFSD_SLOT_CACHE_SIZE 1024
2009-08-28 16:45:01 +04:00
/* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */
# define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32
# define NFSD_MAX_MEM_PER_SESSION \
( NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE )
2009-04-03 09:28:15 +04:00
2009-04-03 09:27:43 +04:00
struct nfsd4_slot {
2009-08-28 16:45:04 +04:00
bool sl_inuse ;
bool sl_cachethis ;
u16 sl_opcnt ;
u32 sl_seqid ;
__be32 sl_status ;
u32 sl_datalen ;
char sl_data [ ] ;
2009-04-03 09:27:43 +04:00
} ;
2009-06-16 05:19:13 +04:00
struct nfsd4_channel_attrs {
u32 headerpadsz ;
u32 maxreq_sz ;
u32 maxresp_sz ;
u32 maxresp_cached ;
u32 maxops ;
u32 maxreqs ;
u32 nr_rdma_attrs ;
u32 rdma_attrs ;
} ;
2009-07-24 03:02:16 +04:00
struct nfsd4_create_session {
clientid_t clientid ;
struct nfs4_sessionid sessionid ;
u32 seqid ;
u32 flags ;
struct nfsd4_channel_attrs fore_channel ;
struct nfsd4_channel_attrs back_channel ;
u32 callback_prog ;
u32 uid ;
u32 gid ;
} ;
2010-10-05 07:12:59 +04:00
struct nfsd4_bind_conn_to_session {
struct nfs4_sessionid sessionid ;
u32 dir ;
} ;
2009-07-24 03:02:16 +04:00
/* The single slot clientid cache structure */
struct nfsd4_clid_slot {
u32 sl_seqid ;
__be32 sl_status ;
struct nfsd4_create_session sl_cr_ses ;
} ;
2010-06-07 02:12:14 +04:00
struct nfsd4_conn {
struct list_head cn_persession ;
struct svc_xprt * cn_xprt ;
2010-06-07 02:37:16 +04:00
struct svc_xpt_user cn_xpt_user ;
struct nfsd4_session * cn_session ;
2010-06-07 02:12:14 +04:00
/* CDFC4_FORE, CDFC4_BACK: */
unsigned char cn_flags ;
} ;
2009-04-03 09:27:43 +04:00
struct nfsd4_session {
struct kref se_ref ;
struct list_head se_hash ; /* hash by sessionid */
struct list_head se_perclnt ;
u32 se_flags ;
2010-05-12 01:13:41 +04:00
struct nfs4_client * se_client ;
2009-04-03 09:27:43 +04:00
struct nfs4_sessionid se_sessionid ;
2009-06-16 05:19:13 +04:00
struct nfsd4_channel_attrs se_fchannel ;
struct nfsd4_channel_attrs se_bchannel ;
2010-06-07 02:12:14 +04:00
struct list_head se_conns ;
2010-10-20 01:31:50 +04:00
u32 se_cb_prog ;
2010-06-15 03:01:57 +04:00
u32 se_cb_seq_nr ;
2009-08-28 16:45:04 +04:00
struct nfsd4_slot * se_slots [ ] ; /* forward channel slots */
2009-04-03 09:27:43 +04:00
} ;
static inline void
nfsd4_put_session ( struct nfsd4_session * ses )
{
extern void free_session ( struct kref * kref ) ;
kref_put ( & ses - > se_ref , free_session ) ;
}
static inline void
nfsd4_get_session ( struct nfsd4_session * ses )
{
kref_get ( & ses - > se_ref ) ;
}
2009-04-03 09:27:52 +04:00
/* formatted contents of nfs4_sessionid */
struct nfsd4_sessionid {
clientid_t clientid ;
u32 sequence ;
u32 reserved ;
} ;
2005-06-24 09:03:52 +04:00
# define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */
2005-04-17 02:20:36 +04:00
/*
* struct nfs4_client - one per client . Clientids live here .
* o Each nfs4_client is hashed by clientid .
*
* o Each nfs4_clients is also hashed by name
* ( the opaque quantity initially sent by the client to identify itself ) .
*
* o cl_perclient list is used to ensure no dangling stateowner references
* when we expire the nfs4_client
*/
struct nfs4_client {
struct list_head cl_idhash ; /* hash by cl_clientid.id */
struct list_head cl_strhash ; /* hash by cl_name */
2005-06-24 09:04:17 +04:00
struct list_head cl_openowners ;
struct list_head cl_delegations ;
2005-04-17 02:20:36 +04:00
struct list_head cl_lru ; /* tail queue */
struct xdr_netobj cl_name ; /* id generated by client */
2005-06-24 09:03:52 +04:00
char cl_recdir [ HEXDIR_LEN ] ; /* recovery dir */
2005-04-17 02:20:36 +04:00
nfs4_verifier cl_verifier ; /* generated by client */
time_t cl_time ; /* time of last lease renewal */
2009-08-14 20:57:56 +04:00
struct sockaddr_storage cl_addr ; /* client ipaddress */
2008-12-24 00:19:00 +03:00
u32 cl_flavor ; /* setclientid pseudoflavor */
2008-12-24 00:17:15 +03:00
char * cl_principal ; /* setclientid principal name */
2005-04-17 02:20:36 +04:00
struct svc_cred cl_cred ; /* setclientid principal */
clientid_t cl_clientid ; /* generated by server */
nfs4_verifier cl_confirm ; /* generated by server */
2005-06-24 09:04:30 +04:00
u32 cl_firststate ; /* recovery dir creation */
2010-10-20 03:36:51 +04:00
u32 cl_minorversion ;
2009-04-03 09:27:46 +04:00
2010-03-08 20:37:27 +03:00
/* for v4.0 and v4.1 callbacks: */
struct nfs4_cb_conn cl_cb_conn ;
2010-06-05 04:04:45 +04:00
# define NFSD4_CLIENT_CB_UPDATE 1
# define NFSD4_CLIENT_KILL 2
unsigned long cl_cb_flags ;
2010-03-08 20:37:27 +03:00
struct rpc_clnt * cl_cb_client ;
2010-06-05 04:04:45 +04:00
u32 cl_cb_ident ;
2010-05-01 02:51:44 +04:00
# define NFSD4_CB_UP 0
# define NFSD4_CB_UNKNOWN 1
# define NFSD4_CB_DOWN 2
int cl_cb_state ;
2010-05-27 01:52:14 +04:00
struct nfsd4_callback cl_cb_null ;
2010-06-15 06:26:31 +04:00
struct nfsd4_session * cl_cb_session ;
2011-01-11 00:44:41 +03:00
struct list_head cl_callbacks ; /* list of in-progress callbacks */
2010-03-08 20:37:27 +03:00
2010-06-05 04:04:45 +04:00
/* for all client information that callback code might need: */
spinlock_t cl_lock ;
2009-04-03 09:27:46 +04:00
/* for nfs41 */
struct list_head cl_sessions ;
2009-07-24 03:02:16 +04:00
struct nfsd4_clid_slot cl_cs_slot ; /* create_session slot */
2009-04-03 09:28:01 +04:00
u32 cl_exchange_flags ;
2010-05-12 01:13:29 +04:00
/* number of rpc's in progress over an associated session: */
atomic_t cl_refcount ;
2009-09-10 13:25:59 +04:00
/* for nfs41 callbacks */
2009-09-10 13:26:25 +04:00
/* We currently support a single back channel with a single slot */
unsigned long cl_cb_slot_busy ;
struct rpc_wait_queue cl_cb_waitq ; /* backchannel callers may */
/* wait here for slots */
2005-04-17 02:20:36 +04:00
} ;
2010-05-12 01:13:41 +04:00
static inline void
mark_client_expired ( struct nfs4_client * clp )
{
clp - > cl_time = 0 ;
}
static inline bool
is_client_expired ( struct nfs4_client * clp )
{
return clp - > cl_time = = 0 ;
}
2005-04-17 02:20:36 +04:00
/* struct nfs4_client_reset
* one per old client . Populates reset_str_hashtbl . Filled from conf_id_hashtbl
* upon lease reset , or from upcall to state_daemon ( to read in state
* from non - volitile storage ) upon reboot .
*/
struct nfs4_client_reclaim {
struct list_head cr_strhash ; /* hash by cr_name */
2005-06-24 09:03:52 +04:00
char cr_recdir [ HEXDIR_LEN ] ; /* recover dir */
2005-04-17 02:20:36 +04:00
} ;
static inline void
update_stateid ( stateid_t * stateid )
{
stateid - > si_generation + + ;
}
/* A reasonable value for REPLAY_ISIZE was estimated as follows:
* The OPEN response , typically the largest , requires
* 4 ( status ) + 8 ( stateid ) + 20 ( changeinfo ) + 4 ( rflags ) + 8 ( verifier ) +
* 4 ( deleg . type ) + 8 ( deleg . stateid ) + 4 ( deleg . recall flag ) +
* 20 ( deleg . space limit ) + ~ 32 ( deleg . ace ) = 112 bytes
*/
# define NFSD4_REPLAY_ISIZE 112
/*
* Replay buffer , where the result of the last seqid - mutating operation
* is cached .
*/
struct nfs4_replay {
2006-10-20 10:28:59 +04:00
__be32 rp_status ;
2005-04-17 02:20:36 +04:00
unsigned int rp_buflen ;
char * rp_buf ;
unsigned intrp_allocated ;
2009-02-03 01:23:10 +03:00
struct knfsd_fh rp_openfh ;
2005-04-17 02:20:36 +04:00
char rp_ibuf [ NFSD4_REPLAY_ISIZE ] ;
} ;
/*
* nfs4_stateowner can either be an open_owner , or a lock_owner
*
* so_idhash : stateid_hashtbl [ ] for open owner , lockstateid_hashtbl [ ]
* for lock_owner
* so_strhash : ownerstr_hashtbl [ ] for open_owner , lock_ownerstr_hashtbl [ ]
* for lock_owner
* so_perclient : nfs4_client - > cl_perclient entry - used when nfs4_client
* struct is reaped .
* so_perfilestate : heads the list of nfs4_stateid ( either open or lock )
* and is used to ensure no dangling nfs4_stateid references when we
* release a stateowner .
* so_perlockowner : ( open ) nfs4_stateid - > st_perlockowner entry - used when
* close is called to reap associated byte - range locks
* so_close_lru : ( open ) stateowner is placed on this list instead of being
* reaped ( when so_perfilestate is empty ) to hold the last close replay .
* reaped by laundramat thread after lease period .
*/
struct nfs4_stateowner {
struct kref so_ref ;
struct list_head so_idhash ; /* hash by so_id */
struct list_head so_strhash ; /* hash by op_name */
2005-06-24 09:04:17 +04:00
struct list_head so_perclient ;
struct list_head so_stateids ;
struct list_head so_perstateid ; /* for lockowners only */
2005-04-17 02:20:36 +04:00
struct list_head so_close_lru ; /* tail queue */
time_t so_time ; /* time of placement on so_close_lru */
int so_is_open_owner ; /* 1=openowner,0=lockowner */
u32 so_id ;
struct nfs4_client * so_client ;
2005-07-08 04:59:20 +04:00
/* after increment in ENCODE_SEQID_OP_TAIL, represents the next
* sequence id expected from the client : */
u32 so_seqid ;
2005-04-17 02:20:36 +04:00
struct xdr_netobj so_owner ; /* open owner name */
int so_confirmed ; /* successful OPEN_CONFIRM? */
struct nfs4_replay so_replay ;
} ;
/*
* nfs4_file : a file opened by some number of ( open ) nfs4_stateowners .
* o fi_perfile list is used to search for conflicting
* share_acces , share_deny on the file .
*/
struct nfs4_file {
2009-02-23 01:51:34 +03:00
atomic_t fi_ref ;
2005-04-17 02:20:36 +04:00
struct list_head fi_hash ; /* hash by "struct inode *" */
2005-06-24 09:03:08 +04:00
struct list_head fi_stateids ;
struct list_head fi_delegations ;
2010-07-08 19:02:09 +04:00
/* One each for O_RDONLY, O_WRONLY, O_RDWR: */
struct file * fi_fds [ 3 ] ;
/* One each for O_RDONLY, O_WRONLY: */
atomic_t fi_access [ 2 ] ;
/*
* Each open stateid contributes 1 to either fi_readers or
* fi_writers , or both , depending on the open mode . A
* delegation also takes an fi_readers reference . Lock
* stateid ' s take none .
*/
atomic_t fi_readers ;
atomic_t fi_writers ;
2011-02-01 03:20:39 +03:00
struct file * fi_deleg_file ;
struct file_lock * fi_lease ;
atomic_t fi_delegees ;
2005-04-17 02:20:36 +04:00
struct inode * fi_inode ;
u32 fi_id ; /* used with stateowner->so_id
* for stateid_hashtbl hash */
2007-07-17 15:04:40 +04:00
bool fi_had_conflict ;
2005-04-17 02:20:36 +04:00
} ;
2010-07-08 19:02:09 +04:00
/* XXX: for first cut may fall back on returning file that doesn't work
* at all ? */
static inline struct file * find_writeable_file ( struct nfs4_file * f )
{
2010-08-21 02:09:31 +04:00
if ( f - > fi_fds [ O_WRONLY ] )
return f - > fi_fds [ O_WRONLY ] ;
return f - > fi_fds [ O_RDWR ] ;
2010-07-08 19:02:09 +04:00
}
static inline struct file * find_readable_file ( struct nfs4_file * f )
{
2010-08-21 02:09:31 +04:00
if ( f - > fi_fds [ O_RDONLY ] )
return f - > fi_fds [ O_RDONLY ] ;
return f - > fi_fds [ O_RDWR ] ;
2010-07-08 19:02:09 +04:00
}
static inline struct file * find_any_file ( struct nfs4_file * f )
{
if ( f - > fi_fds [ O_RDWR ] )
return f - > fi_fds [ O_RDWR ] ;
2010-08-21 02:06:26 +04:00
else if ( f - > fi_fds [ O_WRONLY ] )
2010-07-08 19:02:09 +04:00
return f - > fi_fds [ O_WRONLY ] ;
else
return f - > fi_fds [ O_RDONLY ] ;
}
2005-04-17 02:20:36 +04:00
/*
* nfs4_stateid can either be an open stateid or ( eventually ) a lock stateid
*
* ( open ) nfs4_stateid : one per ( open ) nfs4_stateowner , nfs4_file
*
* st_hash : stateid_hashtbl [ ] entry or lockstateid_hashtbl entry
* st_perfile : file_hashtbl [ ] entry .
* st_perfile_state : nfs4_stateowner - > so_perfilestate
* st_perlockowner : ( open stateid ) list of lock nfs4_stateowners
* st_access_bmap : used only for open stateid
* st_deny_bmap : used only for open stateid
2005-07-08 04:59:27 +04:00
* st_openstp : open stateid lock stateid was derived from
*
* XXX : open stateids and lock stateids have diverged sufficiently that
* we should consider defining separate structs for the two cases .
2005-04-17 02:20:36 +04:00
*/
struct nfs4_stateid {
struct list_head st_hash ;
struct list_head st_perfile ;
2005-06-24 09:04:17 +04:00
struct list_head st_perstateowner ;
struct list_head st_lockowners ;
2005-04-17 02:20:36 +04:00
struct nfs4_stateowner * st_stateowner ;
struct nfs4_file * st_file ;
stateid_t st_stateid ;
unsigned long st_access_bmap ;
unsigned long st_deny_bmap ;
2005-07-08 04:59:27 +04:00
struct nfs4_stateid * st_openstp ;
2005-04-17 02:20:36 +04:00
} ;
/* flags for preprocess_seqid_op() */
2009-04-03 09:28:45 +04:00
# define HAS_SESSION 0x00000001
2005-04-17 02:20:36 +04:00
# define CONFIRM 0x00000002
# define OPEN_STATE 0x00000004
# define LOCK_STATE 0x00000008
# define RD_STATE 0x00000010
# define WR_STATE 0x00000020
# define CLOSE_STATE 0x00000040
# define seqid_mutating_err(err) \
( ( ( err ) ! = nfserr_stale_clientid ) & & \
( ( err ) ! = nfserr_bad_seqid ) & & \
( ( err ) ! = nfserr_stale_stateid ) & & \
( ( err ) ! = nfserr_bad_stateid ) )
2009-04-03 09:28:41 +04:00
struct nfsd4_compound_state ;
extern __be32 nfs4_preprocess_stateid_op ( struct nfsd4_compound_state * cstate ,
2005-04-17 02:20:36 +04:00
stateid_t * stateid , int flags , struct file * * filp ) ;
extern void nfs4_lock_state ( void ) ;
extern void nfs4_unlock_state ( void ) ;
extern int nfs4_in_grace ( void ) ;
2006-10-20 10:28:59 +04:00
extern __be32 nfs4_check_open_reclaim ( clientid_t * clid ) ;
2005-04-17 02:20:36 +04:00
extern void nfs4_free_stateowner ( struct kref * kref ) ;
2009-09-16 02:07:35 +04:00
extern int set_callback_cred ( void ) ;
2010-10-20 01:56:52 +04:00
extern void nfsd4_probe_callback ( struct nfs4_client * clp ) ;
2010-12-09 23:52:19 +03:00
extern void nfsd4_probe_callback_sync ( struct nfs4_client * clp ) ;
2010-10-20 01:56:52 +04:00
extern void nfsd4_change_callback ( struct nfs4_client * clp , struct nfs4_cb_conn * ) ;
2010-03-03 22:52:55 +03:00
extern void nfsd4_do_callback_rpc ( struct work_struct * ) ;
2005-04-17 02:20:36 +04:00
extern void nfsd4_cb_recall ( struct nfs4_delegation * dp ) ;
2010-03-03 22:52:55 +03:00
extern int nfsd4_create_callback_queue ( void ) ;
extern void nfsd4_destroy_callback_queue ( void ) ;
2010-06-05 04:04:45 +04:00
extern void nfsd4_shutdown_callback ( struct nfs4_client * ) ;
2005-04-17 02:20:36 +04:00
extern void nfs4_put_delegation ( struct nfs4_delegation * dp ) ;
2006-10-20 10:28:59 +04:00
extern __be32 nfs4_make_rec_clidname ( char * clidname , struct xdr_netobj * clname ) ;
2005-06-24 09:04:25 +04:00
extern void nfsd4_init_recdir ( char * recdir_name ) ;
extern int nfsd4_recdir_load ( void ) ;
extern void nfsd4_shutdown_recdir ( void ) ;
extern int nfs4_client_to_reclaim ( const char * name ) ;
2009-04-03 09:28:05 +04:00
extern int nfs4_has_reclaimed_state ( const char * name , bool use_exchange_id ) ;
2005-06-24 09:04:30 +04:00
extern void nfsd4_recdir_purge_old ( void ) ;
extern int nfsd4_create_clid_dir ( struct nfs4_client * clp ) ;
extern void nfsd4_remove_clid_dir ( struct nfs4_client * clp ) ;
2010-05-12 01:13:54 +04:00
extern void release_session_client ( struct nfsd4_session * ) ;
2005-04-17 02:20:36 +04:00
static inline void
nfs4_put_stateowner ( struct nfs4_stateowner * so )
{
kref_put ( & so - > so_ref , nfs4_free_stateowner ) ;
}
static inline void
nfs4_get_stateowner ( struct nfs4_stateowner * so )
{
kref_get ( & so - > so_ref ) ;
}
# endif /* NFSD4_STATE_H */