linux/fs/nfs/pnfs.h
<<
>>
Prefs
   1/*
   2 *  pNFS client data structures.
   3 *
   4 *  Copyright (c) 2002
   5 *  The Regents of the University of Michigan
   6 *  All Rights Reserved
   7 *
   8 *  Dean Hildebrand <dhildebz@umich.edu>
   9 *
  10 *  Permission is granted to use, copy, create derivative works, and
  11 *  redistribute this software and such derivative works for any purpose,
  12 *  so long as the name of the University of Michigan is not used in
  13 *  any advertising or publicity pertaining to the use or distribution
  14 *  of this software without specific, written prior authorization. If
  15 *  the above copyright notice or any other identification of the
  16 *  University of Michigan is included in any copy of any portion of
  17 *  this software, then the disclaimer below must also be included.
  18 *
  19 *  This software is provided as is, without representation or warranty
  20 *  of any kind either express or implied, including without limitation
  21 *  the implied warranties of merchantability, fitness for a particular
  22 *  purpose, or noninfringement.  The Regents of the University of
  23 *  Michigan shall not be liable for any damages, including special,
  24 *  indirect, incidental, or consequential damages, with respect to any
  25 *  claim arising out of or in connection with the use of the software,
  26 *  even if it has been or is hereafter advised of the possibility of
  27 *  such damages.
  28 */
  29
  30#ifndef FS_NFS_PNFS_H
  31#define FS_NFS_PNFS_H
  32
  33enum {
  34        NFS_LSEG_VALID = 0,     /* cleared when lseg is recalled/returned */
  35        NFS_LSEG_ROC,           /* roc bit received from server */
  36};
  37
  38struct pnfs_layout_segment {
  39        struct list_head pls_list;
  40        struct pnfs_layout_range pls_range;
  41        atomic_t pls_refcount;
  42        unsigned long pls_flags;
  43        struct pnfs_layout_hdr *pls_layout;
  44};
  45
  46#ifdef CONFIG_NFS_V4_1
  47
  48#define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
  49
  50enum {
  51        NFS_LAYOUT_RO_FAILED = 0,       /* get ro layout failed stop trying */
  52        NFS_LAYOUT_RW_FAILED,           /* get rw layout failed stop trying */
  53        NFS_LAYOUT_BULK_RECALL,         /* bulk recall affecting layout */
  54        NFS_LAYOUT_ROC,                 /* some lseg had roc bit set */
  55        NFS_LAYOUT_DESTROYED,           /* no new use of layout allowed */
  56};
  57
  58/* Per-layout driver specific registration structure */
  59struct pnfs_layoutdriver_type {
  60        struct list_head pnfs_tblid;
  61        const u32 id;
  62        const char *name;
  63        struct module *owner;
  64        int (*set_layoutdriver) (struct nfs_server *);
  65        int (*clear_layoutdriver) (struct nfs_server *);
  66        struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr);
  67        void (*free_lseg) (struct pnfs_layout_segment *lseg);
  68};
  69
  70struct pnfs_layout_hdr {
  71        atomic_t                plh_refcount;
  72        struct list_head        plh_layouts;   /* other client layouts */
  73        struct list_head        plh_bulk_recall; /* clnt list of bulk recalls */
  74        struct list_head        plh_segs;      /* layout segments list */
  75        nfs4_stateid            plh_stateid;
  76        atomic_t                plh_outstanding; /* number of RPCs out */
  77        unsigned long           plh_block_lgets; /* block LAYOUTGET if >0 */
  78        u32                     plh_barrier; /* ignore lower seqids */
  79        unsigned long           plh_flags;
  80        struct inode            *plh_inode;
  81};
  82
  83struct pnfs_device {
  84        struct nfs4_deviceid dev_id;
  85        unsigned int  layout_type;
  86        unsigned int  mincount;
  87        struct page **pages;
  88        void          *area;
  89        unsigned int  pgbase;
  90        unsigned int  pglen;
  91};
  92
  93/*
  94 * Device ID RCU cache. A device ID is unique per client ID and layout type.
  95 */
  96#define NFS4_DEVICE_ID_HASH_BITS        5
  97#define NFS4_DEVICE_ID_HASH_SIZE        (1 << NFS4_DEVICE_ID_HASH_BITS)
  98#define NFS4_DEVICE_ID_HASH_MASK        (NFS4_DEVICE_ID_HASH_SIZE - 1)
  99
 100static inline u32
 101nfs4_deviceid_hash(struct nfs4_deviceid *id)
 102{
 103        unsigned char *cptr = (unsigned char *)id->data;
 104        unsigned int nbytes = NFS4_DEVICEID4_SIZE;
 105        u32 x = 0;
 106
 107        while (nbytes--) {
 108                x *= 37;
 109                x += *cptr++;
 110        }
 111        return x & NFS4_DEVICE_ID_HASH_MASK;
 112}
 113
 114struct pnfs_deviceid_node {
 115        struct hlist_node       de_node;
 116        struct nfs4_deviceid    de_id;
 117        atomic_t                de_ref;
 118};
 119
 120struct pnfs_deviceid_cache {
 121        spinlock_t              dc_lock;
 122        atomic_t                dc_ref;
 123        void                    (*dc_free_callback)(struct pnfs_deviceid_node *);
 124        struct hlist_head       dc_deviceids[NFS4_DEVICE_ID_HASH_SIZE];
 125};
 126
 127extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *,
 128                        void (*free_callback)(struct pnfs_deviceid_node *));
 129extern void pnfs_put_deviceid_cache(struct nfs_client *);
 130extern struct pnfs_deviceid_node *pnfs_find_get_deviceid(
 131                                struct pnfs_deviceid_cache *,
 132                                struct nfs4_deviceid *);
 133extern struct pnfs_deviceid_node *pnfs_add_deviceid(
 134                                struct pnfs_deviceid_cache *,
 135                                struct pnfs_deviceid_node *);
 136extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c,
 137                              struct pnfs_deviceid_node *devid);
 138
 139extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
 140extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
 141
 142/* nfs4proc.c */
 143extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
 144                                   struct pnfs_device *dev);
 145extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);
 146
 147/* pnfs.c */
 148void get_layout_hdr(struct pnfs_layout_hdr *lo);
 149struct pnfs_layout_segment *
 150pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
 151                   enum pnfs_iomode access_type);
 152void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
 153void unset_pnfs_layoutdriver(struct nfs_server *);
 154int pnfs_layout_process(struct nfs4_layoutget *lgp);
 155void pnfs_free_lseg_list(struct list_head *tmp_list);
 156void pnfs_destroy_layout(struct nfs_inode *);
 157void pnfs_destroy_all_layouts(struct nfs_client *);
 158void put_layout_hdr(struct pnfs_layout_hdr *lo);
 159void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
 160                             const nfs4_stateid *new,
 161                             bool update_barrier);
 162int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
 163                                  struct pnfs_layout_hdr *lo,
 164                                  struct nfs4_state *open_state);
 165int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
 166                                struct list_head *tmp_list,
 167                                u32 iomode);
 168bool pnfs_roc(struct inode *ino);
 169void pnfs_roc_release(struct inode *ino);
 170void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
 171bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
 172
 173
 174static inline int lo_fail_bit(u32 iomode)
 175{
 176        return iomode == IOMODE_RW ?
 177                         NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
 178}
 179
 180/* Return true if a layout driver is being used for this mountpoint */
 181static inline int pnfs_enabled_sb(struct nfs_server *nfss)
 182{
 183        return nfss->pnfs_curr_ld != NULL;
 184}
 185
 186#else  /* CONFIG_NFS_V4_1 */
 187
 188static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
 189{
 190}
 191
 192static inline void pnfs_destroy_layout(struct nfs_inode *nfsi)
 193{
 194}
 195
 196static inline struct pnfs_layout_segment *
 197pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
 198                   enum pnfs_iomode access_type)
 199{
 200        return NULL;
 201}
 202
 203static inline bool
 204pnfs_roc(struct inode *ino)
 205{
 206        return false;
 207}
 208
 209static inline void
 210pnfs_roc_release(struct inode *ino)
 211{
 212}
 213
 214static inline void
 215pnfs_roc_set_barrier(struct inode *ino, u32 barrier)
 216{
 217}
 218
 219static inline bool
 220pnfs_roc_drain(struct inode *ino, u32 *barrier)
 221{
 222        return false;
 223}
 224
 225static inline void set_pnfs_layoutdriver(struct nfs_server *s, u32 id)
 226{
 227}
 228
 229static inline void unset_pnfs_layoutdriver(struct nfs_server *s)
 230{
 231}
 232
 233#endif /* CONFIG_NFS_V4_1 */
 234
 235#endif /* FS_NFS_PNFS_H */
 236