Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "A very large number of cleanups and bug fixes --- in particular for the ext4 encryption patches, which is a new feature added in the last merge window. Also fix a number of long-standing xfstest failures. (Quota writes failing due to ENOSPC, a race between truncate and writepage in data=journalled mode that was causing generic/068 to fail, and other corner cases.) Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2 performance eliminating locking when a buffer is modified more than once during a transaction (which is very common for allocation bitmaps, for example), in which case the state of the journalled buffer head doesn't need to change" [ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in the merge resolution, to make it clear that that function is _only_ used for encrypted symlinks. The function doesn't actually work for non-encrypted symlinks at all, and they use the generic helpers - Linus ] * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits) ext4: set lazytime on remount if MS_LAZYTIME is set by mount ext4: only call ext4_truncate when size <= isize ext4: make online defrag error reporting consistent ext4: minor cleanup of ext4_da_reserve_space() ext4: don't retry file block mapping on bigalloc fs with non-extent file ext4: prevent ext4_quota_write() from failing due to ENOSPC ext4: call sync_blockdev() before invalidate_bdev() in put_super() jbd2: speedup jbd2_journal_dirty_metadata() jbd2: get rid of open coded allocation retry loop ext4: improve warning directory handling messages jbd2: fix ocfs2 corrupt when updating journal superblock fails ext4: mballoc: avoid 20-argument function call ext4: wait for existing dio workers in ext4_alloc_file_blocks() ext4: recalculate journal credits as inode depth changes jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail() ext4: use swap() in mext_page_double_lock() ext4: use swap() in memswap() ext4: fix race between truncate and __ext4_journalled_writepage() ext4 crypto: fail the mount if blocksize != pagesize ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate ...
This commit is contained in:
159
fs/ext4/ext4.h
159
fs/ext4/ext4.h
@@ -69,15 +69,6 @@
|
||||
#define ext_debug(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define EXT4_ERROR_INODE(inode, fmt, a...) \
|
||||
ext4_error_inode((inode), __func__, __LINE__, 0, (fmt), ## a)
|
||||
|
||||
#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \
|
||||
ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a)
|
||||
|
||||
#define EXT4_ERROR_FILE(file, block, fmt, a...) \
|
||||
ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
|
||||
|
||||
/* data type for block offset of block group */
|
||||
typedef int ext4_grpblk_t;
|
||||
|
||||
@@ -90,6 +81,11 @@ typedef __u32 ext4_lblk_t;
|
||||
/* data type for block group number */
|
||||
typedef unsigned int ext4_group_t;
|
||||
|
||||
enum SHIFT_DIRECTION {
|
||||
SHIFT_LEFT = 0,
|
||||
SHIFT_RIGHT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags used in mballoc's allocation_context flags field.
|
||||
*
|
||||
@@ -911,7 +907,6 @@ struct ext4_inode_info {
|
||||
|
||||
/* on-disk additional length */
|
||||
__u16 i_extra_isize;
|
||||
char i_crypt_policy_flags;
|
||||
|
||||
/* Indicate the inline data space. */
|
||||
u16 i_inline_off;
|
||||
@@ -955,7 +950,7 @@ struct ext4_inode_info {
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
/* Encryption params */
|
||||
struct ext4_encryption_key i_encryption_key;
|
||||
struct ext4_crypt_info *i_crypt_info;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1374,12 +1369,6 @@ struct ext4_sb_info {
|
||||
struct ratelimit_state s_err_ratelimit_state;
|
||||
struct ratelimit_state s_warning_ratelimit_state;
|
||||
struct ratelimit_state s_msg_ratelimit_state;
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
/* Encryption */
|
||||
uint32_t s_file_encryption_mode;
|
||||
uint32_t s_dir_encryption_mode;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
|
||||
@@ -1838,6 +1827,17 @@ struct dx_hash_info
|
||||
*/
|
||||
#define HASH_NB_ALWAYS 1
|
||||
|
||||
struct ext4_filename {
|
||||
const struct qstr *usr_fname;
|
||||
struct ext4_str disk_name;
|
||||
struct dx_hash_info hinfo;
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
struct ext4_str crypto_buf;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define fname_name(p) ((p)->disk_name.name)
|
||||
#define fname_len(p) ((p)->disk_name.len)
|
||||
|
||||
/*
|
||||
* Describe an inode's exact location on disk and in memory
|
||||
@@ -2054,6 +2054,7 @@ int ext4_get_policy(struct inode *inode,
|
||||
struct ext4_encryption_policy *policy);
|
||||
|
||||
/* crypto.c */
|
||||
extern struct kmem_cache *ext4_crypt_info_cachep;
|
||||
bool ext4_valid_contents_enc_mode(uint32_t mode);
|
||||
uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
|
||||
extern struct workqueue_struct *ext4_read_workqueue;
|
||||
@@ -2085,57 +2086,84 @@ static inline int ext4_sb_has_crypto(struct super_block *sb)
|
||||
/* crypto_fname.c */
|
||||
bool ext4_valid_filenames_enc_mode(uint32_t mode);
|
||||
u32 ext4_fname_crypto_round_up(u32 size, u32 blksize);
|
||||
int ext4_fname_crypto_alloc_buffer(struct ext4_fname_crypto_ctx *ctx,
|
||||
unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen);
|
||||
int ext4_fname_crypto_alloc_buffer(struct inode *inode,
|
||||
u32 ilen, struct ext4_str *crypto_str);
|
||||
int _ext4_fname_disk_to_usr(struct ext4_fname_crypto_ctx *ctx,
|
||||
int _ext4_fname_disk_to_usr(struct inode *inode,
|
||||
struct dx_hash_info *hinfo,
|
||||
const struct ext4_str *iname,
|
||||
struct ext4_str *oname);
|
||||
int ext4_fname_disk_to_usr(struct ext4_fname_crypto_ctx *ctx,
|
||||
int ext4_fname_disk_to_usr(struct inode *inode,
|
||||
struct dx_hash_info *hinfo,
|
||||
const struct ext4_dir_entry_2 *de,
|
||||
struct ext4_str *oname);
|
||||
int ext4_fname_usr_to_disk(struct ext4_fname_crypto_ctx *ctx,
|
||||
int ext4_fname_usr_to_disk(struct inode *inode,
|
||||
const struct qstr *iname,
|
||||
struct ext4_str *oname);
|
||||
int ext4_fname_usr_to_hash(struct ext4_fname_crypto_ctx *ctx,
|
||||
const struct qstr *iname,
|
||||
struct dx_hash_info *hinfo);
|
||||
int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
|
||||
u32 namelen);
|
||||
int ext4_fname_match(struct ext4_fname_crypto_ctx *ctx, struct ext4_str *cstr,
|
||||
int len, const char * const name,
|
||||
struct ext4_dir_entry_2 *de);
|
||||
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx);
|
||||
struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
|
||||
u32 max_len);
|
||||
void ext4_fname_crypto_free_buffer(struct ext4_str *crypto_str);
|
||||
int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
|
||||
int lookup, struct ext4_filename *fname);
|
||||
void ext4_fname_free_filename(struct ext4_filename *fname);
|
||||
#else
|
||||
static inline
|
||||
void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx) { }
|
||||
static inline
|
||||
struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
|
||||
u32 max_len)
|
||||
int ext4_setup_fname_crypto(struct inode *inode)
|
||||
{
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
static inline void ext4_fname_crypto_free_buffer(struct ext4_str *p) { }
|
||||
static inline int ext4_fname_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct ext4_filename *fname)
|
||||
{
|
||||
fname->usr_fname = iname;
|
||||
fname->disk_name.name = (unsigned char *) iname->name;
|
||||
fname->disk_name.len = iname->len;
|
||||
return 0;
|
||||
}
|
||||
static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
|
||||
#endif
|
||||
|
||||
|
||||
/* crypto_key.c */
|
||||
int ext4_generate_encryption_key(struct inode *inode);
|
||||
void ext4_free_crypt_info(struct ext4_crypt_info *ci);
|
||||
void ext4_free_encryption_info(struct inode *inode, struct ext4_crypt_info *ci);
|
||||
int _ext4_get_encryption_info(struct inode *inode);
|
||||
|
||||
#ifdef CONFIG_EXT4_FS_ENCRYPTION
|
||||
int ext4_has_encryption_key(struct inode *inode);
|
||||
|
||||
static inline int ext4_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
|
||||
|
||||
if (!ci ||
|
||||
(ci->ci_keyring_key &&
|
||||
(ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
|
||||
(1 << KEY_FLAG_REVOKED) |
|
||||
(1 << KEY_FLAG_DEAD)))))
|
||||
return _ext4_get_encryption_info(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
|
||||
{
|
||||
return EXT4_I(inode)->i_crypt_info;
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int ext4_has_encryption_key(struct inode *inode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int ext4_get_encryption_info(struct inode *inode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline struct ext4_crypt_info *ext4_encryption_info(struct inode *inode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2156,14 +2184,13 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
|
||||
extern int ext4_find_dest_de(struct inode *dir, struct inode *inode,
|
||||
struct buffer_head *bh,
|
||||
void *buf, int buf_size,
|
||||
const char *name, int namelen,
|
||||
struct ext4_filename *fname,
|
||||
struct ext4_dir_entry_2 **dest_de);
|
||||
int ext4_insert_dentry(struct inode *dir,
|
||||
struct inode *inode,
|
||||
struct ext4_dir_entry_2 *de,
|
||||
int buf_size,
|
||||
const struct qstr *iname,
|
||||
const char *name, int namelen);
|
||||
struct inode *inode,
|
||||
struct ext4_dir_entry_2 *de,
|
||||
int buf_size,
|
||||
struct ext4_filename *fname);
|
||||
static inline void ext4_update_dx_flag(struct inode *inode)
|
||||
{
|
||||
if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
|
||||
@@ -2317,13 +2344,14 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
|
||||
extern int ext4_orphan_del(handle_t *, struct inode *);
|
||||
extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
|
||||
__u32 start_minor_hash, __u32 *next_hash);
|
||||
extern int search_dir(struct buffer_head *bh,
|
||||
char *search_buf,
|
||||
int buf_size,
|
||||
struct inode *dir,
|
||||
const struct qstr *d_name,
|
||||
unsigned int offset,
|
||||
struct ext4_dir_entry_2 **res_dir);
|
||||
extern int ext4_search_dir(struct buffer_head *bh,
|
||||
char *search_buf,
|
||||
int buf_size,
|
||||
struct inode *dir,
|
||||
struct ext4_filename *fname,
|
||||
const struct qstr *d_name,
|
||||
unsigned int offset,
|
||||
struct ext4_dir_entry_2 **res_dir);
|
||||
extern int ext4_generic_delete_entry(handle_t *handle,
|
||||
struct inode *dir,
|
||||
struct ext4_dir_entry_2 *de_del,
|
||||
@@ -2368,6 +2396,9 @@ void __ext4_abort(struct super_block *, const char *, unsigned int,
|
||||
extern __printf(4, 5)
|
||||
void __ext4_warning(struct super_block *, const char *, unsigned int,
|
||||
const char *, ...);
|
||||
extern __printf(4, 5)
|
||||
void __ext4_warning_inode(const struct inode *inode, const char *function,
|
||||
unsigned int line, const char *fmt, ...);
|
||||
extern __printf(3, 4)
|
||||
void __ext4_msg(struct super_block *, const char *, const char *, ...);
|
||||
extern void __dump_mmp_msg(struct super_block *, struct mmp_struct *mmp,
|
||||
@@ -2378,6 +2409,15 @@ void __ext4_grp_locked_error(const char *, unsigned int,
|
||||
unsigned long, ext4_fsblk_t,
|
||||
const char *, ...);
|
||||
|
||||
#define EXT4_ERROR_INODE(inode, fmt, a...) \
|
||||
ext4_error_inode((inode), __func__, __LINE__, 0, (fmt), ## a)
|
||||
|
||||
#define EXT4_ERROR_INODE_BLOCK(inode, block, fmt, a...) \
|
||||
ext4_error_inode((inode), __func__, __LINE__, (block), (fmt), ## a)
|
||||
|
||||
#define EXT4_ERROR_FILE(file, block, fmt, a...) \
|
||||
ext4_error_file((file), __func__, __LINE__, (block), (fmt), ## a)
|
||||
|
||||
#ifdef CONFIG_PRINTK
|
||||
|
||||
#define ext4_error_inode(inode, func, line, block, fmt, ...) \
|
||||
@@ -2390,6 +2430,8 @@ void __ext4_grp_locked_error(const char *, unsigned int,
|
||||
__ext4_abort(sb, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define ext4_warning(sb, fmt, ...) \
|
||||
__ext4_warning(sb, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define ext4_warning_inode(inode, fmt, ...) \
|
||||
__ext4_warning_inode(inode, __func__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
#define ext4_msg(sb, level, fmt, ...) \
|
||||
__ext4_msg(sb, level, fmt, ##__VA_ARGS__)
|
||||
#define dump_mmp_msg(sb, mmp, msg) \
|
||||
@@ -2425,6 +2467,11 @@ do { \
|
||||
no_printk(fmt, ##__VA_ARGS__); \
|
||||
__ext4_warning(sb, "", 0, " "); \
|
||||
} while (0)
|
||||
#define ext4_warning_inode(inode, fmt, ...) \
|
||||
do { \
|
||||
no_printk(fmt, ##__VA_ARGS__); \
|
||||
__ext4_warning_inode(inode, "", 0, " "); \
|
||||
} while (0)
|
||||
#define ext4_msg(sb, level, fmt, ...) \
|
||||
do { \
|
||||
no_printk(fmt, ##__VA_ARGS__); \
|
||||
@@ -2768,7 +2815,9 @@ extern int ext4_da_write_inline_data_begin(struct address_space *mapping,
|
||||
extern int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
|
||||
unsigned len, unsigned copied,
|
||||
struct page *page);
|
||||
extern int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
|
||||
extern int ext4_try_add_inline_entry(handle_t *handle,
|
||||
struct ext4_filename *fname,
|
||||
struct dentry *dentry,
|
||||
struct inode *inode);
|
||||
extern int ext4_try_create_inline_dir(handle_t *handle,
|
||||
struct inode *parent,
|
||||
@@ -2782,6 +2831,7 @@ extern int htree_inlinedir_to_tree(struct file *dir_file,
|
||||
__u32 start_hash, __u32 start_minor_hash,
|
||||
int *has_inline_data);
|
||||
extern struct buffer_head *ext4_find_inline_entry(struct inode *dir,
|
||||
struct ext4_filename *fname,
|
||||
const struct qstr *d_name,
|
||||
struct ext4_dir_entry_2 **res_dir,
|
||||
int *has_inline_data);
|
||||
@@ -2913,6 +2963,7 @@ extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||
__u64 start, __u64 len);
|
||||
extern int ext4_ext_precache(struct inode *inode);
|
||||
extern int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len);
|
||||
extern int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len);
|
||||
extern int ext4_swap_extents(handle_t *handle, struct inode *inode1,
|
||||
struct inode *inode2, ext4_lblk_t lblk1,
|
||||
ext4_lblk_t lblk2, ext4_lblk_t count,
|
||||
|
Reference in New Issue
Block a user