1*de57606cSSage Weil #ifndef _FS_CEPH_SUPER_H 2*de57606cSSage Weil #define _FS_CEPH_SUPER_H 3*de57606cSSage Weil 4*de57606cSSage Weil #include "ceph_debug.h" 5*de57606cSSage Weil 6*de57606cSSage Weil #include <asm/unaligned.h> 7*de57606cSSage Weil #include <linux/backing-dev.h> 8*de57606cSSage Weil #include <linux/completion.h> 9*de57606cSSage Weil #include <linux/exportfs.h> 10*de57606cSSage Weil #include <linux/fs.h> 11*de57606cSSage Weil #include <linux/mempool.h> 12*de57606cSSage Weil #include <linux/pagemap.h> 13*de57606cSSage Weil #include <linux/wait.h> 14*de57606cSSage Weil 15*de57606cSSage Weil #include "types.h" 16*de57606cSSage Weil #include "messenger.h" 17*de57606cSSage Weil #include "msgpool.h" 18*de57606cSSage Weil #include "mon_client.h" 19*de57606cSSage Weil #include "mds_client.h" 20*de57606cSSage Weil #include "osd_client.h" 21*de57606cSSage Weil #include "ceph_fs.h" 22*de57606cSSage Weil 23*de57606cSSage Weil /* f_type in struct statfs */ 24*de57606cSSage Weil #define CEPH_SUPER_MAGIC 0x00c36400 25*de57606cSSage Weil 26*de57606cSSage Weil /* large granularity for statfs utilization stats to facilitate 27*de57606cSSage Weil * large volume sizes on 32-bit machines. */ 28*de57606cSSage Weil #define CEPH_BLOCK_SHIFT 20 /* 1 MB */ 29*de57606cSSage Weil #define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT) 30*de57606cSSage Weil 31*de57606cSSage Weil /* 32*de57606cSSage Weil * mount options 33*de57606cSSage Weil */ 34*de57606cSSage Weil #define CEPH_OPT_FSID (1<<0) 35*de57606cSSage Weil #define CEPH_OPT_NOSHARE (1<<1) /* don't share client with other sbs */ 36*de57606cSSage Weil #define CEPH_OPT_MYIP (1<<2) /* specified my ip */ 37*de57606cSSage Weil #define CEPH_OPT_DIRSTAT (1<<4) /* funky `cat dirname` for stats */ 38*de57606cSSage Weil #define CEPH_OPT_RBYTES (1<<5) /* dir st_bytes = rbytes */ 39*de57606cSSage Weil #define CEPH_OPT_NOCRC (1<<6) /* no data crc on writes */ 40*de57606cSSage Weil #define CEPH_OPT_NOASYNCREADDIR (1<<7) /* no dcache readdir */ 41*de57606cSSage Weil 42*de57606cSSage Weil #define CEPH_OPT_DEFAULT (CEPH_OPT_RBYTES) 43*de57606cSSage Weil 44*de57606cSSage Weil #define ceph_set_opt(client, opt) \ 45*de57606cSSage Weil (client)->mount_args.flags |= CEPH_OPT_##opt; 46*de57606cSSage Weil #define ceph_test_opt(client, opt) \ 47*de57606cSSage Weil (!!((client)->mount_args.flags & CEPH_OPT_##opt)) 48*de57606cSSage Weil 49*de57606cSSage Weil 50*de57606cSSage Weil #define CEPH_MAX_MON_MOUNT_ADDR 5 51*de57606cSSage Weil 52*de57606cSSage Weil struct ceph_mount_args { 53*de57606cSSage Weil int sb_flags; 54*de57606cSSage Weil int flags; 55*de57606cSSage Weil int mount_timeout; 56*de57606cSSage Weil int caps_wanted_delay_min, caps_wanted_delay_max; 57*de57606cSSage Weil struct ceph_fsid fsid; 58*de57606cSSage Weil struct ceph_entity_addr my_addr; 59*de57606cSSage Weil int wsize; 60*de57606cSSage Weil int rsize; /* max readahead */ 61*de57606cSSage Weil int max_readdir; /* max readdir size */ 62*de57606cSSage Weil int osd_timeout; 63*de57606cSSage Weil char *snapdir_name; /* default ".snap" */ 64*de57606cSSage Weil char *secret; 65*de57606cSSage Weil int cap_release_safety; 66*de57606cSSage Weil }; 67*de57606cSSage Weil 68*de57606cSSage Weil /* 69*de57606cSSage Weil * defaults 70*de57606cSSage Weil */ 71*de57606cSSage Weil #define CEPH_MOUNT_TIMEOUT_DEFAULT 60 72*de57606cSSage Weil #define CEPH_MOUNT_RSIZE_DEFAULT (128*1024) /* readahead */ 73*de57606cSSage Weil 74*de57606cSSage Weil #define CEPH_MSG_MAX_FRONT_LEN (16*1024*1024) 75*de57606cSSage Weil #define CEPH_MSG_MAX_DATA_LEN (16*1024*1024) 76*de57606cSSage Weil 77*de57606cSSage Weil #define CEPH_SNAPDIRNAME_DEFAULT ".snap" 78*de57606cSSage Weil 79*de57606cSSage Weil /* 80*de57606cSSage Weil * Delay telling the MDS we no longer want caps, in case we reopen 81*de57606cSSage Weil * the file. Delay a minimum amount of time, even if we send a cap 82*de57606cSSage Weil * message for some other reason. Otherwise, take the oppotunity to 83*de57606cSSage Weil * update the mds to avoid sending another message later. 84*de57606cSSage Weil */ 85*de57606cSSage Weil #define CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT 5 /* cap release delay */ 86*de57606cSSage Weil #define CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT 60 /* cap release delay */ 87*de57606cSSage Weil 88*de57606cSSage Weil 89*de57606cSSage Weil /* mount state */ 90*de57606cSSage Weil enum { 91*de57606cSSage Weil CEPH_MOUNT_MOUNTING, 92*de57606cSSage Weil CEPH_MOUNT_MOUNTED, 93*de57606cSSage Weil CEPH_MOUNT_UNMOUNTING, 94*de57606cSSage Weil CEPH_MOUNT_UNMOUNTED, 95*de57606cSSage Weil CEPH_MOUNT_SHUTDOWN, 96*de57606cSSage Weil }; 97*de57606cSSage Weil 98*de57606cSSage Weil /* 99*de57606cSSage Weil * subtract jiffies 100*de57606cSSage Weil */ 101*de57606cSSage Weil static inline unsigned long time_sub(unsigned long a, unsigned long b) 102*de57606cSSage Weil { 103*de57606cSSage Weil BUG_ON(time_after(b, a)); 104*de57606cSSage Weil return (long)a - (long)b; 105*de57606cSSage Weil } 106*de57606cSSage Weil 107*de57606cSSage Weil /* 108*de57606cSSage Weil * per-filesystem client state 109*de57606cSSage Weil * 110*de57606cSSage Weil * possibly shared by multiple mount points, if they are 111*de57606cSSage Weil * mounting the same ceph filesystem/cluster. 112*de57606cSSage Weil */ 113*de57606cSSage Weil struct ceph_client { 114*de57606cSSage Weil __s64 whoami; /* my client number */ 115*de57606cSSage Weil struct dentry *debugfs_monmap; 116*de57606cSSage Weil struct dentry *debugfs_mdsmap, *debugfs_osdmap; 117*de57606cSSage Weil struct dentry *debugfs_dir, *debugfs_dentry_lru, *debugfs_caps; 118*de57606cSSage Weil 119*de57606cSSage Weil struct mutex mount_mutex; /* serialize mount attempts */ 120*de57606cSSage Weil struct ceph_mount_args mount_args; 121*de57606cSSage Weil struct ceph_fsid fsid; 122*de57606cSSage Weil 123*de57606cSSage Weil struct super_block *sb; 124*de57606cSSage Weil 125*de57606cSSage Weil unsigned long mount_state; 126*de57606cSSage Weil wait_queue_head_t mount_wq; 127*de57606cSSage Weil 128*de57606cSSage Weil int mount_err; 129*de57606cSSage Weil void *signed_ticket; /* our keys to the kingdom */ 130*de57606cSSage Weil int signed_ticket_len; 131*de57606cSSage Weil 132*de57606cSSage Weil struct ceph_messenger *msgr; /* messenger instance */ 133*de57606cSSage Weil struct ceph_mon_client monc; 134*de57606cSSage Weil struct ceph_mds_client mdsc; 135*de57606cSSage Weil struct ceph_osd_client osdc; 136*de57606cSSage Weil 137*de57606cSSage Weil /* writeback */ 138*de57606cSSage Weil mempool_t *wb_pagevec_pool; 139*de57606cSSage Weil struct workqueue_struct *wb_wq; 140*de57606cSSage Weil struct workqueue_struct *pg_inv_wq; 141*de57606cSSage Weil struct workqueue_struct *trunc_wq; 142*de57606cSSage Weil 143*de57606cSSage Weil struct backing_dev_info backing_dev_info; 144*de57606cSSage Weil }; 145*de57606cSSage Weil 146*de57606cSSage Weil static inline struct ceph_client *ceph_client(struct super_block *sb) 147*de57606cSSage Weil { 148*de57606cSSage Weil return sb->s_fs_info; 149*de57606cSSage Weil } 150*de57606cSSage Weil 151*de57606cSSage Weil 152*de57606cSSage Weil /* 153*de57606cSSage Weil * File i/o capability. This tracks shared state with the metadata 154*de57606cSSage Weil * server that allows us to cache or writeback attributes or to read 155*de57606cSSage Weil * and write data. For any given inode, we should have one or more 156*de57606cSSage Weil * capabilities, one issued by each metadata server, and our 157*de57606cSSage Weil * cumulative access is the OR of all issued capabilities. 158*de57606cSSage Weil * 159*de57606cSSage Weil * Each cap is referenced by the inode's i_caps rbtree and by per-mds 160*de57606cSSage Weil * session capability lists. 161*de57606cSSage Weil */ 162*de57606cSSage Weil struct ceph_cap { 163*de57606cSSage Weil struct ceph_inode_info *ci; 164*de57606cSSage Weil struct rb_node ci_node; /* per-ci cap tree */ 165*de57606cSSage Weil struct ceph_mds_session *session; 166*de57606cSSage Weil struct list_head session_caps; /* per-session caplist */ 167*de57606cSSage Weil int mds; 168*de57606cSSage Weil u64 cap_id; /* unique cap id (mds provided) */ 169*de57606cSSage Weil int issued; /* latest, from the mds */ 170*de57606cSSage Weil int implemented; /* implemented superset of issued (for revocation) */ 171*de57606cSSage Weil int mds_wanted; 172*de57606cSSage Weil u32 seq, issue_seq, mseq, gen; 173*de57606cSSage Weil unsigned long last_used; 174*de57606cSSage Weil struct list_head caps_item; 175*de57606cSSage Weil }; 176*de57606cSSage Weil 177*de57606cSSage Weil #define CHECK_CAPS_NODELAY 1 /* do not delay any further */ 178*de57606cSSage Weil #define CHECK_CAPS_AUTHONLY 2 /* only check auth cap */ 179*de57606cSSage Weil #define CHECK_CAPS_FLUSH 4 /* flush any dirty caps */ 180*de57606cSSage Weil 181*de57606cSSage Weil /* 182*de57606cSSage Weil * Snapped cap state that is pending flush to mds. When a snapshot occurs, 183*de57606cSSage Weil * we first complete any in-process sync writes and writeback any dirty 184*de57606cSSage Weil * data before flushing the snapped state (tracked here) back to the MDS. 185*de57606cSSage Weil */ 186*de57606cSSage Weil struct ceph_cap_snap { 187*de57606cSSage Weil atomic_t nref; 188*de57606cSSage Weil struct ceph_inode_info *ci; 189*de57606cSSage Weil struct list_head ci_item, flushing_item; 190*de57606cSSage Weil 191*de57606cSSage Weil u64 follows, flush_tid; 192*de57606cSSage Weil int issued, dirty; 193*de57606cSSage Weil struct ceph_snap_context *context; 194*de57606cSSage Weil 195*de57606cSSage Weil mode_t mode; 196*de57606cSSage Weil uid_t uid; 197*de57606cSSage Weil gid_t gid; 198*de57606cSSage Weil 199*de57606cSSage Weil void *xattr_blob; 200*de57606cSSage Weil int xattr_len; 201*de57606cSSage Weil u64 xattr_version; 202*de57606cSSage Weil 203*de57606cSSage Weil u64 size; 204*de57606cSSage Weil struct timespec mtime, atime, ctime; 205*de57606cSSage Weil u64 time_warp_seq; 206*de57606cSSage Weil int writing; /* a sync write is still in progress */ 207*de57606cSSage Weil int dirty_pages; /* dirty pages awaiting writeback */ 208*de57606cSSage Weil }; 209*de57606cSSage Weil 210*de57606cSSage Weil static inline void ceph_put_cap_snap(struct ceph_cap_snap *capsnap) 211*de57606cSSage Weil { 212*de57606cSSage Weil if (atomic_dec_and_test(&capsnap->nref)) 213*de57606cSSage Weil kfree(capsnap); 214*de57606cSSage Weil } 215*de57606cSSage Weil 216*de57606cSSage Weil /* 217*de57606cSSage Weil * The frag tree describes how a directory is fragmented, potentially across 218*de57606cSSage Weil * multiple metadata servers. It is also used to indicate points where 219*de57606cSSage Weil * metadata authority is delegated, and whether/where metadata is replicated. 220*de57606cSSage Weil * 221*de57606cSSage Weil * A _leaf_ frag will be present in the i_fragtree IFF there is 222*de57606cSSage Weil * delegation info. That is, if mds >= 0 || ndist > 0. 223*de57606cSSage Weil */ 224*de57606cSSage Weil #define CEPH_MAX_DIRFRAG_REP 4 225*de57606cSSage Weil 226*de57606cSSage Weil struct ceph_inode_frag { 227*de57606cSSage Weil struct rb_node node; 228*de57606cSSage Weil 229*de57606cSSage Weil /* fragtree state */ 230*de57606cSSage Weil u32 frag; 231*de57606cSSage Weil int split_by; /* i.e. 2^(split_by) children */ 232*de57606cSSage Weil 233*de57606cSSage Weil /* delegation and replication info */ 234*de57606cSSage Weil int mds; /* -1 if same authority as parent */ 235*de57606cSSage Weil int ndist; /* >0 if replicated */ 236*de57606cSSage Weil int dist[CEPH_MAX_DIRFRAG_REP]; 237*de57606cSSage Weil }; 238*de57606cSSage Weil 239*de57606cSSage Weil /* 240*de57606cSSage Weil * We cache inode xattrs as an encoded blob until they are first used, 241*de57606cSSage Weil * at which point we parse them into an rbtree. 242*de57606cSSage Weil */ 243*de57606cSSage Weil struct ceph_inode_xattr { 244*de57606cSSage Weil struct rb_node node; 245*de57606cSSage Weil 246*de57606cSSage Weil const char *name; 247*de57606cSSage Weil int name_len; 248*de57606cSSage Weil const char *val; 249*de57606cSSage Weil int val_len; 250*de57606cSSage Weil int dirty; 251*de57606cSSage Weil 252*de57606cSSage Weil int should_free_name; 253*de57606cSSage Weil int should_free_val; 254*de57606cSSage Weil }; 255*de57606cSSage Weil 256*de57606cSSage Weil struct ceph_inode_xattrs_info { 257*de57606cSSage Weil /* 258*de57606cSSage Weil * (still encoded) xattr blob. we avoid the overhead of parsing 259*de57606cSSage Weil * this until someone actually calls getxattr, etc. 260*de57606cSSage Weil * 261*de57606cSSage Weil * blob->vec.iov_len == 4 implies there are no xattrs; blob == 262*de57606cSSage Weil * NULL means we don't know. 263*de57606cSSage Weil */ 264*de57606cSSage Weil struct ceph_buffer *blob, *prealloc_blob; 265*de57606cSSage Weil 266*de57606cSSage Weil struct rb_root index; 267*de57606cSSage Weil bool dirty; 268*de57606cSSage Weil int count; 269*de57606cSSage Weil int names_size; 270*de57606cSSage Weil int vals_size; 271*de57606cSSage Weil u64 version, index_version; 272*de57606cSSage Weil }; 273*de57606cSSage Weil 274*de57606cSSage Weil /* 275*de57606cSSage Weil * Ceph inode. 276*de57606cSSage Weil */ 277*de57606cSSage Weil #define CEPH_I_COMPLETE 1 /* we have complete directory cached */ 278*de57606cSSage Weil #define CEPH_I_NODELAY 4 /* do not delay cap release */ 279*de57606cSSage Weil #define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */ 280*de57606cSSage Weil 281*de57606cSSage Weil struct ceph_inode_info { 282*de57606cSSage Weil struct ceph_vino i_vino; /* ceph ino + snap */ 283*de57606cSSage Weil 284*de57606cSSage Weil u64 i_version; 285*de57606cSSage Weil u32 i_time_warp_seq; 286*de57606cSSage Weil 287*de57606cSSage Weil unsigned i_ceph_flags; 288*de57606cSSage Weil unsigned long i_release_count; 289*de57606cSSage Weil 290*de57606cSSage Weil struct ceph_file_layout i_layout; 291*de57606cSSage Weil char *i_symlink; 292*de57606cSSage Weil 293*de57606cSSage Weil /* for dirs */ 294*de57606cSSage Weil struct timespec i_rctime; 295*de57606cSSage Weil u64 i_rbytes, i_rfiles, i_rsubdirs; 296*de57606cSSage Weil u64 i_files, i_subdirs; 297*de57606cSSage Weil u64 i_max_offset; /* largest readdir offset, set with I_COMPLETE */ 298*de57606cSSage Weil 299*de57606cSSage Weil struct rb_root i_fragtree; 300*de57606cSSage Weil struct mutex i_fragtree_mutex; 301*de57606cSSage Weil 302*de57606cSSage Weil struct ceph_inode_xattrs_info i_xattrs; 303*de57606cSSage Weil 304*de57606cSSage Weil /* capabilities. protected _both_ by i_lock and cap->session's 305*de57606cSSage Weil * s_mutex. */ 306*de57606cSSage Weil struct rb_root i_caps; /* cap list */ 307*de57606cSSage Weil struct ceph_cap *i_auth_cap; /* authoritative cap, if any */ 308*de57606cSSage Weil unsigned i_dirty_caps, i_flushing_caps; /* mask of dirtied fields */ 309*de57606cSSage Weil struct list_head i_dirty_item, i_flushing_item; 310*de57606cSSage Weil u64 i_cap_flush_seq; 311*de57606cSSage Weil /* we need to track cap writeback on a per-cap-bit basis, to allow 312*de57606cSSage Weil * overlapping, pipelined cap flushes to the mds. we can probably 313*de57606cSSage Weil * reduce the tid to 8 bits if we're concerned about inode size. */ 314*de57606cSSage Weil u16 i_cap_flush_last_tid, i_cap_flush_tid[CEPH_CAP_BITS]; 315*de57606cSSage Weil wait_queue_head_t i_cap_wq; /* threads waiting on a capability */ 316*de57606cSSage Weil unsigned long i_hold_caps_min; /* jiffies */ 317*de57606cSSage Weil unsigned long i_hold_caps_max; /* jiffies */ 318*de57606cSSage Weil struct list_head i_cap_delay_list; /* for delayed cap release to mds */ 319*de57606cSSage Weil int i_cap_exporting_mds; /* to handle cap migration between */ 320*de57606cSSage Weil unsigned i_cap_exporting_mseq; /* mds's. */ 321*de57606cSSage Weil unsigned i_cap_exporting_issued; 322*de57606cSSage Weil struct ceph_cap_reservation i_cap_migration_resv; 323*de57606cSSage Weil struct list_head i_cap_snaps; /* snapped state pending flush to mds */ 324*de57606cSSage Weil struct ceph_snap_context *i_head_snapc; /* set if wr_buffer_head > 0 */ 325*de57606cSSage Weil unsigned i_snap_caps; /* cap bits for snapped files */ 326*de57606cSSage Weil 327*de57606cSSage Weil int i_nr_by_mode[CEPH_FILE_MODE_NUM]; /* open file counts */ 328*de57606cSSage Weil 329*de57606cSSage Weil u32 i_truncate_seq; /* last truncate to smaller size */ 330*de57606cSSage Weil u64 i_truncate_size; /* and the size we last truncated down to */ 331*de57606cSSage Weil int i_truncate_pending; /* still need to call vmtruncate */ 332*de57606cSSage Weil 333*de57606cSSage Weil u64 i_max_size; /* max file size authorized by mds */ 334*de57606cSSage Weil u64 i_reported_size; /* (max_)size reported to or requested of mds */ 335*de57606cSSage Weil u64 i_wanted_max_size; /* offset we'd like to write too */ 336*de57606cSSage Weil u64 i_requested_max_size; /* max_size we've requested */ 337*de57606cSSage Weil 338*de57606cSSage Weil /* held references to caps */ 339*de57606cSSage Weil int i_pin_ref; 340*de57606cSSage Weil int i_rd_ref, i_rdcache_ref, i_wr_ref; 341*de57606cSSage Weil int i_wrbuffer_ref, i_wrbuffer_ref_head; 342*de57606cSSage Weil u32 i_shared_gen; /* increment each time we get FILE_SHARED */ 343*de57606cSSage Weil u32 i_rdcache_gen; /* we increment this each time we get 344*de57606cSSage Weil FILE_CACHE. If it's non-zero, we 345*de57606cSSage Weil _may_ have cached pages. */ 346*de57606cSSage Weil u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */ 347*de57606cSSage Weil 348*de57606cSSage Weil struct list_head i_unsafe_writes; /* uncommitted sync writes */ 349*de57606cSSage Weil struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */ 350*de57606cSSage Weil spinlock_t i_unsafe_lock; 351*de57606cSSage Weil 352*de57606cSSage Weil struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */ 353*de57606cSSage Weil int i_snap_realm_counter; /* snap realm (if caps) */ 354*de57606cSSage Weil struct list_head i_snap_realm_item; 355*de57606cSSage Weil struct list_head i_snap_flush_item; 356*de57606cSSage Weil 357*de57606cSSage Weil struct work_struct i_wb_work; /* writeback work */ 358*de57606cSSage Weil struct work_struct i_pg_inv_work; /* page invalidation work */ 359*de57606cSSage Weil 360*de57606cSSage Weil struct work_struct i_vmtruncate_work; 361*de57606cSSage Weil 362*de57606cSSage Weil struct inode vfs_inode; /* at end */ 363*de57606cSSage Weil }; 364*de57606cSSage Weil 365*de57606cSSage Weil static inline struct ceph_inode_info *ceph_inode(struct inode *inode) 366*de57606cSSage Weil { 367*de57606cSSage Weil return list_entry(inode, struct ceph_inode_info, vfs_inode); 368*de57606cSSage Weil } 369*de57606cSSage Weil 370*de57606cSSage Weil static inline void ceph_i_clear(struct inode *inode, unsigned mask) 371*de57606cSSage Weil { 372*de57606cSSage Weil struct ceph_inode_info *ci = ceph_inode(inode); 373*de57606cSSage Weil 374*de57606cSSage Weil spin_lock(&inode->i_lock); 375*de57606cSSage Weil ci->i_ceph_flags &= ~mask; 376*de57606cSSage Weil spin_unlock(&inode->i_lock); 377*de57606cSSage Weil } 378*de57606cSSage Weil 379*de57606cSSage Weil static inline void ceph_i_set(struct inode *inode, unsigned mask) 380*de57606cSSage Weil { 381*de57606cSSage Weil struct ceph_inode_info *ci = ceph_inode(inode); 382*de57606cSSage Weil 383*de57606cSSage Weil spin_lock(&inode->i_lock); 384*de57606cSSage Weil ci->i_ceph_flags |= mask; 385*de57606cSSage Weil spin_unlock(&inode->i_lock); 386*de57606cSSage Weil } 387*de57606cSSage Weil 388*de57606cSSage Weil static inline bool ceph_i_test(struct inode *inode, unsigned mask) 389*de57606cSSage Weil { 390*de57606cSSage Weil struct ceph_inode_info *ci = ceph_inode(inode); 391*de57606cSSage Weil bool r; 392*de57606cSSage Weil 393*de57606cSSage Weil smp_mb(); 394*de57606cSSage Weil r = (ci->i_ceph_flags & mask) == mask; 395*de57606cSSage Weil return r; 396*de57606cSSage Weil } 397*de57606cSSage Weil 398*de57606cSSage Weil 399*de57606cSSage Weil /* find a specific frag @f */ 400*de57606cSSage Weil extern struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, 401*de57606cSSage Weil u32 f); 402*de57606cSSage Weil 403*de57606cSSage Weil /* 404*de57606cSSage Weil * choose fragment for value @v. copy frag content to pfrag, if leaf 405*de57606cSSage Weil * exists 406*de57606cSSage Weil */ 407*de57606cSSage Weil extern u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v, 408*de57606cSSage Weil struct ceph_inode_frag *pfrag, 409*de57606cSSage Weil int *found); 410*de57606cSSage Weil 411*de57606cSSage Weil /* 412*de57606cSSage Weil * Ceph dentry state 413*de57606cSSage Weil */ 414*de57606cSSage Weil struct ceph_dentry_info { 415*de57606cSSage Weil struct ceph_mds_session *lease_session; 416*de57606cSSage Weil u32 lease_gen, lease_shared_gen; 417*de57606cSSage Weil u32 lease_seq; 418*de57606cSSage Weil unsigned long lease_renew_after, lease_renew_from; 419*de57606cSSage Weil struct list_head lru; 420*de57606cSSage Weil struct dentry *dentry; 421*de57606cSSage Weil u64 time; 422*de57606cSSage Weil u64 offset; 423*de57606cSSage Weil }; 424*de57606cSSage Weil 425*de57606cSSage Weil static inline struct ceph_dentry_info *ceph_dentry(struct dentry *dentry) 426*de57606cSSage Weil { 427*de57606cSSage Weil return (struct ceph_dentry_info *)dentry->d_fsdata; 428*de57606cSSage Weil } 429*de57606cSSage Weil 430*de57606cSSage Weil static inline loff_t ceph_make_fpos(unsigned frag, unsigned off) 431*de57606cSSage Weil { 432*de57606cSSage Weil return ((loff_t)frag << 32) | (loff_t)off; 433*de57606cSSage Weil } 434*de57606cSSage Weil 435*de57606cSSage Weil /* 436*de57606cSSage Weil * ino_t is <64 bits on many architectures, blech. 437*de57606cSSage Weil * 438*de57606cSSage Weil * don't include snap in ino hash, at least for now. 439*de57606cSSage Weil */ 440*de57606cSSage Weil static inline ino_t ceph_vino_to_ino(struct ceph_vino vino) 441*de57606cSSage Weil { 442*de57606cSSage Weil ino_t ino = (ino_t)vino.ino; /* ^ (vino.snap << 20); */ 443*de57606cSSage Weil #if BITS_PER_LONG == 32 444*de57606cSSage Weil ino ^= vino.ino >> (sizeof(u64)-sizeof(ino_t)) * 8; 445*de57606cSSage Weil if (!ino) 446*de57606cSSage Weil ino = 1; 447*de57606cSSage Weil #endif 448*de57606cSSage Weil return ino; 449*de57606cSSage Weil } 450*de57606cSSage Weil 451*de57606cSSage Weil static inline int ceph_set_ino_cb(struct inode *inode, void *data) 452*de57606cSSage Weil { 453*de57606cSSage Weil ceph_inode(inode)->i_vino = *(struct ceph_vino *)data; 454*de57606cSSage Weil inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data); 455*de57606cSSage Weil return 0; 456*de57606cSSage Weil } 457*de57606cSSage Weil 458*de57606cSSage Weil static inline struct ceph_vino ceph_vino(struct inode *inode) 459*de57606cSSage Weil { 460*de57606cSSage Weil return ceph_inode(inode)->i_vino; 461*de57606cSSage Weil } 462*de57606cSSage Weil 463*de57606cSSage Weil /* for printf-style formatting */ 464*de57606cSSage Weil #define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap 465*de57606cSSage Weil 466*de57606cSSage Weil static inline u64 ceph_ino(struct inode *inode) 467*de57606cSSage Weil { 468*de57606cSSage Weil return ceph_inode(inode)->i_vino.ino; 469*de57606cSSage Weil } 470*de57606cSSage Weil static inline u64 ceph_snap(struct inode *inode) 471*de57606cSSage Weil { 472*de57606cSSage Weil return ceph_inode(inode)->i_vino.snap; 473*de57606cSSage Weil } 474*de57606cSSage Weil 475*de57606cSSage Weil static inline int ceph_ino_compare(struct inode *inode, void *data) 476*de57606cSSage Weil { 477*de57606cSSage Weil struct ceph_vino *pvino = (struct ceph_vino *)data; 478*de57606cSSage Weil struct ceph_inode_info *ci = ceph_inode(inode); 479*de57606cSSage Weil return ci->i_vino.ino == pvino->ino && 480*de57606cSSage Weil ci->i_vino.snap == pvino->snap; 481*de57606cSSage Weil } 482*de57606cSSage Weil 483*de57606cSSage Weil static inline struct inode *ceph_find_inode(struct super_block *sb, 484*de57606cSSage Weil struct ceph_vino vino) 485*de57606cSSage Weil { 486*de57606cSSage Weil ino_t t = ceph_vino_to_ino(vino); 487*de57606cSSage Weil return ilookup5(sb, t, ceph_ino_compare, &vino); 488*de57606cSSage Weil } 489*de57606cSSage Weil 490*de57606cSSage Weil 491*de57606cSSage Weil /* 492*de57606cSSage Weil * caps helpers 493*de57606cSSage Weil */ 494*de57606cSSage Weil static inline bool __ceph_is_any_real_caps(struct ceph_inode_info *ci) 495*de57606cSSage Weil { 496*de57606cSSage Weil return !RB_EMPTY_ROOT(&ci->i_caps); 497*de57606cSSage Weil } 498*de57606cSSage Weil 499*de57606cSSage Weil extern int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented); 500*de57606cSSage Weil extern int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int t); 501*de57606cSSage Weil extern int __ceph_caps_issued_other(struct ceph_inode_info *ci, 502*de57606cSSage Weil struct ceph_cap *cap); 503*de57606cSSage Weil 504*de57606cSSage Weil static inline int ceph_caps_issued(struct ceph_inode_info *ci) 505*de57606cSSage Weil { 506*de57606cSSage Weil int issued; 507*de57606cSSage Weil spin_lock(&ci->vfs_inode.i_lock); 508*de57606cSSage Weil issued = __ceph_caps_issued(ci, NULL); 509*de57606cSSage Weil spin_unlock(&ci->vfs_inode.i_lock); 510*de57606cSSage Weil return issued; 511*de57606cSSage Weil } 512*de57606cSSage Weil 513*de57606cSSage Weil static inline int ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, 514*de57606cSSage Weil int touch) 515*de57606cSSage Weil { 516*de57606cSSage Weil int r; 517*de57606cSSage Weil spin_lock(&ci->vfs_inode.i_lock); 518*de57606cSSage Weil r = __ceph_caps_issued_mask(ci, mask, touch); 519*de57606cSSage Weil spin_unlock(&ci->vfs_inode.i_lock); 520*de57606cSSage Weil return r; 521*de57606cSSage Weil } 522*de57606cSSage Weil 523*de57606cSSage Weil static inline int __ceph_caps_dirty(struct ceph_inode_info *ci) 524*de57606cSSage Weil { 525*de57606cSSage Weil return ci->i_dirty_caps | ci->i_flushing_caps; 526*de57606cSSage Weil } 527*de57606cSSage Weil extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); 528*de57606cSSage Weil 529*de57606cSSage Weil extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); 530*de57606cSSage Weil extern int __ceph_caps_used(struct ceph_inode_info *ci); 531*de57606cSSage Weil 532*de57606cSSage Weil extern int __ceph_caps_file_wanted(struct ceph_inode_info *ci); 533*de57606cSSage Weil 534*de57606cSSage Weil /* 535*de57606cSSage Weil * wanted, by virtue of open file modes AND cap refs (buffered/cached data) 536*de57606cSSage Weil */ 537*de57606cSSage Weil static inline int __ceph_caps_wanted(struct ceph_inode_info *ci) 538*de57606cSSage Weil { 539*de57606cSSage Weil int w = __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci); 540*de57606cSSage Weil if (w & CEPH_CAP_FILE_BUFFER) 541*de57606cSSage Weil w |= CEPH_CAP_FILE_EXCL; /* we want EXCL if dirty data */ 542*de57606cSSage Weil return w; 543*de57606cSSage Weil } 544*de57606cSSage Weil 545*de57606cSSage Weil /* what the mds thinks we want */ 546*de57606cSSage Weil extern int __ceph_caps_mds_wanted(struct ceph_inode_info *ci); 547*de57606cSSage Weil 548*de57606cSSage Weil extern void ceph_caps_init(void); 549*de57606cSSage Weil extern void ceph_caps_finalize(void); 550*de57606cSSage Weil extern int ceph_reserve_caps(struct ceph_cap_reservation *ctx, int need); 551*de57606cSSage Weil extern int ceph_unreserve_caps(struct ceph_cap_reservation *ctx); 552*de57606cSSage Weil extern void ceph_reservation_status(struct ceph_client *client, 553*de57606cSSage Weil int *total, int *avail, int *used, 554*de57606cSSage Weil int *reserved); 555*de57606cSSage Weil 556*de57606cSSage Weil static inline struct ceph_client *ceph_inode_to_client(struct inode *inode) 557*de57606cSSage Weil { 558*de57606cSSage Weil return (struct ceph_client *)inode->i_sb->s_fs_info; 559*de57606cSSage Weil } 560*de57606cSSage Weil 561*de57606cSSage Weil static inline struct ceph_client *ceph_sb_to_client(struct super_block *sb) 562*de57606cSSage Weil { 563*de57606cSSage Weil return (struct ceph_client *)sb->s_fs_info; 564*de57606cSSage Weil } 565*de57606cSSage Weil 566*de57606cSSage Weil static inline int ceph_queue_writeback(struct inode *inode) 567*de57606cSSage Weil { 568*de57606cSSage Weil return queue_work(ceph_inode_to_client(inode)->wb_wq, 569*de57606cSSage Weil &ceph_inode(inode)->i_wb_work); 570*de57606cSSage Weil } 571*de57606cSSage Weil 572*de57606cSSage Weil static inline int ceph_queue_page_invalidation(struct inode *inode) 573*de57606cSSage Weil { 574*de57606cSSage Weil return queue_work(ceph_inode_to_client(inode)->pg_inv_wq, 575*de57606cSSage Weil &ceph_inode(inode)->i_pg_inv_work); 576*de57606cSSage Weil } 577*de57606cSSage Weil 578*de57606cSSage Weil 579*de57606cSSage Weil /* 580*de57606cSSage Weil * we keep buffered readdir results attached to file->private_data 581*de57606cSSage Weil */ 582*de57606cSSage Weil struct ceph_file_info { 583*de57606cSSage Weil int fmode; /* initialized on open */ 584*de57606cSSage Weil 585*de57606cSSage Weil /* readdir: position within the dir */ 586*de57606cSSage Weil u32 frag; 587*de57606cSSage Weil struct ceph_mds_request *last_readdir; 588*de57606cSSage Weil int at_end; 589*de57606cSSage Weil 590*de57606cSSage Weil /* readdir: position within a frag */ 591*de57606cSSage Weil unsigned offset; /* offset of last chunk, adjusted for . and .. */ 592*de57606cSSage Weil u64 next_offset; /* offset of next chunk (last_name's + 1) */ 593*de57606cSSage Weil char *last_name; /* last entry in previous chunk */ 594*de57606cSSage Weil struct dentry *dentry; /* next dentry (for dcache readdir) */ 595*de57606cSSage Weil unsigned long dir_release_count; 596*de57606cSSage Weil 597*de57606cSSage Weil /* used for -o dirstat read() on directory thing */ 598*de57606cSSage Weil char *dir_info; 599*de57606cSSage Weil int dir_info_len; 600*de57606cSSage Weil }; 601*de57606cSSage Weil 602*de57606cSSage Weil 603*de57606cSSage Weil 604*de57606cSSage Weil /* 605*de57606cSSage Weil * snapshots 606*de57606cSSage Weil */ 607*de57606cSSage Weil 608*de57606cSSage Weil /* 609*de57606cSSage Weil * A "snap context" is the set of existing snapshots when we 610*de57606cSSage Weil * write data. It is used by the OSD to guide its COW behavior. 611*de57606cSSage Weil * 612*de57606cSSage Weil * The ceph_snap_context is refcounted, and attached to each dirty 613*de57606cSSage Weil * page, indicating which context the dirty data belonged when it was 614*de57606cSSage Weil * dirtied. 615*de57606cSSage Weil */ 616*de57606cSSage Weil struct ceph_snap_context { 617*de57606cSSage Weil atomic_t nref; 618*de57606cSSage Weil u64 seq; 619*de57606cSSage Weil int num_snaps; 620*de57606cSSage Weil u64 snaps[]; 621*de57606cSSage Weil }; 622*de57606cSSage Weil 623*de57606cSSage Weil static inline struct ceph_snap_context * 624*de57606cSSage Weil ceph_get_snap_context(struct ceph_snap_context *sc) 625*de57606cSSage Weil { 626*de57606cSSage Weil /* 627*de57606cSSage Weil printk("get_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), 628*de57606cSSage Weil atomic_read(&sc->nref)+1); 629*de57606cSSage Weil */ 630*de57606cSSage Weil if (sc) 631*de57606cSSage Weil atomic_inc(&sc->nref); 632*de57606cSSage Weil return sc; 633*de57606cSSage Weil } 634*de57606cSSage Weil 635*de57606cSSage Weil static inline void ceph_put_snap_context(struct ceph_snap_context *sc) 636*de57606cSSage Weil { 637*de57606cSSage Weil if (!sc) 638*de57606cSSage Weil return; 639*de57606cSSage Weil /* 640*de57606cSSage Weil printk("put_snap_context %p %d -> %d\n", sc, atomic_read(&sc->nref), 641*de57606cSSage Weil atomic_read(&sc->nref)-1); 642*de57606cSSage Weil */ 643*de57606cSSage Weil if (atomic_dec_and_test(&sc->nref)) { 644*de57606cSSage Weil /*printk(" deleting snap_context %p\n", sc);*/ 645*de57606cSSage Weil kfree(sc); 646*de57606cSSage Weil } 647*de57606cSSage Weil } 648*de57606cSSage Weil 649*de57606cSSage Weil /* 650*de57606cSSage Weil * A "snap realm" describes a subset of the file hierarchy sharing 651*de57606cSSage Weil * the same set of snapshots that apply to it. The realms themselves 652*de57606cSSage Weil * are organized into a hierarchy, such that children inherit (some of) 653*de57606cSSage Weil * the snapshots of their parents. 654*de57606cSSage Weil * 655*de57606cSSage Weil * All inodes within the realm that have capabilities are linked into a 656*de57606cSSage Weil * per-realm list. 657*de57606cSSage Weil */ 658*de57606cSSage Weil struct ceph_snap_realm { 659*de57606cSSage Weil u64 ino; 660*de57606cSSage Weil atomic_t nref; 661*de57606cSSage Weil u64 created, seq; 662*de57606cSSage Weil u64 parent_ino; 663*de57606cSSage Weil u64 parent_since; /* snapid when our current parent became so */ 664*de57606cSSage Weil 665*de57606cSSage Weil u64 *prior_parent_snaps; /* snaps inherited from any parents we */ 666*de57606cSSage Weil int num_prior_parent_snaps; /* had prior to parent_since */ 667*de57606cSSage Weil u64 *snaps; /* snaps specific to this realm */ 668*de57606cSSage Weil int num_snaps; 669*de57606cSSage Weil 670*de57606cSSage Weil struct ceph_snap_realm *parent; 671*de57606cSSage Weil struct list_head children; /* list of child realms */ 672*de57606cSSage Weil struct list_head child_item; 673*de57606cSSage Weil 674*de57606cSSage Weil struct list_head empty_item; /* if i have ref==0 */ 675*de57606cSSage Weil 676*de57606cSSage Weil /* the current set of snaps for this realm */ 677*de57606cSSage Weil struct ceph_snap_context *cached_context; 678*de57606cSSage Weil 679*de57606cSSage Weil struct list_head inodes_with_caps; 680*de57606cSSage Weil spinlock_t inodes_with_caps_lock; 681*de57606cSSage Weil }; 682*de57606cSSage Weil 683*de57606cSSage Weil 684*de57606cSSage Weil 685*de57606cSSage Weil /* 686*de57606cSSage Weil * calculate the number of pages a given length and offset map onto, 687*de57606cSSage Weil * if we align the data. 688*de57606cSSage Weil */ 689*de57606cSSage Weil static inline int calc_pages_for(u64 off, u64 len) 690*de57606cSSage Weil { 691*de57606cSSage Weil return ((off+len+PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT) - 692*de57606cSSage Weil (off >> PAGE_CACHE_SHIFT); 693*de57606cSSage Weil } 694*de57606cSSage Weil 695*de57606cSSage Weil 696*de57606cSSage Weil 697*de57606cSSage Weil /* snap.c */ 698*de57606cSSage Weil struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, 699*de57606cSSage Weil u64 ino); 700*de57606cSSage Weil extern void ceph_get_snap_realm(struct ceph_mds_client *mdsc, 701*de57606cSSage Weil struct ceph_snap_realm *realm); 702*de57606cSSage Weil extern void ceph_put_snap_realm(struct ceph_mds_client *mdsc, 703*de57606cSSage Weil struct ceph_snap_realm *realm); 704*de57606cSSage Weil extern int ceph_update_snap_trace(struct ceph_mds_client *m, 705*de57606cSSage Weil void *p, void *e, bool deletion); 706*de57606cSSage Weil extern void ceph_handle_snap(struct ceph_mds_client *mdsc, 707*de57606cSSage Weil struct ceph_msg *msg); 708*de57606cSSage Weil extern void ceph_queue_cap_snap(struct ceph_inode_info *ci, 709*de57606cSSage Weil struct ceph_snap_context *snapc); 710*de57606cSSage Weil extern int __ceph_finish_cap_snap(struct ceph_inode_info *ci, 711*de57606cSSage Weil struct ceph_cap_snap *capsnap); 712*de57606cSSage Weil extern void ceph_cleanup_empty_realms(struct ceph_mds_client *mdsc); 713*de57606cSSage Weil 714*de57606cSSage Weil /* 715*de57606cSSage Weil * a cap_snap is "pending" if it is still awaiting an in-progress 716*de57606cSSage Weil * sync write (that may/may not still update size, mtime, etc.). 717*de57606cSSage Weil */ 718*de57606cSSage Weil static inline bool __ceph_have_pending_cap_snap(struct ceph_inode_info *ci) 719*de57606cSSage Weil { 720*de57606cSSage Weil return !list_empty(&ci->i_cap_snaps) && 721*de57606cSSage Weil list_entry(ci->i_cap_snaps.prev, struct ceph_cap_snap, 722*de57606cSSage Weil ci_item)->writing; 723*de57606cSSage Weil } 724*de57606cSSage Weil 725*de57606cSSage Weil 726*de57606cSSage Weil /* super.c */ 727*de57606cSSage Weil extern struct kmem_cache *ceph_inode_cachep; 728*de57606cSSage Weil extern struct kmem_cache *ceph_cap_cachep; 729*de57606cSSage Weil extern struct kmem_cache *ceph_dentry_cachep; 730*de57606cSSage Weil extern struct kmem_cache *ceph_file_cachep; 731*de57606cSSage Weil 732*de57606cSSage Weil extern const char *ceph_msg_type_name(int type); 733*de57606cSSage Weil 734*de57606cSSage Weil #define FSID_FORMAT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" \ 735*de57606cSSage Weil "%02x%02x%02x%02x%02x%02x" 736*de57606cSSage Weil #define PR_FSID(f) (f)->fsid[0], (f)->fsid[1], (f)->fsid[2], (f)->fsid[3], \ 737*de57606cSSage Weil (f)->fsid[4], (f)->fsid[5], (f)->fsid[6], (f)->fsid[7], \ 738*de57606cSSage Weil (f)->fsid[8], (f)->fsid[9], (f)->fsid[10], (f)->fsid[11], \ 739*de57606cSSage Weil (f)->fsid[12], (f)->fsid[13], (f)->fsid[14], (f)->fsid[15] 740*de57606cSSage Weil 741*de57606cSSage Weil /* inode.c */ 742*de57606cSSage Weil extern const struct inode_operations ceph_file_iops; 743*de57606cSSage Weil 744*de57606cSSage Weil extern struct inode *ceph_alloc_inode(struct super_block *sb); 745*de57606cSSage Weil extern void ceph_destroy_inode(struct inode *inode); 746*de57606cSSage Weil 747*de57606cSSage Weil extern struct inode *ceph_get_inode(struct super_block *sb, 748*de57606cSSage Weil struct ceph_vino vino); 749*de57606cSSage Weil extern struct inode *ceph_get_snapdir(struct inode *parent); 750*de57606cSSage Weil extern int ceph_fill_file_size(struct inode *inode, int issued, 751*de57606cSSage Weil u32 truncate_seq, u64 truncate_size, u64 size); 752*de57606cSSage Weil extern void ceph_fill_file_time(struct inode *inode, int issued, 753*de57606cSSage Weil u64 time_warp_seq, struct timespec *ctime, 754*de57606cSSage Weil struct timespec *mtime, struct timespec *atime); 755*de57606cSSage Weil extern int ceph_fill_trace(struct super_block *sb, 756*de57606cSSage Weil struct ceph_mds_request *req, 757*de57606cSSage Weil struct ceph_mds_session *session); 758*de57606cSSage Weil extern int ceph_readdir_prepopulate(struct ceph_mds_request *req, 759*de57606cSSage Weil struct ceph_mds_session *session); 760*de57606cSSage Weil 761*de57606cSSage Weil extern int ceph_inode_holds_cap(struct inode *inode, int mask); 762*de57606cSSage Weil 763*de57606cSSage Weil extern int ceph_inode_set_size(struct inode *inode, loff_t size); 764*de57606cSSage Weil extern void ceph_inode_writeback(struct work_struct *work); 765*de57606cSSage Weil extern void ceph_vmtruncate_work(struct work_struct *work); 766*de57606cSSage Weil extern void __ceph_do_pending_vmtruncate(struct inode *inode); 767*de57606cSSage Weil extern void __ceph_queue_vmtruncate(struct inode *inode); 768*de57606cSSage Weil 769*de57606cSSage Weil extern int ceph_do_getattr(struct inode *inode, int mask); 770*de57606cSSage Weil extern int ceph_permission(struct inode *inode, int mask); 771*de57606cSSage Weil extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); 772*de57606cSSage Weil extern int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry, 773*de57606cSSage Weil struct kstat *stat); 774*de57606cSSage Weil 775*de57606cSSage Weil /* xattr.c */ 776*de57606cSSage Weil extern int ceph_setxattr(struct dentry *, const char *, const void *, 777*de57606cSSage Weil size_t, int); 778*de57606cSSage Weil extern ssize_t ceph_getxattr(struct dentry *, const char *, void *, size_t); 779*de57606cSSage Weil extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); 780*de57606cSSage Weil extern int ceph_removexattr(struct dentry *, const char *); 781*de57606cSSage Weil extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); 782*de57606cSSage Weil extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); 783*de57606cSSage Weil 784*de57606cSSage Weil /* caps.c */ 785*de57606cSSage Weil extern const char *ceph_cap_string(int c); 786*de57606cSSage Weil extern void ceph_handle_caps(struct ceph_mds_session *session, 787*de57606cSSage Weil struct ceph_msg *msg); 788*de57606cSSage Weil extern int ceph_add_cap(struct inode *inode, 789*de57606cSSage Weil struct ceph_mds_session *session, u64 cap_id, 790*de57606cSSage Weil int fmode, unsigned issued, unsigned wanted, 791*de57606cSSage Weil unsigned cap, unsigned seq, u64 realmino, int flags, 792*de57606cSSage Weil struct ceph_cap_reservation *caps_reservation); 793*de57606cSSage Weil extern void __ceph_remove_cap(struct ceph_cap *cap, 794*de57606cSSage Weil struct ceph_cap_reservation *ctx); 795*de57606cSSage Weil static inline void ceph_remove_cap(struct ceph_cap *cap) 796*de57606cSSage Weil { 797*de57606cSSage Weil struct inode *inode = &cap->ci->vfs_inode; 798*de57606cSSage Weil spin_lock(&inode->i_lock); 799*de57606cSSage Weil __ceph_remove_cap(cap, NULL); 800*de57606cSSage Weil spin_unlock(&inode->i_lock); 801*de57606cSSage Weil } 802*de57606cSSage Weil 803*de57606cSSage Weil extern void ceph_queue_caps_release(struct inode *inode); 804*de57606cSSage Weil extern int ceph_write_inode(struct inode *inode, int unused); 805*de57606cSSage Weil extern int ceph_fsync(struct file *file, struct dentry *dentry, int datasync); 806*de57606cSSage Weil extern void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, 807*de57606cSSage Weil struct ceph_mds_session *session); 808*de57606cSSage Weil extern int ceph_get_cap_mds(struct inode *inode); 809*de57606cSSage Weil extern void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps); 810*de57606cSSage Weil extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); 811*de57606cSSage Weil extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr, 812*de57606cSSage Weil struct ceph_snap_context *snapc); 813*de57606cSSage Weil extern void __ceph_flush_snaps(struct ceph_inode_info *ci, 814*de57606cSSage Weil struct ceph_mds_session **psession); 815*de57606cSSage Weil extern void ceph_check_caps(struct ceph_inode_info *ci, int flags, 816*de57606cSSage Weil struct ceph_mds_session *session); 817*de57606cSSage Weil extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc, 818*de57606cSSage Weil int flushdirty); 819*de57606cSSage Weil 820*de57606cSSage Weil extern int ceph_encode_inode_release(void **p, struct inode *inode, 821*de57606cSSage Weil int mds, int drop, int unless, int force); 822*de57606cSSage Weil extern int ceph_encode_dentry_release(void **p, struct dentry *dn, 823*de57606cSSage Weil int mds, int drop, int unless); 824*de57606cSSage Weil 825*de57606cSSage Weil extern int ceph_get_caps(struct ceph_inode_info *ci, int need, int want, 826*de57606cSSage Weil int *got, loff_t endoff); 827*de57606cSSage Weil 828*de57606cSSage Weil /* for counting open files by mode */ 829*de57606cSSage Weil static inline void __ceph_get_fmode(struct ceph_inode_info *ci, int mode) 830*de57606cSSage Weil { 831*de57606cSSage Weil ci->i_nr_by_mode[mode]++; 832*de57606cSSage Weil } 833*de57606cSSage Weil extern void ceph_put_fmode(struct ceph_inode_info *ci, int mode); 834*de57606cSSage Weil 835*de57606cSSage Weil /* addr.c */ 836*de57606cSSage Weil extern const struct address_space_operations ceph_aops; 837*de57606cSSage Weil extern int ceph_mmap(struct file *file, struct vm_area_struct *vma); 838*de57606cSSage Weil 839*de57606cSSage Weil /* file.c */ 840*de57606cSSage Weil extern const struct file_operations ceph_file_fops; 841*de57606cSSage Weil extern const struct address_space_operations ceph_aops; 842*de57606cSSage Weil extern int ceph_open(struct inode *inode, struct file *file); 843*de57606cSSage Weil extern struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, 844*de57606cSSage Weil struct nameidata *nd, int mode, 845*de57606cSSage Weil int locked_dir); 846*de57606cSSage Weil extern int ceph_release(struct inode *inode, struct file *filp); 847*de57606cSSage Weil extern void ceph_release_page_vector(struct page **pages, int num_pages); 848*de57606cSSage Weil 849*de57606cSSage Weil /* dir.c */ 850*de57606cSSage Weil extern const struct file_operations ceph_dir_fops; 851*de57606cSSage Weil extern const struct inode_operations ceph_dir_iops; 852*de57606cSSage Weil extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops, 853*de57606cSSage Weil ceph_snapdir_dentry_ops; 854*de57606cSSage Weil 855*de57606cSSage Weil extern int ceph_handle_notrace_create(struct inode *dir, struct dentry *dentry); 856*de57606cSSage Weil extern struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, 857*de57606cSSage Weil struct dentry *dentry, int err); 858*de57606cSSage Weil 859*de57606cSSage Weil extern void ceph_dentry_lru_add(struct dentry *dn); 860*de57606cSSage Weil extern void ceph_dentry_lru_touch(struct dentry *dn); 861*de57606cSSage Weil extern void ceph_dentry_lru_del(struct dentry *dn); 862*de57606cSSage Weil 863*de57606cSSage Weil /* 864*de57606cSSage Weil * our d_ops vary depending on whether the inode is live, 865*de57606cSSage Weil * snapshotted (read-only), or a virtual ".snap" directory. 866*de57606cSSage Weil */ 867*de57606cSSage Weil int ceph_init_dentry(struct dentry *dentry); 868*de57606cSSage Weil 869*de57606cSSage Weil 870*de57606cSSage Weil /* ioctl.c */ 871*de57606cSSage Weil extern long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 872*de57606cSSage Weil 873*de57606cSSage Weil /* export.c */ 874*de57606cSSage Weil extern const struct export_operations ceph_export_ops; 875*de57606cSSage Weil 876*de57606cSSage Weil /* debugfs.c */ 877*de57606cSSage Weil extern int ceph_debugfs_init(void); 878*de57606cSSage Weil extern void ceph_debugfs_cleanup(void); 879*de57606cSSage Weil extern int ceph_debugfs_client_init(struct ceph_client *client); 880*de57606cSSage Weil extern void ceph_debugfs_client_cleanup(struct ceph_client *client); 881*de57606cSSage Weil 882*de57606cSSage Weil static inline struct inode *get_dentry_parent_inode(struct dentry *dentry) 883*de57606cSSage Weil { 884*de57606cSSage Weil if (dentry && dentry->d_parent) 885*de57606cSSage Weil return dentry->d_parent->d_inode; 886*de57606cSSage Weil 887*de57606cSSage Weil return NULL; 888*de57606cSSage Weil } 889*de57606cSSage Weil 890*de57606cSSage Weil #endif /* _FS_CEPH_SUPER_H */ 891