Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  fs.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_FS_H
#define _LINUX_FS_H

#include <linux/vfsdebug.h>
#include <linux/linkage.h>
#include <linux/wait_bit.h>
#include <linux/kdev_t.h>
#include <linux/dcache.h>
#include <linux/path.h>
#include <linux/stat.h>
#include <linux/cache.h>
#include <linux/list.h>
#include <linux/list_lru.h>
#include <linux/llist.h>
#include <linux/radix-tree.h>
#include <linux/xarray.h>
#include <linux/rbtree.h>
#include <linux/init.h>
#include <linux/pid.h>
#include <linux/bug.h>
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/mm_types.h>
#include <linux/capability.h>
#include <linux/semaphore.h>
#include <linux/fcntl.h>
#include <linux/rculist_bl.h>
#include <linux/atomic.h>
#include <linux/shrinker.h>
#include <linux/migrate_mode.h>
#include <linux/uidgid.h>
#include <linux/lockdep.h>
#include <linux/percpu-rwsem.h>
#include <linux/workqueue.h>
#include <linux/delayed_call.h>
#include <linux/uuid.h>
#include <linux/errseq.h>
#include <linux/ioprio.h>
#include <linux/fs_types.h>
#include <linux/build_bug.h>
#include <linux/stddef.h>
#include <linux/mount.h>
#include <linux/cred.h>
#include <linux/mnt_idmapping.h>
#include <linux/slab.h>
#include <linux/maple_tree.h>
#include <linux/rw_hint.h>
#include <linux/file_ref.h>
#include <linux/unicode.h>

#include <asm/byteorder.h>
#include <uapi/linux/fs.h>

struct backing_dev_info;
struct bdi_writeback;
struct bio;
struct io_comp_batch;
struct export_operations;
struct fiemap_extent_info;
struct hd_geometry;
struct iovec;
struct kiocb;
struct kobject;
struct pipe_inode_info;
struct poll_table_struct;
struct kstatfs;
struct vm_area_struct;
struct vfsmount;
struct cred;
struct swap_info_struct;
struct seq_file;
struct workqueue_struct;
struct iov_iter;
struct fscrypt_inode_info;
struct fscrypt_operations;
struct fsverity_info;
struct fsverity_operations;
struct fsnotify_mark_connector;
struct fsnotify_sb_info;
struct fs_context;
struct fs_parameter_spec;
struct file_kattr;
struct iomap_ops;

extern void __init inode_init(void);
extern void __init inode_init_early(void);
extern void __init files_init(void);
extern void __init files_maxfiles_init(void);

extern unsigned long get_max_files(void);
extern unsigned int sysctl_nr_open;

typedef __kernel_rwf_t rwf_t;

struct buffer_head;
typedef int (get_block_t)(struct inode *inode, sector_t iblock,
   struct buffer_head *bh_result, int create);
typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
   ssize_t bytes, void *private);

#define MAY_EXEC  0x00000001
#define MAY_WRITE  0x00000002
#define MAY_READ  0x00000004
#define MAY_APPEND  0x00000008
#define MAY_ACCESS  0x00000010
#define MAY_OPEN  0x00000020
#define MAY_CHDIR  0x00000040
/* called from RCU mode, don't block */
#define MAY_NOT_BLOCK  0x00000080

/*
 * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
 * to O_WRONLY and O_RDWR via the strange trick in do_dentry_open()
 */


/* file is open for reading */
#define FMODE_READ  ((__force fmode_t)(1 << 0))
/* file is open for writing */
#define FMODE_WRITE  ((__force fmode_t)(1 << 1))
/* file is seekable */
#define FMODE_LSEEK  ((__force fmode_t)(1 << 2))
/* file can be accessed using pread */
#define FMODE_PREAD  ((__force fmode_t)(1 << 3))
/* file can be accessed using pwrite */
#define FMODE_PWRITE  ((__force fmode_t)(1 << 4))
/* File is opened for execution with sys_execve / sys_uselib */
#define FMODE_EXEC  ((__force fmode_t)(1 << 5))
/* File writes are restricted (block device specific) */
#define FMODE_WRITE_RESTRICTED ((__force fmode_t)(1 << 6))
/* File supports atomic writes */
#define FMODE_CAN_ATOMIC_WRITE ((__force fmode_t)(1 << 7))

/* FMODE_* bit 8 */

/* 32bit hashes as llseek() offset (for directories) */
#define FMODE_32BITHASH         ((__force fmode_t)(1 << 9))
/* 64bit hashes as llseek() offset (for directories) */
#define FMODE_64BITHASH         ((__force fmode_t)(1 << 10))

/*
 * Don't update ctime and mtime.
 *
 * Currently a special hack for the XFS open_by_handle ioctl, but we'll
 * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
 */

#define FMODE_NOCMTIME  ((__force fmode_t)(1 << 11))

/* Expect random access pattern */
#define FMODE_RANDOM  ((__force fmode_t)(1 << 12))

/* Supports IOCB_HAS_METADATA */
#define FMODE_HAS_METADATA ((__force fmode_t)(1 << 13))

/* File is opened with O_PATH; almost nothing can be done with it */
#define FMODE_PATH  ((__force fmode_t)(1 << 14))

/* File needs atomic accesses to f_pos */
#define FMODE_ATOMIC_POS ((__force fmode_t)(1 << 15))
/* Write access to underlying fs */
#define FMODE_WRITER  ((__force fmode_t)(1 << 16))
/* Has read method(s) */
#define FMODE_CAN_READ          ((__force fmode_t)(1 << 17))
/* Has write method(s) */
#define FMODE_CAN_WRITE         ((__force fmode_t)(1 << 18))

#define FMODE_OPENED  ((__force fmode_t)(1 << 19))
#define FMODE_CREATED  ((__force fmode_t)(1 << 20))

/* File is stream-like */
#define FMODE_STREAM  ((__force fmode_t)(1 << 21))

/* File supports DIRECT IO */
#define FMODE_CAN_ODIRECT ((__force fmode_t)(1 << 22))

#define FMODE_NOREUSE  ((__force fmode_t)(1 << 23))

/* File is embedded in backing_file object */
#define FMODE_BACKING  ((__force fmode_t)(1 << 24))

/*
 * Together with FMODE_NONOTIFY_PERM defines which fsnotify events shouldn't be
 * generated (see below)
 */

#define FMODE_NONOTIFY  ((__force fmode_t)(1 << 25))

/*
 * Together with FMODE_NONOTIFY defines which fsnotify events shouldn't be
 * generated (see below)
 */

#define FMODE_NONOTIFY_PERM ((__force fmode_t)(1 << 26))

/* File is capable of returning -EAGAIN if I/O will block */
#define FMODE_NOWAIT  ((__force fmode_t)(1 << 27))

/* File represents mount that needs unmounting */
#define FMODE_NEED_UNMOUNT ((__force fmode_t)(1 << 28))

/* File does not contribute to nr_files count */
#define FMODE_NOACCOUNT  ((__force fmode_t)(1 << 29))

/*
 * The two FMODE_NONOTIFY* define which fsnotify events should not be generated
 * for an open file. These are the possible values of
 * (f->f_mode & FMODE_FSNOTIFY_MASK) and their meaning:
 *
 * FMODE_NONOTIFY - suppress all (incl. non-permission) events.
 * FMODE_NONOTIFY_PERM - suppress permission (incl. pre-content) events.
 * FMODE_NONOTIFY | FMODE_NONOTIFY_PERM - suppress only FAN_ACCESS_PERM.
 */

#define FMODE_FSNOTIFY_MASK \
 (FMODE_NONOTIFY | FMODE_NONOTIFY_PERM)

#define FMODE_FSNOTIFY_NONE(mode) \
 ((mode & FMODE_FSNOTIFY_MASK) == FMODE_NONOTIFY)
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
#define FMODE_FSNOTIFY_HSM(mode) \
 ((mode & FMODE_FSNOTIFY_MASK) == 0 || \
  (mode & FMODE_FSNOTIFY_MASK) == (FMODE_NONOTIFY | FMODE_NONOTIFY_PERM))
#define FMODE_FSNOTIFY_ACCESS_PERM(mode) \
 ((mode & FMODE_FSNOTIFY_MASK) == 0)
#else
#define FMODE_FSNOTIFY_ACCESS_PERM(mode) 0
#define FMODE_FSNOTIFY_HSM(mode) 0
#endif

/*
 * Attribute flags.  These should be or-ed together to figure out what
 * has been changed!
 */

#define ATTR_MODE (1 << 0)
#define ATTR_UID (1 << 1)
#define ATTR_GID (1 << 2)
#define ATTR_SIZE (1 << 3)
#define ATTR_ATIME (1 << 4)
#define ATTR_MTIME (1 << 5)
#define ATTR_CTIME (1 << 6)
#define ATTR_ATIME_SET (1 << 7)
#define ATTR_MTIME_SET (1 << 8)
#define ATTR_FORCE (1 << 9) /* Not a change, but a change it */
#define ATTR_CTIME_SET (1 << 10)
#define ATTR_KILL_SUID (1 << 11)
#define ATTR_KILL_SGID (1 << 12)
#define ATTR_FILE (1 << 13)
#define ATTR_KILL_PRIV (1 << 14)
#define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
#define ATTR_TIMES_SET (1 << 16)
#define ATTR_TOUCH (1 << 17)
#define ATTR_DELEG (1 << 18) /* Delegated attrs. Don't break write delegations */

/*
 * Whiteout is represented by a char device.  The following constants define the
 * mode and device number to use.
 */

#define WHITEOUT_MODE 0
#define WHITEOUT_DEV 0

/*
 * This is the Inode Attributes structure, used for notify_change().  It
 * uses the above definitions as flags, to know which values have changed.
 * Also, in this manner, a Filesystem can look at only the values it cares
 * about.  Basically, these are the attributes that the VFS layer can
 * request to change from the FS layer.
 *
 * Derek Atkins <warlord@MIT.EDU> 94-10-20
 */

struct iattr {
 unsigned int ia_valid;
 umode_t  ia_mode;
 /*
 * The two anonymous unions wrap structures with the same member.
 *
 * Filesystems raising FS_ALLOW_IDMAP need to use ia_vfs{g,u}id which
 * are a dedicated type requiring the filesystem to use the dedicated
 * helpers. Other filesystem can continue to use ia_{g,u}id until they
 * have been ported.
 *
 * They always contain the same value. In other words FS_ALLOW_IDMAP
 * pass down the same value on idmapped mounts as they would on regular
 * mounts.
 */

 union {
  kuid_t  ia_uid;
  vfsuid_t ia_vfsuid;
 };
 union {
  kgid_t  ia_gid;
  vfsgid_t ia_vfsgid;
 };
 loff_t  ia_size;
 struct timespec64 ia_atime;
 struct timespec64 ia_mtime;
 struct timespec64 ia_ctime;

 /*
 * Not an attribute, but an auxiliary info for filesystems wanting to
 * implement an ftruncate() like method.  NOTE: filesystem should
 * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
 */

 struct file *ia_file;
};

/*
 * Includes for diskquotas.
 */

#include <linux/quota.h>

/*
 * Maximum number of layers of fs stack.  Needs to be limited to
 * prevent kernel stack overflow
 */

#define FILESYSTEM_MAX_STACK_DEPTH 2

/** 
 * enum positive_aop_returns - aop return codes with specific semantics
 *
 * @AOP_WRITEPAGE_ACTIVATE: Informs the caller that page writeback has
 *      completed, that the page is still locked, and
 *      should be considered active.  The VM uses this hint
 *      to return the page to the active list -- it won't
 *      be a candidate for writeback again in the near
 *      future.  Other callers must be careful to unlock
 *      the page if they get this return.  Returned by
 *      writepage(); 
 *
 * @AOP_TRUNCATED_PAGE: The AOP method that was handed a locked page has
 *   unlocked it and the page might have been truncated.
 *   The caller should back up to acquiring a new page and
 *   trying again.  The aop will be taking reasonable
 *   precautions not to livelock.  If the caller held a page
 *   reference, it should drop it before retrying.  Returned
 *   by read_folio().
 *
 * address_space_operation functions return these large constants to indicate
 * special semantics to the caller.  These are much larger than the bytes in a
 * page to allow for functions that return the number of bytes operated on in a
 * given page.
 */


enum positive_aop_returns {
 AOP_WRITEPAGE_ACTIVATE = 0x80000,
 AOP_TRUNCATED_PAGE = 0x80001,
};

/*
 * oh the beauties of C type declarations.
 */

struct page;
struct address_space;
struct writeback_control;
struct readahead_control;

/* Match RWF_* bits to IOCB bits */
#define IOCB_HIPRI  (__force int) RWF_HIPRI
#define IOCB_DSYNC  (__force int) RWF_DSYNC
#define IOCB_SYNC  (__force int) RWF_SYNC
#define IOCB_NOWAIT  (__force int) RWF_NOWAIT
#define IOCB_APPEND  (__force int) RWF_APPEND
#define IOCB_ATOMIC  (__force int) RWF_ATOMIC
#define IOCB_DONTCACHE  (__force int) RWF_DONTCACHE

/* non-RWF related bits - start at 16 */
#define IOCB_EVENTFD  (1 << 16)
#define IOCB_DIRECT  (1 << 17)
#define IOCB_WRITE  (1 << 18)
/* iocb->ki_waitq is valid */
#define IOCB_WAITQ  (1 << 19)
#define IOCB_NOIO  (1 << 20)
/* can use bio alloc cache */
#define IOCB_ALLOC_CACHE (1 << 21)
/*
 * IOCB_DIO_CALLER_COMP can be set by the iocb owner, to indicate that the
 * iocb completion can be passed back to the owner for execution from a safe
 * context rather than needing to be punted through a workqueue. If this
 * flag is set, the bio completion handling may set iocb->dio_complete to a
 * handler function and iocb->private to context information for that handler.
 * The issuer should call the handler with that context information from task
 * context to complete the processing of the iocb. Note that while this
 * provides a task context for the dio_complete() callback, it should only be
 * used on the completion side for non-IO generating completions. It's fine to
 * call blocking functions from this callback, but they should not wait for
 * unrelated IO (like cache flushing, new IO generation, etc).
 */

#define IOCB_DIO_CALLER_COMP (1 << 22)
/* kiocb is a read or write operation submitted by fs/aio.c. */
#define IOCB_AIO_RW  (1 << 23)
#define IOCB_HAS_METADATA (1 << 24)

/* for use in trace events */
#define TRACE_IOCB_STRINGS \
 { IOCB_HIPRI,  "HIPRI" }, \
 { IOCB_DSYNC,  "DSYNC" }, \
 { IOCB_SYNC,  "SYNC" }, \
 { IOCB_NOWAIT,  "NOWAIT" }, \
 { IOCB_APPEND,  "APPEND" }, \
 { IOCB_ATOMIC,  "ATOMIC" }, \
 { IOCB_DONTCACHE, "DONTCACHE" }, \
 { IOCB_EVENTFD,  "EVENTFD"}, \
 { IOCB_DIRECT,  "DIRECT" }, \
 { IOCB_WRITE,  "WRITE" }, \
 { IOCB_WAITQ,  "WAITQ" }, \
 { IOCB_NOIO,  "NOIO" }, \
 { IOCB_ALLOC_CACHE, "ALLOC_CACHE" }, \
 { IOCB_DIO_CALLER_COMP, "CALLER_COMP" }, \
 { IOCB_AIO_RW,  "AIO_RW" }, \
 { IOCB_HAS_METADATA, "AIO_HAS_METADATA" }

struct kiocb {
 struct file  *ki_filp;
 loff_t   ki_pos;
 void (*ki_complete)(struct kiocb *iocb, long ret);
 void   *private;
 int   ki_flags;
 u16   ki_ioprio; /* See linux/ioprio.h */
 u8   ki_write_stream;
 union {
  /*
 * Only used for async buffered reads, where it denotes the
 * page waitqueue associated with completing the read. Valid
 * IFF IOCB_WAITQ is set.
 */

  struct wait_page_queue *ki_waitq;
  /*
 * Can be used for O_DIRECT IO, where the completion handling
 * is punted back to the issuer of the IO. May only be set
 * if IOCB_DIO_CALLER_COMP is set by the issuer, and the issuer
 * must then check for presence of this handler when ki_complete
 * is invoked. The data passed in to this handler must be
 * assigned to ->private when dio_complete is assigned.
 */

  ssize_t (*dio_complete)(void *data);
 };
};

static inline bool is_sync_kiocb(struct kiocb *kiocb)
{
 return kiocb->ki_complete == NULL;
}

struct address_space_operations {
 int (*read_folio)(struct file *, struct folio *);

 /* Write back some dirty pages from this mapping. */
 int (*writepages)(struct address_space *, struct writeback_control *);

 /* Mark a folio dirty.  Return true if this dirtied it */
 bool (*dirty_folio)(struct address_space *, struct folio *);

 void (*readahead)(struct readahead_control *);

 int (*write_begin)(const struct kiocb *, struct address_space *mapping,
    loff_t pos, unsigned len,
    struct folio **foliop, void **fsdata);
 int (*write_end)(const struct kiocb *, struct address_space *mapping,
    loff_t pos, unsigned len, unsigned copied,
    struct folio *folio, void *fsdata);

 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
 sector_t (*bmap)(struct address_space *, sector_t);
 void (*invalidate_folio) (struct folio *, size_t offset, size_t len);
 bool (*release_folio)(struct folio *, gfp_t);
 void (*free_folio)(struct folio *folio);
 ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
 /*
 * migrate the contents of a folio to the specified target. If
 * migrate_mode is MIGRATE_ASYNC, it must not block.
 */

 int (*migrate_folio)(struct address_space *, struct folio *dst,
   struct folio *src, enum migrate_mode);
 int (*launder_folio)(struct folio *);
 bool (*is_partially_uptodate) (struct folio *, size_t from,
   size_t count);
 void (*is_dirty_writeback) (struct folio *, bool *dirty, bool *wb);
 int (*error_remove_folio)(struct address_space *, struct folio *);

 /* swapfile support */
 int (*swap_activate)(struct swap_info_struct *sis, struct file *file,
    sector_t *span);
 void (*swap_deactivate)(struct file *file);
 int (*swap_rw)(struct kiocb *iocb, struct iov_iter *iter);
};

extern const struct address_space_operations empty_aops;

/**
 * struct address_space - Contents of a cacheable, mappable object.
 * @host: Owner, either the inode or the block_device.
 * @i_pages: Cached pages.
 * @invalidate_lock: Guards coherency between page cache contents and
 *   file offset->disk block mappings in the filesystem during invalidates.
 *   It is also used to block modification of page cache contents through
 *   memory mappings.
 * @gfp_mask: Memory allocation flags to use for allocating pages.
 * @i_mmap_writable: Number of VM_SHARED, VM_MAYWRITE mappings.
 * @nr_thps: Number of THPs in the pagecache (non-shmem only).
 * @i_mmap: Tree of private and shared mappings.
 * @i_mmap_rwsem: Protects @i_mmap and @i_mmap_writable.
 * @nrpages: Number of page entries, protected by the i_pages lock.
 * @writeback_index: Writeback starts here.
 * @a_ops: Methods.
 * @flags: Error bits and flags (AS_*).
 * @wb_err: The most recent error which has occurred.
 * @i_private_lock: For use by the owner of the address_space.
 * @i_private_list: For use by the owner of the address_space.
 * @i_private_data: For use by the owner of the address_space.
 */

struct address_space {
 struct inode  *host;
 struct xarray  i_pages;
 struct rw_semaphore invalidate_lock;
 gfp_t   gfp_mask;
 atomic_t  i_mmap_writable;
#ifdef CONFIG_READ_ONLY_THP_FOR_FS
 /* number of thp, only for non-shmem files */
 atomic_t  nr_thps;
#endif
 struct rb_root_cached i_mmap;
 unsigned long  nrpages;
 pgoff_t   writeback_index;
 const struct address_space_operations *a_ops;
 unsigned long  flags;
 errseq_t  wb_err;
 spinlock_t  i_private_lock;
 struct list_head i_private_list;
 struct rw_semaphore i_mmap_rwsem;
 void *   i_private_data;
} __attribute__((aligned(sizeof(long)))) __randomize_layout;
 /*
 * On most architectures that alignment is already the case; but
 * must be enforced here for CRIS, to let the least significant bit
 * of struct folio's "mapping" pointer be used for FOLIO_MAPPING_ANON.
 */


/* XArray tags, for tagging dirty and writeback pages in the pagecache. */
#define PAGECACHE_TAG_DIRTY XA_MARK_0
#define PAGECACHE_TAG_WRITEBACK XA_MARK_1
#define PAGECACHE_TAG_TOWRITE XA_MARK_2

/*
 * Returns true if any of the pages in the mapping are marked with the tag.
 */

static inline bool mapping_tagged(struct address_space *mapping, xa_mark_t tag)
{
 return xa_marked(&mapping->i_pages, tag);
}

static inline void i_mmap_lock_write(struct address_space *mapping)
{
 down_write(&mapping->i_mmap_rwsem);
}

static inline int i_mmap_trylock_write(struct address_space *mapping)
{
 return down_write_trylock(&mapping->i_mmap_rwsem);
}

static inline void i_mmap_unlock_write(struct address_space *mapping)
{
 up_write(&mapping->i_mmap_rwsem);
}

static inline int i_mmap_trylock_read(struct address_space *mapping)
{
 return down_read_trylock(&mapping->i_mmap_rwsem);
}

static inline void i_mmap_lock_read(struct address_space *mapping)
{
 down_read(&mapping->i_mmap_rwsem);
}

static inline void i_mmap_unlock_read(struct address_space *mapping)
{
 up_read(&mapping->i_mmap_rwsem);
}

static inline void i_mmap_assert_locked(struct address_space *mapping)
{
 lockdep_assert_held(&mapping->i_mmap_rwsem);
}

static inline void i_mmap_assert_write_locked(struct address_space *mapping)
{
 lockdep_assert_held_write(&mapping->i_mmap_rwsem);
}

/*
 * Might pages of this file be mapped into userspace?
 */

static inline int mapping_mapped(struct address_space *mapping)
{
 return !RB_EMPTY_ROOT(&mapping->i_mmap.rb_root);
}

/*
 * Might pages of this file have been modified in userspace?
 * Note that i_mmap_writable counts all VM_SHARED, VM_MAYWRITE vmas: do_mmap
 * marks vma as VM_SHARED if it is shared, and the file was opened for
 * writing i.e. vma may be mprotected writable even if now readonly.
 *
 * If i_mmap_writable is negative, no new writable mappings are allowed. You
 * can only deny writable mappings, if none exists right now.
 */

static inline int mapping_writably_mapped(struct address_space *mapping)
{
 return atomic_read(&mapping->i_mmap_writable) > 0;
}

static inline int mapping_map_writable(struct address_space *mapping)
{
 return atomic_inc_unless_negative(&mapping->i_mmap_writable) ?
  0 : -EPERM;
}

static inline void mapping_unmap_writable(struct address_space *mapping)
{
 atomic_dec(&mapping->i_mmap_writable);
}

static inline int mapping_deny_writable(struct address_space *mapping)
{
 return atomic_dec_unless_positive(&mapping->i_mmap_writable) ?
  0 : -EBUSY;
}

static inline void mapping_allow_writable(struct address_space *mapping)
{
 atomic_inc(&mapping->i_mmap_writable);
}

/*
 * Use sequence counter to get consistent i_size on 32-bit processors.
 */

#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
#include <linux/seqlock.h>
#define __NEED_I_SIZE_ORDERED
#define i_size_ordered_init(inode) seqcount_init(&inode->i_size_seqcount)
#else
#define i_size_ordered_init(inode) do { } while (0)
#endif

struct posix_acl;
#define ACL_NOT_CACHED ((void *)(-1))
/*
 * ACL_DONT_CACHE is for stacked filesystems, that rely on underlying fs to
 * cache the ACL.  This also means that ->get_inode_acl() can be called in RCU
 * mode with the LOOKUP_RCU flag.
 */

#define ACL_DONT_CACHE ((void *)(-3))

static inline struct posix_acl *
uncached_acl_sentinel(struct task_struct *task)
{
 return (void *)task + 1;
}

static inline bool
is_uncached_acl(struct posix_acl *acl)
{
 return (long)acl & 1;
}

#define IOP_FASTPERM 0x0001
#define IOP_LOOKUP 0x0002
#define IOP_NOFOLLOW 0x0004
#define IOP_XATTR 0x0008
#define IOP_DEFAULT_READLINK 0x0010
#define IOP_MGTIME 0x0020
#define IOP_CACHED_LINK 0x0040

/*
 * Keep mostly read-only and often accessed (especially for
 * the RCU path lookup and 'stat' data) fields at the beginning
 * of the 'struct inode'
 */

struct inode {
 umode_t   i_mode;
 unsigned short  i_opflags;
 kuid_t   i_uid;
 kgid_t   i_gid;
 unsigned int  i_flags;

#ifdef CONFIG_FS_POSIX_ACL
 struct posix_acl *i_acl;
 struct posix_acl *i_default_acl;
#endif

 const struct inode_operations *i_op;
 struct super_block *i_sb;
 struct address_space *i_mapping;

#ifdef CONFIG_SECURITY
 void   *i_security;
#endif

 /* Stat data, not accessed from path walking */
 unsigned long  i_ino;
 /*
 * Filesystems may only read i_nlink directly.  They shall use the
 * following functions for modification:
 *
 *    (set|clear|inc|drop)_nlink
 *    inode_(inc|dec)_link_count
 */

 union {
  const unsigned int i_nlink;
  unsigned int __i_nlink;
 };
 dev_t   i_rdev;
 loff_t   i_size;
 time64_t  i_atime_sec;
 time64_t  i_mtime_sec;
 time64_t  i_ctime_sec;
 u32   i_atime_nsec;
 u32   i_mtime_nsec;
 u32   i_ctime_nsec;
 u32   i_generation;
 spinlock_t  i_lock; /* i_blocks, i_bytes, maybe i_size */
 unsigned short          i_bytes;
 u8   i_blkbits;
 enum rw_hint  i_write_hint;
 blkcnt_t  i_blocks;

#ifdef __NEED_I_SIZE_ORDERED
 seqcount_t  i_size_seqcount;
#endif

 /* Misc */
 u32   i_state;
 /* 32-bit hole */
 struct rw_semaphore i_rwsem;

 unsigned long  dirtied_when; /* jiffies of first dirtying */
 unsigned long  dirtied_time_when;

 struct hlist_node i_hash;
 struct list_head i_io_list; /* backing dev IO list */
#ifdef CONFIG_CGROUP_WRITEBACK
 struct bdi_writeback *i_wb;  /* the associated cgroup wb */

 /* foreign inode detection, see wbc_detach_inode() */
 int   i_wb_frn_winner;
 u16   i_wb_frn_avg_time;
 u16   i_wb_frn_history;
#endif
 struct list_head i_lru;  /* inode LRU list */
 struct list_head i_sb_list;
 struct list_head i_wb_list; /* backing dev writeback list */
 union {
  struct hlist_head i_dentry;
  struct rcu_head  i_rcu;
 };
 atomic64_t  i_version;
 atomic64_t  i_sequence; /* see futex */
 atomic_t  i_count;
 atomic_t  i_dio_count;
 atomic_t  i_writecount;
#if defined(CONFIG_IMA) || defined(CONFIG_FILE_LOCKING)
 atomic_t  i_readcount; /* struct files open RO */
#endif
 union {
  const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
  void (*free_inode)(struct inode *);
 };
 struct file_lock_context *i_flctx;
 struct address_space i_data;
 union {
  struct list_head i_devices;
  int   i_linklen;
 };
 union {
  struct pipe_inode_info *i_pipe;
  struct cdev  *i_cdev;
  char   *i_link;
  unsigned  i_dir_seq;
 };


#ifdef CONFIG_FSNOTIFY
 __u32   i_fsnotify_mask; /* all events this inode cares about */
 /* 32-bit hole reserved for expanding i_fsnotify_mask */
 struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
#endif

#ifdef CONFIG_FS_ENCRYPTION
 struct fscrypt_inode_info *i_crypt_info;
#endif

#ifdef CONFIG_FS_VERITY
 struct fsverity_info *i_verity_info;
#endif

 void   *i_private; /* fs or device private pointer */
} __randomize_layout;

static inline void inode_set_cached_link(struct inode *inode, char *link, int linklen)
{
 VFS_WARN_ON_INODE(strlen(link) != linklen, inode);
 VFS_WARN_ON_INODE(inode->i_opflags & IOP_CACHED_LINK, inode);
 inode->i_link = link;
 inode->i_linklen = linklen;
 inode->i_opflags |= IOP_CACHED_LINK;
}

/*
 * Get bit address from inode->i_state to use with wait_var_event()
 * infrastructre.
 */

#define inode_state_wait_address(inode, bit) ((char *)&(inode)->i_state + (bit))

struct wait_queue_head *inode_bit_waitqueue(struct wait_bit_queue_entry *wqe,
         struct inode *inode, u32 bit);

static inline void inode_wake_up_bit(struct inode *inode, u32 bit)
{
 /* Caller is responsible for correct memory barriers. */
 wake_up_var(inode_state_wait_address(inode, bit));
}

struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode);

static inline unsigned int i_blocksize(const struct inode *node)
{
 return (1 << node->i_blkbits);
}

static inline int inode_unhashed(struct inode *inode)
{
 return hlist_unhashed(&inode->i_hash);
}

/*
 * __mark_inode_dirty expects inodes to be hashed.  Since we don't
 * want special inodes in the fileset inode space, we make them
 * appear hashed, but do not put on any lists.  hlist_del()
 * will work fine and require no locking.
 */

static inline void inode_fake_hash(struct inode *inode)
{
 hlist_add_fake(&inode->i_hash);
}

/*
 * inode->i_rwsem nesting subclasses for the lock validator:
 *
 * 0: the object of the current VFS operation
 * 1: parent
 * 2: child/target
 * 3: xattr
 * 4: second non-directory
 * 5: second parent (when locking independent directories in rename)
 *
 * I_MUTEX_NONDIR2 is for certain operations (such as rename) which lock two
 * non-directories at once.
 *
 * The locking order between these classes is
 * parent[2] -> child -> grandchild -> normal -> xattr -> second non-directory
 */

enum inode_i_mutex_lock_class
{
 I_MUTEX_NORMAL,
 I_MUTEX_PARENT,
 I_MUTEX_CHILD,
 I_MUTEX_XATTR,
 I_MUTEX_NONDIR2,
 I_MUTEX_PARENT2,
};

static inline void inode_lock(struct inode *inode)
{
 down_write(&inode->i_rwsem);
}

static inline __must_check int inode_lock_killable(struct inode *inode)
{
 return down_write_killable(&inode->i_rwsem);
}

static inline void inode_unlock(struct inode *inode)
{
 up_write(&inode->i_rwsem);
}

static inline void inode_lock_shared(struct inode *inode)
{
 down_read(&inode->i_rwsem);
}

static inline __must_check int inode_lock_shared_killable(struct inode *inode)
{
 return down_read_killable(&inode->i_rwsem);
}

static inline void inode_unlock_shared(struct inode *inode)
{
 up_read(&inode->i_rwsem);
}

static inline int inode_trylock(struct inode *inode)
{
 return down_write_trylock(&inode->i_rwsem);
}

static inline int inode_trylock_shared(struct inode *inode)
{
 return down_read_trylock(&inode->i_rwsem);
}

static inline int inode_is_locked(struct inode *inode)
{
 return rwsem_is_locked(&inode->i_rwsem);
}

static inline void inode_lock_nested(struct inode *inode, unsigned subclass)
{
 down_write_nested(&inode->i_rwsem, subclass);
}

static inline void inode_lock_shared_nested(struct inode *inode, unsigned subclass)
{
 down_read_nested(&inode->i_rwsem, subclass);
}

static inline void filemap_invalidate_lock(struct address_space *mapping)
{
 down_write(&mapping->invalidate_lock);
}

static inline void filemap_invalidate_unlock(struct address_space *mapping)
{
 up_write(&mapping->invalidate_lock);
}

static inline void filemap_invalidate_lock_shared(struct address_space *mapping)
{
 down_read(&mapping->invalidate_lock);
}

static inline int filemap_invalidate_trylock_shared(
     struct address_space *mapping)
{
 return down_read_trylock(&mapping->invalidate_lock);
}

static inline void filemap_invalidate_unlock_shared(
     struct address_space *mapping)
{
 up_read(&mapping->invalidate_lock);
}

void lock_two_nondirectories(struct inode *, struct inode*);
void unlock_two_nondirectories(struct inode *, struct inode*);

void filemap_invalidate_lock_two(struct address_space *mapping1,
     struct address_space *mapping2);
void filemap_invalidate_unlock_two(struct address_space *mapping1,
       struct address_space *mapping2);


/*
 * NOTE: in a 32bit arch with a preemptable kernel and
 * an UP compile the i_size_read/write must be atomic
 * with respect to the local cpu (unlike with preempt disabled),
 * but they don't need to be atomic with respect to other cpus like in
 * true SMP (so they need either to either locally disable irq around
 * the read or for example on x86 they can be still implemented as a
 * cmpxchg8b without the need of the lock prefix). For SMP compiles
 * and 64bit archs it makes no difference if preempt is enabled or not.
 */

static inline loff_t i_size_read(const struct inode *inode)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
 loff_t i_size;
 unsigned int seq;

 do {
  seq = read_seqcount_begin(&inode->i_size_seqcount);
  i_size = inode->i_size;
 } while (read_seqcount_retry(&inode->i_size_seqcount, seq));
 return i_size;
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION)
 loff_t i_size;

 preempt_disable();
 i_size = inode->i_size;
 preempt_enable();
 return i_size;
#else
 /* Pairs with smp_store_release() in i_size_write() */
 return smp_load_acquire(&inode->i_size);
#endif
}

/*
 * NOTE: unlike i_size_read(), i_size_write() does need locking around it
 * (normally i_rwsem), otherwise on 32bit/SMP an update of i_size_seqcount
 * can be lost, resulting in subsequent i_size_read() calls spinning forever.
 */

static inline void i_size_write(struct inode *inode, loff_t i_size)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
 preempt_disable();
 write_seqcount_begin(&inode->i_size_seqcount);
 inode->i_size = i_size;
 write_seqcount_end(&inode->i_size_seqcount);
 preempt_enable();
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPTION)
 preempt_disable();
 inode->i_size = i_size;
 preempt_enable();
#else
 /*
 * Pairs with smp_load_acquire() in i_size_read() to ensure
 * changes related to inode size (such as page contents) are
 * visible before we see the changed inode size.
 */

 smp_store_release(&inode->i_size, i_size);
#endif
}

static inline unsigned iminor(const struct inode *inode)
{
 return MINOR(inode->i_rdev);
}

static inline unsigned imajor(const struct inode *inode)
{
 return MAJOR(inode->i_rdev);
}

struct fown_struct {
 struct file *file; /* backpointer for security modules */
 rwlock_t lock;          /* protects pid, uid, euid fields */
 struct pid *pid; /* pid or -pgrp where SIGIO should be sent */
 enum pid_type pid_type; /* Kind of process group SIGIO should be sent to */
 kuid_t uid, euid; /* uid/euid of process setting the owner */
 int signum;  /* posix.1b rt signal to be delivered on IO */
};

/**
 * struct file_ra_state - Track a file's readahead state.
 * @start: Where the most recent readahead started.
 * @size: Number of pages read in the most recent readahead.
 * @async_size: Numer of pages that were/are not needed immediately
 *      and so were/are genuinely "ahead".  Start next readahead when
 *      the first of these pages is accessed.
 * @ra_pages: Maximum size of a readahead request, copied from the bdi.
 * @order: Preferred folio order used for most recent readahead.
 * @mmap_miss: How many mmap accesses missed in the page cache.
 * @prev_pos: The last byte in the most recent read request.
 *
 * When this structure is passed to ->readahead(), the "most recent"
 * readahead means the current readahead.
 */

struct file_ra_state {
 pgoff_t start;
 unsigned int size;
 unsigned int async_size;
 unsigned int ra_pages;
 unsigned short order;
 unsigned short mmap_miss;
 loff_t prev_pos;
};

/*
 * Check if @index falls in the readahead windows.
 */

static inline int ra_has_index(struct file_ra_state *ra, pgoff_t index)
{
 return (index >= ra->start &&
  index <  ra->start + ra->size);
}

/**
 * struct file - Represents a file
 * @f_lock: Protects f_ep, f_flags. Must not be taken from IRQ context.
 * @f_mode: FMODE_* flags often used in hotpaths
 * @f_op: file operations
 * @f_mapping: Contents of a cacheable, mappable object.
 * @private_data: filesystem or driver specific data
 * @f_inode: cached inode
 * @f_flags: file flags
 * @f_iocb_flags: iocb flags
 * @f_cred: stashed credentials of creator/opener
 * @f_owner: file owner
 * @f_path: path of the file
 * @f_pos_lock: lock protecting file position
 * @f_pipe: specific to pipes
 * @f_pos: file position
 * @f_security: LSM security context of this file
 * @f_wb_err: writeback error
 * @f_sb_err: per sb writeback errors
 * @f_ep: link of all epoll hooks for this file
 * @f_task_work: task work entry point
 * @f_llist: work queue entrypoint
 * @f_ra: file's readahead state
 * @f_freeptr: Pointer used by SLAB_TYPESAFE_BY_RCU file cache (don't touch.)
 * @f_ref: reference count
 */

struct file {
 spinlock_t   f_lock;
 fmode_t    f_mode;
 const struct file_operations *f_op;
 struct address_space  *f_mapping;
 void    *private_data;
 struct inode   *f_inode;
 unsigned int   f_flags;
 unsigned int   f_iocb_flags;
 const struct cred  *f_cred;
 struct fown_struct  *f_owner;
 /* --- cacheline 1 boundary (64 bytes) --- */
 struct path   f_path;
 union {
  /* regular files (with FMODE_ATOMIC_POS) and directories */
  struct mutex  f_pos_lock;
  /* pipes */
  u64   f_pipe;
 };
 loff_t    f_pos;
#ifdef CONFIG_SECURITY
 void    *f_security;
#endif
 /* --- cacheline 2 boundary (128 bytes) --- */
 errseq_t   f_wb_err;
 errseq_t   f_sb_err;
#ifdef CONFIG_EPOLL
 struct hlist_head  *f_ep;
#endif
 union {
  struct callback_head f_task_work;
  struct llist_node f_llist;
  struct file_ra_state f_ra;
  freeptr_t  f_freeptr;
 };
 file_ref_t   f_ref;
 /* --- cacheline 3 boundary (192 bytes) --- */
} __randomize_layout
  __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */

struct file_handle {
 __u32 handle_bytes;
 int handle_type;
 /* file identifier */
 unsigned char f_handle[] __counted_by(handle_bytes);
};

static inline struct file *get_file(struct file *f)
{
 file_ref_inc(&f->f_ref);
 return f;
}

struct file *get_file_rcu(struct file __rcu **f);
struct file *get_file_active(struct file **f);

#define file_count(f) file_ref_read(&(f)->f_ref)

#define MAX_NON_LFS ((1UL<<31) - 1)

/* Page cache limit. The filesystems should put that into their s_maxbytes 
   limits, otherwise bad things can happen in VM. */

#if BITS_PER_LONG==32
#define MAX_LFS_FILESIZE ((loff_t)ULONG_MAX << PAGE_SHIFT)
#elif BITS_PER_LONG==64
#define MAX_LFS_FILESIZE  ((loff_t)LLONG_MAX)
#endif

/* legacy typedef, should eventually be removed */
typedef void *fl_owner_t;

struct file_lock;
struct file_lease;

/* The following constant reflects the upper bound of the file/locking space */
#ifndef OFFSET_MAX
#define OFFSET_MAX type_max(loff_t)
#define OFFT_OFFSET_MAX type_max(off_t)
#endif

int file_f_owner_allocate(struct file *file);
static inline struct fown_struct *file_f_owner(const struct file *file)
{
 return READ_ONCE(file->f_owner);
}

extern void send_sigio(struct fown_struct *fown, int fd, int band);

static inline struct inode *file_inode(const struct file *f)
{
 return f->f_inode;
}

/*
 * file_dentry() is a relic from the days that overlayfs was using files with a
 * "fake" path, meaning, f_path on overlayfs and f_inode on underlying fs.
 * In those days, file_dentry() was needed to get the underlying fs dentry that
 * matches f_inode.
 * Files with "fake" path should not exist nowadays, so use an assertion to make
 * sure that file_dentry() was not papering over filesystem bugs.
 */

static inline struct dentry *file_dentry(const struct file *file)
{
 struct dentry *dentry = file->f_path.dentry;

 WARN_ON_ONCE(d_inode(dentry) != file_inode(file));
 return dentry;
}

struct fasync_struct {
 rwlock_t  fa_lock;
 int   magic;
 int   fa_fd;
 struct fasync_struct *fa_next; /* singly linked list */
 struct file  *fa_file;
 struct rcu_head  fa_rcu;
};

#define FASYNC_MAGIC 0x4601

/* SMP safe fasync helpers: */
extern int fasync_helper(intstruct file *, intstruct fasync_struct **);
extern struct fasync_struct *fasync_insert_entry(intstruct file *, struct fasync_struct **, struct fasync_struct *);
extern int fasync_remove_entry(struct file *, struct fasync_struct **);
extern struct fasync_struct *fasync_alloc(void);
extern void fasync_free(struct fasync_struct *);

/* can be called from interrupts */
extern void kill_fasync(struct fasync_struct **, intint);

extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
extern int f_setown(struct file *filp, int who, int force);
extern void f_delown(struct file *filp);
extern pid_t f_getown(struct file *filp);
extern int send_sigurg(struct file *file);

/*
 * sb->s_flags.  Note that these mirror the equivalent MS_* flags where
 * represented in both.
 */

#define SB_RDONLY       BIT(0) /* Mount read-only */
#define SB_NOSUID       BIT(1) /* Ignore suid and sgid bits */
#define SB_NODEV        BIT(2) /* Disallow access to device special files */
#define SB_NOEXEC       BIT(3) /* Disallow program execution */
#define SB_SYNCHRONOUS  BIT(4) /* Writes are synced at once */
#define SB_MANDLOCK     BIT(6) /* Allow mandatory locks on an FS */
#define SB_DIRSYNC      BIT(7) /* Directory modifications are synchronous */
#define SB_NOATIME      BIT(10) /* Do not update access times. */
#define SB_NODIRATIME   BIT(11) /* Do not update directory access times */
#define SB_SILENT       BIT(15)
#define SB_POSIXACL     BIT(16) /* Supports POSIX ACLs */
#define SB_INLINECRYPT  BIT(17) /* Use blk-crypto for encrypted files */
#define SB_KERNMOUNT    BIT(22) /* this is a kern_mount call */
#define SB_I_VERSION    BIT(23) /* Update inode I_version field */
#define SB_LAZYTIME     BIT(25) /* Update the on-disk [acm]times lazily */

/* These sb flags are internal to the kernel */
#define SB_DEAD         BIT(21)
#define SB_DYING        BIT(24)
#define SB_FORCE        BIT(27)
#define SB_NOSEC        BIT(28)
#define SB_BORN         BIT(29)
#define SB_ACTIVE       BIT(30)
#define SB_NOUSER       BIT(31)

/* These flags relate to encoding and casefolding */
#define SB_ENC_STRICT_MODE_FL  (1 << 0)
#define SB_ENC_NO_COMPAT_FALLBACK_FL (1 << 1)

#define sb_has_strict_encoding(sb) \
 (sb->s_encoding_flags & SB_ENC_STRICT_MODE_FL)

#if IS_ENABLED(CONFIG_UNICODE)
#define sb_no_casefold_compat_fallback(sb) \
 (sb->s_encoding_flags & SB_ENC_NO_COMPAT_FALLBACK_FL)
#else
#define sb_no_casefold_compat_fallback(sb) (1)
#endif

/*
 * Umount options
 */


#define MNT_FORCE 0x00000001 /* Attempt to forcibily umount */
#define MNT_DETACH 0x00000002 /* Just detach from the tree */
#define MNT_EXPIRE 0x00000004 /* Mark for expiry */
#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
#define UMOUNT_UNUSED 0x80000000 /* Flag guaranteed to be unused */

/* sb->s_iflags */
#define SB_I_CGROUPWB 0x00000001 /* cgroup-aware writeback enabled */
#define SB_I_NOEXEC 0x00000002 /* Ignore executables on this fs */
#define SB_I_NODEV 0x00000004 /* Ignore devices on this fs */
#define SB_I_STABLE_WRITES 0x00000008 /* don't modify blks until WB is done */

/* sb->s_iflags to limit user namespace mounts */
#define SB_I_USERNS_VISIBLE  0x00000010 /* fstype already mounted */
#define SB_I_IMA_UNVERIFIABLE_SIGNATURE 0x00000020
#define SB_I_UNTRUSTED_MOUNTER  0x00000040
#define SB_I_EVM_HMAC_UNSUPPORTED 0x00000080

#define SB_I_SKIP_SYNC 0x00000100 /* Skip superblock at global sync */
#define SB_I_PERSB_BDI 0x00000200 /* has a per-sb bdi */
#define SB_I_TS_EXPIRY_WARNED 0x00000400 /* warned about timestamp range expiry */
#define SB_I_RETIRED 0x00000800 /* superblock shouldn't be reused */
#define SB_I_NOUMASK 0x00001000 /* VFS does not apply umask */
#define SB_I_NOIDMAP 0x00002000 /* No idmapped mounts on this superblock */
#define SB_I_ALLOW_HSM 0x00004000 /* Allow HSM events on this superblock */

/* Possible states of 'frozen' field */
enum {
 SB_UNFROZEN = 0,  /* FS is unfrozen */
 SB_FREEZE_WRITE = 1,  /* Writes, dir ops, ioctls frozen */
 SB_FREEZE_PAGEFAULT = 2, /* Page faults stopped as well */
 SB_FREEZE_FS = 3,  /* For internal FS use (e.g. to stop
 * internal threads if needed) */

 SB_FREEZE_COMPLETE = 4,  /* ->freeze_fs finished successfully */
};

#define SB_FREEZE_LEVELS (SB_FREEZE_COMPLETE - 1)

struct sb_writers {
 unsigned short   frozen;  /* Is sb frozen? */
 int    freeze_kcount; /* How many kernel freeze requests? */
 int    freeze_ucount; /* How many userspace freeze requests? */
 const void   *freeze_owner; /* Owner of the freeze */
 struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];
};

struct super_block {
 struct list_head s_list;  /* Keep this first */
 dev_t   s_dev;  /* search index; _not_ kdev_t */
 unsigned char  s_blocksize_bits;
 unsigned long  s_blocksize;
 loff_t   s_maxbytes; /* Max file size */
 struct file_system_type *s_type;
 const struct super_operations *s_op;
 const struct dquot_operations *dq_op;
 const struct quotactl_ops *s_qcop;
 const struct export_operations *s_export_op;
 unsigned long  s_flags;
 unsigned long  s_iflags; /* internal SB_I_* flags */
 unsigned long  s_magic;
 struct dentry  *s_root;
 struct rw_semaphore s_umount;
 int   s_count;
 atomic_t  s_active;
#ifdef CONFIG_SECURITY
 void                    *s_security;
#endif
 const struct xattr_handler * const *s_xattr;
#ifdef CONFIG_FS_ENCRYPTION
 const struct fscrypt_operations *s_cop;
 struct fscrypt_keyring *s_master_keys; /* master crypto keys in use */
#endif
#ifdef CONFIG_FS_VERITY
 const struct fsverity_operations *s_vop;
#endif
#if IS_ENABLED(CONFIG_UNICODE)
 struct unicode_map *s_encoding;
 __u16 s_encoding_flags;
#endif
 struct hlist_bl_head s_roots; /* alternate root dentries for NFS */
 struct list_head s_mounts; /* list of mounts; _not_ for fs use */
 struct block_device *s_bdev; /* can go away once we use an accessor for @s_bdev_file */
 struct file  *s_bdev_file;
 struct backing_dev_info *s_bdi;
 struct mtd_info  *s_mtd;
 struct hlist_node s_instances;
 unsigned int  s_quota_types; /* Bitmask of supported quota types */
 struct quota_info s_dquot; /* Diskquota specific options */

 struct sb_writers s_writers;

 /*
 * Keep s_fs_info, s_time_gran, s_fsnotify_mask, and
 * s_fsnotify_info together for cache efficiency. They are frequently
 * accessed and rarely modified.
 */

 void   *s_fs_info; /* Filesystem private info */

 /* Granularity of c/m/atime in ns (cannot be worse than a second) */
 u32   s_time_gran;
 /* Time limits for c/m/atime in seconds */
 time64_t     s_time_min;
 time64_t     s_time_max;
#ifdef CONFIG_FSNOTIFY
 u32   s_fsnotify_mask;
 struct fsnotify_sb_info *s_fsnotify_info;
#endif

 /*
 * q: why are s_id and s_sysfs_name not the same? both are human
 * readable strings that identify the filesystem
 * a: s_id is allowed to change at runtime; it's used in log messages,
 * and we want to when a device starts out as single device (s_id is dev
 * name) but then a device is hot added and we have to switch to
 * identifying it by UUID
 * but s_sysfs_name is a handle for programmatic access, and can't
 * change at runtime
 */

 char   s_id[32]; /* Informational name */
 uuid_t   s_uuid;  /* UUID */
 u8   s_uuid_len; /* Default 16, possibly smaller for weird filesystems */

 /* if set, fs shows up under sysfs at /sys/fs/$FSTYP/s_sysfs_name */
 char   s_sysfs_name[UUID_STRING_LEN + 1];

 unsigned int  s_max_links;
 unsigned int  s_d_flags; /* default d_flags for dentries */

 /*
 * The next field is for VFS *only*. No filesystems have any business
 * even looking at it. You had been warned.
 */

 struct mutex s_vfs_rename_mutex; /* Kludge */

 /*
 * Filesystem subtype.  If non-empty the filesystem type field
 * in /proc/mounts will be "type.subtype"
 */

 const char *s_subtype;

 const struct dentry_operations *__s_d_op; /* default d_op for dentries */

 struct shrinker *s_shrink; /* per-sb shrinker handle */

 /* Number of inodes with nlink == 0 but still referenced */
 atomic_long_t s_remove_count;

 /* Read-only state of the superblock is being changed */
 int s_readonly_remount;

 /* per-sb errseq_t for reporting writeback errors via syncfs */
 errseq_t s_wb_err;

 /* AIO completions deferred from interrupt context */
 struct workqueue_struct *s_dio_done_wq;
 struct hlist_head s_pins;

 /*
 * Owning user namespace and default context in which to
 * interpret filesystem uids, gids, quotas, device nodes,
 * xattrs and security labels.
 */

 struct user_namespace *s_user_ns;

 /*
 * The list_lru structure is essentially just a pointer to a table
 * of per-node lru lists, each of which has its own spinlock.
 * There is no need to put them into separate cachelines.
 */

 struct list_lru  s_dentry_lru;
 struct list_lru  s_inode_lru;
 struct rcu_head  rcu;
 struct work_struct destroy_work;

 struct mutex  s_sync_lock; /* sync serialisation lock */

 /*
 * Indicates how deep in a filesystem stack this SB is
 */

 int s_stack_depth;

 /* s_inode_list_lock protects s_inodes */
 spinlock_t  s_inode_list_lock ____cacheline_aligned_in_smp;
 struct list_head s_inodes; /* all inodes */

 spinlock_t  s_inode_wblist_lock;
 struct list_head s_inodes_wb; /* writeback inodes */
} __randomize_layout;

static inline struct user_namespace *i_user_ns(const struct inode *inode)
{
 return inode->i_sb->s_user_ns;
}

/* Helper functions so that in most cases filesystems will
 * not need to deal directly with kuid_t and kgid_t and can
 * instead deal with the raw numeric values that are stored
 * in the filesystem.
 */

static inline uid_t i_uid_read(const struct inode *inode)
{
 return from_kuid(i_user_ns(inode), inode->i_uid);
}

static inline gid_t i_gid_read(const struct inode *inode)
{
 return from_kgid(i_user_ns(inode), inode->i_gid);
}

static inline void i_uid_write(struct inode *inode, uid_t uid)
{
 inode->i_uid = make_kuid(i_user_ns(inode), uid);
}

static inline void i_gid_write(struct inode *inode, gid_t gid)
{
 inode->i_gid = make_kgid(i_user_ns(inode), gid);
}

/**
 * i_uid_into_vfsuid - map an inode's i_uid down according to an idmapping
 * @idmap: idmap of the mount the inode was found from
 * @inode: inode to map
 *
 * Return: whe inode's i_uid mapped down according to @idmap.
 * If the inode's i_uid has no mapping INVALID_VFSUID is returned.
 */

static inline vfsuid_t i_uid_into_vfsuid(struct mnt_idmap *idmap,
      const struct inode *inode)
{
 return make_vfsuid(idmap, i_user_ns(inode), inode->i_uid);
}

/**
 * i_uid_needs_update - check whether inode's i_uid needs to be updated
 * @idmap: idmap of the mount the inode was found from
 * @attr: the new attributes of @inode
 * @inode: the inode to update
 *
 * Check whether the $inode's i_uid field needs to be updated taking idmapped
 * mounts into account if the filesystem supports it.
 *
 * Return: true if @inode's i_uid field needs to be updated, false if not.
 */

static inline bool i_uid_needs_update(struct mnt_idmap *idmap,
          const struct iattr *attr,
          const struct inode *inode)
{
 return ((attr->ia_valid & ATTR_UID) &&
  !vfsuid_eq(attr->ia_vfsuid,
      i_uid_into_vfsuid(idmap, inode)));
}

/**
 * i_uid_update - update @inode's i_uid field
 * @idmap: idmap of the mount the inode was found from
 * @attr: the new attributes of @inode
 * @inode: the inode to update
 *
 * Safely update @inode's i_uid field translating the vfsuid of any idmapped
 * mount into the filesystem kuid.
 */

static inline void i_uid_update(struct mnt_idmap *idmap,
    const struct iattr *attr,
    struct inode *inode)
{
 if (attr->ia_valid & ATTR_UID)
  inode->i_uid = from_vfsuid(idmap, i_user_ns(inode),
        attr->ia_vfsuid);
}

/**
 * i_gid_into_vfsgid - map an inode's i_gid down according to an idmapping
 * @idmap: idmap of the mount the inode was found from
 * @inode: inode to map
 *
 * Return: the inode's i_gid mapped down according to @idmap.
 * If the inode's i_gid has no mapping INVALID_VFSGID is returned.
 */

static inline vfsgid_t i_gid_into_vfsgid(struct mnt_idmap *idmap,
      const struct inode *inode)
{
 return make_vfsgid(idmap, i_user_ns(inode), inode->i_gid);
}

/**
 * i_gid_needs_update - check whether inode's i_gid needs to be updated
 * @idmap: idmap of the mount the inode was found from
 * @attr: the new attributes of @inode
 * @inode: the inode to update
 *
 * Check whether the $inode's i_gid field needs to be updated taking idmapped
 * mounts into account if the filesystem supports it.
 *
 * Return: true if @inode's i_gid field needs to be updated, false if not.
 */

static inline bool i_gid_needs_update(struct mnt_idmap *idmap,
          const struct iattr *attr,
          const struct inode *inode)
{
 return ((attr->ia_valid & ATTR_GID) &&
  !vfsgid_eq(attr->ia_vfsgid,
      i_gid_into_vfsgid(idmap, inode)));
}

/**
 * i_gid_update - update @inode's i_gid field
 * @idmap: idmap of the mount the inode was found from
 * @attr: the new attributes of @inode
 * @inode: the inode to update
 *
 * Safely update @inode's i_gid field translating the vfsgid of any idmapped
 * mount into the filesystem kgid.
 */

static inline void i_gid_update(struct mnt_idmap *idmap,
    const struct iattr *attr,
    struct inode *inode)
{
 if (attr->ia_valid & ATTR_GID)
  inode->i_gid = from_vfsgid(idmap, i_user_ns(inode),
        attr->ia_vfsgid);
}

/**
 * inode_fsuid_set - initialize inode's i_uid field with callers fsuid
 * @inode: inode to initialize
 * @idmap: idmap of the mount the inode was found from
 *
 * Initialize the i_uid field of @inode. If the inode was found/created via
 * an idmapped mount map the caller's fsuid according to @idmap.
 */

static inline void inode_fsuid_set(struct inode *inode,
       struct mnt_idmap *idmap)
{
 inode->i_uid = mapped_fsuid(idmap, i_user_ns(inode));
}

/**
 * inode_fsgid_set - initialize inode's i_gid field with callers fsgid
 * @inode: inode to initialize
 * @idmap: idmap of the mount the inode was found from
 *
 * Initialize the i_gid field of @inode. If the inode was found/created via
 * an idmapped mount map the caller's fsgid according to @idmap.
 */

static inline void inode_fsgid_set(struct inode *inode,
       struct mnt_idmap *idmap)
{
 inode->i_gid = mapped_fsgid(idmap, i_user_ns(inode));
}

/**
 * fsuidgid_has_mapping() - check whether caller's fsuid/fsgid is mapped
 * @sb: the superblock we want a mapping in
 * @idmap: idmap of the relevant mount
 *
 * Check whether the caller's fsuid and fsgid have a valid mapping in the
 * s_user_ns of the superblock @sb. If the caller is on an idmapped mount map
 * the caller's fsuid and fsgid according to the @idmap first.
 *
 * Return: true if fsuid and fsgid is mapped, false if not.
 */

static inline bool fsuidgid_has_mapping(struct super_block *sb,
     struct mnt_idmap *idmap)
{
 struct user_namespace *fs_userns = sb->s_user_ns;
 kuid_t kuid;
 kgid_t kgid;

 kuid = mapped_fsuid(idmap, fs_userns);
 if (!uid_valid(kuid))
  return false;
 kgid = mapped_fsgid(idmap, fs_userns);
 if (!gid_valid(kgid))
  return false;
 return kuid_has_mapping(fs_userns, kuid) &&
        kgid_has_mapping(fs_userns, kgid);
}

struct timespec64 current_time(struct inode *inode);
struct timespec64 inode_set_ctime_current(struct inode *inode);
struct timespec64 inode_set_ctime_deleg(struct inode *inode,
     struct timespec64 update);

static inline time64_t inode_get_atime_sec(const struct inode *inode)
{
 return inode->i_atime_sec;
}

static inline long inode_get_atime_nsec(const struct inode *inode)
{
 return inode->i_atime_nsec;
}

static inline struct timespec64 inode_get_atime(const struct inode *inode)
{
 struct timespec64 ts = { .tv_sec  = inode_get_atime_sec(inode),
     .tv_nsec = inode_get_atime_nsec(inode) };

 return ts;
}

static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode,
            struct timespec64 ts)
{
 inode->i_atime_sec = ts.tv_sec;
 inode->i_atime_nsec = ts.tv_nsec;
 return ts;
}

static inline struct timespec64 inode_set_atime(struct inode *inode,
      time64_t sec, long nsec)
{
 struct timespec64 ts = { .tv_sec  = sec,
     .tv_nsec = nsec };

 return inode_set_atime_to_ts(inode, ts);
}

static inline time64_t inode_get_mtime_sec(const struct inode *inode)
{
 return inode->i_mtime_sec;
}

static inline long inode_get_mtime_nsec(const struct inode *inode)
{
 return inode->i_mtime_nsec;
}

static inline struct timespec64 inode_get_mtime(const struct inode *inode)
{
 struct timespec64 ts = { .tv_sec  = inode_get_mtime_sec(inode),
     .tv_nsec = inode_get_mtime_nsec(inode) };
 return ts;
}

static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode,
            struct timespec64 ts)
{
 inode->i_mtime_sec = ts.tv_sec;
 inode->i_mtime_nsec = ts.tv_nsec;
 return ts;
}

static inline struct timespec64 inode_set_mtime(struct inode *inode,
      time64_t sec, long nsec)
{
 struct timespec64 ts = { .tv_sec  = sec,
     .tv_nsec = nsec };
 return inode_set_mtime_to_ts(inode, ts);
}

/*
 * Multigrain timestamps
 *
 * Conditionally use fine-grained ctime and mtime timestamps when there
 * are users actively observing them via getattr. The primary use-case
 * for this is NFS clients that use the ctime to distinguish between
 * different states of the file, and that are often fooled by multiple
 * operations that occur in the same coarse-grained timer tick.
 */

#define I_CTIME_QUERIED  ((u32)BIT(31))

static inline time64_t inode_get_ctime_sec(const struct inode *inode)
{
 return inode->i_ctime_sec;
}

static inline long inode_get_ctime_nsec(const struct inode *inode)
{
 return inode->i_ctime_nsec & ~I_CTIME_QUERIED;
}

static inline struct timespec64 inode_get_ctime(const struct inode *inode)
{
 struct timespec64 ts = { .tv_sec  = inode_get_ctime_sec(inode),
     .tv_nsec = inode_get_ctime_nsec(inode) };

 return ts;
}

struct timespec64 inode_set_ctime_to_ts(struct inode *inode, struct timespec64 ts);

/**
 * inode_set_ctime - set the ctime in the inode
 * @inode: inode in which to set the ctime
 * @sec: tv_sec value to set
 * @nsec: tv_nsec value to set
 *
 * Set the ctime in @inode to { @sec, @nsec }
 */

static inline struct timespec64 inode_set_ctime(struct inode *inode,
      time64_t sec, long nsec)
{
 struct timespec64 ts = { .tv_sec  = sec,
     .tv_nsec = nsec };

 return inode_set_ctime_to_ts(inode, ts);
}

struct timespec64 simple_inode_init_ts(struct inode *inode);

/*
 * Snapshotting support.
 */


/*
 * These are internal functions, please use sb_start_{write,pagefault,intwrite}
 * instead.
 */

static inline void __sb_end_write(struct super_block *sb, int level)
{
 percpu_up_read(sb->s_writers.rw_sem + level-1);
}

static inline void __sb_start_write(struct super_block *sb, int level)
{
 percpu_down_read_freezable(sb->s_writers.rw_sem + level - 1, true);
}

static inline bool __sb_start_write_trylock(struct super_block *sb, int level)
{
 return percpu_down_read_trylock(sb->s_writers.rw_sem + level - 1);
}

#define __sb_writers_acquired(sb, lev) \
 percpu_rwsem_acquire(&(sb)->s_writers.rw_sem[(lev)-1], 1, _THIS_IP_)
#define __sb_writers_release(sb, lev) \
 percpu_rwsem_release(&(sb)->s_writers.rw_sem[(lev)-1], _THIS_IP_)

/**
 * __sb_write_started - check if sb freeze level is held
 * @sb: the super we write to
 * @level: the freeze level
 *
 * * > 0 - sb freeze level is held
 * *   0 - sb freeze level is not held
 * * < 0 - !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN
 */

static inline int __sb_write_started(const struct super_block *sb, int level)
{
 return lockdep_is_held_type(sb->s_writers.rw_sem + level - 1, 1);
}

/**
 * sb_write_started - check if SB_FREEZE_WRITE is held
 * @sb: the super we write to
 *
 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 */

static inline bool sb_write_started(const struct super_block *sb)
{
 return __sb_write_started(sb, SB_FREEZE_WRITE);
}

/**
 * sb_write_not_started - check if SB_FREEZE_WRITE is not held
 * @sb: the super we write to
 *
 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 */

static inline bool sb_write_not_started(const struct super_block *sb)
{
 return __sb_write_started(sb, SB_FREEZE_WRITE) <= 0;
}

/**
 * file_write_started - check if SB_FREEZE_WRITE is held
 * @file: the file we write to
 *
 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 * May be false positive with !S_ISREG, because file_start_write() has
 * no effect on !S_ISREG.
 */

static inline bool file_write_started(const struct file *file)
{
 if (!S_ISREG(file_inode(file)->i_mode))
  return true;
 return sb_write_started(file_inode(file)->i_sb);
}

/**
 * file_write_not_started - check if SB_FREEZE_WRITE is not held
 * @file: the file we write to
 *
 * May be false positive with !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN.
 * May be false positive with !S_ISREG, because file_start_write() has
 * no effect on !S_ISREG.
 */

static inline bool file_write_not_started(const struct file *file)
{
 if (!S_ISREG(file_inode(file)->i_mode))
  return true;
 return sb_write_not_started(file_inode(file)->i_sb);
}

/**
 * sb_end_write - drop write access to a superblock
 * @sb: the super we wrote to
 *
 * Decrement number of writers to the filesystem. Wake up possible waiters
 * wanting to freeze the filesystem.
 */

static inline void sb_end_write(struct super_block *sb)
{
 __sb_end_write(sb, SB_FREEZE_WRITE);
}

/**
 * sb_end_pagefault - drop write access to a superblock from a page fault
 * @sb: the super we wrote to
 *
 * Decrement number of processes handling write page fault to the filesystem.
 * Wake up possible waiters wanting to freeze the filesystem.
 */

static inline void sb_end_pagefault(struct super_block *sb)
{
 __sb_end_write(sb, SB_FREEZE_PAGEFAULT);
}

/**
 * sb_end_intwrite - drop write access to a superblock for internal fs purposes
 * @sb: the super we wrote to
 *
 * Decrement fs-internal number of writers to the filesystem.  Wake up possible
 * waiters wanting to freeze the filesystem.
 */

static inline void sb_end_intwrite(struct super_block *sb)
{
 __sb_end_write(sb, SB_FREEZE_FS);
}

/**
 * sb_start_write - get write access to a superblock
 * @sb: the super we write to
 *
 * When a process wants to write data or metadata to a file system (i.e. dirty
 * a page or an inode), it should embed the operation in a sb_start_write() -
 * sb_end_write() pair to get exclusion against file system freezing. This
 * function increments number of writers preventing freezing. If the file
 * system is already frozen, the function waits until the file system is
 * thawed.
 *
 * Since freeze protection behaves as a lock, users have to preserve
 * ordering of freeze protection and other filesystem locks. Generally,
 * freeze protection should be the outermost lock. In particular, we have:
 *
 * sb_start_write
 *   -> i_rwsem (write path, truncate, directory ops, ...)
 *   -> s_umount (freeze_super, thaw_super)
 */

static inline void sb_start_write(struct super_block *sb)
{
 __sb_start_write(sb, SB_FREEZE_WRITE);
}

static inline bool sb_start_write_trylock(struct super_block *sb)
{
 return __sb_start_write_trylock(sb, SB_FREEZE_WRITE);
}

/**
 * sb_start_pagefault - get write access to a superblock from a page fault
 * @sb: the super we write to
 *
 * When a process starts handling write page fault, it should embed the
 * operation into sb_start_pagefault() - sb_end_pagefault() pair to get
 * exclusion against file system freezing. This is needed since the page fault
 * is going to dirty a page. This function increments number of running page
 * faults preventing freezing. If the file system is already frozen, the
 * function waits until the file system is thawed.
 *
 * Since page fault freeze protection behaves as a lock, users have to preserve
 * ordering of freeze protection and other filesystem locks. It is advised to
 * put sb_start_pagefault() close to mmap_lock in lock ordering. Page fault
 * handling code implies lock dependency:
 *
 * mmap_lock
 *   -> sb_start_pagefault
 */

static inline void sb_start_pagefault(struct super_block *sb)
{
 __sb_start_write(sb, SB_FREEZE_PAGEFAULT);
}

/**
 * sb_start_intwrite - get write access to a superblock for internal fs purposes
 * @sb: the super we write to
 *
 * This is the third level of protection against filesystem freezing. It is
 * free for use by a filesystem. The only requirement is that it must rank
 * below sb_start_pagefault.
 *
 * For example filesystem can call sb_start_intwrite() when starting a
 * transaction which somewhat eases handling of freezing for internal sources
 * of filesystem changes (internal fs threads, discarding preallocation on file
 * close, etc.).
 */

static inline void sb_start_intwrite(struct super_block *sb)
{
 __sb_start_write(sb, SB_FREEZE_FS);
}

static inline bool sb_start_intwrite_trylock(struct super_block *sb)
{
 return __sb_start_write_trylock(sb, SB_FREEZE_FS);
}

bool inode_owner_or_capable(struct mnt_idmap *idmap,
       const struct inode *inode);

/*
 * VFS helper functions..
 */

int vfs_create(struct mnt_idmap *, struct inode *,
        struct dentry *, umode_t, bool);
struct dentry *vfs_mkdir(struct mnt_idmap *, struct inode *,
    struct dentry *, umode_t);
int vfs_mknod(struct mnt_idmap *, struct inode *, struct dentry *,
              umode_t, dev_t);
int vfs_symlink(struct mnt_idmap *, struct inode *,
  struct dentry *, const char *);
int vfs_link(struct dentry *, struct mnt_idmap *, struct inode *,
      struct dentry *, struct inode **);
int vfs_rmdir(struct mnt_idmap *, struct inode *, struct dentry *);
int vfs_unlink(struct mnt_idmap *, struct inode *, struct dentry *,
        struct inode **);

/**
 * struct renamedata - contains all information required for renaming
 * @old_mnt_idmap:     idmap of the old mount the inode was found from
 * @old_parent:        parent of source
 * @old_dentry:                source
 * @new_mnt_idmap:     idmap of the new mount the inode was found from
 * @new_parent:        parent of destination
 * @new_dentry:                destination
 * @delegated_inode:   returns an inode needing a delegation break
 * @flags:             rename flags
 */

struct renamedata {
 struct mnt_idmap *old_mnt_idmap;
 struct dentry *old_parent;
 struct dentry *old_dentry;
 struct mnt_idmap *new_mnt_idmap;
 struct dentry *new_parent;
 struct dentry *new_dentry;
 struct inode **delegated_inode;
 unsigned int flags;
} __randomize_layout;

int vfs_rename(struct renamedata *);

static inline int vfs_whiteout(struct mnt_idmap *idmap,
          struct inode *dir, struct dentry *dentry)
{
 return vfs_mknod(idmap, dir, dentry, S_IFCHR | WHITEOUT_MODE,
    WHITEOUT_DEV);
}

struct file *kernel_tmpfile_open(struct mnt_idmap *idmap,
     const struct path *parentpath,
     umode_t mode, int open_flag,
     const struct cred *cred);
struct file *kernel_file_open(const struct path *path, int flags,
         const struct cred *cred);

int vfs_mkobj(struct dentry *, umode_t,
  int (*f)(struct dentry *, umode_t, void *),
  void *);

int vfs_fchown(struct file *file, uid_t user, gid_t group);
int vfs_fchmod(struct file *file, umode_t mode);
int vfs_utimes(const struct path *path, struct timespec64 *times);

int vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

#ifdef CONFIG_COMPAT
extern long compat_ptr_ioctl(struct file *file, unsigned int cmd,
     unsigned long arg);
#else
#define compat_ptr_ioctl NULL
#endif

/*
 * VFS file helper functions.
 */

void inode_init_owner(struct mnt_idmap *idmap, struct inode *inode,
        const struct inode *dir, umode_t mode);
extern bool may_open_dev(const struct path *path);
umode_t mode_strip_sgid(struct mnt_idmap *idmap,
   const struct inode *dir, umode_t mode);
bool in_group_or_capable(struct mnt_idmap *idmap,
    const struct inode *inode, vfsgid_t vfsgid);

/*
 * This is the "filldir" function type, used by readdir() to let
 * the kernel specify what kind of dirent layout it wants to have.
 * This allows the kernel to read directories into kernel space or
 * to have different dirent layouts depending on the binary type.
 * Return 'true' to keep going and 'false' if there are no more entries.
 */

struct dir_context;
typedef bool (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64,
    unsigned);

struct dir_context {
 filldir_t actor;
 loff_t pos;
 /*
 * Filesystems MUST NOT MODIFY count, but may use as a hint:
 * 0     unknown
 * > 0      space in buffer (assume at least one entry)
 * INT_MAX  unlimited
 */

 int count;
};

/* If OR-ed with d_type, pending signals are not checked */
#define FILLDIR_FLAG_NOINTR 0x1000

/*
 * These flags let !MMU mmap() govern direct device mapping vs immediate
 * copying more easily for MAP_PRIVATE, especially for ROM filesystems.
 *
 * NOMMU_MAP_COPY: Copy can be mapped (MAP_PRIVATE)
 * NOMMU_MAP_DIRECT: Can be mapped directly (MAP_SHARED)
 * NOMMU_MAP_READ: Can be mapped for reading
 * NOMMU_MAP_WRITE: Can be mapped for writing
 * NOMMU_MAP_EXEC: Can be mapped for execution
 */

#define NOMMU_MAP_COPY  0x00000001
#define NOMMU_MAP_DIRECT 0x00000008
#define NOMMU_MAP_READ  VM_MAYREAD
#define NOMMU_MAP_WRITE  VM_MAYWRITE
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=92 G=93

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge