1d8a5ba45SMiklos Szeredi /* 2d8a5ba45SMiklos Szeredi FUSE: Filesystem in Userspace 31729a16cSMiklos Szeredi Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu> 4d8a5ba45SMiklos Szeredi 5d8a5ba45SMiklos Szeredi This program can be distributed under the terms of the GNU GPL. 6d8a5ba45SMiklos Szeredi See the file COPYING. 7d8a5ba45SMiklos Szeredi */ 8d8a5ba45SMiklos Szeredi 929d434b3STejun Heo #ifndef _FS_FUSE_I_H 1029d434b3STejun Heo #define _FS_FUSE_I_H 1129d434b3STejun Heo 12f2294482SKirill Smelkov #ifndef pr_fmt 13f2294482SKirill Smelkov # define pr_fmt(fmt) "fuse: " fmt 14f2294482SKirill Smelkov #endif 15f2294482SKirill Smelkov 16d8a5ba45SMiklos Szeredi #include <linux/fuse.h> 17d8a5ba45SMiklos Szeredi #include <linux/fs.h> 1851eb01e7SMiklos Szeredi #include <linux/mount.h> 19d8a5ba45SMiklos Szeredi #include <linux/wait.h> 20d8a5ba45SMiklos Szeredi #include <linux/list.h> 21d8a5ba45SMiklos Szeredi #include <linux/spinlock.h> 22d8a5ba45SMiklos Szeredi #include <linux/mm.h> 23d8a5ba45SMiklos Szeredi #include <linux/backing-dev.h> 24bafa9654SMiklos Szeredi #include <linux/mutex.h> 253be5a52bSMiklos Szeredi #include <linux/rwsem.h> 2695668a69STejun Heo #include <linux/rbtree.h> 2795668a69STejun Heo #include <linux/poll.h> 285a18ec17SMiklos Szeredi #include <linux/workqueue.h> 29744742d6SSeth Forshee #include <linux/kref.h> 3060bcc88aSSeth Forshee #include <linux/xattr.h> 310b6e9ea0SSeth Forshee #include <linux/pid_namespace.h> 324e8c2eb5SElena Reshetova #include <linux/refcount.h> 338cb08329SEric W. Biederman #include <linux/user_namespace.h> 34d8a5ba45SMiklos Szeredi 355da784ccSConstantine Shulyupin /** Default max number of pages that can be used in a single read request */ 365da784ccSConstantine Shulyupin #define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32 375da784ccSConstantine Shulyupin 385da784ccSConstantine Shulyupin /** Maximum of max_pages received in init_out */ 395da784ccSConstantine Shulyupin #define FUSE_MAX_MAX_PAGES 256 40334f485dSMiklos Szeredi 413be5a52bSMiklos Szeredi /** Bias for fi->writectr, meaning new writepages must not be sent */ 423be5a52bSMiklos Szeredi #define FUSE_NOWRITE INT_MIN 433be5a52bSMiklos Szeredi 441d3d752bSMiklos Szeredi /** It could be as large as PATH_MAX, but would that have any uses? */ 451d3d752bSMiklos Szeredi #define FUSE_NAME_MAX 1024 461d3d752bSMiklos Szeredi 47bafa9654SMiklos Szeredi /** Number of dentries for each connection in the control filesystem */ 4879a9d994SCsaba Henk #define FUSE_CTL_NUM_DENTRIES 5 49bafa9654SMiklos Szeredi 50bafa9654SMiklos Szeredi /** List of active connections */ 51bafa9654SMiklos Szeredi extern struct list_head fuse_conn_list; 52bafa9654SMiklos Szeredi 53bafa9654SMiklos Szeredi /** Global mutex protecting fuse_conn_list and the control filesystem */ 54bafa9654SMiklos Szeredi extern struct mutex fuse_mutex; 55413ef8cbSMiklos Szeredi 5679a9d994SCsaba Henk /** Module parameters */ 5779a9d994SCsaba Henk extern unsigned max_user_bgreq; 5879a9d994SCsaba Henk extern unsigned max_user_congthresh; 5979a9d994SCsaba Henk 6007e77dcaSMiklos Szeredi /* One forget request */ 6107e77dcaSMiklos Szeredi struct fuse_forget_link { 6202c048b9SMiklos Szeredi struct fuse_forget_one forget_one; 6307e77dcaSMiklos Szeredi struct fuse_forget_link *next; 6407e77dcaSMiklos Szeredi }; 6507e77dcaSMiklos Szeredi 66*2939dd30SKrister Johansen /* Submount lookup tracking */ 67*2939dd30SKrister Johansen struct fuse_submount_lookup { 68*2939dd30SKrister Johansen /** Refcount */ 69*2939dd30SKrister Johansen refcount_t count; 70*2939dd30SKrister Johansen 71*2939dd30SKrister Johansen /** Unique ID, which identifies the inode between userspace 72*2939dd30SKrister Johansen * and kernel */ 73*2939dd30SKrister Johansen u64 nodeid; 74*2939dd30SKrister Johansen 75*2939dd30SKrister Johansen /** The request used for sending the FORGET message */ 76*2939dd30SKrister Johansen struct fuse_forget_link *forget; 77*2939dd30SKrister Johansen }; 78*2939dd30SKrister Johansen 79d8a5ba45SMiklos Szeredi /** FUSE inode */ 80d8a5ba45SMiklos Szeredi struct fuse_inode { 81d8a5ba45SMiklos Szeredi /** Inode data */ 82d8a5ba45SMiklos Szeredi struct inode inode; 83d8a5ba45SMiklos Szeredi 84d8a5ba45SMiklos Szeredi /** Unique ID, which identifies the inode between userspace 85d8a5ba45SMiklos Szeredi * and kernel */ 86d8a5ba45SMiklos Szeredi u64 nodeid; 87d8a5ba45SMiklos Szeredi 889e6268dbSMiklos Szeredi /** Number of lookups on this inode */ 899e6268dbSMiklos Szeredi u64 nlookup; 909e6268dbSMiklos Szeredi 91e5e5558eSMiklos Szeredi /** The request used for sending the FORGET message */ 9207e77dcaSMiklos Szeredi struct fuse_forget_link *forget; 93e5e5558eSMiklos Szeredi 94d8a5ba45SMiklos Szeredi /** Time in jiffies until the file attributes are valid */ 950a0898cfSMiklos Szeredi u64 i_time; 96ebc14c4dSMiklos Szeredi 972f1e8196SMiklos Szeredi /* Which attributes are invalid */ 982f1e8196SMiklos Szeredi u32 inval_mask; 992f1e8196SMiklos Szeredi 100ebc14c4dSMiklos Szeredi /** The sticky bit in inode->i_mode may have been removed, so 101ebc14c4dSMiklos Szeredi preserve the original mode */ 102541af6a0SAl Viro umode_t orig_i_mode; 1031fb69e78SMiklos Szeredi 104972f4c46SMiklos Szeredi /* Cache birthtime */ 105972f4c46SMiklos Szeredi struct timespec64 i_btime; 106972f4c46SMiklos Szeredi 10745c72cd7SPavel Shilovsky /** 64 bit inode number */ 10845c72cd7SPavel Shilovsky u64 orig_ino; 10945c72cd7SPavel Shilovsky 1101fb69e78SMiklos Szeredi /** Version of last attribute change */ 1111fb69e78SMiklos Szeredi u64 attr_version; 11293a8c3cdSMiklos Szeredi 113ab2257e9SMiklos Szeredi union { 114ab2257e9SMiklos Szeredi /* Write related fields (regular file only) */ 115ab2257e9SMiklos Szeredi struct { 116f15ecfefSKirill Tkhai /* Files usable in writepage. Protected by fi->lock */ 11793a8c3cdSMiklos Szeredi struct list_head write_files; 1183be5a52bSMiklos Szeredi 119ab2257e9SMiklos Szeredi /* Writepages pending on truncate or fsync */ 1203be5a52bSMiklos Szeredi struct list_head queued_writes; 1213be5a52bSMiklos Szeredi 122ab2257e9SMiklos Szeredi /* Number of sent writes, a negative bias 123ab2257e9SMiklos Szeredi * (FUSE_NOWRITE) means more writes are blocked */ 1243be5a52bSMiklos Szeredi int writectr; 1253be5a52bSMiklos Szeredi 126ab2257e9SMiklos Szeredi /* Waitq for writepage completion */ 1273be5a52bSMiklos Szeredi wait_queue_head_t page_waitq; 1283be5a52bSMiklos Szeredi 129ab2257e9SMiklos Szeredi /* List of writepage requestst (pending or sent) */ 1306b2fb799SMaxim Patlasov struct rb_root writepages; 131ab2257e9SMiklos Szeredi }; 1324582a4abSFeng Shuo 133ab2257e9SMiklos Szeredi /* readdir cache (directory only) */ 13469e34551SMiklos Szeredi struct { 13569e34551SMiklos Szeredi /* true if fully cached */ 13669e34551SMiklos Szeredi bool cached; 13769e34551SMiklos Szeredi 13869e34551SMiklos Szeredi /* size of cache */ 13969e34551SMiklos Szeredi loff_t size; 14069e34551SMiklos Szeredi 14169e34551SMiklos Szeredi /* position at end of cache (position of next entry) */ 14269e34551SMiklos Szeredi loff_t pos; 14369e34551SMiklos Szeredi 1443494927eSMiklos Szeredi /* version of the cache */ 1453494927eSMiklos Szeredi u64 version; 1463494927eSMiklos Szeredi 147ab2257e9SMiklos Szeredi /* modification time of directory when cache was 148ab2257e9SMiklos Szeredi * started */ 1497118883bSMiklos Szeredi struct timespec64 mtime; 1507118883bSMiklos Szeredi 151261aaba7SMiklos Szeredi /* iversion of directory when cache was started */ 152261aaba7SMiklos Szeredi u64 iversion; 153261aaba7SMiklos Szeredi 15469e34551SMiklos Szeredi /* protects above fields */ 15569e34551SMiklos Szeredi spinlock_t lock; 15669e34551SMiklos Szeredi } rdc; 157ab2257e9SMiklos Szeredi }; 15869e34551SMiklos Szeredi 1594582a4abSFeng Shuo /** Miscellaneous bits describing inode state */ 1604582a4abSFeng Shuo unsigned long state; 1615c672ab3SMiklos Szeredi 1625c672ab3SMiklos Szeredi /** Lock for serializing lookup and readdir for back compatibility*/ 1635c672ab3SMiklos Szeredi struct mutex mutex; 164f15ecfefSKirill Tkhai 165f15ecfefSKirill Tkhai /** Lock to protect write related fields */ 166f15ecfefSKirill Tkhai spinlock_t lock; 167c2d0ad00SVivek Goyal 168c2d0ad00SVivek Goyal #ifdef CONFIG_FUSE_DAX 169c2d0ad00SVivek Goyal /* 170c2d0ad00SVivek Goyal * Dax specific inode data 171c2d0ad00SVivek Goyal */ 172c2d0ad00SVivek Goyal struct fuse_inode_dax *dax; 173c2d0ad00SVivek Goyal #endif 174*2939dd30SKrister Johansen /** Submount specific lookup tracking */ 175*2939dd30SKrister Johansen struct fuse_submount_lookup *submount_lookup; 1764582a4abSFeng Shuo }; 1774582a4abSFeng Shuo 1784582a4abSFeng Shuo /** FUSE inode state bits */ 1794582a4abSFeng Shuo enum { 1804582a4abSFeng Shuo /** Advise readdirplus */ 1814582a4abSFeng Shuo FUSE_I_ADVISE_RDPLUS, 1826314efeeSMiklos Szeredi /** Initialized with readdirplus */ 1836314efeeSMiklos Szeredi FUSE_I_INIT_RDPLUS, 18406a7c3c2SMaxim Patlasov /** An operation changing file size is in progress */ 18506a7c3c2SMaxim Patlasov FUSE_I_SIZE_UNSTABLE, 1865d069dbeSMiklos Szeredi /* Bad inode */ 1875d069dbeSMiklos Szeredi FUSE_I_BAD, 188972f4c46SMiklos Szeredi /* Has btime */ 189972f4c46SMiklos Szeredi FUSE_I_BTIME, 190d8a5ba45SMiklos Szeredi }; 191d8a5ba45SMiklos Szeredi 192da5e4714SMiklos Szeredi struct fuse_conn; 193fcee216bSMax Reitz struct fuse_mount; 1944cb54866SMiklos Szeredi struct fuse_release_args; 195da5e4714SMiklos Szeredi 196b6aeadedSMiklos Szeredi /** FUSE specific file data */ 197b6aeadedSMiklos Szeredi struct fuse_file { 198da5e4714SMiklos Szeredi /** Fuse connection for this file */ 199fcee216bSMax Reitz struct fuse_mount *fm; 200da5e4714SMiklos Szeredi 2014cb54866SMiklos Szeredi /* Argument space reserved for release */ 2024cb54866SMiklos Szeredi struct fuse_release_args *release_args; 203b6aeadedSMiklos Szeredi 204acf99433STejun Heo /** Kernel file handle guaranteed to be unique */ 205acf99433STejun Heo u64 kh; 206acf99433STejun Heo 207b6aeadedSMiklos Szeredi /** File handle used by userspace */ 208b6aeadedSMiklos Szeredi u64 fh; 209c756e0a4SMiklos Szeredi 210da5e4714SMiklos Szeredi /** Node id of this file */ 211da5e4714SMiklos Szeredi u64 nodeid; 212da5e4714SMiklos Szeredi 213c756e0a4SMiklos Szeredi /** Refcount */ 2144e8c2eb5SElena Reshetova refcount_t count; 21593a8c3cdSMiklos Szeredi 216c7b7143cSMiklos Szeredi /** FOPEN_* flags returned by open */ 217c7b7143cSMiklos Szeredi u32 open_flags; 218c7b7143cSMiklos Szeredi 21993a8c3cdSMiklos Szeredi /** Entry on inode's write_files list */ 22093a8c3cdSMiklos Szeredi struct list_head write_entry; 22195668a69STejun Heo 2225d7bc7e8SMiklos Szeredi /* Readdir related */ 2235d7bc7e8SMiklos Szeredi struct { 2245d7bc7e8SMiklos Szeredi /* 2255d7bc7e8SMiklos Szeredi * Protects below fields against (crazy) parallel readdir on 2265d7bc7e8SMiklos Szeredi * same open file. Uncontended in the normal case. 2275d7bc7e8SMiklos Szeredi */ 2285d7bc7e8SMiklos Szeredi struct mutex lock; 2295d7bc7e8SMiklos Szeredi 2305d7bc7e8SMiklos Szeredi /* Dir stream position */ 2315d7bc7e8SMiklos Szeredi loff_t pos; 2325d7bc7e8SMiklos Szeredi 2335d7bc7e8SMiklos Szeredi /* Offset in cache */ 2345d7bc7e8SMiklos Szeredi loff_t cache_off; 2353494927eSMiklos Szeredi 2363494927eSMiklos Szeredi /* Version of cache we are reading */ 2373494927eSMiklos Szeredi u64 version; 2383494927eSMiklos Szeredi 2395d7bc7e8SMiklos Szeredi } readdir; 2405d7bc7e8SMiklos Szeredi 24195668a69STejun Heo /** RB node to be linked on fuse_conn->polled_files */ 24295668a69STejun Heo struct rb_node polled_node; 24395668a69STejun Heo 24495668a69STejun Heo /** Wait queue head for poll */ 24595668a69STejun Heo wait_queue_head_t poll_wait; 24637fb3a30SMiklos Szeredi 24737fb3a30SMiklos Szeredi /** Has flock been performed on this file? */ 24837fb3a30SMiklos Szeredi bool flock:1; 249b6aeadedSMiklos Szeredi }; 250b6aeadedSMiklos Szeredi 251334f485dSMiklos Szeredi /** One input argument of a request */ 252334f485dSMiklos Szeredi struct fuse_in_arg { 253334f485dSMiklos Szeredi unsigned size; 254334f485dSMiklos Szeredi const void *value; 255334f485dSMiklos Szeredi }; 256334f485dSMiklos Szeredi 257334f485dSMiklos Szeredi /** One output argument of a request */ 258334f485dSMiklos Szeredi struct fuse_arg { 259334f485dSMiklos Szeredi unsigned size; 260334f485dSMiklos Szeredi void *value; 261334f485dSMiklos Szeredi }; 262334f485dSMiklos Szeredi 263b2430d75SMaxim Patlasov /** FUSE page descriptor */ 264b2430d75SMaxim Patlasov struct fuse_page_desc { 265b2430d75SMaxim Patlasov unsigned int length; 266b2430d75SMaxim Patlasov unsigned int offset; 267b2430d75SMaxim Patlasov }; 268b2430d75SMaxim Patlasov 2697078187aSMiklos Szeredi struct fuse_args { 2707078187aSMiklos Szeredi uint64_t nodeid; 2711f4e9d03SMiklos Szeredi uint32_t opcode; 27215d937d7SMiklos Szeredi uint8_t in_numargs; 27315d937d7SMiklos Szeredi uint8_t out_numargs; 27415d937d7SMiklos Szeredi uint8_t ext_idx; 275c500ebaaSMiklos Szeredi bool force:1; 276454a7613SMiklos Szeredi bool noreply:1; 277e413754bSMiklos Szeredi bool nocreds:1; 27868583165SMiklos Szeredi bool in_pages:1; 27968583165SMiklos Szeredi bool out_pages:1; 2800c4bcfdeSMiklos Szeredi bool user_pages:1; 2811f4e9d03SMiklos Szeredi bool out_argvar:1; 28268583165SMiklos Szeredi bool page_zeroing:1; 28368583165SMiklos Szeredi bool page_replace:1; 284bb737bbeSVivek Goyal bool may_block:1; 28515d937d7SMiklos Szeredi bool is_ext:1; 286d5b48543SMiklos Szeredi struct fuse_in_arg in_args[3]; 287d5b48543SMiklos Szeredi struct fuse_arg out_args[2]; 288fcee216bSMax Reitz void (*end)(struct fuse_mount *fm, struct fuse_args *args, int error); 2897078187aSMiklos Szeredi }; 2907078187aSMiklos Szeredi 29168583165SMiklos Szeredi struct fuse_args_pages { 29268583165SMiklos Szeredi struct fuse_args args; 29368583165SMiklos Szeredi struct page **pages; 29468583165SMiklos Szeredi struct fuse_page_desc *descs; 29568583165SMiklos Szeredi unsigned int num_pages; 29668583165SMiklos Szeredi }; 29768583165SMiklos Szeredi 2987078187aSMiklos Szeredi #define FUSE_ARGS(args) struct fuse_args args = {} 2997078187aSMiklos Szeredi 30001e9d11aSMaxim Patlasov /** The request IO state (for asynchronous processing) */ 30101e9d11aSMaxim Patlasov struct fuse_io_priv { 302744742d6SSeth Forshee struct kref refcnt; 30301e9d11aSMaxim Patlasov int async; 30401e9d11aSMaxim Patlasov spinlock_t lock; 30501e9d11aSMaxim Patlasov unsigned reqs; 30601e9d11aSMaxim Patlasov ssize_t bytes; 30701e9d11aSMaxim Patlasov size_t size; 30801e9d11aSMaxim Patlasov __u64 offset; 30901e9d11aSMaxim Patlasov bool write; 31061c12b49SAshish Samant bool should_dirty; 31101e9d11aSMaxim Patlasov int err; 31201e9d11aSMaxim Patlasov struct kiocb *iocb; 3139d5722b7SChristoph Hellwig struct completion *done; 3147879c4e5SAshish Sangwan bool blocking; 31501e9d11aSMaxim Patlasov }; 31601e9d11aSMaxim Patlasov 317e1c0eecbSMiklos Szeredi #define FUSE_IO_PRIV_SYNC(i) \ 318744742d6SSeth Forshee { \ 3191e24edcaSPeter Zijlstra .refcnt = KREF_INIT(1), \ 320744742d6SSeth Forshee .async = 0, \ 321e1c0eecbSMiklos Szeredi .iocb = i, \ 322744742d6SSeth Forshee } 323744742d6SSeth Forshee 324334f485dSMiklos Szeredi /** 325825d6d33SMiklos Szeredi * Request flags 326825d6d33SMiklos Szeredi * 327825d6d33SMiklos Szeredi * FR_ISREPLY: set if the request has reply 328825d6d33SMiklos Szeredi * FR_FORCE: force sending of the request even if interrupted 329825d6d33SMiklos Szeredi * FR_BACKGROUND: request is sent in the background 330825d6d33SMiklos Szeredi * FR_WAITING: request is counted as "waiting" 331825d6d33SMiklos Szeredi * FR_ABORTED: the request was aborted 332825d6d33SMiklos Szeredi * FR_INTERRUPTED: the request has been interrupted 333825d6d33SMiklos Szeredi * FR_LOCKED: data is being copied to/from the request 33433e14b4dSMiklos Szeredi * FR_PENDING: request is not yet in userspace 33533e14b4dSMiklos Szeredi * FR_SENT: request is in userspace, waiting for an answer 33633e14b4dSMiklos Szeredi * FR_FINISHED: request is finished 33777cd9d48SMiklos Szeredi * FR_PRIVATE: request is on private list 3383e8cb8b2SMiklos Szeredi * FR_ASYNC: request is asynchronous 339825d6d33SMiklos Szeredi */ 340825d6d33SMiklos Szeredi enum fuse_req_flag { 341825d6d33SMiklos Szeredi FR_ISREPLY, 342825d6d33SMiklos Szeredi FR_FORCE, 343825d6d33SMiklos Szeredi FR_BACKGROUND, 344825d6d33SMiklos Szeredi FR_WAITING, 345825d6d33SMiklos Szeredi FR_ABORTED, 346825d6d33SMiklos Szeredi FR_INTERRUPTED, 347825d6d33SMiklos Szeredi FR_LOCKED, 34833e14b4dSMiklos Szeredi FR_PENDING, 34933e14b4dSMiklos Szeredi FR_SENT, 35033e14b4dSMiklos Szeredi FR_FINISHED, 35177cd9d48SMiklos Szeredi FR_PRIVATE, 3523e8cb8b2SMiklos Szeredi FR_ASYNC, 353825d6d33SMiklos Szeredi }; 354825d6d33SMiklos Szeredi 355825d6d33SMiklos Szeredi /** 356334f485dSMiklos Szeredi * A request to the client 357dc00809aSMiklos Szeredi * 358dc00809aSMiklos Szeredi * .waitq.lock protects the following fields: 359dc00809aSMiklos Szeredi * - FR_ABORTED 360dc00809aSMiklos Szeredi * - FR_LOCKED (may also be modified under fc->lock, tested under both) 361334f485dSMiklos Szeredi */ 362334f485dSMiklos Szeredi struct fuse_req { 363ce1d5a49SMiklos Szeredi /** This can be on either pending processing or io lists in 364ce1d5a49SMiklos Szeredi fuse_conn */ 365334f485dSMiklos Szeredi struct list_head list; 366334f485dSMiklos Szeredi 367a4d27e75SMiklos Szeredi /** Entry on the interrupts list */ 368a4d27e75SMiklos Szeredi struct list_head intr_entry; 369a4d27e75SMiklos Szeredi 37012597287SMiklos Szeredi /* Input/output arguments */ 37112597287SMiklos Szeredi struct fuse_args *args; 37212597287SMiklos Szeredi 373334f485dSMiklos Szeredi /** refcount */ 374ec99f6d3SElena Reshetova refcount_t count; 375334f485dSMiklos Szeredi 376825d6d33SMiklos Szeredi /* Request flags, updated with test/set/clear_bit() */ 377825d6d33SMiklos Szeredi unsigned long flags; 3789bc5dddaSMiklos Szeredi 379d4993774SMiklos Szeredi /* The request input header */ 380d4993774SMiklos Szeredi struct { 381d4993774SMiklos Szeredi struct fuse_in_header h; 382d4993774SMiklos Szeredi } in; 383334f485dSMiklos Szeredi 384d4993774SMiklos Szeredi /* The request output header */ 385d4993774SMiklos Szeredi struct { 386d4993774SMiklos Szeredi struct fuse_out_header h; 387d4993774SMiklos Szeredi } out; 388334f485dSMiklos Szeredi 389334f485dSMiklos Szeredi /** Used to wake up the task waiting for completion of request*/ 390334f485dSMiklos Szeredi wait_queue_head_t waitq; 391334f485dSMiklos Szeredi 392a62a8ef9SStefan Hajnoczi #if IS_ENABLED(CONFIG_VIRTIO_FS) 393a62a8ef9SStefan Hajnoczi /** virtio-fs's physically contiguous buffer for in and out args */ 394a62a8ef9SStefan Hajnoczi void *argbuf; 395a62a8ef9SStefan Hajnoczi #endif 39624754db2SMax Reitz 397fcee216bSMax Reitz /** fuse_mount this request belongs to */ 398fcee216bSMax Reitz struct fuse_mount *fm; 399334f485dSMiklos Szeredi }; 400334f485dSMiklos Szeredi 401ae3aad77SStefan Hajnoczi struct fuse_iqueue; 402ae3aad77SStefan Hajnoczi 403ae3aad77SStefan Hajnoczi /** 404ae3aad77SStefan Hajnoczi * Input queue callbacks 405ae3aad77SStefan Hajnoczi * 406ae3aad77SStefan Hajnoczi * Input queue signalling is device-specific. For example, the /dev/fuse file 407ae3aad77SStefan Hajnoczi * uses fiq->waitq and fasync to wake processes that are waiting on queue 408ae3aad77SStefan Hajnoczi * readiness. These callbacks allow other device types to respond to input 409ae3aad77SStefan Hajnoczi * queue activity. 410ae3aad77SStefan Hajnoczi */ 411ae3aad77SStefan Hajnoczi struct fuse_iqueue_ops { 412ae3aad77SStefan Hajnoczi /** 413ae3aad77SStefan Hajnoczi * Signal that a forget has been queued 414ae3aad77SStefan Hajnoczi */ 415ae3aad77SStefan Hajnoczi void (*wake_forget_and_unlock)(struct fuse_iqueue *fiq) 416ae3aad77SStefan Hajnoczi __releases(fiq->lock); 417ae3aad77SStefan Hajnoczi 418ae3aad77SStefan Hajnoczi /** 419ae3aad77SStefan Hajnoczi * Signal that an INTERRUPT request has been queued 420ae3aad77SStefan Hajnoczi */ 421ae3aad77SStefan Hajnoczi void (*wake_interrupt_and_unlock)(struct fuse_iqueue *fiq) 422ae3aad77SStefan Hajnoczi __releases(fiq->lock); 423ae3aad77SStefan Hajnoczi 424ae3aad77SStefan Hajnoczi /** 425ae3aad77SStefan Hajnoczi * Signal that a request has been queued 426ae3aad77SStefan Hajnoczi */ 427ae3aad77SStefan Hajnoczi void (*wake_pending_and_unlock)(struct fuse_iqueue *fiq) 428ae3aad77SStefan Hajnoczi __releases(fiq->lock); 429a62a8ef9SStefan Hajnoczi 430a62a8ef9SStefan Hajnoczi /** 431a62a8ef9SStefan Hajnoczi * Clean up when fuse_iqueue is destroyed 432a62a8ef9SStefan Hajnoczi */ 433a62a8ef9SStefan Hajnoczi void (*release)(struct fuse_iqueue *fiq); 434ae3aad77SStefan Hajnoczi }; 435ae3aad77SStefan Hajnoczi 436ae3aad77SStefan Hajnoczi /** /dev/fuse input queue operations */ 437ae3aad77SStefan Hajnoczi extern const struct fuse_iqueue_ops fuse_dev_fiq_ops; 438ae3aad77SStefan Hajnoczi 439f88996a9SMiklos Szeredi struct fuse_iqueue { 440e16714d8SMiklos Szeredi /** Connection established */ 441e16714d8SMiklos Szeredi unsigned connected; 442e16714d8SMiklos Szeredi 44376e43c8cSEric Biggers /** Lock protecting accesses to members of this structure */ 44476e43c8cSEric Biggers spinlock_t lock; 44576e43c8cSEric Biggers 446f88996a9SMiklos Szeredi /** Readers of the connection are waiting on this */ 447f88996a9SMiklos Szeredi wait_queue_head_t waitq; 448f88996a9SMiklos Szeredi 449f88996a9SMiklos Szeredi /** The next unique request id */ 450f88996a9SMiklos Szeredi u64 reqctr; 451f88996a9SMiklos Szeredi 452f88996a9SMiklos Szeredi /** The list of pending requests */ 453f88996a9SMiklos Szeredi struct list_head pending; 454f88996a9SMiklos Szeredi 455f88996a9SMiklos Szeredi /** Pending interrupts */ 456f88996a9SMiklos Szeredi struct list_head interrupts; 457f88996a9SMiklos Szeredi 458f88996a9SMiklos Szeredi /** Queue of pending forgets */ 459f88996a9SMiklos Szeredi struct fuse_forget_link forget_list_head; 460f88996a9SMiklos Szeredi struct fuse_forget_link *forget_list_tail; 461f88996a9SMiklos Szeredi 462f88996a9SMiklos Szeredi /** Batching of FORGET requests (positive indicates FORGET batch) */ 463f88996a9SMiklos Szeredi int forget_batch; 464f88996a9SMiklos Szeredi 465f88996a9SMiklos Szeredi /** O_ASYNC requests */ 466f88996a9SMiklos Szeredi struct fasync_struct *fasync; 467ae3aad77SStefan Hajnoczi 468ae3aad77SStefan Hajnoczi /** Device-specific callbacks */ 469ae3aad77SStefan Hajnoczi const struct fuse_iqueue_ops *ops; 470ae3aad77SStefan Hajnoczi 471ae3aad77SStefan Hajnoczi /** Device-specific state */ 472ae3aad77SStefan Hajnoczi void *priv; 473f88996a9SMiklos Szeredi }; 474f88996a9SMiklos Szeredi 475be2ff42cSKirill Tkhai #define FUSE_PQ_HASH_BITS 8 476be2ff42cSKirill Tkhai #define FUSE_PQ_HASH_SIZE (1 << FUSE_PQ_HASH_BITS) 477be2ff42cSKirill Tkhai 4783a2b5b9cSMiklos Szeredi struct fuse_pqueue { 479e96edd94SMiklos Szeredi /** Connection established */ 480e96edd94SMiklos Szeredi unsigned connected; 481e96edd94SMiklos Szeredi 48245a91cb1SMiklos Szeredi /** Lock protecting accessess to members of this structure */ 48345a91cb1SMiklos Szeredi spinlock_t lock; 48445a91cb1SMiklos Szeredi 485be2ff42cSKirill Tkhai /** Hash table of requests being processed */ 486be2ff42cSKirill Tkhai struct list_head *processing; 4873a2b5b9cSMiklos Szeredi 4883a2b5b9cSMiklos Szeredi /** The list of requests under I/O */ 4893a2b5b9cSMiklos Szeredi struct list_head io; 4903a2b5b9cSMiklos Szeredi }; 4913a2b5b9cSMiklos Szeredi 492d8a5ba45SMiklos Szeredi /** 493cc080e9eSMiklos Szeredi * Fuse device instance 494cc080e9eSMiklos Szeredi */ 495cc080e9eSMiklos Szeredi struct fuse_dev { 496cc080e9eSMiklos Szeredi /** Fuse connection for this device */ 497cc080e9eSMiklos Szeredi struct fuse_conn *fc; 498cc080e9eSMiklos Szeredi 499c3696046SMiklos Szeredi /** Processing queue */ 500c3696046SMiklos Szeredi struct fuse_pqueue pq; 501c3696046SMiklos Szeredi 502cc080e9eSMiklos Szeredi /** list entry on fc->devices */ 503cc080e9eSMiklos Szeredi struct list_head entry; 504cc080e9eSMiklos Szeredi }; 505cc080e9eSMiklos Szeredi 506780b1b95SJeffle Xu enum fuse_dax_mode { 507780b1b95SJeffle Xu FUSE_DAX_INODE_DEFAULT, /* default */ 508780b1b95SJeffle Xu FUSE_DAX_ALWAYS, /* "-o dax=always" */ 509780b1b95SJeffle Xu FUSE_DAX_NEVER, /* "-o dax=never" */ 510780b1b95SJeffle Xu FUSE_DAX_INODE_USER, /* "-o dax=inode" */ 511780b1b95SJeffle Xu }; 512780b1b95SJeffle Xu 513780b1b95SJeffle Xu static inline bool fuse_is_inode_dax_mode(enum fuse_dax_mode mode) 514780b1b95SJeffle Xu { 515780b1b95SJeffle Xu return mode == FUSE_DAX_INODE_DEFAULT || mode == FUSE_DAX_INODE_USER; 516780b1b95SJeffle Xu } 517780b1b95SJeffle Xu 5180cc2656cSStefan Hajnoczi struct fuse_fs_context { 5190cc2656cSStefan Hajnoczi int fd; 52062dd1fc8SMiklos Szeredi struct file *file; 5210cc2656cSStefan Hajnoczi unsigned int rootmode; 5220cc2656cSStefan Hajnoczi kuid_t user_id; 5230cc2656cSStefan Hajnoczi kgid_t group_id; 5240cc2656cSStefan Hajnoczi bool is_bdev:1; 5250cc2656cSStefan Hajnoczi bool fd_present:1; 5260cc2656cSStefan Hajnoczi bool rootmode_present:1; 5270cc2656cSStefan Hajnoczi bool user_id_present:1; 5280cc2656cSStefan Hajnoczi bool group_id_present:1; 5290cc2656cSStefan Hajnoczi bool default_permissions:1; 5300cc2656cSStefan Hajnoczi bool allow_other:1; 531783863d6SMiklos Szeredi bool destroy:1; 53215c8e72eSVivek Goyal bool no_control:1; 53315c8e72eSVivek Goyal bool no_force_umount:1; 534f4fd4ae3SVivek Goyal bool legacy_opts_show:1; 535780b1b95SJeffle Xu enum fuse_dax_mode dax_mode; 5360cc2656cSStefan Hajnoczi unsigned int max_read; 5370cc2656cSStefan Hajnoczi unsigned int blksize; 5380cc2656cSStefan Hajnoczi const char *subtype; 5390cc2656cSStefan Hajnoczi 5401dd53957SVivek Goyal /* DAX device, may be NULL */ 5411dd53957SVivek Goyal struct dax_device *dax_dev; 5421dd53957SVivek Goyal 5430cc2656cSStefan Hajnoczi /* fuse_dev pointer to fill in, should contain NULL on entry */ 5440cc2656cSStefan Hajnoczi void **fudptr; 5450cc2656cSStefan Hajnoczi }; 5460cc2656cSStefan Hajnoczi 547660585b5SMiklos Szeredi struct fuse_sync_bucket { 548660585b5SMiklos Szeredi /* count is a possible scalability bottleneck */ 549660585b5SMiklos Szeredi atomic_t count; 550660585b5SMiklos Szeredi wait_queue_head_t waitq; 551660585b5SMiklos Szeredi struct rcu_head rcu; 552660585b5SMiklos Szeredi }; 553660585b5SMiklos Szeredi 554cc080e9eSMiklos Szeredi /** 555d8a5ba45SMiklos Szeredi * A Fuse connection. 556d8a5ba45SMiklos Szeredi * 557fcee216bSMax Reitz * This structure is created, when the root filesystem is mounted, and 558fcee216bSMax Reitz * is destroyed, when the client device is closed and the last 559fcee216bSMax Reitz * fuse_mount is destroyed. 560d8a5ba45SMiklos Szeredi */ 561d8a5ba45SMiklos Szeredi struct fuse_conn { 562d7133114SMiklos Szeredi /** Lock protecting accessess to members of this structure */ 563d7133114SMiklos Szeredi spinlock_t lock; 564d7133114SMiklos Szeredi 565bafa9654SMiklos Szeredi /** Refcount */ 566095fc40aSElena Reshetova refcount_t count; 567bafa9654SMiklos Szeredi 568c3696046SMiklos Szeredi /** Number of fuse_dev's */ 569c3696046SMiklos Szeredi atomic_t dev_count; 570c3696046SMiklos Szeredi 571dd3e2c55SAl Viro struct rcu_head rcu; 572dd3e2c55SAl Viro 573d8a5ba45SMiklos Szeredi /** The user id for this mount */ 574499dcf20SEric W. Biederman kuid_t user_id; 575d8a5ba45SMiklos Szeredi 57687729a55SMiklos Szeredi /** The group id for this mount */ 577499dcf20SEric W. Biederman kgid_t group_id; 57887729a55SMiklos Szeredi 5790b6e9ea0SSeth Forshee /** The pid namespace for this mount */ 5800b6e9ea0SSeth Forshee struct pid_namespace *pid_ns; 5810b6e9ea0SSeth Forshee 5828cb08329SEric W. Biederman /** The user namespace for this mount */ 5838cb08329SEric W. Biederman struct user_namespace *user_ns; 5848cb08329SEric W. Biederman 585db50b96cSMiklos Szeredi /** Maximum read size */ 586db50b96cSMiklos Szeredi unsigned max_read; 587db50b96cSMiklos Szeredi 588413ef8cbSMiklos Szeredi /** Maximum write size */ 589413ef8cbSMiklos Szeredi unsigned max_write; 590413ef8cbSMiklos Szeredi 5914b91459aSConnor Kuehl /** Maximum number of pages that can be used in a single request */ 5925da784ccSConstantine Shulyupin unsigned int max_pages; 5935da784ccSConstantine Shulyupin 594a7f0d7aaSConnor Kuehl /** Constrain ->max_pages to this value during feature negotiation */ 595a7f0d7aaSConnor Kuehl unsigned int max_pages_limit; 596a7f0d7aaSConnor Kuehl 597f88996a9SMiklos Szeredi /** Input queue */ 598f88996a9SMiklos Szeredi struct fuse_iqueue iq; 599334f485dSMiklos Szeredi 600acf99433STejun Heo /** The next unique kernel file handle */ 60175126f55SMiklos Szeredi atomic64_t khctr; 602acf99433STejun Heo 60395668a69STejun Heo /** rbtree of fuse_files waiting for poll events indexed by ph */ 60495668a69STejun Heo struct rb_root polled_files; 60595668a69STejun Heo 6067a6d3c8bSCsaba Henk /** Maximum number of outstanding background requests */ 6077a6d3c8bSCsaba Henk unsigned max_background; 6087a6d3c8bSCsaba Henk 6097a6d3c8bSCsaba Henk /** Number of background requests at which congestion starts */ 6107a6d3c8bSCsaba Henk unsigned congestion_threshold; 6117a6d3c8bSCsaba Henk 61208a53cdcSMiklos Szeredi /** Number of requests currently in the background */ 61308a53cdcSMiklos Szeredi unsigned num_background; 61408a53cdcSMiklos Szeredi 615d12def1bSMiklos Szeredi /** Number of background requests currently queued for userspace */ 616d12def1bSMiklos Szeredi unsigned active_background; 617d12def1bSMiklos Szeredi 618d12def1bSMiklos Szeredi /** The list of background requests set aside for later queuing */ 619d12def1bSMiklos Szeredi struct list_head bg_queue; 620d12def1bSMiklos Szeredi 621ae2dffa3SKirill Tkhai /** Protects: max_background, congestion_threshold, num_background, 622ae2dffa3SKirill Tkhai * active_background, bg_queue, blocked */ 623ae2dffa3SKirill Tkhai spinlock_t bg_lock; 624ae2dffa3SKirill Tkhai 625796523fbSMaxim Patlasov /** Flag indicating that INIT reply has been received. Allocating 626796523fbSMaxim Patlasov * any fuse request will be suspended until the flag is set */ 627796523fbSMaxim Patlasov int initialized; 628796523fbSMaxim Patlasov 62908a53cdcSMiklos Szeredi /** Flag indicating if connection is blocked. This will be 63008a53cdcSMiklos Szeredi the case before the INIT reply is received, and if there 63108a53cdcSMiklos Szeredi are too many outstading backgrounds requests */ 63208a53cdcSMiklos Szeredi int blocked; 63308a53cdcSMiklos Szeredi 63408a53cdcSMiklos Szeredi /** waitq for blocked connection */ 63508a53cdcSMiklos Szeredi wait_queue_head_t blocked_waitq; 63608a53cdcSMiklos Szeredi 63769a53bf2SMiklos Szeredi /** Connection established, cleared on umount, connection 63869a53bf2SMiklos Szeredi abort and device release */ 639095da6cbSMiklos Szeredi unsigned connected; 6401e9a4ed9SMiklos Szeredi 6413b7008b2SSzymon Lukasz /** Connection aborted via sysfs */ 6423b7008b2SSzymon Lukasz bool aborted; 6433b7008b2SSzymon Lukasz 644095da6cbSMiklos Szeredi /** Connection failed (version mismatch). Cannot race with 645095da6cbSMiklos Szeredi setting other bitfields since it is only set once in INIT 646095da6cbSMiklos Szeredi reply, before any other request, and never cleared */ 647334f485dSMiklos Szeredi unsigned conn_error:1; 648334f485dSMiklos Szeredi 6490ec7ca41SMiklos Szeredi /** Connection successful. Only set in INIT */ 6500ec7ca41SMiklos Szeredi unsigned conn_init:1; 6510ec7ca41SMiklos Szeredi 652704528d8SMatthew Wilcox (Oracle) /** Do readahead asynchronously? Only set in INIT */ 6539cd68455SMiklos Szeredi unsigned async_read:1; 6549cd68455SMiklos Szeredi 6553b7008b2SSzymon Lukasz /** Return an unique read error after abort. Only set in INIT */ 6563b7008b2SSzymon Lukasz unsigned abort_err:1; 6573b7008b2SSzymon Lukasz 6586ff958edSMiklos Szeredi /** Do not send separate SETATTR request before open(O_TRUNC) */ 6596ff958edSMiklos Szeredi unsigned atomic_o_trunc:1; 6606ff958edSMiklos Szeredi 66133670fa2SMiklos Szeredi /** Filesystem supports NFS exporting. Only set in INIT */ 66233670fa2SMiklos Szeredi unsigned export_support:1; 66333670fa2SMiklos Szeredi 664d5cd66c5SPavel Emelyanov /** write-back cache policy (default is write-through) */ 665d5cd66c5SPavel Emelyanov unsigned writeback_cache:1; 666d5cd66c5SPavel Emelyanov 6675c672ab3SMiklos Szeredi /** allow parallel lookups and readdir (default is serialized) */ 6685c672ab3SMiklos Szeredi unsigned parallel_dirops:1; 6695c672ab3SMiklos Szeredi 6705e940c1dSMiklos Szeredi /** handle fs handles killing suid/sgid/cap on write/chown/trunc */ 6715e940c1dSMiklos Szeredi unsigned handle_killpriv:1; 6725e940c1dSMiklos Szeredi 6735571f1e6SDan Schatzberg /** cache READLINK responses in page cache */ 6745571f1e6SDan Schatzberg unsigned cache_symlinks:1; 6755571f1e6SDan Schatzberg 676f4fd4ae3SVivek Goyal /* show legacy mount options */ 677f4fd4ae3SVivek Goyal unsigned int legacy_opts_show:1; 678f4fd4ae3SVivek Goyal 679095da6cbSMiklos Szeredi /* 68063f9909fSVivek Goyal * fs kills suid/sgid/cap on write/chown/trunc. suid is killed on 68163f9909fSVivek Goyal * write/trunc only if caller did not have CAP_FSETID. sgid is killed 68263f9909fSVivek Goyal * on write/truncate only if caller did not have CAP_FSETID as well as 68363f9909fSVivek Goyal * file has group execute permission. 68463f9909fSVivek Goyal */ 68563f9909fSVivek Goyal unsigned handle_killpriv_v2:1; 68663f9909fSVivek Goyal 68763f9909fSVivek Goyal /* 688095da6cbSMiklos Szeredi * The following bitfields are only for optimization purposes 689095da6cbSMiklos Szeredi * and hence races in setting them will not cause malfunction 690095da6cbSMiklos Szeredi */ 691095da6cbSMiklos Szeredi 6927678ac50SAndrew Gallagher /** Is open/release not implemented by fs? */ 6937678ac50SAndrew Gallagher unsigned no_open:1; 6947678ac50SAndrew Gallagher 695d9a9ea94SChad Austin /** Is opendir/releasedir not implemented by fs? */ 696d9a9ea94SChad Austin unsigned no_opendir:1; 697d9a9ea94SChad Austin 698b6aeadedSMiklos Szeredi /** Is fsync not implemented by fs? */ 699b6aeadedSMiklos Szeredi unsigned no_fsync:1; 700b6aeadedSMiklos Szeredi 70182547981SMiklos Szeredi /** Is fsyncdir not implemented by fs? */ 70282547981SMiklos Szeredi unsigned no_fsyncdir:1; 70382547981SMiklos Szeredi 704b6aeadedSMiklos Szeredi /** Is flush not implemented by fs? */ 705b6aeadedSMiklos Szeredi unsigned no_flush:1; 706b6aeadedSMiklos Szeredi 70792a8780eSMiklos Szeredi /** Is setxattr not implemented by fs? */ 70892a8780eSMiklos Szeredi unsigned no_setxattr:1; 70992a8780eSMiklos Szeredi 71052a4c95fSVivek Goyal /** Does file server support extended setxattr */ 71152a4c95fSVivek Goyal unsigned setxattr_ext:1; 71252a4c95fSVivek Goyal 71392a8780eSMiklos Szeredi /** Is getxattr not implemented by fs? */ 71492a8780eSMiklos Szeredi unsigned no_getxattr:1; 71592a8780eSMiklos Szeredi 71692a8780eSMiklos Szeredi /** Is listxattr not implemented by fs? */ 71792a8780eSMiklos Szeredi unsigned no_listxattr:1; 71892a8780eSMiklos Szeredi 71992a8780eSMiklos Szeredi /** Is removexattr not implemented by fs? */ 72092a8780eSMiklos Szeredi unsigned no_removexattr:1; 72192a8780eSMiklos Szeredi 72237fb3a30SMiklos Szeredi /** Are posix file locking primitives not implemented by fs? */ 72371421259SMiklos Szeredi unsigned no_lock:1; 72471421259SMiklos Szeredi 72531d40d74SMiklos Szeredi /** Is access not implemented by fs? */ 72631d40d74SMiklos Szeredi unsigned no_access:1; 72731d40d74SMiklos Szeredi 728fd72faacSMiklos Szeredi /** Is create not implemented by fs? */ 729fd72faacSMiklos Szeredi unsigned no_create:1; 730fd72faacSMiklos Szeredi 731a4d27e75SMiklos Szeredi /** Is interrupt not implemented by fs? */ 732a4d27e75SMiklos Szeredi unsigned no_interrupt:1; 733a4d27e75SMiklos Szeredi 734b2d2272fSMiklos Szeredi /** Is bmap not implemented by fs? */ 735b2d2272fSMiklos Szeredi unsigned no_bmap:1; 736b2d2272fSMiklos Szeredi 73795668a69STejun Heo /** Is poll not implemented by fs? */ 73895668a69STejun Heo unsigned no_poll:1; 73995668a69STejun Heo 74078bb6cb9SMiklos Szeredi /** Do multi-page cached writes */ 74178bb6cb9SMiklos Szeredi unsigned big_writes:1; 74278bb6cb9SMiklos Szeredi 743e0a43ddcSMiklos Szeredi /** Don't apply umask to creation modes */ 744e0a43ddcSMiklos Szeredi unsigned dont_mask:1; 745e0a43ddcSMiklos Szeredi 74637fb3a30SMiklos Szeredi /** Are BSD file locking primitives not implemented by fs? */ 74737fb3a30SMiklos Szeredi unsigned no_flock:1; 74837fb3a30SMiklos Szeredi 749519c6040SMiklos Szeredi /** Is fallocate not implemented by fs? */ 750519c6040SMiklos Szeredi unsigned no_fallocate:1; 751519c6040SMiklos Szeredi 7521560c974SMiklos Szeredi /** Is rename with flags implemented by fs? */ 7531560c974SMiklos Szeredi unsigned no_rename2:1; 7541560c974SMiklos Szeredi 75572d0d248SBrian Foster /** Use enhanced/automatic page cache invalidation. */ 75672d0d248SBrian Foster unsigned auto_inval_data:1; 75772d0d248SBrian Foster 758aa6ff555SBhaskar Chowdhury /** Filesystem is fully responsible for page cache invalidation. */ 759ad2ba64dSKirill Smelkov unsigned explicit_inval_data:1; 760ad2ba64dSKirill Smelkov 761634734b6SEric Wong /** Does the filesystem support readdirplus? */ 7620b05b183SAnand V. Avati unsigned do_readdirplus:1; 7630b05b183SAnand V. Avati 764634734b6SEric Wong /** Does the filesystem want adaptive readdirplus? */ 765634734b6SEric Wong unsigned readdirplus_auto:1; 766634734b6SEric Wong 76760b9df7aSMiklos Szeredi /** Does the filesystem support asynchronous direct-IO submission? */ 76860b9df7aSMiklos Szeredi unsigned async_dio:1; 76960b9df7aSMiklos Szeredi 7700b5da8dbSRavishankar N /** Is lseek not implemented by fs? */ 7710b5da8dbSRavishankar N unsigned no_lseek:1; 7720b5da8dbSRavishankar N 77360bcc88aSSeth Forshee /** Does the filesystem support posix acls? */ 77460bcc88aSSeth Forshee unsigned posix_acl:1; 77560bcc88aSSeth Forshee 77629433a29SMiklos Szeredi /** Check permissions based on the file mode or not? */ 77729433a29SMiklos Szeredi unsigned default_permissions:1; 77829433a29SMiklos Szeredi 77929433a29SMiklos Szeredi /** Allow other than the mounter user to access the filesystem ? */ 78029433a29SMiklos Szeredi unsigned allow_other:1; 78129433a29SMiklos Szeredi 78288bc7d50SNiels de Vos /** Does the filesystem support copy_file_range? */ 78388bc7d50SNiels de Vos unsigned no_copy_file_range:1; 78488bc7d50SNiels de Vos 7851ccd1ea2SMiklos Szeredi /* Send DESTROY request */ 7861ccd1ea2SMiklos Szeredi unsigned int destroy:1; 7871ccd1ea2SMiklos Szeredi 7888fab0106SMiklos Szeredi /* Delete dentries that have gone stale */ 7898fab0106SMiklos Szeredi unsigned int delete_stale:1; 7908fab0106SMiklos Szeredi 79115c8e72eSVivek Goyal /** Do not create entry in fusectl fs */ 79215c8e72eSVivek Goyal unsigned int no_control:1; 79315c8e72eSVivek Goyal 79415c8e72eSVivek Goyal /** Do not allow MNT_FORCE umount */ 79515c8e72eSVivek Goyal unsigned int no_force_umount:1; 79615c8e72eSVivek Goyal 797bf109c64SMax Reitz /* Auto-mount submounts announced by the server */ 798bf109c64SMax Reitz unsigned int auto_submounts:1; 799bf109c64SMax Reitz 8002d82ab25SGreg Kurz /* Propagate syncfs() to server */ 8012d82ab25SGreg Kurz unsigned int sync_fs:1; 8022d82ab25SGreg Kurz 8033e2b6fdbSVivek Goyal /* Initialize security xattrs when creating a new inode */ 8043e2b6fdbSVivek Goyal unsigned int init_security:1; 8053e2b6fdbSVivek Goyal 8068ed7cb3fSMiklos Szeredi /* Add supplementary group info when creating a new inode */ 8078ed7cb3fSMiklos Szeredi unsigned int create_supp_group:1; 8088ed7cb3fSMiklos Szeredi 8092ee019faSJeffle Xu /* Does the filesystem support per inode DAX? */ 8102ee019faSJeffle Xu unsigned int inode_dax:1; 8112ee019faSJeffle Xu 8127d375390SMiklos Szeredi /* Is tmpfile not implemented by fs? */ 8137d375390SMiklos Szeredi unsigned int no_tmpfile:1; 8147d375390SMiklos Szeredi 8159f36c1c5STyler Fanelli /* Relax restrictions to allow shared mmap in FOPEN_DIRECT_IO mode */ 8169f36c1c5STyler Fanelli unsigned int direct_io_allow_mmap:1; 817e78662e8SHao Xu 818d3045530SMiklos Szeredi /* Is statx not implemented by fs? */ 819d3045530SMiklos Szeredi unsigned int no_statx:1; 820d3045530SMiklos Szeredi 8210cd5b885SMiklos Szeredi /** The number of requests waiting for completion */ 8220cd5b885SMiklos Szeredi atomic_t num_waiting; 8230cd5b885SMiklos Szeredi 82445714d65SMiklos Szeredi /** Negotiated minor version */ 82545714d65SMiklos Szeredi unsigned minor; 82645714d65SMiklos Szeredi 827fcee216bSMax Reitz /** Entry on the fuse_mount_list */ 828bafa9654SMiklos Szeredi struct list_head entry; 829bafa9654SMiklos Szeredi 830fcee216bSMax Reitz /** Device ID from the root super block */ 831b6f2fcbcSMiklos Szeredi dev_t dev; 832bafa9654SMiklos Szeredi 833bafa9654SMiklos Szeredi /** Dentries in the control filesystem */ 834bafa9654SMiklos Szeredi struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES]; 835bafa9654SMiklos Szeredi 836bafa9654SMiklos Szeredi /** number of dentries used in the above array */ 837bafa9654SMiklos Szeredi int ctl_ndents; 838385a17bfSJeff Dike 8399c8ef561SMiklos Szeredi /** Key for lock owner ID scrambling */ 8409c8ef561SMiklos Szeredi u32 scramble_key[4]; 8410ec7ca41SMiklos Szeredi 8421fb69e78SMiklos Szeredi /** Version counter for attribute changes */ 8434510d86fSKirill Tkhai atomic64_t attr_version; 84443901aabSTejun Heo 84543901aabSTejun Heo /** Called on final put */ 84643901aabSTejun Heo void (*release)(struct fuse_conn *); 8473b463ae0SJohn Muir 848fcee216bSMax Reitz /** 849fcee216bSMax Reitz * Read/write semaphore to hold when accessing the sb of any 850fcee216bSMax Reitz * fuse_mount belonging to this connection 851fcee216bSMax Reitz */ 8523b463ae0SJohn Muir struct rw_semaphore killsb; 853cc080e9eSMiklos Szeredi 854cc080e9eSMiklos Szeredi /** List of device instances belonging to this connection */ 855cc080e9eSMiklos Szeredi struct list_head devices; 8561dd53957SVivek Goyal 8571dd53957SVivek Goyal #ifdef CONFIG_FUSE_DAX 858780b1b95SJeffle Xu /* Dax mode */ 859780b1b95SJeffle Xu enum fuse_dax_mode dax_mode; 860780b1b95SJeffle Xu 8611dd53957SVivek Goyal /* Dax specific conn data, non-NULL if DAX is enabled */ 8621dd53957SVivek Goyal struct fuse_conn_dax *dax; 8631dd53957SVivek Goyal #endif 864fcee216bSMax Reitz 865fcee216bSMax Reitz /** List of filesystems using this connection */ 866fcee216bSMax Reitz struct list_head mounts; 867660585b5SMiklos Szeredi 868660585b5SMiklos Szeredi /* New writepages go into this bucket */ 869660585b5SMiklos Szeredi struct fuse_sync_bucket __rcu *curr_bucket; 870d8a5ba45SMiklos Szeredi }; 871d8a5ba45SMiklos Szeredi 872fcee216bSMax Reitz /* 873fcee216bSMax Reitz * Represents a mounted filesystem, potentially a submount. 874fcee216bSMax Reitz * 875fcee216bSMax Reitz * This object allows sharing a fuse_conn between separate mounts to 876fcee216bSMax Reitz * allow submounts with dedicated superblocks and thus separate device 877fcee216bSMax Reitz * IDs. 878fcee216bSMax Reitz */ 879fcee216bSMax Reitz struct fuse_mount { 880fcee216bSMax Reitz /* Underlying (potentially shared) connection to the FUSE server */ 881fcee216bSMax Reitz struct fuse_conn *fc; 882fcee216bSMax Reitz 883fcee216bSMax Reitz /* 884fcee216bSMax Reitz * Super block for this connection (fc->killsb must be held when 885fcee216bSMax Reitz * accessing this). 886fcee216bSMax Reitz */ 887fcee216bSMax Reitz struct super_block *sb; 888fcee216bSMax Reitz 889fcee216bSMax Reitz /* Entry on fc->mounts */ 890fcee216bSMax Reitz struct list_head fc_entry; 891fcee216bSMax Reitz }; 892fcee216bSMax Reitz 893fcee216bSMax Reitz static inline struct fuse_mount *get_fuse_mount_super(struct super_block *sb) 894d8a5ba45SMiklos Szeredi { 8956383bdaaSMiklos Szeredi return sb->s_fs_info; 896d8a5ba45SMiklos Szeredi } 897d8a5ba45SMiklos Szeredi 898fcee216bSMax Reitz static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) 899fcee216bSMax Reitz { 900bd3bf1e8SMiklos Szeredi return get_fuse_mount_super(sb)->fc; 901fcee216bSMax Reitz } 902fcee216bSMax Reitz 903fcee216bSMax Reitz static inline struct fuse_mount *get_fuse_mount(struct inode *inode) 904fcee216bSMax Reitz { 905fcee216bSMax Reitz return get_fuse_mount_super(inode->i_sb); 906fcee216bSMax Reitz } 907fcee216bSMax Reitz 908d8a5ba45SMiklos Szeredi static inline struct fuse_conn *get_fuse_conn(struct inode *inode) 909d8a5ba45SMiklos Szeredi { 910bd3bf1e8SMiklos Szeredi return get_fuse_mount_super(inode->i_sb)->fc; 911d8a5ba45SMiklos Szeredi } 912d8a5ba45SMiklos Szeredi 913d8a5ba45SMiklos Szeredi static inline struct fuse_inode *get_fuse_inode(struct inode *inode) 914d8a5ba45SMiklos Szeredi { 915d8a5ba45SMiklos Szeredi return container_of(inode, struct fuse_inode, inode); 916d8a5ba45SMiklos Szeredi } 917d8a5ba45SMiklos Szeredi 918d8a5ba45SMiklos Szeredi static inline u64 get_node_id(struct inode *inode) 919d8a5ba45SMiklos Szeredi { 920d8a5ba45SMiklos Szeredi return get_fuse_inode(inode)->nodeid; 921d8a5ba45SMiklos Szeredi } 922d8a5ba45SMiklos Szeredi 923d123d8e1SMiklos Szeredi static inline int invalid_nodeid(u64 nodeid) 924d123d8e1SMiklos Szeredi { 925d123d8e1SMiklos Szeredi return !nodeid || nodeid == FUSE_ROOT_ID; 926d123d8e1SMiklos Szeredi } 927d123d8e1SMiklos Szeredi 9284510d86fSKirill Tkhai static inline u64 fuse_get_attr_version(struct fuse_conn *fc) 9294510d86fSKirill Tkhai { 9304510d86fSKirill Tkhai return atomic64_read(&fc->attr_version); 9314510d86fSKirill Tkhai } 9324510d86fSKirill Tkhai 93315db1683SAmir Goldstein static inline bool fuse_stale_inode(const struct inode *inode, int generation, 93415db1683SAmir Goldstein struct fuse_attr *attr) 93515db1683SAmir Goldstein { 93615db1683SAmir Goldstein return inode->i_generation != generation || 93715db1683SAmir Goldstein inode_wrong_type(inode, attr->mode); 93815db1683SAmir Goldstein } 93915db1683SAmir Goldstein 9405d069dbeSMiklos Szeredi static inline void fuse_make_bad(struct inode *inode) 9415d069dbeSMiklos Szeredi { 942775c5033SAmir Goldstein remove_inode_hash(inode); 9435d069dbeSMiklos Szeredi set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state); 9445d069dbeSMiklos Szeredi } 9455d069dbeSMiklos Szeredi 9465d069dbeSMiklos Szeredi static inline bool fuse_is_bad(struct inode *inode) 9475d069dbeSMiklos Szeredi { 9485d069dbeSMiklos Szeredi return unlikely(test_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state)); 9495d069dbeSMiklos Szeredi } 9505d069dbeSMiklos Szeredi 9519ac29fd3SMiklos Szeredi static inline struct page **fuse_pages_alloc(unsigned int npages, gfp_t flags, 9529ac29fd3SMiklos Szeredi struct fuse_page_desc **desc) 9539ac29fd3SMiklos Szeredi { 9549ac29fd3SMiklos Szeredi struct page **pages; 9559ac29fd3SMiklos Szeredi 9569ac29fd3SMiklos Szeredi pages = kzalloc(npages * (sizeof(struct page *) + 9579ac29fd3SMiklos Szeredi sizeof(struct fuse_page_desc)), flags); 9589ac29fd3SMiklos Szeredi *desc = (void *) (pages + npages); 9599ac29fd3SMiklos Szeredi 9609ac29fd3SMiklos Szeredi return pages; 9619ac29fd3SMiklos Szeredi } 9629ac29fd3SMiklos Szeredi 9639ac29fd3SMiklos Szeredi static inline void fuse_page_descs_length_init(struct fuse_page_desc *descs, 9649ac29fd3SMiklos Szeredi unsigned int index, 9659ac29fd3SMiklos Szeredi unsigned int nr_pages) 9669ac29fd3SMiklos Szeredi { 9679ac29fd3SMiklos Szeredi int i; 9689ac29fd3SMiklos Szeredi 9699ac29fd3SMiklos Szeredi for (i = index; i < index + nr_pages; i++) 9709ac29fd3SMiklos Szeredi descs[i].length = PAGE_SIZE - descs[i].offset; 9719ac29fd3SMiklos Szeredi } 9729ac29fd3SMiklos Szeredi 973660585b5SMiklos Szeredi static inline void fuse_sync_bucket_dec(struct fuse_sync_bucket *bucket) 974660585b5SMiklos Szeredi { 975660585b5SMiklos Szeredi /* Need RCU protection to prevent use after free after the decrement */ 976660585b5SMiklos Szeredi rcu_read_lock(); 977660585b5SMiklos Szeredi if (atomic_dec_and_test(&bucket->count)) 978660585b5SMiklos Szeredi wake_up(&bucket->waitq); 979660585b5SMiklos Szeredi rcu_read_unlock(); 980660585b5SMiklos Szeredi } 981660585b5SMiklos Szeredi 982334f485dSMiklos Szeredi /** Device operations */ 9834b6f5d20SArjan van de Ven extern const struct file_operations fuse_dev_operations; 984334f485dSMiklos Szeredi 9854269590aSAl Viro extern const struct dentry_operations fuse_dentry_operations; 9860ce267ffSMiklos Szeredi extern const struct dentry_operations fuse_root_dentry_operations; 987dbd561d2SMiklos Szeredi 988d8a5ba45SMiklos Szeredi /** 989e5e5558eSMiklos Szeredi * Get a filled in inode 990e5e5558eSMiklos Szeredi */ 991b48badf0SMiklos Szeredi struct inode *fuse_iget(struct super_block *sb, u64 nodeid, 9921fb69e78SMiklos Szeredi int generation, struct fuse_attr *attr, 9931fb69e78SMiklos Szeredi u64 attr_valid, u64 attr_version); 994e5e5558eSMiklos Szeredi 99513983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, 99633670fa2SMiklos Szeredi struct fuse_entry_out *outarg, struct inode **inode); 99733670fa2SMiklos Szeredi 998e5e5558eSMiklos Szeredi /** 999e5e5558eSMiklos Szeredi * Send FORGET command 1000e5e5558eSMiklos Szeredi */ 100107e77dcaSMiklos Szeredi void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, 1002b48badf0SMiklos Szeredi u64 nodeid, u64 nlookup); 1003e5e5558eSMiklos Szeredi 100407e77dcaSMiklos Szeredi struct fuse_forget_link *fuse_alloc_forget(void); 100507e77dcaSMiklos Szeredi 10064388c5aaSVivek Goyal struct fuse_forget_link *fuse_dequeue_forget(struct fuse_iqueue *fiq, 10074388c5aaSVivek Goyal unsigned int max, 10084388c5aaSVivek Goyal unsigned int *countp); 10094388c5aaSVivek Goyal 101043f5098eSMiklos Szeredi /* 1011361b1eb5SMiklos Szeredi * Initialize READ or READDIR request 101204730fefSMiklos Szeredi */ 101343f5098eSMiklos Szeredi struct fuse_io_args { 101443f5098eSMiklos Szeredi union { 101543f5098eSMiklos Szeredi struct { 101643f5098eSMiklos Szeredi struct fuse_read_in in; 101743f5098eSMiklos Szeredi u64 attr_ver; 101843f5098eSMiklos Szeredi } read; 101943f5098eSMiklos Szeredi struct { 102043f5098eSMiklos Szeredi struct fuse_write_in in; 102143f5098eSMiklos Szeredi struct fuse_write_out out; 10224f06dd92SVivek Goyal bool page_locked; 102343f5098eSMiklos Szeredi } write; 102443f5098eSMiklos Szeredi }; 102543f5098eSMiklos Szeredi struct fuse_args_pages ap; 102643f5098eSMiklos Szeredi struct fuse_io_priv *io; 102743f5098eSMiklos Szeredi struct fuse_file *ff; 102843f5098eSMiklos Szeredi }; 102943f5098eSMiklos Szeredi 103043f5098eSMiklos Szeredi void fuse_read_args_fill(struct fuse_io_args *ia, struct file *file, loff_t pos, 103143f5098eSMiklos Szeredi size_t count, int opcode); 103243f5098eSMiklos Szeredi 103304730fefSMiklos Szeredi 103404730fefSMiklos Szeredi /** 103504730fefSMiklos Szeredi * Send OPEN or OPENDIR request 103604730fefSMiklos Szeredi */ 103791fe96b4SMiklos Szeredi int fuse_open_common(struct inode *inode, struct file *file, bool isdir); 103804730fefSMiklos Szeredi 1039fcee216bSMax Reitz struct fuse_file *fuse_file_alloc(struct fuse_mount *fm); 1040fd72faacSMiklos Szeredi void fuse_file_free(struct fuse_file *ff); 1041c7b7143cSMiklos Szeredi void fuse_finish_open(struct inode *inode, struct file *file); 1042fd72faacSMiklos Szeredi 104354d601cbSMiklos Szeredi void fuse_sync_release(struct fuse_inode *fi, struct fuse_file *ff, 104454d601cbSMiklos Szeredi unsigned int flags); 1045c756e0a4SMiklos Szeredi 104604730fefSMiklos Szeredi /** 104704730fefSMiklos Szeredi * Send RELEASE or RELEASEDIR request 104804730fefSMiklos Szeredi */ 10492e64ff15SChad Austin void fuse_release_common(struct file *file, bool isdir); 105004730fefSMiklos Szeredi 105104730fefSMiklos Szeredi /** 105282547981SMiklos Szeredi * Send FSYNC or FSYNCDIR request 105382547981SMiklos Szeredi */ 105402c24a82SJosef Bacik int fuse_fsync_common(struct file *file, loff_t start, loff_t end, 1055a9c2d1e8SMiklos Szeredi int datasync, int opcode); 105682547981SMiklos Szeredi 105782547981SMiklos Szeredi /** 105895668a69STejun Heo * Notify poll wakeup 105995668a69STejun Heo */ 106095668a69STejun Heo int fuse_notify_poll_wakeup(struct fuse_conn *fc, 106195668a69STejun Heo struct fuse_notify_poll_wakeup_out *outarg); 106295668a69STejun Heo 106395668a69STejun Heo /** 10641779381dSMiklos Szeredi * Initialize file operations on a regular file 1065b6aeadedSMiklos Szeredi */ 106693a497b9SJeffle Xu void fuse_init_file_inode(struct inode *inode, unsigned int flags); 1067b6aeadedSMiklos Szeredi 1068b6aeadedSMiklos Szeredi /** 10691779381dSMiklos Szeredi * Initialize inode operations on regular files and special files 1070e5e5558eSMiklos Szeredi */ 1071e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode); 1072e5e5558eSMiklos Szeredi 1073e5e5558eSMiklos Szeredi /** 10741779381dSMiklos Szeredi * Initialize inode and file operations on a directory 1075e5e5558eSMiklos Szeredi */ 1076e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode); 1077e5e5558eSMiklos Szeredi 1078e5e5558eSMiklos Szeredi /** 10791779381dSMiklos Szeredi * Initialize inode operations on a symlink 1080e5e5558eSMiklos Szeredi */ 1081e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode); 1082e5e5558eSMiklos Szeredi 1083e5e5558eSMiklos Szeredi /** 1084e5e5558eSMiklos Szeredi * Change attributes of an inode 1085e5e5558eSMiklos Szeredi */ 10861fb69e78SMiklos Szeredi void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, 1087972f4c46SMiklos Szeredi struct fuse_statx *sx, 10881fb69e78SMiklos Szeredi u64 attr_valid, u64 attr_version); 1089e5e5558eSMiklos Szeredi 10903be5a52bSMiklos Szeredi void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, 1091972f4c46SMiklos Szeredi struct fuse_statx *sx, 10924b52f059SMiklos Szeredi u64 attr_valid, u32 cache_mask); 10934b52f059SMiklos Szeredi 10944b52f059SMiklos Szeredi u32 fuse_get_cache_mask(struct inode *inode); 10953be5a52bSMiklos Szeredi 1096e5e5558eSMiklos Szeredi /** 1097334f485dSMiklos Szeredi * Initialize the client device 1098334f485dSMiklos Szeredi */ 1099334f485dSMiklos Szeredi int fuse_dev_init(void); 1100334f485dSMiklos Szeredi 1101334f485dSMiklos Szeredi /** 1102334f485dSMiklos Szeredi * Cleanup the client device 1103334f485dSMiklos Szeredi */ 1104334f485dSMiklos Szeredi void fuse_dev_cleanup(void); 1105334f485dSMiklos Szeredi 1106bafa9654SMiklos Szeredi int fuse_ctl_init(void); 11077736e8ccSFabian Frederick void __exit fuse_ctl_cleanup(void); 1108bafa9654SMiklos Szeredi 1109334f485dSMiklos Szeredi /** 11107078187aSMiklos Szeredi * Simple request sending that does request allocation and freeing 11117078187aSMiklos Szeredi */ 1112fcee216bSMax Reitz ssize_t fuse_simple_request(struct fuse_mount *fm, struct fuse_args *args); 1113fcee216bSMax Reitz int fuse_simple_background(struct fuse_mount *fm, struct fuse_args *args, 111412597287SMiklos Szeredi gfp_t gfp_flags); 11157078187aSMiklos Szeredi 111604ec5af0SStefan Hajnoczi /** 111704ec5af0SStefan Hajnoczi * End a finished request 111804ec5af0SStefan Hajnoczi */ 11198f622e94SMax Reitz void fuse_request_end(struct fuse_req *req); 112004ec5af0SStefan Hajnoczi 11215a5fb1eaSMiklos Szeredi /* Abort all requests */ 1122eb98e3bdSMiklos Szeredi void fuse_abort_conn(struct fuse_conn *fc); 1123b8f95e5dSMiklos Szeredi void fuse_wait_aborted(struct fuse_conn *fc); 112469a53bf2SMiklos Szeredi 11251e9a4ed9SMiklos Szeredi /** 1126e5e5558eSMiklos Szeredi * Invalidate inode attributes 1127e5e5558eSMiklos Szeredi */ 1128fa5eee57SMiklos Szeredi 1129fa5eee57SMiklos Szeredi /* Attributes possibly changed on data modification */ 1130fa5eee57SMiklos Szeredi #define FUSE_STATX_MODIFY (STATX_MTIME | STATX_CTIME | STATX_BLOCKS) 1131fa5eee57SMiklos Szeredi 1132fa5eee57SMiklos Szeredi /* Attributes possibly changed on data and/or size modification */ 1133fa5eee57SMiklos Szeredi #define FUSE_STATX_MODSIZE (FUSE_STATX_MODIFY | STATX_SIZE) 1134fa5eee57SMiklos Szeredi 1135e5e5558eSMiklos Szeredi void fuse_invalidate_attr(struct inode *inode); 1136fa5eee57SMiklos Szeredi void fuse_invalidate_attr_mask(struct inode *inode, u32 mask); 1137bafa9654SMiklos Szeredi 1138dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry); 1139dbd561d2SMiklos Szeredi 1140451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode); 1141451418fcSAndrew Gallagher 11429dc10a54SMiklos Szeredi u64 fuse_time_to_jiffies(u64 sec, u32 nsec); 11439dc10a54SMiklos Szeredi #define ATTR_TIMEOUT(o) \ 11449dc10a54SMiklos Szeredi fuse_time_to_jiffies((o)->attr_valid, (o)->attr_valid_nsec) 11459dc10a54SMiklos Szeredi 1146d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o); 1147d123d8e1SMiklos Szeredi 1148bafa9654SMiklos Szeredi /** 1149bafa9654SMiklos Szeredi * Acquire reference to fuse_conn 1150bafa9654SMiklos Szeredi */ 1151bafa9654SMiklos Szeredi struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); 1152bafa9654SMiklos Szeredi 1153bafa9654SMiklos Szeredi /** 11540d179aa5STejun Heo * Initialize fuse_conn 11550d179aa5STejun Heo */ 1156fcee216bSMax Reitz void fuse_conn_init(struct fuse_conn *fc, struct fuse_mount *fm, 1157fcee216bSMax Reitz struct user_namespace *user_ns, 1158ae3aad77SStefan Hajnoczi const struct fuse_iqueue_ops *fiq_ops, void *fiq_priv); 11590d179aa5STejun Heo 11600d179aa5STejun Heo /** 1161bafa9654SMiklos Szeredi * Release reference to fuse_conn 1162bafa9654SMiklos Szeredi */ 1163bafa9654SMiklos Szeredi void fuse_conn_put(struct fuse_conn *fc); 1164bafa9654SMiklos Szeredi 11650cd1eb9aSVivek Goyal struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc); 11660cd1eb9aSVivek Goyal struct fuse_dev *fuse_dev_alloc(void); 11670cd1eb9aSVivek Goyal void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc); 1168cc080e9eSMiklos Szeredi void fuse_dev_free(struct fuse_dev *fud); 1169fcee216bSMax Reitz void fuse_send_init(struct fuse_mount *fm); 1170cc080e9eSMiklos Szeredi 1171bafa9654SMiklos Szeredi /** 11720cc2656cSStefan Hajnoczi * Fill in superblock and initialize fuse connection 11730cc2656cSStefan Hajnoczi * @sb: partially-initialized superblock to fill in 11740cc2656cSStefan Hajnoczi * @ctx: mount context 11750cc2656cSStefan Hajnoczi */ 11760cc2656cSStefan Hajnoczi int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx); 11770cc2656cSStefan Hajnoczi 11781866d779SMax Reitz /* 1179fcee216bSMax Reitz * Remove the mount from the connection 1180783863d6SMiklos Szeredi * 1181fcee216bSMax Reitz * Returns whether this was the last mount 1182783863d6SMiklos Szeredi */ 1183fcee216bSMax Reitz bool fuse_mount_remove(struct fuse_mount *fm); 1184fcee216bSMax Reitz 1185fcee216bSMax Reitz /* 1186fe0a7bd8SGreg Kurz * Setup context ops for submounts 1187fe0a7bd8SGreg Kurz */ 1188fe0a7bd8SGreg Kurz int fuse_init_fs_context_submount(struct fs_context *fsc); 1189fe0a7bd8SGreg Kurz 1190fe0a7bd8SGreg Kurz /* 1191fcee216bSMax Reitz * Shut down the connection (possibly sending DESTROY request). 1192fcee216bSMax Reitz */ 1193fcee216bSMax Reitz void fuse_conn_destroy(struct fuse_mount *fm); 1194783863d6SMiklos Szeredi 1195a27c061aSMiklos Szeredi /* Drop the connection and free the fuse mount */ 1196a27c061aSMiklos Szeredi void fuse_mount_destroy(struct fuse_mount *fm); 1197a27c061aSMiklos Szeredi 1198783863d6SMiklos Szeredi /** 1199bafa9654SMiklos Szeredi * Add connection to control filesystem 1200bafa9654SMiklos Szeredi */ 1201bafa9654SMiklos Szeredi int fuse_ctl_add_conn(struct fuse_conn *fc); 1202bafa9654SMiklos Szeredi 1203bafa9654SMiklos Szeredi /** 1204bafa9654SMiklos Szeredi * Remove connection from control filesystem 1205bafa9654SMiklos Szeredi */ 1206bafa9654SMiklos Szeredi void fuse_ctl_remove_conn(struct fuse_conn *fc); 1207a5bfffacSTimo Savola 1208a5bfffacSTimo Savola /** 1209a5bfffacSTimo Savola * Is file type valid? 1210a5bfffacSTimo Savola */ 1211a5bfffacSTimo Savola int fuse_valid_type(int m); 1212e57ac683SMiklos Szeredi 1213eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr); 1214eb59bd17SMiklos Szeredi 1215e57ac683SMiklos Szeredi /** 1216c2132c1bSAnatol Pomozov * Is current process allowed to perform filesystem operation? 1217e57ac683SMiklos Szeredi */ 1218b1387777SDave Marchevsky bool fuse_allow_current_process(struct fuse_conn *fc); 1219f3332114SMiklos Szeredi 1220f3332114SMiklos Szeredi u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id); 1221bcb4be80SMiklos Szeredi 12225c791fe1SMiklos Szeredi void fuse_flush_time_update(struct inode *inode); 1223703c7362SSeth Forshee void fuse_update_ctime(struct inode *inode); 1224703c7362SSeth Forshee 1225c6c745b8SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file, u32 mask); 12263be5a52bSMiklos Szeredi 12273be5a52bSMiklos Szeredi void fuse_flush_writepages(struct inode *inode); 12283be5a52bSMiklos Szeredi 12293be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode); 12303be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode); 12315c5c5e51SMiklos Szeredi 12323b463ae0SJohn Muir /** 1233fcee216bSMax Reitz * Scan all fuse_mounts belonging to fc to find the first where 1234fcee216bSMax Reitz * ilookup5() returns a result. Return that result and the 1235fcee216bSMax Reitz * respective fuse_mount in *fm (unless fm is NULL). 1236fcee216bSMax Reitz * 1237fcee216bSMax Reitz * The caller must hold fc->killsb. 1238fcee216bSMax Reitz */ 1239fcee216bSMax Reitz struct inode *fuse_ilookup(struct fuse_conn *fc, u64 nodeid, 1240fcee216bSMax Reitz struct fuse_mount **fm); 1241fcee216bSMax Reitz 1242fcee216bSMax Reitz /** 12433b463ae0SJohn Muir * File-system tells the kernel to invalidate cache for the given node id. 12443b463ae0SJohn Muir */ 1245fcee216bSMax Reitz int fuse_reverse_inval_inode(struct fuse_conn *fc, u64 nodeid, 12463b463ae0SJohn Muir loff_t offset, loff_t len); 12473b463ae0SJohn Muir 12483b463ae0SJohn Muir /** 12493b463ae0SJohn Muir * File-system tells the kernel to invalidate parent attributes and 12503b463ae0SJohn Muir * the dentry matching parent/name. 1251451d0f59SJohn Muir * 1252451d0f59SJohn Muir * If the child_nodeid is non-zero and: 1253451d0f59SJohn Muir * - matches the inode number for the dentry matching parent/name, 1254451d0f59SJohn Muir * - is not a mount point 1255451d0f59SJohn Muir * - is a file or oan empty directory 1256451d0f59SJohn Muir * then the dentry is unhashed (d_delete()). 12573b463ae0SJohn Muir */ 1258fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid, 12594f8d3702SMiklos Szeredi u64 child_nodeid, struct qstr *name, u32 flags); 12603b463ae0SJohn Muir 1261fcee216bSMax Reitz int fuse_do_open(struct fuse_mount *fm, u64 nodeid, struct file *file, 126208cbf542STejun Heo bool isdir); 1263ea8cd333SPavel Emelyanov 1264ea8cd333SPavel Emelyanov /** 1265ea8cd333SPavel Emelyanov * fuse_direct_io() flags 1266ea8cd333SPavel Emelyanov */ 1267ea8cd333SPavel Emelyanov 1268ea8cd333SPavel Emelyanov /** If set, it is WRITE; otherwise - READ */ 1269ea8cd333SPavel Emelyanov #define FUSE_DIO_WRITE (1 << 0) 1270ea8cd333SPavel Emelyanov 1271ea8cd333SPavel Emelyanov /** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */ 1272ea8cd333SPavel Emelyanov #define FUSE_DIO_CUSE (1 << 1) 1273ea8cd333SPavel Emelyanov 1274d22a943fSAl Viro ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter, 1275d22a943fSAl Viro loff_t *ppos, int flags); 127608cbf542STejun Heo long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, 127708cbf542STejun Heo unsigned int flags); 1278b18da0c5SMiklos Szeredi long fuse_ioctl_common(struct file *file, unsigned int cmd, 1279b18da0c5SMiklos Szeredi unsigned long arg, unsigned int flags); 1280076ccb76SAl Viro __poll_t fuse_file_poll(struct file *file, poll_table *wait); 128108cbf542STejun Heo int fuse_dev_release(struct inode *inode, struct file *file); 128208cbf542STejun Heo 1283d347739aSMiklos Szeredi bool fuse_write_update_attr(struct inode *inode, loff_t pos, ssize_t written); 1284b0aa7606SMaxim Patlasov 1285ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff); 12861e18bda8SMiklos Szeredi int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); 1287a1d75f25SMiklos Szeredi 128862490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr, 1289efb9fa9eSMaxim Patlasov struct file *file); 1290efb9fa9eSMaxim Patlasov 12919759bd51SMiklos Szeredi void fuse_set_initialized(struct fuse_conn *fc); 12929759bd51SMiklos Szeredi 129363576c13SMiklos Szeredi void fuse_unlock_inode(struct inode *inode, bool locked); 129463576c13SMiklos Szeredi bool fuse_lock_inode(struct inode *inode); 12955c672ab3SMiklos Szeredi 129660bcc88aSSeth Forshee int fuse_setxattr(struct inode *inode, const char *name, const void *value, 129752a4c95fSVivek Goyal size_t size, int flags, unsigned int extra_flags); 129860bcc88aSSeth Forshee ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, 129960bcc88aSSeth Forshee size_t size); 1300703c7362SSeth Forshee ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size); 130160bcc88aSSeth Forshee int fuse_removexattr(struct inode *inode, const char *name); 1302703c7362SSeth Forshee extern const struct xattr_handler *fuse_xattr_handlers[]; 130360bcc88aSSeth Forshee 130460bcc88aSSeth Forshee struct posix_acl; 1305facd6105SChristian Brauner struct posix_acl *fuse_get_inode_acl(struct inode *inode, int type, bool rcu); 130605e6295fSLinus Torvalds struct posix_acl *fuse_get_acl(struct mnt_idmap *idmap, 1307facd6105SChristian Brauner struct dentry *dentry, int type); 130805e6295fSLinus Torvalds int fuse_set_acl(struct mnt_idmap *, struct dentry *dentry, 1309549c7297SChristian Brauner struct posix_acl *acl, int type); 1310d123d8e1SMiklos Szeredi 1311d123d8e1SMiklos Szeredi /* readdir.c */ 1312d123d8e1SMiklos Szeredi int fuse_readdir(struct file *file, struct dir_context *ctx); 1313d123d8e1SMiklos Szeredi 131414d46d7aSStefan Hajnoczi /** 131514d46d7aSStefan Hajnoczi * Return the number of bytes in an arguments list 131614d46d7aSStefan Hajnoczi */ 131714d46d7aSStefan Hajnoczi unsigned int fuse_len_args(unsigned int numargs, struct fuse_arg *args); 131814d46d7aSStefan Hajnoczi 131979d96effSStefan Hajnoczi /** 132079d96effSStefan Hajnoczi * Get the next unique ID for a request 132179d96effSStefan Hajnoczi */ 132279d96effSStefan Hajnoczi u64 fuse_get_unique(struct fuse_iqueue *fiq); 1323783863d6SMiklos Szeredi void fuse_free_conn(struct fuse_conn *fc); 132479d96effSStefan Hajnoczi 13251dd53957SVivek Goyal /* dax.c */ 13261dd53957SVivek Goyal 1327c2d0ad00SVivek Goyal #define FUSE_IS_DAX(inode) (IS_ENABLED(CONFIG_FUSE_DAX) && IS_DAX(inode)) 1328c2d0ad00SVivek Goyal 1329c2d0ad00SVivek Goyal ssize_t fuse_dax_read_iter(struct kiocb *iocb, struct iov_iter *to); 1330c2d0ad00SVivek Goyal ssize_t fuse_dax_write_iter(struct kiocb *iocb, struct iov_iter *from); 1331c2d0ad00SVivek Goyal int fuse_dax_mmap(struct file *file, struct vm_area_struct *vma); 13326ae330caSVivek Goyal int fuse_dax_break_layouts(struct inode *inode, u64 dmap_start, u64 dmap_end); 1333780b1b95SJeffle Xu int fuse_dax_conn_alloc(struct fuse_conn *fc, enum fuse_dax_mode mode, 1334780b1b95SJeffle Xu struct dax_device *dax_dev); 13351dd53957SVivek Goyal void fuse_dax_conn_free(struct fuse_conn *fc); 1336c2d0ad00SVivek Goyal bool fuse_dax_inode_alloc(struct super_block *sb, struct fuse_inode *fi); 133793a497b9SJeffle Xu void fuse_dax_inode_init(struct inode *inode, unsigned int flags); 1338c2d0ad00SVivek Goyal void fuse_dax_inode_cleanup(struct inode *inode); 1339c3cb6f93SJeffle Xu void fuse_dax_dontcache(struct inode *inode, unsigned int flags); 1340fd1a1dc6SStefan Hajnoczi bool fuse_dax_check_alignment(struct fuse_conn *fc, unsigned int map_alignment); 13419a752d18SVivek Goyal void fuse_dax_cancel_work(struct fuse_conn *fc); 13421dd53957SVivek Goyal 13439ac29fd3SMiklos Szeredi /* ioctl.c */ 13449ac29fd3SMiklos Szeredi long fuse_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 13459ac29fd3SMiklos Szeredi long fuse_file_compat_ioctl(struct file *file, unsigned int cmd, 13469ac29fd3SMiklos Szeredi unsigned long arg); 134772227eacSMiklos Szeredi int fuse_fileattr_get(struct dentry *dentry, struct fileattr *fa); 13488782a9aeSChristian Brauner int fuse_fileattr_set(struct mnt_idmap *idmap, 134972227eacSMiklos Szeredi struct dentry *dentry, struct fileattr *fa); 13509ac29fd3SMiklos Szeredi 1351b9d54c6fSMiklos Szeredi /* file.c */ 1352b9d54c6fSMiklos Szeredi 1353b9d54c6fSMiklos Szeredi struct fuse_file *fuse_file_open(struct fuse_mount *fm, u64 nodeid, 1354b9d54c6fSMiklos Szeredi unsigned int open_flags, bool isdir); 1355b9d54c6fSMiklos Szeredi void fuse_file_release(struct inode *inode, struct fuse_file *ff, 1356b9d54c6fSMiklos Szeredi unsigned int open_flags, fl_owner_t id, bool isdir); 1357b9d54c6fSMiklos Szeredi 135829d434b3STejun Heo #endif /* _FS_FUSE_I_H */ 1359