aboutsummaryrefslogtreecommitdiff
path: root/fs/reiserfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/dir.c16
-rw-r--r--fs/reiserfs/file.c33
-rw-r--r--fs/reiserfs/fix_node.c50
-rw-r--r--fs/reiserfs/hashes.c1
-rw-r--r--fs/reiserfs/inode.c19
-rw-r--r--fs/reiserfs/journal.c143
-rw-r--r--fs/reiserfs/namei.c24
-rw-r--r--fs/reiserfs/procfs.c3
-rw-r--r--fs/reiserfs/super.c8
-rw-r--r--fs/reiserfs/xattr.c128
-rw-r--r--fs/reiserfs/xattr_acl.c3
11 files changed, 164 insertions, 264 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 9dd71e80703..d71ac657928 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -150,18 +150,15 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (d_reclen <= 32) {
local_buf = small_buf;
} else {
- local_buf =
- reiserfs_kmalloc(d_reclen, GFP_NOFS,
- inode->i_sb);
+ local_buf = kmalloc(d_reclen,
+ GFP_NOFS);
if (!local_buf) {
pathrelse(&path_to_entry);
ret = -ENOMEM;
goto out;
}
if (item_moved(&tmp_ih, &path_to_entry)) {
- reiserfs_kfree(local_buf,
- d_reclen,
- inode->i_sb);
+ kfree(local_buf);
goto research;
}
}
@@ -174,15 +171,12 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
(dirent, local_buf, d_reclen, d_off, d_ino,
DT_UNKNOWN) < 0) {
if (local_buf != small_buf) {
- reiserfs_kfree(local_buf,
- d_reclen,
- inode->i_sb);
+ kfree(local_buf);
}
goto end;
}
if (local_buf != small_buf) {
- reiserfs_kfree(local_buf, d_reclen,
- inode->i_sb);
+ kfree(local_buf);
}
// next entry should be looked for with such offset
next_pos = deh_offset(deh) + 1;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index ad6fa964b0e..be12879bb17 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -192,6 +192,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl
allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
sizeof(b_blocknr_t), GFP_NOFS);
+ if (!allocated_blocks)
+ return -ENOMEM;
/* First we compose a key to point at the writing position, we want to do
that outside of any locking region. */
@@ -1285,6 +1287,23 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
struct reiserfs_transaction_handle th;
th.t_trans_id = 0;
+ /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items
+ * lying around (most of the disk, in fact). Despite the filesystem
+ * now being a v3.6 format, the old items still can't support large
+ * file sizes. Catch this case here, as the rest of the VFS layer is
+ * oblivious to the different limitations between old and new items.
+ * reiserfs_setattr catches this for truncates. This chunk is lifted
+ * from generic_write_checks. */
+ if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 &&
+ *ppos + count > MAX_NON_LFS) {
+ if (*ppos >= MAX_NON_LFS) {
+ send_sig(SIGXFSZ, current, 0);
+ return -EFBIG;
+ }
+ if (count > MAX_NON_LFS - (unsigned long)*ppos)
+ count = MAX_NON_LFS - (unsigned long)*ppos;
+ }
+
if (file->f_flags & O_DIRECT) { // Direct IO needs treatment
ssize_t result, after_file_end = 0;
if ((*ppos + count >= inode->i_size)
@@ -1445,13 +1464,11 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
partially overwritten pages, if needed. And lock the pages,
so that nobody else can access these until we are done.
We get number of actual blocks needed as a result. */
- blocks_to_allocate =
- reiserfs_prepare_file_region_for_write(inode, pos,
- num_pages,
- write_bytes,
- prepared_pages);
- if (blocks_to_allocate < 0) {
- res = blocks_to_allocate;
+ res = reiserfs_prepare_file_region_for_write(inode, pos,
+ num_pages,
+ write_bytes,
+ prepared_pages);
+ if (res < 0) {
reiserfs_release_claimed_blocks(inode->i_sb,
num_pages <<
(PAGE_CACHE_SHIFT -
@@ -1459,6 +1476,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
break;
}
+ blocks_to_allocate = res;
+
/* First we correct our estimate of how many blocks we need */
reiserfs_release_claimed_blocks(inode->i_sb,
(num_pages <<
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 45829889dcd..aa22588019e 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2021,38 +2021,6 @@ static int get_neighbors(struct tree_balance *p_s_tb, int n_h)
return CARRY_ON;
}
-#ifdef CONFIG_REISERFS_CHECK
-void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s)
-{
- void *vp;
- static size_t malloced;
-
- vp = kmalloc(size, flags);
- if (vp) {
- REISERFS_SB(s)->s_kmallocs += size;
- if (REISERFS_SB(s)->s_kmallocs > malloced + 200000) {
- reiserfs_warning(s,
- "vs-8301: reiserfs_kmalloc: allocated memory %d",
- REISERFS_SB(s)->s_kmallocs);
- malloced = REISERFS_SB(s)->s_kmallocs;
- }
- }
- return vp;
-}
-
-void reiserfs_kfree(const void *vp, size_t size, struct super_block *s)
-{
- kfree(vp);
-
- REISERFS_SB(s)->s_kmallocs -= size;
- if (REISERFS_SB(s)->s_kmallocs < 0)
- reiserfs_warning(s,
- "vs-8302: reiserfs_kfree: allocated memory %d",
- REISERFS_SB(s)->s_kmallocs);
-
-}
-#endif
-
static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh)
{
int max_num_of_items;
@@ -2086,7 +2054,7 @@ static int get_mem_for_virtual_node(struct tree_balance *tb)
/* we have to allocate more memory for virtual node */
if (tb->vn_buf) {
/* free memory allocated before */
- reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+ kfree(tb->vn_buf);
/* this is not needed if kfree is atomic */
check_fs = 1;
}
@@ -2095,24 +2063,15 @@ static int get_mem_for_virtual_node(struct tree_balance *tb)
tb->vn_buf_size = size;
/* get memory for virtual item */
- buf =
- reiserfs_kmalloc(size, GFP_ATOMIC | __GFP_NOWARN,
- tb->tb_sb);
+ buf = kmalloc(size, GFP_ATOMIC | __GFP_NOWARN);
if (!buf) {
/* getting memory with GFP_KERNEL priority may involve
balancing now (due to indirect_to_direct conversion on
dcache shrinking). So, release path and collected
resources here */
free_buffers_in_tb(tb);
- buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb);
+ buf = kmalloc(size, GFP_NOFS);
if (!buf) {
-#ifdef CONFIG_REISERFS_CHECK
- reiserfs_warning(tb->tb_sb,
- "vs-8345: get_mem_for_virtual_node: "
- "kmalloc failed. reiserfs kmalloced %d bytes",
- REISERFS_SB(tb->tb_sb)->
- s_kmallocs);
-#endif
tb->vn_buf_size = 0;
}
tb->vn_buf = buf;
@@ -2619,7 +2578,6 @@ void unfix_nodes(struct tree_balance *tb)
}
}
- if (tb->vn_buf)
- reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb);
+ kfree(tb->vn_buf);
}
diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c
index a3ec238fd9e..e664ac16fad 100644
--- a/fs/reiserfs/hashes.c
+++ b/fs/reiserfs/hashes.c
@@ -21,7 +21,6 @@
#include <linux/kernel.h>
#include <linux/reiserfs_fs.h>
#include <asm/types.h>
-#include <asm/bug.h>
#define DELTA 0x9E3779B9
#define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ffa34b861bd..d60f6238c66 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -627,11 +627,6 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
reiserfs_write_lock(inode->i_sb);
version = get_inode_item_key_version(inode);
- if (block < 0) {
- reiserfs_write_unlock(inode->i_sb);
- return -EIO;
- }
-
if (!file_capable(inode, block)) {
reiserfs_write_unlock(inode->i_sb);
return -EFBIG;
@@ -934,12 +929,13 @@ int reiserfs_get_block(struct inode *inode, sector_t block,
//pos_in_item * inode->i_sb->s_blocksize,
TYPE_INDIRECT, 3); // key type is unimportant
+ RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key),
+ "green-805: invalid offset");
blocks_needed =
1 +
((cpu_key_k_offset(&key) -
cpu_key_k_offset(&tmp_key)) >> inode->i_sb->
s_blocksize_bits);
- RFALSE(blocks_needed < 0, "green-805: invalid offset");
if (blocks_needed == 1) {
un = &unf_single;
@@ -2363,6 +2359,13 @@ static int reiserfs_write_full_page(struct page *page,
int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
th.t_trans_id = 0;
+ /* no logging allowed when nonblocking or from PF_MEMALLOC */
+ if (checked && (current->flags & PF_MEMALLOC)) {
+ redirty_page_for_writepage(wbc, page);
+ unlock_page(page);
+ return 0;
+ }
+
/* The page dirty bit is cleared before writepage is called, which
* means we have to tell create_empty_buffers to make dirty buffers
* The page really should be up to date at this point, so tossing
@@ -2743,6 +2746,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
int ret = 1;
struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
+ lock_buffer(bh);
spin_lock(&j->j_dirty_buffers_lock);
if (!buffer_mapped(bh)) {
goto free_jh;
@@ -2758,7 +2762,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
ret = 0;
}
- } else if (buffer_dirty(bh) || buffer_locked(bh)) {
+ } else if (buffer_dirty(bh)) {
struct reiserfs_journal_list *jl;
struct reiserfs_jh *jh = bh->b_private;
@@ -2784,6 +2788,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
reiserfs_free_jh(bh);
}
spin_unlock(&j->j_dirty_buffers_lock);
+ unlock_buffer(bh);
return ret;
}
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4491fcf2a0e..5a9d2722fa0 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -152,18 +152,16 @@ static struct reiserfs_bitmap_node *allocate_bitmap_node(struct super_block
struct reiserfs_bitmap_node *bn;
static int id;
- bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS,
- p_s_sb);
+ bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS);
if (!bn) {
return NULL;
}
- bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb);
+ bn->data = kzalloc(p_s_sb->s_blocksize, GFP_NOFS);
if (!bn->data) {
- reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+ kfree(bn);
return NULL;
}
bn->id = id++;
- memset(bn->data, 0, p_s_sb->s_blocksize);
INIT_LIST_HEAD(&bn->list);
return bn;
}
@@ -197,8 +195,8 @@ static inline void free_bitmap_node(struct super_block *p_s_sb,
struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
journal->j_used_bitmap_nodes--;
if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) {
- reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
- reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+ kfree(bn->data);
+ kfree(bn);
} else {
list_add(&bn->list, &journal->j_bitmap_nodes);
journal->j_free_bitmap_nodes++;
@@ -276,8 +274,8 @@ static int free_bitmap_nodes(struct super_block *p_s_sb)
while (next != &journal->j_bitmap_nodes) {
bn = list_entry(next, struct reiserfs_bitmap_node, list);
list_del(next);
- reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb);
- reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb);
+ kfree(bn->data);
+ kfree(bn);
next = journal->j_bitmap_nodes.next;
journal->j_free_bitmap_nodes--;
}
@@ -581,7 +579,7 @@ static inline void put_journal_list(struct super_block *s,
jl->j_trans_id, jl->j_refcount);
}
if (--jl->j_refcount == 0)
- reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s);
+ kfree(jl);
}
/*
@@ -848,6 +846,14 @@ static int write_ordered_buffers(spinlock_t * lock,
spin_lock(lock);
goto loop_next;
}
+ /* in theory, dirty non-uptodate buffers should never get here,
+ * but the upper layer io error paths still have a few quirks.
+ * Handle them here as gracefully as we can
+ */
+ if (!buffer_uptodate(bh) && buffer_dirty(bh)) {
+ clear_buffer_dirty(bh);
+ ret = -EIO;
+ }
if (buffer_dirty(bh)) {
list_del_init(&jh->list);
list_add(&jh->list, &tmp);
@@ -879,6 +885,19 @@ static int write_ordered_buffers(spinlock_t * lock,
if (!buffer_uptodate(bh)) {
ret = -EIO;
}
+ /* ugly interaction with invalidatepage here.
+ * reiserfs_invalidate_page will pin any buffer that has a valid
+ * journal head from an older transaction. If someone else sets
+ * our buffer dirty after we write it in the first loop, and
+ * then someone truncates the page away, nobody will ever write
+ * the buffer. We're safe if we write the page one last time
+ * after freeing the journal header.
+ */
+ if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) {
+ spin_unlock(lock);
+ ll_rw_block(WRITE, 1, &bh);
+ spin_lock(lock);
+ }
put_bh(bh);
cond_resched_lock(lock);
}
@@ -977,6 +996,7 @@ static int flush_commit_list(struct super_block *s,
struct reiserfs_journal *journal = SB_JOURNAL(s);
int barrier = 0;
int retval = 0;
+ int write_len;
reiserfs_check_lock_depth(s, "flush_commit_list");
@@ -1018,24 +1038,35 @@ static int flush_commit_list(struct super_block *s,
}
if (!list_empty(&jl->j_bh_list)) {
+ int ret;
unlock_kernel();
- write_ordered_buffers(&journal->j_dirty_buffers_lock,
- journal, jl, &jl->j_bh_list);
+ ret = write_ordered_buffers(&journal->j_dirty_buffers_lock,
+ journal, jl, &jl->j_bh_list);
+ if (ret < 0 && retval == 0)
+ retval = ret;
lock_kernel();
}
BUG_ON(!list_empty(&jl->j_bh_list));
/*
* for the description block and all the log blocks, submit any buffers
- * that haven't already reached the disk
+ * that haven't already reached the disk. Try to write at least 256
+ * log blocks. later on, we will only wait on blocks that correspond
+ * to this transaction, but while we're unplugging we might as well
+ * get a chunk of data on there.
*/
atomic_inc(&journal->j_async_throttle);
- for (i = 0; i < (jl->j_len + 1); i++) {
+ write_len = jl->j_len + 1;
+ if (write_len < 256)
+ write_len = 256;
+ for (i = 0 ; i < write_len ; i++) {
bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) %
SB_ONDISK_JOURNAL_SIZE(s);
tbh = journal_find_get_block(s, bn);
- if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */
- ll_rw_block(SWRITE, 1, &tbh);
- put_bh(tbh);
+ if (tbh) {
+ if (buffer_dirty(tbh))
+ ll_rw_block(WRITE, 1, &tbh) ;
+ put_bh(tbh) ;
+ }
}
atomic_dec(&journal->j_async_throttle);
@@ -1818,8 +1849,7 @@ void remove_journal_hash(struct super_block *sb,
static void free_journal_ram(struct super_block *p_s_sb)
{
struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
- reiserfs_kfree(journal->j_current_jl,
- sizeof(struct reiserfs_journal_list), p_s_sb);
+ kfree(journal->j_current_jl);
journal->j_num_lists--;
vfree(journal->j_cnode_free_orig);
@@ -2093,21 +2123,15 @@ static int journal_read_transaction(struct super_block *p_s_sb,
}
trans_id = get_desc_trans_id(desc);
/* now we know we've got a good transaction, and it was inside the valid time ranges */
- log_blocks =
- reiserfs_kmalloc(get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
- real_blocks =
- reiserfs_kmalloc(get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), GFP_NOFS, p_s_sb);
+ log_blocks = kmalloc(get_desc_trans_len(desc) *
+ sizeof(struct buffer_head *), GFP_NOFS);
+ real_blocks = kmalloc(get_desc_trans_len(desc) *
+ sizeof(struct buffer_head *), GFP_NOFS);
if (!log_blocks || !real_blocks) {
brelse(c_bh);
brelse(d_bh);
- reiserfs_kfree(log_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
- reiserfs_kfree(real_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
+ kfree(log_blocks);
+ kfree(real_blocks);
reiserfs_warning(p_s_sb,
"journal-1169: kmalloc failed, unable to mount FS");
return -1;
@@ -2145,12 +2169,8 @@ static int journal_read_transaction(struct super_block *p_s_sb,
brelse_array(real_blocks, i);
brelse(c_bh);
brelse(d_bh);
- reiserfs_kfree(log_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
- reiserfs_kfree(real_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
+ kfree(log_blocks);
+ kfree(real_blocks);
return -1;
}
}
@@ -2166,12 +2186,8 @@ static int journal_read_transaction(struct super_block *p_s_sb,
brelse_array(real_blocks, get_desc_trans_len(desc));
brelse(c_bh);
brelse(d_bh);
- reiserfs_kfree(log_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
- reiserfs_kfree(real_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
+ kfree(log_blocks);
+ kfree(real_blocks);
return -1;
}
memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data,
@@ -2193,12 +2209,8 @@ static int journal_read_transaction(struct super_block *p_s_sb,
get_desc_trans_len(desc) - i);
brelse(c_bh);
brelse(d_bh);
- reiserfs_kfree(log_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
- reiserfs_kfree(real_blocks,
- get_desc_trans_len(desc) *
- sizeof(struct buffer_head *), p_s_sb);
+ kfree(log_blocks);
+ kfree(real_blocks);
return -1;
}
brelse(real_blocks[i]);
@@ -2217,12 +2229,8 @@ static int journal_read_transaction(struct super_block *p_s_sb,
journal->j_trans_id = trans_id + 1;
brelse(c_bh);
brelse(d_bh);
- reiserfs_kfree(log_blocks,
- le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
- p_s_sb);
- reiserfs_kfree(real_blocks,
- le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *),
- p_s_sb);
+ kfree(log_blocks);
+ kfree(real_blocks);
return 0;
}
@@ -2311,8 +2319,7 @@ static int journal_read(struct super_block *p_s_sb)
return 1;
}
jh = (struct reiserfs_journal_header *)(journal->j_header_bh->b_data);
- if (le32_to_cpu(jh->j_first_unflushed_offset) >= 0 &&
- le32_to_cpu(jh->j_first_unflushed_offset) <
+ if (le32_to_cpu(jh->j_first_unflushed_offset) <
SB_ONDISK_JOURNAL_SIZE(p_s_sb)
&& le32_to_cpu(jh->j_last_flush_trans_id) > 0) {
oldest_start =
@@ -2471,14 +2478,8 @@ static int journal_read(struct super_block *p_s_sb)
static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s)
{
struct reiserfs_journal_list *jl;
- retry:
- jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS,
- s);
- if (!jl) {
- yield();
- goto retry;
- }
- memset(jl, 0, sizeof(*jl));
+ jl = kzalloc(sizeof(struct reiserfs_journal_list),
+ GFP_NOFS | __GFP_NOFAIL);
INIT_LIST_HEAD(&jl->j_list);
INIT_LIST_HEAD(&jl->j_working_list);
INIT_LIST_HEAD(&jl->j_tail_bh_list);
@@ -2821,6 +2822,9 @@ int journal_transaction_should_end(struct reiserfs_transaction_handle *th,
journal->j_cnode_free < (journal->j_trans_max * 3)) {
return 1;
}
+ /* protected by the BKL here */
+ journal->j_len_alloc += new_alloc;
+ th->t_blocks_allocated += new_alloc ;
return 0;
}
@@ -3042,14 +3046,12 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct
}
return th;
}
- th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle),
- GFP_NOFS, s);
+ th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS);
if (!th)
return NULL;
ret = journal_begin(th, s, nblocks);
if (ret) {
- reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
- s);
+ kfree(th);
return NULL;
}
@@ -3067,8 +3069,7 @@ int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th)
ret = -EIO;
if (th->t_refcount == 0) {
SB_JOURNAL(s)->j_persistent_trans--;
- reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle),
- s);
+ kfree(th);
}
return ret;
}
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 8f8d8d01107..284f7852de8 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -247,7 +247,7 @@ static int linear_search_in_dir_item(struct cpu_key *key,
/* mark, that this generation number is used */
if (de->de_gen_number_bit_string)
set_bit(GET_GENERATION_NUMBER(deh_offset(deh)),
- (unsigned long *)de->de_gen_number_bit_string);
+ de->de_gen_number_bit_string);
// calculate pointer to name and namelen
de->de_entry_num = i;
@@ -431,7 +431,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
struct reiserfs_de_head *deh;
INITIALIZE_PATH(path);
struct reiserfs_dir_entry de;
- int bit_string[MAX_GENERATION_NUMBER / (sizeof(int) * 8) + 1];
+ DECLARE_BITMAP(bit_string, MAX_GENERATION_NUMBER + 1);
int gen_number;
char small_buf[32 + DEH_SIZE]; /* 48 bytes now and we avoid kmalloc
if we create file with short name */
@@ -456,7 +456,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
/* get memory for composing the entry */
buflen = DEH_SIZE + ROUND_UP(namelen);
if (buflen > sizeof(small_buf)) {
- buffer = reiserfs_kmalloc(buflen, GFP_NOFS, dir->i_sb);
+ buffer = kmalloc(buflen, GFP_NOFS);
if (buffer == 0)
return -ENOMEM;
} else
@@ -486,11 +486,11 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
/* find the proper place for the new entry */
memset(bit_string, 0, sizeof(bit_string));
- de.de_gen_number_bit_string = (char *)bit_string;
+ de.de_gen_number_bit_string = bit_string;
retval = reiserfs_find_entry(dir, name, namelen, &path, &de);
if (retval != NAME_NOT_FOUND) {
if (buffer != small_buf)
- reiserfs_kfree(buffer, buflen, dir->i_sb);
+ kfree(buffer);
pathrelse(&path);
if (retval == IO_ERROR) {
@@ -508,14 +508,14 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
}
gen_number =
- find_first_zero_bit((unsigned long *)bit_string,
+ find_first_zero_bit(bit_string,
MAX_GENERATION_NUMBER + 1);
if (gen_number > MAX_GENERATION_NUMBER) {
/* there is no free generation number */
reiserfs_warning(dir->i_sb,
"reiserfs_add_entry: Congratulations! we have got hash function screwed up");
if (buffer != small_buf)
- reiserfs_kfree(buffer, buflen, dir->i_sb);
+ kfree(buffer);
pathrelse(&path);
return -EBUSY;
}
@@ -535,7 +535,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
&entry_key);
if (buffer != small_buf)
- reiserfs_kfree(buffer, buflen, dir->i_sb);
+ kfree(buffer);
pathrelse(&path);
return -EBUSY;
}
@@ -546,7 +546,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer,
paste_size);
if (buffer != small_buf)
- reiserfs_kfree(buffer, buflen, dir->i_sb);
+ kfree(buffer);
if (retval) {
reiserfs_check_path(&path);
return retval;
@@ -1065,7 +1065,7 @@ static int reiserfs_symlink(struct inode *parent_dir,
goto out_failed;
}
- name = reiserfs_kmalloc(item_len, GFP_NOFS, parent_dir->i_sb);
+ name = kmalloc(item_len, GFP_NOFS);
if (!name) {
drop_new_inode(inode);
retval = -ENOMEM;
@@ -1079,14 +1079,14 @@ static int reiserfs_symlink(struct inode *parent_dir,
retval = journal_begin(&th, parent_dir->i_sb, jbegin_count);
if (retval) {
drop_new_inode(inode);
- reiserfs_kfree(name, item_len, parent_dir->i_sb);
+ kfree(name);
goto out_failed;
}
retval =
reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname),
dentry, inode);
- reiserfs_kfree(name, item_len, parent_dir->i_sb);
+ kfree(name);
if (retval) { /* reiserfs_new_inode iputs for us */
goto out_failed;
}
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index fc2f43c75df..ef6caed9336 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -88,7 +88,6 @@ static int show_super(struct seq_file *m, struct super_block *sb)
seq_printf(m, "state: \t%s\n"
"mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n"
"gen. counter: \t%i\n"
- "s_kmallocs: \t%i\n"
"s_disk_reads: \t%i\n"
"s_disk_writes: \t%i\n"
"s_fix_nodes: \t%i\n"
@@ -128,7 +127,7 @@ static int show_super(struct seq_file *m, struct super_block *sb)
"SMALL_TAILS " : "NO_TAILS ",
replay_only(sb) ? "REPLAY_ONLY " : "",
convert_reiserfs(sb) ? "CONV " : "",
- atomic_read(&r->s_generation_counter), SF(s_kmallocs),
+ atomic_read(&r->s_generation_counter),
SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes),
SF(s_do_balance), SF(s_unneeded_left_neighbor),
SF(s_good_search_by_key_reada), SF(s_bmaps),
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 397d9590c8f..d63da756eb4 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -472,12 +472,6 @@ static void reiserfs_put_super(struct super_block *s)
print_statistics(s);
- if (REISERFS_SB(s)->s_kmallocs != 0) {
- reiserfs_warning(s,
- "vs-2004: reiserfs_put_super: allocated memory left %d",
- REISERFS_SB(s)->s_kmallocs);
- }
-
if (REISERFS_SB(s)->reserved_blocks != 0) {
reiserfs_warning(s,
"green-2005: reiserfs_put_super: reserved blocks left %d",
@@ -1130,8 +1124,6 @@ static void handle_attrs(struct super_block *s)
"reiserfs: cannot support attributes until flag is set in super-block");
REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS);
}
- } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) {
- REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS;
}
}
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index cc061bfd437..ffb79c48c5b 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -368,15 +368,13 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (d_reclen <= 32) {
local_buf = small_buf;
} else {
- local_buf =
- reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb);
+ local_buf = kmalloc(d_reclen, GFP_NOFS);
if (!local_buf) {
pathrelse(&path_to_entry);
return -ENOMEM;
}
if (item_moved(&tmp_ih, &path_to_entry)) {
- reiserfs_kfree(local_buf, d_reclen,
- inode->i_sb);
+ kfree(local_buf);
/* sigh, must retry. Do this same offset again */
next_pos = d_off;
@@ -399,13 +397,12 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filldir(dirent, local_buf, d_reclen, d_off, d_ino,
DT_UNKNOWN) < 0) {
if (local_buf != small_buf) {
- reiserfs_kfree(local_buf, d_reclen,
- inode->i_sb);
+ kfree(local_buf);
}
goto end;
}
if (local_buf != small_buf) {
- reiserfs_kfree(local_buf, d_reclen, inode->i_sb);
+ kfree(local_buf);
}
} /* while */
@@ -1322,109 +1319,44 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
return err;
}
-static int
-__reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd,
- int need_lock)
+static int reiserfs_check_acl(struct inode *inode, int mask)
{
- umode_t mode = inode->i_mode;
-
- if (mask & MAY_WRITE) {
- /*
- * Nobody gets write access to a read-only fs.
- */
- if (IS_RDONLY(inode) &&
- (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
- return -EROFS;
+ struct posix_acl *acl;
+ int error = -EAGAIN; /* do regular unix permission checks by default */
- /*
- * Nobody gets write access to an immutable file.
- */
- if (IS_IMMUTABLE(inode))
- return -EACCES;
- }
+ reiserfs_read_lock_xattr_i(inode);
+ reiserfs_read_lock_xattrs(inode->i_sb);
- /* We don't do permission checks on the internal objects.
- * Permissions are determined by the "owning" object. */
- if (is_reiserfs_priv_object(inode))
- return 0;
+ acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
- if (current->fsuid == inode->i_uid) {
- mode >>= 6;
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
- } else if (reiserfs_posixacl(inode->i_sb) &&
- get_inode_sd_version(inode) != STAT_DATA_V1) {
- struct posix_acl *acl;
-
- /* ACL can't contain additional permissions if
- the ACL_MASK entry is 0 */
- if (!(mode & S_IRWXG))
- goto check_groups;
-
- if (need_lock) {
- reiserfs_read_lock_xattr_i(inode);
- reiserfs_read_lock_xattrs(inode->i_sb);
- }
- acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
- if (need_lock) {
- reiserfs_read_unlock_xattrs(inode->i_sb);
- reiserfs_read_unlock_xattr_i(inode);
- }
- if (IS_ERR(acl)) {
- if (PTR_ERR(acl) == -ENODATA)
- goto check_groups;
- return PTR_ERR(acl);
- }
+ reiserfs_read_unlock_xattrs(inode->i_sb);
+ reiserfs_read_unlock_xattr_i(inode);
- if (acl) {
- int err = posix_acl_permission(inode, acl, mask);
+ if (acl) {
+ if (!IS_ERR(acl)) {
+ error = posix_acl_permission(inode, acl, mask);
posix_acl_release(acl);
- if (err == -EACCES) {
- goto check_capabilities;
- }
- return err;
- } else {
- goto check_groups;
- }
-#endif
- } else {
- check_groups:
- if (in_group_p(inode->i_gid))
- mode >>= 3;
+ } else if (PTR_ERR(acl) != -ENODATA)
+ error = PTR_ERR(acl);
}
- /*
- * If the DACs are ok we don't need any capability check.
- */
- if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask))
- return 0;
+ return error;
+}
- check_capabilities:
+int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
/*
- * Read/write DACs are always overridable.
- * Executable DACs are overridable if at least one exec bit is set.
+ * We don't do permission checks on the internal objects.
+ * Permissions are determined by the "owning" object.
*/
- if (!(mask & MAY_EXEC) ||
- (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode))
- if (capable(CAP_DAC_OVERRIDE))
- return 0;
+ if (is_reiserfs_priv_object(inode))
+ return 0;
/*
- * Searching includes executable on directories, else just read.
+ * Stat data v1 doesn't support ACLs.
*/
- if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE)))
- if (capable(CAP_DAC_READ_SEARCH))
- return 0;
-
- return -EACCES;
-}
-
-int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
- return __reiserfs_permission(inode, mask, nd, 1);
-}
-
-int
-reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd)
-{
- return __reiserfs_permission(inode, mask, nd, 0);
+ if (get_inode_sd_version(inode) == STAT_DATA_V1)
+ return generic_permission(inode, mask, NULL);
+ else
+ return generic_permission(inode, mask, reiserfs_check_acl);
}
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 43de3ba8333..ab8894c3b9e 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -228,7 +228,8 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
acl = ERR_PTR(retval);
} else {
acl = posix_acl_from_disk(value, retval);
- *p_acl = posix_acl_dup(acl);
+ if (!IS_ERR(acl))
+ *p_acl = posix_acl_dup(acl);
}
kfree(value);