pnfs.h 5.7 KB
Newer Older
R
Ricardo Labiaga 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 *  pNFS client data structures.
 *
 *  Copyright (c) 2002
 *  The Regents of the University of Michigan
 *  All Rights Reserved
 *
 *  Dean Hildebrand <dhildebz@umich.edu>
 *
 *  Permission is granted to use, copy, create derivative works, and
 *  redistribute this software and such derivative works for any purpose,
 *  so long as the name of the University of Michigan is not used in
 *  any advertising or publicity pertaining to the use or distribution
 *  of this software without specific, written prior authorization. If
 *  the above copyright notice or any other identification of the
 *  University of Michigan is included in any copy of any portion of
 *  this software, then the disclaimer below must also be included.
 *
 *  This software is provided as is, without representation or warranty
 *  of any kind either express or implied, including without limitation
 *  the implied warranties of merchantability, fitness for a particular
 *  purpose, or noninfringement.  The Regents of the University of
 *  Michigan shall not be liable for any damages, including special,
 *  indirect, incidental, or consequential damages, with respect to any
 *  claim arising out of or in connection with the use of the software,
 *  even if it has been or is hereafter advised of the possibility of
 *  such damages.
 */

#ifndef FS_NFS_PNFS_H
#define FS_NFS_PNFS_H

33 34
struct pnfs_layout_segment {
	struct list_head fi_list;
35
	struct pnfs_layout_range range;
36 37 38 39
	struct kref kref;
	struct pnfs_layout_hdr *layout;
};

R
Ricardo Labiaga 已提交
40 41 42 43
#ifdef CONFIG_NFS_V4_1

#define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"

44 45 46
enum {
	NFS_LAYOUT_RO_FAILED = 0,	/* get ro layout failed stop trying */
	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
47
	NFS_LAYOUT_STATEID_SET,		/* have a valid layout stateid */
48 49
};

R
Ricardo Labiaga 已提交
50 51
/* Per-layout driver specific registration structure */
struct pnfs_layoutdriver_type {
52 53 54 55 56 57
	struct list_head pnfs_tblid;
	const u32 id;
	const char *name;
	struct module *owner;
	int (*initialize_mountpoint) (struct nfs_server *);
	int (*uninitialize_mountpoint) (struct nfs_server *);
58 59
	struct pnfs_layout_segment * (*alloc_lseg) (struct pnfs_layout_hdr *layoutid, struct nfs4_layoutget_res *lgr);
	void (*free_lseg) (struct pnfs_layout_segment *lseg);
R
Ricardo Labiaga 已提交
60 61
};

62 63
struct pnfs_layout_hdr {
	unsigned long		refcount;
64 65
	struct list_head	layouts;   /* other client layouts */
	struct list_head	segs;      /* layout segments list */
66 67
	seqlock_t		seqlock;   /* Protects the stateid */
	nfs4_stateid		stateid;
68 69 70 71
	unsigned long		state;
	struct inode		*inode;
};

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
struct pnfs_device {
	struct nfs4_deviceid dev_id;
	unsigned int  layout_type;
	unsigned int  mincount;
	struct page **pages;
	void          *area;
	unsigned int  pgbase;
	unsigned int  pglen;
};

/*
 * Device ID RCU cache. A device ID is unique per client ID and layout type.
 */
#define NFS4_DEVICE_ID_HASH_BITS	5
#define NFS4_DEVICE_ID_HASH_SIZE	(1 << NFS4_DEVICE_ID_HASH_BITS)
#define NFS4_DEVICE_ID_HASH_MASK	(NFS4_DEVICE_ID_HASH_SIZE - 1)

static inline u32
nfs4_deviceid_hash(struct nfs4_deviceid *id)
{
	unsigned char *cptr = (unsigned char *)id->data;
	unsigned int nbytes = NFS4_DEVICEID4_SIZE;
	u32 x = 0;

	while (nbytes--) {
		x *= 37;
		x += *cptr++;
	}
	return x & NFS4_DEVICE_ID_HASH_MASK;
}

struct pnfs_deviceid_node {
	struct hlist_node	de_node;
	struct nfs4_deviceid	de_id;
	atomic_t		de_ref;
};

struct pnfs_deviceid_cache {
	spinlock_t		dc_lock;
	atomic_t		dc_ref;
	void			(*dc_free_callback)(struct pnfs_deviceid_node *);
	struct hlist_head	dc_deviceids[NFS4_DEVICE_ID_HASH_SIZE];
};

extern int pnfs_alloc_init_deviceid_cache(struct nfs_client *,
			void (*free_callback)(struct pnfs_deviceid_node *));
extern void pnfs_put_deviceid_cache(struct nfs_client *);
extern struct pnfs_deviceid_node *pnfs_find_get_deviceid(
				struct pnfs_deviceid_cache *,
				struct nfs4_deviceid *);
extern struct pnfs_deviceid_node *pnfs_add_deviceid(
				struct pnfs_deviceid_cache *,
				struct pnfs_deviceid_node *);
extern void pnfs_put_deviceid(struct pnfs_deviceid_cache *c,
			      struct pnfs_deviceid_node *devid);

128 129 130
extern int pnfs_register_layoutdriver(struct pnfs_layoutdriver_type *);
extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);

131 132 133 134 135 136
/* nfs4proc.c */
extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
				   struct pnfs_device *dev);
extern int nfs4_proc_layoutget(struct nfs4_layoutget *lgp);

/* pnfs.c */
137 138 139
struct pnfs_layout_segment *
pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
		   enum pnfs_iomode access_type);
R
Ricardo Labiaga 已提交
140 141
void set_pnfs_layoutdriver(struct nfs_server *, u32 id);
void unset_pnfs_layoutdriver(struct nfs_server *);
142
int pnfs_layout_process(struct nfs4_layoutget *lgp);
143
void pnfs_destroy_layout(struct nfs_inode *);
144
void pnfs_destroy_all_layouts(struct nfs_client *);
145 146 147
void put_layout_hdr(struct inode *inode);
void pnfs_get_layout_stateid(nfs4_stateid *dst, struct pnfs_layout_hdr *lo,
			     struct nfs4_state *open_state);
148 149 150 151 152 153 154 155 156 157 158 159 160


static inline int lo_fail_bit(u32 iomode)
{
	return iomode == IOMODE_RW ?
			 NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
}

/* Return true if a layout driver is being used for this mountpoint */
static inline int pnfs_enabled_sb(struct nfs_server *nfss)
{
	return nfss->pnfs_curr_ld != NULL;
}
R
Ricardo Labiaga 已提交
161 162 163

#else  /* CONFIG_NFS_V4_1 */

164 165 166 167
static inline void pnfs_destroy_all_layouts(struct nfs_client *clp)
{
}

168 169 170 171 172 173 174 175 176 177 178
static inline void pnfs_destroy_layout(struct nfs_inode *nfsi)
{
}

static inline struct pnfs_layout_segment *
pnfs_update_layout(struct inode *ino, struct nfs_open_context *ctx,
		   enum pnfs_iomode access_type)
{
	return NULL;
}

R
Ricardo Labiaga 已提交
179 180 181 182 183 184 185 186 187 188 189
static inline void set_pnfs_layoutdriver(struct nfs_server *s, u32 id)
{
}

static inline void unset_pnfs_layoutdriver(struct nfs_server *s)
{
}

#endif /* CONFIG_NFS_V4_1 */

#endif /* FS_NFS_PNFS_H */