ReactOS 0.4.16-dev-297-gc569aee
ext4_extents.c File Reference
#include "ext2fs.h"
#include "linux\ext4.h"
Include dependency graph for ext4_extents.c:

Go to the source code of this file.

Macros

#define EXT4_EXT_MAY_ZEROOUT
 
#define EXT4_EXT_MARK_UNWRIT1   0x2 /* mark first half unwritten */
 
#define EXT4_EXT_MARK_UNWRIT2   0x4 /* mark second half unwritten */
 
#define EXT4_EXT_DATA_VALID1   0x8 /* first half contains valid data */
 
#define EXT4_EXT_DATA_VALID2   0x10 /* second half contains valid data */
 
#define CONFIG_EXTENT_TEST
 
#define ext4_mark_inode_dirty(icb, handle, n)   ext3_mark_inode_dirty(icb, n)
 
#define EXT4_ERROR_INODE
 
#define ext4_std_error(s, err)
 
#define assert   ASSERT
 
#define EXT_MAX_BLOCKS   0xffffffff
 
#define read_extent_tree_block(inode, pblk, depth, flags)
 
#define ext4_ext_check(inode, eh, depth, pblk)    __ext4_ext_check("", __LINE__, (inode), (eh), (depth), (pblk))
 
#define ext4_ext_show_path(inode, path)
 
#define ext4_ext_show_leaf(inode, path)
 
#define ext4_ext_show_move(inode, path, newblock, level)
 

Functions

static ext4_fsblk_t ext4_inode_to_goal_block (struct inode *inode)
 
static ext4_fsblk_t ext4_new_meta_blocks (void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned int flags, unsigned long *count, int *errp)
 
static void ext4_free_blocks (void *icb, handle_t *handle, struct inode *inode, void *fake, ext4_fsblk_t block, int count, int flags)
 
static void ext_debug (char *str,...)
 
static int ext4_ext_space_block (struct inode *inode, int check)
 
static int ext4_ext_space_block_idx (struct inode *inode, int check)
 
static int ext4_ext_space_root (struct inode *inode, int check)
 
static int ext4_ext_space_root_idx (struct inode *inode, int check)
 
static int ext4_ext_max_entries (struct inode *inode, int depth)
 
static int __ext4_ext_check (const char *function, unsigned int line, struct inode *inode, struct ext4_extent_header *eh, int depth, ext4_fsblk_t pblk)
 
static struct buffer_head__read_extent_tree_block (const char *function, unsigned int line, struct inode *inode, ext4_fsblk_t pblk, int depth, int flags)
 
int ext4_ext_check_inode (struct inode *inode)
 
static uint32_t ext4_ext_block_csum (struct inode *inode, struct ext4_extent_header *eh)
 
static void ext4_extent_block_csum_set (struct inode *inode, struct ext4_extent_header *eh)
 
static int ext4_split_extent_at (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, ext4_lblk_t split, int split_flag, int flags)
 
static int ext4_force_split_extent_at (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, ext4_lblk_t lblk, int nofail)
 
static int ext4_ext_get_access (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
 
static ext4_fsblk_t ext4_ext_find_goal (struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
 
static ext4_fsblk_t ext4_ext_new_meta_block (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex, int *err, unsigned int flags)
 
int __ext4_ext_dirty (const char *where, unsigned int line, void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
 
void ext4_ext_drop_refs (struct ext4_ext_path *path)
 
static void ext4_ext_binsearch_idx (struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
 
static void ext4_ext_binsearch (struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
 
struct ext4_ext_pathext4_find_extent (struct inode *inode, ext4_lblk_t block, struct ext4_ext_path **orig_path, int flags)
 
static int ext4_ext_insert_index (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *curp, int logical, ext4_fsblk_t ptr)
 
static int ext4_ext_split (void *icb, handle_t *handle, struct inode *inode, unsigned int flags, struct ext4_ext_path *path, struct ext4_extent *newext, int at)
 
static int ext4_ext_grow_indepth (void *icb, handle_t *handle, struct inode *inode, unsigned int flags)
 
static int ext4_ext_create_new_leaf (void *icb, handle_t *handle, struct inode *inode, unsigned int mb_flags, unsigned int gb_flags, struct ext4_ext_path **ppath, struct ext4_extent *newext)
 
static int ext4_ext_search_left (struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t *logical, ext4_fsblk_t *phys)
 
static int ext4_ext_search_right (struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t *logical, ext4_fsblk_t *phys, struct ext4_extent **ret_ex)
 
ext4_lblk_t ext4_ext_next_allocated_block (struct ext4_ext_path *path)
 
static ext4_lblk_t ext4_ext_next_leaf_block (struct ext4_ext_path *path)
 
static int ext4_ext_correct_indexes (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
 
int ext4_can_extents_be_merged (struct inode *inode, struct ext4_extent *ex1, struct ext4_extent *ex2)
 
static int ext4_ext_try_to_merge_right (struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex)
 
static void ext4_ext_try_to_merge_up (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
 
static void ext4_ext_try_to_merge (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex)
 
int ext4_ext_insert_extent (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, struct ext4_extent *newext, int gb_flags)
 
static int get_default_free_blocks_flags (struct inode *inode)
 
static int ext4_ext_zeroout (struct inode *inode, struct ext4_extent *ex)
 
static int ext4_remove_blocks (void *icb, handle_t *handle, struct inode *inode, struct ext4_extent *ex, unsigned long from, unsigned long to)
 
int ext4_ext_rm_idx (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
 
static int ext4_ext_rm_leaf (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, unsigned long start)
 
static int ext4_ext_more_to_rm (struct ext4_ext_path *path)
 
int ext4_ext_remove_space (void *icb, struct inode *inode, unsigned long start)
 
int ext4_ext_tree_init (void *icb, handle_t *handle, struct inode *inode)
 
void ext4_ext_init (struct super_block *sb)
 
static int ext4_ext_convert_to_initialized (void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, ext4_lblk_t split, unsigned long blocks, int flags)
 
int ext4_ext_get_blocks (void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t iblock, unsigned long max_blocks, struct buffer_head *bh_result, int create, int flags)
 
int ext4_ext_truncate (void *icb, struct inode *inode, unsigned long start)
 

Macro Definition Documentation

◆ assert

#define assert   ASSERT

Definition at line 103 of file ext4_extents.c.

◆ CONFIG_EXTENT_TEST

#define CONFIG_EXTENT_TEST

Definition at line 41 of file ext4_extents.c.

◆ EXT4_ERROR_INODE

#define EXT4_ERROR_INODE

Definition at line 99 of file ext4_extents.c.

◆ ext4_ext_check

#define ext4_ext_check (   inode,
  eh,
  depth,
  pblk 
)     __ext4_ext_check("", __LINE__, (inode), (eh), (depth), (pblk))

Definition at line 231 of file ext4_extents.c.

◆ EXT4_EXT_DATA_VALID1

#define EXT4_EXT_DATA_VALID1   0x8 /* first half contains valid data */

Definition at line 38 of file ext4_extents.c.

◆ EXT4_EXT_DATA_VALID2

#define EXT4_EXT_DATA_VALID2   0x10 /* second half contains valid data */

Definition at line 39 of file ext4_extents.c.

◆ EXT4_EXT_MARK_UNWRIT1

#define EXT4_EXT_MARK_UNWRIT1   0x2 /* mark first half unwritten */

Definition at line 35 of file ext4_extents.c.

◆ EXT4_EXT_MARK_UNWRIT2

#define EXT4_EXT_MARK_UNWRIT2   0x4 /* mark second half unwritten */

Definition at line 36 of file ext4_extents.c.

◆ EXT4_EXT_MAY_ZEROOUT

#define EXT4_EXT_MAY_ZEROOUT
Value:
0x1 /* safe to zeroout if split fails \
due to ENOSPC */

Definition at line 34 of file ext4_extents.c.

◆ ext4_ext_show_leaf

#define ext4_ext_show_leaf (   inode,
  path 
)

Definition at line 639 of file ext4_extents.c.

◆ ext4_ext_show_move

#define ext4_ext_show_move (   inode,
  path,
  newblock,
  level 
)

Definition at line 640 of file ext4_extents.c.

◆ ext4_ext_show_path

#define ext4_ext_show_path (   inode,
  path 
)

Definition at line 638 of file ext4_extents.c.

◆ ext4_mark_inode_dirty

#define ext4_mark_inode_dirty (   icb,
  handle,
  n 
)    ext3_mark_inode_dirty(icb, n)

Definition at line 44 of file ext4_extents.c.

◆ ext4_std_error

#define ext4_std_error (   s,
  err 
)

Definition at line 102 of file ext4_extents.c.

◆ EXT_MAX_BLOCKS

#define EXT_MAX_BLOCKS   0xffffffff

Definition at line 111 of file ext4_extents.c.

◆ read_extent_tree_block

#define read_extent_tree_block (   inode,
  pblk,
  depth,
  flags 
)
Value:
__read_extent_tree_block("", __LINE__, (inode), (pblk), \
(depth), (flags))
static struct buffer_head * __read_extent_tree_block(const char *function, unsigned int line, struct inode *inode, ext4_fsblk_t pblk, int depth, int flags)
Definition: ext4_extents.c:198
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLbitfield flags
Definition: glext.h:7161
Definition: fs.h:78

Definition at line 227 of file ext4_extents.c.

Function Documentation

◆ __ext4_ext_check()

static int __ext4_ext_check ( const char function,
unsigned int  line,
struct inode inode,
struct ext4_extent_header eh,
int  depth,
ext4_fsblk_t  pblk 
)
static

Definition at line 397 of file ext4_extents.c.

402{
403 struct ext4_extent_tail *tail;
404 const char *error_msg;
405#ifndef __REACTOS__
406 int max = 0;
407#endif
408
409 if (eh->eh_magic != EXT4_EXT_MAGIC) {
410 error_msg = "invalid magic";
411 goto corrupted;
412 }
413 if (le16_to_cpu(eh->eh_depth) != depth) {
414 error_msg = "unexpected eh_depth";
415 goto corrupted;
416 }
417 if (eh->eh_max == 0) {
418 error_msg = "invalid eh_max";
419 goto corrupted;
420 }
421 if (eh->eh_entries > eh->eh_max) {
422 error_msg = "invalid eh_entries";
423 goto corrupted;
424 }
425
427 if (tail->et_checksum != ext4_ext_block_csum(inode, eh)) {
428 ext_debug("Warning: extent checksum damaged? tail->et_checksum = "
429 "%lu, ext4_ext_block_csum = %lu\n",
430 tail->et_checksum, ext4_ext_block_csum(inode, eh));
431 }
432
433 return 0;
434
435corrupted:
436 ext_debug("corrupted! %s\n", error_msg);
437 return -EIO;
#define EIO
Definition: acclib.h:81
struct outqueuenode * tail
Definition: adnsresfilter.c:66
#define EXT4_EXT_MAGIC
Definition: ext4_ext.h:50
static struct ext4_extent_tail * find_ext4_extent_tail(struct ext4_extent_header *eh)
Definition: ext4_ext.h:58
static uint32_t ext4_ext_block_csum(struct inode *inode, struct ext4_extent_header *eh)
Definition: ext4_extents.c:239
static void ext_debug(char *str,...)
Definition: ext4_extents.c:85
#define le16_to_cpu
Definition: module.h:151
uint16_t eh_depth
Definition: ext4_ext.h:45
uint16_t eh_max
Definition: ext4_ext.h:44
uint16_t eh_magic
Definition: ext4_ext.h:42
uint16_t eh_entries
Definition: ext4_ext.h:43
#define max(a, b)
Definition: svc.c:63
static const WCHAR * error_msg[8]
Definition: odbccp32.c:62

Referenced by __read_extent_tree_block().

◆ __ext4_ext_dirty()

int __ext4_ext_dirty ( const char where,
unsigned int  line,
void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path 
)

Definition at line 361 of file ext4_extents.c.

366{
367 int err;
368
369 if (path->p_bh) {
371 /* path points to block */
372 err = __ext4_handle_dirty_metadata(where, line, icb, handle, inode, path->p_bh);
373 } else {
374 /* path points to leaf/index in inode body */
376 }
377 return err;
static struct ext4_extent_header * ext_block_hdr(struct buffer_head *bh)
Definition: ext4_ext.h:129
#define ext4_mark_inode_dirty(icb, handle, n)
Definition: ext4_extents.c:44
static void ext4_extent_block_csum_set(struct inode *inode, struct ext4_extent_header *eh)
Definition: ext4_extents.c:246
int __ext4_handle_dirty_metadata(const char *where, unsigned int line, void *icb, handle_t *handle, struct inode *inode, struct buffer_head *bh)
Definition: ext4_jbd2.c:61
#define err(...)
Definition: parser.c:49

◆ __read_extent_tree_block()

static struct buffer_head * __read_extent_tree_block ( const char function,
unsigned int  line,
struct inode inode,
ext4_fsblk_t  pblk,
int  depth,
int  flags 
)
static

Definition at line 198 of file ext4_extents.c.

202{
203 struct buffer_head *bh;
204 int err;
205
206 bh = extents_bread(inode->i_sb, pblk);
207 if (!bh)
208 return ERR_PTR(-ENOMEM);
209
210 if (!buffer_uptodate(bh)) {
211 err = -EIO;
212 goto errout;
213 }
214 if (buffer_verified(bh))
215 return bh;
216 err = __ext4_ext_check(function, line, inode,
217 ext_block_hdr(bh), depth, pblk);
218 if (err)
219 goto errout;
220 set_buffer_verified(bh);
221 return bh;
222errout:
223 extents_brelse(bh);
224 return ERR_PTR(err);
225
#define ENOMEM
Definition: acclib.h:84
static int __ext4_ext_check(const char *function, unsigned int line, struct inode *inode, struct ext4_extent_header *eh, int depth, ext4_fsblk_t pblk)
Definition: ext4_extents.c:397
struct buffer_head * extents_bread(struct super_block *sb, sector_t block)
Definition: ext4_bh.c:15
static void * ERR_PTR(long error)
Definition: module.h:239
void extents_brelse(struct buffer_head *bh)
Definition: ext4_bh.c:51
struct super_block * i_sb
Definition: fs.h:96

◆ ext4_can_extents_be_merged()

int ext4_can_extents_be_merged ( struct inode inode,
struct ext4_extent ex1,
struct ext4_extent ex2 
)

Definition at line 1490 of file ext4_extents.c.

1493{
1494 unsigned short ext1_ee_len, ext2_ee_len;
1495
1496 /*
1497 * Make sure that both extents are initialized. We don't merge
1498 * unwritten extents so that we can be sure that end_io code has
1499 * the extent that was written properly split out and conversion to
1500 * initialized is trivial.
1501 */
1503 return 0;
1504
1505 ext1_ee_len = ext4_ext_get_actual_len(ex1);
1506 ext2_ee_len = ext4_ext_get_actual_len(ex2);
1507
1508 if (le32_to_cpu(ex1->ee_block) + ext1_ee_len !=
1509 le32_to_cpu(ex2->ee_block))
1510 return 0;
1511
1512 /*
1513 * To allow future support for preallocated extents to be added
1514 * as an RO_COMPAT feature, refuse to merge to extents if
1515 * this can result in the top bit of ee_len being set.
1516 */
1517 if (ext1_ee_len + ext2_ee_len > EXT_INIT_MAX_LEN)
1518 return 0;
1519 if (ext4_ext_is_unwritten(ex1) &&
1520 (ext1_ee_len + ext2_ee_len > EXT_UNWRITTEN_MAX_LEN))
1521 return 0;
1522#ifdef AGGRESSIVE_TEST
1523 if (ext1_ee_len >= 4)
1524 return 0;
1525#endif
1526
1527 if (ext4_ext_pblock(ex1) + ext1_ee_len == ext4_ext_pblock(ex2))
1528 return 1;
1529 return 0;
static int ext4_ext_is_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:169
#define EXT_UNWRITTEN_MAX_LEN
Definition: ext4_ext.h:102
#define EXT_INIT_MAX_LEN
Definition: ext4_ext.h:101
static ext4_fsblk_t ext4_ext_pblock(struct ext4_extent *ex)
Definition: ext4_ext.h:179
static uint16_t ext4_ext_get_actual_len(struct ext4_extent *ext)
Definition: ext4_ext.h:151
#define le32_to_cpu
Definition: module.h:149
uint32_t ee_block
Definition: ext4_ext.h:20

Referenced by ext4_ext_insert_extent(), and ext4_ext_try_to_merge_right().

◆ ext4_ext_binsearch()

static void ext4_ext_binsearch ( struct inode inode,
struct ext4_ext_path path,
ext4_lblk_t  block 
)
static

Definition at line 504 of file ext4_extents.c.

507{
508 struct ext4_extent_header *eh = path->p_hdr;
509 struct ext4_extent *r, *l, *m;
510
511 if (eh->eh_entries == 0) {
512 /*
513 * this leaf is empty:
514 * we get such a leaf in split/add case
515 */
516 return;
517 }
518
519 ext_debug("binsearch for %u: ", block);
520
521 l = EXT_FIRST_EXTENT(eh) + 1;
522 r = EXT_LAST_EXTENT(eh);
523
524 while (l <= r) {
525 m = l + (r - l) / 2;
526 if (block < m->ee_block)
527 r = m - 1;
528 else
529 l = m + 1;
530 ext_debug("%p(%u):%p(%u):%p(%u) ", l, l->ee_block,
531 m, (m->ee_block),
532 r, (r->ee_block));
533 }
534
535 path->p_ext = l - 1;
536 ext_debug(" -> %d:%llu:[%d]%d ",
537 (path->p_ext->ee_block),
538 ext4_ext_pblock(path->p_ext),
541
542#ifdef CHECK_BINSEARCH
543 {
544 struct ext4_extent *chex, *ex;
545 int k;
546
547 chex = ex = EXT_FIRST_EXTENT(eh);
548 for (k = 0; k < le16_to_cpu(eh->eh_entries); k++, ex++) {
549 BUG_ON(k && (ex->ee_block)
550 <= (ex[-1].ee_block));
551 if (block < (ex->ee_block))
552 break;
553 chex = ex;
554 }
555 BUG_ON(chex != path->p_ext);
556 }
557#endif
558
r l[0]
Definition: byte_order.h:168
#define EXT_FIRST_EXTENT(__hdr__)
Definition: ext4_ext.h:107
#define EXT_LAST_EXTENT(__hdr__)
Definition: ext4_ext.h:115
uint32_t ee_block
Definition: ext4_ext.h:0
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const GLfloat * m
Definition: glext.h:10848
#define BUG_ON(c)
Definition: module.h:255
int k
Definition: mpi.c:3369
Definition: comerr.c:44
static unsigned int block
Definition: xmlmemory.c:101

Referenced by ext4_find_extent().

◆ ext4_ext_binsearch_idx()

static void ext4_ext_binsearch_idx ( struct inode inode,
struct ext4_ext_path path,
ext4_lblk_t  block 
)
static

Definition at line 445 of file ext4_extents.c.

448{
449 struct ext4_extent_header *eh = path->p_hdr;
450 struct ext4_extent_idx *r, *l, *m;
451
452 ext_debug("binsearch for %u(idx): ", block);
453
454 l = EXT_FIRST_INDEX(eh) + 1;
455 r = EXT_LAST_INDEX(eh);
456 while (l <= r) {
457 m = l + (r - l) / 2;
458 if (block < (m->ei_block))
459 r = m - 1;
460 else
461 l = m + 1;
462 ext_debug("%p(%u):%p(%u):%p(%u) ", l, (l->ei_block),
463 m, (m->ei_block),
464 r, (r->ei_block));
465 }
466
467 path->p_idx = l - 1;
468 ext_debug(" -> %u->%lld ", (path->p_idx->ei_block),
469 ext4_idx_pblock(path->p_idx));
470
471#ifdef CHECK_BINSEARCH
472 {
473 struct ext4_extent_idx *chix, *ix;
474 int k;
475
476 chix = ix = EXT_FIRST_INDEX(eh);
477 for (k = 0; k < (eh->eh_entries); k++, ix++) {
478 if (k != 0 &&
479 (ix->ei_block) <= (ix[-1].ei_block)) {
480 printk(KERN_DEBUG "k=%d, ix=0x%p, "
481 "first=0x%p\n", k,
482 ix, EXT_FIRST_INDEX(eh));
483 printk(KERN_DEBUG "%u <= %u\n",
484 (ix->ei_block),
485 (ix[-1].ei_block));
486 }
487 BUG_ON(k && (ix->ei_block)
488 <= (ix[-1].ei_block));
489 if (block < (ix->ei_block))
490 break;
491 chix = ix;
492 }
493 BUG_ON(chix != path->p_idx);
494 }
495#endif
496
#define EXT_LAST_INDEX(__hdr__)
Definition: ext4_ext.h:117
static ext4_fsblk_t ext4_idx_pblock(struct ext4_extent_idx *ix)
Definition: ext4_ext.h:192
#define EXT_FIRST_INDEX(__hdr__)
Definition: ext4_ext.h:110
#define KERN_DEBUG
Definition: module.h:229
#define printk
Definition: module.h:231
uint32_t ei_block
Definition: ext4_ext.h:31

Referenced by ext4_find_extent().

◆ ext4_ext_block_csum()

static uint32_t ext4_ext_block_csum ( struct inode inode,
struct ext4_extent_header eh 
)
static

Definition at line 239 of file ext4_extents.c.

242{
243 /*return ext4_crc32c(inode->i_csum, eh, EXT4_EXTENT_TAIL_OFFSET(eh));*/
244 return 0;

Referenced by __ext4_ext_check(), and ext4_extent_block_csum_set().

◆ ext4_ext_check_inode()

int ext4_ext_check_inode ( struct inode inode)

Definition at line 234 of file ext4_extents.c.

236{
static struct ext4_extent_header * ext_inode_hdr(struct inode *inode)
Definition: ext4_ext.h:124
static unsigned short ext_depth(struct inode *inode)
Definition: ext4_ext.h:134
#define ext4_ext_check(inode, eh, depth, pblk)
Definition: ext4_extents.c:231

Referenced by ext4_ext_remove_space().

◆ ext4_ext_convert_to_initialized()

static int ext4_ext_convert_to_initialized ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path **  ppath,
ext4_lblk_t  split,
unsigned long  blocks,
int  flags 
)
static

Definition at line 2342 of file ext4_extents.c.

2351{
2352 int depth = ext_depth(inode), err;
2353 struct ext4_extent *ex = (*ppath)[depth].p_ext;
2354
2355 assert (le32_to_cpu(ex->ee_block) <= split);
2356
2357 if (split + blocks == le32_to_cpu(ex->ee_block) +
2359
2360 /* split and initialize right part */
2361 err = ext4_split_extent_at(icb, handle, inode, ppath, split,
2363
2364 } else if (le32_to_cpu(ex->ee_block) == split) {
2365
2366 /* split and initialize left part */
2367 err = ext4_split_extent_at(icb, handle, inode, ppath, split + blocks,
2369
2370 } else {
2371
2372 /* split 1 extent to 3 and initialize the 2nd */
2373 err = ext4_split_extent_at(icb, handle, inode, ppath, split + blocks,
2376 if (0 == err) {
2377 err = ext4_split_extent_at(icb, handle, inode, ppath, split,
2379 }
2380 }
2381
2382 return err;
static LPSTR * split(LPSTR s, LPINT args)
Definition: cmdcons.c:163
#define EXT4_EXT_MARK_UNWRIT1
Definition: ext4_extents.c:35
static int ext4_split_extent_at(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, ext4_lblk_t split, int split_flag, int flags)
#define assert
Definition: ext4_extents.c:103
#define EXT4_EXT_MARK_UNWRIT2
Definition: ext4_extents.c:36
static int blocks
Definition: mkdosfs.c:527

Referenced by ext4_ext_get_blocks().

◆ ext4_ext_correct_indexes()

static int ext4_ext_correct_indexes ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path 
)
static

Definition at line 1432 of file ext4_extents.c.

1435{
1436 struct ext4_extent_header *eh;
1437 int depth = ext_depth(inode);
1438 struct ext4_extent *ex;
1439 __le32 border;
1440 int k, err = 0;
1441
1442 eh = path[depth].p_hdr;
1443 ex = path[depth].p_ext;
1444
1445 if (unlikely(ex == NULL || eh == NULL)) {
1447 "ex %p == NULL or eh %p == NULL", ex, eh);
1448 return -EIO;
1449 }
1450
1451 if (depth == 0) {
1452 /* there is no tree at all */
1453 return 0;
1454 }
1455
1456 if (ex != EXT_FIRST_EXTENT(eh)) {
1457 /* we correct tree if first leaf got modified only */
1458 return 0;
1459 }
1460
1461 /*
1462 * TODO: we need correction if border is smaller than current one
1463 */
1464 k = depth - 1;
1465 border = path[depth].p_ext->ee_block;
1467 if (err)
1468 return err;
1469 path[k].p_idx->ei_block = border;
1470 err = ext4_ext_dirty(icb, handle, inode, path + k);
1471 if (err)
1472 return err;
1473
1474 while (k--) {
1475 /* change all left-side indexes */
1476 if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr))
1477 break;
1479 if (err)
1480 break;
1481 path[k].p_idx->ei_block = border;
1482 err = ext4_ext_dirty(icb, handle, inode, path + k);
1483 if (err)
1484 break;
1485 }
1486
1487 return err;
#define NULL
Definition: types.h:112
#define __le32
Definition: types.h:44
#define ext4_ext_dirty(icb, handle, inode, path)
Definition: ext4_ext.h:225
static int ext4_ext_get_access(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
Definition: ext4_extents.c:284
#define EXT4_ERROR_INODE
Definition: ext4_extents.c:99
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: gl.h:1546
#define unlikely
Definition: module.h:264

Referenced by ext4_ext_insert_extent(), and ext4_ext_rm_leaf().

◆ ext4_ext_create_new_leaf()

static int ext4_ext_create_new_leaf ( void icb,
handle_t handle,
struct inode inode,
unsigned int  mb_flags,
unsigned int  gb_flags,
struct ext4_ext_path **  ppath,
struct ext4_extent newext 
)
static

Definition at line 1117 of file ext4_extents.c.

1123{
1124 struct ext4_ext_path *path = *ppath;
1125 struct ext4_ext_path *curp;
1126 int depth, i, err = 0;
1127
1128repeat:
1129 i = depth = ext_depth(inode);
1130
1131 /* walk up to the tree and look for free index entry */
1132 curp = path + depth;
1133 while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) {
1134 i--;
1135 curp--;
1136 }
1137
1138 /* we use already allocated block for index block,
1139 * so subsequent data blocks should be contiguous */
1140 if (EXT_HAS_FREE_INDEX(curp)) {
1141 /* if we found index with free entry, then use that
1142 * entry: create all needed subtree and add new leaf */
1143 err = ext4_ext_split(icb, handle, inode, mb_flags, path, newext, i);
1144 if (err)
1145 goto out;
1146
1147 /* refill path */
1150 ppath, gb_flags);
1151 if (IS_ERR(path))
1152 err = PTR_ERR(path);
1153 } else {
1154 /* tree is full, time to grow in depth */
1155 err = ext4_ext_grow_indepth(icb, handle, inode, mb_flags);
1156 if (err)
1157 goto out;
1158
1159 /* refill path */
1162 ppath, gb_flags);
1163 if (IS_ERR(path)) {
1164 err = PTR_ERR(path);
1165 goto out;
1166 }
1167
1168 /*
1169 * only first (depth 0 -> 1) produces free space;
1170 * in all other cases we have to split the grown tree
1171 */
1173 if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) {
1174 /* now we need to split */
1175 goto repeat;
1176 }
1177 }
1178
1179out:
1180 return err;
__u32 ext4_lblk_t
Definition: ext3_fs_i.h:31
#define EXT_HAS_FREE_INDEX(__path__)
Definition: ext4_ext.h:113
static int ext4_ext_grow_indepth(void *icb, handle_t *handle, struct inode *inode, unsigned int flags)
static int ext4_ext_split(void *icb, handle_t *handle, struct inode *inode, unsigned int flags, struct ext4_ext_path *path, struct ext4_extent *newext, int at)
Definition: ext4_extents.c:810
struct ext4_ext_path * ext4_find_extent(struct inode *inode, ext4_lblk_t block, struct ext4_ext_path **orig_path, int flags)
Definition: ext4_extents.c:644
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static long IS_ERR(const void *ptr)
Definition: module.h:249
static long PTR_ERR(const void *ptr)
Definition: module.h:244
static FILE * out
Definition: regtests2xml.c:44
struct ext4_extent_header * p_hdr
Definition: ext4_ext.h:76
static int repeat
Definition: xmllint.c:137

Referenced by ext4_ext_insert_extent().

◆ ext4_ext_drop_refs()

void ext4_ext_drop_refs ( struct ext4_ext_path path)

Definition at line 379 of file ext4_extents.c.

381{
382 int depth, i;
383
384 if (!path)
385 return;
386 depth = path->p_depth;
387 for (i = 0; i <= depth; i++, path++)
388 if (path->p_bh) {
389 extents_brelse(path->p_bh);
390 path->p_bh = NULL;
391 }

Referenced by ext4_ext_get_blocks(), ext4_ext_insert_extent(), ext4_ext_remove_space(), and ext4_find_extent().

◆ ext4_ext_find_goal()

static ext4_fsblk_t ext4_ext_find_goal ( struct inode inode,
struct ext4_ext_path path,
ext4_lblk_t  block 
)
static

Definition at line 299 of file ext4_extents.c.

303{
304 if (path) {
305 int depth = path->p_depth;
306 struct ext4_extent *ex;
307
308 /*
309 * Try to predict block placement assuming that we are
310 * filling in a file which will eventually be
311 * non-sparse --- i.e., in the case of libbfd writing
312 * an ELF object sections out-of-order but in a way
313 * the eventually results in a contiguous object or
314 * executable file, or some database extending a table
315 * space file. However, this is actually somewhat
316 * non-ideal if we are writing a sparse file such as
317 * qemu or KVM writing a raw image file that is going
318 * to stay fairly sparse, since it will end up
319 * fragmenting the file system's free space. Maybe we
320 * should have some hueristics or some way to allow
321 * userspace to pass a hint to file system,
322 * especially if the latter case turns out to be
323 * common.
324 */
325 ex = path[depth].p_ext;
326 if (ex) {
327 ext4_fsblk_t ext_pblk = ext4_ext_pblock(ex);
328 ext4_lblk_t ext_block = le32_to_cpu(ex->ee_block);
329
330 if (block > ext_block)
331 return ext_pblk + (block - ext_block);
332 else
333 return ext_pblk - (ext_block - block);
334 }
335
336 /* it looks like index is empty;
337 * try to find starting block from index itself */
338 if (path[depth].p_bh)
339 return path[depth].p_bh->b_blocknr;
340 }
341
342 /* OK. use inode's group */
unsigned long long ext4_fsblk_t
Definition: ext3_fs_i.h:27
static ext4_fsblk_t ext4_inode_to_goal_block(struct inode *inode)
Definition: ext4_extents.c:45

Referenced by ext4_ext_get_blocks(), and ext4_ext_new_meta_block().

◆ ext4_ext_get_access()

static int ext4_ext_get_access ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path 
)
static

Definition at line 284 of file ext4_extents.c.

287{
288 if (path->p_bh) {
289 /* path points to block */
290
291 return ext4_journal_get_write_access(icb, handle, path->p_bh);
292
293 }
294 /* path points to leaf/index in inode body */
295 /* we use in-core data, no need to protect them */
296 return 0;
#define ext4_journal_get_write_access(handle, icb, bh)
Definition: ext4_jbd2.h:28

Referenced by ext4_ext_correct_indexes(), ext4_ext_insert_extent(), ext4_ext_insert_index(), ext4_ext_remove_space(), ext4_ext_rm_idx(), ext4_ext_rm_leaf(), ext4_ext_split(), and ext4_split_extent_at().

◆ ext4_ext_get_blocks()

int ext4_ext_get_blocks ( void icb,
handle_t handle,
struct inode inode,
ext4_fsblk_t  iblock,
unsigned long  max_blocks,
struct buffer_head bh_result,
int  create,
int  flags 
)

Definition at line 2384 of file ext4_extents.c.

2388{
2389 struct ext4_ext_path *path = NULL;
2390 struct ext4_extent newex, *ex;
2391 int goal, err = 0, depth;
2392 unsigned long allocated = 0;
2393 ext4_fsblk_t next, newblock;
2394
2395 clear_buffer_new(bh_result);
2396 /*mutex_lock(&ext4_I(inode)->truncate_mutex);*/
2397
2398 /* find extent for this block */
2399 path = ext4_find_extent(inode, iblock, NULL, 0);
2400 if (IS_ERR(path)) {
2401 err = PTR_ERR(path);
2402 path = NULL;
2403 goto out2;
2404 }
2405
2407
2408 /*
2409 * consistent leaf must not be empty
2410 * this situations is possible, though, _during_ tree modification
2411 * this is why assert can't be put in ext4_ext_find_extent()
2412 */
2413 BUG_ON(path[depth].p_ext == NULL && depth != 0);
2414
2415 if ((ex = path[depth].p_ext)) {
2416 ext4_lblk_t ee_block = le32_to_cpu(ex->ee_block);
2417 ext4_fsblk_t ee_start = ext4_ext_pblock(ex);
2418 unsigned short ee_len = ext4_ext_get_actual_len(ex);
2419 /* if found exent covers block, simple return it */
2420 if (iblock >= ee_block && iblock < ee_block + ee_len) {
2421
2422 /* number of remain blocks in the extent */
2423 allocated = ee_len + ee_block - iblock;
2424
2426 if (create) {
2427 newblock = iblock - ee_block + ee_start;
2429 icb, handle,
2430 inode,
2431 &path,
2432 iblock,
2433 allocated,
2434 flags);
2435 if (err)
2436 goto out2;
2437
2438 } else {
2439 newblock = 0;
2440 }
2441 } else {
2442 newblock = iblock - ee_block + ee_start;
2443 }
2444 goto out;
2445 }
2446 }
2447
2448 /*
2449 * requested block isn't allocated yet
2450 * we couldn't try to create block if create flag is zero
2451 */
2452 if (!create) {
2453 goto out2;
2454 }
2455
2456 /* find next allocated block so that we know how many
2457 * blocks we can allocate without ovelapping next extent */
2459 BUG_ON(next <= iblock);
2460 allocated = next - iblock;
2462 max_blocks = EXT_UNWRITTEN_MAX_LEN;
2463 if (allocated > max_blocks)
2464 allocated = max_blocks;
2465
2466 /* allocate new block */
2467 goal = ext4_ext_find_goal(inode, path, iblock);
2468
2469 newblock = ext4_new_meta_blocks(icb, handle, inode, goal, 0,
2470 &allocated, &err);
2471 if (!newblock)
2472 goto out2;
2473
2474 /* try to insert new extent into found leaf and return */
2475 newex.ee_block = cpu_to_le32(iblock);
2476 ext4_ext_store_pblock(&newex, newblock);
2477 newex.ee_len = cpu_to_le16(allocated);
2478 /* if it's fallocate, mark ex as unwritten */
2481 }
2482 err = ext4_ext_insert_extent(icb, handle, inode, &path, &newex,
2484
2485 if (err) {
2486 /* free data blocks we just allocated */
2489 goto out2;
2490 }
2491
2493
2494 /* previous routine could use block we allocated */
2495 if (ext4_ext_is_unwritten(&newex))
2496 newblock = 0;
2497 else
2498 newblock = ext4_ext_pblock(&newex);
2499
2500 set_buffer_new(bh_result);
2501
2502out:
2503 if (allocated > max_blocks)
2504 allocated = max_blocks;
2505
2507 set_buffer_mapped(bh_result);
2508 bh_result->b_bdev = inode->i_sb->s_bdev;
2509 bh_result->b_blocknr = newblock;
2510out2:
2511 if (path) {
2513 kfree(path);
2514 }
2515 /*mutex_unlock(&ext4_I(inode)->truncate_mutex);*/
2516
2517 return err ? err : allocated;
#define EXT4_GET_BLOCKS_PRE_IO
Definition: ext4.h:31
static void ext4_ext_mark_unwritten(struct ext4_extent *ext)
Definition: ext4_ext.h:163
static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb)
Definition: ext4_ext.h:206
uint16_t ee_len
Definition: ext4_ext.h:1
static int get_default_free_blocks_flags(struct inode *inode)
static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
Definition: ext4_extents.c:299
void ext4_ext_drop_refs(struct ext4_ext_path *path)
Definition: ext4_extents.c:379
static int ext4_ext_convert_to_initialized(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, ext4_lblk_t split, unsigned long blocks, int flags)
int ext4_ext_insert_extent(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path **ppath, struct ext4_extent *newext, int gb_flags)
static void ext4_free_blocks(void *icb, handle_t *handle, struct inode *inode, void *fake, ext4_fsblk_t block, int count, int flags)
Definition: ext4_extents.c:77
static ext4_fsblk_t ext4_new_meta_blocks(void *icb, handle_t *handle, struct inode *inode, ext4_fsblk_t goal, unsigned int flags, unsigned long *count, int *errp)
Definition: ext4_extents.c:52
ext4_lblk_t ext4_ext_next_allocated_block(struct ext4_ext_path *path)
#define ext4_ext_show_leaf(inode, path)
Definition: ext4_extents.c:639
#define cpu_to_le32
Definition: module.h:148
#define kfree(p)
Definition: module.h:1126
#define cpu_to_le16
Definition: module.h:150
static const struct access_res create[16]
Definition: package.c:7505
static unsigned __int64 next
Definition: rand_nt.c:6
struct block_device * b_bdev
Definition: module.h:731
blkcnt_t b_blocknr
Definition: module.h:733

Referenced by Ext2DoExtentExpand(), and Ext2MapExtent().

◆ ext4_ext_grow_indepth()

static int ext4_ext_grow_indepth ( void icb,
handle_t handle,
struct inode inode,
unsigned int  flags 
)
static

Definition at line 1044 of file ext4_extents.c.

1047{
1048 struct ext4_extent_header *neh;
1049 struct buffer_head *bh;
1050 ext4_fsblk_t newblock, goal = 0;
1051 int err = 0;
1052
1053 /* Try to prepend new index to old one */
1054 if (ext_depth(inode))
1057 newblock = ext4_new_meta_blocks(icb, handle, inode, goal, flags,
1058 NULL, &err);
1059 if (newblock == 0)
1060 return err;
1061
1062 bh = extents_bwrite(inode->i_sb, newblock);
1063 if (!bh)
1064 return -ENOMEM;
1065
1067 if (err)
1068 goto out;
1069
1070 /* move top-level index/leaf into new block */
1071 memmove(bh->b_data, EXT4_I(inode)->i_block,
1072 sizeof(EXT4_I(inode)->i_block));
1073
1074 /* set size of new block */
1075 neh = ext_block_hdr(bh);
1076 /* old root could have indexes or leaves
1077 * so calculate e_max right way */
1078 if (ext_depth(inode))
1080 else
1084 set_buffer_uptodate(bh);
1085
1087 if (err)
1088 goto out;
1089
1090 /* Update top-level index: num,max,pointer */
1091 neh = ext_inode_hdr(inode);
1092 neh->eh_entries = cpu_to_le16(1);
1093 ext4_idx_store_pblock(EXT_FIRST_INDEX(neh), newblock);
1094 if (neh->eh_depth == 0) {
1095 /* Root extent block becomes index block */
1097 EXT_FIRST_INDEX(neh)->ei_block =
1098 EXT_FIRST_EXTENT(neh)->ee_block;
1099 }
1100 ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n",
1101 (neh->eh_entries), (neh->eh_max),
1102 (EXT_FIRST_INDEX(neh)->ei_block),
1104
1105 le16_add_cpu(&neh->eh_depth, 1);
1107out:
1108 extents_brelse(bh);
1109
1110 return err;
#define EXT4_I(i)
Definition: ext4.h:117
static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb)
Definition: ext4_ext.h:218
uint32_t ei_block
Definition: ext4_ext.h:0
static int ext4_ext_space_block(struct inode *inode, int check)
Definition: ext4_extents.c:114
static int ext4_ext_space_block_idx(struct inode *inode, int check)
Definition: ext4_extents.c:127
static int ext4_ext_space_root_idx(struct inode *inode, int check)
Definition: ext4_extents.c:154
#define ext4_handle_dirty_metadata(handle, icb, inode, bh)
Definition: ext4_jbd2.h:35
#define ext4_journal_get_create_access(handle, icb, bh)
Definition: ext4_jbd2.h:33
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static void le16_add_cpu(__le16 *var, u16 val)
Definition: module.h:186
struct buffer_head * extents_bwrite(struct super_block *sb, sector_t block)
Definition: ext4_bh.c:27
char * b_data
Definition: module.h:735

Referenced by ext4_ext_create_new_leaf().

◆ ext4_ext_init()

void ext4_ext_init ( struct super_block sb)

Definition at line 2335 of file ext4_extents.c.

2337{
2338 /*
2339 * possible initialization would be here
2340 */

◆ ext4_ext_insert_extent()

int ext4_ext_insert_extent ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path **  ppath,
struct ext4_extent newext,
int  gb_flags 
)

Definition at line 1650 of file ext4_extents.c.

1655{
1656 struct ext4_ext_path *path = *ppath;
1657 struct ext4_extent_header *eh;
1658 struct ext4_extent *ex, *fex;
1659 struct ext4_extent *nearex; /* nearest extent */
1660 struct ext4_ext_path *npath = NULL;
1661 int depth, len, err;
1663 int mb_flags = 0, unwritten;
1664
1665 if (gb_flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
1666 mb_flags |= EXT4_MB_DELALLOC_RESERVED;
1667 if (unlikely(ext4_ext_get_actual_len(newext) == 0)) {
1668 EXT4_ERROR_INODE(inode, "ext4_ext_get_actual_len(newext) == 0");
1669 return -EIO;
1670 }
1672 ex = path[depth].p_ext;
1673 eh = path[depth].p_hdr;
1674 if (unlikely(path[depth].p_hdr == NULL)) {
1675 EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
1676 return -EIO;
1677 }
1678
1679 /* try to insert block into found extent and return */
1680 if (ex && !(gb_flags & EXT4_GET_BLOCKS_PRE_IO)) {
1681
1682 /*
1683 * Try to see whether we should rather test the extent on
1684 * right from ex, or from the left of ex. This is because
1685 * ext4_find_extent() can return either extent on the
1686 * left, or on the right from the searched position. This
1687 * will make merging more effective.
1688 */
1689 if (ex < EXT_LAST_EXTENT(eh) &&
1690 (le32_to_cpu(ex->ee_block) +
1692 le32_to_cpu(newext->ee_block))) {
1693 ex += 1;
1694 goto prepend;
1695 } else if ((ex > EXT_FIRST_EXTENT(eh)) &&
1696 (le32_to_cpu(newext->ee_block) +
1697 ext4_ext_get_actual_len(newext) <
1698 le32_to_cpu(ex->ee_block)))
1699 ex -= 1;
1700
1701 /* Try to append newex to the ex */
1702 if (ext4_can_extents_be_merged(inode, ex, newext)) {
1703 ext_debug("append [%d]%d block to %u:[%d]%d"
1704 "(from %llu)\n",
1705 ext4_ext_is_unwritten(newext),
1707 le32_to_cpu(ex->ee_block),
1712 path + depth);
1713 if (err)
1714 return err;
1715 unwritten = ext4_ext_is_unwritten(ex);
1717 + ext4_ext_get_actual_len(newext));
1718 if (unwritten)
1720 eh = path[depth].p_hdr;
1721 nearex = ex;
1722 goto merge;
1723 }
1724
1725prepend:
1726 /* Try to prepend newex to the ex */
1727 if (ext4_can_extents_be_merged(inode, newext, ex)) {
1728 ext_debug("prepend %u[%d]%d block to %u:[%d]%d"
1729 "(from %llu)\n",
1730 le32_to_cpu(newext->ee_block),
1731 ext4_ext_is_unwritten(newext),
1733 le32_to_cpu(ex->ee_block),
1738 path + depth);
1739 if (err)
1740 return err;
1741
1742 unwritten = ext4_ext_is_unwritten(ex);
1743 ex->ee_block = newext->ee_block;
1746 + ext4_ext_get_actual_len(newext));
1747 if (unwritten)
1749 eh = path[depth].p_hdr;
1750 nearex = ex;
1751 goto merge;
1752 }
1753 }
1754
1756 eh = path[depth].p_hdr;
1757 if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max))
1758 goto has_space;
1759
1760 /* probably next leaf has space for us? */
1761 fex = EXT_LAST_EXTENT(eh);
1763 if (le32_to_cpu(newext->ee_block) > le32_to_cpu(fex->ee_block))
1765 if (next != EXT_MAX_BLOCKS) {
1766 ext_debug("next leaf block - %u\n", next);
1767 BUG_ON(npath != NULL);
1768 npath = ext4_find_extent(inode, next, NULL, 0);
1769 if (IS_ERR(npath))
1770 return PTR_ERR(npath);
1771 BUG_ON(npath->p_depth != path->p_depth);
1772 eh = npath[depth].p_hdr;
1773 if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) {
1774 ext_debug("next leaf isn't full(%d)\n",
1775 le16_to_cpu(eh->eh_entries));
1776 path = npath;
1777 goto has_space;
1778 }
1779 ext_debug("next leaf has no free space(%d,%d)\n",
1781 }
1782
1783 /*
1784 * There is no free space in the found leaf.
1785 * We're gonna add a new leaf in the tree.
1786 */
1787 if (gb_flags & EXT4_GET_BLOCKS_METADATA_NOFAIL)
1788 mb_flags |= EXT4_MB_USE_RESERVED;
1789 err = ext4_ext_create_new_leaf(icb, handle, inode, mb_flags, gb_flags,
1790 ppath, newext);
1791 if (err)
1792 goto cleanup;
1794 eh = path[depth].p_hdr;
1795
1796has_space:
1797 nearex = path[depth].p_ext;
1798
1800 if (err)
1801 goto cleanup;
1802
1803 if (!nearex) {
1804 /* there is no extent in this leaf, create first one */
1805 ext_debug("first extent in the leaf: %u:%llu:[%d]%d\n",
1806 le32_to_cpu(newext->ee_block),
1807 ext4_ext_pblock(newext),
1808 ext4_ext_is_unwritten(newext),
1809 ext4_ext_get_actual_len(newext));
1810 nearex = EXT_FIRST_EXTENT(eh);
1811 } else {
1812 if (le32_to_cpu(newext->ee_block)
1813 > le32_to_cpu(nearex->ee_block)) {
1814 /* Insert after */
1815 ext_debug("insert %u:%llu:[%d]%d before: "
1816 "nearest %p\n",
1817 le32_to_cpu(newext->ee_block),
1818 ext4_ext_pblock(newext),
1819 ext4_ext_is_unwritten(newext),
1821 nearex);
1822 nearex++;
1823 } else {
1824 /* Insert before */
1825 BUG_ON(newext->ee_block == nearex->ee_block);
1826 ext_debug("insert %u:%llu:[%d]%d after: "
1827 "nearest %p\n",
1828 le32_to_cpu(newext->ee_block),
1829 ext4_ext_pblock(newext),
1830 ext4_ext_is_unwritten(newext),
1832 nearex);
1833 }
1834 len = EXT_LAST_EXTENT(eh) - nearex + 1;
1835 if (len > 0) {
1836 ext_debug("insert %u:%llu:[%d]%d: "
1837 "move %d extents from 0x%p to 0x%p\n",
1838 le32_to_cpu(newext->ee_block),
1839 ext4_ext_pblock(newext),
1840 ext4_ext_is_unwritten(newext),
1842 len, nearex, nearex + 1);
1843 memmove(nearex + 1, nearex,
1844 len * sizeof(struct ext4_extent));
1845 }
1846 }
1847
1848 le16_add_cpu(&eh->eh_entries, 1);
1849 path[depth].p_ext = nearex;
1850 nearex->ee_block = newext->ee_block;
1851 ext4_ext_store_pblock(nearex, ext4_ext_pblock(newext));
1852 nearex->ee_len = newext->ee_len;
1853
1854merge:
1855 /* try to merge extents */
1856 if (!(gb_flags & EXT4_GET_BLOCKS_PRE_IO))
1857 ext4_ext_try_to_merge(icb, handle, inode, path, nearex);
1858
1859
1860 /* time to correct all indexes above */
1862 if (err)
1863 goto cleanup;
1864
1865 err = ext4_ext_dirty(icb, handle, inode, path + path->p_depth);
1866
1867cleanup:
1868 if (npath) {
1869 ext4_ext_drop_refs(npath);
1870 kfree(npath);
1871 }
1872 return err;
_STLP_MOVE_TO_STD_NAMESPACE _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, _InputIter2 __first2, _InputIter2 __last2, _OutputIter __result)
Definition: _algo.c:1419
static void cleanup(void)
Definition: main.c:1335
#define EXT4_MB_USE_RESERVED
Definition: ext4.h:108
#define EXT4_GET_BLOCKS_METADATA_NOFAIL
Definition: ext4.h:40
#define EXT4_MB_DELALLOC_RESERVED
Definition: ext4.h:102
#define EXT4_GET_BLOCKS_DELALLOC_RESERVE
Definition: ext4.h:27
static void ext4_ext_try_to_merge(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex)
static ext4_lblk_t ext4_ext_next_leaf_block(struct ext4_ext_path *path)
static int ext4_ext_correct_indexes(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
static int ext4_ext_create_new_leaf(void *icb, handle_t *handle, struct inode *inode, unsigned int mb_flags, unsigned int gb_flags, struct ext4_ext_path **ppath, struct ext4_extent *newext)
#define EXT_MAX_BLOCKS
Definition: ext4_extents.c:111
int ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, struct ext4_extent *ex2)
GLenum GLsizei len
Definition: glext.h:6722
uint16_t ee_len
Definition: ext4_ext.h:21

Referenced by ext4_ext_get_blocks(), and ext4_split_extent_at().

◆ ext4_ext_insert_index()

static int ext4_ext_insert_index ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path curp,
int  logical,
ext4_fsblk_t  ptr 
)
static

Definition at line 734 of file ext4_extents.c.

738{
739 struct ext4_extent_idx *ix;
740 int len, err;
741
742 err = ext4_ext_get_access(icb, handle, inode, curp);
743 if (err)
744 return err;
745
746 if (unlikely(logical == le32_to_cpu(curp->p_idx->ei_block))) {
748 "logical %d == ei_block %d!",
749 logical, le32_to_cpu(curp->p_idx->ei_block));
750 return -EIO;
751 }
752
753 if (unlikely(le16_to_cpu(curp->p_hdr->eh_entries)
754 >= le16_to_cpu(curp->p_hdr->eh_max))) {
756 "eh_entries %d >= eh_max %d!",
757 le16_to_cpu(curp->p_hdr->eh_entries),
758 le16_to_cpu(curp->p_hdr->eh_max));
759 return -EIO;
760 }
761
762 if (logical > le32_to_cpu(curp->p_idx->ei_block)) {
763 /* insert after */
764 ext_debug("insert new index %d after: %llu\n", logical, ptr);
765 ix = curp->p_idx + 1;
766 } else {
767 /* insert before */
768 ext_debug("insert new index %d before: %llu\n", logical, ptr);
769 ix = curp->p_idx;
770 }
771
772 len = EXT_LAST_INDEX(curp->p_hdr) - ix + 1;
773 BUG_ON(len < 0);
774 if (len > 0) {
775 ext_debug("insert new index %d: "
776 "move %d indices from 0x%p to 0x%p\n",
777 logical, len, ix, ix + 1);
778 memmove(ix + 1, ix, len * sizeof(struct ext4_extent_idx));
779 }
780
781 if (unlikely(ix > EXT_MAX_INDEX(curp->p_hdr))) {
782 EXT4_ERROR_INODE(inode, "ix > EXT_MAX_INDEX!");
783 return -EIO;
784 }
785
786 ix->ei_block = cpu_to_le32(logical);
788 le16_add_cpu(&curp->p_hdr->eh_entries, 1);
789
790 if (unlikely(ix > EXT_LAST_INDEX(curp->p_hdr))) {
791 EXT4_ERROR_INODE(inode, "ix > EXT_LAST_INDEX!");
792 return -EIO;
793 }
794
795 err = ext4_ext_dirty(icb, handle, inode, curp);
797
798 return err;
#define EXT_MAX_INDEX(__hdr__)
Definition: ext4_ext.h:121
#define ext4_std_error(s, err)
Definition: ext4_extents.c:102
static PVOID ptr
Definition: dispmode.c:27
struct ext4_extent_idx * p_idx
Definition: ext4_ext.h:75

Referenced by ext4_ext_split().

◆ ext4_ext_max_entries()

static int ext4_ext_max_entries ( struct inode inode,
int  depth 
)
static

Definition at line 169 of file ext4_extents.c.

171{
172 int max;
173
174 if (depth == ext_depth(inode)) {
175 if (depth == 0)
177 else
179 } else {
180 if (depth == 0)
182 else
184 }
185
186 return max;
static int ext4_ext_space_root(struct inode *inode, int check)
Definition: ext4_extents.c:140

◆ ext4_ext_more_to_rm()

static int ext4_ext_more_to_rm ( struct ext4_ext_path path)
inlinestatic

Definition at line 2193 of file ext4_extents.c.

2195{
2196 BUG_ON(path->p_idx == NULL);
2197
2198 if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr))
2199 return 0;
2200
2201 /*
2202 * if truncate on deeper level happened it it wasn't partial
2203 * so we have to consider current index for truncation
2204 */
2205 if (le16_to_cpu(path->p_hdr->eh_entries) == path->p_block)
2206 return 0;
2207 return 1;

Referenced by ext4_ext_remove_space().

◆ ext4_ext_new_meta_block()

static ext4_fsblk_t ext4_ext_new_meta_block ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path,
struct ext4_extent ex,
int err,
unsigned int  flags 
)
static

Definition at line 349 of file ext4_extents.c.

353{
354 ext4_fsblk_t goal, newblock;
355
356 goal = ext4_ext_find_goal(inode, path, le32_to_cpu(ex->ee_block));
357 newblock = ext4_new_meta_blocks(icb, handle, inode, goal, flags,
358 NULL, err);
359 return newblock;

Referenced by ext4_ext_split().

◆ ext4_ext_next_allocated_block()

ext4_lblk_t ext4_ext_next_allocated_block ( struct ext4_ext_path path)

Definition at line 1369 of file ext4_extents.c.

1371{
1372 int depth;
1373
1374 depth = path->p_depth;
1375
1376 if (depth == 0 && path->p_ext == NULL)
1377 return EXT_MAX_BLOCKS;
1378
1379 while (depth >= 0) {
1380 if (depth == path->p_depth) {
1381 /* leaf */
1382 if (path[depth].p_ext &&
1383 path[depth].p_ext !=
1384 EXT_LAST_EXTENT(path[depth].p_hdr))
1385 return le32_to_cpu(path[depth].p_ext[1].ee_block);
1386 } else {
1387 /* index */
1388 if (path[depth].p_idx !=
1389 EXT_LAST_INDEX(path[depth].p_hdr))
1390 return le32_to_cpu(path[depth].p_idx[1].ei_block);
1391 }
1392 depth--;
1393 }
1394
1395 return EXT_MAX_BLOCKS;

Referenced by ext4_ext_get_blocks().

◆ ext4_ext_next_leaf_block()

static ext4_lblk_t ext4_ext_next_leaf_block ( struct ext4_ext_path path)
static

Definition at line 1401 of file ext4_extents.c.

1403{
1404 int depth;
1405
1406 BUG_ON(path == NULL);
1407 depth = path->p_depth;
1408
1409 /* zero-tree has no leaf blocks at all */
1410 if (depth == 0)
1411 return EXT_MAX_BLOCKS;
1412
1413 /* go to index block */
1414 depth--;
1415
1416 while (depth >= 0) {
1417 if (path[depth].p_idx !=
1418 EXT_LAST_INDEX(path[depth].p_hdr))
1419 return (ext4_lblk_t)
1420 le32_to_cpu(path[depth].p_idx[1].ei_block);
1421 depth--;
1422 }
1423
1424 return EXT_MAX_BLOCKS;

Referenced by ext4_ext_insert_extent().

◆ ext4_ext_remove_space()

int ext4_ext_remove_space ( void icb,
struct inode inode,
unsigned long  start 
)

Definition at line 2209 of file ext4_extents.c.

2211{
2212 struct super_block *sb = inode->i_sb;
2213 int depth = ext_depth(inode);
2214 struct ext4_ext_path *path;
2215 handle_t *handle = NULL;
2216 int i = 0, err = 0;
2217
2218 /* probably first extent we're gonna free will be last in block */
2219 /*handle = ext4_journal_start(inode, depth + 1);*/
2220 /*if (IS_ERR(icb, handle))*/
2221 /*return PTR_ERR(icb, handle);*/
2222
2223 /*
2224 * we start scanning from right side freeing all the blocks
2225 * after i_size and walking into the deep
2226 */
2227 path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL);
2228 if (path == NULL) {
2230 return -ENOMEM;
2231 }
2232 memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1));
2233 path[0].p_hdr = ext_inode_hdr(inode);
2235 err = -EIO;
2236 goto out;
2237 }
2238 path[0].p_depth = depth;
2239
2240 while (i >= 0 && err == 0) {
2241 if (i == depth) {
2242 /* this is leaf block */
2244 /* root level have p_bh == NULL, extents_brelse() eats this */
2246 path[i].p_bh = NULL;
2247 i--;
2248 continue;
2249 }
2250
2251 /* this is index block */
2252 if (!path[i].p_hdr) {
2253 path[i].p_hdr = ext_block_hdr(path[i].p_bh);
2254 }
2255
2256 if (!path[i].p_idx) {
2257 /* this level hasn't touched yet */
2258 path[i].p_idx = EXT_LAST_INDEX(path[i].p_hdr);
2259 path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries)+1;
2260 } else {
2261 /* we've already was here, see at next index */
2262 path[i].p_idx--;
2263 }
2264
2265 if (ext4_ext_more_to_rm(path + i)) {
2266 struct buffer_head *bh;
2267 /* go to the next level */
2268 memset(path + i + 1, 0, sizeof(*path));
2269 bh = read_extent_tree_block(inode, ext4_idx_pblock(path[i].p_idx), path[0].p_depth - (i + 1), 0);
2270 if (IS_ERR(bh)) {
2271 /* should we reset i_size? */
2272 err = -EIO;
2273 break;
2274 }
2275 path[i+1].p_bh = bh;
2276
2277 /* put actual number of indexes to know is this
2278 * number got changed at the next iteration */
2279 path[i].p_block = le16_to_cpu(path[i].p_hdr->eh_entries);
2280 i++;
2281 } else {
2282 /* we finish processing this index, go up */
2283 if (path[i].p_hdr->eh_entries == 0 && i > 0) {
2284 /* index is empty, remove it
2285 * handle must be already prepared by the
2286 * truncatei_leaf() */
2287 err = ext4_ext_rm_idx(icb, handle, inode, path + i);
2288 }
2289 /* root level have p_bh == NULL, extents_brelse() eats this */
2290 extents_brelse(path[i].p_bh);
2291 path[i].p_bh = NULL;
2292 i--;
2293 }
2294 }
2295
2296 /* TODO: flexible tree reduction should be here */
2297 if (path->p_hdr->eh_entries == 0) {
2298 /*
2299 * truncate to zero freed all the tree
2300 * so, we need to correct eh_depth
2301 */
2303 if (err == 0) {
2304 ext_inode_hdr(inode)->eh_depth = 0;
2305 ext_inode_hdr(inode)->eh_max =
2308 }
2309 }
2310out:
2311 if (path) {
2313 kfree(path);
2314 }
2316
2317 return err;
superblock * sb
Definition: btrfs.c:4261
int ext4_ext_rm_idx(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
static int ext4_ext_more_to_rm(struct ext4_ext_path *path)
int ext4_ext_check_inode(struct inode *inode)
Definition: ext4_extents.c:234
#define read_extent_tree_block(inode, pblk, depth, flags)
Definition: ext4_extents.c:227
static int ext4_ext_rm_leaf(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, unsigned long start)
#define ext4_journal_stop(icb, handle)
Definition: ext4_jbd2.h:57
GLuint start
Definition: gl.h:1545
#define kmalloc(size, gfp)
Definition: module.h:1125
#define GFP_KERNEL
Definition: module.h:668
#define memset(x, y, z)
Definition: compat.h:39
struct buffer_head * p_bh
Definition: ext4_ext.h:77
Definition: fs.h:64

Referenced by ext4_ext_truncate().

◆ ext4_ext_rm_idx()

int ext4_ext_rm_idx ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path 
)

Definition at line 1920 of file ext4_extents.c.

1923{
1924 int err;
1925 ext4_fsblk_t leaf;
1926
1927 /* free index block */
1928 path--;
1929 leaf = ext4_idx_pblock(path->p_idx);
1930 BUG_ON(path->p_hdr->eh_entries == 0);
1931 if ((err = ext4_ext_get_access(icb, handle, inode, path)))
1932 return err;
1933 path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1);
1934 if ((err = ext4_ext_dirty(icb, handle, inode, path)))
1935 return err;
1936 ext4_free_blocks(icb, handle, inode, NULL, leaf, 1, 0);
1937 return err;

Referenced by ext4_ext_remove_space(), and ext4_ext_rm_leaf().

◆ ext4_ext_rm_leaf()

static int ext4_ext_rm_leaf ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path,
unsigned long  start 
)
static

Definition at line 1940 of file ext4_extents.c.

1943{
1944 int err = 0, correct_index = 0;
1945 int depth = ext_depth(inode), credits;
1946 struct ext4_extent_header *eh;
1947 unsigned a, b, block, num;
1948 unsigned long ex_ee_block;
1949 unsigned short ex_ee_len;
1950 struct ext4_extent *ex;
1951
1952 /* the header must be checked already in ext4_ext_remove_space() */
1953 if (!path[depth].p_hdr)
1954 path[depth].p_hdr = ext_block_hdr(path[depth].p_bh);
1955 eh = path[depth].p_hdr;
1956 BUG_ON(eh == NULL);
1957
1958 /* find where to start removing */
1959 ex = EXT_LAST_EXTENT(eh);
1960
1961 ex_ee_block = le32_to_cpu(ex->ee_block);
1962 ex_ee_len = ext4_ext_get_actual_len(ex);
1963
1964 while (ex >= EXT_FIRST_EXTENT(eh) &&
1965 ex_ee_block + ex_ee_len > start) {
1966 path[depth].p_ext = ex;
1967
1968 a = ex_ee_block > start ? ex_ee_block : start;
1969 b = (unsigned long long)ex_ee_block + ex_ee_len - 1 <
1970 EXT_MAX_BLOCKS ? ex_ee_block + ex_ee_len - 1 : EXT_MAX_BLOCKS;
1971
1972
1973 if (a != ex_ee_block && b != ex_ee_block + ex_ee_len - 1) {
1974 block = 0;
1975 num = 0;
1976 BUG();
1977 } else if (a != ex_ee_block) {
1978 /* remove tail of the extent */
1979 block = ex_ee_block;
1980 num = a - block;
1981 } else if (b != ex_ee_block + ex_ee_len - 1) {
1982 /* remove head of the extent */
1983 block = a;
1984 num = b - a;
1985 /* there is no "make a hole" API yet */
1986 BUG();
1987 } else {
1988 /* remove whole extent: excellent! */
1989 block = ex_ee_block;
1990 num = 0;
1991 BUG_ON(a != ex_ee_block);
1992 BUG_ON(b != ex_ee_block + ex_ee_len - 1);
1993 }
1994
1995 /* at present, extent can't cross block group */
1996 /* leaf + bitmap + group desc + sb + inode */
1997 credits = 5;
1998 if (ex == EXT_FIRST_EXTENT(eh)) {
1999 correct_index = 1;
2000 credits += (ext_depth(inode)) + 1;
2001 }
2002
2003 /*handle = ext4_ext_journal_restart(icb, handle, credits);*/
2004 /*if (IS_ERR(icb, handle)) {*/
2005 /*err = PTR_ERR(icb, handle);*/
2006 /*goto out;*/
2007 /*}*/
2008
2010 if (err)
2011 goto out;
2012
2013 err = ext4_remove_blocks(icb, handle, inode, ex, a, b);
2014 if (err)
2015 goto out;
2016
2017 if (num == 0) {
2018 /* this extent is removed entirely mark slot unused */
2021 }
2022
2023 ex->ee_block = cpu_to_le32(block);
2024 ex->ee_len = cpu_to_le16(num);
2025
2027 if (err)
2028 goto out;
2029
2030 ex--;
2031 ex_ee_block = le32_to_cpu(ex->ee_block);
2032 ex_ee_len = ext4_ext_get_actual_len(ex);
2033 }
2034
2035 if (correct_index && eh->eh_entries)
2037
2038 /* if this leaf is free, then we should
2039 * remove it from index block above */
2040 if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL)
2042
2043out:
2044 return err;
#define BUG()
Definition: types.h:119
static int ext4_remove_blocks(void *icb, handle_t *handle, struct inode *inode, struct ext4_extent *ex, unsigned long from, unsigned long to)
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint GLuint num
Definition: glext.h:9618
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define long
Definition: qsort.c:33

Referenced by ext4_ext_remove_space().

◆ ext4_ext_search_left()

static int ext4_ext_search_left ( struct inode inode,
struct ext4_ext_path path,
ext4_lblk_t logical,
ext4_fsblk_t phys 
)
static

Definition at line 1189 of file ext4_extents.c.

1193{
1194 struct ext4_extent_idx *ix;
1195 struct ext4_extent *ex;
1196 int depth, ee_len;
1197
1198 if (unlikely(path == NULL)) {
1199 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
1200 return -EIO;
1201 }
1202 depth = path->p_depth;
1203 *phys = 0;
1204
1205 if (depth == 0 && path->p_ext == NULL)
1206 return 0;
1207
1208 /* usually extent in the path covers blocks smaller
1209 * then *logical, but it can be that extent is the
1210 * first one in the file */
1211
1212 ex = path[depth].p_ext;
1214 if (*logical < le32_to_cpu(ex->ee_block)) {
1215 if (unlikely(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex)) {
1217 "EXT_FIRST_EXTENT != ex *logical %d ee_block %d!",
1218 *logical, le32_to_cpu(ex->ee_block));
1219 return -EIO;
1220 }
1221 while (--depth >= 0) {
1222 ix = path[depth].p_idx;
1223 if (unlikely(ix != EXT_FIRST_INDEX(path[depth].p_hdr))) {
1225 "ix (%d) != EXT_FIRST_INDEX (%d) (depth %d)!",
1226 ix != NULL ? le32_to_cpu(ix->ei_block) : 0,
1227 EXT_FIRST_INDEX(path[depth].p_hdr) != NULL ?
1229 depth);
1230 return -EIO;
1231 }
1232 }
1233 return 0;
1234 }
1235
1236 if (unlikely(*logical < (le32_to_cpu(ex->ee_block) + ee_len))) {
1238 "logical %d < ee_block %d + ee_len %d!",
1239 *logical, le32_to_cpu(ex->ee_block), ee_len);
1240 return -EIO;
1241 }
1242
1243 *logical = le32_to_cpu(ex->ee_block) + ee_len - 1;
1244 *phys = ext4_ext_pblock(ex) + ee_len - 1;
1245 return 0;

◆ ext4_ext_search_right()

static int ext4_ext_search_right ( struct inode inode,
struct ext4_ext_path path,
ext4_lblk_t logical,
ext4_fsblk_t phys,
struct ext4_extent **  ret_ex 
)
static

logical, le32_to_cpu(ex->ee_block), ee_len);

logical = le32_to_cpu(ex->ee_block);

Definition at line 1254 of file ext4_extents.c.

1259{
1260 struct buffer_head *bh = NULL;
1261 struct ext4_extent_header *eh;
1262 struct ext4_extent_idx *ix;
1263 struct ext4_extent *ex;
1265 int depth; /* Note, NOT eh_depth; depth from top of tree */
1266 int ee_len;
1267
1268 if ((path == NULL)) {
1269 EXT4_ERROR_INODE(inode, "path == NULL *logical %d!", *logical);
1270 return -EIO;
1271 }
1272 depth = path->p_depth;
1273 *phys = 0;
1274
1275 if (depth == 0 && path->p_ext == NULL)
1276 return 0;
1277
1278 /* usually extent in the path covers blocks smaller
1279 * then *logical, but it can be that extent is the
1280 * first one in the file */
1281
1282 ex = path[depth].p_ext;
1284 /*if (*logical < le32_to_cpu(ex->ee_block)) {*/
1285 if (*logical < (ex->ee_block)) {
1286 if (unlikely(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex)) {
1288 "first_extent(path[%d].p_hdr) != ex",
1289 depth);
1290 return -EIO;
1291 }
1292 while (--depth >= 0) {
1293 ix = path[depth].p_idx;
1294 if (unlikely(ix != EXT_FIRST_INDEX(path[depth].p_hdr))) {
1296 "ix != EXT_FIRST_INDEX *logical %d!",
1297 *logical);
1298 return -EIO;
1299 }
1300 }
1301 goto found_extent;
1302 }
1303
1304 /*if (unlikely(*logical < (le32_to_cpu(ex->ee_block) + ee_len))) {*/
1305 if (unlikely(*logical < ((ex->ee_block) + ee_len))) {
1307 "logical %d < ee_block %d + ee_len %d!",
1309 *logical, (ex->ee_block), ee_len);
1310 return -EIO;
1311 }
1312
1313 if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
1314 /* next allocated block in this leaf */
1315 ex++;
1316 goto found_extent;
1317 }
1318
1319 /* go up and search for index to the right */
1320 while (--depth >= 0) {
1321 ix = path[depth].p_idx;
1322 if (ix != EXT_LAST_INDEX(path[depth].p_hdr))
1323 goto got_index;
1324 }
1325
1326 /* we've gone up to the root and found no index to the right */
1327 return 0;
1328
1329got_index:
1330 /* we've found index to the right, let's
1331 * follow it and find the closest allocated
1332 * block to the right */
1333 ix++;
1334 block = ext4_idx_pblock(ix);
1335 while (++depth < path->p_depth) {
1336 /* subtract from p_depth to get proper eh_depth */
1338 path->p_depth - depth, 0);
1339 if (IS_ERR(bh))
1340 return PTR_ERR(bh);
1341 eh = ext_block_hdr(bh);
1342 ix = EXT_FIRST_INDEX(eh);
1343 block = ext4_idx_pblock(ix);
1344 extents_brelse(bh);
1345 }
1346
1347 bh = read_extent_tree_block(inode, block, path->p_depth - depth, 0);
1348 if (IS_ERR(bh))
1349 return PTR_ERR(bh);
1350 eh = ext_block_hdr(bh);
1351 ex = EXT_FIRST_EXTENT(eh);
1352found_extent:
1354 *logical = (ex->ee_block);
1355 *phys = ext4_ext_pblock(ex);
1356 *ret_ex = ex;
1357 if (bh)
1358 extents_brelse(bh);
1359 return 0;

◆ ext4_ext_space_block()

static int ext4_ext_space_block ( struct inode inode,
int  check 
)
inlinestatic

Definition at line 114 of file ext4_extents.c.

116{
117 int size;
118
119 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
121#ifdef AGGRESSIVE_TEST
122 if (!check && size > 6)
123 size = 6;
124#endif
125 return size;
#define check(expected, result)
Definition: dplayx.c:32
GLsizeiptr size
Definition: glext.h:5919
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by ext4_ext_grow_indepth(), ext4_ext_max_entries(), and ext4_ext_split().

◆ ext4_ext_space_block_idx()

static int ext4_ext_space_block_idx ( struct inode inode,
int  check 
)
inlinestatic

Definition at line 127 of file ext4_extents.c.

129{
130 int size;
131
132 size = (inode->i_sb->s_blocksize - sizeof(struct ext4_extent_header))
134#ifdef AGGRESSIVE_TEST
135 if (!check && size > 5)
136 size = 5;
137#endif
138 return size;

Referenced by ext4_ext_grow_indepth(), ext4_ext_max_entries(), and ext4_ext_split().

◆ ext4_ext_space_root()

static int ext4_ext_space_root ( struct inode inode,
int  check 
)
inlinestatic

Definition at line 140 of file ext4_extents.c.

142{
143 int size;
144
145 size = sizeof(EXT4_I(inode)->i_block);
146 size -= sizeof(struct ext4_extent_header);
147 size /= sizeof(struct ext4_extent);
148#ifdef AGGRESSIVE_TEST
149 if (!check && size > 3)
150 size = 3;
151#endif
152 return size;

Referenced by ext4_ext_max_entries(), ext4_ext_remove_space(), ext4_ext_tree_init(), and ext4_ext_try_to_merge_up().

◆ ext4_ext_space_root_idx()

static int ext4_ext_space_root_idx ( struct inode inode,
int  check 
)
inlinestatic

Definition at line 154 of file ext4_extents.c.

156{
157 int size;
158
159 size = sizeof(EXT4_I(inode)->i_block);
160 size -= sizeof(struct ext4_extent_header);
161 size /= sizeof(struct ext4_extent_idx);
162#ifdef AGGRESSIVE_TEST
163 if (!check && size > 4)
164 size = 4;
165#endif
166 return size;

Referenced by ext4_ext_grow_indepth(), and ext4_ext_max_entries().

◆ ext4_ext_split()

static int ext4_ext_split ( void icb,
handle_t handle,
struct inode inode,
unsigned int  flags,
struct ext4_ext_path path,
struct ext4_extent newext,
int  at 
)
static

Definition at line 810 of file ext4_extents.c.

815{
816 struct buffer_head *bh = NULL;
817 int depth = ext_depth(inode);
818 struct ext4_extent_header *neh;
819 struct ext4_extent_idx *fidx;
820 int i = at, k, m, a;
821 ext4_fsblk_t newblock, oldblock;
823 ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
824 int err = 0;
825
826 /* make decision: where to split? */
827 /* FIXME: now decision is simplest: at current extent */
828
829 /* if current leaf will be split, then we should use
830 * border from split point */
831 if (unlikely(path[depth].p_ext > EXT_MAX_EXTENT(path[depth].p_hdr))) {
832 EXT4_ERROR_INODE(inode, "p_ext > EXT_MAX_EXTENT!");
833 return -EIO;
834 }
835 if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) {
836 border = path[depth].p_ext[1].ee_block;
837 ext_debug("leaf will be split."
838 " next leaf starts at %d\n",
840 } else {
841 border = newext->ee_block;
842 ext_debug("leaf will be added."
843 " next leaf starts at %d\n",
845 }
846
847 /*
848 * If error occurs, then we break processing
849 * and mark filesystem read-only. index won't
850 * be inserted and tree will be in consistent
851 * state. Next mount will repair buffers too.
852 */
853
854 /*
855 * Get array to track all allocated blocks.
856 * We need this to handle errors and free blocks
857 * upon them.
858 */
859 ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS);
860 if (!ablocks)
861 return -ENOMEM;
862
863 /* allocate all needed blocks */
864 ext_debug("allocate %d blocks for indexes/leaf\n", depth - at);
865 for (a = 0; a < depth - at; a++) {
866 newblock = ext4_ext_new_meta_block(icb, handle, inode, path,
867 newext, &err, flags);
868 if (newblock == 0)
869 goto cleanup;
870 ablocks[a] = newblock;
871 }
872
873 /* initialize new leaf */
874 newblock = ablocks[--a];
875 if (unlikely(newblock == 0)) {
876 EXT4_ERROR_INODE(inode, "newblock == 0!");
877 err = -EIO;
878 goto cleanup;
879 }
880 bh = extents_bwrite(inode->i_sb, newblock);
881 if (unlikely(!bh)) {
882 err = -ENOMEM;
883 goto cleanup;
884 }
885
887 if (err)
888 goto cleanup;
889
890 neh = ext_block_hdr(bh);
891 neh->eh_entries = 0;
894 neh->eh_depth = 0;
895
896 /* move remainder of path[depth] to the new leaf */
897 if (unlikely(path[depth].p_hdr->eh_entries !=
898 path[depth].p_hdr->eh_max)) {
899 EXT4_ERROR_INODE(inode, "eh_entries %d != eh_max %d!",
900 path[depth].p_hdr->eh_entries,
901 path[depth].p_hdr->eh_max);
902 err = -EIO;
903 goto cleanup;
904 }
905 /* start copy from next extent */
906 m = EXT_MAX_EXTENT(path[depth].p_hdr) - path[depth].p_ext++;
907 ext4_ext_show_move(inode, path, newblock, depth);
908 if (m) {
909 struct ext4_extent *ex;
910 ex = EXT_FIRST_EXTENT(neh);
911 memmove(ex, path[depth].p_ext, sizeof(struct ext4_extent) * m);
912 le16_add_cpu(&neh->eh_entries, m);
913 }
914
916 set_buffer_uptodate(bh);
917
919 if (err)
920 goto cleanup;
921 extents_brelse(bh);
922 bh = NULL;
923
924 /* correct old leaf */
925 if (m) {
927 if (err)
928 goto cleanup;
929 le16_add_cpu(&path[depth].p_hdr->eh_entries, -m);
931 if (err)
932 goto cleanup;
933
934 }
935
936 /* create intermediate indexes */
937 k = depth - at - 1;
938 if (unlikely(k < 0)) {
939 EXT4_ERROR_INODE(inode, "k %d < 0!", k);
940 err = -EIO;
941 goto cleanup;
942 }
943 if (k)
944 ext_debug("create %d intermediate indices\n", k);
945 /* insert new index into current index block */
946 /* current depth stored in i var */
947 i = depth - 1;
948 while (k--) {
949 oldblock = newblock;
950 newblock = ablocks[--a];
951 bh = extents_bwrite(inode->i_sb, newblock);
952 if (unlikely(!bh)) {
953 err = -ENOMEM;
954 goto cleanup;
955 }
956
958 if (err)
959 goto cleanup;
960
961 neh = ext_block_hdr(bh);
962 neh->eh_entries = cpu_to_le16(1);
965 neh->eh_depth = cpu_to_le16(depth - i);
966 fidx = EXT_FIRST_INDEX(neh);
967 fidx->ei_block = border;
968 ext4_idx_store_pblock(fidx, oldblock);
969
970 ext_debug("int.index at %d (block %llu): %u -> %llu\n",
971 i, newblock, le32_to_cpu(border), oldblock);
972
973 /* move remainder of path[i] to the new index block */
974 if (unlikely(EXT_MAX_INDEX(path[i].p_hdr) !=
975 EXT_LAST_INDEX(path[i].p_hdr))) {
977 "EXT_MAX_INDEX != EXT_LAST_INDEX ee_block %d!",
978 le32_to_cpu(path[i].p_ext->ee_block));
979 err = -EIO;
980 goto cleanup;
981 }
982 /* start copy indexes */
983 m = EXT_MAX_INDEX(path[i].p_hdr) - path[i].p_idx++;
984 ext_debug("cur 0x%p, last 0x%p\n", path[i].p_idx,
985 EXT_MAX_INDEX(path[i].p_hdr));
986 ext4_ext_show_move(inode, path, newblock, i);
987 if (m) {
988 memmove(++fidx, path[i].p_idx,
989 sizeof(struct ext4_extent_idx) * m);
990 le16_add_cpu(&neh->eh_entries, m);
991 }
993 set_buffer_uptodate(bh);
994
996 if (err)
997 goto cleanup;
998 extents_brelse(bh);
999 bh = NULL;
1000
1001 /* correct old index */
1002 if (m) {
1004 if (err)
1005 goto cleanup;
1006 le16_add_cpu(&path[i].p_hdr->eh_entries, -m);
1007 err = ext4_ext_dirty(icb, handle, inode, path + i);
1008 if (err)
1009 goto cleanup;
1010 }
1011
1012 i--;
1013 }
1014
1015 /* insert new index */
1017 le32_to_cpu(border), newblock);
1018
1019cleanup:
1020 if (bh)
1021 extents_brelse(bh);
1022
1023 if (err) {
1024 /* free all allocated blocks in error case */
1025 for (i = 0; i < depth; i++) {
1026 if (!ablocks[i])
1027 continue;
1028 ext4_free_blocks(icb, handle, inode, NULL, ablocks[i], 1,
1030 }
1031 }
1032 kfree(ablocks);
1033
1034 return err;
#define EXT4_FREE_BLOCKS_METADATA
Definition: ext4.h:67
#define EXT_MAX_EXTENT(__hdr__)
Definition: ext4_ext.h:119
static int ext4_ext_insert_index(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *curp, int logical, ext4_fsblk_t ptr)
Definition: ext4_extents.c:734
static ext4_fsblk_t ext4_ext_new_meta_block(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex, int *err, unsigned int flags)
Definition: ext4_extents.c:349
#define ext4_ext_show_move(inode, path, newblock, level)
Definition: ext4_extents.c:640
#define GFP_NOFS
Definition: module.h:669
void * kzalloc(int size, int flags)
Definition: linux.c:34

Referenced by ext4_ext_create_new_leaf().

◆ ext4_ext_tree_init()

int ext4_ext_tree_init ( void icb,
handle_t handle,
struct inode inode 
)

Definition at line 2319 of file ext4_extents.c.

2321{
2322 struct ext4_extent_header *eh;
2323
2324 eh = ext_inode_hdr(inode);
2325 eh->eh_depth = 0;
2326 eh->eh_entries = 0;
2330 return 0;

Referenced by Ext2CreateInode(), Ext2DoExtentExpand(), and Ext2MapExtent().

◆ ext4_ext_truncate()

int ext4_ext_truncate ( void icb,
struct inode inode,
unsigned long  start 
)

Definition at line 2519 of file ext4_extents.c.

2521{
2522 int ret = ext4_ext_remove_space(icb, inode, start);
2523
2524 /* Save modifications on i_blocks field of the inode. */
2525 if (!ret)
2527
2528 return ret;
int ext4_ext_remove_space(void *icb, struct inode *inode, unsigned long start)
int ret

Referenced by Ext2TruncateExtent().

◆ ext4_ext_try_to_merge()

static void ext4_ext_try_to_merge ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path,
struct ext4_extent ex 
)
static

Definition at line 1623 of file ext4_extents.c.

1627 {
1628 struct ext4_extent_header *eh;
1629 unsigned int depth;
1630 int merge_done = 0;
1631
1633 BUG_ON(path[depth].p_hdr == NULL);
1634 eh = path[depth].p_hdr;
1635
1636 if (ex > EXT_FIRST_EXTENT(eh))
1637 merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1);
1638
1639 if (!merge_done)
1641
static void ext4_ext_try_to_merge_up(void *icb, handle_t *handle, struct inode *inode, struct ext4_ext_path *path)
static int ext4_ext_try_to_merge_right(struct inode *inode, struct ext4_ext_path *path, struct ext4_extent *ex)

Referenced by ext4_ext_insert_extent(), and ext4_split_extent_at().

◆ ext4_ext_try_to_merge_right()

static int ext4_ext_try_to_merge_right ( struct inode inode,
struct ext4_ext_path path,
struct ext4_extent ex 
)
static

Definition at line 1538 of file ext4_extents.c.

1542{
1543 struct ext4_extent_header *eh;
1544 unsigned int depth, len;
1545 int merge_done = 0, unwritten;
1546
1548 assert(path[depth].p_hdr != NULL);
1549 eh = path[depth].p_hdr;
1550
1551 while (ex < EXT_LAST_EXTENT(eh)) {
1553 break;
1554 /* merge with next extent! */
1555 unwritten = ext4_ext_is_unwritten(ex);
1558 if (unwritten)
1560
1561 if (ex + 1 < EXT_LAST_EXTENT(eh)) {
1562 len = (EXT_LAST_EXTENT(eh) - ex - 1)
1563 * sizeof(struct ext4_extent);
1564 memmove(ex + 1, ex + 2, len);
1565 }
1566 le16_add_cpu(&eh->eh_entries, -1);
1567 merge_done = 1;
1568 if (!eh->eh_entries)
1569 EXT4_ERROR_INODE(inode, "eh->eh_entries = 0!");
1570 }
1571
1572 return merge_done;

Referenced by ext4_ext_try_to_merge().

◆ ext4_ext_try_to_merge_up()

static void ext4_ext_try_to_merge_up ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path path 
)
static

Definition at line 1578 of file ext4_extents.c.

1582{
1583 size_t s;
1584 unsigned max_root = ext4_ext_space_root(inode, 0);
1586
1587 if ((path[0].p_depth != 1) ||
1588 (le16_to_cpu(path[0].p_hdr->eh_entries) != 1) ||
1589 (le16_to_cpu(path[1].p_hdr->eh_entries) > max_root))
1590 return;
1591
1592 /*
1593 * We need to modify the block allocation bitmap and the block
1594 * group descriptor to release the extent tree block. If we
1595 * can't get the journal credits, give up.
1596 */
1597 if (ext4_journal_extend(icb, handle, 2))
1598 return;
1599
1600 /*
1601 * Copy the extent data up to the inode
1602 */
1603 blk = ext4_idx_pblock(path[0].p_idx);
1604 s = le16_to_cpu(path[1].p_hdr->eh_entries) *
1605 sizeof(struct ext4_extent_idx);
1606 s += sizeof(struct ext4_extent_header);
1607
1608 path[1].p_maxdepth = path[0].p_maxdepth;
1609 memcpy(path[0].p_hdr, path[1].p_hdr, s);
1610 path[0].p_depth = 0;
1611 path[0].p_ext = EXT_FIRST_EXTENT(path[0].p_hdr) +
1612 (path[1].p_ext - EXT_FIRST_EXTENT(path[1].p_hdr));
1613 path[0].p_hdr->eh_max = cpu_to_le16(max_root);
1614
1615 extents_brelse(path[1].p_bh);
#define EXT4_FREE_BLOCKS_FORGET
Definition: ext4.h:68
static int ext4_journal_extend(void *icb, handle_t *handle, int nblocks)
Definition: ext4_jbd2.h:60
GLdouble s
Definition: gl.h:2039
#define blk
Definition: linetest.c:70
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by ext4_ext_try_to_merge().

◆ ext4_ext_zeroout()

static int ext4_ext_zeroout ( struct inode inode,
struct ext4_extent ex 
)
static

Definition at line 1880 of file ext4_extents.c.

1882{
1883 ext4_fsblk_t ee_pblock;
1884 unsigned int ee_len;
1885 int ret;
1886
1888 ee_pblock = ext4_ext_pblock(ex);
1889
1890 ret = 0;
1891
1892 return ret;

Referenced by ext4_split_extent_at().

◆ ext4_extent_block_csum_set()

static void ext4_extent_block_csum_set ( struct inode inode,
struct ext4_extent_header eh 
)
static

Definition at line 246 of file ext4_extents.c.

249{
250 struct ext4_extent_tail *tail;
251
253 tail->et_checksum = ext4_ext_block_csum(
254 inode, eh);

Referenced by __ext4_ext_dirty(), ext4_ext_grow_indepth(), and ext4_ext_split().

◆ ext4_find_extent()

struct ext4_ext_path * ext4_find_extent ( struct inode inode,
ext4_lblk_t  block,
struct ext4_ext_path **  orig_path,
int  flags 
)

Definition at line 644 of file ext4_extents.c.

647{
648 struct ext4_extent_header *eh;
649 struct buffer_head *bh;
650 struct ext4_ext_path *path = orig_path ? *orig_path : NULL;
651 short int depth, i, ppos = 0;
652 int ret;
653
654 eh = ext_inode_hdr(inode);
656
657 if (path) {
659 if (depth > path[0].p_maxdepth) {
660 kfree(path);
661 *orig_path = path = NULL;
662 }
663 }
664 if (!path) {
665 /* account possible depth increase */
666 path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2),
667 GFP_NOFS);
668 if (unlikely(!path))
669 return ERR_PTR(-ENOMEM);
670 path[0].p_maxdepth = depth + 1;
671 }
672 path[0].p_hdr = eh;
673 path[0].p_bh = NULL;
674
675 i = depth;
676 /* walk through the tree */
677 while (i) {
678 ext_debug("depth %d: num %d, max %d\n",
679 ppos, le16_to_cpu(eh->eh_entries), le16_to_cpu(eh->eh_max));
680
682 path[ppos].p_block = ext4_idx_pblock(path[ppos].p_idx);
683 path[ppos].p_depth = i;
684 path[ppos].p_ext = NULL;
685
687 flags);
688 if (unlikely(IS_ERR(bh))) {
689 ret = PTR_ERR(bh);
690 goto err;
691 }
692
693 eh = ext_block_hdr(bh);
694 ppos++;
695 if (unlikely(ppos > depth)) {
696 extents_brelse(bh);
698 "ppos %d > depth %d", ppos, depth);
699 ret = -EIO;
700 goto err;
701 }
702 path[ppos].p_bh = bh;
703 path[ppos].p_hdr = eh;
704 }
705
706 path[ppos].p_depth = i;
707 path[ppos].p_ext = NULL;
708 path[ppos].p_idx = NULL;
709
710 /* find extent */
712 /* if not an empty leaf */
713 if (path[ppos].p_ext)
714 path[ppos].p_block = ext4_ext_pblock(path[ppos].p_ext);
715
717
718 return path;
719
720err:
722 if (path) {
723 kfree(path);
724 if (orig_path)
725 *orig_path = NULL;
726 }
727 return ERR_PTR(ret);
#define ext4_ext_show_path(inode, path)
Definition: ext4_extents.c:638
static void ext4_ext_binsearch(struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
Definition: ext4_extents.c:504
static void ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block)
Definition: ext4_extents.c:445
int p_maxdepth
Definition: ext4_ext.h:73
struct ext4_extent * p_ext
Definition: ext4_ext.h:74
ext4_fsblk_t p_block
Definition: ext4_ext.h:71

Referenced by ext4_ext_create_new_leaf(), ext4_ext_get_blocks(), and ext4_ext_insert_extent().

◆ ext4_force_split_extent_at()

static int ext4_force_split_extent_at ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path **  ppath,
ext4_lblk_t  lblk,
int  nofail 
)
inlinestatic

Definition at line 265 of file ext4_extents.c.

269{
270 struct ext4_ext_path *path = *ppath;
271 int unwritten = ext4_ext_is_unwritten(path[path->p_depth].p_ext);
272
273 return ext4_split_extent_at(icb, handle, inode, ppath, lblk, unwritten ?
#define EXT4_EX_NOCACHE
Definition: ext4.h:61

◆ ext4_free_blocks()

static void ext4_free_blocks ( void icb,
handle_t handle,
struct inode inode,
void fake,
ext4_fsblk_t  block,
int  count,
int  flags 
)
static

Definition at line 77 of file ext4_extents.c.

80{
82 inode->i_blocks -= count * (inode->i_sb->s_blocksize >> 9);
83 return;
NTSTATUS Ext2FreeBlock(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG Block, IN ULONG Number)
Definition: generic.c:1217
GLuint GLuint GLsizei count
Definition: gl.h:1545
__u64 i_blocks
Definition: fs.h:85

Referenced by ext4_ext_get_blocks(), ext4_ext_rm_idx(), ext4_ext_split(), ext4_ext_try_to_merge_up(), and ext4_remove_blocks().

◆ ext4_inode_to_goal_block()

static ext4_fsblk_t ext4_inode_to_goal_block ( struct inode inode)
inlinestatic

Definition at line 45 of file ext4_extents.c.

47{
49 Vcb = inode->i_sb->s_priv;
50 return (inode->i_ino - 1) / BLOCKS_PER_GROUP;
#define BLOCKS_PER_GROUP
Definition: ext2fs.h:100
#define Vcb
Definition: cdprocs.h:1415
__u32 i_ino
Definition: fs.h:79

Referenced by ext4_ext_find_goal(), and ext4_ext_grow_indepth().

◆ ext4_new_meta_blocks()

static ext4_fsblk_t ext4_new_meta_blocks ( void icb,
handle_t handle,
struct inode inode,
ext4_fsblk_t  goal,
unsigned int  flags,
unsigned long count,
int errp 
)
static

Definition at line 52 of file ext4_extents.c.

57{
59 ULONG blockcnt = (count)?*count:1;
60 ULONG block = 0;
61
63 inode->i_sb->s_priv,
64 0, goal,
65 &block,
66 &blockcnt);
67 if (count)
68 *count = blockcnt;
69
70 if (!NT_SUCCESS(status)) {
71 *errp = Ext2LinuxError(status);
72 return 0;
73 }
74 inode->i_blocks += (blockcnt * (inode->i_sb->s_blocksize >> 9));
75 return block;
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS Ext2NewBlock(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN ULONG GroupHint, IN ULONG BlockHint, OUT PULONG Block, IN OUT PULONG Number)
Definition: generic.c:1008
int Ext2LinuxError(NTSTATUS Status)
Definition: misc.c:304
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59

Referenced by ext4_ext_get_blocks(), ext4_ext_grow_indepth(), and ext4_ext_new_meta_block().

◆ ext4_remove_blocks()

static int ext4_remove_blocks ( void icb,
handle_t handle,
struct inode inode,
struct ext4_extent ex,
unsigned long  from,
unsigned long  to 
)
static

Definition at line 1894 of file ext4_extents.c.

1898{
1899 struct buffer_head *bh;
1900 int i;
1901
1902 if (from >= le32_to_cpu(ex->ee_block)
1903 && to == le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex) - 1) {
1904 /* tail removal */
1905 unsigned long num, start;
1906 num = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex) - from;
1909 } else if (from == le32_to_cpu(ex->ee_block)
1910 && to <= le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex) - 1) {
1911 } else {
1912 }
1913 return 0;
CardRegion * from
Definition: spigame.cpp:19

Referenced by ext4_ext_rm_leaf().

◆ ext4_split_extent_at()

static int ext4_split_extent_at ( void icb,
handle_t handle,
struct inode inode,
struct ext4_ext_path **  ppath,
ext4_lblk_t  split,
int  split_flag,
int  flags 
)
static

Definition at line 2067 of file ext4_extents.c.

2074{
2075 struct ext4_ext_path *path = *ppath;
2076 ext4_fsblk_t newblock;
2078 struct ext4_extent *ex, newex, orig_ex, zero_ex;
2079 struct ext4_extent *ex2 = NULL;
2080 unsigned int ee_len, depth;
2081 int err = 0;
2082
2084
2086 ex = path[depth].p_ext;
2087 ee_block = le32_to_cpu(ex->ee_block);
2089 newblock = split - ee_block + ext4_ext_pblock(ex);
2090
2091 BUG_ON(split < ee_block || split >= (ee_block + ee_len));
2092
2094 if (err)
2095 goto out;
2096
2097 if (split == ee_block) {
2098 /*
2099 * case b: block @split is the block that the extent begins with
2100 * then we just change the state of the extent, and splitting
2101 * is not needed.
2102 */
2103 if (split_flag & EXT4_EXT_MARK_UNWRIT2)
2105 else
2107
2110
2111 err = ext4_ext_dirty(icb, handle, inode, path + path->p_depth);
2112 goto out;
2113 }
2114
2115 /* case a */
2116 memcpy(&orig_ex, ex, sizeof(orig_ex));
2117 ex->ee_len = cpu_to_le16(split - ee_block);
2118 if (split_flag & EXT4_EXT_MARK_UNWRIT1)
2120
2121 /*
2122 * path may lead to new leaf, not to original leaf any more
2123 * after ext4_ext_insert_extent() returns,
2124 */
2126 if (err)
2127 goto fix_extent_len;
2128
2129 ex2 = &newex;
2130 ex2->ee_block = cpu_to_le32(split);
2131 ex2->ee_len = cpu_to_le16(ee_len - (split - ee_block));
2132 ext4_ext_store_pblock(ex2, newblock);
2133 if (split_flag & EXT4_EXT_MARK_UNWRIT2)
2135
2136 err = ext4_ext_insert_extent(icb, handle, inode, ppath, &newex, flags);
2137 if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
2138 if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
2139 if (split_flag & EXT4_EXT_DATA_VALID1) {
2140 err = ext4_ext_zeroout(inode, ex2);
2141 zero_ex.ee_block = ex2->ee_block;
2142 zero_ex.ee_len = cpu_to_le16(
2144 ext4_ext_store_pblock(&zero_ex,
2145 ext4_ext_pblock(ex2));
2146 } else {
2148 zero_ex.ee_block = ex->ee_block;
2149 zero_ex.ee_len = cpu_to_le16(
2151 ext4_ext_store_pblock(&zero_ex,
2153 }
2154 } else {
2155 err = ext4_ext_zeroout(inode, &orig_ex);
2156 zero_ex.ee_block = orig_ex.ee_block;
2157 zero_ex.ee_len = cpu_to_le16(
2158 ext4_ext_get_actual_len(&orig_ex));
2159 ext4_ext_store_pblock(&zero_ex,
2160 ext4_ext_pblock(&orig_ex));
2161 }
2162
2163 if (err)
2164 goto fix_extent_len;
2165 /* update the extent length and mark as initialized */
2166 ex->ee_len = cpu_to_le16(ee_len);
2168 err = ext4_ext_dirty(icb, handle, inode, path + path->p_depth);
2169 if (err)
2170 goto fix_extent_len;
2171
2172 goto out;
2173 } else if (err)
2174 goto fix_extent_len;
2175
2176out:
2178 return err;
2179
2180fix_extent_len:
2181 ex->ee_len = orig_ex.ee_len;
2182 ext4_ext_dirty(icb, handle, inode, path + path->p_depth);
2183 return err;
#define ENOSPC
Definition: errno.h:34
static void ext4_ext_mark_initialized(struct ext4_extent *ext)
Definition: ext4_ext.h:158
static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
#define EXT4_EXT_MAY_ZEROOUT
Definition: ext4_extents.c:34
#define EXT4_EXT_DATA_VALID2
Definition: ext4_extents.c:39
#define EXT4_EXT_DATA_VALID1
Definition: ext4_extents.c:38

Referenced by ext4_ext_convert_to_initialized(), and ext4_force_split_extent_at().

◆ ext_debug()

◆ get_default_free_blocks_flags()

static int get_default_free_blocks_flags ( struct inode inode)
inlinestatic

Definition at line 1874 of file ext4_extents.c.

1876{
1877 return 0;

Referenced by ext4_ext_get_blocks().