Release 4.10 fs/ext4/namei.c
/*
* linux/fs/ext4/namei.c
*
* Copyright (C) 1992, 1993, 1994, 1995
* Remy Card (card@masi.ibp.fr)
* Laboratoire MASI - Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* from
*
* linux/fs/minix/namei.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* Big-endian to little-endian byte-swapping/bitmaps by
* David S. Miller (davem@caip.rutgers.edu), 1995
* Directory entry file type support and forward compatibility hooks
* for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
* Hash Tree Directory indexing (c)
* Daniel Phillips, 2001
* Hash Tree Directory indexing porting
* Christopher Li, 2002
* Hash Tree Directory indexing cleanup
* Theodore Ts'o, 2002
*/
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/time.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/bio.h>
#include "ext4.h"
#include "ext4_jbd2.h"
#include "xattr.h"
#include "acl.h"
#include <trace/events/ext4.h>
/*
* define how far ahead to read directories while searching them.
*/
#define NAMEI_RA_CHUNKS 2
#define NAMEI_RA_BLOCKS 4
#define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
static struct buffer_head *ext4_append(handle_t *handle,
struct inode *inode,
ext4_lblk_t *block)
{
struct buffer_head *bh;
int err;
if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb &&
((inode->i_size >> 10) >=
EXT4_SB(inode->i_sb)->s_max_dir_size_kb)))
return ERR_PTR(-ENOSPC);
*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
bh = ext4_bread(handle, inode, *block, EXT4_GET_BLOCKS_CREATE);
if (IS_ERR(bh))
return bh;
inode->i_size += inode->i_sb->s_blocksize;
EXT4_I(inode)->i_disksize = inode->i_size;
BUFFER_TRACE(bh, "get_write_access");
err = ext4_journal_get_write_access(handle, bh);
if (err) {
brelse(bh);
ext4_std_error(inode->i_sb, err);
return ERR_PTR(err);
}
return bh;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 78 | 45.35% | 1 | 10.00% |
theodore tso | theodore tso | 58 | 33.72% | 4 | 40.00% |
akinobu mita | akinobu mita | 16 | 9.30% | 1 | 10.00% |
carlos maiolino | carlos maiolino | 8 | 4.65% | 1 | 10.00% |
liang xie | liang xie | 7 | 4.07% | 1 | 10.00% |
mingming cao | mingming cao | 4 | 2.33% | 1 | 10.00% |
aneesh kumar | aneesh kumar | 1 | 0.58% | 1 | 10.00% |
| Total | 172 | 100.00% | 10 | 100.00% |
static int ext4_dx_csum_verify(struct inode *inode,
struct ext4_dir_entry *dirent);
typedef enum {
EITHER, INDEX, DIRENT
}
dirblock_type_t;
#define ext4_read_dirblock(inode, block, type) \
__ext4_read_dirblock((inode), (block), (type), __func__, __LINE__)
static struct buffer_head *__ext4_read_dirblock(struct inode *inode,
ext4_lblk_t block,
dirblock_type_t type,
const char *func,
unsigned int line)
{
struct buffer_head *bh;
struct ext4_dir_entry *dirent;
int is_dx_block = 0;
bh = ext4_bread(NULL, inode, block, 0);
if (IS_ERR(bh)) {
__ext4_warning(inode->i_sb, func, line,
"inode #%lu: lblock %lu: comm %s: "
"error %ld reading directory block",
inode->i_ino, (unsigned long)block,
current->comm, PTR_ERR(bh));
return bh;
}
if (!bh) {
ext4_error_inode(inode, func, line, block,
"Directory hole found");
return ERR_PTR(-EFSCORRUPTED);
}
dirent = (struct ext4_dir_entry *) bh->b_data;
/* Determine whether or not we have an index block */
if (is_dx(inode)) {
if (block == 0)
is_dx_block = 1;
else if (ext4_rec_len_from_disk(dirent->rec_len,
inode->i_sb->s_blocksize) ==
inode->i_sb->s_blocksize)
is_dx_block = 1;
}
if (!is_dx_block && type == INDEX) {
ext4_error_inode(inode, func, line, block,
"directory leaf block found instead of index block");
return ERR_PTR(-EFSCORRUPTED);
}
if (!ext4_has_metadata_csum(inode->i_sb) ||
buffer_verified(bh))
return bh;
/*
* An empty leaf block can get mistaken for a index block; for
* this reason, we can only check the index checksum when the
* caller is sure it should be an index block.
*/
if (is_dx_block && type == INDEX) {
if (ext4_dx_csum_verify(inode, dirent))
set_buffer_verified(bh);
else {
ext4_error_inode(inode, func, line, block,
"Directory index failed checksum");
brelse(bh);
return ERR_PTR(-EFSBADCRC);
}
}
if (!is_dx_block) {
if (ext4_dirent_csum_verify(inode, dirent))
set_buffer_verified(bh);
else {
ext4_error_inode(inode, func, line, block,
"Directory block failed checksum");
brelse(bh);
return ERR_PTR(-EFSBADCRC);
}
}
return bh;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 282 | 83.19% | 2 | 25.00% |
andreas dilger | andreas dilger | 21 | 6.19% | 1 | 12.50% |
carlos maiolino | carlos maiolino | 13 | 3.83% | 1 | 12.50% |
akinobu mita | akinobu mita | 11 | 3.24% | 1 | 12.50% |
dave kleikamp | dave kleikamp | 7 | 2.06% | 1 | 12.50% |
darrick j. wong | darrick j. wong | 4 | 1.18% | 1 | 12.50% |
dmitriy monakhov | dmitriy monakhov | 1 | 0.29% | 1 | 12.50% |
| Total | 339 | 100.00% | 8 | 100.00% |
#ifndef assert
#define assert(test) J_ASSERT(test)
#endif
#ifdef DX_DEBUG
#define dxtrace(command) command
#else
#define dxtrace(command)
#endif
struct fake_dirent
{
__le32 inode;
__le16 rec_len;
u8 name_len;
u8 file_type;
};
struct dx_countlimit
{
__le16 limit;
__le16 count;
};
struct dx_entry
{
__le32 hash;
__le32 block;
};
/*
* dx_root_info is laid out so that if it should somehow get overlaid by a
* dirent the two low bits of the hash version will be zero. Therefore, the
* hash version mod 4 should never be 0. Sincerely, the paranoia department.
*/
struct dx_root
{
struct fake_dirent dot;
char dot_name[4];
struct fake_dirent dotdot;
char dotdot_name[4];
struct dx_root_info
{
__le32 reserved_zero;
u8 hash_version;
u8 info_length; /* 8 */
u8 indirect_levels;
u8 unused_flags;
}
info;
struct dx_entry entries[0];
};
struct dx_node
{
struct fake_dirent fake;
struct dx_entry entries[0];
};
struct dx_frame
{
struct buffer_head *bh;
struct dx_entry *entries;
struct dx_entry *at;
};
struct dx_map_entry
{
u32 hash;
u16 offs;
u16 size;
};
/*
* This goes at the end of each htree block.
*/
struct dx_tail {
u32 dt_reserved;
__le32 dt_checksum; /* crc32c(uuid+inum+dirblock) */
};
static inline ext4_lblk_t dx_get_block(struct dx_entry *entry);
static void dx_set_block(struct dx_entry *entry, ext4_lblk_t value);
static inline unsigned dx_get_hash(struct dx_entry *entry);
static void dx_set_hash(struct dx_entry *entry, unsigned value);
static unsigned dx_get_count(struct dx_entry *entries);
static unsigned dx_get_limit(struct dx_entry *entries);
static void dx_set_count(struct dx_entry *entries, unsigned value);
static void dx_set_limit(struct dx_entry *entries, unsigned value);
static unsigned dx_root_limit(struct inode *dir, unsigned infosize);
static unsigned dx_node_limit(struct inode *dir);
static struct dx_frame *dx_probe(struct ext4_filename *fname,
struct inode *dir,
struct dx_hash_info *hinfo,
struct dx_frame *frame);
static void dx_release(struct dx_frame *frames);
static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de,
unsigned blocksize, struct dx_hash_info *hinfo,
struct dx_map_entry map[]);
static void dx_sort_map(struct dx_map_entry *map, unsigned count);
static struct ext4_dir_entry_2 *dx_move_dirents(char *from, char *to,
struct dx_map_entry *offsets, int count, unsigned blocksize);
static struct ext4_dir_entry_2* dx_pack_dirents(char *base, unsigned blocksize);
static void dx_insert_block(struct dx_frame *frame,
u32 hash, ext4_lblk_t block);
static int ext4_htree_next_block(struct inode *dir, __u32 hash,
struct dx_frame *frame,
struct dx_frame *frames,
__u32 *start_hash);
static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
struct ext4_filename *fname,
struct ext4_dir_entry_2 **res_dir);
static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
struct inode *dir, struct inode *inode);
/* checksumming functions */
void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
unsigned int blocksize)
{
memset(t, 0, sizeof(struct ext4_dir_entry_tail));
t->det_rec_len = ext4_rec_len_to_disk(
sizeof(struct ext4_dir_entry_tail), blocksize);
t->det_reserved_ft = EXT4_FT_DIR_CSUM;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 34 | 70.83% | 1 | 33.33% |
li zefan | li zefan | 9 | 18.75% | 1 | 33.33% |
wei yongjun | wei yongjun | 5 | 10.42% | 1 | 33.33% |
| Total | 48 | 100.00% | 3 | 100.00% |
/* Walk through a dirent block to find a checksum "dirent" at the tail */
static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode,
struct ext4_dir_entry *de)
{
struct ext4_dir_entry_tail *t;
#ifdef PARANOID
struct ext4_dir_entry *d, *top;
d = de;
top = (struct ext4_dir_entry *)(((void *)de) +
(EXT4_BLOCK_SIZE(inode->i_sb) -
sizeof(struct ext4_dir_entry_tail)));
while (d < top && d->rec_len)
d = (struct ext4_dir_entry *)(((void *)d) +
le16_to_cpu(d->rec_len));
if (d != top)
return NULL;
t = (struct ext4_dir_entry_tail *)d;
#else
t = EXT4_DIRENT_TAIL(de, EXT4_BLOCK_SIZE(inode->i_sb));
#endif
if (t->det_reserved_zero1 ||
le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) ||
t->det_reserved_zero2 ||
t->det_reserved_ft != EXT4_FT_DIR_CSUM)
return NULL;
return t;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 145 | 82.86% | 1 | 50.00% |
dave kleikamp | dave kleikamp | 30 | 17.14% | 1 | 50.00% |
| Total | 175 | 100.00% | 2 | 100.00% |
static __le32 ext4_dirent_csum(struct inode *inode,
struct ext4_dir_entry *dirent, int size)
{
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
__u32 csum;
csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size);
return cpu_to_le32(csum);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 69 | 100.00% | 1 | 100.00% |
| Total | 69 | 100.00% | 1 | 100.00% |
#define warn_no_space_for_csum(inode) \
__warn_no_space_for_csum((inode), __func__, __LINE__)
static void __warn_no_space_for_csum(struct inode *inode, const char *func,
unsigned int line)
{
__ext4_warning_inode(inode, func, line,
"No space for directory leaf checksum. Please run e2fsck -D.");
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
theodore tso | theodore tso | 16 | 51.61% | 1 | 50.00% |
andreas dilger | andreas dilger | 15 | 48.39% | 1 | 50.00% |
| Total | 31 | 100.00% | 2 | 100.00% |
int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent)
{
struct ext4_dir_entry_tail *t;
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;
t = get_dirent_tail(inode, dirent);
if (!t) {
warn_no_space_for_csum(inode);
return 0;
}
if (t->det_checksum != ext4_dirent_csum(inode, dirent,
(void *)t - (void *)dirent))
return 0;
return 1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 86 | 97.73% | 1 | 33.33% |
dmitriy monakhov | dmitriy monakhov | 1 | 1.14% | 1 | 33.33% |
theodore tso | theodore tso | 1 | 1.14% | 1 | 33.33% |
| Total | 88 | 100.00% | 3 | 100.00% |
static void ext4_dirent_csum_set(struct inode *inode,
struct ext4_dir_entry *dirent)
{
struct ext4_dir_entry_tail *t;
if (!ext4_has_metadata_csum(inode->i_sb))
return;
t = get_dirent_tail(inode, dirent);
if (!t) {
warn_no_space_for_csum(inode);
return;
}
t->det_checksum = ext4_dirent_csum(inode, dirent,
(void *)t - (void *)dirent);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 75 | 97.40% | 1 | 33.33% |
dmitriy monakhov | dmitriy monakhov | 1 | 1.30% | 1 | 33.33% |
theodore tso | theodore tso | 1 | 1.30% | 1 | 33.33% |
| Total | 77 | 100.00% | 3 | 100.00% |
int ext4_handle_dirty_dirent_node(handle_t *handle,
struct inode *inode,
struct buffer_head *bh)
{
ext4_dirent_csum_set(inode, (struct ext4_dir_entry *)bh->b_data);
return ext4_handle_dirty_metadata(handle, inode, bh);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 43 | 100.00% | 1 | 100.00% |
| Total | 43 | 100.00% | 1 | 100.00% |
static struct dx_countlimit *get_dx_countlimit(struct inode *inode,
struct ext4_dir_entry *dirent,
int *offset)
{
struct ext4_dir_entry *dp;
struct dx_root_info *root;
int count_offset;
if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb))
count_offset = 8;
else if (le16_to_cpu(dirent->rec_len) == 12) {
dp = (struct ext4_dir_entry *)(((void *)dirent) + 12);
if (le16_to_cpu(dp->rec_len) !=
EXT4_BLOCK_SIZE(inode->i_sb) - 12)
return NULL;
root = (struct dx_root_info *)(((void *)dp + 12));
if (root->reserved_zero ||
root->info_length != sizeof(struct dx_root_info))
return NULL;
count_offset = 32;
} else
return NULL;
if (offset)
*offset = count_offset;
return (struct dx_countlimit *)(((void *)dirent) + count_offset);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 182 | 100.00% | 1 | 100.00% |
| Total | 182 | 100.00% | 1 | 100.00% |
static __le32 ext4_dx_csum(struct inode *inode, struct ext4_dir_entry *dirent,
int count_offset, int count, struct dx_tail *t)
{
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct ext4_inode_info *ei = EXT4_I(inode);
__u32 csum;
int size;
__u32 dummy_csum = 0;
int offset = offsetof(struct dx_tail, dt_checksum);
size = count_offset + (count * sizeof(struct dx_entry));
csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size);
csum = ext4_chksum(sbi, csum, (__u8 *)t, offset);
csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
return cpu_to_le32(csum);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 112 | 75.68% | 1 | 33.33% |
daeho jeong | daeho jeong | 35 | 23.65% | 1 | 33.33% |
theodore tso | theodore tso | 1 | 0.68% | 1 | 33.33% |
| Total | 148 | 100.00% | 3 | 100.00% |
static int ext4_dx_csum_verify(struct inode *inode,
struct ext4_dir_entry *dirent)
{
struct dx_countlimit *c;
struct dx_tail *t;
int count_offset, limit, count;
if (!ext4_has_metadata_csum(inode->i_sb))
return 1;
c = get_dx_countlimit(inode, dirent, &count_offset);
if (!c) {
EXT4_ERROR_INODE(inode, "dir seems corrupt? Run e2fsck -D.");
return 0;
}
limit = le16_to_cpu(c->limit);
count = le16_to_cpu(c->count);
if (count_offset + (limit * sizeof(struct dx_entry)) >
EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) {
warn_no_space_for_csum(inode);
return 0;
}
t = (struct dx_tail *)(((struct dx_entry *)c) + limit);
if (t->dt_checksum != ext4_dx_csum(inode, dirent, count_offset,
count, t))
return 0;
return 1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 171 | 97.71% | 1 | 25.00% |
daeho jeong | daeho jeong | 2 | 1.14% | 1 | 25.00% |
dmitriy monakhov | dmitriy monakhov | 1 | 0.57% | 1 | 25.00% |
theodore tso | theodore tso | 1 | 0.57% | 1 | 25.00% |
| Total | 175 | 100.00% | 4 | 100.00% |
static void ext4_dx_csum_set(struct inode *inode, struct ext4_dir_entry *dirent)
{
struct dx_countlimit *c;
struct dx_tail *t;
int count_offset, limit, count;
if (!ext4_has_metadata_csum(inode->i_sb))
return;
c = get_dx_countlimit(inode, dirent, &count_offset);
if (!c) {
EXT4_ERROR_INODE(inode, "dir seems corrupt? Run e2fsck -D.");
return;
}
limit = le16_to_cpu(c->limit);
count = le16_to_cpu(c->count);
if (count_offset + (limit * sizeof(struct dx_entry)) >
EXT4_BLOCK_SIZE(inode->i_sb) - sizeof(struct dx_tail)) {
warn_no_space_for_csum(inode);
return;
}
t = (struct dx_tail *)(((struct dx_entry *)c) + limit);
t->dt_checksum = ext4_dx_csum(inode, dirent, count_offset, count, t);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 159 | 98.76% | 1 | 33.33% |
theodore tso | theodore tso | 1 | 0.62% | 1 | 33.33% |
dmitriy monakhov | dmitriy monakhov | 1 | 0.62% | 1 | 33.33% |
| Total | 161 | 100.00% | 3 | 100.00% |
static inline int ext4_handle_dirty_dx_node(handle_t *handle,
struct inode *inode,
struct buffer_head *bh)
{
ext4_dx_csum_set(inode, (struct ext4_dir_entry *)bh->b_data);
return ext4_handle_dirty_metadata(handle, inode, bh);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
darrick j. wong | darrick j. wong | 45 | 100.00% | 1 | 100.00% |
| Total | 45 | 100.00% | 1 | 100.00% |
/*
* p is at least 6 bytes before the end of page
*/
static inline struct ext4_dir_entry_2 *
ext4_next_entry(struct ext4_dir_entry_2 *p, unsigned long blocksize)
{
return (struct ext4_dir_entry_2 *)((char *)p +
ext4_rec_len_from_disk(p->rec_len, blocksize));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
li zefan | li zefan | 35 | 85.37% | 1 | 50.00% |
wei yongjun | wei yongjun | 6 | 14.63% | 1 | 50.00% |
| Total | 41 | 100.00% | 2 | 100.00% |
/*
* Future: use high four bits of block for coalesce-on-delete flags
* Mask them off for now.
*/
static inline ext4_lblk_t dx_get_block(struct dx_entry *entry)
{
return le32_to_cpu(entry->block) & 0x00ffffff;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 21 | 95.45% | 1 | 50.00% |
aneesh kumar | aneesh kumar | 1 | 4.55% | 1 | 50.00% |
| Total | 22 | 100.00% | 2 | 100.00% |
static inline void dx_set_block(struct dx_entry *entry, ext4_lblk_t value)
{
entry->block = cpu_to_le32(value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 23 | 95.83% | 1 | 50.00% |
aneesh kumar | aneesh kumar | 1 | 4.17% | 1 | 50.00% |
| Total | 24 | 100.00% | 2 | 100.00% |
static inline unsigned dx_get_hash(struct dx_entry *entry)
{
return le32_to_cpu(entry->hash);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 20 | 100.00% | 1 | 100.00% |
| Total | 20 | 100.00% | 1 | 100.00% |
static inline void dx_set_hash(struct dx_entry *entry, unsigned value)
{
entry->hash = cpu_to_le32(value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 24 | 100.00% | 1 | 100.00% |
| Total | 24 | 100.00% | 1 | 100.00% |
static inline unsigned dx_get_count(struct dx_entry *entries)
{
return le16_to_cpu(((struct dx_countlimit *) entries)->count);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 27 | 100.00% | 1 | 100.00% |
| Total | 27 | 100.00% | 1 | 100.00% |
static inline unsigned dx_get_limit(struct dx_entry *entries)
{
return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 27 | 100.00% | 1 | 100.00% |
| Total | 27 | 100.00% | 1 | 100.00% |
static inline void dx_set_count(struct dx_entry *entries, unsigned value)
{
((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 31 | 100.00% | 1 | 100.00% |
| Total | 31 | 100.00% | 1 | 100.00% |
static inline void dx_set_limit(struct dx_entry *entries, unsigned value)
{
((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 31 | 100.00% | 1 | 100.00% |
| Total | 31 | 100.00% | 1 | 100.00% |
static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)
{
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
EXT4_DIR_REC_LEN(2) - infosize;
if (ext4_has_metadata_csum(dir->i_sb))
entry_space -= sizeof(struct dx_tail);
return entry_space / sizeof(struct dx_entry);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 43 | 69.35% | 1 | 25.00% |
darrick j. wong | darrick j. wong | 16 | 25.81% | 1 | 25.00% |
mingming cao | mingming cao | 2 | 3.23% | 1 | 25.00% |
dmitriy monakhov | dmitriy monakhov | 1 | 1.61% | 1 | 25.00% |
| Total | 62 | 100.00% | 4 | 100.00% |
static inline unsigned dx_node_limit(struct inode *dir)
{
unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
if (ext4_has_metadata_csum(dir->i_sb))
entry_space -= sizeof(struct dx_tail);
return entry_space / sizeof(struct dx_entry);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
dave kleikamp | dave kleikamp | 34 | 65.38% | 1 | 25.00% |
darrick j. wong | darrick j. wong | 16 | 30.77% | 1 | 25.00% |
mingming cao | mingming cao | 1 | 1.92% | 1 | 25.00% |
dmitriy monakhov | dmitriy monakhov | 1 | 1.92% | 1 | 25.00% |
| Total | 52 | 100.00% | 4 | 100.00% |
/*
* Debug
*/
#ifdef DX_DEBUG
static void dx_show_index(char * label, struct dx_entry *entries)
{
int i, n = dx_get_count (entries);
printk(KERN_DEBUG "%s index", label);
for (i = 0; i < n; i++) {
printk(KERN_CONT " %x->%lu",
i ? dx_get_hash(entries + i) : 0,
(unsigned long)dx_get_block(entries + i));