Commit 2840c566 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs

Pull reiserfs and ext3 changes from Jan Kara:
 "Big reiserfs cleanup from Jeff, an ext3 deadlock fix, and some small
  cleanups"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (34 commits)
  reiserfs: Fix compilation breakage with CONFIG_REISERFS_CHECK
  ext3: Fix deadlock in data=journal mode when fs is frozen
  reiserfs: call truncate_setsize under tailpack mutex
  fs/jbd/revoke.c: replace shift loop by ilog2
  reiserfs: remove obsolete __constant_cpu_to_le32
  reiserfs: balance_leaf refactor, split up balance_leaf_when_delete
  reiserfs: balance_leaf refactor, format balance_leaf_finish_node
  reiserfs: balance_leaf refactor, format balance_leaf_new_nodes_paste
  reiserfs: balance_leaf refactor, format balance_leaf_paste_right
  reiserfs: balance_leaf refactor, format balance_leaf_insert_right
  reiserfs: balance_leaf refactor, format balance_leaf_paste_left
  reiserfs: balance_leaf refactor, format balance_leaf_insert_left
  reiserfs: balance_leaf refactor, pull out balance_leaf{left, right, new_nodes, finish_node}
  reiserfs: balance_leaf refactor, pull out balance_leaf_finish_node_paste
  reiserfs: balance_leaf refactor pull out balance_leaf_finish_node_insert
  reiserfs: balance_leaf refactor, pull out balance_leaf_new_nodes_paste
  reiserfs: balance_leaf refactor, pull out balance_leaf_new_nodes_insert
  reiserfs: balance_leaf refactor, pull out balance_leaf_paste_right
  reiserfs: balance_leaf refactor, pull out balance_leaf_insert_right
  reiserfs: balance_leaf refactor, pull out balance_leaf_paste_left
  ...
parents 859862dd 19ef1229
...@@ -1716,17 +1716,17 @@ static int ext3_journalled_writepage(struct page *page, ...@@ -1716,17 +1716,17 @@ static int ext3_journalled_writepage(struct page *page,
WARN_ON_ONCE(IS_RDONLY(inode) && WARN_ON_ONCE(IS_RDONLY(inode) &&
!(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
if (ext3_journal_current_handle())
goto no_write;
trace_ext3_journalled_writepage(page); trace_ext3_journalled_writepage(page);
handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
goto no_write;
}
if (!page_has_buffers(page) || PageChecked(page)) { if (!page_has_buffers(page) || PageChecked(page)) {
if (ext3_journal_current_handle())
goto no_write;
handle = ext3_journal_start(inode,
ext3_writepage_trans_blocks(inode));
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
goto no_write;
}
/* /*
* It's mmapped pagecache. Add buffers and journal it. There * It's mmapped pagecache. Add buffers and journal it. There
* doesn't seem much point in redirtying the page here. * doesn't seem much point in redirtying the page here.
...@@ -1749,17 +1749,18 @@ static int ext3_journalled_writepage(struct page *page, ...@@ -1749,17 +1749,18 @@ static int ext3_journalled_writepage(struct page *page,
atomic_set(&EXT3_I(inode)->i_datasync_tid, atomic_set(&EXT3_I(inode)->i_datasync_tid,
handle->h_transaction->t_tid); handle->h_transaction->t_tid);
unlock_page(page); unlock_page(page);
err = ext3_journal_stop(handle);
if (!ret)
ret = err;
} else { } else {
/* /*
* It may be a page full of checkpoint-mode buffers. We don't * It is a page full of checkpoint-mode buffers. Go and write
* really know unless we go poke around in the buffer_heads. * them. They should have been already mapped when they went
* But block_write_full_page will do the right thing. * to the journal so provide NULL get_block function to catch
* errors.
*/ */
ret = block_write_full_page(page, ext3_get_block, wbc); ret = block_write_full_page(page, NULL, wbc);
} }
err = ext3_journal_stop(handle);
if (!ret)
ret = err;
out: out:
return ret; return ret;
......
...@@ -231,19 +231,15 @@ int __init journal_init_revoke_caches(void) ...@@ -231,19 +231,15 @@ int __init journal_init_revoke_caches(void)
static struct jbd_revoke_table_s *journal_init_revoke_table(int hash_size) static struct jbd_revoke_table_s *journal_init_revoke_table(int hash_size)
{ {
int shift = 0; int i;
int tmp = hash_size;
struct jbd_revoke_table_s *table; struct jbd_revoke_table_s *table;
table = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); table = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
if (!table) if (!table)
goto out; goto out;
while((tmp >>= 1UL) != 0UL)
shift++;
table->hash_size = hash_size; table->hash_size = hash_size;
table->hash_shift = shift; table->hash_shift = ilog2(hash_size);
table->hash_table = table->hash_table =
kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL); kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
if (!table->hash_table) { if (!table->hash_table) {
...@@ -252,8 +248,8 @@ static struct jbd_revoke_table_s *journal_init_revoke_table(int hash_size) ...@@ -252,8 +248,8 @@ static struct jbd_revoke_table_s *journal_init_revoke_table(int hash_size)
goto out; goto out;
} }
for (tmp = 0; tmp < hash_size; tmp++) for (i = 0; i < hash_size; i++)
INIT_LIST_HEAD(&table->hash_table[tmp]); INIT_LIST_HEAD(&table->hash_table[i]);
out: out:
return table; return table;
......
This diff is collapsed.
...@@ -59,7 +59,10 @@ static inline bool is_privroot_deh(struct inode *dir, struct reiserfs_de_head *d ...@@ -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) ...@@ -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;
} }
...@@ -102,41 +112,49 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) ...@@ -102,41 +112,49 @@ int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx)
store_ih(&tmp_ih, ih); store_ih(&tmp_ih, ih);
/* we must have found item, that is item of this directory, */ /* we must have found item, that is item of this directory, */
RFALSE(COMP_SHORT_KEYS(&(ih->ih_key), &pos_key), RFALSE(COMP_SHORT_KEYS(&ih->ih_key, &pos_key),
"vs-9000: found item %h does not match to dir we readdir %K", "vs-9000: found item %h does not match to dir we readdir %K",
ih, &pos_key); ih, &pos_key);
RFALSE(item_num > B_NR_ITEMS(bh) - 1, RFALSE(item_num > B_NR_ITEMS(bh) - 1,
"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 */ /*
RFALSE(I_ENTRY_COUNT(ih) < entry_num, * and entry must be not more than number of entries
* in the item
*/
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, I_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 < I_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;
for (; entry_num < I_ENTRY_COUNT(ih); for (; entry_num < ih_entry_count(ih);
entry_num++, deh++) { entry_num++, deh++) {
int d_reclen; int d_reclen;
char *d_name; char *d_name;
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) ...@@ -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) ...@@ -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) ...@@ -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,71 +274,73 @@ static int reiserfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -248,71 +274,73 @@ 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)
{ {
struct reiserfs_de_head *deh; struct reiserfs_de_head *dot, *dotdot;
memset(body, 0, EMPTY_DIR_SIZE_V1); memset(body, 0, EMPTY_DIR_SIZE_V1);
deh = (struct reiserfs_de_head *)body; dot = (struct reiserfs_de_head *)body;
dotdot = dot + 1;
/* direntry header of "." */ /* direntry header of "." */
put_deh_offset(&(deh[0]), DOT_OFFSET); put_deh_offset(dot, DOT_OFFSET);
/* these two are from make_le_item_head, and are are LE */ /* these two are from make_le_item_head, and are are LE */
deh[0].deh_dir_id = dirid; dot->deh_dir_id = dirid;
deh[0].deh_objectid = objid; dot->deh_objectid = objid;
deh[0].deh_state = 0; /* Endian safe if 0 */ dot->deh_state = 0; /* Endian safe if 0 */
put_deh_location(&(deh[0]), EMPTY_DIR_SIZE_V1 - strlen(".")); put_deh_location(dot, EMPTY_DIR_SIZE_V1 - strlen("."));
mark_de_visible(&(deh[0])); mark_de_visible(dot);
/* direntry header of ".." */ /* direntry header of ".." */
put_deh_offset(&(deh[1]), DOT_DOT_OFFSET); put_deh_offset(dotdot, DOT_DOT_OFFSET);
/* key of ".." for the root directory */ /* key of ".." for the root directory */
/* these two are from the inode, and are are LE */ /* these two are from the inode, and are are LE */
deh[1].deh_dir_id = par_dirid; dotdot->deh_dir_id = par_dirid;
deh[1].deh_objectid = par_objid; dotdot->deh_objectid = par_objid;
deh[1].deh_state = 0; /* Endian safe if 0 */ dotdot->deh_state = 0; /* Endian safe if 0 */
put_deh_location(&(deh[1]), deh_location(&(deh[0])) - strlen("..")); put_deh_location(dotdot, deh_location(dot) - strlen(".."));
mark_de_visible(&(deh[1])); mark_de_visible(dotdot);
/* copy ".." and "." */ /* copy ".." and "." */
memcpy(body + deh_location(&(deh[0])), ".", 1); memcpy(body + deh_location(dot), ".", 1);
memcpy(body + deh_location(&(deh[1])), "..", 2); memcpy(body + deh_location(dotdot), "..", 2);
} }
/* compose directory item containing "." and ".." entries */ /* compose directory item containing "." and ".." entries */
void make_empty_dir_item(char *body, __le32 dirid, __le32 objid, void make_empty_dir_item(char *body, __le32 dirid, __le32 objid,
__le32 par_dirid, __le32 par_objid) __le32 par_dirid, __le32 par_objid)
{ {
struct reiserfs_de_head *deh; struct reiserfs_de_head *dot, *dotdot;
memset(body, 0, EMPTY_DIR_SIZE); memset(body, 0, EMPTY_DIR_SIZE);
deh = (struct reiserfs_de_head *)body; dot = (struct reiserfs_de_head *)body;
dotdot = dot + 1;
/* direntry header of "." */ /* direntry header of "." */
put_deh_offset(&(deh[0]), DOT_OFFSET); put_deh_offset(dot, DOT_OFFSET);
/* these two are from make_le_item_head, and are are LE */ /* these two are from make_le_item_head, and are are LE */
deh[0].deh_dir_id = dirid; dot->deh_dir_id = dirid;
deh[0].deh_objectid = objid; dot->deh_objectid = objid;
deh[0].deh_state = 0; /* Endian safe if 0 */ dot->deh_state = 0; /* Endian safe if 0 */
put_deh_location(&(deh[0]), EMPTY_DIR_SIZE - ROUND_UP(strlen("."))); put_deh_location(dot, EMPTY_DIR_SIZE - ROUND_UP(strlen(".")));
mark_de_visible(&(deh[0])); mark_de_visible(dot);
/* direntry header of ".." */ /* direntry header of ".." */
put_deh_offset(&(deh[1]), DOT_DOT_OFFSET); put_deh_offset(dotdot, DOT_DOT_OFFSET);
/* key of ".." for the root directory */ /* key of ".." for the root directory */
/* these two are from the inode, and are are LE */ /* these two are from the inode, and are are LE */
deh[1].deh_dir_id = par_dirid; dotdot->deh_dir_id = par_dirid;
deh[1].deh_objectid = par_objid; dotdot->deh_objectid = par_objid;
deh[1].deh_state = 0; /* Endian safe if 0 */ dotdot->deh_state = 0; /* Endian safe if 0 */
put_deh_location(&(deh[1]), put_deh_location(dotdot, deh_location(dot) - ROUND_UP(strlen("..")));
deh_location(&(deh[0])) - ROUND_UP(strlen(".."))); mark_de_visible(dotdot);
mark_de_visible(&(deh[1]));
/* copy ".." and "." */ /* copy ".." and "." */
memcpy(body + deh_location(&(deh[0])), ".", 1); memcpy(body + deh_location(dot), ".", 1);
memcpy(body + deh_location(&(deh[1])), "..", 2); memcpy(body + deh_location(dotdot), "..", 2);
} }
This diff is collapsed.
...@@ -15,20 +15,20 @@ ...@@ -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)
{ {
...@@ -41,10 +41,10 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) ...@@ -41,10 +41,10 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
if (atomic_add_unless(&REISERFS_I(inode)->openers, -1, 1)) if (atomic_add_unless(&REISERFS_I(inode)->openers, -1, 1))
return 0; return 0;
mutex_lock(&(REISERFS_I(inode)->tailpack)); mutex_lock(&REISERFS_I(inode)->tailpack);
if (!atomic_dec_and_test(&REISERFS_I(inode)->openers)) { if (!atomic_dec_and_test(&REISERFS_I(inode)->openers)) {
mutex_unlock(&(REISERFS_I(inode)->tailpack)); mutex_unlock(&REISERFS_I(inode)->tailpack);
return 0; return 0;
} }
...@@ -52,31 +52,35 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) ...@@ -52,31 +52,35 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
if ((!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) || if ((!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
!tail_has_to_be_packed(inode)) && !tail_has_to_be_packed(inode)) &&
REISERFS_I(inode)->i_prealloc_count <= 0) { REISERFS_I(inode)->i_prealloc_count <= 0) {
mutex_unlock(&(REISERFS_I(inode)->tailpack)); mutex_unlock(&REISERFS_I(inode)->tailpack);
return 0; return 0;
} }
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
*/ */
jbegin_failure = err; jbegin_failure = err;
err = journal_join_abort(&th, inode->i_sb, 1); err = journal_join_abort(&th, inode->i_sb);
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);
...@@ -92,7 +96,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) ...@@ -92,7 +96,7 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
#ifdef REISERFS_PREALLOCATE #ifdef REISERFS_PREALLOCATE
reiserfs_discard_prealloc(&th, inode); reiserfs_discard_prealloc(&th, inode);
#endif #endif
err = journal_end(&th, inode->i_sb, 1); err = journal_end(&th);
/* copy back the error code from journal_begin */ /* copy back the error code from journal_begin */
if (!err) if (!err)
...@@ -102,35 +106,38 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) ...@@ -102,35 +106,38 @@ 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:
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
mutex_unlock(&(REISERFS_I(inode)->tailpack)); mutex_unlock(&REISERFS_I(inode)->tailpack);
return err; return err;
} }
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);
} }
return err; return err;
} }
void reiserfs_vfs_truncate_file(struct inode *inode) void reiserfs_vfs_truncate_file(struct inode *inode)
{ {
mutex_lock(&(REISERFS_I(inode)->tailpack)); mutex_lock(&REISERFS_I(inode)->tailpack);
reiserfs_truncate_file(inode, 1); reiserfs_truncate_file(inode, 1);
mutex_unlock(&(REISERFS_I(inode)->tailpack)); mutex_unlock(&REISERFS_I(inode)->tailpack);
} }
/* Sync a reiserfs file. */ /* Sync a reiserfs file. */
...@@ -205,10 +212,11 @@ int reiserfs_commit_page(struct inode *inode, struct page *page, ...@@ -205,10 +212,11 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
set_buffer_uptodate(bh); set_buffer_uptodate(bh);
if (logit) { if (logit) {
reiserfs_prepare_for_journal(s, bh, 1); reiserfs_prepare_for_journal(s, bh, 1);
journal_mark_dirty(&th, s, bh); journal_mark_dirty(&th, 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) &&
...@@ -219,8 +227,8 @@ int reiserfs_commit_page(struct inode *inode, struct page *page, ...@@ -219,8 +227,8 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
} }
} }
if (logit) { if (logit) {
ret = journal_end(&th, s, bh_per_page + 1); ret = journal_end(&th);
drop_write_lock: drop_write_lock:
reiserfs_write_unlock(s); reiserfs_write_unlock(s);
} }
/* /*
......
This diff is collapsed.
...@@ -12,12 +12,6 @@ ...@@ -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) ...@@ -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) ...@@ -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;
......
This diff is collapsed.
This diff is collapsed.
...@@ -15,7 +15,8 @@ ...@@ -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 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ...@@ -132,7 +133,10 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
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, ...@@ -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) ...@@ -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;
...@@ -214,11 +219,11 @@ int reiserfs_unpack(struct inode *inode, struct file *filp) ...@@ -214,11 +219,11 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
retval = reiserfs_commit_write(NULL, page, write_from, write_from); retval = reiserfs_commit_write(NULL, page, write_from, write_from);
REISERFS_I(inode)->i_flags |= i_nopack_mask; REISERFS_I(inode)->i_flags |= i_nopack_mask;
out_unlock: out_unlock:
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
out: out:
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
reiserfs_write_unlock(inode->i_sb); reiserfs_write_unlock(inode->i_sb);
return retval; return retval;
......
...@@ -5,15 +5,17 @@ ...@@ -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) ...@@ -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, ...@@ -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 = { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 = { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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 = { ...@@ -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",
...@@ -396,7 +390,7 @@ static void direntry_print_item(struct item_head *ih, char *item) ...@@ -396,7 +390,7 @@ static void direntry_print_item(struct item_head *ih, char *item)
deh = (struct reiserfs_de_head *)item; deh = (struct reiserfs_de_head *)item;
for (i = 0; i < I_ENTRY_COUNT(ih); i++, deh++) { for (i = 0; i < ih_entry_count(ih); i++, deh++) {
namelen = namelen =
(i ? (deh_location(deh - 1)) : ih_item_len(ih)) - (i ? (deh_location(deh - 1)) : ih_item_len(ih)) -
deh_location(deh); deh_location(deh);
...@@ -428,9 +422,9 @@ static void direntry_check_item(struct item_head *ih, char *item) ...@@ -428,9 +422,9 @@ 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 < I_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) ...@@ -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, ...@@ -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)
...@@ -494,8 +491,8 @@ static int direntry_create_vi(struct virtual_node *vn, ...@@ -494,8 +491,8 @@ static int direntry_create_vi(struct virtual_node *vn,
j = old_entry_num(is_affected, i, vn->vn_pos_in_item, j = old_entry_num(is_affected, i, vn->vn_pos_in_item,
vn->vn_mode); vn->vn_mode);
dir_u->entry_sizes[i] = dir_u->entry_sizes[i] =
(j ? deh_location(&(deh[j - 1])) : ih_item_len(vi->vi_ih)) - (j ? deh_location(&deh[j - 1]) : ih_item_len(vi->vi_ih)) -
deh_location(&(deh[j])) + DEH_SIZE; deh_location(&deh[j]) + DEH_SIZE;
} }
size += (dir_u->entry_count * sizeof(short)); size += (dir_u->entry_count * sizeof(short));
...@@ -529,10 +526,10 @@ static int direntry_create_vi(struct virtual_node *vn, ...@@ -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, ...@@ -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) ...@@ -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 = { ...@@ -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, ...@@ -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 = { ...@@ -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
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -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) ...@@ -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) ...@@ -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,26 +66,30 @@ __u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th) ...@@ -64,26 +66,30 @@ __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));
set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2); set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);
} }
journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s)); journal_mark_dirty(th, SB_BUFFER_WITH_SB(s));
return unused_objectid; return unused_objectid;
} }
...@@ -97,30 +103,33 @@ void reiserfs_release_objectid(struct reiserfs_transaction_handle *th, ...@@ -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, 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, ...@@ -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) ...@@ -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);
......
This diff is collapsed.
This diff is collapsed.
...@@ -53,8 +53,10 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
...@@ -167,7 +182,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) ...@@ -167,7 +182,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
info = SB_AP_BITMAP(s) + bmap_nr - 1; info = SB_AP_BITMAP(s) + bmap_nr - 1;
bh = reiserfs_read_bitmap_block(s, bmap_nr - 1); bh = reiserfs_read_bitmap_block(s, bmap_nr - 1);
if (!bh) { if (!bh) {
int jerr = journal_end(&th, s, 10); int jerr = journal_end(&th);
if (jerr) if (jerr)
return jerr; return jerr;
return -EIO; return -EIO;
...@@ -178,14 +193,14 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) ...@@ -178,14 +193,14 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
reiserfs_clear_le_bit(i, bh->b_data); reiserfs_clear_le_bit(i, bh->b_data);
info->free_count += s->s_blocksize * 8 - block_r; info->free_count += s->s_blocksize * 8 - block_r;
journal_mark_dirty(&th, s, bh); journal_mark_dirty(&th, bh);
brelse(bh); brelse(bh);
/* Correct new last bitmap block - It may not be full */ /* Correct new last bitmap block - It may not be full */
info = SB_AP_BITMAP(s) + bmap_nr_new - 1; info = SB_AP_BITMAP(s) + bmap_nr_new - 1;
bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1); bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1);
if (!bh) { if (!bh) {
int jerr = journal_end(&th, s, 10); int jerr = journal_end(&th);
if (jerr) if (jerr)
return jerr; return jerr;
return -EIO; return -EIO;
...@@ -194,7 +209,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) ...@@ -194,7 +209,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
reiserfs_prepare_for_journal(s, bh, 1); reiserfs_prepare_for_journal(s, bh, 1);
for (i = block_r_new; i < s->s_blocksize * 8; i++) for (i = block_r_new; i < s->s_blocksize * 8; i++)
reiserfs_set_le_bit(i, bh->b_data); reiserfs_set_le_bit(i, bh->b_data);
journal_mark_dirty(&th, s, bh); journal_mark_dirty(&th, bh);
brelse(bh); brelse(bh);
info->free_count -= s->s_blocksize * 8 - block_r_new; info->free_count -= s->s_blocksize * 8 - block_r_new;
...@@ -207,8 +222,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) ...@@ -207,8 +222,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
PUT_SB_BLOCK_COUNT(s, block_count_new); PUT_SB_BLOCK_COUNT(s, block_count_new);
PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);
journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); journal_mark_dirty(&th, SB_BUFFER_WITH_SB(s));
SB_JOURNAL(s)->j_must_wait = 1; SB_JOURNAL(s)->j_must_wait = 1;
return journal_end(&th, s, 10); return journal_end(&th);
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -61,7 +61,8 @@ static inline loff_t reiserfs_xattr_nblocks(struct inode *inode, loff_t size) ...@@ -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
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment