1
0
Fork 0

reiserfs: cleanup, reformat comments to normal kernel style

This patch reformats comments in the reiserfs code to fit in 80 columns and
to follow the style rules.

There is no functional change but it helps make my eyes bleed less.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Jan Kara <jack@suse.cz>
hifive-unleashed-5.1
Jeff Mahoney 2014-04-23 10:00:36 -04:00 committed by Jan Kara
parent 4cf5f7addf
commit 098297b27d
23 changed files with 5112 additions and 3299 deletions

View File

@ -50,8 +50,10 @@ static inline void get_bit_address(struct super_block *s,
unsigned int *bmap_nr, unsigned int *bmap_nr,
unsigned int *offset) unsigned int *offset)
{ {
/* It is in the bitmap block number equal to the block /*
* number divided by the number of bits in a block. */ * It is in the bitmap block number equal to the block
* number divided by the number of bits in a block.
*/
*bmap_nr = block >> (s->s_blocksize_bits + 3); *bmap_nr = block >> (s->s_blocksize_bits + 3);
/* Within that bitmap block it is located at bit offset *offset. */ /* Within that bitmap block it is located at bit offset *offset. */
*offset = block & ((s->s_blocksize << 3) - 1); *offset = block & ((s->s_blocksize << 3) - 1);
@ -71,8 +73,10 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
get_bit_address(s, block, &bmap, &offset); get_bit_address(s, block, &bmap, &offset);
/* Old format filesystem? Unlikely, but the bitmaps are all up front so /*
* we need to account for it. */ * Old format filesystem? Unlikely, but the bitmaps are all
* up front so we need to account for it.
*/
if (unlikely(test_bit(REISERFS_OLD_FORMAT, if (unlikely(test_bit(REISERFS_OLD_FORMAT,
&(REISERFS_SB(s)->s_properties)))) { &(REISERFS_SB(s)->s_properties)))) {
b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
@ -108,8 +112,11 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
return 1; return 1;
} }
/* searches in journal structures for a given block number (bmap, off). If block /*
is found in reiserfs journal it suggests next free block candidate to test. */ * Searches in journal structures for a given block number (bmap, off).
* If block is found in reiserfs journal it suggests next free block
* candidate to test.
*/
static inline int is_block_in_journal(struct super_block *s, unsigned int bmap, static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
int off, int *next) int off, int *next)
{ {
@ -120,7 +127,7 @@ static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
*next = tmp; *next = tmp;
PROC_INFO_INC(s, scan_bitmap.in_journal_hint); PROC_INFO_INC(s, scan_bitmap.in_journal_hint);
} else { } else {
(*next) = off + 1; /* inc offset to avoid looping. */ (*next) = off + 1; /* inc offset to avoid looping. */
PROC_INFO_INC(s, scan_bitmap.in_journal_nohint); PROC_INFO_INC(s, scan_bitmap.in_journal_nohint);
} }
PROC_INFO_INC(s, scan_bitmap.retry); PROC_INFO_INC(s, scan_bitmap.retry);
@ -129,8 +136,10 @@ static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
return 0; return 0;
} }
/* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap /*
* block; */ * Searches for a window of zero bits with given minimum and maximum
* lengths in one bitmap block
*/
static int scan_bitmap_block(struct reiserfs_transaction_handle *th, static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
unsigned int bmap_n, int *beg, int boundary, unsigned int bmap_n, int *beg, int boundary,
int min, int max, int unfm) int min, int max, int unfm)
@ -146,10 +155,6 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of " RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of "
"range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1); "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1);
PROC_INFO_INC(s, scan_bitmap.bmap); PROC_INFO_INC(s, scan_bitmap.bmap);
/* this is unclear and lacks comments, explain how journal bitmaps
work here for the reader. Convey a sense of the design here. What
is a window? */
/* - I mean `a window of zero bits' as in description of this function - Zam. */
if (!bi) { if (!bi) {
reiserfs_error(s, "jdm-4055", "NULL bitmap info pointer " reiserfs_error(s, "jdm-4055", "NULL bitmap info pointer "
@ -165,15 +170,18 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
cont: cont:
if (bi->free_count < min) { if (bi->free_count < min) {
brelse(bh); brelse(bh);
return 0; // No free blocks in this bitmap return 0; /* No free blocks in this bitmap */
} }
/* search for a first zero bit -- beginning of a window */ /* search for a first zero bit -- beginning of a window */
*beg = reiserfs_find_next_zero_le_bit *beg = reiserfs_find_next_zero_le_bit
((unsigned long *)(bh->b_data), boundary, *beg); ((unsigned long *)(bh->b_data), boundary, *beg);
if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block /*
* cannot contain a zero window of minimum size */ * search for a zero bit fails or the rest of bitmap block
* cannot contain a zero window of minimum size
*/
if (*beg + min > boundary) {
brelse(bh); brelse(bh);
return 0; return 0;
} }
@ -187,37 +195,63 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
next = end; next = end;
break; break;
} }
/* finding the other end of zero bit window requires looking into journal structures (in
* case of searching for free blocks for unformatted nodes) */ /*
* finding the other end of zero bit window requires
* looking into journal structures (in case of
* searching for free blocks for unformatted nodes)
*/
if (unfm && is_block_in_journal(s, bmap_n, end, &next)) if (unfm && is_block_in_journal(s, bmap_n, end, &next))
break; break;
} }
/* now (*beg) points to beginning of zero bits window, /*
* (end) points to one bit after the window end */ * now (*beg) points to beginning of zero bits window,
if (end - *beg >= min) { /* it seems we have found window of proper size */ * (end) points to one bit after the window end
*/
/* found window of proper size */
if (end - *beg >= min) {
int i; int i;
reiserfs_prepare_for_journal(s, bh, 1); reiserfs_prepare_for_journal(s, bh, 1);
/* try to set all blocks used checking are they still free */ /*
* try to set all blocks used checking are
* they still free
*/
for (i = *beg; i < end; i++) { for (i = *beg; i < end; i++) {
/* It seems that we should not check in journal again. */ /* Don't check in journal again. */
if (reiserfs_test_and_set_le_bit if (reiserfs_test_and_set_le_bit
(i, bh->b_data)) { (i, bh->b_data)) {
/* bit was set by another process /*
* while we slept in prepare_for_journal() */ * bit was set by another process while
* we slept in prepare_for_journal()
*/
PROC_INFO_INC(s, scan_bitmap.stolen); PROC_INFO_INC(s, scan_bitmap.stolen);
if (i >= *beg + min) { /* we can continue with smaller set of allocated blocks,
* if length of this set is more or equal to `min' */ /*
* we can continue with smaller set
* of allocated blocks, if length of
* this set is more or equal to `min'
*/
if (i >= *beg + min) {
end = i; end = i;
break; break;
} }
/* otherwise we clear all bit were set ... */
/*
* otherwise we clear all bit
* were set ...
*/
while (--i >= *beg) while (--i >= *beg)
reiserfs_clear_le_bit reiserfs_clear_le_bit
(i, bh->b_data); (i, bh->b_data);
reiserfs_restore_prepared_buffer(s, bh); reiserfs_restore_prepared_buffer(s, bh);
*beg = org; *beg = org;
/* ... and search again in current block from beginning */
/*
* Search again in current block
* from beginning
*/
goto cont; goto cont;
} }
} }
@ -268,11 +302,13 @@ static inline int block_group_used(struct super_block *s, u32 id)
int bm = bmap_hash_id(s, id); int bm = bmap_hash_id(s, id);
struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm]; struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm];
/* If we don't have cached information on this bitmap block, we're /*
* If we don't have cached information on this bitmap block, we're
* going to have to load it later anyway. Loading it here allows us * going to have to load it later anyway. Loading it here allows us
* to make a better decision. This favors long-term performance gain * to make a better decision. This favors long-term performance gain
* with a better on-disk layout vs. a short term gain of skipping the * with a better on-disk layout vs. a short term gain of skipping the
* read and potentially having a bad placement. */ * read and potentially having a bad placement.
*/
if (info->free_count == UINT_MAX) { if (info->free_count == UINT_MAX) {
struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
brelse(bh); brelse(bh);
@ -305,17 +341,16 @@ __le32 reiserfs_choose_packing(struct inode * dir)
return packing; return packing;
} }
/* Tries to find contiguous zero bit window (given size) in given region of /*
* bitmap and place new blocks there. Returns number of allocated blocks. */ * Tries to find contiguous zero bit window (given size) in given region of
* bitmap and place new blocks there. Returns number of allocated blocks.
*/
static int scan_bitmap(struct reiserfs_transaction_handle *th, static int scan_bitmap(struct reiserfs_transaction_handle *th,
b_blocknr_t * start, b_blocknr_t finish, b_blocknr_t * start, b_blocknr_t finish,
int min, int max, int unfm, sector_t file_block) int min, int max, int unfm, sector_t file_block)
{ {
int nr_allocated = 0; int nr_allocated = 0;
struct super_block *s = th->t_super; struct super_block *s = th->t_super;
/* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
* - Hans, it is not a block number - Zam. */
unsigned int bm, off; unsigned int bm, off;
unsigned int end_bm, end_off; unsigned int end_bm, end_off;
unsigned int off_max = s->s_blocksize << 3; unsigned int off_max = s->s_blocksize << 3;
@ -323,8 +358,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id); BUG_ON(!th->t_trans_id);
PROC_INFO_INC(s, scan_bitmap.call); PROC_INFO_INC(s, scan_bitmap.call);
/* No point in looking for more free blocks */
if (SB_FREE_BLOCKS(s) <= 0) if (SB_FREE_BLOCKS(s) <= 0)
return 0; // No point in looking for more free blocks return 0;
get_bit_address(s, *start, &bm, &off); get_bit_address(s, *start, &bm, &off);
get_bit_address(s, finish, &end_bm, &end_off); get_bit_address(s, finish, &end_bm, &end_off);
@ -333,7 +370,8 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th,
if (end_bm > reiserfs_bmap_count(s)) if (end_bm > reiserfs_bmap_count(s))
end_bm = reiserfs_bmap_count(s); end_bm = reiserfs_bmap_count(s);
/* When the bitmap is more than 10% free, anyone can allocate. /*
* When the bitmap is more than 10% free, anyone can allocate.
* When it's less than 10% free, only files that already use the * When it's less than 10% free, only files that already use the
* bitmap are allowed. Once we pass 80% full, this restriction * bitmap are allowed. Once we pass 80% full, this restriction
* is lifted. * is lifted.
@ -532,7 +570,8 @@ int reiserfs_parse_alloc_options(struct super_block *s, char *options)
{ {
char *this_char, *value; char *this_char, *value;
REISERFS_SB(s)->s_alloc_options.bits = 0; /* clear default settings */ /* clear default settings */
REISERFS_SB(s)->s_alloc_options.bits = 0;
while ((this_char = strsep(&options, ":")) != NULL) { while ((this_char = strsep(&options, ":")) != NULL) {
if ((value = strchr(this_char, '=')) != NULL) if ((value = strchr(this_char, '=')) != NULL)
@ -733,7 +772,7 @@ static inline void new_hashed_relocation(reiserfs_blocknr_hint_t * hint)
hash_in = (char *)&hint->key.k_dir_id; hash_in = (char *)&hint->key.k_dir_id;
} else { } else {
if (!hint->inode) { if (!hint->inode) {
//hint->search_start = hint->beg; /*hint->search_start = hint->beg;*/
hash_in = (char *)&hint->key.k_dir_id; hash_in = (char *)&hint->key.k_dir_id;
} else } else
if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super)) if (TEST_OPTION(displace_based_on_dirid, hint->th->t_super))
@ -786,7 +825,8 @@ static void oid_groups(reiserfs_blocknr_hint_t * hint)
dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id); dirid = le32_to_cpu(INODE_PKEY(hint->inode)->k_dir_id);
/* keep the root dir and it's first set of subdirs close to /*
* keep the root dir and it's first set of subdirs close to
* the start of the disk * the start of the disk
*/ */
if (dirid <= 2) if (dirid <= 2)
@ -800,7 +840,8 @@ static void oid_groups(reiserfs_blocknr_hint_t * hint)
} }
} }
/* returns 1 if it finds an indirect item and gets valid hint info /*
* returns 1 if it finds an indirect item and gets valid hint info
* from it, otherwise 0 * from it, otherwise 0
*/ */
static int get_left_neighbor(reiserfs_blocknr_hint_t * hint) static int get_left_neighbor(reiserfs_blocknr_hint_t * hint)
@ -812,8 +853,11 @@ static int get_left_neighbor(reiserfs_blocknr_hint_t * hint)
__le32 *item; __le32 *item;
int ret = 0; int ret = 0;
if (!hint->path) /* reiserfs code can call this function w/o pointer to path /*
* structure supplied; then we rely on supplied search_start */ * reiserfs code can call this function w/o pointer to path
* structure supplied; then we rely on supplied search_start
*/
if (!hint->path)
return 0; return 0;
path = hint->path; path = hint->path;
@ -825,12 +869,13 @@ static int get_left_neighbor(reiserfs_blocknr_hint_t * hint)
hint->search_start = bh->b_blocknr; hint->search_start = bh->b_blocknr;
/*
* for indirect item: go to left and look for the first non-hole entry
* in the indirect item
*/
if (!hint->formatted_node && is_indirect_le_ih(ih)) { if (!hint->formatted_node && is_indirect_le_ih(ih)) {
/* for indirect item: go to left and look for the first non-hole entry
in the indirect item */
if (pos_in_item == I_UNFM_NUM(ih)) if (pos_in_item == I_UNFM_NUM(ih))
pos_in_item--; pos_in_item--;
// pos_in_item = I_UNFM_NUM (ih) - 1;
while (pos_in_item >= 0) { while (pos_in_item >= 0) {
int t = get_block_num(item, pos_in_item); int t = get_block_num(item, pos_in_item);
if (t) { if (t) {
@ -846,10 +891,12 @@ static int get_left_neighbor(reiserfs_blocknr_hint_t * hint)
return ret; return ret;
} }
/* should be, if formatted node, then try to put on first part of the device /*
specified as number of percent with mount option device, else try to put * should be, if formatted node, then try to put on first part of the device
on last of device. This is not to say it is good code to do so, * specified as number of percent with mount option device, else try to put
but the effect should be measured. */ * on last of device. This is not to say it is good code to do so,
* but the effect should be measured.
*/
static inline void set_border_in_hint(struct super_block *s, static inline void set_border_in_hint(struct super_block *s,
reiserfs_blocknr_hint_t * hint) reiserfs_blocknr_hint_t * hint)
{ {
@ -975,21 +1022,27 @@ static void determine_search_start(reiserfs_blocknr_hint_t * hint,
set_border_in_hint(s, hint); set_border_in_hint(s, hint);
#ifdef DISPLACE_NEW_PACKING_LOCALITIES #ifdef DISPLACE_NEW_PACKING_LOCALITIES
/* whenever we create a new directory, we displace it. At first we will /*
hash for location, later we might look for a moderately empty place for * whenever we create a new directory, we displace it. At first
it */ * we will hash for location, later we might look for a moderately
* empty place for it
*/
if (displacing_new_packing_localities(s) if (displacing_new_packing_localities(s)
&& hint->th->displace_new_blocks) { && hint->th->displace_new_blocks) {
displace_new_packing_locality(hint); displace_new_packing_locality(hint);
/* we do not continue determine_search_start, /*
* if new packing locality is being displaced */ * we do not continue determine_search_start,
* if new packing locality is being displaced
*/
return; return;
} }
#endif #endif
/* all persons should feel encouraged to add more special cases here and /*
* test them */ * all persons should feel encouraged to add more special cases
* here and test them
*/
if (displacing_large_files(s) && !hint->formatted_node if (displacing_large_files(s) && !hint->formatted_node
&& this_blocknr_allocation_would_make_it_a_large_file(hint)) { && this_blocknr_allocation_would_make_it_a_large_file(hint)) {
@ -997,8 +1050,10 @@ static void determine_search_start(reiserfs_blocknr_hint_t * hint,
return; return;
} }
/* if none of our special cases is relevant, use the left neighbor in the /*
tree order of the new node we are allocating for */ * if none of our special cases is relevant, use the left
* neighbor in the tree order of the new node we are allocating for
*/
if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes, s)) { if (hint->formatted_node && TEST_OPTION(hashed_formatted_nodes, s)) {
hash_formatted_node(hint); hash_formatted_node(hint);
return; return;
@ -1006,10 +1061,13 @@ static void determine_search_start(reiserfs_blocknr_hint_t * hint,
unfm_hint = get_left_neighbor(hint); unfm_hint = get_left_neighbor(hint);
/* Mimic old block allocator behaviour, that is if VFS allowed for preallocation, /*
new blocks are displaced based on directory ID. Also, if suggested search_start * Mimic old block allocator behaviour, that is if VFS allowed for
is less than last preallocated block, we start searching from it, assuming that * preallocation, new blocks are displaced based on directory ID.
HDD dataflow is faster in forward direction */ * Also, if suggested search_start is less than last preallocated
* block, we start searching from it, assuming that HDD dataflow
* is faster in forward direction
*/
if (TEST_OPTION(old_way, s)) { if (TEST_OPTION(old_way, s)) {
if (!hint->formatted_node) { if (!hint->formatted_node) {
if (!reiserfs_hashed_relocation(s)) if (!reiserfs_hashed_relocation(s))
@ -1038,11 +1096,13 @@ static void determine_search_start(reiserfs_blocknr_hint_t * hint,
TEST_OPTION(old_hashed_relocation, s)) { TEST_OPTION(old_hashed_relocation, s)) {
old_hashed_relocation(hint); old_hashed_relocation(hint);
} }
/* new_hashed_relocation works with both formatted/unformatted nodes */ /* new_hashed_relocation works with both formatted/unformatted nodes */
if ((!unfm_hint || hint->formatted_node) && if ((!unfm_hint || hint->formatted_node) &&
TEST_OPTION(new_hashed_relocation, s)) { TEST_OPTION(new_hashed_relocation, s)) {
new_hashed_relocation(hint); new_hashed_relocation(hint);
} }
/* dirid grouping works only on unformatted nodes */ /* dirid grouping works only on unformatted nodes */
if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups, s)) { if (!unfm_hint && !hint->formatted_node && TEST_OPTION(dirid_groups, s)) {
dirid_groups(hint); dirid_groups(hint);
@ -1080,8 +1140,6 @@ static int determine_prealloc_size(reiserfs_blocknr_hint_t * hint)
return CARRY_ON; return CARRY_ON;
} }
/* XXX I know it could be merged with upper-level function;
but may be result function would be too complex. */
static inline int allocate_without_wrapping_disk(reiserfs_blocknr_hint_t * hint, static inline int allocate_without_wrapping_disk(reiserfs_blocknr_hint_t * hint,
b_blocknr_t * new_blocknrs, b_blocknr_t * new_blocknrs,
b_blocknr_t start, b_blocknr_t start,
@ -1109,7 +1167,10 @@ static inline int allocate_without_wrapping_disk(reiserfs_blocknr_hint_t * hint,
/* do we have something to fill prealloc. array also ? */ /* do we have something to fill prealloc. array also ? */
if (nr_allocated > 0) { if (nr_allocated > 0) {
/* it means prealloc_size was greater that 0 and we do preallocation */ /*
* it means prealloc_size was greater that 0 and
* we do preallocation
*/
list_add(&REISERFS_I(hint->inode)->i_prealloc_list, list_add(&REISERFS_I(hint->inode)->i_prealloc_list,
&SB_JOURNAL(hint->th->t_super)-> &SB_JOURNAL(hint->th->t_super)->
j_prealloc_list); j_prealloc_list);
@ -1177,7 +1238,8 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
start = 0; start = 0;
finish = hint->beg; finish = hint->beg;
break; break;
default: /* We've tried searching everywhere, not enough space */ default:
/* We've tried searching everywhere, not enough space */
/* Free the blocks */ /* Free the blocks */
if (!hint->formatted_node) { if (!hint->formatted_node) {
#ifdef REISERQUOTA_DEBUG #ifdef REISERQUOTA_DEBUG
@ -1262,8 +1324,11 @@ static int use_preallocated_list_if_available(reiserfs_blocknr_hint_t * hint,
return amount_needed; return amount_needed;
} }
int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t * hint, b_blocknr_t * new_blocknrs, int amount_needed, int reserved_by_us /* Amount of blocks we have int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t *hint,
already reserved */ ) b_blocknr_t *new_blocknrs,
int amount_needed,
/* Amount of blocks we have already reserved */
int reserved_by_us)
{ {
int initial_amount_needed = amount_needed; int initial_amount_needed = amount_needed;
int ret; int ret;
@ -1275,15 +1340,21 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t * hint, b_blocknr_t * new
return NO_DISK_SPACE; return NO_DISK_SPACE;
/* should this be if !hint->inode && hint->preallocate? */ /* should this be if !hint->inode && hint->preallocate? */
/* do you mean hint->formatted_node can be removed ? - Zam */ /* do you mean hint->formatted_node can be removed ? - Zam */
/* hint->formatted_node cannot be removed because we try to access /*
inode information here, and there is often no inode assotiated with * hint->formatted_node cannot be removed because we try to access
metadata allocations - green */ * inode information here, and there is often no inode associated with
* metadata allocations - green
*/
if (!hint->formatted_node && hint->preallocate) { if (!hint->formatted_node && hint->preallocate) {
amount_needed = use_preallocated_list_if_available amount_needed = use_preallocated_list_if_available
(hint, new_blocknrs, amount_needed); (hint, new_blocknrs, amount_needed);
if (amount_needed == 0) /* all blocknrs we need we got from
prealloc. list */ /*
* We have all the block numbers we need from the
* prealloc list
*/
if (amount_needed == 0)
return CARRY_ON; return CARRY_ON;
new_blocknrs += (initial_amount_needed - amount_needed); new_blocknrs += (initial_amount_needed - amount_needed);
} }
@ -1297,10 +1368,12 @@ int reiserfs_allocate_blocknrs(reiserfs_blocknr_hint_t * hint, b_blocknr_t * new
ret = blocknrs_and_prealloc_arrays_from_search_start ret = blocknrs_and_prealloc_arrays_from_search_start
(hint, new_blocknrs, amount_needed); (hint, new_blocknrs, amount_needed);
/* we used prealloc. list to fill (partially) new_blocknrs array. If final allocation fails we /*
* need to return blocks back to prealloc. list or just free them. -- Zam (I chose second * We used prealloc. list to fill (partially) new_blocknrs array.
* variant) */ * If final allocation fails we need to return blocks back to
* prealloc. list or just free them. -- Zam (I chose second
* variant)
*/
if (ret != CARRY_ON) { if (ret != CARRY_ON) {
while (amount_needed++ < initial_amount_needed) { while (amount_needed++ < initial_amount_needed) {
reiserfs_free_block(hint->th, hint->inode, reiserfs_free_block(hint->th, hint->inode,
@ -1339,8 +1412,10 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap; struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap;
struct buffer_head *bh; struct buffer_head *bh;
/* Way old format filesystems had the bitmaps packed up front. /*
* I doubt there are any of these left, but just in case... */ * Way old format filesystems had the bitmaps packed up front.
* I doubt there are any of these left, but just in case...
*/
if (unlikely(test_bit(REISERFS_OLD_FORMAT, if (unlikely(test_bit(REISERFS_OLD_FORMAT,
&(REISERFS_SB(sb)->s_properties)))) &(REISERFS_SB(sb)->s_properties))))
block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap; block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;

View File

@ -59,7 +59,10 @@ static inline bool is_privroot_deh(struct inode *dir, struct reiserfs_de_head *d
int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
{ {
struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */
/* key of current position in the directory (key of directory entry) */
struct cpu_key pos_key;
INITIALIZE_PATH(path_to_entry); INITIALIZE_PATH(path_to_entry);
struct buffer_head *bh; struct buffer_head *bh;
int item_num, entry_num; int item_num, entry_num;
@ -77,21 +80,28 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
reiserfs_check_lock_depth(inode->i_sb, "readdir"); reiserfs_check_lock_depth(inode->i_sb, "readdir");
/* form key for search the next directory entry using f_pos field of /*
file structure */ * form key for search the next directory entry using
* f_pos field of file structure
*/
make_cpu_key(&pos_key, inode, ctx->pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); make_cpu_key(&pos_key, inode, ctx->pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3);
next_pos = cpu_key_k_offset(&pos_key); next_pos = cpu_key_k_offset(&pos_key);
path_to_entry.reada = PATH_READA; path_to_entry.reada = PATH_READA;
while (1) { while (1) {
research: research:
/* search the directory item, containing entry with specified key */ /*
* search the directory item, containing entry with
* specified key
*/
search_res = search_res =
search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry, search_by_entry_key(inode->i_sb, &pos_key, &path_to_entry,
&de); &de);
if (search_res == IO_ERROR) { if (search_res == IO_ERROR) {
// FIXME: we could just skip part of directory which could /*
// not be read * FIXME: we could just skip part of directory
* which could not be read
*/
ret = -EIO; ret = -EIO;
goto out; goto out;
} }
@ -109,14 +119,20 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
"vs-9005 item_num == %d, item amount == %d", "vs-9005 item_num == %d, item amount == %d",
item_num, B_NR_ITEMS(bh)); item_num, B_NR_ITEMS(bh));
/* and entry must be not more than number of entries in the item */ /*
* and entry must be not more than number of entries
* in the item
*/
RFALSE(ih_entry_count(ih) < entry_num, RFALSE(ih_entry_count(ih) < entry_num,
"vs-9010: entry number is too big %d (%d)", "vs-9010: entry number is too big %d (%d)",
entry_num, ih_entry_count(ih)); entry_num, ih_entry_count(ih));
/*
* go through all entries in the directory item beginning
* from the entry, that has been found
*/
if (search_res == POSITION_FOUND if (search_res == POSITION_FOUND
|| entry_num < ih_entry_count(ih)) { || entry_num < ih_entry_count(ih)) {
/* go through all entries in the directory item beginning from the entry, that has been found */
struct reiserfs_de_head *deh = struct reiserfs_de_head *deh =
B_I_DEH(bh, ih) + entry_num; B_I_DEH(bh, ih) + entry_num;
@ -127,16 +143,18 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
ino_t d_ino; ino_t d_ino;
loff_t cur_pos = deh_offset(deh); loff_t cur_pos = deh_offset(deh);
/* it is hidden entry */
if (!de_visible(deh)) if (!de_visible(deh))
/* it is hidden entry */
continue; continue;
d_reclen = entry_length(bh, ih, entry_num); d_reclen = entry_length(bh, ih, entry_num);
d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh); d_name = B_I_DEH_ENTRY_FILE_NAME(bh, ih, deh);
if (d_reclen <= 0 || if (d_reclen <= 0 ||
d_name + d_reclen > bh->b_data + bh->b_size) { d_name + d_reclen > bh->b_data + bh->b_size) {
/* There is corrupted data in entry, /*
* We'd better stop here */ * There is corrupted data in entry,
* We'd better stop here
*/
pathrelse(&path_to_entry); pathrelse(&path_to_entry);
ret = -EIO; ret = -EIO;
goto out; goto out;
@ -145,10 +163,10 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
if (!d_name[d_reclen - 1]) if (!d_name[d_reclen - 1])
d_reclen = strlen(d_name); d_reclen = strlen(d_name);
/* too big to send back to VFS */
if (d_reclen > if (d_reclen >
REISERFS_MAX_NAME(inode->i_sb-> REISERFS_MAX_NAME(inode->i_sb->
s_blocksize)) { s_blocksize)) {
/* too big to send back to VFS */
continue; continue;
} }
@ -173,10 +191,14 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
goto research; goto research;
} }
} }
// Note, that we copy name to user space via temporary
// buffer (local_buf) because filldir will block if /*
// user space buffer is swapped out. At that time * Note, that we copy name to user space via
// entry can move to somewhere else * temporary buffer (local_buf) because
* filldir will block if user space buffer is
* swapped out. At that time entry can move to
* somewhere else
*/
memcpy(local_buf, d_name, d_reclen); memcpy(local_buf, d_name, d_reclen);
/* /*
@ -209,22 +231,26 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
} /* for */ } /* for */
} }
/* end of directory has been reached */
if (item_num != B_NR_ITEMS(bh) - 1) if (item_num != B_NR_ITEMS(bh) - 1)
// end of directory has been reached
goto end; goto end;
/* item we went through is last item of node. Using right /*
delimiting key check is it directory end */ * item we went through is last item of node. Using right
* delimiting key check is it directory end
*/
rkey = get_rkey(&path_to_entry, inode->i_sb); rkey = get_rkey(&path_to_entry, inode->i_sb);
if (!comp_le_keys(rkey, &MIN_KEY)) { if (!comp_le_keys(rkey, &MIN_KEY)) {
/* set pos_key to key, that is the smallest and greater /*
that key of the last entry in the item */ * set pos_key to key, that is the smallest and greater
* that key of the last entry in the item
*/
set_cpu_key_k_offset(&pos_key, next_pos); set_cpu_key_k_offset(&pos_key, next_pos);
continue; continue;
} }
/* end of directory has been reached */
if (COMP_SHORT_KEYS(rkey, &pos_key)) { if (COMP_SHORT_KEYS(rkey, &pos_key)) {
// end of directory has been reached
goto end; goto end;
} }
@ -248,9 +274,10 @@ static int reiserfs_readdir(struct file *file, struct dir_context *ctx)
return reiserfs_readdir_inode(file_inode(file), ctx); return reiserfs_readdir_inode(file_inode(file), ctx);
} }
/* compose directory item containing "." and ".." entries (entries are /*
not aligned to 4 byte boundary) */ * compose directory item containing "." and ".." entries (entries are
/* the last four params are LE */ * not aligned to 4 byte boundary)
*/
void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid, void make_empty_dir_item_v1(char *body, __le32 dirid, __le32 objid,
__le32 par_dirid, __le32 par_objid) __le32 par_dirid, __le32 par_objid)
{ {

View File

@ -2,18 +2,13 @@
* Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
*/ */
/* Now we have all buffers that must be used in balancing of the tree */ /*
/* Further calculations can not cause schedule(), and thus the buffer */ * Now we have all buffers that must be used in balancing of the tree
/* tree will be stable until the balancing will be finished */ * Further calculations can not cause schedule(), and thus the buffer
/* balance the tree according to the analysis made before, */ * tree will be stable until the balancing will be finished
/* and using buffers obtained after all above. */ * balance the tree according to the analysis made before,
* and using buffers obtained after all above.
/** */
** balance_leaf_when_delete
** balance_leaf
** do_balance
**
**/
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/time.h> #include <linux/time.h>
@ -68,35 +63,39 @@ inline void do_balance_mark_leaf_dirty(struct tree_balance *tb,
#define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty #define do_balance_mark_internal_dirty do_balance_mark_leaf_dirty
#define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty #define do_balance_mark_sb_dirty do_balance_mark_leaf_dirty
/* summary: /*
if deleting something ( tb->insert_size[0] < 0 ) * summary:
return(balance_leaf_when_delete()); (flag d handled here) * if deleting something ( tb->insert_size[0] < 0 )
else * return(balance_leaf_when_delete()); (flag d handled here)
if lnum is larger than 0 we put items into the left node * else
if rnum is larger than 0 we put items into the right node * if lnum is larger than 0 we put items into the left node
if snum1 is larger than 0 we put items into the new node s1 * if rnum is larger than 0 we put items into the right node
if snum2 is larger than 0 we put items into the new node s2 * if snum1 is larger than 0 we put items into the new node s1
Note that all *num* count new items being created. * if snum2 is larger than 0 we put items into the new node s2
* Note that all *num* count new items being created.
*
* It would be easier to read balance_leaf() if each of these summary
* lines was a separate procedure rather than being inlined. I think
* that there are many passages here and in balance_leaf_when_delete() in
* which two calls to one procedure can replace two passages, and it
* might save cache space and improve software maintenance costs to do so.
*
* Vladimir made the perceptive comment that we should offload most of
* the decision making in this function into fix_nodes/check_balance, and
* then create some sort of structure in tb that says what actions should
* be performed by do_balance.
*
* -Hans
*/
It would be easier to read balance_leaf() if each of these summary /*
lines was a separate procedure rather than being inlined. I think * Balance leaf node in case of delete or cut: insert_size[0] < 0
that there are many passages here and in balance_leaf_when_delete() in
which two calls to one procedure can replace two passages, and it
might save cache space and improve software maintenance costs to do so.
Vladimir made the perceptive comment that we should offload most of
the decision making in this function into fix_nodes/check_balance, and
then create some sort of structure in tb that says what actions should
be performed by do_balance.
-Hans */
/* Balance leaf node in case of delete or cut: insert_size[0] < 0
* *
* lnum, rnum can have values >= -1 * lnum, rnum can have values >= -1
* -1 means that the neighbor must be joined with S * -1 means that the neighbor must be joined with S
* 0 means that nothing should be done with the neighbor * 0 means that nothing should be done with the neighbor
* >0 means to shift entirely or partly the specified number of items to the neighbor * >0 means to shift entirely or partly the specified number of items
* to the neighbor
*/ */
static int balance_leaf_when_delete(struct tree_balance *tb, int flag) static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
{ {
@ -149,8 +148,16 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
case M_CUT:{ /* cut item in S[0] */ case M_CUT:{ /* cut item in S[0] */
if (is_direntry_le_ih(ih)) { if (is_direntry_le_ih(ih)) {
/* UFS unlink semantics are such that you can only delete one directory entry at a time. */ /*
/* when we cut a directory tb->insert_size[0] means number of entries to be cut (always 1) */ * UFS unlink semantics are such that you
* can only delete one directory entry at
* a time.
*/
/*
* when we cut a directory tb->insert_size[0]
* means number of entries to be cut (always 1)
*/
tb->insert_size[0] = -1; tb->insert_size[0] = -1;
leaf_cut_from_buffer(&bi, item_pos, pos_in_item, leaf_cut_from_buffer(&bi, item_pos, pos_in_item,
-tb->insert_size[0]); -tb->insert_size[0]);
@ -183,13 +190,22 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
"UNKNOWN"), flag); "UNKNOWN"), flag);
} }
/* the rule is that no shifting occurs unless by shifting a node can be freed */ /*
* the rule is that no shifting occurs unless by shifting
* a node can be freed
*/
n = B_NR_ITEMS(tbS0); n = B_NR_ITEMS(tbS0);
if (tb->lnum[0]) { /* L[0] takes part in balancing */ /* L[0] takes part in balancing */
if (tb->lnum[0] == -1) { /* L[0] must be joined with S[0] */ if (tb->lnum[0]) {
if (tb->rnum[0] == -1) { /* R[0] must be also joined with S[0] */ /* L[0] must be joined with S[0] */
if (tb->lnum[0] == -1) {
/* R[0] must be also joined with S[0] */
if (tb->rnum[0] == -1) {
if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) { if (tb->FR[0] == PATH_H_PPARENT(tb->tb_path, 0)) {
/* all contents of all the 3 buffers will be in L[0] */ /*
* all contents of all the 3 buffers
* will be in L[0]
*/
if (PATH_H_POSITION(tb->tb_path, 1) == 0 if (PATH_H_POSITION(tb->tb_path, 1) == 0
&& 1 < B_NR_ITEMS(tb->FR[0])) && 1 < B_NR_ITEMS(tb->FR[0]))
replace_key(tb, tb->CFL[0], replace_key(tb, tb->CFL[0],
@ -208,7 +224,10 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
return 0; return 0;
} }
/* all contents of all the 3 buffers will be in R[0] */ /*
* all contents of all the 3 buffers will
* be in R[0]
*/
leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1, leaf_move_items(LEAF_FROM_S_TO_R, tb, n, -1,
NULL); NULL);
leaf_move_items(LEAF_FROM_L_TO_R, tb, leaf_move_items(LEAF_FROM_L_TO_R, tb,
@ -233,7 +252,11 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag)
return 0; return 0;
} }
/* a part of contents of S[0] will be in L[0] and the rest part of S[0] will be in R[0] */
/*
* a part of contents of S[0] will be in L[0] and the
* rest part of S[0] will be in R[0]
*/
RFALSE((tb->lnum[0] + tb->rnum[0] < n) || RFALSE((tb->lnum[0] + tb->rnum[0] < n) ||
(tb->lnum[0] + tb->rnum[0] > n + 1), (tb->lnum[0] + tb->rnum[0] > n + 1),
@ -1178,9 +1201,7 @@ struct buffer_head *get_FEB(struct tree_balance *tb)
return tb->used[i]; return tb->used[i];
} }
/* This is now used because reiserfs_free_block has to be able to /* This is now used because reiserfs_free_block has to be able to schedule. */
** schedule.
*/
static void store_thrown(struct tree_balance *tb, struct buffer_head *bh) static void store_thrown(struct tree_balance *tb, struct buffer_head *bh)
{ {
int i; int i;
@ -1335,8 +1356,10 @@ static int check_before_balancing(struct tree_balance *tb)
"mount point."); "mount point.");
} }
/* double check that buffers that we will modify are unlocked. (fix_nodes should already have /*
prepped all of these for us). */ * double check that buffers that we will modify are unlocked.
* (fix_nodes should already have prepped all of these for us).
*/
if (tb->lnum[0]) { if (tb->lnum[0]) {
retval |= locked_or_not_in_tree(tb, tb->L[0], "L[0]"); retval |= locked_or_not_in_tree(tb, tb->L[0], "L[0]");
retval |= locked_or_not_in_tree(tb, tb->FL[0], "FL[0]"); retval |= locked_or_not_in_tree(tb, tb->FL[0], "FL[0]");
@ -1429,49 +1452,51 @@ static void check_internal_levels(struct tree_balance *tb)
#endif #endif
/* Now we have all of the buffers that must be used in balancing of /*
the tree. We rely on the assumption that schedule() will not occur * Now we have all of the buffers that must be used in balancing of
while do_balance works. ( Only interrupt handlers are acceptable.) * the tree. We rely on the assumption that schedule() will not occur
We balance the tree according to the analysis made before this, * while do_balance works. ( Only interrupt handlers are acceptable.)
using buffers already obtained. For SMP support it will someday be * We balance the tree according to the analysis made before this,
necessary to add ordered locking of tb. */ * using buffers already obtained. For SMP support it will someday be
* necessary to add ordered locking of tb.
*/
/* Some interesting rules of balancing: /*
* Some interesting rules of balancing:
we delete a maximum of two nodes per level per balancing: we never * we delete a maximum of two nodes per level per balancing: we never
delete R, when we delete two of three nodes L, S, R then we move * delete R, when we delete two of three nodes L, S, R then we move
them into R. * them into R.
*
we only delete L if we are deleting two nodes, if we delete only * we only delete L if we are deleting two nodes, if we delete only
one node we delete S * one node we delete S
*
if we shift leaves then we shift as much as we can: this is a * if we shift leaves then we shift as much as we can: this is a
deliberate policy of extremism in node packing which results in * deliberate policy of extremism in node packing which results in
higher average utilization after repeated random balance operations * higher average utilization after repeated random balance operations
at the cost of more memory copies and more balancing as a result of * at the cost of more memory copies and more balancing as a result of
small insertions to full nodes. * small insertions to full nodes.
*
if we shift internal nodes we try to evenly balance the node * if we shift internal nodes we try to evenly balance the node
utilization, with consequent less balancing at the cost of lower * utilization, with consequent less balancing at the cost of lower
utilization. * utilization.
*
one could argue that the policy for directories in leaves should be * one could argue that the policy for directories in leaves should be
that of internal nodes, but we will wait until another day to * that of internal nodes, but we will wait until another day to
evaluate this.... It would be nice to someday measure and prove * evaluate this.... It would be nice to someday measure and prove
these assumptions as to what is optimal.... * these assumptions as to what is optimal....
*/
*/
static inline void do_balance_starts(struct tree_balance *tb) static inline void do_balance_starts(struct tree_balance *tb)
{ {
/* use print_cur_tb() to see initial state of struct /* use print_cur_tb() to see initial state of struct tree_balance */
tree_balance */
/* store_print_tb (tb); */ /* store_print_tb (tb); */
/* do not delete, just comment it out */ /* do not delete, just comment it out */
/* print_tb(flag, PATH_LAST_POSITION(tb->tb_path), tb->tb_path->pos_in_item, tb, /*
"check");*/ print_tb(flag, PATH_LAST_POSITION(tb->tb_path),
tb->tb_path->pos_in_item, tb, "check");
*/
RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB"); RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB");
#ifdef CONFIG_REISERFS_CHECK #ifdef CONFIG_REISERFS_CHECK
REISERFS_SB(tb->tb_sb)->cur_tb = tb; REISERFS_SB(tb->tb_sb)->cur_tb = tb;
@ -1487,9 +1512,10 @@ static inline void do_balance_completed(struct tree_balance *tb)
REISERFS_SB(tb->tb_sb)->cur_tb = NULL; REISERFS_SB(tb->tb_sb)->cur_tb = NULL;
#endif #endif
/* reiserfs_free_block is no longer schedule safe. So, we need to /*
** put the buffers we want freed on the thrown list during do_balance, * reiserfs_free_block is no longer schedule safe. So, we need to
** and then free them now * put the buffers we want freed on the thrown list during do_balance,
* and then free them now
*/ */
REISERFS_SB(tb->tb_sb)->s_do_balance++; REISERFS_SB(tb->tb_sb)->s_do_balance++;
@ -1500,36 +1526,40 @@ static inline void do_balance_completed(struct tree_balance *tb)
free_thrown(tb); free_thrown(tb);
} }
void do_balance(struct tree_balance *tb, /* tree_balance structure */ /*
struct item_head *ih, /* item header of inserted item */ * do_balance - balance the tree
const char *body, /* body of inserted item or bytes to paste */ *
int flag) * @tb: tree_balance structure
{ /* i - insert, d - delete * @ih: item header of inserted item
c - cut, p - paste * @body: body of inserted item or bytes to paste
* @flag: 'i' - insert, 'd' - delete, 'c' - cut, 'p' paste
*
* Cut means delete part of an item (includes removing an entry from a
* directory).
*
* Delete means delete whole item.
*
* Insert means add a new item into the tree.
*
* Paste means to append to the end of an existing file or to
* insert a directory entry.
*/
void do_balance(struct tree_balance *tb, struct item_head *ih,
const char *body, int flag)
{
int child_pos; /* position of a child node in its parent */
int h; /* level of the tree being processed */
Cut means delete part of an item /*
(includes removing an entry from a * in our processing of one level we sometimes determine what
directory). * must be inserted into the next higher level. This insertion
* consists of a key or two keys and their corresponding
* pointers
*/
struct item_head insert_key[2];
Delete means delete whole item. /* inserted node-ptrs for the next level */
struct buffer_head *insert_ptr[2];
Insert means add a new item into the
tree.
Paste means to append to the end of an
existing file or to insert a directory
entry. */
int child_pos, /* position of a child node in its parent */
h; /* level of the tree being processed */
struct item_head insert_key[2]; /* in our processing of one level
we sometimes determine what
must be inserted into the next
higher level. This insertion
consists of a key or two keys
and their corresponding
pointers */
struct buffer_head *insert_ptr[2]; /* inserted node-ptrs for the next
level */
tb->tb_mode = flag; tb->tb_mode = flag;
tb->need_balance_dirty = 0; tb->need_balance_dirty = 0;
@ -1549,9 +1579,11 @@ void do_balance(struct tree_balance *tb, /* tree_balance structure */
atomic_inc(&(fs_generation(tb->tb_sb))); atomic_inc(&(fs_generation(tb->tb_sb)));
do_balance_starts(tb); do_balance_starts(tb);
/* balance leaf returns 0 except if combining L R and S into /*
one node. see balance_internal() for explanation of this * balance_leaf returns 0 except if combining L R and S into
line of code. */ * one node. see balance_internal() for explanation of this
* line of code.
*/
child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) + child_pos = PATH_H_B_ITEM_ORDER(tb->tb_path, 0) +
balance_leaf(tb, ih, body, flag, insert_key, insert_ptr); balance_leaf(tb, ih, body, flag, insert_key, insert_ptr);

View File

@ -15,20 +15,20 @@
#include <linux/quotaops.h> #include <linux/quotaops.h>
/* /*
** We pack the tails of files on file close, not at the time they are written. * We pack the tails of files on file close, not at the time they are written.
** This implies an unnecessary copy of the tail and an unnecessary indirect item * This implies an unnecessary copy of the tail and an unnecessary indirect item
** insertion/balancing, for files that are written in one write. * insertion/balancing, for files that are written in one write.
** It avoids unnecessary tail packings (balances) for files that are written in * It avoids unnecessary tail packings (balances) for files that are written in
** multiple writes and are small enough to have tails. * multiple writes and are small enough to have tails.
** *
** file_release is called by the VFS layer when the file is closed. If * file_release is called by the VFS layer when the file is closed. If
** this is the last open file descriptor, and the file * this is the last open file descriptor, and the file
** small enough to have a tail, and the tail is currently in an * small enough to have a tail, and the tail is currently in an
** unformatted node, the tail is converted back into a direct item. * unformatted node, the tail is converted back into a direct item.
** *
** We use reiserfs_truncate_file to pack the tail, since it already has * We use reiserfs_truncate_file to pack the tail, since it already has
** all the conditions coded. * all the conditions coded.
*/ */
static int reiserfs_file_release(struct inode *inode, struct file *filp) static int reiserfs_file_release(struct inode *inode, struct file *filp)
{ {
@ -57,14 +57,16 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
} }
reiserfs_write_lock(inode->i_sb); reiserfs_write_lock(inode->i_sb);
/* freeing preallocation only involves relogging blocks that /*
* freeing preallocation only involves relogging blocks that
* are already in the current transaction. preallocation gets * are already in the current transaction. preallocation gets
* freed at the end of each transaction, so it is impossible for * freed at the end of each transaction, so it is impossible for
* us to log any additional blocks (including quota blocks) * us to log any additional blocks (including quota blocks)
*/ */
err = journal_begin(&th, inode->i_sb, 1); err = journal_begin(&th, inode->i_sb, 1);
if (err) { if (err) {
/* uh oh, we can't allow the inode to go away while there /*
* uh oh, we can't allow the inode to go away while there
* is still preallocation blocks pending. Try to join the * is still preallocation blocks pending. Try to join the
* aborted transaction * aborted transaction
*/ */
@ -72,11 +74,13 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
err = journal_join_abort(&th, inode->i_sb, 1); err = journal_join_abort(&th, inode->i_sb, 1);
if (err) { if (err) {
/* hmpf, our choices here aren't good. We can pin the inode /*
* which will disallow unmount from every happening, we can * hmpf, our choices here aren't good. We can pin
* do nothing, which will corrupt random memory on unmount, * the inode which will disallow unmount from ever
* or we can forcibly remove the file from the preallocation * happening, we can do nothing, which will corrupt
* list, which will leak blocks on disk. Lets pin the inode * random memory on unmount, or we can forcibly
* remove the file from the preallocation list, which
* will leak blocks on disk. Lets pin the inode
* and let the admin know what is going on. * and let the admin know what is going on.
*/ */
igrab(inode); igrab(inode);
@ -102,10 +106,12 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) && (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
tail_has_to_be_packed(inode)) { tail_has_to_be_packed(inode)) {
/* if regular file is released by last holder and it has been /*
appended (we append by unformatted node only) or its direct * if regular file is released by last holder and it has been
item(s) had to be converted, then it may have to be * appended (we append by unformatted node only) or its direct
indirect2direct converted */ * item(s) had to be converted, then it may have to be
* indirect2direct converted
*/
err = reiserfs_truncate_file(inode, 0); err = reiserfs_truncate_file(inode, 0);
} }
out: out:
@ -117,8 +123,9 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
static int reiserfs_file_open(struct inode *inode, struct file *file) static int reiserfs_file_open(struct inode *inode, struct file *file)
{ {
int err = dquot_file_open(inode, file); int err = dquot_file_open(inode, file);
/* somebody might be tailpacking on final close; wait for it */
if (!atomic_inc_not_zero(&REISERFS_I(inode)->openers)) { if (!atomic_inc_not_zero(&REISERFS_I(inode)->openers)) {
/* somebody might be tailpacking on final close; wait for it */
mutex_lock(&(REISERFS_I(inode)->tailpack)); mutex_lock(&(REISERFS_I(inode)->tailpack));
atomic_inc(&REISERFS_I(inode)->openers); atomic_inc(&REISERFS_I(inode)->openers);
mutex_unlock(&(REISERFS_I(inode)->tailpack)); mutex_unlock(&(REISERFS_I(inode)->tailpack));
@ -208,7 +215,8 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
journal_mark_dirty(&th, s, bh); journal_mark_dirty(&th, s, bh);
} else if (!buffer_dirty(bh)) { } else if (!buffer_dirty(bh)) {
mark_buffer_dirty(bh); mark_buffer_dirty(bh);
/* do data=ordered on any page past the end /*
* do data=ordered on any page past the end
* of file and any buffer marked BH_New. * of file and any buffer marked BH_New.
*/ */
if (reiserfs_data_ordered(inode->i_sb) && if (reiserfs_data_ordered(inode->i_sb) &&

File diff suppressed because it is too large Load Diff

View File

@ -12,12 +12,6 @@
* Yura's function is added (04/07/2000) * Yura's function is added (04/07/2000)
*/ */
//
// keyed_hash
// yura_hash
// r5_hash
//
#include <linux/kernel.h> #include <linux/kernel.h>
#include "reiserfs.h" #include "reiserfs.h"
#include <asm/types.h> #include <asm/types.h>
@ -56,7 +50,7 @@ u32 keyed_hash(const signed char *msg, int len)
u32 pad; u32 pad;
int i; int i;
// assert(len >= 0 && len < 256); /* assert(len >= 0 && len < 256); */
pad = (u32) len | ((u32) len << 8); pad = (u32) len | ((u32) len << 8);
pad |= pad << 16; pad |= pad << 16;
@ -127,9 +121,10 @@ u32 keyed_hash(const signed char *msg, int len)
return h0 ^ h1; return h0 ^ h1;
} }
/* What follows in this file is copyright 2000 by Hans Reiser, and the /*
* licensing of what follows is governed by reiserfs/README */ * What follows in this file is copyright 2000 by Hans Reiser, and the
* licensing of what follows is governed by reiserfs/README
*/
u32 yura_hash(const signed char *msg, int len) u32 yura_hash(const signed char *msg, int len)
{ {
int j, pow; int j, pow;

View File

@ -12,7 +12,10 @@
int balance_internal(struct tree_balance *, int balance_internal(struct tree_balance *,
int, int, struct item_head *, struct buffer_head **); int, int, struct item_head *, struct buffer_head **);
/* modes of internal_shift_left, internal_shift_right and internal_insert_childs */ /*
* modes of internal_shift_left, internal_shift_right and
* internal_insert_childs
*/
#define INTERNAL_SHIFT_FROM_S_TO_L 0 #define INTERNAL_SHIFT_FROM_S_TO_L 0
#define INTERNAL_SHIFT_FROM_R_TO_S 1 #define INTERNAL_SHIFT_FROM_R_TO_S 1
#define INTERNAL_SHIFT_FROM_L_TO_S 2 #define INTERNAL_SHIFT_FROM_L_TO_S 2
@ -32,7 +35,9 @@ static void internal_define_dest_src_infos(int shift_mode,
memset(src_bi, 0, sizeof(struct buffer_info)); memset(src_bi, 0, sizeof(struct buffer_info));
/* define dest, src, dest parent, dest position */ /* define dest, src, dest parent, dest position */
switch (shift_mode) { switch (shift_mode) {
case INTERNAL_SHIFT_FROM_S_TO_L: /* used in internal_shift_left */
/* used in internal_shift_left */
case INTERNAL_SHIFT_FROM_S_TO_L:
src_bi->tb = tb; src_bi->tb = tb;
src_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h); src_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h); src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
@ -52,12 +57,14 @@ static void internal_define_dest_src_infos(int shift_mode,
dest_bi->tb = tb; dest_bi->tb = tb;
dest_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h); dest_bi->bi_bh = PATH_H_PBUFFER(tb->tb_path, h);
dest_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h); dest_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, h);
dest_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1); /* dest position is analog of dest->b_item_order */ /* dest position is analog of dest->b_item_order */
dest_bi->bi_position = PATH_H_POSITION(tb->tb_path, h + 1);
*d_key = tb->lkey[h]; *d_key = tb->lkey[h];
*cf = tb->CFL[h]; *cf = tb->CFL[h];
break; break;
case INTERNAL_SHIFT_FROM_R_TO_S: /* used in internal_shift_left */ /* used in internal_shift_left */
case INTERNAL_SHIFT_FROM_R_TO_S:
src_bi->tb = tb; src_bi->tb = tb;
src_bi->bi_bh = tb->R[h]; src_bi->bi_bh = tb->R[h];
src_bi->bi_parent = tb->FR[h]; src_bi->bi_parent = tb->FR[h];
@ -111,7 +118,8 @@ static void internal_define_dest_src_infos(int shift_mode,
} }
} }
/* Insert count node pointers into buffer cur before position to + 1. /*
* Insert count node pointers into buffer cur before position to + 1.
* Insert count items into buffer cur before position to. * Insert count items into buffer cur before position to.
* Items and node pointers are specified by inserted and bh respectively. * Items and node pointers are specified by inserted and bh respectively.
*/ */
@ -190,8 +198,10 @@ static void internal_insert_childs(struct buffer_info *cur_bi,
} }
/* Delete del_num items and node pointers from buffer cur starting from * /*
* the first_i'th item and first_p'th pointers respectively. */ * Delete del_num items and node pointers from buffer cur starting from
* the first_i'th item and first_p'th pointers respectively.
*/
static void internal_delete_pointers_items(struct buffer_info *cur_bi, static void internal_delete_pointers_items(struct buffer_info *cur_bi,
int first_p, int first_p,
int first_i, int del_num) int first_i, int del_num)
@ -270,22 +280,30 @@ static void internal_delete_childs(struct buffer_info *cur_bi, int from, int n)
i_from = (from == 0) ? from : from - 1; i_from = (from == 0) ? from : from - 1;
/* delete n pointers starting from `from' position in CUR; /*
delete n keys starting from 'i_from' position in CUR; * delete n pointers starting from `from' position in CUR;
* delete n keys starting from 'i_from' position in CUR;
*/ */
internal_delete_pointers_items(cur_bi, from, i_from, n); internal_delete_pointers_items(cur_bi, from, i_from, n);
} }
/* copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer dest /*
* last_first == FIRST_TO_LAST means, that we copy first items from src to tail of dest * copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer
* last_first == LAST_TO_FIRST means, that we copy last items from src to head of dest * dest
* last_first == FIRST_TO_LAST means that we copy first items
* from src to tail of dest
* last_first == LAST_TO_FIRST means that we copy last items
* from src to head of dest
*/ */
static void internal_copy_pointers_items(struct buffer_info *dest_bi, static void internal_copy_pointers_items(struct buffer_info *dest_bi,
struct buffer_head *src, struct buffer_head *src,
int last_first, int cpy_num) int last_first, int cpy_num)
{ {
/* ATTENTION! Number of node pointers in DEST is equal to number of items in DEST * /*
* as delimiting key have already inserted to buffer dest.*/ * ATTENTION! Number of node pointers in DEST is equal to number
* of items in DEST as delimiting key have already inserted to
* buffer dest.
*/
struct buffer_head *dest = dest_bi->bi_bh; struct buffer_head *dest = dest_bi->bi_bh;
int nr_dest, nr_src; int nr_dest, nr_src;
int dest_order, src_order; int dest_order, src_order;
@ -366,7 +384,9 @@ static void internal_copy_pointers_items(struct buffer_info *dest_bi,
} }
/* Copy cpy_num node pointers and cpy_num - 1 items from buffer src to buffer dest. /*
* Copy cpy_num node pointers and cpy_num - 1 items from buffer src to
* buffer dest.
* Delete cpy_num - del_par items and node pointers from buffer src. * Delete cpy_num - del_par items and node pointers from buffer src.
* last_first == FIRST_TO_LAST means, that we copy/delete first items from src. * last_first == FIRST_TO_LAST means, that we copy/delete first items from src.
* last_first == LAST_TO_FIRST means, that we copy/delete last items from src. * last_first == LAST_TO_FIRST means, that we copy/delete last items from src.
@ -385,8 +405,10 @@ static void internal_move_pointers_items(struct buffer_info *dest_bi,
if (last_first == FIRST_TO_LAST) { /* shift_left occurs */ if (last_first == FIRST_TO_LAST) { /* shift_left occurs */
first_pointer = 0; first_pointer = 0;
first_item = 0; first_item = 0;
/* delete cpy_num - del_par pointers and keys starting for pointers with first_pointer, /*
for key - with first_item */ * delete cpy_num - del_par pointers and keys starting for
* pointers with first_pointer, for key - with first_item
*/
internal_delete_pointers_items(src_bi, first_pointer, internal_delete_pointers_items(src_bi, first_pointer,
first_item, cpy_num - del_par); first_item, cpy_num - del_par);
} else { /* shift_right occurs */ } else { /* shift_right occurs */
@ -404,7 +426,9 @@ static void internal_move_pointers_items(struct buffer_info *dest_bi,
} }
/* Insert n_src'th key of buffer src before n_dest'th key of buffer dest. */ /* Insert n_src'th key of buffer src before n_dest'th key of buffer dest. */
static void internal_insert_key(struct buffer_info *dest_bi, int dest_position_before, /* insert key before key with n_dest number */ static void internal_insert_key(struct buffer_info *dest_bi,
/* insert key before key with n_dest number */
int dest_position_before,
struct buffer_head *src, int src_position) struct buffer_head *src, int src_position)
{ {
struct buffer_head *dest = dest_bi->bi_bh; struct buffer_head *dest = dest_bi->bi_bh;
@ -453,13 +477,19 @@ static void internal_insert_key(struct buffer_info *dest_bi, int dest_position_b
} }
} }
/* Insert d_key'th (delimiting) key from buffer cfl to tail of dest. /*
* Copy pointer_amount node pointers and pointer_amount - 1 items from buffer src to buffer dest. * Insert d_key'th (delimiting) key from buffer cfl to tail of dest.
* Copy pointer_amount node pointers and pointer_amount - 1 items from
* buffer src to buffer dest.
* Replace d_key'th key in buffer cfl. * Replace d_key'th key in buffer cfl.
* Delete pointer_amount items and node pointers from buffer src. * Delete pointer_amount items and node pointers from buffer src.
*/ */
/* this can be invoked both to shift from S to L and from R to S */ /* this can be invoked both to shift from S to L and from R to S */
static void internal_shift_left(int mode, /* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S */ static void internal_shift_left(
/*
* INTERNAL_FROM_S_TO_L | INTERNAL_FROM_R_TO_S
*/
int mode,
struct tree_balance *tb, struct tree_balance *tb,
int h, int pointer_amount) int h, int pointer_amount)
{ {
@ -473,7 +503,10 @@ static void internal_shift_left(int mode, /* INTERNAL_FROM_S_TO_L | INTERNAL_FRO
/*printk("pointer_amount = %d\n",pointer_amount); */ /*printk("pointer_amount = %d\n",pointer_amount); */
if (pointer_amount) { if (pointer_amount) {
/* insert delimiting key from common father of dest and src to node dest into position B_NR_ITEM(dest) */ /*
* insert delimiting key from common father of dest and
* src to node dest into position B_NR_ITEM(dest)
*/
internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf, internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
d_key_position); d_key_position);
@ -492,7 +525,8 @@ static void internal_shift_left(int mode, /* INTERNAL_FROM_S_TO_L | INTERNAL_FRO
} }
/* Insert delimiting key to L[h]. /*
* Insert delimiting key to L[h].
* Copy n node pointers and n - 1 items from buffer S[h] to L[h]. * Copy n node pointers and n - 1 items from buffer S[h] to L[h].
* Delete n - 1 items and node pointers from buffer S[h]. * Delete n - 1 items and node pointers from buffer S[h].
*/ */
@ -507,23 +541,27 @@ static void internal_shift1_left(struct tree_balance *tb,
internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_L, tb, h, internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
&dest_bi, &src_bi, &d_key_position, &cf); &dest_bi, &src_bi, &d_key_position, &cf);
if (pointer_amount > 0) /* insert lkey[h]-th key from CFL[h] to left neighbor L[h] */ /* insert lkey[h]-th key from CFL[h] to left neighbor L[h] */
if (pointer_amount > 0)
internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf, internal_insert_key(&dest_bi, B_NR_ITEMS(dest_bi.bi_bh), cf,
d_key_position); d_key_position);
/* internal_insert_key (tb->L[h], B_NR_ITEM(tb->L[h]), tb->CFL[h], tb->lkey[h]); */
/* last parameter is del_parameter */ /* last parameter is del_parameter */
internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST, internal_move_pointers_items(&dest_bi, &src_bi, FIRST_TO_LAST,
pointer_amount, 1); pointer_amount, 1);
/* internal_move_pointers_items (tb->L[h], tb->S[h], FIRST_TO_LAST, pointer_amount, 1); */
} }
/* Insert d_key'th (delimiting) key from buffer cfr to head of dest. /*
* Insert d_key'th (delimiting) key from buffer cfr to head of dest.
* Copy n node pointers and n - 1 items from buffer src to buffer dest. * Copy n node pointers and n - 1 items from buffer src to buffer dest.
* Replace d_key'th key in buffer cfr. * Replace d_key'th key in buffer cfr.
* Delete n items and node pointers from buffer src. * Delete n items and node pointers from buffer src.
*/ */
static void internal_shift_right(int mode, /* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S */ static void internal_shift_right(
/*
* INTERNAL_FROM_S_TO_R | INTERNAL_FROM_L_TO_S
*/
int mode,
struct tree_balance *tb, struct tree_balance *tb,
int h, int pointer_amount) int h, int pointer_amount)
{ {
@ -538,7 +576,10 @@ static void internal_shift_right(int mode, /* INTERNAL_FROM_S_TO_R | INTERNAL_FR
nr = B_NR_ITEMS(src_bi.bi_bh); nr = B_NR_ITEMS(src_bi.bi_bh);
if (pointer_amount > 0) { if (pointer_amount > 0) {
/* insert delimiting key from common father of dest and src to dest node into position 0 */ /*
* insert delimiting key from common father of dest
* and src to dest node into position 0
*/
internal_insert_key(&dest_bi, 0, cf, d_key_position); internal_insert_key(&dest_bi, 0, cf, d_key_position);
if (nr == pointer_amount - 1) { if (nr == pointer_amount - 1) {
RFALSE(src_bi.bi_bh != PATH_H_PBUFFER(tb->tb_path, h) /*tb->S[h] */ || RFALSE(src_bi.bi_bh != PATH_H_PBUFFER(tb->tb_path, h) /*tb->S[h] */ ||
@ -559,7 +600,8 @@ static void internal_shift_right(int mode, /* INTERNAL_FROM_S_TO_R | INTERNAL_FR
pointer_amount, 0); pointer_amount, 0);
} }
/* Insert delimiting key to R[h]. /*
* Insert delimiting key to R[h].
* Copy n node pointers and n - 1 items from buffer S[h] to R[h]. * Copy n node pointers and n - 1 items from buffer S[h] to R[h].
* Delete n - 1 items and node pointers from buffer S[h]. * Delete n - 1 items and node pointers from buffer S[h].
*/ */
@ -574,18 +616,19 @@ static void internal_shift1_right(struct tree_balance *tb,
internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_R, tb, h, internal_define_dest_src_infos(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
&dest_bi, &src_bi, &d_key_position, &cf); &dest_bi, &src_bi, &d_key_position, &cf);
if (pointer_amount > 0) /* insert rkey from CFR[h] to right neighbor R[h] */ /* insert rkey from CFR[h] to right neighbor R[h] */
if (pointer_amount > 0)
internal_insert_key(&dest_bi, 0, cf, d_key_position); internal_insert_key(&dest_bi, 0, cf, d_key_position);
/* internal_insert_key (tb->R[h], 0, tb->CFR[h], tb->rkey[h]); */
/* last parameter is del_parameter */ /* last parameter is del_parameter */
internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST, internal_move_pointers_items(&dest_bi, &src_bi, LAST_TO_FIRST,
pointer_amount, 1); pointer_amount, 1);
/* internal_move_pointers_items (tb->R[h], tb->S[h], LAST_TO_FIRST, pointer_amount, 1); */
} }
/* Delete insert_num node pointers together with their left items /*
* and balance current node.*/ * Delete insert_num node pointers together with their left items
* and balance current node.
*/
static void balance_internal_when_delete(struct tree_balance *tb, static void balance_internal_when_delete(struct tree_balance *tb,
int h, int child_pos) int h, int child_pos)
{ {
@ -626,9 +669,11 @@ static void balance_internal_when_delete(struct tree_balance *tb,
new_root = tb->R[h - 1]; new_root = tb->R[h - 1];
else else
new_root = tb->L[h - 1]; new_root = tb->L[h - 1];
/* switch super block's tree root block number to the new value */ /*
* switch super block's tree root block
* number to the new value */
PUT_SB_ROOT_BLOCK(tb->tb_sb, new_root->b_blocknr); PUT_SB_ROOT_BLOCK(tb->tb_sb, new_root->b_blocknr);
//REISERFS_SB(tb->tb_sb)->s_rs->s_tree_height --; /*REISERFS_SB(tb->tb_sb)->s_rs->s_tree_height --; */
PUT_SB_TREE_HEIGHT(tb->tb_sb, PUT_SB_TREE_HEIGHT(tb->tb_sb,
SB_TREE_HEIGHT(tb->tb_sb) - 1); SB_TREE_HEIGHT(tb->tb_sb) - 1);
@ -636,8 +681,8 @@ static void balance_internal_when_delete(struct tree_balance *tb,
REISERFS_SB(tb->tb_sb)->s_sbh, REISERFS_SB(tb->tb_sb)->s_sbh,
1); 1);
/*&&&&&&&&&&&&&&&&&&&&&& */ /*&&&&&&&&&&&&&&&&&&&&&& */
/* use check_internal if new root is an internal node */
if (h > 1) if (h > 1)
/* use check_internal if new root is an internal node */
check_internal(new_root); check_internal(new_root);
/*&&&&&&&&&&&&&&&&&&&&&& */ /*&&&&&&&&&&&&&&&&&&&&&& */
@ -648,7 +693,8 @@ static void balance_internal_when_delete(struct tree_balance *tb,
return; return;
} }
if (tb->L[h] && tb->lnum[h] == -B_NR_ITEMS(tb->L[h]) - 1) { /* join S[h] with L[h] */ /* join S[h] with L[h] */
if (tb->L[h] && tb->lnum[h] == -B_NR_ITEMS(tb->L[h]) - 1) {
RFALSE(tb->rnum[h] != 0, RFALSE(tb->rnum[h] != 0,
"invalid tb->rnum[%d]==%d when joining S[h] with L[h]", "invalid tb->rnum[%d]==%d when joining S[h] with L[h]",
@ -660,7 +706,8 @@ static void balance_internal_when_delete(struct tree_balance *tb,
return; return;
} }
if (tb->R[h] && tb->rnum[h] == -B_NR_ITEMS(tb->R[h]) - 1) { /* join S[h] with R[h] */ /* join S[h] with R[h] */
if (tb->R[h] && tb->rnum[h] == -B_NR_ITEMS(tb->R[h]) - 1) {
RFALSE(tb->lnum[h] != 0, RFALSE(tb->lnum[h] != 0,
"invalid tb->lnum[%d]==%d when joining S[h] with R[h]", "invalid tb->lnum[%d]==%d when joining S[h] with R[h]",
h, tb->lnum[h]); h, tb->lnum[h]);
@ -671,17 +718,18 @@ static void balance_internal_when_delete(struct tree_balance *tb,
return; return;
} }
if (tb->lnum[h] < 0) { /* borrow from left neighbor L[h] */ /* borrow from left neighbor L[h] */
if (tb->lnum[h] < 0) {
RFALSE(tb->rnum[h] != 0, RFALSE(tb->rnum[h] != 0,
"wrong tb->rnum[%d]==%d when borrow from L[h]", h, "wrong tb->rnum[%d]==%d when borrow from L[h]", h,
tb->rnum[h]); tb->rnum[h]);
/*internal_shift_right (tb, h, tb->L[h], tb->CFL[h], tb->lkey[h], tb->S[h], -tb->lnum[h]); */
internal_shift_right(INTERNAL_SHIFT_FROM_L_TO_S, tb, h, internal_shift_right(INTERNAL_SHIFT_FROM_L_TO_S, tb, h,
-tb->lnum[h]); -tb->lnum[h]);
return; return;
} }
if (tb->rnum[h] < 0) { /* borrow from right neighbor R[h] */ /* borrow from right neighbor R[h] */
if (tb->rnum[h] < 0) {
RFALSE(tb->lnum[h] != 0, RFALSE(tb->lnum[h] != 0,
"invalid tb->lnum[%d]==%d when borrow from R[h]", "invalid tb->lnum[%d]==%d when borrow from R[h]",
h, tb->lnum[h]); h, tb->lnum[h]);
@ -689,7 +737,8 @@ static void balance_internal_when_delete(struct tree_balance *tb,
return; return;
} }
if (tb->lnum[h] > 0) { /* split S[h] into two parts and put them into neighbors */ /* split S[h] into two parts and put them into neighbors */
if (tb->lnum[h] > 0) {
RFALSE(tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1, RFALSE(tb->rnum[h] == 0 || tb->lnum[h] + tb->rnum[h] != n + 1,
"invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them", "invalid tb->lnum[%d]==%d or tb->rnum[%d]==%d when S[h](item number == %d) is split between them",
h, tb->lnum[h], h, tb->rnum[h], n); h, tb->lnum[h], h, tb->rnum[h], n);
@ -737,29 +786,36 @@ static void replace_rkey(struct tree_balance *tb, int h, struct item_head *key)
do_balance_mark_internal_dirty(tb, tb->CFR[h], 0); do_balance_mark_internal_dirty(tb, tb->CFR[h], 0);
} }
int balance_internal(struct tree_balance *tb, /* tree_balance structure */
int h, /* level of the tree */ /*
int child_pos, struct item_head *insert_key, /* key for insertion on higher level */ * if inserting/pasting {
struct buffer_head **insert_ptr /* node for insertion on higher level */ * child_pos is the position of the node-pointer in S[h] that
) * pointed to S[h-1] before balancing of the h-1 level;
/* if inserting/pasting * this means that new pointers and items must be inserted AFTER
{ * child_pos
child_pos is the position of the node-pointer in S[h] that * * } else {
pointed to S[h-1] before balancing of the h-1 level; * * it is the position of the leftmost pointer that must be deleted
this means that new pointers and items must be inserted AFTER * * (together with its corresponding key to the left of the pointer)
child_pos * as a result of the previous level's balancing.
} * }
else */
{
it is the position of the leftmost pointer that must be deleted (together with int balance_internal(struct tree_balance *tb,
its corresponding key to the left of the pointer) int h, /* level of the tree */
as a result of the previous level's balancing. int child_pos,
} /* key for insertion on higher level */
*/ struct item_head *insert_key,
/* node for insertion on higher level */
struct buffer_head **insert_ptr)
{ {
struct buffer_head *tbSh = PATH_H_PBUFFER(tb->tb_path, h); struct buffer_head *tbSh = PATH_H_PBUFFER(tb->tb_path, h);
struct buffer_info bi; struct buffer_info bi;
int order; /* we return this: it is 0 if there is no S[h], else it is tb->S[h]->b_item_order */
/*
* we return this: it is 0 if there is no S[h],
* else it is tb->S[h]->b_item_order
*/
int order;
int insert_num, n, k; int insert_num, n, k;
struct buffer_head *S_new; struct buffer_head *S_new;
struct item_head new_insert_key; struct item_head new_insert_key;
@ -774,8 +830,10 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
(tbSh) ? PATH_H_POSITION(tb->tb_path, (tbSh) ? PATH_H_POSITION(tb->tb_path,
h + 1) /*tb->S[h]->b_item_order */ : 0; h + 1) /*tb->S[h]->b_item_order */ : 0;
/* Using insert_size[h] calculate the number insert_num of items /*
that must be inserted to or deleted from S[h]. */ * Using insert_size[h] calculate the number insert_num of items
* that must be inserted to or deleted from S[h].
*/
insert_num = tb->insert_size[h] / ((int)(KEY_SIZE + DC_SIZE)); insert_num = tb->insert_size[h] / ((int)(KEY_SIZE + DC_SIZE));
/* Check whether insert_num is proper * */ /* Check whether insert_num is proper * */
@ -794,23 +852,21 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
k = 0; k = 0;
if (tb->lnum[h] > 0) { if (tb->lnum[h] > 0) {
/* shift lnum[h] items from S[h] to the left neighbor L[h]. /*
check how many of new items fall into L[h] or CFL[h] after * shift lnum[h] items from S[h] to the left neighbor L[h].
shifting */ * check how many of new items fall into L[h] or CFL[h] after
* shifting
*/
n = B_NR_ITEMS(tb->L[h]); /* number of items in L[h] */ n = B_NR_ITEMS(tb->L[h]); /* number of items in L[h] */
if (tb->lnum[h] <= child_pos) { if (tb->lnum[h] <= child_pos) {
/* new items don't fall into L[h] or CFL[h] */ /* new items don't fall into L[h] or CFL[h] */
internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h, internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
tb->lnum[h]); tb->lnum[h]);
/*internal_shift_left (tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,tb->lnum[h]); */
child_pos -= tb->lnum[h]; child_pos -= tb->lnum[h];
} else if (tb->lnum[h] > child_pos + insert_num) { } else if (tb->lnum[h] > child_pos + insert_num) {
/* all new items fall into L[h] */ /* all new items fall into L[h] */
internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h, internal_shift_left(INTERNAL_SHIFT_FROM_S_TO_L, tb, h,
tb->lnum[h] - insert_num); tb->lnum[h] - insert_num);
/* internal_shift_left(tb->L[h],tb->CFL[h],tb->lkey[h],tbSh,
tb->lnum[h]-insert_num);
*/
/* insert insert_num keys and node-pointers into L[h] */ /* insert insert_num keys and node-pointers into L[h] */
bi.tb = tb; bi.tb = tb;
bi.bi_bh = tb->L[h]; bi.bi_bh = tb->L[h];
@ -826,7 +882,10 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
} else { } else {
struct disk_child *dc; struct disk_child *dc;
/* some items fall into L[h] or CFL[h], but some don't fall */ /*
* some items fall into L[h] or CFL[h],
* but some don't fall
*/
internal_shift1_left(tb, h, child_pos + 1); internal_shift1_left(tb, h, child_pos + 1);
/* calculate number of new items that fall into L[h] */ /* calculate number of new items that fall into L[h] */
k = tb->lnum[h] - child_pos - 1; k = tb->lnum[h] - child_pos - 1;
@ -841,7 +900,10 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
replace_lkey(tb, h, insert_key + k); replace_lkey(tb, h, insert_key + k);
/* replace the first node-ptr in S[h] by node-ptr to insert_ptr[k] */ /*
* replace the first node-ptr in S[h] by
* node-ptr to insert_ptr[k]
*/
dc = B_N_CHILD(tbSh, 0); dc = B_N_CHILD(tbSh, 0);
put_dc_size(dc, put_dc_size(dc,
MAX_CHILD_SIZE(insert_ptr[k]) - MAX_CHILD_SIZE(insert_ptr[k]) -
@ -860,17 +922,17 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
/* tb->lnum[h] > 0 */ /* tb->lnum[h] > 0 */
if (tb->rnum[h] > 0) { if (tb->rnum[h] > 0) {
/*shift rnum[h] items from S[h] to the right neighbor R[h] */ /*shift rnum[h] items from S[h] to the right neighbor R[h] */
/* check how many of new items fall into R or CFR after shifting */ /*
* check how many of new items fall into R or CFR
* after shifting
*/
n = B_NR_ITEMS(tbSh); /* number of items in S[h] */ n = B_NR_ITEMS(tbSh); /* number of items in S[h] */
if (n - tb->rnum[h] >= child_pos) if (n - tb->rnum[h] >= child_pos)
/* new items fall into S[h] */ /* new items fall into S[h] */
/*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],tb->rnum[h]); */
internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h, internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
tb->rnum[h]); tb->rnum[h]);
else if (n + insert_num - tb->rnum[h] < child_pos) { else if (n + insert_num - tb->rnum[h] < child_pos) {
/* all new items fall into R[h] */ /* all new items fall into R[h] */
/*internal_shift_right(tb,h,tbSh,tb->CFR[h],tb->rkey[h],tb->R[h],
tb->rnum[h] - insert_num); */
internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h, internal_shift_right(INTERNAL_SHIFT_FROM_S_TO_R, tb, h,
tb->rnum[h] - insert_num); tb->rnum[h] - insert_num);
@ -904,7 +966,10 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
replace_rkey(tb, h, insert_key + insert_num - k - 1); replace_rkey(tb, h, insert_key + insert_num - k - 1);
/* replace the first node-ptr in R[h] by node-ptr insert_ptr[insert_num-k-1] */ /*
* replace the first node-ptr in R[h] by
* node-ptr insert_ptr[insert_num-k-1]
*/
dc = B_N_CHILD(tb->R[h], 0); dc = B_N_CHILD(tb->R[h], 0);
put_dc_size(dc, put_dc_size(dc,
MAX_CHILD_SIZE(insert_ptr MAX_CHILD_SIZE(insert_ptr
@ -921,7 +986,7 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
} }
} }
/** Fill new node that appears instead of S[h] **/ /** Fill new node that appears instead of S[h] **/
RFALSE(tb->blknum[h] > 2, "blknum can not be > 2 for internal level"); RFALSE(tb->blknum[h] > 2, "blknum can not be > 2 for internal level");
RFALSE(tb->blknum[h] < 0, "blknum can not be < 0"); RFALSE(tb->blknum[h] < 0, "blknum can not be < 0");
@ -1002,11 +1067,13 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
/* last parameter is del_par */ /* last parameter is del_par */
internal_move_pointers_items(&dest_bi, &src_bi, internal_move_pointers_items(&dest_bi, &src_bi,
LAST_TO_FIRST, snum, 0); LAST_TO_FIRST, snum, 0);
/* internal_move_pointers_items(S_new, tbSh, LAST_TO_FIRST, snum, 0); */
} else if (n + insert_num - snum < child_pos) { } else if (n + insert_num - snum < child_pos) {
/* all new items fall into S_new */ /* all new items fall into S_new */
/* store the delimiting key for the next level */ /* store the delimiting key for the next level */
/* new_insert_key = (n + insert_item - snum)'th key in S[h] */ /*
* new_insert_key = (n + insert_item - snum)'th
* key in S[h]
*/
memcpy(&new_insert_key, memcpy(&new_insert_key,
internal_key(tbSh, n + insert_num - snum), internal_key(tbSh, n + insert_num - snum),
KEY_SIZE); KEY_SIZE);
@ -1014,9 +1081,11 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
internal_move_pointers_items(&dest_bi, &src_bi, internal_move_pointers_items(&dest_bi, &src_bi,
LAST_TO_FIRST, LAST_TO_FIRST,
snum - insert_num, 0); snum - insert_num, 0);
/* internal_move_pointers_items(S_new,tbSh,1,snum - insert_num,0); */
/* insert insert_num keys and node-pointers into S_new */ /*
* insert insert_num keys and node-pointers
* into S_new
*/
internal_insert_childs(&dest_bi, internal_insert_childs(&dest_bi,
/*S_new,tb->S[h-1]->b_next, */ /*S_new,tb->S[h-1]->b_next, */
child_pos - n - insert_num + child_pos - n - insert_num +
@ -1033,7 +1102,6 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
internal_move_pointers_items(&dest_bi, &src_bi, internal_move_pointers_items(&dest_bi, &src_bi,
LAST_TO_FIRST, LAST_TO_FIRST,
n - child_pos + 1, 1); n - child_pos + 1, 1);
/* internal_move_pointers_items(S_new,tbSh,1,n - child_pos + 1,1); */
/* calculate number of new items that fall into S_new */ /* calculate number of new items that fall into S_new */
k = snum - n + child_pos - 1; k = snum - n + child_pos - 1;
@ -1043,7 +1111,10 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
/* new_insert_key = insert_key[insert_num - k - 1] */ /* new_insert_key = insert_key[insert_num - k - 1] */
memcpy(&new_insert_key, insert_key + insert_num - k - 1, memcpy(&new_insert_key, insert_key + insert_num - k - 1,
KEY_SIZE); KEY_SIZE);
/* replace first node-ptr in S_new by node-ptr to insert_ptr[insert_num-k-1] */ /*
* replace first node-ptr in S_new by node-ptr
* to insert_ptr[insert_num-k-1]
*/
dc = B_N_CHILD(S_new, 0); dc = B_N_CHILD(S_new, 0);
put_dc_size(dc, put_dc_size(dc,
@ -1066,7 +1137,7 @@ int balance_internal(struct tree_balance *tb, /* tree_balance structure
|| buffer_dirty(S_new), "cm-00001: bad S_new (%b)", || buffer_dirty(S_new), "cm-00001: bad S_new (%b)",
S_new); S_new);
// S_new is released in unfix_nodes /* S_new is released in unfix_nodes */
} }
n = B_NR_ITEMS(tbSh); /*number of items in S[h] */ n = B_NR_ITEMS(tbSh); /*number of items in S[h] */

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,8 @@
* reiserfs_ioctl - handler for ioctl for inode * reiserfs_ioctl - handler for ioctl for inode
* supported commands: * supported commands:
* 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect * 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect
* and prevent packing file (argument arg has to be non-zero) * and prevent packing file (argument arg has t
* be non-zero)
* 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION * 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION
* 3) That's all for a while ... * 3) That's all for a while ...
*/ */
@ -132,7 +133,10 @@ setversion_out:
long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
/* These are just misnamed, they actually get/put from/to user an int */ /*
* These are just misnamed, they actually
* get/put from/to user an int
*/
switch (cmd) { switch (cmd) {
case REISERFS_IOC32_UNPACK: case REISERFS_IOC32_UNPACK:
cmd = REISERFS_IOC_UNPACK; cmd = REISERFS_IOC_UNPACK;
@ -160,10 +164,10 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
int reiserfs_commit_write(struct file *f, struct page *page, int reiserfs_commit_write(struct file *f, struct page *page,
unsigned from, unsigned to); unsigned from, unsigned to);
/* /*
** reiserfs_unpack * reiserfs_unpack
** Function try to convert tail from direct item into indirect. * Function try to convert tail from direct item into indirect.
** It set up nopack attribute in the REISERFS_I(inode)->nopack * It set up nopack attribute in the REISERFS_I(inode)->nopack
*/ */
int reiserfs_unpack(struct inode *inode, struct file *filp) int reiserfs_unpack(struct inode *inode, struct file *filp)
{ {
int retval = 0; int retval = 0;
@ -194,9 +198,10 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
goto out; goto out;
} }
/* we unpack by finding the page with the tail, and calling /*
** __reiserfs_write_begin on that page. This will force a * we unpack by finding the page with the tail, and calling
** reiserfs_get_block to unpack the tail for us. * __reiserfs_write_begin on that page. This will force a
* reiserfs_get_block to unpack the tail for us.
*/ */
index = inode->i_size >> PAGE_CACHE_SHIFT; index = inode->i_size >> PAGE_CACHE_SHIFT;
mapping = inode->i_mapping; mapping = inode->i_mapping;

View File

@ -5,15 +5,17 @@
#include <linux/time.h> #include <linux/time.h>
#include "reiserfs.h" #include "reiserfs.h"
// this contains item handlers for old item types: sd, direct, /*
// indirect, directory * this contains item handlers for old item types: sd, direct,
* indirect, directory
*/
/* and where are the comments? how about saying where we can find an /*
explanation of each item handler method? -Hans */ * and where are the comments? how about saying where we can find an
* explanation of each item handler method? -Hans
*/
////////////////////////////////////////////////////////////////////////////// /* stat data functions */
// stat data functions
//
static int sd_bytes_number(struct item_head *ih, int block_size) static int sd_bytes_number(struct item_head *ih, int block_size)
{ {
return 0; return 0;
@ -60,7 +62,7 @@ static void sd_print_item(struct item_head *ih, char *item)
static void sd_check_item(struct item_head *ih, char *item) static void sd_check_item(struct item_head *ih, char *item)
{ {
// FIXME: type something here! /* unused */
} }
static int sd_create_vi(struct virtual_node *vn, static int sd_create_vi(struct virtual_node *vn,
@ -68,7 +70,6 @@ static int sd_create_vi(struct virtual_node *vn,
int is_affected, int insert_size) int is_affected, int insert_size)
{ {
vi->vi_index = TYPE_STAT_DATA; vi->vi_index = TYPE_STAT_DATA;
//vi->vi_type |= VI_TYPE_STAT_DATA;// not needed?
return 0; return 0;
} }
@ -117,15 +118,13 @@ static struct item_operations stat_data_ops = {
.print_vi = sd_print_vi .print_vi = sd_print_vi
}; };
////////////////////////////////////////////////////////////////////////////// /* direct item functions */
// direct item functions
//
static int direct_bytes_number(struct item_head *ih, int block_size) static int direct_bytes_number(struct item_head *ih, int block_size)
{ {
return ih_item_len(ih); return ih_item_len(ih);
} }
// FIXME: this should probably switch to indirect as well /* FIXME: this should probably switch to indirect as well */
static void direct_decrement_key(struct cpu_key *key) static void direct_decrement_key(struct cpu_key *key)
{ {
cpu_key_k_offset_dec(key); cpu_key_k_offset_dec(key);
@ -144,7 +143,7 @@ static void direct_print_item(struct item_head *ih, char *item)
{ {
int j = 0; int j = 0;
// return; /* return; */
printk("\""); printk("\"");
while (j < ih_item_len(ih)) while (j < ih_item_len(ih))
printk("%c", item[j++]); printk("%c", item[j++]);
@ -153,7 +152,7 @@ static void direct_print_item(struct item_head *ih, char *item)
static void direct_check_item(struct item_head *ih, char *item) static void direct_check_item(struct item_head *ih, char *item)
{ {
// FIXME: type something here! /* unused */
} }
static int direct_create_vi(struct virtual_node *vn, static int direct_create_vi(struct virtual_node *vn,
@ -161,7 +160,6 @@ static int direct_create_vi(struct virtual_node *vn,
int is_affected, int insert_size) int is_affected, int insert_size)
{ {
vi->vi_index = TYPE_DIRECT; vi->vi_index = TYPE_DIRECT;
//vi->vi_type |= VI_TYPE_DIRECT;
return 0; return 0;
} }
@ -211,16 +209,13 @@ static struct item_operations direct_ops = {
.print_vi = direct_print_vi .print_vi = direct_print_vi
}; };
////////////////////////////////////////////////////////////////////////////// /* indirect item functions */
// indirect item functions
//
static int indirect_bytes_number(struct item_head *ih, int block_size) static int indirect_bytes_number(struct item_head *ih, int block_size)
{ {
return ih_item_len(ih) / UNFM_P_SIZE * block_size; //- get_ih_free_space (ih); return ih_item_len(ih) / UNFM_P_SIZE * block_size;
} }
// decrease offset, if it becomes 0, change type to stat data /* decrease offset, if it becomes 0, change type to stat data */
static void indirect_decrement_key(struct cpu_key *key) static void indirect_decrement_key(struct cpu_key *key)
{ {
cpu_key_k_offset_dec(key); cpu_key_k_offset_dec(key);
@ -228,7 +223,7 @@ static void indirect_decrement_key(struct cpu_key *key)
set_cpu_key_k_type(key, TYPE_STAT_DATA); set_cpu_key_k_type(key, TYPE_STAT_DATA);
} }
// if it is not first item of the body, then it is mergeable /* if it is not first item of the body, then it is mergeable */
static int indirect_is_left_mergeable(struct reiserfs_key *key, static int indirect_is_left_mergeable(struct reiserfs_key *key,
unsigned long bsize) unsigned long bsize)
{ {
@ -236,7 +231,7 @@ static int indirect_is_left_mergeable(struct reiserfs_key *key,
return (le_key_k_offset(version, key) != 1); return (le_key_k_offset(version, key) != 1);
} }
// printing of indirect item /* printing of indirect item */
static void start_new_sequence(__u32 * start, int *len, __u32 new) static void start_new_sequence(__u32 * start, int *len, __u32 new)
{ {
*start = new; *start = new;
@ -295,7 +290,7 @@ static void indirect_print_item(struct item_head *ih, char *item)
static void indirect_check_item(struct item_head *ih, char *item) static void indirect_check_item(struct item_head *ih, char *item)
{ {
// FIXME: type something here! /* unused */
} }
static int indirect_create_vi(struct virtual_node *vn, static int indirect_create_vi(struct virtual_node *vn,
@ -303,7 +298,6 @@ static int indirect_create_vi(struct virtual_node *vn,
int is_affected, int insert_size) int is_affected, int insert_size)
{ {
vi->vi_index = TYPE_INDIRECT; vi->vi_index = TYPE_INDIRECT;
//vi->vi_type |= VI_TYPE_INDIRECT;
return 0; return 0;
} }
@ -321,16 +315,19 @@ static int indirect_check_right(struct virtual_item *vi, int free)
return indirect_check_left(vi, free, 0, 0); return indirect_check_left(vi, free, 0, 0);
} }
// return size in bytes of 'units' units. If first == 0 - calculate from the head (left), otherwise - from tail (right) /*
* return size in bytes of 'units' units. If first == 0 - calculate
* from the head (left), otherwise - from tail (right)
*/
static int indirect_part_size(struct virtual_item *vi, int first, int units) static int indirect_part_size(struct virtual_item *vi, int first, int units)
{ {
// unit of indirect item is byte (yet) /* unit of indirect item is byte (yet) */
return units; return units;
} }
static int indirect_unit_num(struct virtual_item *vi) static int indirect_unit_num(struct virtual_item *vi)
{ {
// unit of indirect item is byte (yet) /* unit of indirect item is byte (yet) */
return vi->vi_item_len - IH_SIZE; return vi->vi_item_len - IH_SIZE;
} }
@ -356,10 +353,7 @@ static struct item_operations indirect_ops = {
.print_vi = indirect_print_vi .print_vi = indirect_print_vi
}; };
////////////////////////////////////////////////////////////////////////////// /* direntry functions */
// direntry functions
//
static int direntry_bytes_number(struct item_head *ih, int block_size) static int direntry_bytes_number(struct item_head *ih, int block_size)
{ {
reiserfs_warning(NULL, "vs-16090", reiserfs_warning(NULL, "vs-16090",
@ -428,7 +422,7 @@ static void direntry_check_item(struct item_head *ih, char *item)
int i; int i;
struct reiserfs_de_head *deh; struct reiserfs_de_head *deh;
// FIXME: type something here! /* unused */
deh = (struct reiserfs_de_head *)item; deh = (struct reiserfs_de_head *)item;
for (i = 0; i < ih_entry_count(ih); i++, deh++) { for (i = 0; i < ih_entry_count(ih); i++, deh++) {
; ;
@ -439,7 +433,8 @@ static void direntry_check_item(struct item_head *ih, char *item)
/* /*
* function returns old entry number in directory item in real node * function returns old entry number in directory item in real node
* using new entry number in virtual item in virtual node */ * using new entry number in virtual item in virtual node
*/
static inline int old_entry_num(int is_affected, int virtual_entry_num, static inline int old_entry_num(int is_affected, int virtual_entry_num,
int pos_in_item, int mode) int pos_in_item, int mode)
{ {
@ -463,9 +458,11 @@ static inline int old_entry_num(int is_affected, int virtual_entry_num,
return virtual_entry_num - 1; return virtual_entry_num - 1;
} }
/* Create an array of sizes of directory entries for virtual /*
item. Return space used by an item. FIXME: no control over * Create an array of sizes of directory entries for virtual
consuming of space used by this item handler */ * item. Return space used by an item. FIXME: no control over
* consuming of space used by this item handler
*/
static int direntry_create_vi(struct virtual_node *vn, static int direntry_create_vi(struct virtual_node *vn,
struct virtual_item *vi, struct virtual_item *vi,
int is_affected, int insert_size) int is_affected, int insert_size)
@ -529,10 +526,10 @@ static int direntry_create_vi(struct virtual_node *vn,
} }
// /*
// return number of entries which may fit into specified amount of * return number of entries which may fit into specified amount of
// free space, or -1 if free space is not enough even for 1 entry * free space, or -1 if free space is not enough even for 1 entry
// */
static int direntry_check_left(struct virtual_item *vi, int free, static int direntry_check_left(struct virtual_item *vi, int free,
int start_skip, int end_skip) int start_skip, int end_skip)
{ {
@ -541,8 +538,8 @@ static int direntry_check_left(struct virtual_item *vi, int free,
struct direntry_uarea *dir_u = vi->vi_uarea; struct direntry_uarea *dir_u = vi->vi_uarea;
for (i = start_skip; i < dir_u->entry_count - end_skip; i++) { for (i = start_skip; i < dir_u->entry_count - end_skip; i++) {
/* i-th entry doesn't fit into the remaining free space */
if (dir_u->entry_sizes[i] > free) if (dir_u->entry_sizes[i] > free)
/* i-th entry doesn't fit into the remaining free space */
break; break;
free -= dir_u->entry_sizes[i]; free -= dir_u->entry_sizes[i];
@ -570,8 +567,8 @@ static int direntry_check_right(struct virtual_item *vi, int free)
struct direntry_uarea *dir_u = vi->vi_uarea; struct direntry_uarea *dir_u = vi->vi_uarea;
for (i = dir_u->entry_count - 1; i >= 0; i--) { for (i = dir_u->entry_count - 1; i >= 0; i--) {
/* i-th entry doesn't fit into the remaining free space */
if (dir_u->entry_sizes[i] > free) if (dir_u->entry_sizes[i] > free)
/* i-th entry doesn't fit into the remaining free space */
break; break;
free -= dir_u->entry_sizes[i]; free -= dir_u->entry_sizes[i];
@ -643,9 +640,7 @@ static struct item_operations direntry_ops = {
.print_vi = direntry_print_vi .print_vi = direntry_print_vi
}; };
////////////////////////////////////////////////////////////////////////////// /* Error catching functions to catch errors caused by incorrect item types. */
// Error catching functions to catch errors caused by incorrect item types.
//
static int errcatch_bytes_number(struct item_head *ih, int block_size) static int errcatch_bytes_number(struct item_head *ih, int block_size)
{ {
reiserfs_warning(NULL, "green-16001", reiserfs_warning(NULL, "green-16001",
@ -685,8 +680,12 @@ static int errcatch_create_vi(struct virtual_node *vn,
{ {
reiserfs_warning(NULL, "green-16006", reiserfs_warning(NULL, "green-16006",
"Invalid item type observed, run fsck ASAP"); "Invalid item type observed, run fsck ASAP");
return 0; // We might return -1 here as well, but it won't help as create_virtual_node() from where /*
// this operation is called from is of return type void. * We might return -1 here as well, but it won't help as
* create_virtual_node() from where this operation is called
* from is of return type void.
*/
return 0;
} }
static int errcatch_check_left(struct virtual_item *vi, int free, static int errcatch_check_left(struct virtual_item *vi, int free,
@ -739,9 +738,6 @@ static struct item_operations errcatch_ops = {
errcatch_print_vi errcatch_print_vi
}; };
//////////////////////////////////////////////////////////////////////////////
//
//
#if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3) #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
#error Item types must use disk-format assigned values. #error Item types must use disk-format assigned values.
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -8,28 +8,21 @@
#include "reiserfs.h" #include "reiserfs.h"
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
/* these are used in do_balance.c */ /*
* copy copy_count entries from source directory item to dest buffer
/* leaf_move_items * (creating new item if needed)
leaf_shift_left */
leaf_shift_right
leaf_delete_items
leaf_insert_into_buf
leaf_paste_in_buffer
leaf_cut_from_buffer
leaf_paste_entries
*/
/* copy copy_count entries from source directory item to dest buffer (creating new item if needed) */
static void leaf_copy_dir_entries(struct buffer_info *dest_bi, static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
struct buffer_head *source, int last_first, struct buffer_head *source, int last_first,
int item_num, int from, int copy_count) int item_num, int from, int copy_count)
{ {
struct buffer_head *dest = dest_bi->bi_bh; struct buffer_head *dest = dest_bi->bi_bh;
int item_num_in_dest; /* either the number of target item, /*
or if we must create a new item, * either the number of target item, or if we must create a
the number of the item we will * new item, the number of the item we will create it next to
create it next to */ */
int item_num_in_dest;
struct item_head *ih; struct item_head *ih;
struct reiserfs_de_head *deh; struct reiserfs_de_head *deh;
int copy_records_len; /* length of all records in item to be copied */ int copy_records_len; /* length of all records in item to be copied */
@ -39,7 +32,10 @@ static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item"); RFALSE(!is_direntry_le_ih(ih), "vs-10000: item must be directory item");
/* length of all record to be copied and first byte of the last of them */ /*
* length of all record to be copied and first byte of
* the last of them
*/
deh = B_I_DEH(source, ih); deh = B_I_DEH(source, ih);
if (copy_count) { if (copy_count) {
copy_records_len = (from ? deh_location(&(deh[from - 1])) : copy_records_len = (from ? deh_location(&(deh[from - 1])) :
@ -59,7 +55,10 @@ static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest) LAST_TO_FIRST) ? ((B_NR_ITEMS(dest)) ? 0 : -1) : (B_NR_ITEMS(dest)
- 1); - 1);
/* if there are no items in dest or the first/last item in dest is not item of the same directory */ /*
* if there are no items in dest or the first/last item in
* dest is not item of the same directory
*/
if ((item_num_in_dest == -1) || if ((item_num_in_dest == -1) ||
(last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) || (last_first == FIRST_TO_LAST && le_ih_k_offset(ih) == DOT_OFFSET) ||
(last_first == LAST_TO_FIRST (last_first == LAST_TO_FIRST
@ -83,11 +82,17 @@ static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
if (from < ih_entry_count(ih)) { if (from < ih_entry_count(ih)) {
set_le_ih_k_offset(&new_ih, set_le_ih_k_offset(&new_ih,
deh_offset(&(deh[from]))); deh_offset(&(deh[from])));
/*memcpy (&new_ih.ih_key.k_offset, &deh[from].deh_offset, SHORT_KEY_SIZE); */
} else { } else {
/* no entries will be copied to this item in this function */ /*
* no entries will be copied to this
* item in this function
*/
set_le_ih_k_offset(&new_ih, U32_MAX); set_le_ih_k_offset(&new_ih, U32_MAX);
/* this item is not yet valid, but we want I_IS_DIRECTORY_ITEM to return 1 for it, so we -1 */ /*
* this item is not yet valid, but we
* want I_IS_DIRECTORY_ITEM to return 1
* for it, so we -1
*/
} }
set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key), set_le_key_k_type(KEY_FORMAT_3_5, &(new_ih.ih_key),
TYPE_DIRENTRY); TYPE_DIRENTRY);
@ -119,30 +124,38 @@ static void leaf_copy_dir_entries(struct buffer_info *dest_bi,
DEH_SIZE * copy_count + copy_records_len); DEH_SIZE * copy_count + copy_records_len);
} }
/* Copy the first (if last_first == FIRST_TO_LAST) or last (last_first == LAST_TO_FIRST) item or /*
part of it or nothing (see the return 0 below) from SOURCE to the end * Copy the first (if last_first == FIRST_TO_LAST) or last
(if last_first) or beginning (!last_first) of the DEST */ * (last_first == LAST_TO_FIRST) item or part of it or nothing
* (see the return 0 below) from SOURCE to the end (if last_first)
* or beginning (!last_first) of the DEST
*/
/* returns 1 if anything was copied, else 0 */ /* returns 1 if anything was copied, else 0 */
static int leaf_copy_boundary_item(struct buffer_info *dest_bi, static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
struct buffer_head *src, int last_first, struct buffer_head *src, int last_first,
int bytes_or_entries) int bytes_or_entries)
{ {
struct buffer_head *dest = dest_bi->bi_bh; struct buffer_head *dest = dest_bi->bi_bh;
int dest_nr_item, src_nr_item; /* number of items in the source and destination buffers */ /* number of items in the source and destination buffers */
int dest_nr_item, src_nr_item;
struct item_head *ih; struct item_head *ih;
struct item_head *dih; struct item_head *dih;
dest_nr_item = B_NR_ITEMS(dest); dest_nr_item = B_NR_ITEMS(dest);
/*
* if ( DEST is empty or first item of SOURCE and last item of
* DEST are the items of different objects or of different types )
* then there is no need to treat this item differently from the
* other items that we copy, so we return
*/
if (last_first == FIRST_TO_LAST) { if (last_first == FIRST_TO_LAST) {
/* if ( DEST is empty or first item of SOURCE and last item of DEST are the items of different objects
or of different types ) then there is no need to treat this item differently from the other items
that we copy, so we return */
ih = item_head(src, 0); ih = item_head(src, 0);
dih = item_head(dest, dest_nr_item - 1); dih = item_head(dest, dest_nr_item - 1);
/* there is nothing to merge */
if (!dest_nr_item if (!dest_nr_item
|| (!op_is_left_mergeable(&(ih->ih_key), src->b_size))) || (!op_is_left_mergeable(&(ih->ih_key), src->b_size)))
/* there is nothing to merge */
return 0; return 0;
RFALSE(!ih_item_len(ih), RFALSE(!ih_item_len(ih),
@ -157,8 +170,11 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
return 1; return 1;
} }
/* copy part of the body of the first item of SOURCE to the end of the body of the last item of the DEST /*
part defined by 'bytes_or_entries'; if bytes_or_entries == -1 copy whole body; don't create new item header * copy part of the body of the first item of SOURCE
* to the end of the body of the last item of the DEST
* part defined by 'bytes_or_entries'; if bytes_or_entries
* == -1 copy whole body; don't create new item header
*/ */
if (bytes_or_entries == -1) if (bytes_or_entries == -1)
bytes_or_entries = ih_item_len(ih); bytes_or_entries = ih_item_len(ih);
@ -176,8 +192,10 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
} }
#endif #endif
/* merge first item (or its part) of src buffer with the last /*
item of dest buffer. Both are of the same file */ * merge first item (or its part) of src buffer with the last
* item of dest buffer. Both are of the same file
*/
leaf_paste_in_buffer(dest_bi, leaf_paste_in_buffer(dest_bi,
dest_nr_item - 1, ih_item_len(dih), dest_nr_item - 1, ih_item_len(dih),
bytes_or_entries, ih_item_body(src, ih), 0); bytes_or_entries, ih_item_body(src, ih), 0);
@ -195,8 +213,9 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
/* copy boundary item to right (last_first == LAST_TO_FIRST) */ /* copy boundary item to right (last_first == LAST_TO_FIRST) */
/* ( DEST is empty or last item of SOURCE and first item of DEST /*
are the items of different object or of different types ) * (DEST is empty or last item of SOURCE and first item of DEST
* are the items of different object or of different types)
*/ */
src_nr_item = B_NR_ITEMS(src); src_nr_item = B_NR_ITEMS(src);
ih = item_head(src, src_nr_item - 1); ih = item_head(src, src_nr_item - 1);
@ -206,8 +225,11 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
return 0; return 0;
if (is_direntry_le_ih(ih)) { if (is_direntry_le_ih(ih)) {
/*
* bytes_or_entries = entries number in last
* item body of SOURCE
*/
if (bytes_or_entries == -1) if (bytes_or_entries == -1)
/* bytes_or_entries = entries number in last item body of SOURCE */
bytes_or_entries = ih_entry_count(ih); bytes_or_entries = ih_entry_count(ih);
leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST, leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
@ -217,9 +239,11 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
return 1; return 1;
} }
/* copy part of the body of the last item of SOURCE to the begin of the body of the first item of the DEST; /*
part defined by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body; change first item key of the DEST; * copy part of the body of the last item of SOURCE to the
don't create new item header * begin of the body of the first item of the DEST; part defined
* by 'bytes_or_entries'; if byte_or_entriess == -1 copy whole body;
* change first item key of the DEST; don't create new item header
*/ */
RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih), RFALSE(is_indirect_le_ih(ih) && get_ih_free_space(ih),
@ -276,9 +300,12 @@ static int leaf_copy_boundary_item(struct buffer_info *dest_bi,
return 1; return 1;
} }
/* copy cpy_mun items from buffer src to buffer dest /*
* last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning from first-th item in src to tail of dest * copy cpy_mun items from buffer src to buffer dest
* last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning from first-th item in src to head of dest * last_first == FIRST_TO_LAST means, that we copy cpy_num items beginning
* from first-th item in src to tail of dest
* last_first == LAST_TO_FIRST means, that we copy cpy_num items beginning
* from first-th item in src to head of dest
*/ */
static void leaf_copy_items_entirely(struct buffer_info *dest_bi, static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
struct buffer_head *src, int last_first, struct buffer_head *src, int last_first,
@ -311,7 +338,10 @@ static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
nr = blkh_nr_item(blkh); nr = blkh_nr_item(blkh);
free_space = blkh_free_space(blkh); free_space = blkh_free_space(blkh);
/* we will insert items before 0-th or nr-th item in dest buffer. It depends of last_first parameter */ /*
* we will insert items before 0-th or nr-th item in dest buffer.
* It depends of last_first parameter
*/
dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr; dest_before = (last_first == LAST_TO_FIRST) ? 0 : nr;
/* location of head of first new item */ /* location of head of first new item */
@ -377,8 +407,10 @@ static void leaf_copy_items_entirely(struct buffer_info *dest_bi,
} }
} }
/* This function splits the (liquid) item into two items (useful when /*
shifting part of an item into another node.) */ * This function splits the (liquid) item into two items (useful when
* shifting part of an item into another node.)
*/
static void leaf_item_bottle(struct buffer_info *dest_bi, static void leaf_item_bottle(struct buffer_info *dest_bi,
struct buffer_head *src, int last_first, struct buffer_head *src, int last_first,
int item_num, int cpy_bytes) int item_num, int cpy_bytes)
@ -390,7 +422,10 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
"vs-10170: bytes == - 1 means: do not split item"); "vs-10170: bytes == - 1 means: do not split item");
if (last_first == FIRST_TO_LAST) { if (last_first == FIRST_TO_LAST) {
/* if ( if item in position item_num in buffer SOURCE is directory item ) */ /*
* if ( if item in position item_num in buffer SOURCE
* is directory item )
*/
ih = item_head(src, item_num); ih = item_head(src, item_num);
if (is_direntry_le_ih(ih)) if (is_direntry_le_ih(ih))
leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST, leaf_copy_dir_entries(dest_bi, src, FIRST_TO_LAST,
@ -398,9 +433,11 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
else { else {
struct item_head n_ih; struct item_head n_ih;
/* copy part of the body of the item number 'item_num' of SOURCE to the end of the DEST /*
part defined by 'cpy_bytes'; create new item header; change old item_header (????); * copy part of the body of the item number 'item_num'
n_ih = new item_header; * of SOURCE to the end of the DEST part defined by
* 'cpy_bytes'; create new item header; change old
* item_header (????); n_ih = new item_header;
*/ */
memcpy(&n_ih, ih, IH_SIZE); memcpy(&n_ih, ih, IH_SIZE);
put_ih_item_len(&n_ih, cpy_bytes); put_ih_item_len(&n_ih, cpy_bytes);
@ -419,7 +456,10 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
item_body(src, item_num), 0); item_body(src, item_num), 0);
} }
} else { } else {
/* if ( if item in position item_num in buffer SOURCE is directory item ) */ /*
* if ( if item in position item_num in buffer
* SOURCE is directory item )
*/
ih = item_head(src, item_num); ih = item_head(src, item_num);
if (is_direntry_le_ih(ih)) if (is_direntry_le_ih(ih))
leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST, leaf_copy_dir_entries(dest_bi, src, LAST_TO_FIRST,
@ -429,13 +469,16 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
else { else {
struct item_head n_ih; struct item_head n_ih;
/* copy part of the body of the item number 'item_num' of SOURCE to the begin of the DEST /*
part defined by 'cpy_bytes'; create new item header; * copy part of the body of the item number 'item_num'
n_ih = new item_header; * of SOURCE to the begin of the DEST part defined by
* 'cpy_bytes'; create new item header;
* n_ih = new item_header;
*/ */
memcpy(&n_ih, ih, SHORT_KEY_SIZE); memcpy(&n_ih, ih, SHORT_KEY_SIZE);
n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */ /* Endian safe, both le */
n_ih.ih_version = ih->ih_version;
if (is_direct_le_ih(ih)) { if (is_direct_le_ih(ih)) {
set_le_ih_k_offset(&n_ih, set_le_ih_k_offset(&n_ih,
@ -459,7 +502,8 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
/* set item length */ /* set item length */
put_ih_item_len(&n_ih, cpy_bytes); put_ih_item_len(&n_ih, cpy_bytes);
n_ih.ih_version = ih->ih_version; /* JDM Endian safe, both le */ /* Endian safe, both le */
n_ih.ih_version = ih->ih_version;
leaf_insert_into_buf(dest_bi, 0, &n_ih, leaf_insert_into_buf(dest_bi, 0, &n_ih,
item_body(src, item_num) + item_body(src, item_num) +
@ -468,10 +512,12 @@ static void leaf_item_bottle(struct buffer_info *dest_bi,
} }
} }
/* If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE to DEST. /*
If cpy_bytes not equal to minus one than copy cpy_num-1 whole items from SOURCE to DEST. * If cpy_bytes equals minus one than copy cpy_num whole items from SOURCE
From last item copy cpy_num bytes for regular item and cpy_num directory entries for * to DEST. If cpy_bytes not equal to minus one than copy cpy_num-1 whole
directory item. */ * items from SOURCE to DEST. From last item copy cpy_num bytes for regular
* item and cpy_num directory entries for directory item.
*/
static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src, static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
int last_first, int cpy_num, int cpy_bytes) int last_first, int cpy_num, int cpy_bytes)
{ {
@ -498,22 +544,34 @@ static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
else else
bytes = -1; bytes = -1;
/* copy the first item or it part or nothing to the end of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes)) */ /*
* copy the first item or it part or nothing to the end of
* the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,0,bytes))
*/
i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes); i = leaf_copy_boundary_item(dest_bi, src, FIRST_TO_LAST, bytes);
cpy_num -= i; cpy_num -= i;
if (cpy_num == 0) if (cpy_num == 0)
return i; return i;
pos += i; pos += i;
if (cpy_bytes == -1) if (cpy_bytes == -1)
/* copy first cpy_num items starting from position 'pos' of SOURCE to end of DEST */ /*
* copy first cpy_num items starting from position
* 'pos' of SOURCE to end of DEST
*/
leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST, leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
pos, cpy_num); pos, cpy_num);
else { else {
/* copy first cpy_num-1 items starting from position 'pos-1' of the SOURCE to the end of the DEST */ /*
* copy first cpy_num-1 items starting from position
* 'pos-1' of the SOURCE to the end of the DEST
*/
leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST, leaf_copy_items_entirely(dest_bi, src, FIRST_TO_LAST,
pos, cpy_num - 1); pos, cpy_num - 1);
/* copy part of the item which number is cpy_num+pos-1 to the end of the DEST */ /*
* copy part of the item which number is
* cpy_num+pos-1 to the end of the DEST
*/
leaf_item_bottle(dest_bi, src, FIRST_TO_LAST, leaf_item_bottle(dest_bi, src, FIRST_TO_LAST,
cpy_num + pos - 1, cpy_bytes); cpy_num + pos - 1, cpy_bytes);
} }
@ -525,7 +583,11 @@ static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
else else
bytes = -1; bytes = -1;
/* copy the last item or it part or nothing to the begin of the DEST (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes)); */ /*
* copy the last item or it part or nothing to the
* begin of the DEST
* (i = leaf_copy_boundary_item(DEST,SOURCE,1,bytes));
*/
i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes); i = leaf_copy_boundary_item(dest_bi, src, LAST_TO_FIRST, bytes);
cpy_num -= i; cpy_num -= i;
@ -534,15 +596,24 @@ static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
pos = src_nr_item - cpy_num - i; pos = src_nr_item - cpy_num - i;
if (cpy_bytes == -1) { if (cpy_bytes == -1) {
/* starting from position 'pos' copy last cpy_num items of SOURCE to begin of DEST */ /*
* starting from position 'pos' copy last cpy_num
* items of SOURCE to begin of DEST
*/
leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST, leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
pos, cpy_num); pos, cpy_num);
} else { } else {
/* copy last cpy_num-1 items starting from position 'pos+1' of the SOURCE to the begin of the DEST; */ /*
* copy last cpy_num-1 items starting from position
* 'pos+1' of the SOURCE to the begin of the DEST;
*/
leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST, leaf_copy_items_entirely(dest_bi, src, LAST_TO_FIRST,
pos + 1, cpy_num - 1); pos + 1, cpy_num - 1);
/* copy part of the item which number is pos to the begin of the DEST */ /*
* copy part of the item which number is pos to
* the begin of the DEST
*/
leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos, leaf_item_bottle(dest_bi, src, LAST_TO_FIRST, pos,
cpy_bytes); cpy_bytes);
} }
@ -550,9 +621,11 @@ static int leaf_copy_items(struct buffer_info *dest_bi, struct buffer_head *src,
return i; return i;
} }
/* there are types of coping: from S[0] to L[0], from S[0] to R[0], /*
from R[0] to L[0]. for each of these we have to define parent and * there are types of coping: from S[0] to L[0], from S[0] to R[0],
positions of destination and source buffers */ * from R[0] to L[0]. for each of these we have to define parent and
* positions of destination and source buffers
*/
static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb, static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
struct buffer_info *dest_bi, struct buffer_info *dest_bi,
struct buffer_info *src_bi, struct buffer_info *src_bi,
@ -568,7 +641,9 @@ static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
src_bi->tb = tb; src_bi->tb = tb;
src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path); src_bi->bi_bh = PATH_PLAST_BUFFER(tb->tb_path);
src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0); src_bi->bi_parent = PATH_H_PPARENT(tb->tb_path, 0);
src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0); /* src->b_item_order */
/* src->b_item_order */
src_bi->bi_position = PATH_H_B_ITEM_ORDER(tb->tb_path, 0);
dest_bi->tb = tb; dest_bi->tb = tb;
dest_bi->bi_bh = tb->L[0]; dest_bi->bi_bh = tb->L[0];
dest_bi->bi_parent = tb->FL[0]; dest_bi->bi_parent = tb->FL[0];
@ -633,8 +708,10 @@ static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
shift_mode, src_bi->bi_bh, dest_bi->bi_bh); shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
} }
/* copy mov_num items and mov_bytes of the (mov_num-1)th item to /*
neighbor. Delete them from source */ * copy mov_num items and mov_bytes of the (mov_num-1)th item to
* neighbor. Delete them from source
*/
int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num, int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
int mov_bytes, struct buffer_head *Snew) int mov_bytes, struct buffer_head *Snew)
{ {
@ -657,18 +734,24 @@ int leaf_move_items(int shift_mode, struct tree_balance *tb, int mov_num,
return ret_value; return ret_value;
} }
/* Shift shift_num items (and shift_bytes of last shifted item if shift_bytes != -1) /*
from S[0] to L[0] and replace the delimiting key */ * Shift shift_num items (and shift_bytes of last shifted item if
* shift_bytes != -1) from S[0] to L[0] and replace the delimiting key
*/
int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes) int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
{ {
struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path); struct buffer_head *S0 = PATH_PLAST_BUFFER(tb->tb_path);
int i; int i;
/* move shift_num (and shift_bytes bytes) items from S[0] to left neighbor L[0] */ /*
* move shift_num (and shift_bytes bytes) items from S[0]
* to left neighbor L[0]
*/
i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL); i = leaf_move_items(LEAF_FROM_S_TO_L, tb, shift_num, shift_bytes, NULL);
if (shift_num) { if (shift_num) {
if (B_NR_ITEMS(S0) == 0) { /* number of items in S[0] == 0 */ /* number of items in S[0] == 0 */
if (B_NR_ITEMS(S0) == 0) {
RFALSE(shift_bytes != -1, RFALSE(shift_bytes != -1,
"vs-10270: S0 is empty now, but shift_bytes != -1 (%d)", "vs-10270: S0 is empty now, but shift_bytes != -1 (%d)",
@ -704,13 +787,18 @@ int leaf_shift_left(struct tree_balance *tb, int shift_num, int shift_bytes)
/* CLEANING STOPPED HERE */ /* CLEANING STOPPED HERE */
/* Shift shift_num (shift_bytes) items from S[0] to the right neighbor, and replace the delimiting key */ /*
* Shift shift_num (shift_bytes) items from S[0] to the right neighbor,
* and replace the delimiting key
*/
int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes) int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
{ {
// struct buffer_head * S0 = PATH_PLAST_BUFFER (tb->tb_path);
int ret_value; int ret_value;
/* move shift_num (and shift_bytes) items from S[0] to right neighbor R[0] */ /*
* move shift_num (and shift_bytes) items from S[0] to
* right neighbor R[0]
*/
ret_value = ret_value =
leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL); leaf_move_items(LEAF_FROM_S_TO_R, tb, shift_num, shift_bytes, NULL);
@ -725,12 +813,16 @@ int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes)
static void leaf_delete_items_entirely(struct buffer_info *bi, static void leaf_delete_items_entirely(struct buffer_info *bi,
int first, int del_num); int first, int del_num);
/* If del_bytes == -1, starting from position 'first' delete del_num items in whole in buffer CUR. /*
If not. * If del_bytes == -1, starting from position 'first' delete del_num
If last_first == 0. Starting from position 'first' delete del_num-1 items in whole. Delete part of body of * items in whole in buffer CUR.
the first item. Part defined by del_bytes. Don't delete first item header * If not.
If last_first == 1. Starting from position 'first+1' delete del_num-1 items in whole. Delete part of body of * If last_first == 0. Starting from position 'first' delete del_num-1
the last item . Part defined by del_bytes. Don't delete last item header. * items in whole. Delete part of body of the first item. Part defined by
* del_bytes. Don't delete first item header
* If last_first == 1. Starting from position 'first+1' delete del_num-1
* items in whole. Delete part of body of the last item . Part defined by
* del_bytes. Don't delete last item header.
*/ */
void leaf_delete_items(struct buffer_info *cur_bi, int last_first, void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
int first, int del_num, int del_bytes) int first, int del_num, int del_bytes)
@ -761,32 +853,43 @@ void leaf_delete_items(struct buffer_info *cur_bi, int last_first,
leaf_delete_items_entirely(cur_bi, first, del_num); leaf_delete_items_entirely(cur_bi, first, del_num);
else { else {
if (last_first == FIRST_TO_LAST) { if (last_first == FIRST_TO_LAST) {
/* delete del_num-1 items beginning from item in position first */ /*
* delete del_num-1 items beginning from
* item in position first
*/
leaf_delete_items_entirely(cur_bi, first, del_num - 1); leaf_delete_items_entirely(cur_bi, first, del_num - 1);
/* delete the part of the first item of the bh /*
do not delete item header * delete the part of the first item of the bh
* do not delete item header
*/ */
leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes); leaf_cut_from_buffer(cur_bi, 0, 0, del_bytes);
} else { } else {
struct item_head *ih; struct item_head *ih;
int len; int len;
/* delete del_num-1 items beginning from item in position first+1 */ /*
* delete del_num-1 items beginning from
* item in position first+1
*/
leaf_delete_items_entirely(cur_bi, first + 1, leaf_delete_items_entirely(cur_bi, first + 1,
del_num - 1); del_num - 1);
ih = item_head(bh, B_NR_ITEMS(bh) - 1); ih = item_head(bh, B_NR_ITEMS(bh) - 1);
if (is_direntry_le_ih(ih)) if (is_direntry_le_ih(ih))
/* the last item is directory */ /* the last item is directory */
/* len = numbers of directory entries in this item */ /*
* len = numbers of directory entries
* in this item
*/
len = ih_entry_count(ih); len = ih_entry_count(ih);
else else
/* len = body len of item */ /* len = body len of item */
len = ih_item_len(ih); len = ih_item_len(ih);
/* delete the part of the last item of the bh /*
do not delete item header * delete the part of the last item of the bh
* do not delete item header
*/ */
leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1, leaf_cut_from_buffer(cur_bi, B_NR_ITEMS(bh) - 1,
len - del_bytes, del_bytes); len - del_bytes, del_bytes);
@ -867,8 +970,10 @@ void leaf_insert_into_buf(struct buffer_info *bi, int before,
} }
} }
/* paste paste_size bytes to affected_item_num-th item. /*
When item is a directory, this only prepare space for new entries */ * paste paste_size bytes to affected_item_num-th item.
* When item is a directory, this only prepare space for new entries
*/
void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num, void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
int pos_in_item, int paste_size, int pos_in_item, int paste_size,
const char *body, int zeros_number) const char *body, int zeros_number)
@ -957,10 +1062,12 @@ void leaf_paste_in_buffer(struct buffer_info *bi, int affected_item_num,
} }
} }
/* cuts DEL_COUNT entries beginning from FROM-th entry. Directory item /*
does not have free space, so it moves DEHs and remaining records as * cuts DEL_COUNT entries beginning from FROM-th entry. Directory item
necessary. Return value is size of removed part of directory item * does not have free space, so it moves DEHs and remaining records as
in bytes. */ * necessary. Return value is size of removed part of directory item
* in bytes.
*/
static int leaf_cut_entries(struct buffer_head *bh, static int leaf_cut_entries(struct buffer_head *bh,
struct item_head *ih, int from, int del_count) struct item_head *ih, int from, int del_count)
{ {
@ -971,8 +1078,10 @@ static int leaf_cut_entries(struct buffer_head *bh,
int cut_records_len; /* length of all removed records */ int cut_records_len; /* length of all removed records */
int i; int i;
/* make sure, that item is directory and there are enough entries to /*
remove */ * make sure that item is directory and there are enough entries to
* remove
*/
RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item"); RFALSE(!is_direntry_le_ih(ih), "10180: item is not directory item");
RFALSE(ih_entry_count(ih) < from + del_count, RFALSE(ih_entry_count(ih) < from + del_count,
"10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d", "10185: item contains not enough entries: entry_count = %d, from = %d, to delete = %d",
@ -987,8 +1096,10 @@ static int leaf_cut_entries(struct buffer_head *bh,
/* entry head array */ /* entry head array */
deh = B_I_DEH(bh, ih); deh = B_I_DEH(bh, ih);
/* first byte of remaining entries, those are BEFORE cut entries /*
(prev_record) and length of all removed records (cut_records_len) */ * first byte of remaining entries, those are BEFORE cut entries
* (prev_record) and length of all removed records (cut_records_len)
*/
prev_record_offset = prev_record_offset =
(from ? deh_location(&(deh[from - 1])) : ih_item_len(ih)); (from ? deh_location(&(deh[from - 1])) : ih_item_len(ih));
cut_records_len = prev_record_offset /*from_record */ - cut_records_len = prev_record_offset /*from_record */ -
@ -1021,14 +1132,15 @@ static int leaf_cut_entries(struct buffer_head *bh,
return DEH_SIZE * del_count + cut_records_len; return DEH_SIZE * del_count + cut_records_len;
} }
/* when cut item is part of regular file /*
pos_in_item - first byte that must be cut * when cut item is part of regular file
cut_size - number of bytes to be cut beginning from pos_in_item * pos_in_item - first byte that must be cut
* cut_size - number of bytes to be cut beginning from pos_in_item
when cut item is part of directory *
pos_in_item - number of first deleted entry * when cut item is part of directory
cut_size - count of deleted entries * pos_in_item - number of first deleted entry
*/ * cut_size - count of deleted entries
*/
void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num, void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
int pos_in_item, int cut_size) int pos_in_item, int cut_size)
{ {
@ -1055,7 +1167,6 @@ void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num,
cut_item_num); cut_item_num);
/* change item key by key of first entry in the item */ /* change item key by key of first entry in the item */
set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih))); set_le_ih_k_offset(ih, deh_offset(B_I_DEH(bh, ih)));
/*memcpy (&ih->ih_key.k_offset, &(B_I_DEH (bh, ih)->deh_offset), SHORT_KEY_SIZE); */
} }
} else { } else {
/* item is direct or indirect */ /* item is direct or indirect */
@ -1195,7 +1306,10 @@ static void leaf_delete_items_entirely(struct buffer_info *bi,
} }
} }
/* paste new_entry_count entries (new_dehs, records) into position before to item_num-th item */ /*
* paste new_entry_count entries (new_dehs, records) into position
* before to item_num-th item
*/
void leaf_paste_entries(struct buffer_info *bi, void leaf_paste_entries(struct buffer_info *bi,
int item_num, int item_num,
int before, int before,
@ -1215,7 +1329,10 @@ void leaf_paste_entries(struct buffer_info *bi,
ih = item_head(bh, item_num); ih = item_head(bh, item_num);
/* make sure, that item is directory, and there are enough records in it */ /*
* make sure, that item is directory, and there are enough
* records in it
*/
RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item"); RFALSE(!is_direntry_le_ih(ih), "10225: item is not directory item");
RFALSE(ih_entry_count(ih) < before, RFALSE(ih_entry_count(ih) < before,
"10230: there are no entry we paste entries before. entry_count = %d, before = %d", "10230: there are no entry we paste entries before. entry_count = %d, before = %d",
@ -1277,8 +1394,6 @@ void leaf_paste_entries(struct buffer_info *bi,
/* change item key if necessary (when we paste before 0-th entry */ /* change item key if necessary (when we paste before 0-th entry */
if (!before) { if (!before) {
set_le_ih_k_offset(ih, deh_offset(new_dehs)); set_le_ih_k_offset(ih, deh_offset(new_dehs));
/* memcpy (&ih->ih_key.k_offset,
&new_dehs->deh_offset, SHORT_KEY_SIZE);*/
} }
#ifdef CONFIG_REISERFS_CHECK #ifdef CONFIG_REISERFS_CHECK
{ {

View File

@ -22,8 +22,10 @@
#define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) set_nlink(i, 1); } #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { inc_nlink(i); if (i->i_nlink >= REISERFS_LINK_MAX) set_nlink(i, 1); }
#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i); #define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
// directory item contains array of entry headers. This performs /*
// binary search through that array * directory item contains array of entry headers. This performs
* binary search through that array
*/
static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off) static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off)
{ {
struct item_head *ih = de->de_ih; struct item_head *ih = de->de_ih;
@ -43,7 +45,7 @@ static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off)
lbound = j + 1; lbound = j + 1;
continue; continue;
} }
// this is not name found, but matched third key component /* this is not name found, but matched third key component */
de->de_entry_num = j; de->de_entry_num = j;
return NAME_FOUND; return NAME_FOUND;
} }
@ -52,7 +54,9 @@ static int bin_search_in_dir_item(struct reiserfs_dir_entry *de, loff_t off)
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
} }
// comment? maybe something like set de to point to what the path points to? /*
* comment? maybe something like set de to point to what the path points to?
*/
static inline void set_de_item_location(struct reiserfs_dir_entry *de, static inline void set_de_item_location(struct reiserfs_dir_entry *de,
struct treepath *path) struct treepath *path)
{ {
@ -62,7 +66,9 @@ static inline void set_de_item_location(struct reiserfs_dir_entry *de,
de->de_item_num = PATH_LAST_POSITION(path); de->de_item_num = PATH_LAST_POSITION(path);
} }
// de_bh, de_ih, de_deh (points to first element of array), de_item_num is set /*
* de_bh, de_ih, de_deh (points to first element of array), de_item_num is set
*/
inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de) inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de)
{ {
struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num; struct reiserfs_de_head *deh = de->de_deh + de->de_entry_num;
@ -76,7 +82,7 @@ inline void set_de_name_and_namelen(struct reiserfs_dir_entry *de)
de->de_namelen = strlen(de->de_name); de->de_namelen = strlen(de->de_name);
} }
// what entry points to /* what entry points to */
static inline void set_de_object_key(struct reiserfs_dir_entry *de) static inline void set_de_object_key(struct reiserfs_dir_entry *de)
{ {
BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih)); BUG_ON(de->de_entry_num >= ih_entry_count(de->de_ih));
@ -100,17 +106,16 @@ static inline void store_de_entry_key(struct reiserfs_dir_entry *de)
set_cpu_key_k_type(&(de->de_entry_key), TYPE_DIRENTRY); set_cpu_key_k_type(&(de->de_entry_key), TYPE_DIRENTRY);
} }
/* We assign a key to each directory item, and place multiple entries /*
in a single directory item. A directory item has a key equal to the * We assign a key to each directory item, and place multiple entries in a
key of the first directory entry in it. * single directory item. A directory item has a key equal to the key of
* the first directory entry in it.
This function first calls search_by_key, then, if item whose first
entry matches is not found it looks for the entry inside directory
item found by search_by_key. Fills the path to the entry, and to the
entry position in the item
*/
* This function first calls search_by_key, then, if item whose first entry
* matches is not found it looks for the entry inside directory item found
* by search_by_key. Fills the path to the entry, and to the entry position
* in the item
*/
/* The function is NOT SCHEDULE-SAFE! */ /* The function is NOT SCHEDULE-SAFE! */
int search_by_entry_key(struct super_block *sb, const struct cpu_key *key, int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
struct treepath *path, struct reiserfs_dir_entry *de) struct treepath *path, struct reiserfs_dir_entry *de)
@ -152,12 +157,17 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
} }
#endif /* CONFIG_REISERFS_CHECK */ #endif /* CONFIG_REISERFS_CHECK */
/* binary search in directory item by third componen t of the /*
key. sets de->de_entry_num of de */ * binary search in directory item by third component of the
* key. sets de->de_entry_num of de
*/
retval = bin_search_in_dir_item(de, cpu_key_k_offset(key)); retval = bin_search_in_dir_item(de, cpu_key_k_offset(key));
path->pos_in_item = de->de_entry_num; path->pos_in_item = de->de_entry_num;
if (retval != NAME_NOT_FOUND) { if (retval != NAME_NOT_FOUND) {
// ugly, but rename needs de_bh, de_deh, de_name, de_namelen, de_objectid set /*
* ugly, but rename needs de_bh, de_deh, de_name,
* de_namelen, de_objectid set
*/
set_de_name_and_namelen(de); set_de_name_and_namelen(de);
set_de_object_key(de); set_de_object_key(de);
} }
@ -166,11 +176,12 @@ int search_by_entry_key(struct super_block *sb, const struct cpu_key *key,
/* Keyed 32-bit hash function using TEA in a Davis-Meyer function */ /* Keyed 32-bit hash function using TEA in a Davis-Meyer function */
/* The third component is hashed, and you can choose from more than /*
one hash function. Per directory hashes are not yet implemented * The third component is hashed, and you can choose from more than
but are thought about. This function should be moved to hashes.c * one hash function. Per directory hashes are not yet implemented
Jedi, please do so. -Hans */ * but are thought about. This function should be moved to hashes.c
* Jedi, please do so. -Hans
*/
static __u32 get_third_component(struct super_block *s, static __u32 get_third_component(struct super_block *s,
const char *name, int len) const char *name, int len)
{ {
@ -183,11 +194,13 @@ static __u32 get_third_component(struct super_block *s,
res = REISERFS_SB(s)->s_hash_function(name, len); res = REISERFS_SB(s)->s_hash_function(name, len);
// take bits from 7-th to 30-th including both bounds /* take bits from 7-th to 30-th including both bounds */
res = GET_HASH_VALUE(res); res = GET_HASH_VALUE(res);
if (res == 0) if (res == 0)
// needed to have no names before "." and ".." those have hash /*
// value == 0 and generation conters 1 and 2 accordingly * needed to have no names before "." and ".." those have hash
* value == 0 and generation conters 1 and 2 accordingly
*/
res = 128; res = 128;
return res + MAX_GENERATION_NUMBER; return res + MAX_GENERATION_NUMBER;
} }
@ -208,7 +221,7 @@ static int reiserfs_match(struct reiserfs_dir_entry *de,
/* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */ /* de's de_bh, de_ih, de_deh, de_item_num, de_entry_num are set already */
/* used when hash collisions exist */ /* used when hash collisions exist */
static int linear_search_in_dir_item(struct cpu_key *key, static int linear_search_in_dir_item(struct cpu_key *key,
struct reiserfs_dir_entry *de, struct reiserfs_dir_entry *de,
@ -232,43 +245,50 @@ static int linear_search_in_dir_item(struct cpu_key *key,
deh += i; deh += i;
for (; i >= 0; i--, deh--) { for (; i >= 0; i--, deh--) {
/* hash value does not match, no need to check whole name */
if (GET_HASH_VALUE(deh_offset(deh)) != if (GET_HASH_VALUE(deh_offset(deh)) !=
GET_HASH_VALUE(cpu_key_k_offset(key))) { GET_HASH_VALUE(cpu_key_k_offset(key))) {
// hash value does not match, no need to check whole name
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
} }
/* mark, that this generation number is used */ /* mark that this generation number is used */
if (de->de_gen_number_bit_string) if (de->de_gen_number_bit_string)
set_bit(GET_GENERATION_NUMBER(deh_offset(deh)), set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
de->de_gen_number_bit_string); de->de_gen_number_bit_string);
// calculate pointer to name and namelen /* calculate pointer to name and namelen */
de->de_entry_num = i; de->de_entry_num = i;
set_de_name_and_namelen(de); set_de_name_and_namelen(de);
/*
* de's de_name, de_namelen, de_recordlen are set.
* Fill the rest.
*/
if ((retval = if ((retval =
reiserfs_match(de, name, namelen)) != NAME_NOT_FOUND) { reiserfs_match(de, name, namelen)) != NAME_NOT_FOUND) {
// de's de_name, de_namelen, de_recordlen are set. Fill the rest:
// key of pointed object /* key of pointed object */
set_de_object_key(de); set_de_object_key(de);
store_de_entry_key(de); store_de_entry_key(de);
// retval can be NAME_FOUND or NAME_FOUND_INVISIBLE /* retval can be NAME_FOUND or NAME_FOUND_INVISIBLE */
return retval; return retval;
} }
} }
if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0) if (GET_GENERATION_NUMBER(le_ih_k_offset(de->de_ih)) == 0)
/* we have reached left most entry in the node. In common we /*
have to go to the left neighbor, but if generation counter * we have reached left most entry in the node. In common we
is 0 already, we know for sure, that there is no name with * have to go to the left neighbor, but if generation counter
the same hash value */ * is 0 already, we know for sure, that there is no name with
// FIXME: this work correctly only because hash value can not * the same hash value
// be 0. Btw, in case of Yura's hash it is probably possible, */
// so, this is a bug /*
* FIXME: this work correctly only because hash value can not
* be 0. Btw, in case of Yura's hash it is probably possible,
* so, this is a bug
*/
return NAME_NOT_FOUND; return NAME_NOT_FOUND;
RFALSE(de->de_item_num, RFALSE(de->de_item_num,
@ -277,8 +297,10 @@ static int linear_search_in_dir_item(struct cpu_key *key,
return GOTO_PREVIOUS_ITEM; return GOTO_PREVIOUS_ITEM;
} }
// may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND /*
// FIXME: should add something like IOERROR * may return NAME_FOUND, NAME_FOUND_INVISIBLE, NAME_NOT_FOUND
* FIXME: should add something like IOERROR
*/
static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen, static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen,
struct treepath *path_to_entry, struct treepath *path_to_entry,
struct reiserfs_dir_entry *de) struct reiserfs_dir_entry *de)
@ -307,13 +329,19 @@ static int reiserfs_find_entry(struct inode *dir, const char *name, int namelen,
retval = retval =
linear_search_in_dir_item(&key_to_search, de, name, linear_search_in_dir_item(&key_to_search, de, name,
namelen); namelen);
/*
* there is no need to scan directory anymore.
* Given entry found or does not exist
*/
if (retval != GOTO_PREVIOUS_ITEM) { if (retval != GOTO_PREVIOUS_ITEM) {
/* there is no need to scan directory anymore. Given entry found or does not exist */
path_to_entry->pos_in_item = de->de_entry_num; path_to_entry->pos_in_item = de->de_entry_num;
return retval; return retval;
} }
/* there is left neighboring item of this directory and given entry can be there */ /*
* there is left neighboring item of this directory
* and given entry can be there
*/
set_cpu_key_k_offset(&key_to_search, set_cpu_key_k_offset(&key_to_search,
le_ih_k_offset(de->de_ih) - 1); le_ih_k_offset(de->de_ih) - 1);
pathrelse(path_to_entry); pathrelse(path_to_entry);
@ -347,8 +375,10 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
return ERR_PTR(-EACCES); return ERR_PTR(-EACCES);
} }
/* Propagate the private flag so we know we're /*
* in the priv tree */ * Propagate the private flag so we know we're
* in the priv tree
*/
if (IS_PRIVATE(dir)) if (IS_PRIVATE(dir))
inode->i_flags |= S_PRIVATE; inode->i_flags |= S_PRIVATE;
} }
@ -361,9 +391,9 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry,
} }
/* /*
** looks up the dentry of the parent directory for child. * looks up the dentry of the parent directory for child.
** taken from ext2_get_parent * taken from ext2_get_parent
*/ */
struct dentry *reiserfs_get_parent(struct dentry *child) struct dentry *reiserfs_get_parent(struct dentry *child)
{ {
int retval; int retval;
@ -406,8 +436,13 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
struct reiserfs_dir_entry de; struct reiserfs_dir_entry de;
DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1); DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1);
int gen_number; int gen_number;
char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc
if we create file with short name */ /*
* 48 bytes now and we avoid kmalloc if we
* create file with short name
*/
char small_buf[32 + DEH_SIZE];
char *buffer; char *buffer;
int buflen, paste_size; int buflen, paste_size;
int retval; int retval;
@ -439,21 +474,30 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
(get_inode_sd_version(dir) == (get_inode_sd_version(dir) ==
STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen; STAT_DATA_V1) ? (DEH_SIZE + namelen) : buflen;
/* fill buffer : directory entry head, name[, dir objectid | , stat data | ,stat data, dir objectid ] */ /*
* fill buffer : directory entry head, name[, dir objectid | ,
* stat data | ,stat data, dir objectid ]
*/
deh = (struct reiserfs_de_head *)buffer; deh = (struct reiserfs_de_head *)buffer;
deh->deh_location = 0; /* JDM Endian safe if 0 */ deh->deh_location = 0; /* JDM Endian safe if 0 */
put_deh_offset(deh, cpu_key_k_offset(&entry_key)); put_deh_offset(deh, cpu_key_k_offset(&entry_key));
deh->deh_state = 0; /* JDM Endian safe if 0 */ deh->deh_state = 0; /* JDM Endian safe if 0 */
/* put key (ino analog) to de */ /* put key (ino analog) to de */
deh->deh_dir_id = INODE_PKEY(inode)->k_dir_id; /* safe: k_dir_id is le */
deh->deh_objectid = INODE_PKEY(inode)->k_objectid; /* safe: k_objectid is le */ /* safe: k_dir_id is le */
deh->deh_dir_id = INODE_PKEY(inode)->k_dir_id;
/* safe: k_objectid is le */
deh->deh_objectid = INODE_PKEY(inode)->k_objectid;
/* copy name */ /* copy name */
memcpy((char *)(deh + 1), name, namelen); memcpy((char *)(deh + 1), name, namelen);
/* padd by 0s to the 4 byte boundary */ /* padd by 0s to the 4 byte boundary */
padd_item((char *)(deh + 1), ROUND_UP(namelen), namelen); padd_item((char *)(deh + 1), ROUND_UP(namelen), namelen);
/* entry is ready to be pasted into tree, set 'visibility' and 'stat data in entry' attributes */ /*
* entry is ready to be pasted into tree, set 'visibility'
* and 'stat data in entry' attributes
*/
mark_de_without_sd(deh); mark_de_without_sd(deh);
visible ? mark_de_visible(deh) : mark_de_hidden(deh); visible ? mark_de_visible(deh) : mark_de_hidden(deh);
@ -499,7 +543,8 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
/* update max-hash-collisions counter in reiserfs_sb_info */ /* update max-hash-collisions counter in reiserfs_sb_info */
PROC_INFO_MAX(th->t_super, max_hash_collisions, gen_number); PROC_INFO_MAX(th->t_super, max_hash_collisions, gen_number);
if (gen_number != 0) { /* we need to re-search for the insertion point */ /* we need to re-search for the insertion point */
if (gen_number != 0) {
if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) != if (search_by_entry_key(dir->i_sb, &entry_key, &path, &de) !=
NAME_NOT_FOUND) { NAME_NOT_FOUND) {
reiserfs_warning(dir->i_sb, "vs-7032", reiserfs_warning(dir->i_sb, "vs-7032",
@ -527,18 +572,19 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
dir->i_size += paste_size; dir->i_size += paste_size;
dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
if (!S_ISDIR(inode->i_mode) && visible) if (!S_ISDIR(inode->i_mode) && visible)
// reiserfs_mkdir or reiserfs_rename will do that by itself /* reiserfs_mkdir or reiserfs_rename will do that by itself */
reiserfs_update_sd(th, dir); reiserfs_update_sd(th, dir);
reiserfs_check_path(&path); reiserfs_check_path(&path);
return 0; return 0;
} }
/* quota utility function, call if you've had to abort after calling /*
** new_inode_init, and have not called reiserfs_new_inode yet. * quota utility function, call if you've had to abort after calling
** This should only be called on inodes that do not have stat data * new_inode_init, and have not called reiserfs_new_inode yet.
** inserted into the tree yet. * This should only be called on inodes that do not have stat data
*/ * inserted into the tree yet.
*/
static int drop_new_inode(struct inode *inode) static int drop_new_inode(struct inode *inode)
{ {
dquot_drop(inode); dquot_drop(inode);
@ -548,18 +594,23 @@ static int drop_new_inode(struct inode *inode)
return 0; return 0;
} }
/* utility function that does setup for reiserfs_new_inode. /*
** dquot_initialize needs lots of credits so it's better to have it * utility function that does setup for reiserfs_new_inode.
** outside of a transaction, so we had to pull some bits of * dquot_initialize needs lots of credits so it's better to have it
** reiserfs_new_inode out into this func. * outside of a transaction, so we had to pull some bits of
*/ * reiserfs_new_inode out into this func.
*/
static int new_inode_init(struct inode *inode, struct inode *dir, umode_t mode) static int new_inode_init(struct inode *inode, struct inode *dir, umode_t mode)
{ {
/* Make inode invalid - just in case we are going to drop it before /*
* the initialization happens */ * Make inode invalid - just in case we are going to drop it before
* the initialization happens
*/
INODE_PKEY(inode)->k_objectid = 0; INODE_PKEY(inode)->k_objectid = 0;
/* the quota init calls have to know who to charge the quota to, so
** we have to set uid and gid here /*
* the quota init calls have to know who to charge the quota to, so
* we have to set uid and gid here
*/ */
inode_init_owner(inode, dir, mode); inode_init_owner(inode, dir, mode);
dquot_initialize(inode); dquot_initialize(inode);
@ -571,7 +622,10 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, umode_t mod
{ {
int retval; int retval;
struct inode *inode; struct inode *inode;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ /*
* We need blocks for transaction + (user+group)*(quotas
* for new inode + update of quota for directory owner)
*/
int jbegin_count = int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 2 + JOURNAL_PER_BALANCE_CNT * 2 +
2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
@ -644,7 +698,10 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode
struct inode *inode; struct inode *inode;
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
struct reiserfs_security_handle security; struct reiserfs_security_handle security;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ /*
* We need blocks for transaction + (user+group)*(quotas
* for new inode + update of quota for directory owner)
*/
int jbegin_count = int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 + JOURNAL_PER_BALANCE_CNT * 3 +
2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
@ -685,7 +742,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode
inode->i_op = &reiserfs_special_inode_operations; inode->i_op = &reiserfs_special_inode_operations;
init_special_inode(inode, inode->i_mode, rdev); init_special_inode(inode, inode->i_mode, rdev);
//FIXME: needed for block and char devices only /* FIXME: needed for block and char devices only */
reiserfs_update_sd(&th, inode); reiserfs_update_sd(&th, inode);
reiserfs_update_inode_transaction(inode); reiserfs_update_inode_transaction(inode);
@ -721,7 +778,10 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
struct inode *inode; struct inode *inode;
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
struct reiserfs_security_handle security; struct reiserfs_security_handle security;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ /*
* We need blocks for transaction + (user+group)*(quotas
* for new inode + update of quota for directory owner)
*/
int jbegin_count = int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 + JOURNAL_PER_BALANCE_CNT * 3 +
2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) +
@ -730,7 +790,10 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
dquot_initialize(dir); dquot_initialize(dir);
#ifdef DISPLACE_NEW_PACKING_LOCALITIES #ifdef DISPLACE_NEW_PACKING_LOCALITIES
/* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ /*
* set flag that new packing locality created and new blocks
* for the content of that directory are not displaced yet
*/
REISERFS_I(dir)->new_packing_locality = 1; REISERFS_I(dir)->new_packing_locality = 1;
#endif #endif
mode = S_IFDIR | mode; mode = S_IFDIR | mode;
@ -754,8 +817,9 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
goto out_failed; goto out_failed;
} }
/* inc the link count now, so another writer doesn't overflow it while /*
** we sleep later on. * inc the link count now, so another writer doesn't overflow
* it while we sleep later on.
*/ */
INC_DIR_INODE_NLINK(dir) INC_DIR_INODE_NLINK(dir)
@ -774,7 +838,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
inode->i_op = &reiserfs_dir_inode_operations; inode->i_op = &reiserfs_dir_inode_operations;
inode->i_fop = &reiserfs_dir_operations; inode->i_fop = &reiserfs_dir_operations;
// note, _this_ add_entry will not update dir's stat data /* note, _this_ add_entry will not update dir's stat data */
retval = retval =
reiserfs_add_entry(&th, dir, dentry->d_name.name, reiserfs_add_entry(&th, dir, dentry->d_name.name,
dentry->d_name.len, inode, 1 /*visible */ ); dentry->d_name.len, inode, 1 /*visible */ );
@ -790,7 +854,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
iput(inode); iput(inode);
goto out_failed; goto out_failed;
} }
// the above add_entry did not update dir's stat data /* the above add_entry did not update dir's stat data */
reiserfs_update_sd(&th, dir); reiserfs_update_sd(&th, dir);
unlock_new_inode(inode); unlock_new_inode(inode);
@ -803,10 +867,11 @@ out_failed:
static inline int reiserfs_empty_dir(struct inode *inode) static inline int reiserfs_empty_dir(struct inode *inode)
{ {
/* we can cheat because an old format dir cannot have /*
** EMPTY_DIR_SIZE, and a new format dir cannot have * we can cheat because an old format dir cannot have
** EMPTY_DIR_SIZE_V1. So, if the inode is either size, * EMPTY_DIR_SIZE, and a new format dir cannot have
** regardless of disk format version, the directory is empty. * EMPTY_DIR_SIZE_V1. So, if the inode is either size,
* regardless of disk format version, the directory is empty.
*/ */
if (inode->i_size != EMPTY_DIR_SIZE && if (inode->i_size != EMPTY_DIR_SIZE &&
inode->i_size != EMPTY_DIR_SIZE_V1) { inode->i_size != EMPTY_DIR_SIZE_V1) {
@ -824,10 +889,12 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
INITIALIZE_PATH(path); INITIALIZE_PATH(path);
struct reiserfs_dir_entry de; struct reiserfs_dir_entry de;
/* we will be doing 2 balancings and update 2 stat data, we change quotas /*
* of the owner of the directory and of the owner of the parent directory. * we will be doing 2 balancings and update 2 stat data, we
* The quota structure is possibly deleted only on last iput => outside * change quotas of the owner of the directory and of the owner
* of this transaction */ * of the parent directory. The quota structure is possibly
* deleted only on last iput => outside of this transaction
*/
jbegin_count = jbegin_count =
JOURNAL_PER_BALANCE_CNT * 2 + 2 + JOURNAL_PER_BALANCE_CNT * 2 + 2 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
@ -856,8 +923,9 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
reiserfs_update_inode_transaction(dir); reiserfs_update_inode_transaction(dir);
if (de.de_objectid != inode->i_ino) { if (de.de_objectid != inode->i_ino) {
// FIXME: compare key of an object and a key found in the /*
// entry * FIXME: compare key of an object and a key found in the entry
*/
retval = -EIO; retval = -EIO;
goto end_rmdir; goto end_rmdir;
} }
@ -895,9 +963,11 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry)
return retval; return retval;
end_rmdir: end_rmdir:
/* we must release path, because we did not call /*
reiserfs_cut_from_item, or reiserfs_cut_from_item does not * we must release path, because we did not call
release path if operation was not complete */ * reiserfs_cut_from_item, or reiserfs_cut_from_item does not
* release path if operation was not complete
*/
pathrelse(&path); pathrelse(&path);
err = journal_end(&th, dir->i_sb, jbegin_count); err = journal_end(&th, dir->i_sb, jbegin_count);
reiserfs_write_unlock(dir->i_sb); reiserfs_write_unlock(dir->i_sb);
@ -918,10 +988,13 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
inode = dentry->d_inode; inode = dentry->d_inode;
/* in this transaction we can be doing at max two balancings and update /*
* two stat datas, we change quotas of the owner of the directory and of * in this transaction we can be doing at max two balancings and
* the owner of the parent directory. The quota structure is possibly * update two stat datas, we change quotas of the owner of the
* deleted only on iput => outside of this transaction */ * directory and of the owner of the parent directory. The quota
* structure is possibly deleted only on iput => outside of
* this transaction
*/
jbegin_count = jbegin_count =
JOURNAL_PER_BALANCE_CNT * 2 + 2 + JOURNAL_PER_BALANCE_CNT * 2 + 2 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
@ -946,8 +1019,9 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
reiserfs_update_inode_transaction(dir); reiserfs_update_inode_transaction(dir);
if (de.de_objectid != inode->i_ino) { if (de.de_objectid != inode->i_ino) {
// FIXME: compare key of an object and a key found in the /*
// entry * FIXME: compare key of an object and a key found in the entry
*/
retval = -EIO; retval = -EIO;
goto end_unlink; goto end_unlink;
} }
@ -1011,7 +1085,10 @@ static int reiserfs_symlink(struct inode *parent_dir,
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
struct reiserfs_security_handle security; struct reiserfs_security_handle security;
int mode = S_IFLNK | S_IRWXUGO; int mode = S_IFLNK | S_IRWXUGO;
/* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ /*
* We need blocks for transaction + (user+group)*(quotas for
* new inode + update of quota for directory owner)
*/
int jbegin_count = int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 + JOURNAL_PER_BALANCE_CNT * 3 +
2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) +
@ -1070,10 +1147,6 @@ static int reiserfs_symlink(struct inode *parent_dir,
inode->i_op = &reiserfs_symlink_inode_operations; inode->i_op = &reiserfs_symlink_inode_operations;
inode->i_mapping->a_ops = &reiserfs_address_space_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations;
// must be sure this inode is written with this transaction
//
//reiserfs_update_sd (&th, inode, READ_BLOCKS);
retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name, retval = reiserfs_add_entry(&th, parent_dir, dentry->d_name.name,
dentry->d_name.len, inode, 1 /*visible */ ); dentry->d_name.len, inode, 1 /*visible */ );
if (retval) { if (retval) {
@ -1102,7 +1175,10 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
int retval; int retval;
struct inode *inode = old_dentry->d_inode; struct inode *inode = old_dentry->d_inode;
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
/* We need blocks for transaction + update of quotas for the owners of the directory */ /*
* We need blocks for transaction + update of quotas for
* the owners of the directory
*/
int jbegin_count = int jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 + JOURNAL_PER_BALANCE_CNT * 3 +
2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb);
@ -1111,7 +1187,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir,
reiserfs_write_lock(dir->i_sb); reiserfs_write_lock(dir->i_sb);
if (inode->i_nlink >= REISERFS_LINK_MAX) { if (inode->i_nlink >= REISERFS_LINK_MAX) {
//FIXME: sd_nlink is 32 bit for new files /* FIXME: sd_nlink is 32 bit for new files */
reiserfs_write_unlock(dir->i_sb); reiserfs_write_unlock(dir->i_sb);
return -EMLINK; return -EMLINK;
} }
@ -1158,9 +1234,9 @@ static int de_still_valid(const char *name, int len,
{ {
struct reiserfs_dir_entry tmp = *de; struct reiserfs_dir_entry tmp = *de;
// recalculate pointer to name and name length /* recalculate pointer to name and name length */
set_de_name_and_namelen(&tmp); set_de_name_and_namelen(&tmp);
// FIXME: could check more /* FIXME: could check more */
if (tmp.de_namelen != len || memcmp(name, de->de_name, len)) if (tmp.de_namelen != len || memcmp(name, de->de_name, len))
return 0; return 0;
return 1; return 1;
@ -1217,14 +1293,16 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
unsigned long savelink = 1; unsigned long savelink = 1;
struct timespec ctime; struct timespec ctime;
/* three balancings: (1) old name removal, (2) new name insertion /*
and (3) maybe "save" link insertion * three balancings: (1) old name removal, (2) new name insertion
stat data updates: (1) old directory, * and (3) maybe "save" link insertion
(2) new directory and (3) maybe old object stat data (when it is * stat data updates: (1) old directory,
directory) and (4) maybe stat data of object to which new entry * (2) new directory and (3) maybe old object stat data (when it is
pointed initially and (5) maybe block containing ".." of * directory) and (4) maybe stat data of object to which new entry
renamed directory * pointed initially and (5) maybe block containing ".." of
quota updates: two parent directories */ * renamed directory
* quota updates: two parent directories
*/
jbegin_count = jbegin_count =
JOURNAL_PER_BALANCE_CNT * 3 + 5 + JOURNAL_PER_BALANCE_CNT * 3 + 5 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb);
@ -1235,8 +1313,10 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_inode = old_dentry->d_inode; old_inode = old_dentry->d_inode;
new_dentry_inode = new_dentry->d_inode; new_dentry_inode = new_dentry->d_inode;
// make sure, that oldname still exists and points to an object we /*
// are going to rename * make sure that oldname still exists and points to an object we
* are going to rename
*/
old_de.de_gen_number_bit_string = NULL; old_de.de_gen_number_bit_string = NULL;
reiserfs_write_lock(old_dir->i_sb); reiserfs_write_lock(old_dir->i_sb);
retval = retval =
@ -1256,10 +1336,11 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_inode_mode = old_inode->i_mode; old_inode_mode = old_inode->i_mode;
if (S_ISDIR(old_inode_mode)) { if (S_ISDIR(old_inode_mode)) {
// make sure, that directory being renamed has correct ".." /*
// and that its new parent directory has not too many links * make sure that directory being renamed has correct ".."
// already * and that its new parent directory has not too many links
* already
*/
if (new_dentry_inode) { if (new_dentry_inode) {
if (!reiserfs_empty_dir(new_dentry_inode)) { if (!reiserfs_empty_dir(new_dentry_inode)) {
reiserfs_write_unlock(old_dir->i_sb); reiserfs_write_unlock(old_dir->i_sb);
@ -1267,8 +1348,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} }
} }
/* directory is renamed, its parent directory will be changed, /*
** so find ".." entry * directory is renamed, its parent directory will be changed,
* so find ".." entry
*/ */
dot_dot_de.de_gen_number_bit_string = NULL; dot_dot_de.de_gen_number_bit_string = NULL;
retval = retval =
@ -1311,8 +1393,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
reiserfs_update_inode_transaction(old_dir); reiserfs_update_inode_transaction(old_dir);
reiserfs_update_inode_transaction(new_dir); reiserfs_update_inode_transaction(new_dir);
/* this makes it so an fsync on an open fd for the old name will /*
** commit the rename operation * this makes it so an fsync on an open fd for the old name will
* commit the rename operation
*/ */
reiserfs_update_inode_transaction(old_inode); reiserfs_update_inode_transaction(old_inode);
@ -1320,7 +1403,10 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
reiserfs_update_inode_transaction(new_dentry_inode); reiserfs_update_inode_transaction(new_dentry_inode);
while (1) { while (1) {
// look for old name using corresponding entry key (found by reiserfs_find_entry) /*
* look for old name using corresponding entry key
* (found by reiserfs_find_entry)
*/
if ((retval = if ((retval =
search_by_entry_key(new_dir->i_sb, &old_de.de_entry_key, search_by_entry_key(new_dir->i_sb, &old_de.de_entry_key,
&old_entry_path, &old_entry_path,
@ -1335,14 +1421,18 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1); reiserfs_prepare_for_journal(old_inode->i_sb, old_de.de_bh, 1);
// look for new name by reiserfs_find_entry /* look for new name by reiserfs_find_entry */
new_de.de_gen_number_bit_string = NULL; new_de.de_gen_number_bit_string = NULL;
retval = retval =
reiserfs_find_entry(new_dir, new_dentry->d_name.name, reiserfs_find_entry(new_dir, new_dentry->d_name.name,
new_dentry->d_name.len, &new_entry_path, new_dentry->d_name.len, &new_entry_path,
&new_de); &new_de);
// reiserfs_add_entry should not return IO_ERROR, because it is called with essentially same parameters from /*
// reiserfs_add_entry above, and we'll catch any i/o errors before we get here. * reiserfs_add_entry should not return IO_ERROR,
* because it is called with essentially same parameters from
* reiserfs_add_entry above, and we'll catch any i/o errors
* before we get here.
*/
if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) { if (retval != NAME_FOUND_INVISIBLE && retval != NAME_FOUND) {
pathrelse(&new_entry_path); pathrelse(&new_entry_path);
pathrelse(&old_entry_path); pathrelse(&old_entry_path);
@ -1370,22 +1460,26 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} }
copy_item_head(&dot_dot_ih, copy_item_head(&dot_dot_ih,
tp_item_head(&dot_dot_entry_path)); tp_item_head(&dot_dot_entry_path));
// node containing ".." gets into transaction /* node containing ".." gets into transaction */
reiserfs_prepare_for_journal(old_inode->i_sb, reiserfs_prepare_for_journal(old_inode->i_sb,
dot_dot_de.de_bh, 1); dot_dot_de.de_bh, 1);
} }
/* we should check seals here, not do /*
this stuff, yes? Then, having * we should check seals here, not do
gathered everything into RAM we * this stuff, yes? Then, having
should lock the buffers, yes? -Hans */ * gathered everything into RAM we
/* probably. our rename needs to hold more * should lock the buffers, yes? -Hans
** than one path at once. The seals would
** have to be written to deal with multi-path
** issues -chris
*/ */
/* sanity checking before doing the rename - avoid races many /*
** of the above checks could have scheduled. We have to be * probably. our rename needs to hold more
** sure our items haven't been shifted by another process. * than one path at once. The seals would
* have to be written to deal with multi-path
* issues -chris
*/
/*
* sanity checking before doing the rename - avoid races many
* of the above checks could have scheduled. We have to be
* sure our items haven't been shifted by another process.
*/ */
if (item_moved(&new_entry_ih, &new_entry_path) || if (item_moved(&new_entry_ih, &new_entry_path) ||
!entry_points_to_object(new_dentry->d_name.name, !entry_points_to_object(new_dentry->d_name.name,
@ -1430,8 +1524,10 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
break; break;
} }
/* ok, all the changes can be done in one fell swoop when we /*
have claimed all the buffers needed. */ * ok, all the changes can be done in one fell swoop when we
* have claimed all the buffers needed.
*/
mark_de_visible(new_de.de_deh + new_de.de_entry_num); mark_de_visible(new_de.de_deh + new_de.de_entry_num);
set_ino_in_dir_entry(&new_de, INODE_PKEY(old_inode)); set_ino_in_dir_entry(&new_de, INODE_PKEY(old_inode));
@ -1442,12 +1538,14 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
ctime = CURRENT_TIME_SEC; ctime = CURRENT_TIME_SEC;
old_dir->i_ctime = old_dir->i_mtime = ctime; old_dir->i_ctime = old_dir->i_mtime = ctime;
new_dir->i_ctime = new_dir->i_mtime = ctime; new_dir->i_ctime = new_dir->i_mtime = ctime;
/* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of /*
renamed object */ * thanks to Alex Adriaanse <alex_a@caltech.edu> for patch
* which adds ctime update of renamed object
*/
old_inode->i_ctime = ctime; old_inode->i_ctime = ctime;
if (new_dentry_inode) { if (new_dentry_inode) {
// adjust link number of the victim /* adjust link number of the victim */
if (S_ISDIR(new_dentry_inode->i_mode)) { if (S_ISDIR(new_dentry_inode->i_mode)) {
clear_nlink(new_dentry_inode); clear_nlink(new_dentry_inode);
} else { } else {
@ -1462,21 +1560,28 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir)); set_ino_in_dir_entry(&dot_dot_de, INODE_PKEY(new_dir));
journal_mark_dirty(&th, new_dir->i_sb, dot_dot_de.de_bh); journal_mark_dirty(&th, new_dir->i_sb, dot_dot_de.de_bh);
/*
* there (in new_dir) was no directory, so it got new link
* (".." of renamed directory)
*/
if (!new_dentry_inode) if (!new_dentry_inode)
/* there (in new_dir) was no directory, so it got new link
(".." of renamed directory) */
INC_DIR_INODE_NLINK(new_dir); INC_DIR_INODE_NLINK(new_dir);
/* old directory lost one link - ".. " of renamed directory */ /* old directory lost one link - ".. " of renamed directory */
DEC_DIR_INODE_NLINK(old_dir); DEC_DIR_INODE_NLINK(old_dir);
} }
// looks like in 2.3.99pre3 brelse is atomic. so we can use pathrelse /*
* looks like in 2.3.99pre3 brelse is atomic.
* so we can use pathrelse
*/
pathrelse(&new_entry_path); pathrelse(&new_entry_path);
pathrelse(&dot_dot_entry_path); pathrelse(&dot_dot_entry_path);
// FIXME: this reiserfs_cut_from_item's return value may screw up /*
// anybody, but it will panic if will not be able to find the * FIXME: this reiserfs_cut_from_item's return value may screw up
// entry. This needs one more clean up * anybody, but it will panic if will not be able to find the
* entry. This needs one more clean up
*/
if (reiserfs_cut_from_item if (reiserfs_cut_from_item
(&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL, (&th, &old_entry_path, &(old_de.de_entry_key), old_dir, NULL,
0) < 0) 0) < 0)
@ -1501,11 +1606,8 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
return retval; return retval;
} }
/* /* directories can handle most operations... */
* directories can handle most operations...
*/
const struct inode_operations reiserfs_dir_inode_operations = { const struct inode_operations reiserfs_dir_inode_operations = {
//&reiserfs_dir_operations, /* default_file_ops */
.create = reiserfs_create, .create = reiserfs_create,
.lookup = reiserfs_lookup, .lookup = reiserfs_lookup,
.link = reiserfs_link, .link = reiserfs_link,

View File

@ -7,7 +7,7 @@
#include <linux/time.h> #include <linux/time.h>
#include "reiserfs.h" #include "reiserfs.h"
// find where objectid map starts /* find where objectid map starts */
#define objectid_map(s,rs) (old_format_only (s) ? \ #define objectid_map(s,rs) (old_format_only (s) ? \
(__le32 *)((struct reiserfs_super_block_v1 *)(rs) + 1) :\ (__le32 *)((struct reiserfs_super_block_v1 *)(rs) + 1) :\
(__le32 *)((rs) + 1)) (__le32 *)((rs) + 1))
@ -20,7 +20,7 @@ static void check_objectid_map(struct super_block *s, __le32 * map)
reiserfs_panic(s, "vs-15010", "map corrupted: %lx", reiserfs_panic(s, "vs-15010", "map corrupted: %lx",
(long unsigned int)le32_to_cpu(map[0])); (long unsigned int)le32_to_cpu(map[0]));
// FIXME: add something else here /* FIXME: add something else here */
} }
#else #else
@ -29,19 +29,21 @@ static void check_objectid_map(struct super_block *s, __le32 * map)
} }
#endif #endif
/* When we allocate objectids we allocate the first unused objectid. /*
Each sequence of objectids in use (the odd sequences) is followed * When we allocate objectids we allocate the first unused objectid.
by a sequence of objectids not in use (the even sequences). We * Each sequence of objectids in use (the odd sequences) is followed
only need to record the last objectid in each of these sequences * by a sequence of objectids not in use (the even sequences). We
(both the odd and even sequences) in order to fully define the * only need to record the last objectid in each of these sequences
boundaries of the sequences. A consequence of allocating the first * (both the odd and even sequences) in order to fully define the
objectid not in use is that under most conditions this scheme is * boundaries of the sequences. A consequence of allocating the first
extremely compact. The exception is immediately after a sequence * objectid not in use is that under most conditions this scheme is
of operations which deletes a large number of objects of * extremely compact. The exception is immediately after a sequence
non-sequential objectids, and even then it will become compact * of operations which deletes a large number of objects of
again as soon as more objects are created. Note that many * non-sequential objectids, and even then it will become compact
interesting optimizations of layout could result from complicating * again as soon as more objects are created. Note that many
objectid assignment, but we have deferred making them for now. */ * interesting optimizations of layout could result from complicating
* objectid assignment, but we have deferred making them for now.
*/
/* get unique object identifier */ /* get unique object identifier */
__u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th) __u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th)
@ -64,19 +66,23 @@ __u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th)
return 0; return 0;
} }
/* This incrementation allocates the first unused objectid. That /*
is to say, the first entry on the objectid map is the first * This incrementation allocates the first unused objectid. That
unused objectid, and by incrementing it we use it. See below * is to say, the first entry on the objectid map is the first
where we check to see if we eliminated a sequence of unused * unused objectid, and by incrementing it we use it. See below
objectids.... */ * where we check to see if we eliminated a sequence of unused
* objectids....
*/
map[1] = cpu_to_le32(unused_objectid + 1); map[1] = cpu_to_le32(unused_objectid + 1);
/* Now we check to see if we eliminated the last remaining member of /*
the first even sequence (and can eliminate the sequence by * Now we check to see if we eliminated the last remaining member of
eliminating its last objectid from oids), and can collapse the * the first even sequence (and can eliminate the sequence by
first two odd sequences into one sequence. If so, then the net * eliminating its last objectid from oids), and can collapse the
result is to eliminate a pair of objectids from oids. We do this * first two odd sequences into one sequence. If so, then the net
by shifting the entire map to the left. */ * result is to eliminate a pair of objectids from oids. We do this
* by shifting the entire map to the left.
*/
if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) { if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) {
memmove(map + 1, map + 3, memmove(map + 1, map + 3,
(sb_oid_cursize(rs) - 3) * sizeof(__u32)); (sb_oid_cursize(rs) - 3) * sizeof(__u32));
@ -97,30 +103,33 @@ void reiserfs_release_objectid(struct reiserfs_transaction_handle *th,
int i = 0; int i = 0;
BUG_ON(!th->t_trans_id); BUG_ON(!th->t_trans_id);
//return; /*return; */
check_objectid_map(s, map); check_objectid_map(s, map);
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s)); journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));
/* start at the beginning of the objectid map (i = 0) and go to /*
the end of it (i = disk_sb->s_oid_cursize). Linear search is * start at the beginning of the objectid map (i = 0) and go to
what we use, though it is possible that binary search would be * the end of it (i = disk_sb->s_oid_cursize). Linear search is
more efficient after performing lots of deletions (which is * what we use, though it is possible that binary search would be
when oids is large.) We only check even i's. */ * more efficient after performing lots of deletions (which is
* when oids is large.) We only check even i's.
*/
while (i < sb_oid_cursize(rs)) { while (i < sb_oid_cursize(rs)) {
if (objectid_to_release == le32_to_cpu(map[i])) { if (objectid_to_release == le32_to_cpu(map[i])) {
/* This incrementation unallocates the objectid. */ /* This incrementation unallocates the objectid. */
//map[i]++;
le32_add_cpu(&map[i], 1); le32_add_cpu(&map[i], 1);
/* Did we unallocate the last member of an odd sequence, and can shrink oids? */ /*
* Did we unallocate the last member of an
* odd sequence, and can shrink oids?
*/
if (map[i] == map[i + 1]) { if (map[i] == map[i + 1]) {
/* shrink objectid map */ /* shrink objectid map */
memmove(map + i, map + i + 2, memmove(map + i, map + i + 2,
(sb_oid_cursize(rs) - i - (sb_oid_cursize(rs) - i -
2) * sizeof(__u32)); 2) * sizeof(__u32));
//disk_sb->s_oid_cursize -= 2;
set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2); set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);
RFALSE(sb_oid_cursize(rs) < 2 || RFALSE(sb_oid_cursize(rs) < 2 ||
@ -135,14 +144,19 @@ void reiserfs_release_objectid(struct reiserfs_transaction_handle *th,
objectid_to_release < le32_to_cpu(map[i + 1])) { objectid_to_release < le32_to_cpu(map[i + 1])) {
/* size of objectid map is not changed */ /* size of objectid map is not changed */
if (objectid_to_release + 1 == le32_to_cpu(map[i + 1])) { if (objectid_to_release + 1 == le32_to_cpu(map[i + 1])) {
//objectid_map[i+1]--;
le32_add_cpu(&map[i + 1], -1); le32_add_cpu(&map[i + 1], -1);
return; return;
} }
/* JDM comparing two little-endian values for equality -- safe */ /*
* JDM comparing two little-endian values for
* equality -- safe
*/
/*
* objectid map must be expanded, but
* there is no space
*/
if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) { if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) {
/* objectid map must be expanded, but there is no space */
PROC_INFO_INC(s, leaked_oid); PROC_INFO_INC(s, leaked_oid);
return; return;
} }
@ -178,8 +192,9 @@ int reiserfs_convert_objectid_map_v1(struct super_block *s)
new_objectid_map = (__le32 *) (disk_sb + 1); new_objectid_map = (__le32 *) (disk_sb + 1);
if (cur_size > new_size) { if (cur_size > new_size) {
/* mark everyone used that was listed as free at the end of the objectid /*
** map * mark everyone used that was listed as free at
* the end of the objectid map
*/ */
objectid_map[new_size - 1] = objectid_map[cur_size - 1]; objectid_map[new_size - 1] = objectid_map[cur_size - 1];
set_sb_oid_cursize(disk_sb, new_size); set_sb_oid_cursize(disk_sb, new_size);

View File

@ -172,18 +172,19 @@ static char *is_there_reiserfs_struct(char *fmt, int *what)
return k; return k;
} }
/* debugging reiserfs we used to print out a lot of different /*
variables, like keys, item headers, buffer heads etc. Values of * debugging reiserfs we used to print out a lot of different
most fields matter. So it took a long time just to write * variables, like keys, item headers, buffer heads etc. Values of
appropriative printk. With this reiserfs_warning you can use format * most fields matter. So it took a long time just to write
specification for complex structures like you used to do with * appropriative printk. With this reiserfs_warning you can use format
printfs for integers, doubles and pointers. For instance, to print * specification for complex structures like you used to do with
out key structure you have to write just: * printfs for integers, doubles and pointers. For instance, to print
reiserfs_warning ("bad key %k", key); * out key structure you have to write just:
instead of * reiserfs_warning ("bad key %k", key);
printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid, * instead of
key->k_offset, key->k_uniqueness); * printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid,
*/ * key->k_offset, key->k_uniqueness);
*/
static DEFINE_SPINLOCK(error_lock); static DEFINE_SPINLOCK(error_lock);
static void prepare_error_buf(const char *fmt, va_list args) static void prepare_error_buf(const char *fmt, va_list args)
{ {
@ -243,15 +244,16 @@ static void prepare_error_buf(const char *fmt, va_list args)
} }
/* in addition to usual conversion specifiers this accepts reiserfs /*
specific conversion specifiers: * in addition to usual conversion specifiers this accepts reiserfs
%k to print little endian key, * specific conversion specifiers:
%K to print cpu key, * %k to print little endian key,
%h to print item_head, * %K to print cpu key,
%t to print directory entry * %h to print item_head,
%z to print block head (arg must be struct buffer_head * * %t to print directory entry
%b to print buffer_head * %z to print block head (arg must be struct buffer_head *
*/ * %b to print buffer_head
*/
#define do_reiserfs_warning(fmt)\ #define do_reiserfs_warning(fmt)\
{\ {\
@ -304,50 +306,52 @@ void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
#endif #endif
} }
/* The format: /*
* The format:
maintainer-errorid: [function-name:] message *
* maintainer-errorid: [function-name:] message
where errorid is unique to the maintainer and function-name is *
optional, is recommended, so that anyone can easily find the bug * where errorid is unique to the maintainer and function-name is
with a simple grep for the short to type string * optional, is recommended, so that anyone can easily find the bug
maintainer-errorid. Don't bother with reusing errorids, there are * with a simple grep for the short to type string
lots of numbers out there. * maintainer-errorid. Don't bother with reusing errorids, there are
* lots of numbers out there.
Example: *
* Example:
reiserfs_panic( *
p_sb, "reiser-29: reiserfs_new_blocknrs: " * reiserfs_panic(
"one of search_start or rn(%d) is equal to MAX_B_NUM," * p_sb, "reiser-29: reiserfs_new_blocknrs: "
"which means that we are optimizing location based on the bogus location of a temp buffer (%p).", * "one of search_start or rn(%d) is equal to MAX_B_NUM,"
rn, bh * "which means that we are optimizing location based on the "
); * "bogus location of a temp buffer (%p).",
* rn, bh
Regular panic()s sometimes clear the screen before the message can * );
be read, thus the need for the while loop. *
* Regular panic()s sometimes clear the screen before the message can
Numbering scheme for panic used by Vladimir and Anatoly( Hans completely ignores this scheme, and considers it * be read, thus the need for the while loop.
pointless complexity): *
* Numbering scheme for panic used by Vladimir and Anatoly( Hans completely
panics in reiserfs.h have numbers from 1000 to 1999 * ignores this scheme, and considers it pointless complexity):
super.c 2000 to 2999 *
preserve.c (unused) 3000 to 3999 * panics in reiserfs_fs.h have numbers from 1000 to 1999
bitmap.c 4000 to 4999 * super.c 2000 to 2999
stree.c 5000 to 5999 * preserve.c (unused) 3000 to 3999
prints.c 6000 to 6999 * bitmap.c 4000 to 4999
namei.c 7000 to 7999 * stree.c 5000 to 5999
fix_nodes.c 8000 to 8999 * prints.c 6000 to 6999
dir.c 9000 to 9999 * namei.c 7000 to 7999
lbalance.c 10000 to 10999 * fix_nodes.c 8000 to 8999
ibalance.c 11000 to 11999 not ready * dir.c 9000 to 9999
do_balan.c 12000 to 12999 * lbalance.c 10000 to 10999
inode.c 13000 to 13999 * ibalance.c 11000 to 11999 not ready
file.c 14000 to 14999 * do_balan.c 12000 to 12999
objectid.c 15000 - 15999 * inode.c 13000 to 13999
buffer.c 16000 - 16999 * file.c 14000 to 14999
symlink.c 17000 - 17999 * objectid.c 15000 - 15999
* buffer.c 16000 - 16999
. */ * symlink.c 17000 - 17999
*
* . */
void __reiserfs_panic(struct super_block *sb, const char *id, void __reiserfs_panic(struct super_block *sb, const char *id,
const char *function, const char *fmt, ...) const char *function, const char *fmt, ...)
@ -411,9 +415,11 @@ void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
reiserfs_abort_journal(sb, errno); reiserfs_abort_journal(sb, errno);
} }
/* this prints internal nodes (4 keys/items in line) (dc_number, /*
dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number, * this prints internal nodes (4 keys/items in line) (dc_number,
dc_size)...*/ * dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
* dc_size)...
*/
static int print_internal(struct buffer_head *bh, int first, int last) static int print_internal(struct buffer_head *bh, int first, int last)
{ {
struct reiserfs_key *key; struct reiserfs_key *key;
@ -543,9 +549,11 @@ static int print_super_block(struct buffer_head *bh)
printk("Block count %u\n", sb_block_count(rs)); printk("Block count %u\n", sb_block_count(rs));
printk("Blocksize %d\n", sb_blocksize(rs)); printk("Blocksize %d\n", sb_blocksize(rs));
printk("Free blocks %u\n", sb_free_blocks(rs)); printk("Free blocks %u\n", sb_free_blocks(rs));
// FIXME: this would be confusing if /*
// someone stores reiserfs super block in some data block ;) * FIXME: this would be confusing if
* someone stores reiserfs super block in some data block ;)
// skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs); // skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
*/
skipped = bh->b_blocknr; skipped = bh->b_blocknr;
data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) - data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
(!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) + (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
@ -581,8 +589,8 @@ static int print_desc_block(struct buffer_head *bh)
return 0; return 0;
} }
/* ..., int print_mode, int first, int last) */
void print_block(struct buffer_head *bh, ...) //int print_mode, int first, int last) void print_block(struct buffer_head *bh, ...)
{ {
va_list args; va_list args;
int mode, first, last; int mode, first, last;

File diff suppressed because it is too large Load Diff

View File

@ -53,8 +53,10 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
} }
bforget(bh); bforget(bh);
/* old disk layout detection; those partitions can be mounted, but /*
* cannot be resized */ * old disk layout detection; those partitions can be mounted, but
* cannot be resized
*/
if (SB_BUFFER_WITH_SB(s)->b_blocknr * SB_BUFFER_WITH_SB(s)->b_size if (SB_BUFFER_WITH_SB(s)->b_blocknr * SB_BUFFER_WITH_SB(s)->b_size
!= REISERFS_DISK_OFFSET_IN_BYTES) { != REISERFS_DISK_OFFSET_IN_BYTES) {
printk printk
@ -86,12 +88,14 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
("reiserfs_resize: unable to allocate memory for journal bitmaps\n"); ("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
return -ENOMEM; return -ENOMEM;
} }
/* the new journal bitmaps are zero filled, now we copy in the bitmap /*
** node pointers from the old journal bitmap structs, and then * the new journal bitmaps are zero filled, now we copy i
** transfer the new data structures into the journal struct. * the bitmap node pointers from the old journal bitmap
** * structs, and then transfer the new data structures
** using the copy_size var below allows this code to work for * into the journal struct.
** both shrinking and expanding the FS. *
* using the copy_size var below allows this code to work for
* both shrinking and expanding the FS.
*/ */
copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr; copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr;
copy_size = copy_size =
@ -101,36 +105,45 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
jb = SB_JOURNAL(s)->j_list_bitmap + i; jb = SB_JOURNAL(s)->j_list_bitmap + i;
memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size); memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size);
/* just in case vfree schedules on us, copy the new /*
** pointer into the journal struct before freeing the * just in case vfree schedules on us, copy the new
** old one * pointer into the journal struct before freeing the
* old one
*/ */
node_tmp = jb->bitmaps; node_tmp = jb->bitmaps;
jb->bitmaps = jbitmap[i].bitmaps; jb->bitmaps = jbitmap[i].bitmaps;
vfree(node_tmp); vfree(node_tmp);
} }
/* allocate additional bitmap blocks, reallocate array of bitmap /*
* block pointers */ * allocate additional bitmap blocks, reallocate
* array of bitmap block pointers
*/
bitmap = bitmap =
vzalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new); vzalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
if (!bitmap) { if (!bitmap) {
/* Journal bitmaps are still supersized, but the memory isn't /*
* leaked, so I guess it's ok */ * Journal bitmaps are still supersized, but the
* memory isn't leaked, so I guess it's ok
*/
printk("reiserfs_resize: unable to allocate memory.\n"); printk("reiserfs_resize: unable to allocate memory.\n");
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < bmap_nr; i++) for (i = 0; i < bmap_nr; i++)
bitmap[i] = old_bitmap[i]; bitmap[i] = old_bitmap[i];
/* This doesn't go through the journal, but it doesn't have to. /*
* The changes are still atomic: We're synced up when the journal * This doesn't go through the journal, but it doesn't have to.
* transaction begins, and the new bitmaps don't matter if the * The changes are still atomic: We're synced up when the
* transaction fails. */ * journal transaction begins, and the new bitmaps don't
* matter if the transaction fails.
*/
for (i = bmap_nr; i < bmap_nr_new; i++) { for (i = bmap_nr; i < bmap_nr_new; i++) {
int depth; int depth;
/* don't use read_bitmap_block since it will cache /*
* the uninitialized bitmap */ * don't use read_bitmap_block since it will cache
* the uninitialized bitmap
*/
depth = reiserfs_write_unlock_nested(s); depth = reiserfs_write_unlock_nested(s);
bh = sb_bread(s, i * s->s_blocksize * 8); bh = sb_bread(s, i * s->s_blocksize * 8);
reiserfs_write_lock_nested(s, depth); reiserfs_write_lock_nested(s, depth);
@ -147,7 +160,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
depth = reiserfs_write_unlock_nested(s); depth = reiserfs_write_unlock_nested(s);
sync_dirty_buffer(bh); sync_dirty_buffer(bh);
reiserfs_write_lock_nested(s, depth); reiserfs_write_lock_nested(s, depth);
// update bitmap_info stuff /* update bitmap_info stuff */
bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
brelse(bh); brelse(bh);
} }
@ -156,9 +169,11 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
vfree(old_bitmap); vfree(old_bitmap);
} }
/* begin transaction, if there was an error, it's fine. Yes, we have /*
* begin transaction, if there was an error, it's fine. Yes, we have
* incorrect bitmaps now, but none of it is ever going to touch the * incorrect bitmaps now, but none of it is ever going to touch the
* disk anyway. */ * disk anyway.
*/
err = journal_begin(&th, s, 10); err = journal_begin(&th, s, 10);
if (err) if (err)
return err; return err;

File diff suppressed because it is too large Load Diff

View File

@ -153,13 +153,15 @@ static int reiserfs_unfreeze(struct super_block *s)
extern const struct in_core_key MAX_IN_CORE_KEY; extern const struct in_core_key MAX_IN_CORE_KEY;
/* this is used to delete "save link" when there are no items of a /*
file it points to. It can either happen if unlink is completed but * this is used to delete "save link" when there are no items of a
"save unlink" removal, or if file has both unlink and truncate * file it points to. It can either happen if unlink is completed but
pending and as unlink completes first (because key of "save link" * "save unlink" removal, or if file has both unlink and truncate
protecting unlink is bigger that a key lf "save link" which * pending and as unlink completes first (because key of "save link"
protects truncate), so there left no items to make truncate * protecting unlink is bigger that a key lf "save link" which
completion on */ * protects truncate), so there left no items to make truncate
* completion on
*/
static int remove_save_link_only(struct super_block *s, static int remove_save_link_only(struct super_block *s,
struct reiserfs_key *key, int oid_free) struct reiserfs_key *key, int oid_free)
{ {
@ -282,8 +284,10 @@ static int finish_unfinished(struct super_block *s)
inode = reiserfs_iget(s, &obj_key); inode = reiserfs_iget(s, &obj_key);
if (!inode) { if (!inode) {
/* the unlink almost completed, it just did not manage to remove /*
"save" link and release objectid */ * the unlink almost completed, it just did not
* manage to remove "save" link and release objectid
*/
reiserfs_warning(s, "vs-2180", "iget failed for %K", reiserfs_warning(s, "vs-2180", "iget failed for %K",
&obj_key); &obj_key);
retval = remove_save_link_only(s, &save_link_key, 1); retval = remove_save_link_only(s, &save_link_key, 1);
@ -303,10 +307,13 @@ static int finish_unfinished(struct super_block *s)
reiserfs_write_lock_nested(inode->i_sb, depth); reiserfs_write_lock_nested(inode->i_sb, depth);
if (truncate && S_ISDIR(inode->i_mode)) { if (truncate && S_ISDIR(inode->i_mode)) {
/* We got a truncate request for a dir which is impossible. /*
The only imaginable way is to execute unfinished truncate request * We got a truncate request for a dir which
then boot into old kernel, remove the file and create dir with * is impossible. The only imaginable way is to
the same key. */ * execute unfinished truncate request then boot
* into old kernel, remove the file and create dir
* with the same key.
*/
reiserfs_warning(s, "green-2101", reiserfs_warning(s, "green-2101",
"impossible truncate on a " "impossible truncate on a "
"directory %k. Please report", "directory %k. Please report",
@ -320,14 +327,16 @@ static int finish_unfinished(struct super_block *s)
if (truncate) { if (truncate) {
REISERFS_I(inode)->i_flags |= REISERFS_I(inode)->i_flags |=
i_link_saved_truncate_mask; i_link_saved_truncate_mask;
/* not completed truncate found. New size was committed together /*
with "save" link */ * not completed truncate found. New size was
* committed together with "save" link
*/
reiserfs_info(s, "Truncating %k to %Ld ..", reiserfs_info(s, "Truncating %k to %Ld ..",
INODE_PKEY(inode), inode->i_size); INODE_PKEY(inode), inode->i_size);
reiserfs_truncate_file(inode,
0 /* don't update modification time */
/*don't update modification time */ reiserfs_truncate_file(inode, 0);
);
retval = remove_save_link(inode, truncate); retval = remove_save_link(inode, truncate);
} else { } else {
REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask; REISERFS_I(inode)->i_flags |= i_link_saved_unlink_mask;
@ -373,10 +382,12 @@ static int finish_unfinished(struct super_block *s)
return retval; return retval;
} }
/* to protect file being unlinked from getting lost we "safe" link files /*
being unlinked. This link will be deleted in the same transaction with last * to protect file being unlinked from getting lost we "safe" link files
item of file. mounting the filesystem we scan all these links and remove * being unlinked. This link will be deleted in the same transaction with last
files which almost got lost */ * item of file. mounting the filesystem we scan all these links and remove
* files which almost got lost
*/
void add_save_link(struct reiserfs_transaction_handle *th, void add_save_link(struct reiserfs_transaction_handle *th,
struct inode *inode, int truncate) struct inode *inode, int truncate)
{ {
@ -530,7 +541,10 @@ static void reiserfs_put_super(struct super_block *s)
reiserfs_write_lock(s); reiserfs_write_lock(s);
/* change file system state to current state if it was mounted with read-write permissions */ /*
* change file system state to current state if it was mounted
* with read-write permissions
*/
if (!(s->s_flags & MS_RDONLY)) { if (!(s->s_flags & MS_RDONLY)) {
if (!journal_begin(&th, s, 10)) { if (!journal_begin(&th, s, 10)) {
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
@ -541,8 +555,9 @@ static void reiserfs_put_super(struct super_block *s)
} }
} }
/* note, journal_release checks for readonly mount, and can decide not /*
** to do a journal_end * note, journal_release checks for readonly mount, and can
* decide not to do a journal_end
*/ */
journal_release(&th, s); journal_release(&th, s);
@ -635,8 +650,9 @@ static void reiserfs_dirty_inode(struct inode *inode, int flags)
} }
reiserfs_write_lock(inode->i_sb); reiserfs_write_lock(inode->i_sb);
/* this is really only used for atime updates, so they don't have /*
** to be included in O_SYNC or fsync * this is really only used for atime updates, so they don't have
* to be included in O_SYNC or fsync
*/ */
err = journal_begin(&th, inode->i_sb, 1); err = journal_begin(&th, inode->i_sb, 1);
if (err) if (err)
@ -789,31 +805,53 @@ static const struct export_operations reiserfs_export_ops = {
.get_parent = reiserfs_get_parent, .get_parent = reiserfs_get_parent,
}; };
/* this struct is used in reiserfs_getopt () for containing the value for those /*
mount options that have values rather than being toggles. */ * this struct is used in reiserfs_getopt () for containing the value for
* those mount options that have values rather than being toggles.
*/
typedef struct { typedef struct {
char *value; char *value;
int setmask; /* bitmask which is to set on mount_options bitmask when this /*
value is found, 0 is no bits are to be changed. */ * bitmask which is to set on mount_options bitmask
int clrmask; /* bitmask which is to clear on mount_options bitmask when this * when this value is found, 0 is no bits are to be changed.
value is found, 0 is no bits are to be changed. This is */
applied BEFORE setmask */ int setmask;
/*
* bitmask which is to clear on mount_options bitmask
* when this value is found, 0 is no bits are to be changed.
* This is applied BEFORE setmask
*/
int clrmask;
} arg_desc_t; } arg_desc_t;
/* Set this bit in arg_required to allow empty arguments */ /* Set this bit in arg_required to allow empty arguments */
#define REISERFS_OPT_ALLOWEMPTY 31 #define REISERFS_OPT_ALLOWEMPTY 31
/* this struct is used in reiserfs_getopt() for describing the set of reiserfs /*
mount options */ * this struct is used in reiserfs_getopt() for describing the
* set of reiserfs mount options
*/
typedef struct { typedef struct {
char *option_name; char *option_name;
int arg_required; /* 0 if argument is not required, not 0 otherwise */
const arg_desc_t *values; /* list of values accepted by an option */ /* 0 if argument is not required, not 0 otherwise */
int setmask; /* bitmask which is to set on mount_options bitmask when this int arg_required;
value is found, 0 is no bits are to be changed. */
int clrmask; /* bitmask which is to clear on mount_options bitmask when this /* list of values accepted by an option */
value is found, 0 is no bits are to be changed. This is const arg_desc_t *values;
applied BEFORE setmask */
/*
* bitmask which is to set on mount_options bitmask
* when this value is found, 0 is no bits are to be changed.
*/
int setmask;
/*
* bitmask which is to clear on mount_options bitmask
* when this value is found, 0 is no bits are to be changed.
* This is applied BEFORE setmask
*/
int clrmask;
} opt_desc_t; } opt_desc_t;
/* possible values for -o data= */ /* possible values for -o data= */
@ -834,8 +872,10 @@ static const arg_desc_t barrier_mode[] = {
{.value = NULL} {.value = NULL}
}; };
/* possible values for "-o block-allocator=" and bits which are to be set in /*
s_mount_opt of reiserfs specific part of in-core super block */ * possible values for "-o block-allocator=" and bits which are to be set in
* s_mount_opt of reiserfs specific part of in-core super block
*/
static const arg_desc_t balloc[] = { static const arg_desc_t balloc[] = {
{"noborder", 1 << REISERFS_NO_BORDER, 0}, {"noborder", 1 << REISERFS_NO_BORDER, 0},
{"border", 0, 1 << REISERFS_NO_BORDER}, {"border", 0, 1 << REISERFS_NO_BORDER},
@ -865,21 +905,25 @@ static const arg_desc_t error_actions[] = {
{NULL, 0, 0}, {NULL, 0, 0},
}; };
/* proceed only one option from a list *cur - string containing of mount options /*
opts - array of options which are accepted * proceed only one option from a list *cur - string containing of mount
opt_arg - if option is found and requires an argument and if it is specifed * options
in the input - pointer to the argument is stored here * opts - array of options which are accepted
bit_flags - if option requires to set a certain bit - it is set here * opt_arg - if option is found and requires an argument and if it is specifed
return -1 if unknown option is found, opt->arg_required otherwise */ * in the input - pointer to the argument is stored here
* bit_flags - if option requires to set a certain bit - it is set here
* return -1 if unknown option is found, opt->arg_required otherwise
*/
static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts, static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
char **opt_arg, unsigned long *bit_flags) char **opt_arg, unsigned long *bit_flags)
{ {
char *p; char *p;
/* foo=bar, /*
^ ^ ^ * foo=bar,
| | +-- option_end * ^ ^ ^
| +-- arg_start * | | +-- option_end
+-- option_start * | +-- arg_start
* +-- option_start
*/ */
const opt_desc_t *opt; const opt_desc_t *opt;
const arg_desc_t *arg; const arg_desc_t *arg;
@ -894,9 +938,12 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
} }
if (!strncmp(p, "alloc=", 6)) { if (!strncmp(p, "alloc=", 6)) {
/* Ugly special case, probably we should redo options parser so that /*
it can understand several arguments for some options, also so that * Ugly special case, probably we should redo options
it can fill several bitfields with option values. */ * parser so that it can understand several arguments for
* some options, also so that it can fill several bitfields
* with option values.
*/
if (reiserfs_parse_alloc_options(s, p + 6)) { if (reiserfs_parse_alloc_options(s, p + 6)) {
return -1; return -1;
} else { } else {
@ -959,7 +1006,10 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
return -1; return -1;
} }
/* move to the argument, or to next option if argument is not required */ /*
* move to the argument, or to next option if argument is not
* required
*/
p++; p++;
if (opt->arg_required if (opt->arg_required
@ -996,12 +1046,20 @@ static int reiserfs_getopt(struct super_block *s, char **cur, opt_desc_t * opts,
} }
/* returns 0 if something is wrong in option string, 1 - otherwise */ /* returns 0 if something is wrong in option string, 1 - otherwise */
static int reiserfs_parse_options(struct super_block *s, char *options, /* string given via mount's -o */ static int reiserfs_parse_options(struct super_block *s,
/* string given via mount's -o */
char *options,
/*
* after the parsing phase, contains the
* collection of bitflags defining what
* mount options were selected.
*/
unsigned long *mount_options, unsigned long *mount_options,
/* after the parsing phase, contains the
collection of bitflags defining what /* strtol-ed from NNN of resize=NNN */
mount options were selected. */ unsigned long *blocks,
unsigned long *blocks, /* strtol-ed from NNN of resize=NNN */
char **jdev_name, char **jdev_name,
unsigned int *commit_max_age, unsigned int *commit_max_age,
char **qf_names, char **qf_names,
@ -1011,7 +1069,10 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
char *arg = NULL; char *arg = NULL;
char *pos; char *pos;
opt_desc_t opts[] = { opt_desc_t opts[] = {
/* Compatibility stuff, so that -o notail for old setups still work */ /*
* Compatibility stuff, so that -o notail for old
* setups still work
*/
{"tails",.arg_required = 't',.values = tails}, {"tails",.arg_required = 't',.values = tails},
{"notail",.clrmask = {"notail",.clrmask =
(1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)}, (1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)},
@ -1056,8 +1117,10 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
*blocks = 0; *blocks = 0;
if (!options || !*options) if (!options || !*options)
/* use default configuration: create tails, journaling on, no /*
conversion to newest format */ * use default configuration: create tails, journaling on, no
* conversion to newest format
*/
return 1; return 1;
for (pos = options; pos;) { for (pos = options; pos;) {
@ -1110,7 +1173,8 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
if (c == 'j') { if (c == 'j') {
if (arg && *arg && jdev_name) { if (arg && *arg && jdev_name) {
if (*jdev_name) { //Hm, already assigned? /* Hm, already assigned? */
if (*jdev_name) {
reiserfs_warning(s, "super-6510", reiserfs_warning(s, "super-6510",
"journal device was " "journal device was "
"already specified to " "already specified to "
@ -1363,8 +1427,10 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
safe_mask |= 1 << REISERFS_USRQUOTA; safe_mask |= 1 << REISERFS_USRQUOTA;
safe_mask |= 1 << REISERFS_GRPQUOTA; safe_mask |= 1 << REISERFS_GRPQUOTA;
/* Update the bitmask, taking care to keep /*
* the bits we're not allowed to change here */ * Update the bitmask, taking care to keep
* the bits we're not allowed to change here
*/
REISERFS_SB(s)->s_mount_opt = REISERFS_SB(s)->s_mount_opt =
(REISERFS_SB(s)-> (REISERFS_SB(s)->
s_mount_opt & ~safe_mask) | (mount_options & safe_mask); s_mount_opt & ~safe_mask) | (mount_options & safe_mask);
@ -1428,7 +1494,9 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
handle_data_mode(s, mount_options); handle_data_mode(s, mount_options);
handle_barrier_mode(s, mount_options); handle_barrier_mode(s, mount_options);
REISERFS_SB(s)->s_mount_state = sb_umount_state(rs); REISERFS_SB(s)->s_mount_state = sb_umount_state(rs);
s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */
/* now it is safe to call journal_begin */
s->s_flags &= ~MS_RDONLY;
err = journal_begin(&th, s, 10); err = journal_begin(&th, s, 10);
if (err) if (err)
goto out_err_unlock; goto out_err_unlock;
@ -1490,9 +1558,9 @@ static int read_super_block(struct super_block *s, int offset)
brelse(bh); brelse(bh);
return 1; return 1;
} }
// /*
// ok, reiserfs signature (old or new) found in at the given offset * ok, reiserfs signature (old or new) found in at the given offset
// */
fs_blocksize = sb_blocksize(rs); fs_blocksize = sb_blocksize(rs);
brelse(bh); brelse(bh);
sb_set_blocksize(s, fs_blocksize); sb_set_blocksize(s, fs_blocksize);
@ -1530,9 +1598,11 @@ static int read_super_block(struct super_block *s, int offset)
SB_BUFFER_WITH_SB(s) = bh; SB_BUFFER_WITH_SB(s) = bh;
SB_DISK_SUPER_BLOCK(s) = rs; SB_DISK_SUPER_BLOCK(s) = rs;
/*
* magic is of non-standard journal filesystem, look at s_version to
* find which format is in use
*/
if (is_reiserfs_jr(rs)) { if (is_reiserfs_jr(rs)) {
/* magic is of non-standard journal filesystem, look at s_version to
find which format is in use */
if (sb_version(rs) == REISERFS_VERSION_2) if (sb_version(rs) == REISERFS_VERSION_2)
reiserfs_info(s, "found reiserfs format \"3.6\"" reiserfs_info(s, "found reiserfs format \"3.6\""
" with non-standard journal\n"); " with non-standard journal\n");
@ -1546,8 +1616,10 @@ static int read_super_block(struct super_block *s, int offset)
return 1; return 1;
} }
} else } else
/* s_version of standard format may contain incorrect information, /*
so we just look at the magic string */ * s_version of standard format may contain incorrect
* information, so we just look at the magic string
*/
reiserfs_info(s, reiserfs_info(s,
"found reiserfs format \"%s\" with standard journal\n", "found reiserfs format \"%s\" with standard journal\n",
is_reiserfs_3_5(rs) ? "3.5" : "3.6"); is_reiserfs_3_5(rs) ? "3.5" : "3.6");
@ -1559,8 +1631,9 @@ static int read_super_block(struct super_block *s, int offset)
s->dq_op = &reiserfs_quota_operations; s->dq_op = &reiserfs_quota_operations;
#endif #endif
/* new format is limited by the 32 bit wide i_blocks field, want to /*
** be one full block below that. * new format is limited by the 32 bit wide i_blocks field, want to
* be one full block below that.
*/ */
s->s_maxbytes = (512LL << 32) - s->s_blocksize; s->s_maxbytes = (512LL << 32) - s->s_blocksize;
return 0; return 0;
@ -1579,14 +1652,15 @@ static int reread_meta_blocks(struct super_block *s)
return 0; return 0;
} }
///////////////////////////////////////////////////// /* hash detection stuff */
// hash detection stuff
// if root directory is empty - we set default - Yura's - hash and /*
// warn about it * if root directory is empty - we set default - Yura's - hash and
// FIXME: we look for only one name in a directory. If tea and yura * warn about it
// bith have the same value - we ask user to send report to the * FIXME: we look for only one name in a directory. If tea and yura
// mailing list * both have the same value - we ask user to send report to the
* mailing list
*/
static __u32 find_hash_out(struct super_block *s) static __u32 find_hash_out(struct super_block *s)
{ {
int retval; int retval;
@ -1598,7 +1672,7 @@ static __u32 find_hash_out(struct super_block *s)
inode = s->s_root->d_inode; inode = s->s_root->d_inode;
do { // Some serious "goto"-hater was there ;) do { /* Some serious "goto"-hater was there ;) */
u32 teahash, r5hash, yurahash; u32 teahash, r5hash, yurahash;
make_cpu_key(&key, inode, ~0, TYPE_DIRENTRY, 3); make_cpu_key(&key, inode, ~0, TYPE_DIRENTRY, 3);
@ -1663,23 +1737,25 @@ static __u32 find_hash_out(struct super_block *s)
return hash; return hash;
} }
// finds out which hash names are sorted with /* finds out which hash names are sorted with */
static int what_hash(struct super_block *s) static int what_hash(struct super_block *s)
{ {
__u32 code; __u32 code;
code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s)); code = sb_hash_function_code(SB_DISK_SUPER_BLOCK(s));
/* reiserfs_hash_detect() == true if any of the hash mount options /*
** were used. We must check them to make sure the user isn't * reiserfs_hash_detect() == true if any of the hash mount options
** using a bad hash value * were used. We must check them to make sure the user isn't
* using a bad hash value
*/ */
if (code == UNSET_HASH || reiserfs_hash_detect(s)) if (code == UNSET_HASH || reiserfs_hash_detect(s))
code = find_hash_out(s); code = find_hash_out(s);
if (code != UNSET_HASH && reiserfs_hash_detect(s)) { if (code != UNSET_HASH && reiserfs_hash_detect(s)) {
/* detection has found the hash, and we must check against the /*
** mount options * detection has found the hash, and we must check against the
* mount options
*/ */
if (reiserfs_rupasov_hash(s) && code != YURA_HASH) { if (reiserfs_rupasov_hash(s) && code != YURA_HASH) {
reiserfs_warning(s, "reiserfs-2507", reiserfs_warning(s, "reiserfs-2507",
@ -1701,7 +1777,10 @@ static int what_hash(struct super_block *s)
code = UNSET_HASH; code = UNSET_HASH;
} }
} else { } else {
/* find_hash_out was not called or could not determine the hash */ /*
* find_hash_out was not called or
* could not determine the hash
*/
if (reiserfs_rupasov_hash(s)) { if (reiserfs_rupasov_hash(s)) {
code = YURA_HASH; code = YURA_HASH;
} else if (reiserfs_tea_hash(s)) { } else if (reiserfs_tea_hash(s)) {
@ -1711,8 +1790,9 @@ static int what_hash(struct super_block *s)
} }
} }
/* if we are mounted RW, and we have a new valid hash code, update /*
** the super * if we are mounted RW, and we have a new valid hash code, update
* the super
*/ */
if (code != UNSET_HASH && if (code != UNSET_HASH &&
!(s->s_flags & MS_RDONLY) && !(s->s_flags & MS_RDONLY) &&
@ -1722,7 +1802,7 @@ static int what_hash(struct super_block *s)
return code; return code;
} }
// return pointer to appropriate function /* return pointer to appropriate function */
static hashf_t hash_function(struct super_block *s) static hashf_t hash_function(struct super_block *s)
{ {
switch (what_hash(s)) { switch (what_hash(s)) {
@ -1739,7 +1819,7 @@ static hashf_t hash_function(struct super_block *s)
return NULL; return NULL;
} }
// this is used to set up correct value for old partitions /* this is used to set up correct value for old partitions */
static int function2code(hashf_t func) static int function2code(hashf_t func)
{ {
if (func == keyed_hash) if (func == keyed_hash)
@ -1749,7 +1829,7 @@ static int function2code(hashf_t func)
if (func == r5_hash) if (func == r5_hash)
return R5_HASH; return R5_HASH;
BUG(); // should never happen BUG(); /* should never happen */
return 0; return 0;
} }
@ -1784,8 +1864,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
sbi->s_mount_opt |= (1 << REISERFS_SMALLTAIL); sbi->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
sbi->s_mount_opt |= (1 << REISERFS_ERROR_RO); sbi->s_mount_opt |= (1 << REISERFS_ERROR_RO);
sbi->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH); sbi->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH);
/* no preallocation minimum, be smart in /* no preallocation minimum, be smart in reiserfs_file_write instead */
reiserfs_file_write instead */
sbi->s_alloc_options.preallocmin = 0; sbi->s_alloc_options.preallocmin = 0;
/* Preallocate by 16 blocks (17-1) at once */ /* Preallocate by 16 blocks (17-1) at once */
sbi->s_alloc_options.preallocsize = 17; sbi->s_alloc_options.preallocsize = 17;
@ -1828,10 +1907,17 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
goto error_unlocked; goto error_unlocked;
} }
/* try old format (undistributed bitmap, super block in 8-th 1k block of a device) */ /*
* try old format (undistributed bitmap, super block in 8-th 1k
* block of a device)
*/
if (!read_super_block(s, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) if (!read_super_block(s, REISERFS_OLD_DISK_OFFSET_IN_BYTES))
old_format = 1; old_format = 1;
/* try new format (64-th 1k block), which can contain reiserfs super block */
/*
* try new format (64-th 1k block), which can contain reiserfs
* super block
*/
else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) { else if (read_super_block(s, REISERFS_DISK_OFFSET_IN_BYTES)) {
SWARN(silent, s, "sh-2021", "can not find reiserfs on %s", SWARN(silent, s, "sh-2021", "can not find reiserfs on %s",
s->s_id); s->s_id);
@ -1839,9 +1925,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
} }
rs = SB_DISK_SUPER_BLOCK(s); rs = SB_DISK_SUPER_BLOCK(s);
/* Let's do basic sanity check to verify that underlying device is not /*
smaller than the filesystem. If the check fails then abort and scream, * Let's do basic sanity check to verify that underlying device is not
because bad stuff will happen otherwise. */ * smaller than the filesystem. If the check fails then abort and
* scream, because bad stuff will happen otherwise.
*/
if (s->s_bdev && s->s_bdev->bd_inode if (s->s_bdev && s->s_bdev->bd_inode
&& i_size_read(s->s_bdev->bd_inode) < && i_size_read(s->s_bdev->bd_inode) <
sb_block_count(rs) * sb_blocksize(rs)) { sb_block_count(rs) * sb_blocksize(rs)) {
@ -1885,15 +1973,16 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
printk("reiserfs: using flush barriers\n"); printk("reiserfs: using flush barriers\n");
} }
// set_device_ro(s->s_dev, 1) ;
if (journal_init(s, jdev_name, old_format, commit_max_age)) { if (journal_init(s, jdev_name, old_format, commit_max_age)) {
SWARN(silent, s, "sh-2022", SWARN(silent, s, "sh-2022",
"unable to initialize journal space"); "unable to initialize journal space");
goto error_unlocked; goto error_unlocked;
} else { } else {
jinit_done = 1; /* once this is set, journal_release must be called /*
** if we error out of the mount * once this is set, journal_release must be called
*/ * if we error out of the mount
*/
jinit_done = 1;
} }
if (reread_meta_blocks(s)) { if (reread_meta_blocks(s)) {
@ -1938,7 +2027,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
s->s_root = d_make_root(root_inode); s->s_root = d_make_root(root_inode);
if (!s->s_root) if (!s->s_root)
goto error; goto error;
// define and initialize hash function /* define and initialize hash function */
sbi->s_hash_function = hash_function(s); sbi->s_hash_function = hash_function(s);
if (sbi->s_hash_function == NULL) { if (sbi->s_hash_function == NULL) {
dput(s->s_root); dput(s->s_root);
@ -1967,10 +2056,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
set_sb_umount_state(rs, REISERFS_ERROR_FS); set_sb_umount_state(rs, REISERFS_ERROR_FS);
set_sb_fs_state(rs, 0); set_sb_fs_state(rs, 0);
/* Clear out s_bmap_nr if it would wrap. We can handle this /*
* Clear out s_bmap_nr if it would wrap. We can handle this
* case, but older revisions can't. This will cause the * case, but older revisions can't. This will cause the
* file system to fail mount on those older implementations, * file system to fail mount on those older implementations,
* avoiding corruption. -jeffm */ * avoiding corruption. -jeffm
*/
if (bmap_would_wrap(reiserfs_bmap_count(s)) && if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
sb_bmap_nr(rs) != 0) { sb_bmap_nr(rs) != 0) {
reiserfs_warning(s, "super-2030", "This file system " reiserfs_warning(s, "super-2030", "This file system "
@ -1983,8 +2074,10 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
} }
if (old_format_only(s)) { if (old_format_only(s)) {
/* filesystem of format 3.5 either with standard or non-standard /*
journal */ * filesystem of format 3.5 either with standard
* or non-standard journal
*/
if (convert_reiserfs(s)) { if (convert_reiserfs(s)) {
/* and -o conv is given */ /* and -o conv is given */
if (!silent) if (!silent)
@ -1992,8 +2085,11 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
"converting 3.5 filesystem to the 3.6 format"); "converting 3.5 filesystem to the 3.6 format");
if (is_reiserfs_3_5(rs)) if (is_reiserfs_3_5(rs))
/* put magic string of 3.6 format. 2.2 will not be able to /*
mount this filesystem anymore */ * put magic string of 3.6 format.
* 2.2 will not be able to
* mount this filesystem anymore
*/
memcpy(rs->s_v1.s_magic, memcpy(rs->s_v1.s_magic,
reiserfs_3_6_magic_string, reiserfs_3_6_magic_string,
sizeof sizeof
@ -2027,7 +2123,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
} }
reiserfs_write_lock(s); reiserfs_write_lock(s);
/* look for files which were to be removed in previous session */ /*
* look for files which were to be removed in previous session
*/
finish_unfinished(s); finish_unfinished(s);
} else { } else {
if (old_format_only(s) && !silent) { if (old_format_only(s) && !silent) {
@ -2043,7 +2141,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
} }
reiserfs_write_lock(s); reiserfs_write_lock(s);
} }
// mark hash in super block: it could be unset. overwrite should be ok /*
* mark hash in super block: it could be unset. overwrite should be ok
*/
set_sb_hash_function_code(rs, function2code(sbi->s_hash_function)); set_sb_hash_function_code(rs, function2code(sbi->s_hash_function));
handle_attrs(s); handle_attrs(s);
@ -2247,7 +2347,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
goto out; goto out;
} }
inode = path->dentry->d_inode; inode = path->dentry->d_inode;
/* We must not pack tails for quota files on reiserfs for quota IO to work */ /*
* We must not pack tails for quota files on reiserfs for quota
* IO to work
*/
if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
err = reiserfs_unpack(inode, NULL); err = reiserfs_unpack(inode, NULL);
if (err) { if (err) {
@ -2288,10 +2391,12 @@ out:
return err; return err;
} }
/* Read data from quotafile - avoid pagecache and such because we cannot afford /*
* Read data from quotafile - avoid pagecache and such because we cannot afford
* acquiring the locks... As quota files are never truncated and quota code * acquiring the locks... As quota files are never truncated and quota code
* itself serializes the operations (and no one else should touch the files) * itself serializes the operations (and no one else should touch the files)
* we don't have to be afraid of races */ * we don't have to be afraid of races
*/
static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data, static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
size_t len, loff_t off) size_t len, loff_t off)
{ {
@ -2312,7 +2417,10 @@ static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
sb->s_blocksize - offset < sb->s_blocksize - offset <
toread ? sb->s_blocksize - offset : toread; toread ? sb->s_blocksize - offset : toread;
tmp_bh.b_state = 0; tmp_bh.b_state = 0;
/* Quota files are without tails so we can safely use this function */ /*
* Quota files are without tails so we can safely
* use this function
*/
reiserfs_write_lock(sb); reiserfs_write_lock(sb);
err = reiserfs_get_block(inode, blk, &tmp_bh, 0); err = reiserfs_get_block(inode, blk, &tmp_bh, 0);
reiserfs_write_unlock(sb); reiserfs_write_unlock(sb);
@ -2335,8 +2443,10 @@ static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,
return len; return len;
} }
/* Write to quotafile (we know the transaction is already started and has /*
* enough credits) */ * Write to quotafile (we know the transaction is already started and has
* enough credits)
*/
static ssize_t reiserfs_quota_write(struct super_block *sb, int type, static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
const char *data, size_t len, loff_t off) const char *data, size_t len, loff_t off)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright
* details
*/ */
#include <linux/time.h> #include <linux/time.h>
@ -7,13 +8,19 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include "reiserfs.h" #include "reiserfs.h"
/* access to tail : when one is going to read tail it must make sure, that is not running. /*
direct2indirect and indirect2direct can not run concurrently */ * access to tail : when one is going to read tail it must make sure, that is
* not running. direct2indirect and indirect2direct can not run concurrently
*/
/* Converts direct items to an unformatted node. Panics if file has no /*
tail. -ENOSPC if no disk space for conversion */ * Converts direct items to an unformatted node. Panics if file has no
/* path points to first direct item of the file regarless of how many of * tail. -ENOSPC if no disk space for conversion
them are there */ */
/*
* path points to first direct item of the file regardless of how many of
* them are there
*/
int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode, int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
struct treepath *path, struct buffer_head *unbh, struct treepath *path, struct buffer_head *unbh,
loff_t tail_offset) loff_t tail_offset)
@ -22,14 +29,20 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
struct buffer_head *up_to_date_bh; struct buffer_head *up_to_date_bh;
struct item_head *p_le_ih = tp_item_head(path); struct item_head *p_le_ih = tp_item_head(path);
unsigned long total_tail = 0; unsigned long total_tail = 0;
struct cpu_key end_key; /* Key to search for the last byte of the
converted item. */ /* Key to search for the last byte of the converted item. */
struct item_head ind_ih; /* new indirect item to be inserted or struct cpu_key end_key;
key of unfm pointer to be pasted */
int blk_size, retval; /* returned value for reiserfs_insert_item and clones */ /*
unp_t unfm_ptr; /* Handle on an unformatted node * new indirect item to be inserted or key
that will be inserted in the * of unfm pointer to be pasted
tree. */ */
struct item_head ind_ih;
int blk_size;
/* returned value for reiserfs_insert_item and clones */
int retval;
/* Handle on an unformatted node that will be inserted in the tree. */
unp_t unfm_ptr;
BUG_ON(!th->t_trans_id); BUG_ON(!th->t_trans_id);
@ -37,8 +50,10 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
blk_size = sb->s_blocksize; blk_size = sb->s_blocksize;
/* and key to search for append or insert pointer to the new /*
unformatted node. */ * and key to search for append or insert pointer to the new
* unformatted node.
*/
copy_item_head(&ind_ih, p_le_ih); copy_item_head(&ind_ih, p_le_ih);
set_le_ih_k_offset(&ind_ih, tail_offset); set_le_ih_k_offset(&ind_ih, tail_offset);
set_le_ih_k_type(&ind_ih, TYPE_INDIRECT); set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
@ -76,20 +91,26 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
if (retval) { if (retval) {
return retval; return retval;
} }
// note: from here there are two keys which have matching first /*
// three key components. They only differ by the fourth one. * note: from here there are two keys which have matching first
* three key components. They only differ by the fourth one.
*/
/* Set the key to search for the direct items of the file */ /* Set the key to search for the direct items of the file */
make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT, make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
4); 4);
/* Move bytes from the direct items to the new unformatted node /*
and delete them. */ * Move bytes from the direct items to the new unformatted node
* and delete them.
*/
while (1) { while (1) {
int tail_size; int tail_size;
/* end_key.k_offset is set so, that we will always have found /*
last item of the file */ * end_key.k_offset is set so, that we will always have found
* last item of the file
*/
if (search_for_position_by_key(sb, &end_key, path) == if (search_for_position_by_key(sb, &end_key, path) ==
POSITION_FOUND) POSITION_FOUND)
reiserfs_panic(sb, "PAP-14050", reiserfs_panic(sb, "PAP-14050",
@ -101,11 +122,12 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1)) tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1))
+ ih_item_len(p_le_ih) - 1; + ih_item_len(p_le_ih) - 1;
/* we only send the unbh pointer if the buffer is not up to date. /*
** this avoids overwriting good data from writepage() with old data * we only send the unbh pointer if the buffer is not
** from the disk or buffer cache * up to date. this avoids overwriting good data from
** Special case: unbh->b_page will be NULL if we are coming through * writepage() with old data from the disk or buffer cache
** DIRECT_IO handler here. * Special case: unbh->b_page will be NULL if we are coming
* through DIRECT_IO handler here.
*/ */
if (!unbh->b_page || buffer_uptodate(unbh) if (!unbh->b_page || buffer_uptodate(unbh)
|| PageUptodate(unbh->b_page)) { || PageUptodate(unbh->b_page)) {
@ -117,13 +139,15 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
up_to_date_bh); up_to_date_bh);
total_tail += retval; total_tail += retval;
/* done: file does not have direct items anymore */
if (tail_size == retval) if (tail_size == retval)
// done: file does not have direct items anymore
break; break;
} }
/* if we've copied bytes from disk into the page, we need to zero /*
** out the unused part of the block (it was not up to date before) * if we've copied bytes from disk into the page, we need to zero
* out the unused part of the block (it was not up to date before)
*/ */
if (up_to_date_bh) { if (up_to_date_bh) {
unsigned pgoff = unsigned pgoff =
@ -146,9 +170,11 @@ void reiserfs_unmap_buffer(struct buffer_head *bh)
BUG(); BUG();
} }
clear_buffer_dirty(bh); clear_buffer_dirty(bh);
/* Remove the buffer from whatever list it belongs to. We are mostly /*
interested in removing it from per-sb j_dirty_buffers list, to avoid * Remove the buffer from whatever list it belongs to. We are mostly
BUG() on attempt to write not mapped buffer */ * interested in removing it from per-sb j_dirty_buffers list, to avoid
* BUG() on attempt to write not mapped buffer
*/
if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) { if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
struct inode *inode = bh->b_page->mapping->host; struct inode *inode = bh->b_page->mapping->host;
struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
@ -164,12 +190,14 @@ void reiserfs_unmap_buffer(struct buffer_head *bh)
unlock_buffer(bh); unlock_buffer(bh);
} }
/* this first locks inode (neither reads nor sync are permitted), /*
reads tail through page cache, insert direct item. When direct item * this first locks inode (neither reads nor sync are permitted),
inserted successfully inode is left locked. Return value is always * reads tail through page cache, insert direct item. When direct item
what we expect from it (number of cut bytes). But when tail remains * inserted successfully inode is left locked. Return value is always
in the unformatted node, we set mode to SKIP_BALANCING and unlock * what we expect from it (number of cut bytes). But when tail remains
inode */ * in the unformatted node, we set mode to SKIP_BALANCING and unlock
* inode
*/
int indirect2direct(struct reiserfs_transaction_handle *th, int indirect2direct(struct reiserfs_transaction_handle *th,
struct inode *inode, struct page *page, struct inode *inode, struct page *page,
struct treepath *path, /* path to the indirect item. */ struct treepath *path, /* path to the indirect item. */
@ -207,9 +235,11 @@ int indirect2direct(struct reiserfs_transaction_handle *th,
1) * sb->s_blocksize; 1) * sb->s_blocksize;
pos1 = pos; pos1 = pos;
// we are protected by i_mutex. The tail can not disapper, not /*
// append can be done either * we are protected by i_mutex. The tail can not disapper, not
// we are in truncate or packing tail in file_release * append can be done either
* we are in truncate or packing tail in file_release
*/
tail = (char *)kmap(page); /* this can schedule */ tail = (char *)kmap(page); /* this can schedule */
@ -236,9 +266,10 @@ int indirect2direct(struct reiserfs_transaction_handle *th,
pos1 + 1, TYPE_DIRECT, round_tail_len, pos1 + 1, TYPE_DIRECT, round_tail_len,
0xffff /*ih_free_space */ ); 0xffff /*ih_free_space */ );
/* we want a pointer to the first byte of the tail in the page. /*
** the page was locked and this part of the page was up to date when * we want a pointer to the first byte of the tail in the page.
** indirect2direct was called, so we know the bytes are still valid * the page was locked and this part of the page was up to date when
* indirect2direct was called, so we know the bytes are still valid
*/ */
tail = tail + (pos & (PAGE_CACHE_SIZE - 1)); tail = tail + (pos & (PAGE_CACHE_SIZE - 1));
@ -250,12 +281,14 @@ int indirect2direct(struct reiserfs_transaction_handle *th,
/* Insert tail as new direct item in the tree */ /* Insert tail as new direct item in the tree */
if (reiserfs_insert_item(th, path, &key, &s_ih, inode, if (reiserfs_insert_item(th, path, &key, &s_ih, inode,
tail ? tail : NULL) < 0) { tail ? tail : NULL) < 0) {
/* No disk memory. So we can not convert last unformatted node /*
to the direct item. In this case we used to adjust * No disk memory. So we can not convert last unformatted node
indirect items's ih_free_space. Now ih_free_space is not * to the direct item. In this case we used to adjust
used, it would be ideal to write zeros to corresponding * indirect items's ih_free_space. Now ih_free_space is not
unformatted node. For now i_size is considered as guard for * used, it would be ideal to write zeros to corresponding
going out of file size */ * unformatted node. For now i_size is considered as guard for
* going out of file size
*/
kunmap(page); kunmap(page);
return block_size - round_tail_len; return block_size - round_tail_len;
} }
@ -264,12 +297,16 @@ int indirect2direct(struct reiserfs_transaction_handle *th,
/* make sure to get the i_blocks changes from reiserfs_insert_item */ /* make sure to get the i_blocks changes from reiserfs_insert_item */
reiserfs_update_sd(th, inode); reiserfs_update_sd(th, inode);
// note: we have now the same as in above direct2indirect /*
// conversion: there are two keys which have matching first three * note: we have now the same as in above direct2indirect
// key components. They only differ by the fouhth one. * conversion: there are two keys which have matching first three
* key components. They only differ by the fourth one.
*/
/* We have inserted new direct item and must remove last /*
unformatted node. */ * We have inserted new direct item and must remove last
* unformatted node.
*/
*mode = M_CUT; *mode = M_CUT;
/* we store position of first direct item in the in-core inode */ /* we store position of first direct item in the in-core inode */

View File

@ -56,9 +56,11 @@
#define XAROOT_NAME "xattrs" #define XAROOT_NAME "xattrs"
/* Helpers for inode ops. We do this so that we don't have all the VFS /*
* Helpers for inode ops. We do this so that we don't have all the VFS
* overhead and also for proper i_mutex annotation. * overhead and also for proper i_mutex annotation.
* dir->i_mutex must be held for all of them. */ * dir->i_mutex must be held for all of them.
*/
#ifdef CONFIG_REISERFS_FS_XATTR #ifdef CONFIG_REISERFS_FS_XATTR
static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) static int xattr_create(struct inode *dir, struct dentry *dentry, int mode)
{ {
@ -73,10 +75,12 @@ static int xattr_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
return dir->i_op->mkdir(dir, dentry, mode); return dir->i_op->mkdir(dir, dentry, mode);
} }
/* We use I_MUTEX_CHILD here to silence lockdep. It's safe because xattr /*
* We use I_MUTEX_CHILD here to silence lockdep. It's safe because xattr
* mutation ops aren't called during rename or splace, which are the * mutation ops aren't called during rename or splace, which are the
* only other users of I_MUTEX_CHILD. It violates the ordering, but that's * only other users of I_MUTEX_CHILD. It violates the ordering, but that's
* better than allocating another subclass just for this code. */ * better than allocating another subclass just for this code.
*/
static int xattr_unlink(struct inode *dir, struct dentry *dentry) static int xattr_unlink(struct inode *dir, struct dentry *dentry)
{ {
int error; int error;
@ -166,9 +170,11 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags)
return xadir; return xadir;
} }
/* The following are side effects of other operations that aren't explicitly /*
* The following are side effects of other operations that aren't explicitly
* modifying extended attributes. This includes operations such as permissions * modifying extended attributes. This includes operations such as permissions
* or ownership changes, object deletions, etc. */ * or ownership changes, object deletions, etc.
*/
struct reiserfs_dentry_buf { struct reiserfs_dentry_buf {
struct dir_context ctx; struct dir_context ctx;
struct dentry *xadir; struct dentry *xadir;
@ -267,11 +273,13 @@ static int reiserfs_for_each_xattr(struct inode *inode,
cleanup_dentry_buf(&buf); cleanup_dentry_buf(&buf);
if (!err) { if (!err) {
/* We start a transaction here to avoid a ABBA situation /*
* We start a transaction here to avoid a ABBA situation
* between the xattr root's i_mutex and the journal lock. * between the xattr root's i_mutex and the journal lock.
* This doesn't incur much additional overhead since the * This doesn't incur much additional overhead since the
* new transaction will just nest inside the * new transaction will just nest inside the
* outer transaction. */ * outer transaction.
*/
int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 + int blocks = JOURNAL_PER_BALANCE_CNT * 2 + 2 +
4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); 4 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
struct reiserfs_transaction_handle th; struct reiserfs_transaction_handle th;
@ -349,9 +357,11 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
} }
#ifdef CONFIG_REISERFS_FS_XATTR #ifdef CONFIG_REISERFS_FS_XATTR
/* Returns a dentry corresponding to a specific extended attribute file /*
* Returns a dentry corresponding to a specific extended attribute file
* for the inode. If flags allow, the file is created. Otherwise, a * for the inode. If flags allow, the file is created. Otherwise, a
* valid or negative dentry, or an error is returned. */ * valid or negative dentry, or an error is returned.
*/
static struct dentry *xattr_lookup(struct inode *inode, const char *name, static struct dentry *xattr_lookup(struct inode *inode, const char *name,
int flags) int flags)
{ {
@ -400,8 +410,10 @@ static struct page *reiserfs_get_page(struct inode *dir, size_t n)
{ {
struct address_space *mapping = dir->i_mapping; struct address_space *mapping = dir->i_mapping;
struct page *page; struct page *page;
/* We can deadlock if we try to free dentries, /*
and an unlink/rmdir has just occurred - GFP_NOFS avoids this */ * We can deadlock if we try to free dentries,
* and an unlink/rmdir has just occurred - GFP_NOFS avoids this
*/
mapping_set_gfp_mask(mapping, GFP_NOFS); mapping_set_gfp_mask(mapping, GFP_NOFS);
page = read_mapping_page(mapping, n >> PAGE_CACHE_SHIFT, NULL); page = read_mapping_page(mapping, n >> PAGE_CACHE_SHIFT, NULL);
if (!IS_ERR(page)) { if (!IS_ERR(page)) {
@ -615,8 +627,10 @@ reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer,
if (name == NULL) if (name == NULL)
return -EINVAL; return -EINVAL;
/* We can't have xattrs attached to v1 items since they don't have /*
* generation numbers */ * We can't have xattrs attached to v1 items since they don't have
* generation numbers
*/
if (get_inode_sd_version(inode) == STAT_DATA_V1) if (get_inode_sd_version(inode) == STAT_DATA_V1)
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -913,12 +927,16 @@ static const struct xattr_handler *reiserfs_xattr_handlers[] = {
static int xattr_mount_check(struct super_block *s) static int xattr_mount_check(struct super_block *s)
{ {
/* We need generation numbers to ensure that the oid mapping is correct /*
* v3.5 filesystems don't have them. */ * We need generation numbers to ensure that the oid mapping is correct
* v3.5 filesystems don't have them.
*/
if (old_format_only(s)) { if (old_format_only(s)) {
if (reiserfs_xattrs_optional(s)) { if (reiserfs_xattrs_optional(s)) {
/* Old format filesystem, but optional xattrs have /*
* been enabled. Error out. */ * Old format filesystem, but optional xattrs have
* been enabled. Error out.
*/
reiserfs_warning(s, "jdm-2005", reiserfs_warning(s, "jdm-2005",
"xattrs/ACLs not supported " "xattrs/ACLs not supported "
"on pre-v3.6 format filesystems. " "on pre-v3.6 format filesystems. "
@ -972,9 +990,11 @@ int reiserfs_lookup_privroot(struct super_block *s)
return err; return err;
} }
/* We need to take a copy of the mount flags since things like /*
* We need to take a copy of the mount flags since things like
* MS_RDONLY don't get set until *after* we're called. * MS_RDONLY don't get set until *after* we're called.
* mount_flags != mount_options */ * mount_flags != mount_options
*/
int reiserfs_xattr_init(struct super_block *s, int mount_flags) int reiserfs_xattr_init(struct super_block *s, int mount_flags)
{ {
int err = 0; int err = 0;

View File

@ -61,7 +61,8 @@ static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size)
return ret; return ret;
} }
/* We may have to create up to 3 objects: xattr root, xattr dir, xattr file. /*
* We may have to create up to 3 objects: xattr root, xattr dir, xattr file.
* Let's try to be smart about it. * Let's try to be smart about it.
* xattr root: We cache it. If it's not cached, we may need to create it. * xattr root: We cache it. If it's not cached, we may need to create it.
* xattr dir: If anything has been loaded for this inode, we can set a flag * xattr dir: If anything has been loaded for this inode, we can set a flag

View File

@ -25,8 +25,10 @@ reiserfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
int size = acl ? posix_acl_xattr_size(acl->a_count) : 0; int size = acl ? posix_acl_xattr_size(acl->a_count) : 0;
/* Pessimism: We can't assume that anything from the xattr root up /*
* has been created. */ * Pessimism: We can't assume that anything from the xattr root up
* has been created.
*/
jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) + jcreate_blocks = reiserfs_xattr_jcreate_nblocks(inode) +
reiserfs_xattr_nblocks(inode, size) * 2; reiserfs_xattr_nblocks(inode, size) * 2;
@ -208,8 +210,10 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
retval = reiserfs_xattr_get(inode, name, value, size); retval = reiserfs_xattr_get(inode, name, value, size);
if (retval == -ENODATA || retval == -ENOSYS) { if (retval == -ENODATA || retval == -ENOSYS) {
/* This shouldn't actually happen as it should have /*
been caught above.. but just in case */ * This shouldn't actually happen as it should have
* been caught above.. but just in case
*/
acl = NULL; acl = NULL;
} else if (retval < 0) { } else if (retval < 0) {
acl = ERR_PTR(retval); acl = ERR_PTR(retval);
@ -290,8 +294,10 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
return error; return error;
} }
/* dir->i_mutex: locked, /*
* inode is new and not released into the wild yet */ * dir->i_mutex: locked,
* inode is new and not released into the wild yet
*/
int int
reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
struct inode *dir, struct dentry *dentry, struct inode *dir, struct dentry *dentry,
@ -304,14 +310,18 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
if (S_ISLNK(inode->i_mode)) if (S_ISLNK(inode->i_mode))
return 0; return 0;
/* ACLs can only be used on "new" objects, so if it's an old object /*
* there is nothing to inherit from */ * ACLs can only be used on "new" objects, so if it's an old object
* there is nothing to inherit from
*/
if (get_inode_sd_version(dir) == STAT_DATA_V1) if (get_inode_sd_version(dir) == STAT_DATA_V1)
goto apply_umask; goto apply_umask;
/* Don't apply ACLs to objects in the .reiserfs_priv tree.. This /*
* Don't apply ACLs to objects in the .reiserfs_priv tree.. This
* would be useless since permissions are ignored, and a pain because * would be useless since permissions are ignored, and a pain because
* it introduces locking cycles */ * it introduces locking cycles
*/
if (IS_PRIVATE(dir)) { if (IS_PRIVATE(dir)) {
inode->i_flags |= S_PRIVATE; inode->i_flags |= S_PRIVATE;
goto apply_umask; goto apply_umask;