android_kernel_motorola_sm6225/fs/fuse/fuse_i.h
Ivaylo Georgiev 2857d83eee Merge android-4.19-q.77 (cd1eb9f) into msm-4.19
* refs/heads/tmp-cd1eb9f:
  Revert "net: qrtr: Stop rx_worker before freeing node"
  Linux 4.19.77
  drm/amd/display: Restore backlight brightness after system resume
  mm/compaction.c: clear total_{migrate,free}_scanned before scanning a new zone
  fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock
  md/raid0: avoid RAID0 data corruption due to layout confusion.
  CIFS: Fix oplock handling for SMB 2.1+ protocols
  CIFS: fix max ea value size
  i2c: riic: Clear NACK in tend isr
  hwrng: core - don't wait on add_early_randomness()
  quota: fix wrong condition in is_quota_modification()
  ext4: fix punch hole for inline_data file systems
  ext4: fix warning inside ext4_convert_unwritten_extents_endio
  /dev/mem: Bail out upon SIGKILL.
  cfg80211: Purge frame registrations on iftype change
  md: only call set_in_sync() when it is expected to succeed.
  md: don't report active array_state until after revalidate_disk() completes.
  md/raid6: Set R5_ReadError when there is read failure on parity disk
  Btrfs: fix race setting up and completing qgroup rescan workers
  btrfs: qgroup: Fix reserved data space leak if we have multiple reserve calls
  btrfs: qgroup: Fix the wrong target io_tree when freeing reserved data space
  btrfs: Relinquish CPUs in btrfs_compare_trees
  Btrfs: fix use-after-free when using the tree modification log
  btrfs: fix allocation of free space cache v1 bitmap pages
  ovl: filter of trusted xattr results in audit
  ovl: Fix dereferencing possible ERR_PTR()
  smb3: allow disabling requesting leases
  block: fix null pointer dereference in blk_mq_rq_timed_out()
  i40e: check __I40E_VF_DISABLE bit in i40e_sync_filters_subtask
  memcg, kmem: do not fail __GFP_NOFAIL charges
  memcg, oom: don't require __GFP_FS when invoking memcg OOM killer
  gfs2: clear buf_in_tr when ending a transaction in sweep_bh_for_rgrps
  efifb: BGRT: Improve efifb_bgrt_sanity_check
  regulator: Defer init completion for a while after late_initcall
  alarmtimer: Use EOPNOTSUPP instead of ENOTSUPP
  arm64: dts: rockchip: limit clock rate of MMC controllers for RK3328
  arm64: tlb: Ensure we execute an ISB following walk cache invalidation
  Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}"
  ARM: zynq: Use memcpy_toio instead of memcpy on smp bring-up
  ARM: samsung: Fix system restart on S3C6410
  ASoC: Intel: Fix use of potentially uninitialized variable
  ASoC: Intel: Skylake: Use correct function to access iomem space
  ASoC: Intel: NHLT: Fix debug print format
  binfmt_elf: Do not move brk for INTERP-less ET_EXEC
  media: don't drop front-end reference count for ->detach
  media: sn9c20x: Add MSI MS-1039 laptop to flip_dmi_table
  KVM: x86: Manually calculate reserved bits when loading PDPTRS
  KVM: x86: set ctxt->have_exception in x86_decode_insn()
  KVM: x86: always stop emulation on page fault
  parisc: Disable HP HSC-PCI Cards to prevent kernel crash
  fuse: fix missing unlock_page in fuse_writepage()
  powerpc/imc: Dont create debugfs files for cpu-less nodes
  scsi: implement .cleanup_rq callback
  blk-mq: add callback of .cleanup_rq
  ALSA: hda/realtek - PCI quirk for Medion E4254
  ceph: use ceph_evict_inode to cleanup inode's resource
  Revert "ceph: use ceph_evict_inode to cleanup inode's resource"
  randstruct: Check member structs in is_pure_ops_struct()
  IB/hfi1: Define variables as unsigned long to fix KASAN warning
  IB/mlx5: Free mpi in mp_slave mode
  printk: Do not lose last line in kmsg buffer dump
  scsi: qla2xxx: Fix Relogin to prevent modifying scan_state flag
  scsi: scsi_dh_rdac: zero cdb in send_mode_select()
  ALSA: firewire-tascam: check intermediate state of clock status and retry
  ALSA: firewire-tascam: handle error code when getting current source of clock
  iwlwifi: fw: don't send GEO_TX_POWER_LIMIT command to FW version 36
  PM / devfreq: passive: fix compiler warning
  media: omap3isp: Set device on omap3isp subdevs
  btrfs: extent-tree: Make sure we only allocate extents from block groups with the same type
  iommu/amd: Override wrong IVRS IOAPIC on Raven Ridge systems
  ALSA: hda/realtek - Blacklist PC beep for Lenovo ThinkCentre M73/93
  media: ttusb-dec: Fix info-leak in ttusb_dec_send_command()
  drm/amd/powerplay/smu7: enforce minimal VBITimeout (v2)
  ALSA: hda - Drop unsol event handler for Intel HDMI codecs
  e1000e: add workaround for possible stalled packet
  libertas: Add missing sentinel at end of if_usb.c fw_table
  raid5: don't increment read_errors on EILSEQ return
  mmc: dw_mmc: Re-store SDIO IRQs mask at system resume
  mmc: core: Add helper function to indicate if SDIO IRQs is enabled
  mmc: sdhci: Fix incorrect switch to HS mode
  mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD
  raid5: don't set STRIPE_HANDLE to stripe which is in batch list
  ASoC: dmaengine: Make the pcm->name equal to pcm->id if the name is not set
  platform/x86: intel_pmc_core: Do not ioremap RAM
  x86/cpu: Add Tiger Lake to Intel family
  s390/crypto: xts-aes-s390 fix extra run-time crypto self tests finding
  kprobes: Prohibit probing on BUG() and WARN() address
  dmaengine: ti: edma: Do not reset reserved paRAM slots
  md/raid1: fail run raid1 array when active disk less than one
  hwmon: (acpi_power_meter) Change log level for 'unsafe software power cap'
  closures: fix a race on wakeup from closure_sync
  ACPI / PCI: fix acpi_pci_irq_enable() memory leak
  ACPI: custom_method: fix memory leaks
  ARM: dts: exynos: Mark LDO10 as always-on on Peach Pit/Pi Chromebooks
  libtraceevent: Change users plugin directory
  iommu/iova: Avoid false sharing on fq_timer_on
  libata/ahci: Drop PCS quirk for Denverton and beyond
  iommu/amd: Silence warnings under memory pressure
  ALSA: firewire-motu: add support for MOTU 4pre
  nvme-multipath: fix ana log nsid lookup when nsid is not found
  nvmet: fix data units read and written counters in SMART log
  x86/mm/pti: Handle unaligned address gracefully in pti_clone_pagetable()
  ASoC: fsl_ssi: Fix clock control issue in master mode
  x86/mm/pti: Do not invoke PTI functions when PTI is disabled
  arm64: kpti: ensure patched kernel text is fetched from PoU
  x86/apic/vector: Warn when vector space exhaustion breaks affinity
  sched/cpufreq: Align trace event behavior of fast switching
  ACPI / CPPC: do not require the _PSD method
  ASoC: es8316: fix headphone mixer volume table
  media: ov9650: add a sanity check
  perf trace beauty ioctl: Fix off-by-one error in cmd->string table
  media: saa7134: fix terminology around saa7134_i2c_eeprom_md7134_gate()
  media: cpia2_usb: fix memory leaks
  media: saa7146: add cleanup in hexium_attach()
  media: cec-notifier: clear cec_adap in cec_notifier_unregister
  PM / devfreq: exynos-bus: Correct clock enable sequence
  PM / devfreq: passive: Use non-devm notifiers
  EDAC/amd64: Decode syndrome before translating address
  EDAC/amd64: Recognize DRAM device type ECC capability
  libperf: Fix alignment trap with xyarray contents in 'perf stat'
  media: dvb-core: fix a memory leak bug
  posix-cpu-timers: Sanitize bogus WARNONS
  media: dvb-frontends: use ida for pll number
  media: mceusb: fix (eliminate) TX IR signal length limit
  nbd: add missing config put
  led: triggers: Fix a memory leak bug
  ASoC: sun4i-i2s: Don't use the oversample to calculate BCLK
  tools headers: Fixup bitsperlong per arch includes
  ASoC: uniphier: Fix double reset assersion when transitioning to suspend state
  media: hdpvr: add terminating 0 at end of string
  media: radio/si470x: kill urb on error
  ARM: dts: imx7-colibri: disable HS400
  ARM: dts: imx7d: cl-som-imx7: make ethernet work again
  m68k: Prevent some compiler warnings in Coldfire builds
  net: lpc-enet: fix printk format strings
  media: imx: mipi csi-2: Don't fail if initial state times-out
  media: omap3isp: Don't set streaming state on random subdevs
  media: i2c: ov5645: Fix power sequence
  media: vsp1: fix memory leak of dl on error return path
  perf record: Support aarch64 random socket_id assignment
  dmaengine: iop-adma: use correct printk format strings
  media: rc: imon: Allow iMON RC protocol for ffdc 7e device
  media: em28xx: modules workqueue not inited for 2nd device
  media: fdp1: Reduce FCP not found message level to debug
  media: mtk-mdp: fix reference count on old device tree
  perf test vfs_getname: Disable ~/.perfconfig to get default output
  perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig
  media: gspca: zero usb_buf on error
  idle: Prevent late-arriving interrupts from disrupting offline
  sched/fair: Use rq_lock/unlock in online_fair_sched_group
  firmware: arm_scmi: Check if platform has released shmem before using
  efi: cper: print AER info of PCIe fatal error
  EDAC, pnd2: Fix ioremap() size in dnv_rd_reg()
  loop: Add LOOP_SET_DIRECT_IO to compat ioctl
  ACPI / processor: don't print errors for processorIDs == 0xff
  media: media/platform: fsl-viu.c: fix build for MICROBLAZE
  md: don't set In_sync if array is frozen
  md: don't call spare_active in md_reap_sync_thread if all member devices can't work
  md/raid1: end bio when the device faulty
  arm64/prefetch: fix a -Wtype-limits warning
  ASoC: rsnd: don't call clk_get_rate() under atomic context
  EDAC/altera: Use the proper type for the IRQ status bits
  ia64:unwind: fix double free for mod->arch.init_unw_table
  ALSA: usb-audio: Skip bSynchAddress endpoint check if it is invalid
  base: soc: Export soc_device_register/unregister APIs
  media: iguanair: add sanity checks
  EDAC/mc: Fix grain_bits calculation
  ALSA: i2c: ak4xxx-adda: Fix a possible null pointer dereference in build_adc_controls()
  ALSA: hda - Show the fatal CORB/RIRB error more clearly
  x86/apic: Soft disable APIC before initializing it
  x86/reboot: Always use NMI fallback when shutdown via reboot vector IPI fails
  sched/deadline: Fix bandwidth accounting at all levels after offline migration
  x86/apic: Make apic_pending_intr_clear() more robust
  sched/core: Fix CPU controller for !RT_GROUP_SCHED
  sched/fair: Fix imbalance due to CPU affinity
  time/tick-broadcast: Fix tick_broadcast_offline() lockdep complaint
  media: i2c: ov5640: Check for devm_gpiod_get_optional() error
  media: hdpvr: Add device num check and handling
  media: exynos4-is: fix leaked of_node references
  media: mtk-cir: lower de-glitch counter for rc-mm protocol
  media: dib0700: fix link error for dibx000_i2c_set_speed
  leds: leds-lp5562 allow firmware files up to the maximum length
  dmaengine: bcm2835: Print error in case setting DMA mask fails
  firmware: qcom_scm: Use proper types for dma mappings
  ASoC: sgtl5000: Fix charge pump source assignment
  ASoC: sgtl5000: Fix of unmute outputs on probe
  ASoC: tlv320aic31xx: suppress error message for EPROBE_DEFER
  regulator: lm363x: Fix off-by-one n_voltages for lm3632 ldo_vpos/ldo_vneg
  ALSA: hda: Flush interrupts on disabling
  nfp: flower: prevent memory leak in nfp_flower_spawn_phy_reprs
  nfc: enforce CAP_NET_RAW for raw sockets
  ieee802154: enforce CAP_NET_RAW for raw sockets
  ax25: enforce CAP_NET_RAW for raw sockets
  appletalk: enforce CAP_NET_RAW for raw sockets
  mISDN: enforce CAP_NET_RAW for raw sockets
  net/mlx5: Add device ID of upcoming BlueField-2
  tcp: better handle TCP_USER_TIMEOUT in SYN_SENT state
  net: sched: fix possible crash in tcf_action_destroy()
  usbnet: sanity checking of packet sizes and device mtu
  usbnet: ignore endpoints with invalid wMaxPacketSize
  skge: fix checksum byte order
  sch_netem: fix a divide by zero in tabledist()
  ppp: Fix memory leak in ppp_write
  openvswitch: change type of UPCALL_PID attribute to NLA_UNSPEC
  nfp: flower: fix memory leak in nfp_flower_spawn_vnic_reprs
  net_sched: add max len check for TCA_KIND
  net/sched: act_sample: don't push mac header on ip6gre ingress
  net: qrtr: Stop rx_worker before freeing node
  net/phy: fix DP83865 10 Mbps HDX loopback disable function
  macsec: drop skb sk before calling gro_cells_receive
  cdc_ncm: fix divide-by-zero caused by invalid wMaxPacketSize
  arcnet: provide a buffer big enough to actually receive packets
  ANDROID: properly export new symbols with _GPL tag

Conflicts:
	kernel/sched/cpufreq_schedutil.c
	mm/compaction.c

Change-Id: I3f2cc4a1421480479b9040aa5eefe7e17437021d
Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
2019-10-14 00:52:41 -07:00

1001 lines
24 KiB
C

/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
*/
#ifndef _FS_FUSE_I_H
#define _FS_FUSE_I_H
#include <linux/fuse.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/backing-dev.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/rbtree.h>
#include <linux/poll.h>
#include <linux/workqueue.h>
#include <linux/kref.h>
#include <linux/xattr.h>
#include <linux/pid_namespace.h>
#include <linux/refcount.h>
#include <linux/user_namespace.h>
/** Max number of pages that can be used in a single read request */
#define FUSE_MAX_PAGES_PER_REQ 32
/** Bias for fi->writectr, meaning new writepages must not be sent */
#define FUSE_NOWRITE INT_MIN
/** It could be as large as PATH_MAX, but would that have any uses? */
#define FUSE_NAME_MAX 1024
/** Number of dentries for each connection in the control filesystem */
#define FUSE_CTL_NUM_DENTRIES 5
/** Number of page pointers embedded in fuse_req */
#define FUSE_REQ_INLINE_PAGES 1
/** List of active connections */
extern struct list_head fuse_conn_list;
/** Global mutex protecting fuse_conn_list and the control filesystem */
extern struct mutex fuse_mutex;
/** Module parameters */
extern unsigned max_user_bgreq;
extern unsigned max_user_congthresh;
/* One forget request */
struct fuse_forget_link {
struct fuse_forget_one forget_one;
struct fuse_forget_link *next;
};
/** FUSE inode */
struct fuse_inode {
/** Inode data */
struct inode inode;
/** Unique ID, which identifies the inode between userspace
* and kernel */
u64 nodeid;
/** Number of lookups on this inode */
u64 nlookup;
/** The request used for sending the FORGET message */
struct fuse_forget_link *forget;
/** Time in jiffies until the file attributes are valid */
u64 i_time;
/** The sticky bit in inode->i_mode may have been removed, so
preserve the original mode */
umode_t orig_i_mode;
/** 64 bit inode number */
u64 orig_ino;
/** Version of last attribute change */
u64 attr_version;
/** Files usable in writepage. Protected by fc->lock */
struct list_head write_files;
/** Writepages pending on truncate or fsync */
struct list_head queued_writes;
/** Number of sent writes, a negative bias (FUSE_NOWRITE)
* means more writes are blocked */
int writectr;
/** Waitq for writepage completion */
wait_queue_head_t page_waitq;
/** List of writepage requestst (pending or sent) */
struct list_head writepages;
/** Miscellaneous bits describing inode state */
unsigned long state;
/** Lock for serializing lookup and readdir for back compatibility*/
struct mutex mutex;
};
/** FUSE inode state bits */
enum {
/** Advise readdirplus */
FUSE_I_ADVISE_RDPLUS,
/** Initialized with readdirplus */
FUSE_I_INIT_RDPLUS,
/** An operation changing file size is in progress */
FUSE_I_SIZE_UNSTABLE,
};
struct fuse_conn;
/** FUSE specific file data */
struct fuse_file {
/** Fuse connection for this file */
struct fuse_conn *fc;
/** Request reserved for flush and release */
struct fuse_req *reserved_req;
/** Kernel file handle guaranteed to be unique */
u64 kh;
/** File handle used by userspace */
u64 fh;
/** Node id of this file */
u64 nodeid;
/** Refcount */
refcount_t count;
/** FOPEN_* flags returned by open */
u32 open_flags;
/** Entry on inode's write_files list */
struct list_head write_entry;
/** RB node to be linked on fuse_conn->polled_files */
struct rb_node polled_node;
/** Wait queue head for poll */
wait_queue_head_t poll_wait;
/** Has flock been performed on this file? */
bool flock:1;
};
/** One input argument of a request */
struct fuse_in_arg {
unsigned size;
const void *value;
};
/** The request input */
struct fuse_in {
/** The request header */
struct fuse_in_header h;
/** True if the data for the last argument is in req->pages */
unsigned argpages:1;
/** Number of arguments */
unsigned numargs;
/** Array of arguments */
struct fuse_in_arg args[3];
};
/** One output argument of a request */
struct fuse_arg {
unsigned size;
void *value;
};
/** The request output */
struct fuse_out {
/** Header returned from userspace */
struct fuse_out_header h;
/*
* The following bitfields are not changed during the request
* processing
*/
/** Last argument is variable length (can be shorter than
arg->size) */
unsigned argvar:1;
/** Last argument is a list of pages to copy data to */
unsigned argpages:1;
/** Zero partially or not copied pages */
unsigned page_zeroing:1;
/** Pages may be replaced with new ones */
unsigned page_replace:1;
/** Number or arguments */
unsigned numargs;
/** Array of arguments */
struct fuse_arg args[2];
};
/** FUSE page descriptor */
struct fuse_page_desc {
unsigned int length;
unsigned int offset;
};
struct fuse_args {
struct {
struct {
uint32_t opcode;
uint64_t nodeid;
} h;
unsigned numargs;
struct fuse_in_arg args[3];
} in;
struct {
unsigned argvar:1;
unsigned numargs;
struct fuse_arg args[2];
} out;
};
#define FUSE_ARGS(args) struct fuse_args args = {}
/** The request IO state (for asynchronous processing) */
struct fuse_io_priv {
struct kref refcnt;
int async;
spinlock_t lock;
unsigned reqs;
ssize_t bytes;
size_t size;
__u64 offset;
bool write;
bool should_dirty;
int err;
struct kiocb *iocb;
struct completion *done;
bool blocking;
};
#define FUSE_IO_PRIV_SYNC(i) \
{ \
.refcnt = KREF_INIT(1), \
.async = 0, \
.iocb = i, \
}
/**
* Request flags
*
* FR_ISREPLY: set if the request has reply
* FR_FORCE: force sending of the request even if interrupted
* FR_BACKGROUND: request is sent in the background
* FR_WAITING: request is counted as "waiting"
* FR_ABORTED: the request was aborted
* FR_INTERRUPTED: the request has been interrupted
* FR_LOCKED: data is being copied to/from the request
* FR_PENDING: request is not yet in userspace
* FR_SENT: request is in userspace, waiting for an answer
* FR_FINISHED: request is finished
* FR_PRIVATE: request is on private list
*/
enum fuse_req_flag {
FR_ISREPLY,
FR_FORCE,
FR_BACKGROUND,
FR_WAITING,
FR_ABORTED,
FR_INTERRUPTED,
FR_LOCKED,
FR_PENDING,
FR_SENT,
FR_FINISHED,
FR_PRIVATE,
};
/**
* A request to the client
*
* .waitq.lock protects the following fields:
* - FR_ABORTED
* - FR_LOCKED (may also be modified under fc->lock, tested under both)
*/
struct fuse_req {
/** This can be on either pending processing or io lists in
fuse_conn */
struct list_head list;
/** Entry on the interrupts list */
struct list_head intr_entry;
/** refcount */
refcount_t count;
/** Unique ID for the interrupt request */
u64 intr_unique;
/* Request flags, updated with test/set/clear_bit() */
unsigned long flags;
/** The request input */
struct fuse_in in;
/** The request output */
struct fuse_out out;
/** Used to wake up the task waiting for completion of request*/
wait_queue_head_t waitq;
/** Data for asynchronous requests */
union {
struct {
struct fuse_release_in in;
struct inode *inode;
} release;
struct fuse_init_in init_in;
struct fuse_init_out init_out;
struct cuse_init_in cuse_init_in;
struct {
struct fuse_read_in in;
u64 attr_ver;
} read;
struct {
struct fuse_write_in in;
struct fuse_write_out out;
struct fuse_req *next;
} write;
struct fuse_notify_retrieve_in retrieve_in;
} misc;
/** page vector */
struct page **pages;
/** page-descriptor vector */
struct fuse_page_desc *page_descs;
/** size of the 'pages' array */
unsigned max_pages;
/** inline page vector */
struct page *inline_pages[FUSE_REQ_INLINE_PAGES];
/** inline page-descriptor vector */
struct fuse_page_desc inline_page_descs[FUSE_REQ_INLINE_PAGES];
/** number of pages in vector */
unsigned num_pages;
/** File used in the request (or NULL) */
struct fuse_file *ff;
/** Inode used in the request or NULL */
struct inode *inode;
/** Path used for completing d_canonical_path */
struct path *canonical_path;
/** AIO control block */
struct fuse_io_priv *io;
/** Link on fi->writepages */
struct list_head writepages_entry;
/** Request completion callback */
void (*end)(struct fuse_conn *, struct fuse_req *);
/** Request is stolen from fuse_file->reserved_req */
struct file *stolen_file;
};
struct fuse_iqueue {
/** Connection established */
unsigned connected;
/** Lock protecting accesses to members of this structure */
spinlock_t lock;
/** Readers of the connection are waiting on this */
wait_queue_head_t waitq;
/** The next unique request id */
u64 reqctr;
/** The list of pending requests */
struct list_head pending;
/** Pending interrupts */
struct list_head interrupts;
/** Queue of pending forgets */
struct fuse_forget_link forget_list_head;
struct fuse_forget_link *forget_list_tail;
/** Batching of FORGET requests (positive indicates FORGET batch) */
int forget_batch;
/** O_ASYNC requests */
struct fasync_struct *fasync;
};
struct fuse_pqueue {
/** Connection established */
unsigned connected;
/** Lock protecting accessess to members of this structure */
spinlock_t lock;
/** The list of requests being processed */
struct list_head processing;
/** The list of requests under I/O */
struct list_head io;
};
/**
* Fuse device instance
*/
struct fuse_dev {
/** Fuse connection for this device */
struct fuse_conn *fc;
/** Processing queue */
struct fuse_pqueue pq;
/** list entry on fc->devices */
struct list_head entry;
};
/**
* A Fuse connection.
*
* This structure is created, when the filesystem is mounted, and is
* destroyed, when the client device is closed and the filesystem is
* unmounted.
*/
struct fuse_conn {
/** Lock protecting accessess to members of this structure */
spinlock_t lock;
/** Refcount */
refcount_t count;
/** Number of fuse_dev's */
atomic_t dev_count;
struct rcu_head rcu;
/** The user id for this mount */
kuid_t user_id;
/** The group id for this mount */
kgid_t group_id;
/** The pid namespace for this mount */
struct pid_namespace *pid_ns;
/** The user namespace for this mount */
struct user_namespace *user_ns;
/** Maximum read size */
unsigned max_read;
/** Maximum write size */
unsigned max_write;
/** Input queue */
struct fuse_iqueue iq;
/** The next unique kernel file handle */
u64 khctr;
/** rbtree of fuse_files waiting for poll events indexed by ph */
struct rb_root polled_files;
/** Maximum number of outstanding background requests */
unsigned max_background;
/** Number of background requests at which congestion starts */
unsigned congestion_threshold;
/** Number of requests currently in the background */
unsigned num_background;
/** Number of background requests currently queued for userspace */
unsigned active_background;
/** The list of background requests set aside for later queuing */
struct list_head bg_queue;
/** Flag indicating that INIT reply has been received. Allocating
* any fuse request will be suspended until the flag is set */
int initialized;
/** Flag indicating if connection is blocked. This will be
the case before the INIT reply is received, and if there
are too many outstading backgrounds requests */
int blocked;
/** waitq for blocked connection */
wait_queue_head_t blocked_waitq;
/** waitq for reserved requests */
wait_queue_head_t reserved_req_waitq;
/** Connection established, cleared on umount, connection
abort and device release */
unsigned connected;
/** Connection aborted via sysfs */
bool aborted;
/** Connection failed (version mismatch). Cannot race with
setting other bitfields since it is only set once in INIT
reply, before any other request, and never cleared */
unsigned conn_error:1;
/** Connection successful. Only set in INIT */
unsigned conn_init:1;
/** Do readpages asynchronously? Only set in INIT */
unsigned async_read:1;
/** Return an unique read error after abort. Only set in INIT */
unsigned abort_err:1;
/** Do not send separate SETATTR request before open(O_TRUNC) */
unsigned atomic_o_trunc:1;
/** Filesystem supports NFS exporting. Only set in INIT */
unsigned export_support:1;
/** write-back cache policy (default is write-through) */
unsigned writeback_cache:1;
/** allow parallel lookups and readdir (default is serialized) */
unsigned parallel_dirops:1;
/** handle fs handles killing suid/sgid/cap on write/chown/trunc */
unsigned handle_killpriv:1;
/*
* The following bitfields are only for optimization purposes
* and hence races in setting them will not cause malfunction
*/
/** Is open/release not implemented by fs? */
unsigned no_open:1;
/** Is fsync not implemented by fs? */
unsigned no_fsync:1;
/** Is fsyncdir not implemented by fs? */
unsigned no_fsyncdir:1;
/** Is flush not implemented by fs? */
unsigned no_flush:1;
/** Is setxattr not implemented by fs? */
unsigned no_setxattr:1;
/** Is getxattr not implemented by fs? */
unsigned no_getxattr:1;
/** Is listxattr not implemented by fs? */
unsigned no_listxattr:1;
/** Is removexattr not implemented by fs? */
unsigned no_removexattr:1;
/** Are posix file locking primitives not implemented by fs? */
unsigned no_lock:1;
/** Is access not implemented by fs? */
unsigned no_access:1;
/** Is create not implemented by fs? */
unsigned no_create:1;
/** Is interrupt not implemented by fs? */
unsigned no_interrupt:1;
/** Is bmap not implemented by fs? */
unsigned no_bmap:1;
/** Is poll not implemented by fs? */
unsigned no_poll:1;
/** Do multi-page cached writes */
unsigned big_writes:1;
/** Don't apply umask to creation modes */
unsigned dont_mask:1;
/** Are BSD file locking primitives not implemented by fs? */
unsigned no_flock:1;
/** Is fallocate not implemented by fs? */
unsigned no_fallocate:1;
/** Is rename with flags implemented by fs? */
unsigned no_rename2:1;
/** Use enhanced/automatic page cache invalidation. */
unsigned auto_inval_data:1;
/** Does the filesystem support readdirplus? */
unsigned do_readdirplus:1;
/** Does the filesystem want adaptive readdirplus? */
unsigned readdirplus_auto:1;
/** Does the filesystem support asynchronous direct-IO submission? */
unsigned async_dio:1;
/** Is lseek not implemented by fs? */
unsigned no_lseek:1;
/** Does the filesystem support posix acls? */
unsigned posix_acl:1;
/** Check permissions based on the file mode or not? */
unsigned default_permissions:1;
/** Allow other than the mounter user to access the filesystem ? */
unsigned allow_other:1;
/** The number of requests waiting for completion */
atomic_t num_waiting;
/** Negotiated minor version */
unsigned minor;
/** Entry on the fuse_conn_list */
struct list_head entry;
/** Device ID from super block */
dev_t dev;
/** Dentries in the control filesystem */
struct dentry *ctl_dentry[FUSE_CTL_NUM_DENTRIES];
/** number of dentries used in the above array */
int ctl_ndents;
/** Key for lock owner ID scrambling */
u32 scramble_key[4];
/** Reserved request for the DESTROY message */
struct fuse_req *destroy_req;
/** Version counter for attribute changes */
u64 attr_version;
/** Called on final put */
void (*release)(struct fuse_conn *);
/** Super block for this connection. */
struct super_block *sb;
/** Read/write semaphore to hold when accessing sb. */
struct rw_semaphore killsb;
/** List of device instances belonging to this connection */
struct list_head devices;
};
static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb)
{
return sb->s_fs_info;
}
static inline struct fuse_conn *get_fuse_conn(struct inode *inode)
{
return get_fuse_conn_super(inode->i_sb);
}
static inline struct fuse_inode *get_fuse_inode(struct inode *inode)
{
return container_of(inode, struct fuse_inode, inode);
}
static inline u64 get_node_id(struct inode *inode)
{
return get_fuse_inode(inode)->nodeid;
}
/** Device operations */
extern const struct file_operations fuse_dev_operations;
extern const struct dentry_operations fuse_dentry_operations;
extern const struct dentry_operations fuse_root_dentry_operations;
/**
* Inode to nodeid comparison.
*/
int fuse_inode_eq(struct inode *inode, void *_nodeidp);
/**
* Get a filled in inode
*/
struct inode *fuse_iget(struct super_block *sb, u64 nodeid,
int generation, struct fuse_attr *attr,
u64 attr_valid, u64 attr_version);
int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
struct fuse_entry_out *outarg, struct inode **inode);
/**
* Send FORGET command
*/
void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
u64 nodeid, u64 nlookup);
struct fuse_forget_link *fuse_alloc_forget(void);
/* Used by READDIRPLUS */
void fuse_force_forget(struct file *file, u64 nodeid);
/**
* Initialize READ or READDIR request
*/
void fuse_read_fill(struct fuse_req *req, struct file *file,
loff_t pos, size_t count, int opcode);
/**
* Send OPEN or OPENDIR request
*/
int fuse_open_common(struct inode *inode, struct file *file, bool isdir);
struct fuse_file *fuse_file_alloc(struct fuse_conn *fc);
void fuse_file_free(struct fuse_file *ff);
void fuse_finish_open(struct inode *inode, struct file *file);
void fuse_sync_release(struct fuse_file *ff, int flags);
/**
* Send RELEASE or RELEASEDIR request
*/
void fuse_release_common(struct file *file, bool isdir);
/**
* Send FSYNC or FSYNCDIR request
*/
int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
int datasync, int isdir);
/**
* Notify poll wakeup
*/
int fuse_notify_poll_wakeup(struct fuse_conn *fc,
struct fuse_notify_poll_wakeup_out *outarg);
/**
* Initialize file operations on a regular file
*/
void fuse_init_file_inode(struct inode *inode);
/**
* Initialize inode operations on regular files and special files
*/
void fuse_init_common(struct inode *inode);
/**
* Initialize inode and file operations on a directory
*/
void fuse_init_dir(struct inode *inode);
/**
* Initialize inode operations on a symlink
*/
void fuse_init_symlink(struct inode *inode);
/**
* Change attributes of an inode
*/
void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr,
u64 attr_valid, u64 attr_version);
void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
u64 attr_valid);
/**
* Initialize the client device
*/
int fuse_dev_init(void);
/**
* Cleanup the client device
*/
void fuse_dev_cleanup(void);
int fuse_ctl_init(void);
void __exit fuse_ctl_cleanup(void);
/**
* Allocate a request
*/
struct fuse_req *fuse_request_alloc(unsigned npages);
struct fuse_req *fuse_request_alloc_nofs(unsigned npages);
/**
* Free a request
*/
void fuse_request_free(struct fuse_req *req);
/**
* Get a request, may fail with -ENOMEM,
* caller should specify # elements in req->pages[] explicitly
*/
struct fuse_req *fuse_get_req(struct fuse_conn *fc, unsigned npages);
struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
unsigned npages);
/*
* Increment reference count on request
*/
void __fuse_get_request(struct fuse_req *req);
/**
* Gets a requests for a file operation, always succeeds
*/
struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc,
struct file *file);
/**
* Decrement reference count of a request. If count goes to zero free
* the request.
*/
void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
/**
* Send a request (synchronous)
*/
void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
/**
* Simple request sending that does request allocation and freeing
*/
ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
/**
* Send a request in the background
*/
void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req);
void fuse_request_send_background_locked(struct fuse_conn *fc,
struct fuse_req *req);
/* Abort all requests */
void fuse_abort_conn(struct fuse_conn *fc, bool is_abort);
void fuse_wait_aborted(struct fuse_conn *fc);
/**
* Invalidate inode attributes
*/
void fuse_invalidate_attr(struct inode *inode);
void fuse_invalidate_entry_cache(struct dentry *entry);
void fuse_invalidate_atime(struct inode *inode);
/**
* Acquire reference to fuse_conn
*/
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
/**
* Initialize fuse_conn
*/
void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns);
/**
* Release reference to fuse_conn
*/
void fuse_conn_put(struct fuse_conn *fc);
struct fuse_dev *fuse_dev_alloc(struct fuse_conn *fc);
void fuse_dev_free(struct fuse_dev *fud);
/**
* Add connection to control filesystem
*/
int fuse_ctl_add_conn(struct fuse_conn *fc);
/**
* Remove connection from control filesystem
*/
void fuse_ctl_remove_conn(struct fuse_conn *fc);
/**
* Is file type valid?
*/
int fuse_valid_type(int m);
/**
* Is current process allowed to perform filesystem operation?
*/
int fuse_allow_current_process(struct fuse_conn *fc);
u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
void fuse_update_ctime(struct inode *inode);
int fuse_update_attributes(struct inode *inode, struct file *file);
void fuse_flush_writepages(struct inode *inode);
void fuse_set_nowrite(struct inode *inode);
void fuse_release_nowrite(struct inode *inode);
u64 fuse_get_attr_version(struct fuse_conn *fc);
/**
* File-system tells the kernel to invalidate cache for the given node id.
*/
int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
loff_t offset, loff_t len);
/**
* File-system tells the kernel to invalidate parent attributes and
* the dentry matching parent/name.
*
* If the child_nodeid is non-zero and:
* - matches the inode number for the dentry matching parent/name,
* - is not a mount point
* - is a file or oan empty directory
* then the dentry is unhashed (d_delete()).
*/
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
u64 child_nodeid, struct qstr *name);
int fuse_do_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
bool isdir);
/**
* fuse_direct_io() flags
*/
/** If set, it is WRITE; otherwise - READ */
#define FUSE_DIO_WRITE (1 << 0)
/** CUSE pass fuse_direct_io() a file which f_mapping->host is not from FUSE */
#define FUSE_DIO_CUSE (1 << 1)
ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
loff_t *ppos, int flags);
long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
unsigned int flags);
long fuse_ioctl_common(struct file *file, unsigned int cmd,
unsigned long arg, unsigned int flags);
__poll_t fuse_file_poll(struct file *file, poll_table *wait);
int fuse_dev_release(struct inode *inode, struct file *file);
bool fuse_write_update_size(struct inode *inode, loff_t pos);
int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
struct file *file);
void fuse_set_initialized(struct fuse_conn *fc);
void fuse_unlock_inode(struct inode *inode, bool locked);
bool fuse_lock_inode(struct inode *inode);
int fuse_setxattr(struct inode *inode, const char *name, const void *value,
size_t size, int flags);
ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
size_t size);
ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size);
int fuse_removexattr(struct inode *inode, const char *name);
extern const struct xattr_handler *fuse_xattr_handlers[];
extern const struct xattr_handler *fuse_acl_xattr_handlers[];
extern const struct xattr_handler *fuse_no_acl_xattr_handlers[];
struct posix_acl;
struct posix_acl *fuse_get_acl(struct inode *inode, int type);
int fuse_set_acl(struct inode *inode, struct posix_acl *acl, int type);
#endif /* _FS_FUSE_I_H */