diff options
Diffstat (limited to 'fs/reiserfs')
-rw-r--r-- | fs/reiserfs/dir.c | 16 | ||||
-rw-r--r-- | fs/reiserfs/file.c | 19 | ||||
-rw-r--r-- | fs/reiserfs/fix_node.c | 50 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 11 | ||||
-rw-r--r-- | fs/reiserfs/journal.c | 140 | ||||
-rw-r--r-- | fs/reiserfs/namei.c | 16 | ||||
-rw-r--r-- | fs/reiserfs/procfs.c | 3 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 6 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 128 |
9 files changed, 148 insertions, 241 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9dd71e807034..d71ac6579289 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) | |||
150 | if (d_reclen <= 32) { | 150 | if (d_reclen <= 32) { |
151 | local_buf = small_buf; | 151 | local_buf = small_buf; |
152 | } else { | 152 | } else { |
153 | local_buf = | 153 | local_buf = kmalloc(d_reclen, |
154 | reiserfs_kmalloc(d_reclen, GFP_NOFS, | 154 | GFP_NOFS); |
155 | inode->i_sb); | ||
156 | if (!local_buf) { | 155 | if (!local_buf) { |
157 | pathrelse(&path_to_entry); | 156 | pathrelse(&path_to_entry); |
158 | ret = -ENOMEM; | 157 | ret = -ENOMEM; |
159 | goto out; | 158 | goto out; |
160 | } | 159 | } |
161 | if (item_moved(&tmp_ih, &path_to_entry)) { | 160 | if (item_moved(&tmp_ih, &path_to_entry)) { |
162 | reiserfs_kfree(local_buf, | 161 | kfree(local_buf); |
163 | d_reclen, | ||
164 | inode->i_sb); | ||
165 | goto research; | 162 | goto research; |
166 | } | 163 | } |
167 | } | 164 | } |
@@ -174,15 +171,12 @@ static int reiserfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
174 | (dirent, local_buf, d_reclen, d_off, d_ino, | 171 | (dirent, local_buf, d_reclen, d_off, d_ino, |
175 | DT_UNKNOWN) < 0) { | 172 | DT_UNKNOWN) < 0) { |
176 | if (local_buf != small_buf) { | 173 | if (local_buf != small_buf) { |
177 | reiserfs_kfree(local_buf, | 174 | kfree(local_buf); |
178 | d_reclen, | ||
179 | inode->i_sb); | ||
180 | } | 175 | } |
181 | goto end; | 176 | goto end; |
182 | } | 177 | } |
183 | if (local_buf != small_buf) { | 178 | if (local_buf != small_buf) { |
184 | reiserfs_kfree(local_buf, d_reclen, | 179 | kfree(local_buf); |
185 | inode->i_sb); | ||
186 | } | 180 | } |
187 | // next entry should be looked for with such offset | 181 | // next entry should be looked for with such offset |
188 | next_pos = deh_offset(deh) + 1; | 182 | next_pos = deh_offset(deh) + 1; |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index ad6fa964b0e7..f3473176c83a 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 | |||
192 | 192 | ||
193 | allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) * | 193 | allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) * |
194 | sizeof(b_blocknr_t), GFP_NOFS); | 194 | sizeof(b_blocknr_t), GFP_NOFS); |
195 | if (!allocated_blocks) | ||
196 | return -ENOMEM; | ||
195 | 197 | ||
196 | /* First we compose a key to point at the writing position, we want to do | 198 | /* First we compose a key to point at the writing position, we want to do |
197 | that outside of any locking region. */ | 199 | 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 | |||
1285 | struct reiserfs_transaction_handle th; | 1287 | struct reiserfs_transaction_handle th; |
1286 | th.t_trans_id = 0; | 1288 | th.t_trans_id = 0; |
1287 | 1289 | ||
1290 | /* If a filesystem is converted from 3.5 to 3.6, we'll have v3.5 items | ||
1291 | * lying around (most of the disk, in fact). Despite the filesystem | ||
1292 | * now being a v3.6 format, the old items still can't support large | ||
1293 | * file sizes. Catch this case here, as the rest of the VFS layer is | ||
1294 | * oblivious to the different limitations between old and new items. | ||
1295 | * reiserfs_setattr catches this for truncates. This chunk is lifted | ||
1296 | * from generic_write_checks. */ | ||
1297 | if (get_inode_item_key_version (inode) == KEY_FORMAT_3_5 && | ||
1298 | *ppos + count > MAX_NON_LFS) { | ||
1299 | if (*ppos >= MAX_NON_LFS) { | ||
1300 | send_sig(SIGXFSZ, current, 0); | ||
1301 | return -EFBIG; | ||
1302 | } | ||
1303 | if (count > MAX_NON_LFS - (unsigned long)*ppos) | ||
1304 | count = MAX_NON_LFS - (unsigned long)*ppos; | ||
1305 | } | ||
1306 | |||
1288 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment | 1307 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment |
1289 | ssize_t result, after_file_end = 0; | 1308 | ssize_t result, after_file_end = 0; |
1290 | if ((*ppos + count >= inode->i_size) | 1309 | if ((*ppos + count >= inode->i_size) |
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 45829889dcdc..aa22588019ec 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) | |||
2021 | return CARRY_ON; | 2021 | return CARRY_ON; |
2022 | } | 2022 | } |
2023 | 2023 | ||
2024 | #ifdef CONFIG_REISERFS_CHECK | ||
2025 | void *reiserfs_kmalloc(size_t size, gfp_t flags, struct super_block *s) | ||
2026 | { | ||
2027 | void *vp; | ||
2028 | static size_t malloced; | ||
2029 | |||
2030 | vp = kmalloc(size, flags); | ||
2031 | if (vp) { | ||
2032 | REISERFS_SB(s)->s_kmallocs += size; | ||
2033 | if (REISERFS_SB(s)->s_kmallocs > malloced + 200000) { | ||
2034 | reiserfs_warning(s, | ||
2035 | "vs-8301: reiserfs_kmalloc: allocated memory %d", | ||
2036 | REISERFS_SB(s)->s_kmallocs); | ||
2037 | malloced = REISERFS_SB(s)->s_kmallocs; | ||
2038 | } | ||
2039 | } | ||
2040 | return vp; | ||
2041 | } | ||
2042 | |||
2043 | void reiserfs_kfree(const void *vp, size_t size, struct super_block *s) | ||
2044 | { | ||
2045 | kfree(vp); | ||
2046 | |||
2047 | REISERFS_SB(s)->s_kmallocs -= size; | ||
2048 | if (REISERFS_SB(s)->s_kmallocs < 0) | ||
2049 | reiserfs_warning(s, | ||
2050 | "vs-8302: reiserfs_kfree: allocated memory %d", | ||
2051 | REISERFS_SB(s)->s_kmallocs); | ||
2052 | |||
2053 | } | ||
2054 | #endif | ||
2055 | |||
2056 | static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh) | 2024 | static int get_virtual_node_size(struct super_block *sb, struct buffer_head *bh) |
2057 | { | 2025 | { |
2058 | int max_num_of_items; | 2026 | int max_num_of_items; |
@@ -2086,7 +2054,7 @@ static int get_mem_for_virtual_node(struct tree_balance *tb) | |||
2086 | /* we have to allocate more memory for virtual node */ | 2054 | /* we have to allocate more memory for virtual node */ |
2087 | if (tb->vn_buf) { | 2055 | if (tb->vn_buf) { |
2088 | /* free memory allocated before */ | 2056 | /* free memory allocated before */ |
2089 | reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb); | 2057 | kfree(tb->vn_buf); |
2090 | /* this is not needed if kfree is atomic */ | 2058 | /* this is not needed if kfree is atomic */ |
2091 | check_fs = 1; | 2059 | check_fs = 1; |
2092 | } | 2060 | } |
@@ -2095,24 +2063,15 @@ static int get_mem_for_virtual_node(struct tree_balance *tb) | |||
2095 | tb->vn_buf_size = size; | 2063 | tb->vn_buf_size = size; |
2096 | 2064 | ||
2097 | /* get memory for virtual item */ | 2065 | /* get memory for virtual item */ |
2098 | buf = | 2066 | buf = kmalloc(size, GFP_ATOMIC | __GFP_NOWARN); |
2099 | reiserfs_kmalloc(size, GFP_ATOMIC | __GFP_NOWARN, | ||
2100 | tb->tb_sb); | ||
2101 | if (!buf) { | 2067 | if (!buf) { |
2102 | /* getting memory with GFP_KERNEL priority may involve | 2068 | /* getting memory with GFP_KERNEL priority may involve |
2103 | balancing now (due to indirect_to_direct conversion on | 2069 | balancing now (due to indirect_to_direct conversion on |
2104 | dcache shrinking). So, release path and collected | 2070 | dcache shrinking). So, release path and collected |
2105 | resources here */ | 2071 | resources here */ |
2106 | free_buffers_in_tb(tb); | 2072 | free_buffers_in_tb(tb); |
2107 | buf = reiserfs_kmalloc(size, GFP_NOFS, tb->tb_sb); | 2073 | buf = kmalloc(size, GFP_NOFS); |
2108 | if (!buf) { | 2074 | if (!buf) { |
2109 | #ifdef CONFIG_REISERFS_CHECK | ||
2110 | reiserfs_warning(tb->tb_sb, | ||
2111 | "vs-8345: get_mem_for_virtual_node: " | ||
2112 | "kmalloc failed. reiserfs kmalloced %d bytes", | ||
2113 | REISERFS_SB(tb->tb_sb)-> | ||
2114 | s_kmallocs); | ||
2115 | #endif | ||
2116 | tb->vn_buf_size = 0; | 2075 | tb->vn_buf_size = 0; |
2117 | } | 2076 | } |
2118 | tb->vn_buf = buf; | 2077 | tb->vn_buf = buf; |
@@ -2619,7 +2578,6 @@ void unfix_nodes(struct tree_balance *tb) | |||
2619 | } | 2578 | } |
2620 | } | 2579 | } |
2621 | 2580 | ||
2622 | if (tb->vn_buf) | 2581 | kfree(tb->vn_buf); |
2623 | reiserfs_kfree(tb->vn_buf, tb->vn_buf_size, tb->tb_sb); | ||
2624 | 2582 | ||
2625 | } | 2583 | } |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index ffa34b861bdb..b33d67bba2fd 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -2363,6 +2363,13 @@ static int reiserfs_write_full_page(struct page *page, | |||
2363 | int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize; | 2363 | int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize; |
2364 | th.t_trans_id = 0; | 2364 | th.t_trans_id = 0; |
2365 | 2365 | ||
2366 | /* no logging allowed when nonblocking or from PF_MEMALLOC */ | ||
2367 | if (checked && (current->flags & PF_MEMALLOC)) { | ||
2368 | redirty_page_for_writepage(wbc, page); | ||
2369 | unlock_page(page); | ||
2370 | return 0; | ||
2371 | } | ||
2372 | |||
2366 | /* The page dirty bit is cleared before writepage is called, which | 2373 | /* The page dirty bit is cleared before writepage is called, which |
2367 | * means we have to tell create_empty_buffers to make dirty buffers | 2374 | * means we have to tell create_empty_buffers to make dirty buffers |
2368 | * The page really should be up to date at this point, so tossing | 2375 | * The page really should be up to date at this point, so tossing |
@@ -2743,6 +2750,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) | |||
2743 | int ret = 1; | 2750 | int ret = 1; |
2744 | struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); | 2751 | struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); |
2745 | 2752 | ||
2753 | lock_buffer(bh); | ||
2746 | spin_lock(&j->j_dirty_buffers_lock); | 2754 | spin_lock(&j->j_dirty_buffers_lock); |
2747 | if (!buffer_mapped(bh)) { | 2755 | if (!buffer_mapped(bh)) { |
2748 | goto free_jh; | 2756 | goto free_jh; |
@@ -2758,7 +2766,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) | |||
2758 | if (buffer_journaled(bh) || buffer_journal_dirty(bh)) { | 2766 | if (buffer_journaled(bh) || buffer_journal_dirty(bh)) { |
2759 | ret = 0; | 2767 | ret = 0; |
2760 | } | 2768 | } |
2761 | } else if (buffer_dirty(bh) || buffer_locked(bh)) { | 2769 | } else if (buffer_dirty(bh)) { |
2762 | struct reiserfs_journal_list *jl; | 2770 | struct reiserfs_journal_list *jl; |
2763 | struct reiserfs_jh *jh = bh->b_private; | 2771 | struct reiserfs_jh *jh = bh->b_private; |
2764 | 2772 | ||
@@ -2784,6 +2792,7 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) | |||
2784 | reiserfs_free_jh(bh); | 2792 | reiserfs_free_jh(bh); |
2785 | } | 2793 | } |
2786 | spin_unlock(&j->j_dirty_buffers_lock); | 2794 | spin_unlock(&j->j_dirty_buffers_lock); |
2795 | unlock_buffer(bh); | ||
2787 | return ret; | 2796 | return ret; |
2788 | } | 2797 | } |
2789 | 2798 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 4491fcf2a0e6..b7a179560ab4 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 | |||
152 | struct reiserfs_bitmap_node *bn; | 152 | struct reiserfs_bitmap_node *bn; |
153 | static int id; | 153 | static int id; |
154 | 154 | ||
155 | bn = reiserfs_kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS, | 155 | bn = kmalloc(sizeof(struct reiserfs_bitmap_node), GFP_NOFS); |
156 | p_s_sb); | ||
157 | if (!bn) { | 156 | if (!bn) { |
158 | return NULL; | 157 | return NULL; |
159 | } | 158 | } |
160 | bn->data = reiserfs_kmalloc(p_s_sb->s_blocksize, GFP_NOFS, p_s_sb); | 159 | bn->data = kzalloc(p_s_sb->s_blocksize, GFP_NOFS); |
161 | if (!bn->data) { | 160 | if (!bn->data) { |
162 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 161 | kfree(bn); |
163 | return NULL; | 162 | return NULL; |
164 | } | 163 | } |
165 | bn->id = id++; | 164 | bn->id = id++; |
166 | memset(bn->data, 0, p_s_sb->s_blocksize); | ||
167 | INIT_LIST_HEAD(&bn->list); | 165 | INIT_LIST_HEAD(&bn->list); |
168 | return bn; | 166 | return bn; |
169 | } | 167 | } |
@@ -197,8 +195,8 @@ static inline void free_bitmap_node(struct super_block *p_s_sb, | |||
197 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 195 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); |
198 | journal->j_used_bitmap_nodes--; | 196 | journal->j_used_bitmap_nodes--; |
199 | if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) { | 197 | if (journal->j_free_bitmap_nodes > REISERFS_MAX_BITMAP_NODES) { |
200 | reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb); | 198 | kfree(bn->data); |
201 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 199 | kfree(bn); |
202 | } else { | 200 | } else { |
203 | list_add(&bn->list, &journal->j_bitmap_nodes); | 201 | list_add(&bn->list, &journal->j_bitmap_nodes); |
204 | journal->j_free_bitmap_nodes++; | 202 | journal->j_free_bitmap_nodes++; |
@@ -276,8 +274,8 @@ static int free_bitmap_nodes(struct super_block *p_s_sb) | |||
276 | while (next != &journal->j_bitmap_nodes) { | 274 | while (next != &journal->j_bitmap_nodes) { |
277 | bn = list_entry(next, struct reiserfs_bitmap_node, list); | 275 | bn = list_entry(next, struct reiserfs_bitmap_node, list); |
278 | list_del(next); | 276 | list_del(next); |
279 | reiserfs_kfree(bn->data, p_s_sb->s_blocksize, p_s_sb); | 277 | kfree(bn->data); |
280 | reiserfs_kfree(bn, sizeof(struct reiserfs_bitmap_node), p_s_sb); | 278 | kfree(bn); |
281 | next = journal->j_bitmap_nodes.next; | 279 | next = journal->j_bitmap_nodes.next; |
282 | journal->j_free_bitmap_nodes--; | 280 | journal->j_free_bitmap_nodes--; |
283 | } | 281 | } |
@@ -581,7 +579,7 @@ static inline void put_journal_list(struct super_block *s, | |||
581 | jl->j_trans_id, jl->j_refcount); | 579 | jl->j_trans_id, jl->j_refcount); |
582 | } | 580 | } |
583 | if (--jl->j_refcount == 0) | 581 | if (--jl->j_refcount == 0) |
584 | reiserfs_kfree(jl, sizeof(struct reiserfs_journal_list), s); | 582 | kfree(jl); |
585 | } | 583 | } |
586 | 584 | ||
587 | /* | 585 | /* |
@@ -848,6 +846,14 @@ static int write_ordered_buffers(spinlock_t * lock, | |||
848 | spin_lock(lock); | 846 | spin_lock(lock); |
849 | goto loop_next; | 847 | goto loop_next; |
850 | } | 848 | } |
849 | /* in theory, dirty non-uptodate buffers should never get here, | ||
850 | * but the upper layer io error paths still have a few quirks. | ||
851 | * Handle them here as gracefully as we can | ||
852 | */ | ||
853 | if (!buffer_uptodate(bh) && buffer_dirty(bh)) { | ||
854 | clear_buffer_dirty(bh); | ||
855 | ret = -EIO; | ||
856 | } | ||
851 | if (buffer_dirty(bh)) { | 857 | if (buffer_dirty(bh)) { |
852 | list_del_init(&jh->list); | 858 | list_del_init(&jh->list); |
853 | list_add(&jh->list, &tmp); | 859 | list_add(&jh->list, &tmp); |
@@ -879,6 +885,19 @@ static int write_ordered_buffers(spinlock_t * lock, | |||
879 | if (!buffer_uptodate(bh)) { | 885 | if (!buffer_uptodate(bh)) { |
880 | ret = -EIO; | 886 | ret = -EIO; |
881 | } | 887 | } |
888 | /* ugly interaction with invalidatepage here. | ||
889 | * reiserfs_invalidate_page will pin any buffer that has a valid | ||
890 | * journal head from an older transaction. If someone else sets | ||
891 | * our buffer dirty after we write it in the first loop, and | ||
892 | * then someone truncates the page away, nobody will ever write | ||
893 | * the buffer. We're safe if we write the page one last time | ||
894 | * after freeing the journal header. | ||
895 | */ | ||
896 | if (buffer_dirty(bh) && unlikely(bh->b_page->mapping == NULL)) { | ||
897 | spin_unlock(lock); | ||
898 | ll_rw_block(WRITE, 1, &bh); | ||
899 | spin_lock(lock); | ||
900 | } | ||
882 | put_bh(bh); | 901 | put_bh(bh); |
883 | cond_resched_lock(lock); | 902 | cond_resched_lock(lock); |
884 | } | 903 | } |
@@ -977,6 +996,7 @@ static int flush_commit_list(struct super_block *s, | |||
977 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 996 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
978 | int barrier = 0; | 997 | int barrier = 0; |
979 | int retval = 0; | 998 | int retval = 0; |
999 | int write_len; | ||
980 | 1000 | ||
981 | reiserfs_check_lock_depth(s, "flush_commit_list"); | 1001 | reiserfs_check_lock_depth(s, "flush_commit_list"); |
982 | 1002 | ||
@@ -1018,24 +1038,35 @@ static int flush_commit_list(struct super_block *s, | |||
1018 | } | 1038 | } |
1019 | 1039 | ||
1020 | if (!list_empty(&jl->j_bh_list)) { | 1040 | if (!list_empty(&jl->j_bh_list)) { |
1041 | int ret; | ||
1021 | unlock_kernel(); | 1042 | unlock_kernel(); |
1022 | write_ordered_buffers(&journal->j_dirty_buffers_lock, | 1043 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, |
1023 | journal, jl, &jl->j_bh_list); | 1044 | journal, jl, &jl->j_bh_list); |
1045 | if (ret < 0 && retval == 0) | ||
1046 | retval = ret; | ||
1024 | lock_kernel(); | 1047 | lock_kernel(); |
1025 | } | 1048 | } |
1026 | BUG_ON(!list_empty(&jl->j_bh_list)); | 1049 | BUG_ON(!list_empty(&jl->j_bh_list)); |
1027 | /* | 1050 | /* |
1028 | * for the description block and all the log blocks, submit any buffers | 1051 | * for the description block and all the log blocks, submit any buffers |
1029 | * that haven't already reached the disk | 1052 | * that haven't already reached the disk. Try to write at least 256 |
1053 | * log blocks. later on, we will only wait on blocks that correspond | ||
1054 | * to this transaction, but while we're unplugging we might as well | ||
1055 | * get a chunk of data on there. | ||
1030 | */ | 1056 | */ |
1031 | atomic_inc(&journal->j_async_throttle); | 1057 | atomic_inc(&journal->j_async_throttle); |
1032 | for (i = 0; i < (jl->j_len + 1); i++) { | 1058 | write_len = jl->j_len + 1; |
1059 | if (write_len < 256) | ||
1060 | write_len = 256; | ||
1061 | for (i = 0 ; i < write_len ; i++) { | ||
1033 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % | 1062 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + (jl->j_start + i) % |
1034 | SB_ONDISK_JOURNAL_SIZE(s); | 1063 | SB_ONDISK_JOURNAL_SIZE(s); |
1035 | tbh = journal_find_get_block(s, bn); | 1064 | tbh = journal_find_get_block(s, bn); |
1036 | if (buffer_dirty(tbh)) /* redundant, ll_rw_block() checks */ | 1065 | if (tbh) { |
1037 | ll_rw_block(SWRITE, 1, &tbh); | 1066 | if (buffer_dirty(tbh)) |
1038 | put_bh(tbh); | 1067 | ll_rw_block(WRITE, 1, &tbh) ; |
1068 | put_bh(tbh) ; | ||
1069 | } | ||
1039 | } | 1070 | } |
1040 | atomic_dec(&journal->j_async_throttle); | 1071 | atomic_dec(&journal->j_async_throttle); |
1041 | 1072 | ||
@@ -1818,8 +1849,7 @@ void remove_journal_hash(struct super_block *sb, | |||
1818 | static void free_journal_ram(struct super_block *p_s_sb) | 1849 | static void free_journal_ram(struct super_block *p_s_sb) |
1819 | { | 1850 | { |
1820 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 1851 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); |
1821 | reiserfs_kfree(journal->j_current_jl, | 1852 | kfree(journal->j_current_jl); |
1822 | sizeof(struct reiserfs_journal_list), p_s_sb); | ||
1823 | journal->j_num_lists--; | 1853 | journal->j_num_lists--; |
1824 | 1854 | ||
1825 | vfree(journal->j_cnode_free_orig); | 1855 | vfree(journal->j_cnode_free_orig); |
@@ -2093,21 +2123,15 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2093 | } | 2123 | } |
2094 | trans_id = get_desc_trans_id(desc); | 2124 | trans_id = get_desc_trans_id(desc); |
2095 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ | 2125 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ |
2096 | log_blocks = | 2126 | log_blocks = kmalloc(get_desc_trans_len(desc) * |
2097 | reiserfs_kmalloc(get_desc_trans_len(desc) * | 2127 | sizeof(struct buffer_head *), GFP_NOFS); |
2098 | sizeof(struct buffer_head *), GFP_NOFS, p_s_sb); | 2128 | real_blocks = kmalloc(get_desc_trans_len(desc) * |
2099 | real_blocks = | 2129 | sizeof(struct buffer_head *), GFP_NOFS); |
2100 | reiserfs_kmalloc(get_desc_trans_len(desc) * | ||
2101 | sizeof(struct buffer_head *), GFP_NOFS, p_s_sb); | ||
2102 | if (!log_blocks || !real_blocks) { | 2130 | if (!log_blocks || !real_blocks) { |
2103 | brelse(c_bh); | 2131 | brelse(c_bh); |
2104 | brelse(d_bh); | 2132 | brelse(d_bh); |
2105 | reiserfs_kfree(log_blocks, | 2133 | kfree(log_blocks); |
2106 | get_desc_trans_len(desc) * | 2134 | kfree(real_blocks); |
2107 | sizeof(struct buffer_head *), p_s_sb); | ||
2108 | reiserfs_kfree(real_blocks, | ||
2109 | get_desc_trans_len(desc) * | ||
2110 | sizeof(struct buffer_head *), p_s_sb); | ||
2111 | reiserfs_warning(p_s_sb, | 2135 | reiserfs_warning(p_s_sb, |
2112 | "journal-1169: kmalloc failed, unable to mount FS"); | 2136 | "journal-1169: kmalloc failed, unable to mount FS"); |
2113 | return -1; | 2137 | return -1; |
@@ -2145,12 +2169,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2145 | brelse_array(real_blocks, i); | 2169 | brelse_array(real_blocks, i); |
2146 | brelse(c_bh); | 2170 | brelse(c_bh); |
2147 | brelse(d_bh); | 2171 | brelse(d_bh); |
2148 | reiserfs_kfree(log_blocks, | 2172 | kfree(log_blocks); |
2149 | get_desc_trans_len(desc) * | 2173 | kfree(real_blocks); |
2150 | sizeof(struct buffer_head *), p_s_sb); | ||
2151 | reiserfs_kfree(real_blocks, | ||
2152 | get_desc_trans_len(desc) * | ||
2153 | sizeof(struct buffer_head *), p_s_sb); | ||
2154 | return -1; | 2174 | return -1; |
2155 | } | 2175 | } |
2156 | } | 2176 | } |
@@ -2166,12 +2186,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2166 | brelse_array(real_blocks, get_desc_trans_len(desc)); | 2186 | brelse_array(real_blocks, get_desc_trans_len(desc)); |
2167 | brelse(c_bh); | 2187 | brelse(c_bh); |
2168 | brelse(d_bh); | 2188 | brelse(d_bh); |
2169 | reiserfs_kfree(log_blocks, | 2189 | kfree(log_blocks); |
2170 | get_desc_trans_len(desc) * | 2190 | kfree(real_blocks); |
2171 | sizeof(struct buffer_head *), p_s_sb); | ||
2172 | reiserfs_kfree(real_blocks, | ||
2173 | get_desc_trans_len(desc) * | ||
2174 | sizeof(struct buffer_head *), p_s_sb); | ||
2175 | return -1; | 2191 | return -1; |
2176 | } | 2192 | } |
2177 | memcpy(real_blocks[i]->b_data, log_blocks[i]->b_data, | 2193 | 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, | |||
2193 | get_desc_trans_len(desc) - i); | 2209 | get_desc_trans_len(desc) - i); |
2194 | brelse(c_bh); | 2210 | brelse(c_bh); |
2195 | brelse(d_bh); | 2211 | brelse(d_bh); |
2196 | reiserfs_kfree(log_blocks, | 2212 | kfree(log_blocks); |
2197 | get_desc_trans_len(desc) * | 2213 | kfree(real_blocks); |
2198 | sizeof(struct buffer_head *), p_s_sb); | ||
2199 | reiserfs_kfree(real_blocks, | ||
2200 | get_desc_trans_len(desc) * | ||
2201 | sizeof(struct buffer_head *), p_s_sb); | ||
2202 | return -1; | 2214 | return -1; |
2203 | } | 2215 | } |
2204 | brelse(real_blocks[i]); | 2216 | brelse(real_blocks[i]); |
@@ -2217,12 +2229,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2217 | journal->j_trans_id = trans_id + 1; | 2229 | journal->j_trans_id = trans_id + 1; |
2218 | brelse(c_bh); | 2230 | brelse(c_bh); |
2219 | brelse(d_bh); | 2231 | brelse(d_bh); |
2220 | reiserfs_kfree(log_blocks, | 2232 | kfree(log_blocks); |
2221 | le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), | 2233 | kfree(real_blocks); |
2222 | p_s_sb); | ||
2223 | reiserfs_kfree(real_blocks, | ||
2224 | le32_to_cpu(desc->j_len) * sizeof(struct buffer_head *), | ||
2225 | p_s_sb); | ||
2226 | return 0; | 2234 | return 0; |
2227 | } | 2235 | } |
2228 | 2236 | ||
@@ -2471,14 +2479,8 @@ static int journal_read(struct super_block *p_s_sb) | |||
2471 | static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s) | 2479 | static struct reiserfs_journal_list *alloc_journal_list(struct super_block *s) |
2472 | { | 2480 | { |
2473 | struct reiserfs_journal_list *jl; | 2481 | struct reiserfs_journal_list *jl; |
2474 | retry: | 2482 | jl = kzalloc(sizeof(struct reiserfs_journal_list), |
2475 | jl = reiserfs_kmalloc(sizeof(struct reiserfs_journal_list), GFP_NOFS, | 2483 | GFP_NOFS | __GFP_NOFAIL); |
2476 | s); | ||
2477 | if (!jl) { | ||
2478 | yield(); | ||
2479 | goto retry; | ||
2480 | } | ||
2481 | memset(jl, 0, sizeof(*jl)); | ||
2482 | INIT_LIST_HEAD(&jl->j_list); | 2484 | INIT_LIST_HEAD(&jl->j_list); |
2483 | INIT_LIST_HEAD(&jl->j_working_list); | 2485 | INIT_LIST_HEAD(&jl->j_working_list); |
2484 | INIT_LIST_HEAD(&jl->j_tail_bh_list); | 2486 | INIT_LIST_HEAD(&jl->j_tail_bh_list); |
@@ -2821,6 +2823,9 @@ int journal_transaction_should_end(struct reiserfs_transaction_handle *th, | |||
2821 | journal->j_cnode_free < (journal->j_trans_max * 3)) { | 2823 | journal->j_cnode_free < (journal->j_trans_max * 3)) { |
2822 | return 1; | 2824 | return 1; |
2823 | } | 2825 | } |
2826 | /* protected by the BKL here */ | ||
2827 | journal->j_len_alloc += new_alloc; | ||
2828 | th->t_blocks_allocated += new_alloc ; | ||
2824 | return 0; | 2829 | return 0; |
2825 | } | 2830 | } |
2826 | 2831 | ||
@@ -3042,14 +3047,12 @@ struct reiserfs_transaction_handle *reiserfs_persistent_transaction(struct | |||
3042 | } | 3047 | } |
3043 | return th; | 3048 | return th; |
3044 | } | 3049 | } |
3045 | th = reiserfs_kmalloc(sizeof(struct reiserfs_transaction_handle), | 3050 | th = kmalloc(sizeof(struct reiserfs_transaction_handle), GFP_NOFS); |
3046 | GFP_NOFS, s); | ||
3047 | if (!th) | 3051 | if (!th) |
3048 | return NULL; | 3052 | return NULL; |
3049 | ret = journal_begin(th, s, nblocks); | 3053 | ret = journal_begin(th, s, nblocks); |
3050 | if (ret) { | 3054 | if (ret) { |
3051 | reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), | 3055 | kfree(th); |
3052 | s); | ||
3053 | return NULL; | 3056 | return NULL; |
3054 | } | 3057 | } |
3055 | 3058 | ||
@@ -3067,8 +3070,7 @@ int reiserfs_end_persistent_transaction(struct reiserfs_transaction_handle *th) | |||
3067 | ret = -EIO; | 3070 | ret = -EIO; |
3068 | if (th->t_refcount == 0) { | 3071 | if (th->t_refcount == 0) { |
3069 | SB_JOURNAL(s)->j_persistent_trans--; | 3072 | SB_JOURNAL(s)->j_persistent_trans--; |
3070 | reiserfs_kfree(th, sizeof(struct reiserfs_transaction_handle), | 3073 | kfree(th); |
3071 | s); | ||
3072 | } | 3074 | } |
3073 | return ret; | 3075 | return ret; |
3074 | } | 3076 | } |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 8f8d8d01107c..c8123308e060 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -456,7 +456,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
456 | /* get memory for composing the entry */ | 456 | /* get memory for composing the entry */ |
457 | buflen = DEH_SIZE + ROUND_UP(namelen); | 457 | buflen = DEH_SIZE + ROUND_UP(namelen); |
458 | if (buflen > sizeof(small_buf)) { | 458 | if (buflen > sizeof(small_buf)) { |
459 | buffer = reiserfs_kmalloc(buflen, GFP_NOFS, dir->i_sb); | 459 | buffer = kmalloc(buflen, GFP_NOFS); |
460 | if (buffer == 0) | 460 | if (buffer == 0) |
461 | return -ENOMEM; | 461 | return -ENOMEM; |
462 | } else | 462 | } else |
@@ -490,7 +490,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
490 | retval = reiserfs_find_entry(dir, name, namelen, &path, &de); | 490 | retval = reiserfs_find_entry(dir, name, namelen, &path, &de); |
491 | if (retval != NAME_NOT_FOUND) { | 491 | if (retval != NAME_NOT_FOUND) { |
492 | if (buffer != small_buf) | 492 | if (buffer != small_buf) |
493 | reiserfs_kfree(buffer, buflen, dir->i_sb); | 493 | kfree(buffer); |
494 | pathrelse(&path); | 494 | pathrelse(&path); |
495 | 495 | ||
496 | if (retval == IO_ERROR) { | 496 | if (retval == IO_ERROR) { |
@@ -515,7 +515,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
515 | reiserfs_warning(dir->i_sb, | 515 | reiserfs_warning(dir->i_sb, |
516 | "reiserfs_add_entry: Congratulations! we have got hash function screwed up"); | 516 | "reiserfs_add_entry: Congratulations! we have got hash function screwed up"); |
517 | if (buffer != small_buf) | 517 | if (buffer != small_buf) |
518 | reiserfs_kfree(buffer, buflen, dir->i_sb); | 518 | kfree(buffer); |
519 | pathrelse(&path); | 519 | pathrelse(&path); |
520 | return -EBUSY; | 520 | return -EBUSY; |
521 | } | 521 | } |
@@ -535,7 +535,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
535 | &entry_key); | 535 | &entry_key); |
536 | 536 | ||
537 | if (buffer != small_buf) | 537 | if (buffer != small_buf) |
538 | reiserfs_kfree(buffer, buflen, dir->i_sb); | 538 | kfree(buffer); |
539 | pathrelse(&path); | 539 | pathrelse(&path); |
540 | return -EBUSY; | 540 | return -EBUSY; |
541 | } | 541 | } |
@@ -546,7 +546,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
546 | reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer, | 546 | reiserfs_paste_into_item(th, &path, &entry_key, dir, buffer, |
547 | paste_size); | 547 | paste_size); |
548 | if (buffer != small_buf) | 548 | if (buffer != small_buf) |
549 | reiserfs_kfree(buffer, buflen, dir->i_sb); | 549 | kfree(buffer); |
550 | if (retval) { | 550 | if (retval) { |
551 | reiserfs_check_path(&path); | 551 | reiserfs_check_path(&path); |
552 | return retval; | 552 | return retval; |
@@ -1065,7 +1065,7 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1065 | goto out_failed; | 1065 | goto out_failed; |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | name = reiserfs_kmalloc(item_len, GFP_NOFS, parent_dir->i_sb); | 1068 | name = kmalloc(item_len, GFP_NOFS); |
1069 | if (!name) { | 1069 | if (!name) { |
1070 | drop_new_inode(inode); | 1070 | drop_new_inode(inode); |
1071 | retval = -ENOMEM; | 1071 | retval = -ENOMEM; |
@@ -1079,14 +1079,14 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1079 | retval = journal_begin(&th, parent_dir->i_sb, jbegin_count); | 1079 | retval = journal_begin(&th, parent_dir->i_sb, jbegin_count); |
1080 | if (retval) { | 1080 | if (retval) { |
1081 | drop_new_inode(inode); | 1081 | drop_new_inode(inode); |
1082 | reiserfs_kfree(name, item_len, parent_dir->i_sb); | 1082 | kfree(name); |
1083 | goto out_failed; | 1083 | goto out_failed; |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | retval = | 1086 | retval = |
1087 | reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname), | 1087 | reiserfs_new_inode(&th, parent_dir, mode, name, strlen(symname), |
1088 | dentry, inode); | 1088 | dentry, inode); |
1089 | reiserfs_kfree(name, item_len, parent_dir->i_sb); | 1089 | kfree(name); |
1090 | if (retval) { /* reiserfs_new_inode iputs for us */ | 1090 | if (retval) { /* reiserfs_new_inode iputs for us */ |
1091 | goto out_failed; | 1091 | goto out_failed; |
1092 | } | 1092 | } |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index fc2f43c75df4..ef6caed9336b 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) | |||
88 | seq_printf(m, "state: \t%s\n" | 88 | seq_printf(m, "state: \t%s\n" |
89 | "mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n" | 89 | "mount options: \t%s%s%s%s%s%s%s%s%s%s%s\n" |
90 | "gen. counter: \t%i\n" | 90 | "gen. counter: \t%i\n" |
91 | "s_kmallocs: \t%i\n" | ||
92 | "s_disk_reads: \t%i\n" | 91 | "s_disk_reads: \t%i\n" |
93 | "s_disk_writes: \t%i\n" | 92 | "s_disk_writes: \t%i\n" |
94 | "s_fix_nodes: \t%i\n" | 93 | "s_fix_nodes: \t%i\n" |
@@ -128,7 +127,7 @@ static int show_super(struct seq_file *m, struct super_block *sb) | |||
128 | "SMALL_TAILS " : "NO_TAILS ", | 127 | "SMALL_TAILS " : "NO_TAILS ", |
129 | replay_only(sb) ? "REPLAY_ONLY " : "", | 128 | replay_only(sb) ? "REPLAY_ONLY " : "", |
130 | convert_reiserfs(sb) ? "CONV " : "", | 129 | convert_reiserfs(sb) ? "CONV " : "", |
131 | atomic_read(&r->s_generation_counter), SF(s_kmallocs), | 130 | atomic_read(&r->s_generation_counter), |
132 | SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes), | 131 | SF(s_disk_reads), SF(s_disk_writes), SF(s_fix_nodes), |
133 | SF(s_do_balance), SF(s_unneeded_left_neighbor), | 132 | SF(s_do_balance), SF(s_unneeded_left_neighbor), |
134 | SF(s_good_search_by_key_reada), SF(s_bmaps), | 133 | SF(s_good_search_by_key_reada), SF(s_bmaps), |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 397d9590c8f2..77891de0e02e 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -472,12 +472,6 @@ static void reiserfs_put_super(struct super_block *s) | |||
472 | 472 | ||
473 | print_statistics(s); | 473 | print_statistics(s); |
474 | 474 | ||
475 | if (REISERFS_SB(s)->s_kmallocs != 0) { | ||
476 | reiserfs_warning(s, | ||
477 | "vs-2004: reiserfs_put_super: allocated memory left %d", | ||
478 | REISERFS_SB(s)->s_kmallocs); | ||
479 | } | ||
480 | |||
481 | if (REISERFS_SB(s)->reserved_blocks != 0) { | 475 | if (REISERFS_SB(s)->reserved_blocks != 0) { |
482 | reiserfs_warning(s, | 476 | reiserfs_warning(s, |
483 | "green-2005: reiserfs_put_super: reserved blocks left %d", | 477 | "green-2005: reiserfs_put_super: reserved blocks left %d", |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index cc061bfd437b..ffb79c48c5bf 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) | |||
368 | if (d_reclen <= 32) { | 368 | if (d_reclen <= 32) { |
369 | local_buf = small_buf; | 369 | local_buf = small_buf; |
370 | } else { | 370 | } else { |
371 | local_buf = | 371 | local_buf = kmalloc(d_reclen, GFP_NOFS); |
372 | reiserfs_kmalloc(d_reclen, GFP_NOFS, inode->i_sb); | ||
373 | if (!local_buf) { | 372 | if (!local_buf) { |
374 | pathrelse(&path_to_entry); | 373 | pathrelse(&path_to_entry); |
375 | return -ENOMEM; | 374 | return -ENOMEM; |
376 | } | 375 | } |
377 | if (item_moved(&tmp_ih, &path_to_entry)) { | 376 | if (item_moved(&tmp_ih, &path_to_entry)) { |
378 | reiserfs_kfree(local_buf, d_reclen, | 377 | kfree(local_buf); |
379 | inode->i_sb); | ||
380 | 378 | ||
381 | /* sigh, must retry. Do this same offset again */ | 379 | /* sigh, must retry. Do this same offset again */ |
382 | next_pos = d_off; | 380 | next_pos = d_off; |
@@ -399,13 +397,12 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
399 | if (filldir(dirent, local_buf, d_reclen, d_off, d_ino, | 397 | if (filldir(dirent, local_buf, d_reclen, d_off, d_ino, |
400 | DT_UNKNOWN) < 0) { | 398 | DT_UNKNOWN) < 0) { |
401 | if (local_buf != small_buf) { | 399 | if (local_buf != small_buf) { |
402 | reiserfs_kfree(local_buf, d_reclen, | 400 | kfree(local_buf); |
403 | inode->i_sb); | ||
404 | } | 401 | } |
405 | goto end; | 402 | goto end; |
406 | } | 403 | } |
407 | if (local_buf != small_buf) { | 404 | if (local_buf != small_buf) { |
408 | reiserfs_kfree(local_buf, d_reclen, inode->i_sb); | 405 | kfree(local_buf); |
409 | } | 406 | } |
410 | } /* while */ | 407 | } /* while */ |
411 | 408 | ||
@@ -1322,109 +1319,44 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
1322 | return err; | 1319 | return err; |
1323 | } | 1320 | } |
1324 | 1321 | ||
1325 | static int | 1322 | static int reiserfs_check_acl(struct inode *inode, int mask) |
1326 | __reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd, | ||
1327 | int need_lock) | ||
1328 | { | 1323 | { |
1329 | umode_t mode = inode->i_mode; | 1324 | struct posix_acl *acl; |
1330 | 1325 | int error = -EAGAIN; /* do regular unix permission checks by default */ | |
1331 | if (mask & MAY_WRITE) { | ||
1332 | /* | ||
1333 | * Nobody gets write access to a read-only fs. | ||
1334 | */ | ||
1335 | if (IS_RDONLY(inode) && | ||
1336 | (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) | ||
1337 | return -EROFS; | ||
1338 | 1326 | ||
1339 | /* | 1327 | reiserfs_read_lock_xattr_i(inode); |
1340 | * Nobody gets write access to an immutable file. | 1328 | reiserfs_read_lock_xattrs(inode->i_sb); |
1341 | */ | ||
1342 | if (IS_IMMUTABLE(inode)) | ||
1343 | return -EACCES; | ||
1344 | } | ||
1345 | 1329 | ||
1346 | /* We don't do permission checks on the internal objects. | 1330 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); |
1347 | * Permissions are determined by the "owning" object. */ | ||
1348 | if (is_reiserfs_priv_object(inode)) | ||
1349 | return 0; | ||
1350 | 1331 | ||
1351 | if (current->fsuid == inode->i_uid) { | 1332 | reiserfs_read_unlock_xattrs(inode->i_sb); |
1352 | mode >>= 6; | 1333 | reiserfs_read_unlock_xattr_i(inode); |
1353 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | ||
1354 | } else if (reiserfs_posixacl(inode->i_sb) && | ||
1355 | get_inode_sd_version(inode) != STAT_DATA_V1) { | ||
1356 | struct posix_acl *acl; | ||
1357 | |||
1358 | /* ACL can't contain additional permissions if | ||
1359 | the ACL_MASK entry is 0 */ | ||
1360 | if (!(mode & S_IRWXG)) | ||
1361 | goto check_groups; | ||
1362 | |||
1363 | if (need_lock) { | ||
1364 | reiserfs_read_lock_xattr_i(inode); | ||
1365 | reiserfs_read_lock_xattrs(inode->i_sb); | ||
1366 | } | ||
1367 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | ||
1368 | if (need_lock) { | ||
1369 | reiserfs_read_unlock_xattrs(inode->i_sb); | ||
1370 | reiserfs_read_unlock_xattr_i(inode); | ||
1371 | } | ||
1372 | if (IS_ERR(acl)) { | ||
1373 | if (PTR_ERR(acl) == -ENODATA) | ||
1374 | goto check_groups; | ||
1375 | return PTR_ERR(acl); | ||
1376 | } | ||
1377 | 1334 | ||
1378 | if (acl) { | 1335 | if (acl) { |
1379 | int err = posix_acl_permission(inode, acl, mask); | 1336 | if (!IS_ERR(acl)) { |
1337 | error = posix_acl_permission(inode, acl, mask); | ||
1380 | posix_acl_release(acl); | 1338 | posix_acl_release(acl); |
1381 | if (err == -EACCES) { | 1339 | } else if (PTR_ERR(acl) != -ENODATA) |
1382 | goto check_capabilities; | 1340 | error = PTR_ERR(acl); |
1383 | } | ||
1384 | return err; | ||
1385 | } else { | ||
1386 | goto check_groups; | ||
1387 | } | ||
1388 | #endif | ||
1389 | } else { | ||
1390 | check_groups: | ||
1391 | if (in_group_p(inode->i_gid)) | ||
1392 | mode >>= 3; | ||
1393 | } | 1341 | } |
1394 | 1342 | ||
1395 | /* | 1343 | return error; |
1396 | * If the DACs are ok we don't need any capability check. | 1344 | } |
1397 | */ | ||
1398 | if (((mode & mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == mask)) | ||
1399 | return 0; | ||
1400 | 1345 | ||
1401 | check_capabilities: | 1346 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) |
1347 | { | ||
1402 | /* | 1348 | /* |
1403 | * Read/write DACs are always overridable. | 1349 | * We don't do permission checks on the internal objects. |
1404 | * Executable DACs are overridable if at least one exec bit is set. | 1350 | * Permissions are determined by the "owning" object. |
1405 | */ | 1351 | */ |
1406 | if (!(mask & MAY_EXEC) || | 1352 | if (is_reiserfs_priv_object(inode)) |
1407 | (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) | 1353 | return 0; |
1408 | if (capable(CAP_DAC_OVERRIDE)) | ||
1409 | return 0; | ||
1410 | 1354 | ||
1411 | /* | 1355 | /* |
1412 | * Searching includes executable on directories, else just read. | 1356 | * Stat data v1 doesn't support ACLs. |
1413 | */ | 1357 | */ |
1414 | if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) | 1358 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
1415 | if (capable(CAP_DAC_READ_SEARCH)) | 1359 | return generic_permission(inode, mask, NULL); |
1416 | return 0; | 1360 | else |
1417 | 1361 | return generic_permission(inode, mask, reiserfs_check_acl); | |
1418 | return -EACCES; | ||
1419 | } | ||
1420 | |||
1421 | int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
1422 | { | ||
1423 | return __reiserfs_permission(inode, mask, nd, 1); | ||
1424 | } | ||
1425 | |||
1426 | int | ||
1427 | reiserfs_permission_locked(struct inode *inode, int mask, struct nameidata *nd) | ||
1428 | { | ||
1429 | return __reiserfs_permission(inode, mask, nd, 0); | ||
1430 | } | 1362 | } |