Merge commit '73450231ffff' into android-4.4
Synced to the latest commit for merge:
73450231ff
f2fs: run fstrim asynchronously if runtime discard is on
Change-Id: Icec09d14f2768dfaa1a0691eac275f68adbf470b
Signed-off-by: Jaegeuk Kim <jaegeuk@google.com>
This commit is contained in:
commit
b826c97998
2 changed files with 523 additions and 110 deletions
411
include/linux/fscrypto.h
Normal file
411
include/linux/fscrypto.h
Normal file
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* General per-file encryption definition
|
||||
*
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
*
|
||||
* Written by Michael Halcrow, 2015.
|
||||
* Modified by Jaegeuk Kim, 2015.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FSCRYPTO_H
|
||||
#define _LINUX_FSCRYPTO_H
|
||||
|
||||
#include <linux/key.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bio.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include <uapi/linux/fs.h>
|
||||
|
||||
#define FS_KEY_DERIVATION_NONCE_SIZE 16
|
||||
#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
|
||||
|
||||
#define FS_POLICY_FLAGS_PAD_4 0x00
|
||||
#define FS_POLICY_FLAGS_PAD_8 0x01
|
||||
#define FS_POLICY_FLAGS_PAD_16 0x02
|
||||
#define FS_POLICY_FLAGS_PAD_32 0x03
|
||||
#define FS_POLICY_FLAGS_PAD_MASK 0x03
|
||||
#define FS_POLICY_FLAGS_VALID 0x03
|
||||
|
||||
/* Encryption algorithms */
|
||||
#define FS_ENCRYPTION_MODE_INVALID 0
|
||||
#define FS_ENCRYPTION_MODE_AES_256_XTS 1
|
||||
#define FS_ENCRYPTION_MODE_AES_256_GCM 2
|
||||
#define FS_ENCRYPTION_MODE_AES_256_CBC 3
|
||||
#define FS_ENCRYPTION_MODE_AES_256_CTS 4
|
||||
|
||||
/**
|
||||
* Encryption context for inode
|
||||
*
|
||||
* Protector format:
|
||||
* 1 byte: Protector format (1 = this version)
|
||||
* 1 byte: File contents encryption mode
|
||||
* 1 byte: File names encryption mode
|
||||
* 1 byte: Flags
|
||||
* 8 bytes: Master Key descriptor
|
||||
* 16 bytes: Encryption Key derivation nonce
|
||||
*/
|
||||
struct fscrypt_context {
|
||||
u8 format;
|
||||
u8 contents_encryption_mode;
|
||||
u8 filenames_encryption_mode;
|
||||
u8 flags;
|
||||
u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
|
||||
u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
|
||||
} __packed;
|
||||
|
||||
/* Encryption parameters */
|
||||
#define FS_XTS_TWEAK_SIZE 16
|
||||
#define FS_AES_128_ECB_KEY_SIZE 16
|
||||
#define FS_AES_256_GCM_KEY_SIZE 32
|
||||
#define FS_AES_256_CBC_KEY_SIZE 32
|
||||
#define FS_AES_256_CTS_KEY_SIZE 32
|
||||
#define FS_AES_256_XTS_KEY_SIZE 64
|
||||
#define FS_MAX_KEY_SIZE 64
|
||||
|
||||
#define FS_KEY_DESC_PREFIX "fscrypt:"
|
||||
#define FS_KEY_DESC_PREFIX_SIZE 8
|
||||
|
||||
/* This is passed in from userspace into the kernel keyring */
|
||||
struct fscrypt_key {
|
||||
u32 mode;
|
||||
u8 raw[FS_MAX_KEY_SIZE];
|
||||
u32 size;
|
||||
} __packed;
|
||||
|
||||
struct fscrypt_info {
|
||||
u8 ci_data_mode;
|
||||
u8 ci_filename_mode;
|
||||
u8 ci_flags;
|
||||
struct crypto_skcipher *ci_ctfm;
|
||||
struct key *ci_keyring_key;
|
||||
u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
|
||||
};
|
||||
|
||||
#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
|
||||
#define FS_WRITE_PATH_FL 0x00000002
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
u8 mode; /* Encryption mode for tfm */
|
||||
};
|
||||
|
||||
struct fscrypt_completion_result {
|
||||
struct completion completion;
|
||||
int res;
|
||||
};
|
||||
|
||||
#define DECLARE_FS_COMPLETION_RESULT(ecr) \
|
||||
struct fscrypt_completion_result ecr = { \
|
||||
COMPLETION_INITIALIZER((ecr).completion), 0 }
|
||||
|
||||
#define FS_FNAME_NUM_SCATTER_ENTRIES 4
|
||||
#define FS_CRYPTO_BLOCK_SIZE 16
|
||||
#define FS_FNAME_CRYPTO_DIGEST_SIZE 32
|
||||
|
||||
/**
|
||||
* For encrypted symlinks, the ciphertext length is stored at the beginning
|
||||
* of the string in little-endian format.
|
||||
*/
|
||||
struct fscrypt_symlink_data {
|
||||
__le16 len;
|
||||
char encrypted_path[1];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* This function is used to calculate the disk space required to
|
||||
* store a filename of length l in encrypted symlink format.
|
||||
*/
|
||||
static inline u32 fscrypt_symlink_data_len(u32 l)
|
||||
{
|
||||
if (l < FS_CRYPTO_BLOCK_SIZE)
|
||||
l = FS_CRYPTO_BLOCK_SIZE;
|
||||
return (l + sizeof(struct fscrypt_symlink_data) - 1);
|
||||
}
|
||||
|
||||
struct fscrypt_str {
|
||||
unsigned char *name;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct fscrypt_name {
|
||||
const struct qstr *usr_fname;
|
||||
struct fscrypt_str disk_name;
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
struct fscrypt_str crypto_buf;
|
||||
};
|
||||
|
||||
#define FSTR_INIT(n, l) { .name = n, .len = l }
|
||||
#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len)
|
||||
#define fname_name(p) ((p)->disk_name.name)
|
||||
#define fname_len(p) ((p)->disk_name.len)
|
||||
|
||||
/*
|
||||
* crypto opertions for filesystems
|
||||
*/
|
||||
struct fscrypt_operations {
|
||||
int (*get_context)(struct inode *, void *, size_t);
|
||||
int (*key_prefix)(struct inode *, u8 **);
|
||||
int (*prepare_context)(struct inode *);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
int (*dummy_context)(struct inode *);
|
||||
bool (*is_encrypted)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned (*max_namelen)(struct inode *);
|
||||
};
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
if (inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_valid_contents_enc_mode(u32 mode)
|
||||
{
|
||||
return (mode == FS_ENCRYPTION_MODE_AES_256_XTS);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_valid_filenames_enc_mode(u32 mode)
|
||||
{
|
||||
return (mode == FS_ENCRYPTION_MODE_AES_256_CTS);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
|
||||
{
|
||||
if (str->len == 1 && str->name[0] == '.')
|
||||
return true;
|
||||
|
||||
if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
#else
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int fscrypt_has_encryption_key(struct inode *inode)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
return (inode->i_crypt_info != NULL);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
spin_lock(&dentry->d_lock);
|
||||
dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
extern const struct dentry_operations fscrypt_d_ops;
|
||||
#endif
|
||||
|
||||
static inline void fscrypt_set_d_op(struct dentry *dentry)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
d_set_d_op(dentry, &fscrypt_d_ops);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
/* crypto.c */
|
||||
extern struct kmem_cache *fscrypt_info_cachep;
|
||||
int fscrypt_initialize(void);
|
||||
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(struct inode *, struct page *, gfp_t);
|
||||
extern int fscrypt_decrypt_page(struct page *);
|
||||
extern void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *, struct bio *);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int get_crypt_info(struct inode *);
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
extern void fscrypt_free_filename(struct fscrypt_name *);
|
||||
extern u32 fscrypt_fname_encrypted_size(struct inode *, u32);
|
||||
extern int fscrypt_fname_alloc_buffer(struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *,
|
||||
struct fscrypt_str *);
|
||||
#endif
|
||||
|
||||
/* crypto.c */
|
||||
static inline struct fscrypt_ctx *fscrypt_notsupp_get_ctx(struct inode *i,
|
||||
gfp_t f)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_notsupp_encrypt_page(struct inode *i,
|
||||
struct page *p, gfp_t f)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_decrypt_page(struct page *p)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_decrypt_bio_pages(struct fscrypt_ctx *c,
|
||||
struct bio *b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_pullback_bio_page(struct page **p, bool b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_restore_control_page(struct page *p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_zeroout_range(struct inode *i, pgoff_t p,
|
||||
sector_t s, unsigned int f)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* policy.c */
|
||||
static inline int fscrypt_notsupp_ioctl_set_policy(struct file *f,
|
||||
const void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_ioctl_get_policy(struct file *f,
|
||||
void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_has_permitted_context(struct inode *p,
|
||||
struct inode *i)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_inherit_context(struct inode *p,
|
||||
struct inode *i, void *v, bool b)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_notsupp_get_encryption_info(struct inode *i)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_put_encryption_info(struct inode *i,
|
||||
struct fscrypt_info *f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* fname.c */
|
||||
static inline int fscrypt_notsupp_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct fscrypt_name *fname)
|
||||
{
|
||||
if (dir->i_sb->s_cop->is_encrypted(dir))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(fname, 0, sizeof(struct fscrypt_name));
|
||||
fname->usr_fname = iname;
|
||||
fname->disk_name.name = (unsigned char *)iname->name;
|
||||
fname->disk_name.len = iname->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline u32 fscrypt_notsupp_fname_encrypted_size(struct inode *i, u32 s)
|
||||
{
|
||||
/* never happens */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_alloc_buffer(struct inode *inode,
|
||||
u32 ilen, struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_fname_free_buffer(struct fscrypt_str *c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_disk_to_usr(struct inode *inode,
|
||||
u32 hash, u32 minor_hash,
|
||||
const struct fscrypt_str *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_usr_to_disk(struct inode *inode,
|
||||
const struct qstr *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* _LINUX_FSCRYPTO_H */
|
222
scripts/tags.sh
222
scripts/tags.sh
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Generate tags or cscope files
|
||||
# Usage tags.sh <mode>
|
||||
#
|
||||
|
@ -135,11 +135,6 @@ all_kconfigs()
|
|||
find_other_sources 'Kconfig*'
|
||||
}
|
||||
|
||||
all_defconfigs()
|
||||
{
|
||||
find_sources $ALLSOURCE_ARCHS "defconfig"
|
||||
}
|
||||
|
||||
docscope()
|
||||
{
|
||||
(echo \-k; echo \-q; all_target_sources) > cscope.files
|
||||
|
@ -151,8 +146,111 @@ dogtags()
|
|||
all_target_sources | gtags -i -f -
|
||||
}
|
||||
|
||||
# Basic regular expressions with an optional /kind-spec/ for ctags and
|
||||
# the following limitations:
|
||||
# - No regex modifiers
|
||||
# - Use \{0,1\} instead of \?, because etags expects an unescaped ?
|
||||
# - \s is not working with etags, use a space or [ \t]
|
||||
# - \w works, but does not match underscores in etags
|
||||
# - etags regular expressions have to match at the start of a line;
|
||||
# a ^[^#] is prepended by setup_regex unless an anchor is already present
|
||||
regex_asm=(
|
||||
'/^\(ENTRY\|_GLOBAL\)(\([[:alnum:]_\\]*\)).*/\2/'
|
||||
)
|
||||
regex_c=(
|
||||
'/^SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/sys_\1/'
|
||||
'/^COMPAT_SYSCALL_DEFINE[0-9](\([[:alnum:]_]*\).*/compat_sys_\1/'
|
||||
'/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1/'
|
||||
'/^TRACE_EVENT(\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
|
||||
'/^DEFINE_EVENT([^,)]*, *\([[:alnum:]_]*\).*/trace_\1/'
|
||||
'/^DEFINE_EVENT([^,)]*, *\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
|
||||
'/^DEFINE_INSN_CACHE_OPS(\([[:alnum:]_]*\).*/get_\1_slot/'
|
||||
'/^DEFINE_INSN_CACHE_OPS(\([[:alnum:]_]*\).*/free_\1_slot/'
|
||||
'/^PAGEFLAG(\([[:alnum:]_]*\).*/Page\1/'
|
||||
'/^PAGEFLAG(\([[:alnum:]_]*\).*/SetPage\1/'
|
||||
'/^PAGEFLAG(\([[:alnum:]_]*\).*/ClearPage\1/'
|
||||
'/^TESTSETFLAG(\([[:alnum:]_]*\).*/TestSetPage\1/'
|
||||
'/^TESTPAGEFLAG(\([[:alnum:]_]*\).*/Page\1/'
|
||||
'/^SETPAGEFLAG(\([[:alnum:]_]*\).*/SetPage\1/'
|
||||
'/\<__SETPAGEFLAG(\([[:alnum:]_]*\).*/__SetPage\1/'
|
||||
'/\<TESTCLEARFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
|
||||
'/\<__TESTCLEARFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
|
||||
'/\<CLEARPAGEFLAG(\([[:alnum:]_]*\).*/ClearPage\1/'
|
||||
'/\<__CLEARPAGEFLAG(\([[:alnum:]_]*\).*/__ClearPage\1/'
|
||||
'/^__PAGEFLAG(\([[:alnum:]_]*\).*/__SetPage\1/'
|
||||
'/^__PAGEFLAG(\([[:alnum:]_]*\).*/__ClearPage\1/'
|
||||
'/^PAGEFLAG_FALSE(\([[:alnum:]_]*\).*/Page\1/'
|
||||
'/\<TESTSCFLAG(\([[:alnum:]_]*\).*/TestSetPage\1/'
|
||||
'/\<TESTSCFLAG(\([[:alnum:]_]*\).*/TestClearPage\1/'
|
||||
'/\<SETPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/SetPage\1/'
|
||||
'/\<CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/ClearPage\1/'
|
||||
'/\<__CLEARPAGEFLAG_NOOP(\([[:alnum:]_]*\).*/__ClearPage\1/'
|
||||
'/\<TESTCLEARFLAG_FALSE(\([[:alnum:]_]*\).*/TestClearPage\1/'
|
||||
'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/Page\1/'
|
||||
'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__SetPage\1/'
|
||||
'/^PAGE_MAPCOUNT_OPS(\([[:alnum:]_]*\).*/__ClearPage\1/'
|
||||
'/^TASK_PFA_TEST([^,]*, *\([[:alnum:]_]*\))/task_\1/'
|
||||
'/^TASK_PFA_SET([^,]*, *\([[:alnum:]_]*\))/task_set_\1/'
|
||||
'/^TASK_PFA_CLEAR([^,]*, *\([[:alnum:]_]*\))/task_clear_\1/'
|
||||
'/^DEF_MMIO_\(IN\|OUT\)_[XD](\([[:alnum:]_]*\),[^)]*)/\2/'
|
||||
'/^DEBUGGER_BOILERPLATE(\([[:alnum:]_]*\))/\1/'
|
||||
'/^DEF_PCI_AC_\(\|NO\)RET(\([[:alnum:]_]*\).*/\2/'
|
||||
'/^PCI_OP_READ(\(\w*\).*[1-4])/pci_bus_read_config_\1/'
|
||||
'/^PCI_OP_WRITE(\(\w*\).*[1-4])/pci_bus_write_config_\1/'
|
||||
'/\<DEFINE_\(MUTEX\|SEMAPHORE\|SPINLOCK\)(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\<DEFINE_\(RAW_SPINLOCK\|RWLOCK\|SEQLOCK\)(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\<DECLARE_\(RWSEM\|COMPLETION\)(\([[:alnum:]_]\+\)/\2/v/'
|
||||
'/\<DECLARE_BITMAP(\([[:alnum:]_]*\)/\1/v/'
|
||||
'/\(^\|\s\)\(\|L\|H\)LIST_HEAD(\([[:alnum:]_]*\)/\3/v/'
|
||||
'/\(^\|\s\)RADIX_TREE(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\<DEFINE_PER_CPU([^,]*, *\([[:alnum:]_]*\)/\1/v/'
|
||||
'/\<DEFINE_PER_CPU_SHARED_ALIGNED([^,]*, *\([[:alnum:]_]*\)/\1/v/'
|
||||
'/\<DECLARE_WAIT_QUEUE_HEAD(\([[:alnum:]_]*\)/\1/v/'
|
||||
'/\<DECLARE_\(TASKLET\|WORK\|DELAYED_WORK\)(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\(^\s\)OFFSET(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\(^\s\)DEFINE(\([[:alnum:]_]*\)/\2/v/'
|
||||
'/\<DEFINE_HASHTABLE(\([[:alnum:]_]*\)/\1/v/'
|
||||
)
|
||||
regex_kconfig=(
|
||||
'/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/\2/'
|
||||
'/^[[:blank:]]*\(menu\|\)config[[:blank:]]\+\([[:alnum:]_]\+\)/CONFIG_\2/'
|
||||
)
|
||||
setup_regex()
|
||||
{
|
||||
local mode=$1 lang tmp=() r
|
||||
shift
|
||||
|
||||
regex=()
|
||||
for lang; do
|
||||
case "$lang" in
|
||||
asm) tmp=("${regex_asm[@]}") ;;
|
||||
c) tmp=("${regex_c[@]}") ;;
|
||||
kconfig) tmp=("${regex_kconfig[@]}") ;;
|
||||
esac
|
||||
for r in "${tmp[@]}"; do
|
||||
if test "$mode" = "exuberant"; then
|
||||
regex[${#regex[@]}]="--regex-$lang=${r}b"
|
||||
else
|
||||
# Remove ctags /kind-spec/
|
||||
case "$r" in
|
||||
/*/*/?/)
|
||||
r=${r%?/}
|
||||
esac
|
||||
# Prepend ^[^#] unless already anchored
|
||||
case "$r" in
|
||||
/^*) ;;
|
||||
*)
|
||||
r="/^[^#]*${r#/}"
|
||||
esac
|
||||
regex[${#regex[@]}]="--regex=$r"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
exuberant()
|
||||
{
|
||||
setup_regex exuberant asm c
|
||||
all_target_sources | xargs $1 -a \
|
||||
-I __initdata,__exitdata,__initconst, \
|
||||
-I __initdata_memblock \
|
||||
|
@ -166,118 +264,22 @@ exuberant()
|
|||
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL,ACPI_EXPORT_SYMBOL \
|
||||
-I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \
|
||||
-I static,const \
|
||||
--extra=+f --c-kinds=+px \
|
||||
--regex-asm='/^(ENTRY|_GLOBAL)\(([^)]*)\).*/\2/' \
|
||||
--regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
|
||||
--regex-c='/^COMPAT_SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/compat_sys_\1/' \
|
||||
--regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
|
||||
--regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1_rcuidle/' \
|
||||
--regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/' \
|
||||
--regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1_rcuidle/' \
|
||||
--regex-c++='/PAGEFLAG\(([^,)]*).*/Page\1/' \
|
||||
--regex-c++='/PAGEFLAG\(([^,)]*).*/SetPage\1/' \
|
||||
--regex-c++='/PAGEFLAG\(([^,)]*).*/ClearPage\1/' \
|
||||
--regex-c++='/TESTSETFLAG\(([^,)]*).*/TestSetPage\1/' \
|
||||
--regex-c++='/TESTPAGEFLAG\(([^,)]*).*/Page\1/' \
|
||||
--regex-c++='/SETPAGEFLAG\(([^,)]*).*/SetPage\1/' \
|
||||
--regex-c++='/__SETPAGEFLAG\(([^,)]*).*/__SetPage\1/' \
|
||||
--regex-c++='/TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
|
||||
--regex-c++='/__TESTCLEARFLAG\(([^,)]*).*/TestClearPage\1/' \
|
||||
--regex-c++='/CLEARPAGEFLAG\(([^,)]*).*/ClearPage\1/' \
|
||||
--regex-c++='/__CLEARPAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
|
||||
--regex-c++='/__PAGEFLAG\(([^,)]*).*/__SetPage\1/' \
|
||||
--regex-c++='/__PAGEFLAG\(([^,)]*).*/__ClearPage\1/' \
|
||||
--regex-c++='/PAGEFLAG_FALSE\(([^,)]*).*/Page\1/' \
|
||||
--regex-c++='/TESTSCFLAG\(([^,)]*).*/TestSetPage\1/' \
|
||||
--regex-c++='/TESTSCFLAG\(([^,)]*).*/TestClearPage\1/' \
|
||||
--regex-c++='/SETPAGEFLAG_NOOP\(([^,)]*).*/SetPage\1/' \
|
||||
--regex-c++='/CLEARPAGEFLAG_NOOP\(([^,)]*).*/ClearPage\1/' \
|
||||
--regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
|
||||
--regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
|
||||
--regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
|
||||
--regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \
|
||||
--regex-c++='/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \
|
||||
--regex-c++='/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \
|
||||
--regex-c++='/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/'\
|
||||
--regex-c++='/DEF_MMIO_(IN|OUT)_(X|D)\(([^,]*),\s*[^)]*\)/\3/' \
|
||||
--regex-c++='/DEBUGGER_BOILERPLATE\(([^,]*)\)/\1/' \
|
||||
--regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \
|
||||
--regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \
|
||||
--regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \
|
||||
--regex-c='/DEFINE_(RAW_SPINLOCK|RWLOCK|SEQLOCK)\((\w*)/\2/v/' \
|
||||
--regex-c='/DECLARE_(RWSEM|COMPLETION)\((\w*)/\2/v/' \
|
||||
--regex-c='/DECLARE_BITMAP\((\w*)/\1/v/' \
|
||||
--regex-c='/(^|\s)(|L|H)LIST_HEAD\((\w*)/\3/v/' \
|
||||
--regex-c='/(^|\s)RADIX_TREE\((\w*)/\2/v/' \
|
||||
--regex-c='/DEFINE_PER_CPU\(([^,]*,\s*)(\w*).*\)/\2/v/' \
|
||||
--regex-c='/DEFINE_PER_CPU_SHARED_ALIGNED\(([^,]*,\s*)(\w*).*\)/\2/v/' \
|
||||
--regex-c='/DECLARE_WAIT_QUEUE_HEAD\((\w*)/\1/v/' \
|
||||
--regex-c='/DECLARE_(TASKLET|WORK|DELAYED_WORK)\((\w*)/\2/v/' \
|
||||
--regex-c='/DEFINE_PCI_DEVICE_TABLE\((\w*)/\1/v/' \
|
||||
--regex-c='/(^\s)OFFSET\((\w*)/\2/v/' \
|
||||
--regex-c='/(^\s)DEFINE\((\w*)/\2/v/' \
|
||||
--regex-c='/DEFINE_HASHTABLE\((\w*)/\1/v/'
|
||||
--extra=+fq --c-kinds=+px --fields=+iaS --langmap=c:+.h \
|
||||
"${regex[@]}"
|
||||
|
||||
setup_regex exuberant kconfig
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--langdef=kconfig --language-force=kconfig \
|
||||
--regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/\2/'
|
||||
--langdef=kconfig --language-force=kconfig "${regex[@]}"
|
||||
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--langdef=kconfig --language-force=kconfig \
|
||||
--regex-kconfig='/^[[:blank:]]*(menu|)config[[:blank:]]+([[:alnum:]_]+)/CONFIG_\2/'
|
||||
|
||||
all_defconfigs | xargs -r $1 -a \
|
||||
--langdef=dotconfig --language-force=dotconfig \
|
||||
--regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'
|
||||
}
|
||||
|
||||
emacs()
|
||||
{
|
||||
all_target_sources | xargs $1 -a \
|
||||
--regex='/^\(ENTRY\|_GLOBAL\)(\([^)]*\)).*/\2/' \
|
||||
--regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
|
||||
--regex='/^COMPAT_SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/compat_sys_\1/' \
|
||||
--regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
|
||||
--regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1_rcuidle/' \
|
||||
--regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/' \
|
||||
--regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1_rcuidle/' \
|
||||
--regex='/PAGEFLAG(\([^,)]*\).*/Page\1/' \
|
||||
--regex='/PAGEFLAG(\([^,)]*\).*/SetPage\1/' \
|
||||
--regex='/PAGEFLAG(\([^,)]*\).*/ClearPage\1/' \
|
||||
--regex='/TESTSETFLAG(\([^,)]*\).*/TestSetPage\1/' \
|
||||
--regex='/TESTPAGEFLAG(\([^,)]*\).*/Page\1/' \
|
||||
--regex='/SETPAGEFLAG(\([^,)]*\).*/SetPage\1/' \
|
||||
--regex='/__SETPAGEFLAG(\([^,)]*\).*/__SetPage\1/' \
|
||||
--regex='/TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \
|
||||
--regex='/__TESTCLEARFLAG(\([^,)]*\).*/TestClearPage\1/' \
|
||||
--regex='/CLEARPAGEFLAG(\([^,)]*\).*/ClearPage\1/' \
|
||||
--regex='/__CLEARPAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \
|
||||
--regex='/__PAGEFLAG(\([^,)]*\).*/__SetPage\1/' \
|
||||
--regex='/__PAGEFLAG(\([^,)]*\).*/__ClearPage\1/' \
|
||||
--regex='/PAGEFLAG_FALSE(\([^,)]*\).*/Page\1/' \
|
||||
--regex='/TESTSCFLAG(\([^,)]*\).*/TestSetPage\1/' \
|
||||
--regex='/TESTSCFLAG(\([^,)]*\).*/TestClearPage\1/' \
|
||||
--regex='/SETPAGEFLAG_NOOP(\([^,)]*\).*/SetPage\1/' \
|
||||
--regex='/CLEARPAGEFLAG_NOOP(\([^,)]*\).*/ClearPage\1/' \
|
||||
--regex='/__CLEARPAGEFLAG_NOOP(\([^,)]*\).*/__ClearPage\1/' \
|
||||
--regex='/TESTCLEARFLAG_FALSE(\([^,)]*\).*/TestClearPage\1/' \
|
||||
--regex='/__TESTCLEARFLAG_FALSE(\([^,)]*\).*/__TestClearPage\1/' \
|
||||
--regex='/TASK_PFA_TEST\([^,]*,\s*([^)]*)\)/task_\1/' \
|
||||
--regex='/TASK_PFA_SET\([^,]*,\s*([^)]*)\)/task_set_\1/' \
|
||||
--regex='/TASK_PFA_CLEAR\([^,]*,\s*([^)]*)\)/task_clear_\1/' \
|
||||
--regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \
|
||||
--regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \
|
||||
--regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\
|
||||
--regex='/[^#]*DEFINE_HASHTABLE(\([^,)]*\)/\1/'
|
||||
setup_regex emacs asm c
|
||||
all_target_sources | xargs $1 -a "${regex[@]}"
|
||||
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
|
||||
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/CONFIG_\3/'
|
||||
|
||||
all_defconfigs | xargs -r $1 -a \
|
||||
--regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'
|
||||
setup_regex emacs kconfig
|
||||
all_kconfigs | xargs $1 -a "${regex[@]}"
|
||||
}
|
||||
|
||||
xtags()
|
||||
|
|
Loading…
Add table
Reference in a new issue