libceph.h 8.7 KB
Newer Older
1 2 3
#ifndef _FS_CEPH_LIBCEPH_H
#define _FS_CEPH_LIBCEPH_H

4
#include <linux/ceph/ceph_debug.h>
5 6 7 8 9

#include <asm/unaligned.h>
#include <linux/backing-dev.h>
#include <linux/completion.h>
#include <linux/exportfs.h>
10
#include <linux/bug.h>
11 12 13 14 15 16 17
#include <linux/fs.h>
#include <linux/mempool.h>
#include <linux/pagemap.h>
#include <linux/wait.h>
#include <linux/writeback.h>
#include <linux/slab.h>

18 19 20 21 22 23
#include <linux/ceph/types.h>
#include <linux/ceph/messenger.h>
#include <linux/ceph/msgpool.h>
#include <linux/ceph/mon_client.h>
#include <linux/ceph/osd_client.h>
#include <linux/ceph/ceph_fs.h>
24
#include <linux/ceph/string_table.h>
25 26 27 28 29 30 31 32

/*
 * mount options
 */
#define CEPH_OPT_FSID             (1<<0)
#define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
#define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
#define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes */
33
#define CEPH_OPT_NOMSGAUTH	  (1<<4) /* don't require msg signing feat */
C
Chaitanya Huilgol 已提交
34
#define CEPH_OPT_TCP_NODELAY	  (1<<5) /* TCP_NODELAY on TCP sockets */
35
#define CEPH_OPT_NOMSGSIGN	  (1<<6) /* don't sign msgs */
36

C
Chaitanya Huilgol 已提交
37
#define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
38 39 40 41 42 43 44 45 46 47

#define ceph_set_opt(client, opt) \
	(client)->options->flags |= CEPH_OPT_##opt;
#define ceph_test_opt(client, opt) \
	(!!((client)->options->flags & CEPH_OPT_##opt))

struct ceph_options {
	int flags;
	struct ceph_fsid fsid;
	struct ceph_entity_addr my_addr;
48 49 50
	unsigned long mount_timeout;		/* jiffies */
	unsigned long osd_idle_ttl;		/* jiffies */
	unsigned long osd_keepalive_timeout;	/* jiffies */
51
	unsigned long osd_request_timeout;	/* jiffies */
52 53 54 55 56 57 58 59 60 61 62

	/*
	 * any type that can't be simply compared or doesn't need need
	 * to be compared should go beyond this point,
	 * ceph_compare_options() should be updated accordingly
	 */

	struct ceph_entity_addr *mon_addr; /* should be the first
					      pointer type of args */
	int num_mon;
	char *name;
63
	struct ceph_crypto_key *key;
64 65 66 67 68
};

/*
 * defaults
 */
69 70 71
#define CEPH_MOUNT_TIMEOUT_DEFAULT	msecs_to_jiffies(60 * 1000)
#define CEPH_OSD_KEEPALIVE_DEFAULT	msecs_to_jiffies(5 * 1000)
#define CEPH_OSD_IDLE_TTL_DEFAULT	msecs_to_jiffies(60 * 1000)
72
#define CEPH_OSD_REQUEST_TIMEOUT_DEFAULT 0  /* no timeout */
I
Ilya Dryomov 已提交
73

74
#define CEPH_MONC_HUNT_INTERVAL		msecs_to_jiffies(3 * 1000)
I
Ilya Dryomov 已提交
75 76
#define CEPH_MONC_PING_INTERVAL		msecs_to_jiffies(10 * 1000)
#define CEPH_MONC_PING_TIMEOUT		msecs_to_jiffies(30 * 1000)
77 78
#define CEPH_MONC_HUNT_BACKOFF		2
#define CEPH_MONC_HUNT_MAX_MULT		10
79 80

#define CEPH_MSG_MAX_FRONT_LEN	(16*1024*1024)
81
#define CEPH_MSG_MAX_MIDDLE_LEN	(16*1024*1024)
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#define CEPH_MSG_MAX_DATA_LEN	(16*1024*1024)

#define CEPH_AUTH_NAME_DEFAULT   "guest"

/*
 * Delay telling the MDS we no longer want caps, in case we reopen
 * the file.  Delay a minimum amount of time, even if we send a cap
 * message for some other reason.  Otherwise, take the oppotunity to
 * update the mds to avoid sending another message later.
 */
#define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT      5  /* cap release delay */
#define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT     60  /* cap release delay */

#define CEPH_CAP_RELEASE_SAFETY_DEFAULT        (CEPH_CAPS_PER_RELEASE * 4)

/* mount state */
enum {
	CEPH_MOUNT_MOUNTING,
	CEPH_MOUNT_MOUNTED,
	CEPH_MOUNT_UNMOUNTING,
	CEPH_MOUNT_UNMOUNTED,
	CEPH_MOUNT_SHUTDOWN,
};

106 107 108 109 110
static inline unsigned long ceph_timeout_jiffies(unsigned long timeout)
{
	return timeout ?: MAX_SCHEDULE_TIMEOUT;
}

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
struct ceph_mds_client;

/*
 * per client state
 *
 * possibly shared by multiple mount points, if they are
 * mounting the same ceph filesystem/cluster.
 */
struct ceph_client {
	struct ceph_fsid fsid;
	bool have_fsid;

	void *private;

	struct ceph_options *options;

	struct mutex mount_mutex;      /* serialize mount attempts */
	wait_queue_head_t auth_wq;
	int auth_err;

	int (*extra_mon_dispatch)(struct ceph_client *, struct ceph_msg *);

133 134
	u64 supported_features;
	u64 required_features;
135

136
	struct ceph_messenger msgr;   /* messenger instance */
137 138 139 140 141 142 143
	struct ceph_mon_client monc;
	struct ceph_osd_client osdc;

#ifdef CONFIG_DEBUG_FS
	struct dentry *debugfs_dir;
	struct dentry *debugfs_monmap;
	struct dentry *debugfs_osdmap;
144
	struct dentry *debugfs_options;
145 146 147
#endif
};

148
#define from_msgr(ms)	container_of(ms, struct ceph_client, msgr)
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165


/*
 * snapshots
 */

/*
 * A "snap context" is the set of existing snapshots when we
 * write data.  It is used by the OSD to guide its COW behavior.
 *
 * The ceph_snap_context is refcounted, and attached to each dirty
 * page, indicating which context the dirty data belonged when it was
 * dirtied.
 */
struct ceph_snap_context {
	atomic_t nref;
	u64 seq;
166
	u32 num_snaps;
167 168 169
	u64 snaps[];
};

170 171 172 173 174
extern struct ceph_snap_context *ceph_create_snap_context(u32 snap_count,
					gfp_t gfp_flags);
extern struct ceph_snap_context *ceph_get_snap_context(
					struct ceph_snap_context *sc);
extern void ceph_put_snap_context(struct ceph_snap_context *sc);
175 176 177 178 179 180 181

/*
 * calculate the number of pages a given length and offset map onto,
 * if we align the data.
 */
static inline int calc_pages_for(u64 off, u64 len)
{
182 183
	return ((off+len+PAGE_SIZE-1) >> PAGE_SHIFT) -
		(off >> PAGE_SHIFT);
184 185
}

I
Ilya Dryomov 已提交
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
/*
 * These are not meant to be generic - an integer key is assumed.
 */
#define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld)		\
static void insert_##name(struct rb_root *root, type *t)		\
{									\
	struct rb_node **n = &root->rb_node;				\
	struct rb_node *parent = NULL;					\
									\
	BUG_ON(!RB_EMPTY_NODE(&t->nodefld));				\
									\
	while (*n) {							\
		type *cur = rb_entry(*n, type, nodefld);		\
									\
		parent = *n;						\
		if (t->keyfld < cur->keyfld)				\
			n = &(*n)->rb_left;				\
		else if (t->keyfld > cur->keyfld)			\
			n = &(*n)->rb_right;				\
		else							\
			BUG();						\
	}								\
									\
	rb_link_node(&t->nodefld, parent, n);				\
	rb_insert_color(&t->nodefld, root);				\
}									\
static void erase_##name(struct rb_root *root, type *t)			\
{									\
	BUG_ON(RB_EMPTY_NODE(&t->nodefld));				\
	rb_erase(&t->nodefld, root);					\
	RB_CLEAR_NODE(&t->nodefld);					\
}

#define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)		\
220
extern type __lookup_##name##_key;					\
I
Ilya Dryomov 已提交
221
static type *lookup_##name(struct rb_root *root,			\
222
			   typeof(__lookup_##name##_key.keyfld) key)	\
I
Ilya Dryomov 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
{									\
	struct rb_node *n = root->rb_node;				\
									\
	while (n) {							\
		type *cur = rb_entry(n, type, nodefld);			\
									\
		if (key < cur->keyfld)					\
			n = n->rb_left;					\
		else if (key > cur->keyfld)				\
			n = n->rb_right;				\
		else							\
			return cur;					\
	}								\
									\
	return NULL;							\
}

#define DEFINE_RB_FUNCS(name, type, keyfld, nodefld)			\
DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld)			\
DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)

244 245
extern struct kmem_cache *ceph_inode_cachep;
extern struct kmem_cache *ceph_cap_cachep;
246
extern struct kmem_cache *ceph_cap_flush_cachep;
247 248 249
extern struct kmem_cache *ceph_dentry_cachep;
extern struct kmem_cache *ceph_file_cachep;

250
/* ceph_common.c */
251 252
extern bool libceph_compatible(void *data);

253 254
extern const char *ceph_msg_type_name(int type);
extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
255
extern void *ceph_kvmalloc(size_t size, gfp_t flags);
256

257
extern struct ceph_options *ceph_parse_options(char *options,
258 259 260
			      const char *dev_name, const char *dev_name_end,
			      int (*parse_extra_token)(char *c, void *private),
			      void *private);
261
int ceph_print_client_options(struct seq_file *m, struct ceph_client *client);
262 263 264
extern void ceph_destroy_options(struct ceph_options *opt);
extern int ceph_compare_options(struct ceph_options *new_opt,
				struct ceph_client *client);
265
struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private);
266
struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client);
267
u64 ceph_client_gid(struct ceph_client *client);
268 269 270 271 272 273 274 275
extern void ceph_destroy_client(struct ceph_client *client);
extern int __ceph_open_session(struct ceph_client *client,
			       unsigned long started);
extern int ceph_open_session(struct ceph_client *client);

/* pagevec.c */
extern void ceph_release_page_vector(struct page **pages, int num_pages);

276
extern struct page **ceph_get_direct_page_vector(const void __user *data,
277 278 279 280
						 int num_pages,
						 bool write_page);
extern void ceph_put_page_vector(struct page **pages, int num_pages,
				 bool dirty);
281 282
extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
extern int ceph_copy_user_to_page_vector(struct page **pages,
283
					 const void __user *data,
284
					 loff_t off, size_t len);
285
extern void ceph_copy_to_page_vector(struct page **pages,
286
				    const void *data,
287
				    loff_t off, size_t len);
288
extern void ceph_copy_from_page_vector(struct page **pages,
289
				    void *data,
290 291 292 293 294
				    loff_t off, size_t len);
extern void ceph_zero_page_vector_range(int off, int len, struct page **pages);


#endif /* _FS_CEPH_SUPER_H */