diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/arm-smccc.h | 135 | ||||
-rw-r--r-- | include/linux/dcache.h | 109 | ||||
-rw-r--r-- | include/linux/fs.h | 131 | ||||
-rw-r--r-- | include/linux/mount.h | 3 | ||||
-rw-r--r-- | include/linux/namei.h | 52 | ||||
-rw-r--r-- | include/linux/stat.h | 2 |
6 files changed, 391 insertions, 41 deletions
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h new file mode 100644 index 0000000000..1b38b7b372 --- /dev/null +++ b/include/linux/arm-smccc.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015, Linaro Limited + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef __LINUX_ARM_SMCCC_H +#define __LINUX_ARM_SMCCC_H + +/* + * This file provides common defines for ARM SMC Calling Convention as + * specified in + * http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html + */ + +/* This constant is shifted by 31, make sure it's of an unsigned type */ +#define ARM_SMCCC_STD_CALL 0UL +#define ARM_SMCCC_FAST_CALL 1UL +#define ARM_SMCCC_TYPE_SHIFT 31 + +#define ARM_SMCCC_SMC_32 0 +#define ARM_SMCCC_SMC_64 1 +#define ARM_SMCCC_CALL_CONV_SHIFT 30 + +#define ARM_SMCCC_OWNER_MASK 0x3F +#define ARM_SMCCC_OWNER_SHIFT 24 + +#define ARM_SMCCC_FUNC_MASK 0xFFFF + +#define ARM_SMCCC_IS_FAST_CALL(smc_val) \ + ((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT)) +#define ARM_SMCCC_IS_64(smc_val) \ + ((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT)) +#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK) +#define ARM_SMCCC_OWNER_NUM(smc_val) \ + (((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK) + +#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \ + (((type) << ARM_SMCCC_TYPE_SHIFT) | \ + ((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \ + (((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \ + ((func_num) & ARM_SMCCC_FUNC_MASK)) + +#define ARM_SMCCC_OWNER_ARCH 0 +#define ARM_SMCCC_OWNER_CPU 1 +#define ARM_SMCCC_OWNER_SIP 2 +#define ARM_SMCCC_OWNER_OEM 3 +#define ARM_SMCCC_OWNER_STANDARD 4 +#define ARM_SMCCC_OWNER_TRUSTED_APP 48 +#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49 +#define ARM_SMCCC_OWNER_TRUSTED_OS 50 +#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63 + +#define ARM_SMCCC_QUIRK_NONE 0 +#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */ + +#ifndef __ASSEMBLY__ + +#include <linux/linkage.h> +#include <linux/types.h> +/** + * struct arm_smccc_res - Result from SMC/HVC call + * @a0-a3 result values from registers 0 to 3 + */ +struct arm_smccc_res { + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; +}; + +/** + * struct arm_smccc_quirk - Contains quirk information + * @id: quirk identification + * @state: quirk specific information + * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 + */ +struct arm_smccc_quirk { + int id; + union { + unsigned long a6; + } state; +}; + +/** + * __arm_smccc_smc() - make SMC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 + * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make SMC calls following SMC Calling Convention. + * The content of the supplied param are copied to registers 0 to 7 prior + * to the SMC instruction. The return values are updated with the content + * from register 0 to 3 on return from the SMC instruction. An optional + * quirk structure provides vendor specific behavior. + */ +asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); + +/** + * __arm_smccc_hvc() - make HVC calls + * @a0-a7: arguments passed in registers 0 to 7 + * @res: result values from registers 0 to 3 + * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. + * + * This function is used to make HVC calls following SMC Calling + * Convention. The content of the supplied param are copied to registers 0 + * to 7 prior to the HVC instruction. The return values are updated with + * the content from register 0 to 3 on return from the HVC instruction. An + * optional quirk structure provides vendor specific behavior. + */ +asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, + unsigned long a2, unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long a6, unsigned long a7, + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); + +#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) + +#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) + +#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL) + +#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) + +#endif /*__ASSEMBLY__*/ +#endif /*__LINUX_ARM_SMCCC_H*/ diff --git a/include/linux/dcache.h b/include/linux/dcache.h index dfb466722c..16244129bf 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -53,6 +53,10 @@ struct dentry { spinlock_t d_lock; /* per dentry lock */ struct inode *d_inode; /* Where the name belongs to - NULL is * negative */ + + unsigned int d_count; + const struct dentry_operations *d_op; + /* * The next three fields are touched by __d_lookup. Place them here * so they all fit in a cache line. @@ -65,8 +69,8 @@ struct dentry { /* * d_child and d_rcu can share memory */ + struct list_head d_child; /* child of parent list */ struct list_head d_subdirs; /* our children */ - struct list_head d_alias; /* inode alias list */ unsigned long d_time; /* used by d_revalidate */ struct super_block *d_sb; /* The root of the dentry tree */ void *d_fsdata; /* fs-specific data */ @@ -74,7 +78,108 @@ struct dentry { struct dcookie_struct *d_cookie; /* cookie, if any */ #endif int d_mounted; - unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ + unsigned char *name; /* all names */ +}; + +struct dentry_operations { }; +struct dentry * d_make_root(struct inode *); +void d_add(struct dentry *, struct inode *); +struct dentry * d_alloc_anon(struct super_block *); +void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op); +void d_instantiate(struct dentry *dentry, struct inode *inode); +void d_delete(struct dentry *); +struct dentry *dget(struct dentry *); +void dput(struct dentry *); + +#define DCACHE_ENTRY_TYPE 0x00700000 +#define DCACHE_MISS_TYPE 0x00000000 /* Negative dentry (maybe fallthru to nowhere) */ +#define DCACHE_WHITEOUT_TYPE 0x00100000 /* Whiteout dentry (stop pathwalk) */ +#define DCACHE_DIRECTORY_TYPE 0x00200000 /* Normal directory */ +#define DCACHE_AUTODIR_TYPE 0x00300000 /* Lookupless directory (presumed automount) */ +#define DCACHE_REGULAR_TYPE 0x00400000 /* Regular file type (or fallthru to such) */ +#define DCACHE_SPECIAL_TYPE 0x00500000 /* Other file type (or fallthru to such) */ +#define DCACHE_SYMLINK_TYPE 0x00600000 /* Symlink (or fallthru to such) */ + +#define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ +#define DCACHE_CANT_MOUNT 0x00000100 +#define DCACHE_MOUNTED 0x00010000 /* is a mountpoint */ +#define DCACHE_NEED_AUTOMOUNT 0x00020000 /* handle automount on this dir */ +#define DCACHE_MANAGED_DENTRY \ + (DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT) + +static inline bool d_mountpoint(const struct dentry *dentry) +{ + return dentry->d_flags & DCACHE_MOUNTED; +} + +/* + * Directory cache entry type accessor functions. + */ +static inline unsigned __d_entry_type(const struct dentry *dentry) +{ + return dentry->d_flags & DCACHE_ENTRY_TYPE; +} + +static inline bool d_is_miss(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_MISS_TYPE; +} + +static inline bool d_can_lookup(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_DIRECTORY_TYPE; +} + +static inline bool d_is_autodir(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_AUTODIR_TYPE; +} + +static inline bool d_is_dir(const struct dentry *dentry) +{ + return d_can_lookup(dentry) || d_is_autodir(dentry); +} + +static inline bool d_is_symlink(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_SYMLINK_TYPE; +} + +static inline bool d_is_reg(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_REGULAR_TYPE; +} + +static inline bool d_is_special(const struct dentry *dentry) +{ + return __d_entry_type(dentry) == DCACHE_SPECIAL_TYPE; +} + +static inline bool d_is_file(const struct dentry *dentry) +{ + return d_is_reg(dentry) || d_is_special(dentry); +} + +static inline bool d_is_negative(const struct dentry *dentry) +{ + // TODO: check d_is_whiteout(dentry) also. + return d_is_miss(dentry); +} + +static inline bool d_is_positive(const struct dentry *dentry) +{ + return !d_is_negative(dentry); +} + +static inline struct inode *d_inode(const struct dentry *dentry) +{ + return dentry->d_inode; +} + +#define IS_ROOT(x) ((x) == (x)->d_parent) + +char *dpath(struct dentry *dentry, struct dentry *root); + #endif /* __LINUX_DCACHE_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 153c464470..4550e8feeb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -34,7 +34,18 @@ #define DT_SOCK 12 #define DT_WHT 14 +/* + * 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. + */ +struct dir_context; +typedef int (*filldir_t)(struct dir_context *, const char *, int, loff_t, u64, + unsigned); + struct dir_context { + const filldir_t actor; loff_t pos; }; @@ -94,12 +105,8 @@ struct inode { }; uid_t i_uid; gid_t i_gid; - dev_t i_rdev; u64 i_version; loff_t i_size; -#ifdef __NEED_I_SIZE_ORDERED - seqcount_t i_size_seqcount; -#endif struct timespec i_atime; struct timespec i_mtime; struct timespec i_ctime; @@ -107,39 +114,19 @@ struct inode { blkcnt_t i_blocks; unsigned short i_bytes; umode_t i_mode; - spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ - struct mutex i_mutex; - struct rw_semaphore i_alloc_sem; const struct inode_operations *i_op; const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct super_block *i_sb; - struct file_lock *i_flock; -#ifdef CONFIG_QUOTA - struct dquot *i_dquot[MAXQUOTAS]; -#endif - struct list_head i_devices; - int i_cindex; __u32 i_generation; -#ifdef CONFIG_DNOTIFY - unsigned long i_dnotify_mask; /* Directory notify events */ - struct dnotify_struct *i_dnotify; /* for directory notifications */ -#endif - -#ifdef CONFIG_INOTIFY - struct list_head inotify_watches; /* watches on this inode */ - struct mutex inotify_mutex; /* protects the watches list */ -#endif - unsigned long i_state; - unsigned long dirtied_when; /* jiffies of first dirtying */ unsigned int i_flags; + unsigned int i_count; + + char *i_link; -#ifdef CONFIG_SECURITY - void *i_security; -#endif void *i_private; /* fs or device private pointer */ }; @@ -199,19 +186,9 @@ struct super_block { Cannot be worse than a second */ u32 s_time_gran; - /* - * Filesystem subtype. If non-empty the filesystem type field - * in /proc/mounts will be "type.subtype" - */ - char *s_subtype; - - /* - * Saved mount options for lazy filesystems using - * generic_show_options() - */ - char *s_options; - /* Number of inodes with nlink == 0 but still referenced */ + + const struct dentry_operations *s_d_op; /* default d_op for dentries */ }; struct file_system_type { @@ -405,4 +382,80 @@ static inline loff_t i_size_read(const struct inode *inode) return inode->i_size; } +struct inode *new_inode(struct super_block *sb); +unsigned int get_next_ino(void); +void iput(struct inode *); +struct inode *iget(struct inode *); +void inc_nlink(struct inode *inode); + +struct inode_operations { + struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); + + const char *(*get_link) (struct dentry *dentry, struct inode *inode); + + int (*create) (struct inode *,struct dentry *, umode_t); + int (*link) (struct dentry *,struct inode *,struct dentry *); + int (*unlink) (struct inode *,struct dentry *); + int (*symlink) (struct inode *,struct dentry *,const char *); + int (*mkdir) (struct inode *,struct dentry *,umode_t); + int (*rmdir) (struct inode *,struct dentry *); + int (*rename) (struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); +}; + +static inline ino_t parent_ino(struct dentry *dentry) +{ + return dentry->d_parent->d_inode->i_ino; +} + +static inline bool dir_emit(struct dir_context *ctx, + const char *name, int namelen, + u64 ino, unsigned type) +{ + return ctx->actor(ctx, name, namelen, ctx->pos, ino, type) == 0; +} + +static inline bool dir_emit_dot(struct file *file, struct dir_context *ctx) +{ + return ctx->actor(ctx, ".", 1, ctx->pos, + file->f_path.dentry->d_inode->i_ino, DT_DIR) == 0; +} +static inline bool dir_emit_dotdot(struct file *file, struct dir_context *ctx) +{ + return ctx->actor(ctx, "..", 2, ctx->pos, + parent_ino(file->f_path.dentry), DT_DIR) == 0; +} + +static inline void dir_emit_dots(struct file *file, struct dir_context *ctx) +{ + if (ctx->pos == 0) { + dir_emit_dot(file, ctx); + ctx->pos = 1; + } + if (ctx->pos == 1) { + dir_emit_dotdot(file, ctx); + ctx->pos = 2; + } +} + +struct file_operations { + int (*iterate) (struct file *, struct dir_context *); + ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); + int (*ioctl) (struct file *, int request, void *buf); + int (*truncate) (struct file *, loff_t); +}; + +void drop_nlink(struct inode *inode); + +extern const struct file_operations simple_dir_operations; +extern const struct inode_operations simple_symlink_inode_operations; + +int simple_empty(struct dentry *dentry); +int simple_unlink(struct inode *dir, struct dentry *dentry); +int simple_rmdir(struct inode *dir, struct dentry *dentry); +struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned int flags); +int dcache_readdir(struct file *, struct dir_context *); +const char *simple_get_link(struct dentry *dentry, struct inode *inode); + #endif /* _LINUX_FS_H */ diff --git a/include/linux/mount.h b/include/linux/mount.h index 57d5ba9523..9557365fb5 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -14,8 +14,11 @@ struct vfsmount { struct dentry *mnt_root; /* root of the mounted tree */ + struct dentry *mountpoint; /* where it's mounted (barebox specific, no support */ + struct vfsmount *parent; /* for bind mounts and the like) */ struct super_block *mnt_sb; /* pointer to superblock */ int mnt_flags; + int ref; }; #endif /* _LINUX_MOUNT_H */ diff --git a/include/linux/namei.h b/include/linux/namei.h new file mode 100644 index 0000000000..8ed7f8a1cd --- /dev/null +++ b/include/linux/namei.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_NAMEI_H +#define _LINUX_NAMEI_H + +#include <linux/kernel.h> +#include <linux/path.h> + +enum { MAX_NESTED_LINKS = 8 }; + +#define MAXSYMLINKS 40 + +/* + * Type of the last component on LOOKUP_PARENT + */ +enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; + +/* + * The bitmask for a lookup event: + * - follow links at the end + * - require a directory + * - ending slashes ok even for nonexistent files + * - internal "there are more path components" flag + * - dentry cache is untrusted; force a real lookup + * - suppress terminal automount + */ +#define LOOKUP_FOLLOW 0x0001 +#define LOOKUP_DIRECTORY 0x0002 +#define LOOKUP_AUTOMOUNT 0x0004 + +#define LOOKUP_PARENT 0x0010 +#define LOOKUP_REVAL 0x0020 +#define LOOKUP_RCU 0x0040 +#define LOOKUP_NO_REVAL 0x0080 + +/* + * Intent data + */ +#define LOOKUP_OPEN 0x0100 +#define LOOKUP_CREATE 0x0200 +#define LOOKUP_EXCL 0x0400 +#define LOOKUP_RENAME_TARGET 0x0800 + +#define LOOKUP_JUMPED 0x1000 +#define LOOKUP_ROOT 0x2000 +#define LOOKUP_EMPTY 0x4000 +#define LOOKUP_DOWN 0x8000 + +#define AT_FDCWD -100 /* Special value used to indicate + openat should use the current + working directory. */ + +#endif /* _LINUX_NAMEI_H */ diff --git a/include/linux/stat.h b/include/linux/stat.h index af022c5c79..87fe068396 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h @@ -42,6 +42,8 @@ extern "C" { #define S_IWOTH 00002 /* read permission for other */ #define S_IXOTH 00001 /* execute/search permission for other */ +#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) + struct stat { unsigned short st_dev; unsigned short __pad1; |