Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _FS_CEPH_LIBCEPH_H
0003 #define _FS_CEPH_LIBCEPH_H
0004 
0005 #include <linux/ceph/ceph_debug.h>
0006 
0007 #include <asm/unaligned.h>
0008 #include <linux/backing-dev.h>
0009 #include <linux/completion.h>
0010 #include <linux/exportfs.h>
0011 #include <linux/bug.h>
0012 #include <linux/fs.h>
0013 #include <linux/mempool.h>
0014 #include <linux/pagemap.h>
0015 #include <linux/wait.h>
0016 #include <linux/writeback.h>
0017 #include <linux/slab.h>
0018 #include <linux/refcount.h>
0019 
0020 #include <linux/ceph/types.h>
0021 #include <linux/ceph/messenger.h>
0022 #include <linux/ceph/msgpool.h>
0023 #include <linux/ceph/mon_client.h>
0024 #include <linux/ceph/osd_client.h>
0025 #include <linux/ceph/ceph_fs.h>
0026 #include <linux/ceph/string_table.h>
0027 
0028 /*
0029  * mount options
0030  */
0031 #define CEPH_OPT_FSID             (1<<0)
0032 #define CEPH_OPT_NOSHARE          (1<<1) /* don't share client with other sbs */
0033 #define CEPH_OPT_MYIP             (1<<2) /* specified my ip */
0034 #define CEPH_OPT_NOCRC            (1<<3) /* no data crc on writes (msgr1) */
0035 #define CEPH_OPT_TCP_NODELAY      (1<<4) /* TCP_NODELAY on TCP sockets */
0036 #define CEPH_OPT_NOMSGSIGN        (1<<5) /* don't sign msgs (msgr1) */
0037 #define CEPH_OPT_ABORT_ON_FULL    (1<<6) /* abort w/ ENOSPC when full */
0038 #define CEPH_OPT_RXBOUNCE         (1<<7) /* double-buffer read data */
0039 
0040 #define CEPH_OPT_DEFAULT   (CEPH_OPT_TCP_NODELAY)
0041 
0042 #define ceph_set_opt(client, opt) \
0043     (client)->options->flags |= CEPH_OPT_##opt;
0044 #define ceph_test_opt(client, opt) \
0045     (!!((client)->options->flags & CEPH_OPT_##opt))
0046 
0047 struct ceph_options {
0048     int flags;
0049     struct ceph_fsid fsid;
0050     struct ceph_entity_addr my_addr;
0051     unsigned long mount_timeout;        /* jiffies */
0052     unsigned long osd_idle_ttl;     /* jiffies */
0053     unsigned long osd_keepalive_timeout;    /* jiffies */
0054     unsigned long osd_request_timeout;  /* jiffies */
0055     u32 read_from_replica;  /* CEPH_OSD_FLAG_BALANCE/LOCALIZE_READS */
0056     int con_modes[2];  /* CEPH_CON_MODE_* */
0057 
0058     /*
0059      * any type that can't be simply compared or doesn't need
0060      * to be compared should go beyond this point,
0061      * ceph_compare_options() should be updated accordingly
0062      */
0063 
0064     struct ceph_entity_addr *mon_addr; /* should be the first
0065                           pointer type of args */
0066     int num_mon;
0067     char *name;
0068     struct ceph_crypto_key *key;
0069     struct rb_root crush_locs;
0070 };
0071 
0072 /*
0073  * defaults
0074  */
0075 #define CEPH_MOUNT_TIMEOUT_DEFAULT  msecs_to_jiffies(60 * 1000)
0076 #define CEPH_OSD_KEEPALIVE_DEFAULT  msecs_to_jiffies(5 * 1000)
0077 #define CEPH_OSD_IDLE_TTL_DEFAULT   msecs_to_jiffies(60 * 1000)
0078 #define CEPH_OSD_REQUEST_TIMEOUT_DEFAULT 0  /* no timeout */
0079 #define CEPH_READ_FROM_REPLICA_DEFAULT  0  /* read from primary */
0080 
0081 #define CEPH_MONC_HUNT_INTERVAL     msecs_to_jiffies(3 * 1000)
0082 #define CEPH_MONC_PING_INTERVAL     msecs_to_jiffies(10 * 1000)
0083 #define CEPH_MONC_PING_TIMEOUT      msecs_to_jiffies(30 * 1000)
0084 #define CEPH_MONC_HUNT_BACKOFF      2
0085 #define CEPH_MONC_HUNT_MAX_MULT     10
0086 
0087 #define CEPH_MSG_MAX_CONTROL_LEN (16*1024*1024)
0088 #define CEPH_MSG_MAX_FRONT_LEN  (16*1024*1024)
0089 #define CEPH_MSG_MAX_MIDDLE_LEN (16*1024*1024)
0090 
0091 /*
0092  * The largest possible rbd data object is 32M.
0093  * The largest possible rbd object map object is 64M.
0094  *
0095  * There is no limit on the size of cephfs objects, but it has to obey
0096  * rsize and wsize mount options anyway.
0097  */
0098 #define CEPH_MSG_MAX_DATA_LEN   (64*1024*1024)
0099 
0100 #define CEPH_AUTH_NAME_DEFAULT   "guest"
0101 
0102 /* mount state */
0103 enum {
0104     CEPH_MOUNT_MOUNTING,
0105     CEPH_MOUNT_MOUNTED,
0106     CEPH_MOUNT_UNMOUNTING,
0107     CEPH_MOUNT_UNMOUNTED,
0108     CEPH_MOUNT_SHUTDOWN,
0109     CEPH_MOUNT_RECOVER,
0110 };
0111 
0112 static inline unsigned long ceph_timeout_jiffies(unsigned long timeout)
0113 {
0114     return timeout ?: MAX_SCHEDULE_TIMEOUT;
0115 }
0116 
0117 struct ceph_mds_client;
0118 
0119 /*
0120  * per client state
0121  *
0122  * possibly shared by multiple mount points, if they are
0123  * mounting the same ceph filesystem/cluster.
0124  */
0125 struct ceph_client {
0126     struct ceph_fsid fsid;
0127     bool have_fsid;
0128 
0129     void *private;
0130 
0131     struct ceph_options *options;
0132 
0133     struct mutex mount_mutex;      /* serialize mount attempts */
0134     wait_queue_head_t auth_wq;
0135     int auth_err;
0136 
0137     int (*extra_mon_dispatch)(struct ceph_client *, struct ceph_msg *);
0138 
0139     u64 supported_features;
0140     u64 required_features;
0141 
0142     struct ceph_messenger msgr;   /* messenger instance */
0143     struct ceph_mon_client monc;
0144     struct ceph_osd_client osdc;
0145 
0146 #ifdef CONFIG_DEBUG_FS
0147     struct dentry *debugfs_dir;
0148     struct dentry *debugfs_monmap;
0149     struct dentry *debugfs_osdmap;
0150     struct dentry *debugfs_options;
0151 #endif
0152 };
0153 
0154 #define from_msgr(ms)   container_of(ms, struct ceph_client, msgr)
0155 
0156 static inline bool ceph_msgr2(struct ceph_client *client)
0157 {
0158     return client->options->con_modes[0] != CEPH_CON_MODE_UNKNOWN;
0159 }
0160 
0161 /*
0162  * snapshots
0163  */
0164 
0165 /*
0166  * A "snap context" is the set of existing snapshots when we
0167  * write data.  It is used by the OSD to guide its COW behavior.
0168  *
0169  * The ceph_snap_context is refcounted, and attached to each dirty
0170  * page, indicating which context the dirty data belonged when it was
0171  * dirtied.
0172  */
0173 struct ceph_snap_context {
0174     refcount_t nref;
0175     u64 seq;
0176     u32 num_snaps;
0177     u64 snaps[];
0178 };
0179 
0180 extern struct ceph_snap_context *ceph_create_snap_context(u32 snap_count,
0181                     gfp_t gfp_flags);
0182 extern struct ceph_snap_context *ceph_get_snap_context(
0183                     struct ceph_snap_context *sc);
0184 extern void ceph_put_snap_context(struct ceph_snap_context *sc);
0185 
0186 /*
0187  * calculate the number of pages a given length and offset map onto,
0188  * if we align the data.
0189  */
0190 static inline int calc_pages_for(u64 off, u64 len)
0191 {
0192     return ((off+len+PAGE_SIZE-1) >> PAGE_SHIFT) -
0193         (off >> PAGE_SHIFT);
0194 }
0195 
0196 #define RB_BYVAL(a)      (a)
0197 #define RB_BYPTR(a)      (&(a))
0198 #define RB_CMP3WAY(a, b) ((a) < (b) ? -1 : (a) > (b))
0199 
0200 #define DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, cmpexp, keyexp, nodefld) \
0201 static bool __insert_##name(struct rb_root *root, type *t)      \
0202 {                                   \
0203     struct rb_node **n = &root->rb_node;                \
0204     struct rb_node *parent = NULL;                  \
0205                                     \
0206     BUG_ON(!RB_EMPTY_NODE(&t->nodefld));                \
0207                                     \
0208     while (*n) {                            \
0209         type *cur = rb_entry(*n, type, nodefld);        \
0210         int cmp;                        \
0211                                     \
0212         parent = *n;                        \
0213         cmp = cmpexp(keyexp(t->keyfld), keyexp(cur->keyfld));   \
0214         if (cmp < 0)                        \
0215             n = &(*n)->rb_left;             \
0216         else if (cmp > 0)                   \
0217             n = &(*n)->rb_right;                \
0218         else                            \
0219             return false;                   \
0220     }                               \
0221                                     \
0222     rb_link_node(&t->nodefld, parent, n);               \
0223     rb_insert_color(&t->nodefld, root);             \
0224     return true;                            \
0225 }                                   \
0226 static void __maybe_unused insert_##name(struct rb_root *root, type *t) \
0227 {                                   \
0228     if (!__insert_##name(root, t))                  \
0229         BUG();                          \
0230 }                                   \
0231 static void erase_##name(struct rb_root *root, type *t)         \
0232 {                                   \
0233     BUG_ON(RB_EMPTY_NODE(&t->nodefld));             \
0234     rb_erase(&t->nodefld, root);                    \
0235     RB_CLEAR_NODE(&t->nodefld);                 \
0236 }
0237 
0238 /*
0239  * @lookup_param_type is a parameter and not constructed from (@type,
0240  * @keyfld) with typeof() because adding const is too unwieldy.
0241  */
0242 #define DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, cmpexp, keyexp,  \
0243                    lookup_param_type, nodefld)      \
0244 static type *lookup_##name(struct rb_root *root, lookup_param_type key) \
0245 {                                   \
0246     struct rb_node *n = root->rb_node;              \
0247                                     \
0248     while (n) {                         \
0249         type *cur = rb_entry(n, type, nodefld);         \
0250         int cmp;                        \
0251                                     \
0252         cmp = cmpexp(key, keyexp(cur->keyfld));         \
0253         if (cmp < 0)                        \
0254             n = n->rb_left;                 \
0255         else if (cmp > 0)                   \
0256             n = n->rb_right;                \
0257         else                            \
0258             return cur;                 \
0259     }                               \
0260                                     \
0261     return NULL;                            \
0262 }
0263 
0264 #define DEFINE_RB_FUNCS2(name, type, keyfld, cmpexp, keyexp,        \
0265              lookup_param_type, nodefld)            \
0266 DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, cmpexp, keyexp, nodefld)    \
0267 DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, cmpexp, keyexp,      \
0268                lookup_param_type, nodefld)
0269 
0270 /*
0271  * Shorthands for integer keys.
0272  */
0273 #define DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld)     \
0274 DEFINE_RB_INSDEL_FUNCS2(name, type, keyfld, RB_CMP3WAY, RB_BYVAL, nodefld)
0275 
0276 #define DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)      \
0277 extern type __lookup_##name##_key;                  \
0278 DEFINE_RB_LOOKUP_FUNC2(name, type, keyfld, RB_CMP3WAY, RB_BYVAL,    \
0279                typeof(__lookup_##name##_key.keyfld), nodefld)
0280 
0281 #define DEFINE_RB_FUNCS(name, type, keyfld, nodefld)            \
0282 DEFINE_RB_INSDEL_FUNCS(name, type, keyfld, nodefld)         \
0283 DEFINE_RB_LOOKUP_FUNC(name, type, keyfld, nodefld)
0284 
0285 extern struct kmem_cache *ceph_inode_cachep;
0286 extern struct kmem_cache *ceph_cap_cachep;
0287 extern struct kmem_cache *ceph_cap_snap_cachep;
0288 extern struct kmem_cache *ceph_cap_flush_cachep;
0289 extern struct kmem_cache *ceph_dentry_cachep;
0290 extern struct kmem_cache *ceph_file_cachep;
0291 extern struct kmem_cache *ceph_dir_file_cachep;
0292 extern struct kmem_cache *ceph_mds_request_cachep;
0293 extern mempool_t *ceph_wb_pagevec_pool;
0294 
0295 /* ceph_common.c */
0296 extern bool libceph_compatible(void *data);
0297 
0298 extern const char *ceph_msg_type_name(int type);
0299 extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
0300 extern int ceph_parse_fsid(const char *str, struct ceph_fsid *fsid);
0301 
0302 struct fs_parameter;
0303 struct fc_log;
0304 struct ceph_options *ceph_alloc_options(void);
0305 int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
0306                struct fc_log *l, char delim);
0307 int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
0308              struct fc_log *l);
0309 int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
0310                   bool show_all);
0311 extern void ceph_destroy_options(struct ceph_options *opt);
0312 extern int ceph_compare_options(struct ceph_options *new_opt,
0313                 struct ceph_client *client);
0314 struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private);
0315 struct ceph_entity_addr *ceph_client_addr(struct ceph_client *client);
0316 u64 ceph_client_gid(struct ceph_client *client);
0317 extern void ceph_destroy_client(struct ceph_client *client);
0318 extern void ceph_reset_client_addr(struct ceph_client *client);
0319 extern int __ceph_open_session(struct ceph_client *client,
0320                    unsigned long started);
0321 extern int ceph_open_session(struct ceph_client *client);
0322 int ceph_wait_for_latest_osdmap(struct ceph_client *client,
0323                 unsigned long timeout);
0324 
0325 /* pagevec.c */
0326 extern void ceph_release_page_vector(struct page **pages, int num_pages);
0327 extern void ceph_put_page_vector(struct page **pages, int num_pages,
0328                  bool dirty);
0329 extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
0330 extern int ceph_copy_user_to_page_vector(struct page **pages,
0331                      const void __user *data,
0332                      loff_t off, size_t len);
0333 extern void ceph_copy_to_page_vector(struct page **pages,
0334                     const void *data,
0335                     loff_t off, size_t len);
0336 extern void ceph_copy_from_page_vector(struct page **pages,
0337                     void *data,
0338                     loff_t off, size_t len);
0339 extern void ceph_zero_page_vector_range(int off, int len, struct page **pages);
0340 
0341 
0342 #endif /* _FS_CEPH_SUPER_H */