diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /fs/reiserfs | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/reiserfs')
-rw-r--r-- | fs/reiserfs/Makefile | 6 | ||||
-rw-r--r-- | fs/reiserfs/bitmap.c | 19 | ||||
-rw-r--r-- | fs/reiserfs/dir.c | 13 | ||||
-rw-r--r-- | fs/reiserfs/do_balan.c | 17 | ||||
-rw-r--r-- | fs/reiserfs/file.c | 4 | ||||
-rw-r--r-- | fs/reiserfs/fix_node.c | 22 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 164 | ||||
-rw-r--r-- | fs/reiserfs/ioctl.c | 80 | ||||
-rw-r--r-- | fs/reiserfs/journal.c | 164 | ||||
-rw-r--r-- | fs/reiserfs/lock.c | 97 | ||||
-rw-r--r-- | fs/reiserfs/namei.c | 51 | ||||
-rw-r--r-- | fs/reiserfs/prints.c | 4 | ||||
-rw-r--r-- | fs/reiserfs/procfs.c | 65 | ||||
-rw-r--r-- | fs/reiserfs/resize.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/stree.c | 73 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 76 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 104 | ||||
-rw-r--r-- | fs/reiserfs/xattr_acl.c | 72 | ||||
-rw-r--r-- | fs/reiserfs/xattr_security.c | 24 | ||||
-rw-r--r-- | fs/reiserfs/xattr_trusted.c | 21 | ||||
-rw-r--r-- | fs/reiserfs/xattr_user.c | 21 |
21 files changed, 678 insertions, 421 deletions
diff --git a/fs/reiserfs/Makefile b/fs/reiserfs/Makefile index 7c5ab6330dd6..792b3cb2cd18 100644 --- a/fs/reiserfs/Makefile +++ b/fs/reiserfs/Makefile | |||
@@ -7,7 +7,11 @@ obj-$(CONFIG_REISERFS_FS) += reiserfs.o | |||
7 | reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \ | 7 | reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \ |
8 | super.o prints.o objectid.o lbalance.o ibalance.o stree.o \ | 8 | super.o prints.o objectid.o lbalance.o ibalance.o stree.o \ |
9 | hashes.o tail_conversion.o journal.o resize.o \ | 9 | hashes.o tail_conversion.o journal.o resize.o \ |
10 | item_ops.o ioctl.o procfs.o xattr.o | 10 | item_ops.o ioctl.o xattr.o lock.o |
11 | |||
12 | ifeq ($(CONFIG_REISERFS_PROC_INFO),y) | ||
13 | reiserfs-objs += procfs.o | ||
14 | endif | ||
11 | 15 | ||
12 | ifeq ($(CONFIG_REISERFS_FS_XATTR),y) | 16 | ifeq ($(CONFIG_REISERFS_FS_XATTR),y) |
13 | reiserfs-objs += xattr_user.o xattr_trusted.o | 17 | reiserfs-objs += xattr_user.o xattr_trusted.o |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index e716161ab325..483442e66ed6 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -169,7 +169,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
169 | return 0; // No free blocks in this bitmap | 169 | return 0; // No free blocks in this bitmap |
170 | } | 170 | } |
171 | 171 | ||
172 | /* search for a first zero bit -- beggining of a window */ | 172 | /* search for a first zero bit -- beginning of a window */ |
173 | *beg = reiserfs_find_next_zero_le_bit | 173 | *beg = reiserfs_find_next_zero_le_bit |
174 | ((unsigned long *)(bh->b_data), boundary, *beg); | 174 | ((unsigned long *)(bh->b_data), boundary, *beg); |
175 | 175 | ||
@@ -425,7 +425,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
425 | 425 | ||
426 | journal_mark_dirty(th, s, sbh); | 426 | journal_mark_dirty(th, s, sbh); |
427 | if (for_unformatted) | 427 | if (for_unformatted) |
428 | vfs_dq_free_block_nodirty(inode, 1); | 428 | dquot_free_block_nodirty(inode, 1); |
429 | } | 429 | } |
430 | 430 | ||
431 | void reiserfs_free_block(struct reiserfs_transaction_handle *th, | 431 | void reiserfs_free_block(struct reiserfs_transaction_handle *th, |
@@ -1049,7 +1049,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start | |||
1049 | amount_needed, hint->inode->i_uid); | 1049 | amount_needed, hint->inode->i_uid); |
1050 | #endif | 1050 | #endif |
1051 | quota_ret = | 1051 | quota_ret = |
1052 | vfs_dq_alloc_block_nodirty(hint->inode, amount_needed); | 1052 | dquot_alloc_block_nodirty(hint->inode, amount_needed); |
1053 | if (quota_ret) /* Quota exceeded? */ | 1053 | if (quota_ret) /* Quota exceeded? */ |
1054 | return QUOTA_EXCEEDED; | 1054 | return QUOTA_EXCEEDED; |
1055 | if (hint->preallocate && hint->prealloc_size) { | 1055 | if (hint->preallocate && hint->prealloc_size) { |
@@ -1058,7 +1058,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start | |||
1058 | "reiserquota: allocating (prealloc) %d blocks id=%u", | 1058 | "reiserquota: allocating (prealloc) %d blocks id=%u", |
1059 | hint->prealloc_size, hint->inode->i_uid); | 1059 | hint->prealloc_size, hint->inode->i_uid); |
1060 | #endif | 1060 | #endif |
1061 | quota_ret = vfs_dq_prealloc_block_nodirty(hint->inode, | 1061 | quota_ret = dquot_prealloc_block_nodirty(hint->inode, |
1062 | hint->prealloc_size); | 1062 | hint->prealloc_size); |
1063 | if (quota_ret) | 1063 | if (quota_ret) |
1064 | hint->preallocate = hint->prealloc_size = 0; | 1064 | hint->preallocate = hint->prealloc_size = 0; |
@@ -1092,7 +1092,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start | |||
1092 | hint->inode->i_uid); | 1092 | hint->inode->i_uid); |
1093 | #endif | 1093 | #endif |
1094 | /* Free not allocated blocks */ | 1094 | /* Free not allocated blocks */ |
1095 | vfs_dq_free_block_nodirty(hint->inode, | 1095 | dquot_free_block_nodirty(hint->inode, |
1096 | amount_needed + hint->prealloc_size - | 1096 | amount_needed + hint->prealloc_size - |
1097 | nr_allocated); | 1097 | nr_allocated); |
1098 | } | 1098 | } |
@@ -1125,7 +1125,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start | |||
1125 | REISERFS_I(hint->inode)->i_prealloc_count, | 1125 | REISERFS_I(hint->inode)->i_prealloc_count, |
1126 | hint->inode->i_uid); | 1126 | hint->inode->i_uid); |
1127 | #endif | 1127 | #endif |
1128 | vfs_dq_free_block_nodirty(hint->inode, amount_needed + | 1128 | dquot_free_block_nodirty(hint->inode, amount_needed + |
1129 | hint->prealloc_size - nr_allocated - | 1129 | hint->prealloc_size - nr_allocated - |
1130 | REISERFS_I(hint->inode)-> | 1130 | REISERFS_I(hint->inode)-> |
1131 | i_prealloc_count); | 1131 | i_prealloc_count); |
@@ -1249,14 +1249,18 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1249 | else if (bitmap == 0) | 1249 | else if (bitmap == 0) |
1250 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; | 1250 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; |
1251 | 1251 | ||
1252 | reiserfs_write_unlock(sb); | ||
1252 | bh = sb_bread(sb, block); | 1253 | bh = sb_bread(sb, block); |
1254 | reiserfs_write_lock(sb); | ||
1253 | if (bh == NULL) | 1255 | if (bh == NULL) |
1254 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " | 1256 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) " |
1255 | "reading failed", __func__, block); | 1257 | "reading failed", __func__, block); |
1256 | else { | 1258 | else { |
1257 | if (buffer_locked(bh)) { | 1259 | if (buffer_locked(bh)) { |
1258 | PROC_INFO_INC(sb, scan_bitmap.wait); | 1260 | PROC_INFO_INC(sb, scan_bitmap.wait); |
1261 | reiserfs_write_unlock(sb); | ||
1259 | __wait_on_buffer(bh); | 1262 | __wait_on_buffer(bh); |
1263 | reiserfs_write_lock(sb); | ||
1260 | } | 1264 | } |
1261 | BUG_ON(!buffer_uptodate(bh)); | 1265 | BUG_ON(!buffer_uptodate(bh)); |
1262 | BUG_ON(atomic_read(&bh->b_count) == 0); | 1266 | BUG_ON(atomic_read(&bh->b_count) == 0); |
@@ -1273,7 +1277,10 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
1273 | struct reiserfs_bitmap_info *bitmap; | 1277 | struct reiserfs_bitmap_info *bitmap; |
1274 | unsigned int bmap_nr = reiserfs_bmap_count(sb); | 1278 | unsigned int bmap_nr = reiserfs_bmap_count(sb); |
1275 | 1279 | ||
1280 | /* Avoid lock recursion in fault case */ | ||
1281 | reiserfs_write_unlock(sb); | ||
1276 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); | 1282 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); |
1283 | reiserfs_write_lock(sb); | ||
1277 | if (bitmap == NULL) | 1284 | if (bitmap == NULL) |
1278 | return -ENOMEM; | 1285 | return -ENOMEM; |
1279 | 1286 | ||
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 6d2668fdc384..07930449a958 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/reiserfs_fs.h> | 8 | #include <linux/reiserfs_fs.h> |
9 | #include <linux/stat.h> | 9 | #include <linux/stat.h> |
10 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
11 | #include <linux/slab.h> | ||
11 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
12 | 13 | ||
13 | extern const struct reiserfs_key MIN_KEY; | 14 | extern const struct reiserfs_key MIN_KEY; |
@@ -20,7 +21,7 @@ const struct file_operations reiserfs_dir_operations = { | |||
20 | .read = generic_read_dir, | 21 | .read = generic_read_dir, |
21 | .readdir = reiserfs_readdir, | 22 | .readdir = reiserfs_readdir, |
22 | .fsync = reiserfs_dir_fsync, | 23 | .fsync = reiserfs_dir_fsync, |
23 | .ioctl = reiserfs_ioctl, | 24 | .unlocked_ioctl = reiserfs_ioctl, |
24 | #ifdef CONFIG_COMPAT | 25 | #ifdef CONFIG_COMPAT |
25 | .compat_ioctl = reiserfs_compat_ioctl, | 26 | .compat_ioctl = reiserfs_compat_ioctl, |
26 | #endif | 27 | #endif |
@@ -45,8 +46,6 @@ static inline bool is_privroot_deh(struct dentry *dir, | |||
45 | struct reiserfs_de_head *deh) | 46 | struct reiserfs_de_head *deh) |
46 | { | 47 | { |
47 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; | 48 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; |
48 | if (reiserfs_expose_privroot(dir->d_sb)) | ||
49 | return 0; | ||
50 | return (dir == dir->d_parent && privroot->d_inode && | 49 | return (dir == dir->d_parent && privroot->d_inode && |
51 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); | 50 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); |
52 | } | 51 | } |
@@ -174,14 +173,22 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
174 | // user space buffer is swapped out. At that time | 173 | // user space buffer is swapped out. At that time |
175 | // entry can move to somewhere else | 174 | // entry can move to somewhere else |
176 | memcpy(local_buf, d_name, d_reclen); | 175 | memcpy(local_buf, d_name, d_reclen); |
176 | |||
177 | /* | ||
178 | * Since filldir might sleep, we can release | ||
179 | * the write lock here for other waiters | ||
180 | */ | ||
181 | reiserfs_write_unlock(inode->i_sb); | ||
177 | if (filldir | 182 | if (filldir |
178 | (dirent, local_buf, d_reclen, d_off, d_ino, | 183 | (dirent, local_buf, d_reclen, d_off, d_ino, |
179 | DT_UNKNOWN) < 0) { | 184 | DT_UNKNOWN) < 0) { |
185 | reiserfs_write_lock(inode->i_sb); | ||
180 | if (local_buf != small_buf) { | 186 | if (local_buf != small_buf) { |
181 | kfree(local_buf); | 187 | kfree(local_buf); |
182 | } | 188 | } |
183 | goto end; | 189 | goto end; |
184 | } | 190 | } |
191 | reiserfs_write_lock(inode->i_sb); | ||
185 | if (local_buf != small_buf) { | 192 | if (local_buf != small_buf) { |
186 | kfree(local_buf); | 193 | kfree(local_buf); |
187 | } | 194 | } |
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 128d3f7c8aa5..60c080440661 100644 --- a/fs/reiserfs/do_balan.c +++ b/fs/reiserfs/do_balan.c | |||
@@ -21,14 +21,6 @@ | |||
21 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | 23 | ||
24 | #ifdef CONFIG_REISERFS_CHECK | ||
25 | |||
26 | struct tree_balance *cur_tb = NULL; /* detects whether more than one | ||
27 | copy of tb exists as a means | ||
28 | of checking whether schedule | ||
29 | is interrupting do_balance */ | ||
30 | #endif | ||
31 | |||
32 | static inline void buffer_info_init_left(struct tree_balance *tb, | 24 | static inline void buffer_info_init_left(struct tree_balance *tb, |
33 | struct buffer_info *bi) | 25 | struct buffer_info *bi) |
34 | { | 26 | { |
@@ -1840,11 +1832,12 @@ static int check_before_balancing(struct tree_balance *tb) | |||
1840 | { | 1832 | { |
1841 | int retval = 0; | 1833 | int retval = 0; |
1842 | 1834 | ||
1843 | if (cur_tb) { | 1835 | if (REISERFS_SB(tb->tb_sb)->cur_tb) { |
1844 | reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule " | 1836 | reiserfs_panic(tb->tb_sb, "vs-12335", "suspect that schedule " |
1845 | "occurred based on cur_tb not being null at " | 1837 | "occurred based on cur_tb not being null at " |
1846 | "this point in code. do_balance cannot properly " | 1838 | "this point in code. do_balance cannot properly " |
1847 | "handle schedule occurring while it runs."); | 1839 | "handle concurrent tree accesses on a same " |
1840 | "mount point."); | ||
1848 | } | 1841 | } |
1849 | 1842 | ||
1850 | /* double check that buffers that we will modify are unlocked. (fix_nodes should already have | 1843 | /* double check that buffers that we will modify are unlocked. (fix_nodes should already have |
@@ -1986,7 +1979,7 @@ static inline void do_balance_starts(struct tree_balance *tb) | |||
1986 | "check");*/ | 1979 | "check");*/ |
1987 | RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB"); | 1980 | RFALSE(check_before_balancing(tb), "PAP-12340: locked buffers in TB"); |
1988 | #ifdef CONFIG_REISERFS_CHECK | 1981 | #ifdef CONFIG_REISERFS_CHECK |
1989 | cur_tb = tb; | 1982 | REISERFS_SB(tb->tb_sb)->cur_tb = tb; |
1990 | #endif | 1983 | #endif |
1991 | } | 1984 | } |
1992 | 1985 | ||
@@ -1996,7 +1989,7 @@ static inline void do_balance_completed(struct tree_balance *tb) | |||
1996 | #ifdef CONFIG_REISERFS_CHECK | 1989 | #ifdef CONFIG_REISERFS_CHECK |
1997 | check_leaf_level(tb); | 1990 | check_leaf_level(tb); |
1998 | check_internal_levels(tb); | 1991 | check_internal_levels(tb); |
1999 | cur_tb = NULL; | 1992 | REISERFS_SB(tb->tb_sb)->cur_tb = NULL; |
2000 | #endif | 1993 | #endif |
2001 | 1994 | ||
2002 | /* reiserfs_free_block is no longer schedule safe. So, we need to | 1995 | /* reiserfs_free_block is no longer schedule safe. So, we need to |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 9f436668b7f8..1d9c12714c5c 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -284,12 +284,12 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
284 | const struct file_operations reiserfs_file_operations = { | 284 | const struct file_operations reiserfs_file_operations = { |
285 | .read = do_sync_read, | 285 | .read = do_sync_read, |
286 | .write = reiserfs_file_write, | 286 | .write = reiserfs_file_write, |
287 | .ioctl = reiserfs_ioctl, | 287 | .unlocked_ioctl = reiserfs_ioctl, |
288 | #ifdef CONFIG_COMPAT | 288 | #ifdef CONFIG_COMPAT |
289 | .compat_ioctl = reiserfs_compat_ioctl, | 289 | .compat_ioctl = reiserfs_compat_ioctl, |
290 | #endif | 290 | #endif |
291 | .mmap = reiserfs_file_mmap, | 291 | .mmap = reiserfs_file_mmap, |
292 | .open = generic_file_open, | 292 | .open = dquot_file_open, |
293 | .release = reiserfs_file_release, | 293 | .release = reiserfs_file_release, |
294 | .fsync = reiserfs_sync_file, | 294 | .fsync = reiserfs_sync_file, |
295 | .aio_read = generic_file_aio_read, | 295 | .aio_read = generic_file_aio_read, |
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c index 5e5a4e6fbaf8..1e4250bc3a6f 100644 --- a/fs/reiserfs/fix_node.c +++ b/fs/reiserfs/fix_node.c | |||
@@ -35,6 +35,7 @@ | |||
35 | **/ | 35 | **/ |
36 | 36 | ||
37 | #include <linux/time.h> | 37 | #include <linux/time.h> |
38 | #include <linux/slab.h> | ||
38 | #include <linux/string.h> | 39 | #include <linux/string.h> |
39 | #include <linux/reiserfs_fs.h> | 40 | #include <linux/reiserfs_fs.h> |
40 | #include <linux/buffer_head.h> | 41 | #include <linux/buffer_head.h> |
@@ -563,9 +564,6 @@ static int get_num_ver(int mode, struct tree_balance *tb, int h, | |||
563 | return needed_nodes; | 564 | return needed_nodes; |
564 | } | 565 | } |
565 | 566 | ||
566 | #ifdef CONFIG_REISERFS_CHECK | ||
567 | extern struct tree_balance *cur_tb; | ||
568 | #endif | ||
569 | 567 | ||
570 | /* Set parameters for balancing. | 568 | /* Set parameters for balancing. |
571 | * Performs write of results of analysis of balancing into structure tb, | 569 | * Performs write of results of analysis of balancing into structure tb, |
@@ -834,7 +832,7 @@ static int get_empty_nodes(struct tree_balance *tb, int h) | |||
834 | RFALSE(buffer_dirty(new_bh) || | 832 | RFALSE(buffer_dirty(new_bh) || |
835 | buffer_journaled(new_bh) || | 833 | buffer_journaled(new_bh) || |
836 | buffer_journal_dirty(new_bh), | 834 | buffer_journal_dirty(new_bh), |
837 | "PAP-8140: journlaled or dirty buffer %b for the new block", | 835 | "PAP-8140: journaled or dirty buffer %b for the new block", |
838 | new_bh); | 836 | new_bh); |
839 | 837 | ||
840 | /* Put empty buffers into the array. */ | 838 | /* Put empty buffers into the array. */ |
@@ -1022,7 +1020,11 @@ static int get_far_parent(struct tree_balance *tb, | |||
1022 | /* Check whether the common parent is locked. */ | 1020 | /* Check whether the common parent is locked. */ |
1023 | 1021 | ||
1024 | if (buffer_locked(*pcom_father)) { | 1022 | if (buffer_locked(*pcom_father)) { |
1023 | |||
1024 | /* Release the write lock while the buffer is busy */ | ||
1025 | reiserfs_write_unlock(tb->tb_sb); | ||
1025 | __wait_on_buffer(*pcom_father); | 1026 | __wait_on_buffer(*pcom_father); |
1027 | reiserfs_write_lock(tb->tb_sb); | ||
1026 | if (FILESYSTEM_CHANGED_TB(tb)) { | 1028 | if (FILESYSTEM_CHANGED_TB(tb)) { |
1027 | brelse(*pcom_father); | 1029 | brelse(*pcom_father); |
1028 | return REPEAT_SEARCH; | 1030 | return REPEAT_SEARCH; |
@@ -1927,7 +1929,9 @@ static int get_direct_parent(struct tree_balance *tb, int h) | |||
1927 | return REPEAT_SEARCH; | 1929 | return REPEAT_SEARCH; |
1928 | 1930 | ||
1929 | if (buffer_locked(bh)) { | 1931 | if (buffer_locked(bh)) { |
1932 | reiserfs_write_unlock(tb->tb_sb); | ||
1930 | __wait_on_buffer(bh); | 1933 | __wait_on_buffer(bh); |
1934 | reiserfs_write_lock(tb->tb_sb); | ||
1931 | if (FILESYSTEM_CHANGED_TB(tb)) | 1935 | if (FILESYSTEM_CHANGED_TB(tb)) |
1932 | return REPEAT_SEARCH; | 1936 | return REPEAT_SEARCH; |
1933 | } | 1937 | } |
@@ -1965,7 +1969,9 @@ static int get_neighbors(struct tree_balance *tb, int h) | |||
1965 | tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb-> | 1969 | tb->FL[h]) ? tb->lkey[h] : B_NR_ITEMS(tb-> |
1966 | FL[h]); | 1970 | FL[h]); |
1967 | son_number = B_N_CHILD_NUM(tb->FL[h], child_position); | 1971 | son_number = B_N_CHILD_NUM(tb->FL[h], child_position); |
1972 | reiserfs_write_unlock(sb); | ||
1968 | bh = sb_bread(sb, son_number); | 1973 | bh = sb_bread(sb, son_number); |
1974 | reiserfs_write_lock(sb); | ||
1969 | if (!bh) | 1975 | if (!bh) |
1970 | return IO_ERROR; | 1976 | return IO_ERROR; |
1971 | if (FILESYSTEM_CHANGED_TB(tb)) { | 1977 | if (FILESYSTEM_CHANGED_TB(tb)) { |
@@ -2003,7 +2009,9 @@ static int get_neighbors(struct tree_balance *tb, int h) | |||
2003 | child_position = | 2009 | child_position = |
2004 | (bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0; | 2010 | (bh == tb->FR[h]) ? tb->rkey[h] + 1 : 0; |
2005 | son_number = B_N_CHILD_NUM(tb->FR[h], child_position); | 2011 | son_number = B_N_CHILD_NUM(tb->FR[h], child_position); |
2012 | reiserfs_write_unlock(sb); | ||
2006 | bh = sb_bread(sb, son_number); | 2013 | bh = sb_bread(sb, son_number); |
2014 | reiserfs_write_lock(sb); | ||
2007 | if (!bh) | 2015 | if (!bh) |
2008 | return IO_ERROR; | 2016 | return IO_ERROR; |
2009 | if (FILESYSTEM_CHANGED_TB(tb)) { | 2017 | if (FILESYSTEM_CHANGED_TB(tb)) { |
@@ -2278,7 +2286,9 @@ static int wait_tb_buffers_until_unlocked(struct tree_balance *tb) | |||
2278 | REPEAT_SEARCH : CARRY_ON; | 2286 | REPEAT_SEARCH : CARRY_ON; |
2279 | } | 2287 | } |
2280 | #endif | 2288 | #endif |
2289 | reiserfs_write_unlock(tb->tb_sb); | ||
2281 | __wait_on_buffer(locked); | 2290 | __wait_on_buffer(locked); |
2291 | reiserfs_write_lock(tb->tb_sb); | ||
2282 | if (FILESYSTEM_CHANGED_TB(tb)) | 2292 | if (FILESYSTEM_CHANGED_TB(tb)) |
2283 | return REPEAT_SEARCH; | 2293 | return REPEAT_SEARCH; |
2284 | } | 2294 | } |
@@ -2349,12 +2359,14 @@ int fix_nodes(int op_mode, struct tree_balance *tb, | |||
2349 | 2359 | ||
2350 | /* if it possible in indirect_to_direct conversion */ | 2360 | /* if it possible in indirect_to_direct conversion */ |
2351 | if (buffer_locked(tbS0)) { | 2361 | if (buffer_locked(tbS0)) { |
2362 | reiserfs_write_unlock(tb->tb_sb); | ||
2352 | __wait_on_buffer(tbS0); | 2363 | __wait_on_buffer(tbS0); |
2364 | reiserfs_write_lock(tb->tb_sb); | ||
2353 | if (FILESYSTEM_CHANGED_TB(tb)) | 2365 | if (FILESYSTEM_CHANGED_TB(tb)) |
2354 | return REPEAT_SEARCH; | 2366 | return REPEAT_SEARCH; |
2355 | } | 2367 | } |
2356 | #ifdef CONFIG_REISERFS_CHECK | 2368 | #ifdef CONFIG_REISERFS_CHECK |
2357 | if (cur_tb) { | 2369 | if (REISERFS_SB(tb->tb_sb)->cur_tb) { |
2358 | print_cur_tb("fix_nodes"); | 2370 | print_cur_tb("fix_nodes"); |
2359 | reiserfs_panic(tb->tb_sb, "PAP-8305", | 2371 | reiserfs_panic(tb->tb_sb, "PAP-8305", |
2360 | "there is pending do_balance"); | 2372 | "there is pending do_balance"); |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index a14d6cd9eeda..dc2c65e04853 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/smp_lock.h> | 11 | #include <linux/smp_lock.h> |
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/highmem.h> | 13 | #include <linux/highmem.h> |
14 | #include <linux/slab.h> | ||
14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
15 | #include <asm/unaligned.h> | 16 | #include <asm/unaligned.h> |
16 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
@@ -31,11 +32,15 @@ void reiserfs_delete_inode(struct inode *inode) | |||
31 | JOURNAL_PER_BALANCE_CNT * 2 + | 32 | JOURNAL_PER_BALANCE_CNT * 2 + |
32 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); | 33 | 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); |
33 | struct reiserfs_transaction_handle th; | 34 | struct reiserfs_transaction_handle th; |
35 | int depth; | ||
34 | int err; | 36 | int err; |
35 | 37 | ||
38 | if (!is_bad_inode(inode)) | ||
39 | dquot_initialize(inode); | ||
40 | |||
36 | truncate_inode_pages(&inode->i_data, 0); | 41 | truncate_inode_pages(&inode->i_data, 0); |
37 | 42 | ||
38 | reiserfs_write_lock(inode->i_sb); | 43 | depth = reiserfs_write_lock_once(inode->i_sb); |
39 | 44 | ||
40 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ | 45 | /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ |
41 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ | 46 | if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ |
@@ -53,7 +58,7 @@ void reiserfs_delete_inode(struct inode *inode) | |||
53 | * after delete_object so that quota updates go into the same transaction as | 58 | * after delete_object so that quota updates go into the same transaction as |
54 | * stat data deletion */ | 59 | * stat data deletion */ |
55 | if (!err) | 60 | if (!err) |
56 | vfs_dq_free_inode(inode); | 61 | dquot_free_inode(inode); |
57 | 62 | ||
58 | if (journal_end(&th, inode->i_sb, jbegin_count)) | 63 | if (journal_end(&th, inode->i_sb, jbegin_count)) |
59 | goto out; | 64 | goto out; |
@@ -74,7 +79,7 @@ void reiserfs_delete_inode(struct inode *inode) | |||
74 | out: | 79 | out: |
75 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ | 80 | clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */ |
76 | inode->i_blocks = 0; | 81 | inode->i_blocks = 0; |
77 | reiserfs_write_unlock(inode->i_sb); | 82 | reiserfs_write_unlock_once(inode->i_sb, depth); |
78 | } | 83 | } |
79 | 84 | ||
80 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, | 85 | static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, |
@@ -251,7 +256,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
251 | struct cpu_key key; | 256 | struct cpu_key key; |
252 | struct buffer_head *bh; | 257 | struct buffer_head *bh; |
253 | struct item_head *ih, tmp_ih; | 258 | struct item_head *ih, tmp_ih; |
254 | int fs_gen; | ||
255 | b_blocknr_t blocknr; | 259 | b_blocknr_t blocknr; |
256 | char *p = NULL; | 260 | char *p = NULL; |
257 | int chars; | 261 | int chars; |
@@ -265,7 +269,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
265 | (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, | 269 | (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, |
266 | 3); | 270 | 3); |
267 | 271 | ||
268 | research: | ||
269 | result = search_for_position_by_key(inode->i_sb, &key, &path); | 272 | result = search_for_position_by_key(inode->i_sb, &key, &path); |
270 | if (result != POSITION_FOUND) { | 273 | if (result != POSITION_FOUND) { |
271 | pathrelse(&path); | 274 | pathrelse(&path); |
@@ -340,7 +343,6 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
340 | } | 343 | } |
341 | // read file tail into part of page | 344 | // read file tail into part of page |
342 | offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1); | 345 | offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1); |
343 | fs_gen = get_generation(inode->i_sb); | ||
344 | copy_item_head(&tmp_ih, ih); | 346 | copy_item_head(&tmp_ih, ih); |
345 | 347 | ||
346 | /* we only want to kmap if we are reading the tail into the page. | 348 | /* we only want to kmap if we are reading the tail into the page. |
@@ -348,13 +350,9 @@ static int _get_block_create_0(struct inode *inode, sector_t block, | |||
348 | ** sure we need to. But, this means the item might move if | 350 | ** sure we need to. But, this means the item might move if |
349 | ** kmap schedules | 351 | ** kmap schedules |
350 | */ | 352 | */ |
351 | if (!p) { | 353 | if (!p) |
352 | p = (char *)kmap(bh_result->b_page); | 354 | p = (char *)kmap(bh_result->b_page); |
353 | if (fs_changed(fs_gen, inode->i_sb) | 355 | |
354 | && item_moved(&tmp_ih, &path)) { | ||
355 | goto research; | ||
356 | } | ||
357 | } | ||
358 | p += offset; | 356 | p += offset; |
359 | memset(p, 0, inode->i_sb->s_blocksize); | 357 | memset(p, 0, inode->i_sb->s_blocksize); |
360 | do { | 358 | do { |
@@ -489,10 +487,14 @@ static int reiserfs_get_blocks_direct_io(struct inode *inode, | |||
489 | disappeared */ | 487 | disappeared */ |
490 | if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { | 488 | if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { |
491 | int err; | 489 | int err; |
492 | lock_kernel(); | 490 | |
491 | reiserfs_write_lock(inode->i_sb); | ||
492 | |||
493 | err = reiserfs_commit_for_inode(inode); | 493 | err = reiserfs_commit_for_inode(inode); |
494 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 494 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
495 | unlock_kernel(); | 495 | |
496 | reiserfs_write_unlock(inode->i_sb); | ||
497 | |||
496 | if (err < 0) | 498 | if (err < 0) |
497 | ret = err; | 499 | ret = err; |
498 | } | 500 | } |
@@ -601,6 +603,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
601 | __le32 *item; | 603 | __le32 *item; |
602 | int done; | 604 | int done; |
603 | int fs_gen; | 605 | int fs_gen; |
606 | int lock_depth; | ||
604 | struct reiserfs_transaction_handle *th = NULL; | 607 | struct reiserfs_transaction_handle *th = NULL; |
605 | /* space reserved in transaction batch: | 608 | /* space reserved in transaction batch: |
606 | . 3 balancings in direct->indirect conversion | 609 | . 3 balancings in direct->indirect conversion |
@@ -616,12 +619,11 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
616 | loff_t new_offset = | 619 | loff_t new_offset = |
617 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; | 620 | (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; |
618 | 621 | ||
619 | /* bad.... */ | 622 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
620 | reiserfs_write_lock(inode->i_sb); | ||
621 | version = get_inode_item_key_version(inode); | 623 | version = get_inode_item_key_version(inode); |
622 | 624 | ||
623 | if (!file_capable(inode, block)) { | 625 | if (!file_capable(inode, block)) { |
624 | reiserfs_write_unlock(inode->i_sb); | 626 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
625 | return -EFBIG; | 627 | return -EFBIG; |
626 | } | 628 | } |
627 | 629 | ||
@@ -633,7 +635,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
633 | /* find number of block-th logical block of the file */ | 635 | /* find number of block-th logical block of the file */ |
634 | ret = _get_block_create_0(inode, block, bh_result, | 636 | ret = _get_block_create_0(inode, block, bh_result, |
635 | create | GET_BLOCK_READ_DIRECT); | 637 | create | GET_BLOCK_READ_DIRECT); |
636 | reiserfs_write_unlock(inode->i_sb); | 638 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
637 | return ret; | 639 | return ret; |
638 | } | 640 | } |
639 | /* | 641 | /* |
@@ -751,7 +753,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
751 | if (!dangle && th) | 753 | if (!dangle && th) |
752 | retval = reiserfs_end_persistent_transaction(th); | 754 | retval = reiserfs_end_persistent_transaction(th); |
753 | 755 | ||
754 | reiserfs_write_unlock(inode->i_sb); | 756 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
755 | 757 | ||
756 | /* the item was found, so new blocks were not added to the file | 758 | /* the item was found, so new blocks were not added to the file |
757 | ** there is no need to make sure the inode is updated with this | 759 | ** there is no need to make sure the inode is updated with this |
@@ -935,7 +937,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
935 | if (blocks_needed == 1) { | 937 | if (blocks_needed == 1) { |
936 | un = &unf_single; | 938 | un = &unf_single; |
937 | } else { | 939 | } else { |
938 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. | 940 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_NOFS); |
939 | if (!un) { | 941 | if (!un) { |
940 | un = &unf_single; | 942 | un = &unf_single; |
941 | blocks_needed = 1; | 943 | blocks_needed = 1; |
@@ -997,10 +999,16 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
997 | if (retval) | 999 | if (retval) |
998 | goto failure; | 1000 | goto failure; |
999 | } | 1001 | } |
1000 | /* inserting indirect pointers for a hole can take a | 1002 | /* |
1001 | ** long time. reschedule if needed | 1003 | * inserting indirect pointers for a hole can take a |
1004 | * long time. reschedule if needed and also release the write | ||
1005 | * lock for others. | ||
1002 | */ | 1006 | */ |
1003 | cond_resched(); | 1007 | if (need_resched()) { |
1008 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
1009 | schedule(); | ||
1010 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | ||
1011 | } | ||
1004 | 1012 | ||
1005 | retval = search_for_position_by_key(inode->i_sb, &key, &path); | 1013 | retval = search_for_position_by_key(inode->i_sb, &key, &path); |
1006 | if (retval == IO_ERROR) { | 1014 | if (retval == IO_ERROR) { |
@@ -1035,7 +1043,7 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
1035 | retval = err; | 1043 | retval = err; |
1036 | } | 1044 | } |
1037 | 1045 | ||
1038 | reiserfs_write_unlock(inode->i_sb); | 1046 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
1039 | reiserfs_check_path(&path); | 1047 | reiserfs_check_path(&path); |
1040 | return retval; | 1048 | return retval; |
1041 | } | 1049 | } |
@@ -1493,9 +1501,11 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key) | |||
1493 | 1501 | ||
1494 | args.objectid = key->on_disk_key.k_objectid; | 1502 | args.objectid = key->on_disk_key.k_objectid; |
1495 | args.dirid = key->on_disk_key.k_dir_id; | 1503 | args.dirid = key->on_disk_key.k_dir_id; |
1504 | reiserfs_write_unlock(s); | ||
1496 | inode = iget5_locked(s, key->on_disk_key.k_objectid, | 1505 | inode = iget5_locked(s, key->on_disk_key.k_objectid, |
1497 | reiserfs_find_actor, reiserfs_init_locked_inode, | 1506 | reiserfs_find_actor, reiserfs_init_locked_inode, |
1498 | (void *)(&args)); | 1507 | (void *)(&args)); |
1508 | reiserfs_write_lock(s); | ||
1499 | if (!inode) | 1509 | if (!inode) |
1500 | return ERR_PTR(-ENOMEM); | 1510 | return ERR_PTR(-ENOMEM); |
1501 | 1511 | ||
@@ -1609,7 +1619,7 @@ int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, | |||
1609 | ** to properly mark inodes for datasync and such, but only actually | 1619 | ** to properly mark inodes for datasync and such, but only actually |
1610 | ** does something when called for a synchronous update. | 1620 | ** does something when called for a synchronous update. |
1611 | */ | 1621 | */ |
1612 | int reiserfs_write_inode(struct inode *inode, int do_sync) | 1622 | int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1613 | { | 1623 | { |
1614 | struct reiserfs_transaction_handle th; | 1624 | struct reiserfs_transaction_handle th; |
1615 | int jbegin_count = 1; | 1625 | int jbegin_count = 1; |
@@ -1621,7 +1631,7 @@ int reiserfs_write_inode(struct inode *inode, int do_sync) | |||
1621 | ** inode needs to reach disk for safety, and they can safely be | 1631 | ** inode needs to reach disk for safety, and they can safely be |
1622 | ** ignored because the altered inode has already been logged. | 1632 | ** ignored because the altered inode has already been logged. |
1623 | */ | 1633 | */ |
1624 | if (do_sync && !(current->flags & PF_MEMALLOC)) { | 1634 | if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) { |
1625 | reiserfs_write_lock(inode->i_sb); | 1635 | reiserfs_write_lock(inode->i_sb); |
1626 | if (!journal_begin(&th, inode->i_sb, jbegin_count)) { | 1636 | if (!journal_begin(&th, inode->i_sb, jbegin_count)) { |
1627 | reiserfs_update_sd(&th, inode); | 1637 | reiserfs_update_sd(&th, inode); |
@@ -1759,10 +1769,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1759 | 1769 | ||
1760 | BUG_ON(!th->t_trans_id); | 1770 | BUG_ON(!th->t_trans_id); |
1761 | 1771 | ||
1762 | if (vfs_dq_alloc_inode(inode)) { | 1772 | dquot_initialize(inode); |
1763 | err = -EDQUOT; | 1773 | err = dquot_alloc_inode(inode); |
1774 | if (err) | ||
1764 | goto out_end_trans; | 1775 | goto out_end_trans; |
1765 | } | ||
1766 | if (!dir->i_nlink) { | 1776 | if (!dir->i_nlink) { |
1767 | err = -EPERM; | 1777 | err = -EPERM; |
1768 | goto out_bad_inode; | 1778 | goto out_bad_inode; |
@@ -1953,12 +1963,12 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1953 | INODE_PKEY(inode)->k_objectid = 0; | 1963 | INODE_PKEY(inode)->k_objectid = 0; |
1954 | 1964 | ||
1955 | /* Quota change must be inside a transaction for journaling */ | 1965 | /* Quota change must be inside a transaction for journaling */ |
1956 | vfs_dq_free_inode(inode); | 1966 | dquot_free_inode(inode); |
1957 | 1967 | ||
1958 | out_end_trans: | 1968 | out_end_trans: |
1959 | journal_end(th, th->t_super, th->t_blocks_allocated); | 1969 | journal_end(th, th->t_super, th->t_blocks_allocated); |
1960 | /* Drop can be outside and it needs more credits so it's better to have it outside */ | 1970 | /* Drop can be outside and it needs more credits so it's better to have it outside */ |
1961 | vfs_dq_drop(inode); | 1971 | dquot_drop(inode); |
1962 | inode->i_flags |= S_NOQUOTA; | 1972 | inode->i_flags |= S_NOQUOTA; |
1963 | make_bad_inode(inode); | 1973 | make_bad_inode(inode); |
1964 | 1974 | ||
@@ -2072,8 +2082,9 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2072 | int error; | 2082 | int error; |
2073 | struct buffer_head *bh = NULL; | 2083 | struct buffer_head *bh = NULL; |
2074 | int err2; | 2084 | int err2; |
2085 | int lock_depth; | ||
2075 | 2086 | ||
2076 | reiserfs_write_lock(inode->i_sb); | 2087 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
2077 | 2088 | ||
2078 | if (inode->i_size > 0) { | 2089 | if (inode->i_size > 0) { |
2079 | error = grab_tail_page(inode, &page, &bh); | 2090 | error = grab_tail_page(inode, &page, &bh); |
@@ -2142,14 +2153,17 @@ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) | |||
2142 | page_cache_release(page); | 2153 | page_cache_release(page); |
2143 | } | 2154 | } |
2144 | 2155 | ||
2145 | reiserfs_write_unlock(inode->i_sb); | 2156 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); |
2157 | |||
2146 | return 0; | 2158 | return 0; |
2147 | out: | 2159 | out: |
2148 | if (page) { | 2160 | if (page) { |
2149 | unlock_page(page); | 2161 | unlock_page(page); |
2150 | page_cache_release(page); | 2162 | page_cache_release(page); |
2151 | } | 2163 | } |
2152 | reiserfs_write_unlock(inode->i_sb); | 2164 | |
2165 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2166 | |||
2153 | return error; | 2167 | return error; |
2154 | } | 2168 | } |
2155 | 2169 | ||
@@ -2531,6 +2545,12 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc) | |||
2531 | return reiserfs_write_full_page(page, wbc); | 2545 | return reiserfs_write_full_page(page, wbc); |
2532 | } | 2546 | } |
2533 | 2547 | ||
2548 | static void reiserfs_truncate_failed_write(struct inode *inode) | ||
2549 | { | ||
2550 | truncate_inode_pages(inode->i_mapping, inode->i_size); | ||
2551 | reiserfs_truncate_file(inode, 0); | ||
2552 | } | ||
2553 | |||
2534 | static int reiserfs_write_begin(struct file *file, | 2554 | static int reiserfs_write_begin(struct file *file, |
2535 | struct address_space *mapping, | 2555 | struct address_space *mapping, |
2536 | loff_t pos, unsigned len, unsigned flags, | 2556 | loff_t pos, unsigned len, unsigned flags, |
@@ -2597,6 +2617,8 @@ static int reiserfs_write_begin(struct file *file, | |||
2597 | if (ret) { | 2617 | if (ret) { |
2598 | unlock_page(page); | 2618 | unlock_page(page); |
2599 | page_cache_release(page); | 2619 | page_cache_release(page); |
2620 | /* Truncate allocated blocks */ | ||
2621 | reiserfs_truncate_failed_write(inode); | ||
2600 | } | 2622 | } |
2601 | return ret; | 2623 | return ret; |
2602 | } | 2624 | } |
@@ -2608,7 +2630,10 @@ int reiserfs_prepare_write(struct file *f, struct page *page, | |||
2608 | int ret; | 2630 | int ret; |
2609 | int old_ref = 0; | 2631 | int old_ref = 0; |
2610 | 2632 | ||
2633 | reiserfs_write_unlock(inode->i_sb); | ||
2611 | reiserfs_wait_on_write_block(inode->i_sb); | 2634 | reiserfs_wait_on_write_block(inode->i_sb); |
2635 | reiserfs_write_lock(inode->i_sb); | ||
2636 | |||
2612 | fix_tail_page_for_writing(page); | 2637 | fix_tail_page_for_writing(page); |
2613 | if (reiserfs_transaction_running(inode->i_sb)) { | 2638 | if (reiserfs_transaction_running(inode->i_sb)) { |
2614 | struct reiserfs_transaction_handle *th; | 2639 | struct reiserfs_transaction_handle *th; |
@@ -2664,6 +2689,8 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2664 | int update_sd = 0; | 2689 | int update_sd = 0; |
2665 | struct reiserfs_transaction_handle *th; | 2690 | struct reiserfs_transaction_handle *th; |
2666 | unsigned start; | 2691 | unsigned start; |
2692 | int lock_depth = 0; | ||
2693 | bool locked = false; | ||
2667 | 2694 | ||
2668 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) | 2695 | if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND) |
2669 | pos ++; | 2696 | pos ++; |
@@ -2689,10 +2716,10 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2689 | ** transaction tracking stuff when the size changes. So, we have | 2716 | ** transaction tracking stuff when the size changes. So, we have |
2690 | ** to do the i_size updates here. | 2717 | ** to do the i_size updates here. |
2691 | */ | 2718 | */ |
2692 | pos += copied; | 2719 | if (pos + copied > inode->i_size) { |
2693 | if (pos > inode->i_size) { | ||
2694 | struct reiserfs_transaction_handle myth; | 2720 | struct reiserfs_transaction_handle myth; |
2695 | reiserfs_write_lock(inode->i_sb); | 2721 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
2722 | locked = true; | ||
2696 | /* If the file have grown beyond the border where it | 2723 | /* If the file have grown beyond the border where it |
2697 | can have a tail, unmark it as needing a tail | 2724 | can have a tail, unmark it as needing a tail |
2698 | packing */ | 2725 | packing */ |
@@ -2703,12 +2730,11 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2703 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 2730 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
2704 | 2731 | ||
2705 | ret = journal_begin(&myth, inode->i_sb, 1); | 2732 | ret = journal_begin(&myth, inode->i_sb, 1); |
2706 | if (ret) { | 2733 | if (ret) |
2707 | reiserfs_write_unlock(inode->i_sb); | ||
2708 | goto journal_error; | 2734 | goto journal_error; |
2709 | } | 2735 | |
2710 | reiserfs_update_inode_transaction(inode); | 2736 | reiserfs_update_inode_transaction(inode); |
2711 | inode->i_size = pos; | 2737 | inode->i_size = pos + copied; |
2712 | /* | 2738 | /* |
2713 | * this will just nest into our transaction. It's important | 2739 | * this will just nest into our transaction. It's important |
2714 | * to use mark_inode_dirty so the inode gets pushed around on the | 2740 | * to use mark_inode_dirty so the inode gets pushed around on the |
@@ -2718,34 +2744,40 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping, | |||
2718 | reiserfs_update_sd(&myth, inode); | 2744 | reiserfs_update_sd(&myth, inode); |
2719 | update_sd = 1; | 2745 | update_sd = 1; |
2720 | ret = journal_end(&myth, inode->i_sb, 1); | 2746 | ret = journal_end(&myth, inode->i_sb, 1); |
2721 | reiserfs_write_unlock(inode->i_sb); | ||
2722 | if (ret) | 2747 | if (ret) |
2723 | goto journal_error; | 2748 | goto journal_error; |
2724 | } | 2749 | } |
2725 | if (th) { | 2750 | if (th) { |
2726 | reiserfs_write_lock(inode->i_sb); | 2751 | if (!locked) { |
2752 | lock_depth = reiserfs_write_lock_once(inode->i_sb); | ||
2753 | locked = true; | ||
2754 | } | ||
2727 | if (!update_sd) | 2755 | if (!update_sd) |
2728 | mark_inode_dirty(inode); | 2756 | mark_inode_dirty(inode); |
2729 | ret = reiserfs_end_persistent_transaction(th); | 2757 | ret = reiserfs_end_persistent_transaction(th); |
2730 | reiserfs_write_unlock(inode->i_sb); | ||
2731 | if (ret) | 2758 | if (ret) |
2732 | goto out; | 2759 | goto out; |
2733 | } | 2760 | } |
2734 | 2761 | ||
2735 | out: | 2762 | out: |
2763 | if (locked) | ||
2764 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2736 | unlock_page(page); | 2765 | unlock_page(page); |
2737 | page_cache_release(page); | 2766 | page_cache_release(page); |
2767 | |||
2768 | if (pos + len > inode->i_size) | ||
2769 | reiserfs_truncate_failed_write(inode); | ||
2770 | |||
2738 | return ret == 0 ? copied : ret; | 2771 | return ret == 0 ? copied : ret; |
2739 | 2772 | ||
2740 | journal_error: | 2773 | journal_error: |
2774 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
2775 | locked = false; | ||
2741 | if (th) { | 2776 | if (th) { |
2742 | reiserfs_write_lock(inode->i_sb); | ||
2743 | if (!update_sd) | 2777 | if (!update_sd) |
2744 | reiserfs_update_sd(th, inode); | 2778 | reiserfs_update_sd(th, inode); |
2745 | ret = reiserfs_end_persistent_transaction(th); | 2779 | ret = reiserfs_end_persistent_transaction(th); |
2746 | reiserfs_write_unlock(inode->i_sb); | ||
2747 | } | 2780 | } |
2748 | |||
2749 | goto out; | 2781 | goto out; |
2750 | } | 2782 | } |
2751 | 2783 | ||
@@ -2758,7 +2790,10 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2758 | int update_sd = 0; | 2790 | int update_sd = 0; |
2759 | struct reiserfs_transaction_handle *th = NULL; | 2791 | struct reiserfs_transaction_handle *th = NULL; |
2760 | 2792 | ||
2793 | reiserfs_write_unlock(inode->i_sb); | ||
2761 | reiserfs_wait_on_write_block(inode->i_sb); | 2794 | reiserfs_wait_on_write_block(inode->i_sb); |
2795 | reiserfs_write_lock(inode->i_sb); | ||
2796 | |||
2762 | if (reiserfs_transaction_running(inode->i_sb)) { | 2797 | if (reiserfs_transaction_running(inode->i_sb)) { |
2763 | th = current->journal_info; | 2798 | th = current->journal_info; |
2764 | } | 2799 | } |
@@ -2770,7 +2805,6 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2770 | */ | 2805 | */ |
2771 | if (pos > inode->i_size) { | 2806 | if (pos > inode->i_size) { |
2772 | struct reiserfs_transaction_handle myth; | 2807 | struct reiserfs_transaction_handle myth; |
2773 | reiserfs_write_lock(inode->i_sb); | ||
2774 | /* If the file have grown beyond the border where it | 2808 | /* If the file have grown beyond the border where it |
2775 | can have a tail, unmark it as needing a tail | 2809 | can have a tail, unmark it as needing a tail |
2776 | packing */ | 2810 | packing */ |
@@ -2781,10 +2815,9 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2781 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; | 2815 | REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; |
2782 | 2816 | ||
2783 | ret = journal_begin(&myth, inode->i_sb, 1); | 2817 | ret = journal_begin(&myth, inode->i_sb, 1); |
2784 | if (ret) { | 2818 | if (ret) |
2785 | reiserfs_write_unlock(inode->i_sb); | ||
2786 | goto journal_error; | 2819 | goto journal_error; |
2787 | } | 2820 | |
2788 | reiserfs_update_inode_transaction(inode); | 2821 | reiserfs_update_inode_transaction(inode); |
2789 | inode->i_size = pos; | 2822 | inode->i_size = pos; |
2790 | /* | 2823 | /* |
@@ -2796,16 +2829,13 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2796 | reiserfs_update_sd(&myth, inode); | 2829 | reiserfs_update_sd(&myth, inode); |
2797 | update_sd = 1; | 2830 | update_sd = 1; |
2798 | ret = journal_end(&myth, inode->i_sb, 1); | 2831 | ret = journal_end(&myth, inode->i_sb, 1); |
2799 | reiserfs_write_unlock(inode->i_sb); | ||
2800 | if (ret) | 2832 | if (ret) |
2801 | goto journal_error; | 2833 | goto journal_error; |
2802 | } | 2834 | } |
2803 | if (th) { | 2835 | if (th) { |
2804 | reiserfs_write_lock(inode->i_sb); | ||
2805 | if (!update_sd) | 2836 | if (!update_sd) |
2806 | mark_inode_dirty(inode); | 2837 | mark_inode_dirty(inode); |
2807 | ret = reiserfs_end_persistent_transaction(th); | 2838 | ret = reiserfs_end_persistent_transaction(th); |
2808 | reiserfs_write_unlock(inode->i_sb); | ||
2809 | if (ret) | 2839 | if (ret) |
2810 | goto out; | 2840 | goto out; |
2811 | } | 2841 | } |
@@ -2815,11 +2845,9 @@ int reiserfs_commit_write(struct file *f, struct page *page, | |||
2815 | 2845 | ||
2816 | journal_error: | 2846 | journal_error: |
2817 | if (th) { | 2847 | if (th) { |
2818 | reiserfs_write_lock(inode->i_sb); | ||
2819 | if (!update_sd) | 2848 | if (!update_sd) |
2820 | reiserfs_update_sd(th, inode); | 2849 | reiserfs_update_sd(th, inode); |
2821 | ret = reiserfs_end_persistent_transaction(th); | 2850 | ret = reiserfs_end_persistent_transaction(th); |
2822 | reiserfs_write_unlock(inode->i_sb); | ||
2823 | } | 2851 | } |
2824 | 2852 | ||
2825 | return ret; | 2853 | return ret; |
@@ -3040,14 +3068,17 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb, | |||
3040 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | 3068 | int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) |
3041 | { | 3069 | { |
3042 | struct inode *inode = dentry->d_inode; | 3070 | struct inode *inode = dentry->d_inode; |
3043 | int error; | ||
3044 | unsigned int ia_valid; | 3071 | unsigned int ia_valid; |
3072 | int depth; | ||
3073 | int error; | ||
3045 | 3074 | ||
3046 | /* must be turned off for recursive notify_change calls */ | 3075 | /* must be turned off for recursive notify_change calls */ |
3047 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | 3076 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); |
3048 | 3077 | ||
3049 | reiserfs_write_lock(inode->i_sb); | 3078 | depth = reiserfs_write_lock_once(inode->i_sb); |
3050 | if (attr->ia_valid & ATTR_SIZE) { | 3079 | if (attr->ia_valid & ATTR_SIZE) { |
3080 | dquot_initialize(inode); | ||
3081 | |||
3051 | /* version 2 items will be caught by the s_maxbytes check | 3082 | /* version 2 items will be caught by the s_maxbytes check |
3052 | ** done for us in vmtruncate | 3083 | ** done for us in vmtruncate |
3053 | */ | 3084 | */ |
@@ -3109,8 +3140,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3109 | jbegin_count); | 3140 | jbegin_count); |
3110 | if (error) | 3141 | if (error) |
3111 | goto out; | 3142 | goto out; |
3112 | error = | 3143 | error = dquot_transfer(inode, attr); |
3113 | vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; | ||
3114 | if (error) { | 3144 | if (error) { |
3115 | journal_end(&th, inode->i_sb, | 3145 | journal_end(&th, inode->i_sb, |
3116 | jbegin_count); | 3146 | jbegin_count); |
@@ -3127,8 +3157,17 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3127 | journal_end(&th, inode->i_sb, jbegin_count); | 3157 | journal_end(&th, inode->i_sb, jbegin_count); |
3128 | } | 3158 | } |
3129 | } | 3159 | } |
3130 | if (!error) | 3160 | if (!error) { |
3161 | /* | ||
3162 | * Relax the lock here, as it might truncate the | ||
3163 | * inode pages and wait for inode pages locks. | ||
3164 | * To release such page lock, the owner needs the | ||
3165 | * reiserfs lock | ||
3166 | */ | ||
3167 | reiserfs_write_unlock_once(inode->i_sb, depth); | ||
3131 | error = inode_setattr(inode, attr); | 3168 | error = inode_setattr(inode, attr); |
3169 | depth = reiserfs_write_lock_once(inode->i_sb); | ||
3170 | } | ||
3132 | } | 3171 | } |
3133 | 3172 | ||
3134 | if (!error && reiserfs_posixacl(inode->i_sb)) { | 3173 | if (!error && reiserfs_posixacl(inode->i_sb)) { |
@@ -3137,7 +3176,8 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3137 | } | 3176 | } |
3138 | 3177 | ||
3139 | out: | 3178 | out: |
3140 | reiserfs_write_unlock(inode->i_sb); | 3179 | reiserfs_write_unlock_once(inode->i_sb, depth); |
3180 | |||
3141 | return error; | 3181 | return error; |
3142 | } | 3182 | } |
3143 | 3183 | ||
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 0ccc3fdda7bf..f53505de0712 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c | |||
@@ -13,44 +13,52 @@ | |||
13 | #include <linux/compat.h> | 13 | #include <linux/compat.h> |
14 | 14 | ||
15 | /* | 15 | /* |
16 | ** reiserfs_ioctl - handler for ioctl for inode | 16 | * reiserfs_ioctl - handler for ioctl for inode |
17 | ** supported commands: | 17 | * supported commands: |
18 | ** 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect | 18 | * 1) REISERFS_IOC_UNPACK - try to unpack tail from direct item into indirect |
19 | ** and prevent packing file (argument arg has to be non-zero) | 19 | * and prevent packing file (argument arg has to be non-zero) |
20 | ** 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION | 20 | * 2) REISERFS_IOC_[GS]ETFLAGS, REISERFS_IOC_[GS]ETVERSION |
21 | ** 3) That's all for a while ... | 21 | * 3) That's all for a while ... |
22 | */ | 22 | */ |
23 | int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 23 | long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
24 | unsigned long arg) | ||
25 | { | 24 | { |
25 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
26 | unsigned int flags; | 26 | unsigned int flags; |
27 | int err = 0; | 27 | int err = 0; |
28 | 28 | ||
29 | reiserfs_write_lock(inode->i_sb); | ||
30 | |||
29 | switch (cmd) { | 31 | switch (cmd) { |
30 | case REISERFS_IOC_UNPACK: | 32 | case REISERFS_IOC_UNPACK: |
31 | if (S_ISREG(inode->i_mode)) { | 33 | if (S_ISREG(inode->i_mode)) { |
32 | if (arg) | 34 | if (arg) |
33 | return reiserfs_unpack(inode, filp); | 35 | err = reiserfs_unpack(inode, filp); |
34 | else | ||
35 | return 0; | ||
36 | } else | 36 | } else |
37 | return -ENOTTY; | 37 | err = -ENOTTY; |
38 | /* following two cases are taken from fs/ext2/ioctl.c by Remy | 38 | break; |
39 | Card (card@masi.ibp.fr) */ | 39 | /* |
40 | * following two cases are taken from fs/ext2/ioctl.c by Remy | ||
41 | * Card (card@masi.ibp.fr) | ||
42 | */ | ||
40 | case REISERFS_IOC_GETFLAGS: | 43 | case REISERFS_IOC_GETFLAGS: |
41 | if (!reiserfs_attrs(inode->i_sb)) | 44 | if (!reiserfs_attrs(inode->i_sb)) { |
42 | return -ENOTTY; | 45 | err = -ENOTTY; |
46 | break; | ||
47 | } | ||
43 | 48 | ||
44 | flags = REISERFS_I(inode)->i_attrs; | 49 | flags = REISERFS_I(inode)->i_attrs; |
45 | i_attrs_to_sd_attrs(inode, (__u16 *) & flags); | 50 | i_attrs_to_sd_attrs(inode, (__u16 *) & flags); |
46 | return put_user(flags, (int __user *)arg); | 51 | err = put_user(flags, (int __user *)arg); |
52 | break; | ||
47 | case REISERFS_IOC_SETFLAGS:{ | 53 | case REISERFS_IOC_SETFLAGS:{ |
48 | if (!reiserfs_attrs(inode->i_sb)) | 54 | if (!reiserfs_attrs(inode->i_sb)) { |
49 | return -ENOTTY; | 55 | err = -ENOTTY; |
56 | break; | ||
57 | } | ||
50 | 58 | ||
51 | err = mnt_want_write(filp->f_path.mnt); | 59 | err = mnt_want_write(filp->f_path.mnt); |
52 | if (err) | 60 | if (err) |
53 | return err; | 61 | break; |
54 | 62 | ||
55 | if (!is_owner_or_cap(inode)) { | 63 | if (!is_owner_or_cap(inode)) { |
56 | err = -EPERM; | 64 | err = -EPERM; |
@@ -90,16 +98,19 @@ int reiserfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
90 | mark_inode_dirty(inode); | 98 | mark_inode_dirty(inode); |
91 | setflags_out: | 99 | setflags_out: |
92 | mnt_drop_write(filp->f_path.mnt); | 100 | mnt_drop_write(filp->f_path.mnt); |
93 | return err; | 101 | break; |
94 | } | 102 | } |
95 | case REISERFS_IOC_GETVERSION: | 103 | case REISERFS_IOC_GETVERSION: |
96 | return put_user(inode->i_generation, (int __user *)arg); | 104 | err = put_user(inode->i_generation, (int __user *)arg); |
105 | break; | ||
97 | case REISERFS_IOC_SETVERSION: | 106 | case REISERFS_IOC_SETVERSION: |
98 | if (!is_owner_or_cap(inode)) | 107 | if (!is_owner_or_cap(inode)) { |
99 | return -EPERM; | 108 | err = -EPERM; |
109 | break; | ||
110 | } | ||
100 | err = mnt_want_write(filp->f_path.mnt); | 111 | err = mnt_want_write(filp->f_path.mnt); |
101 | if (err) | 112 | if (err) |
102 | return err; | 113 | break; |
103 | if (get_user(inode->i_generation, (int __user *)arg)) { | 114 | if (get_user(inode->i_generation, (int __user *)arg)) { |
104 | err = -EFAULT; | 115 | err = -EFAULT; |
105 | goto setversion_out; | 116 | goto setversion_out; |
@@ -108,19 +119,20 @@ setflags_out: | |||
108 | mark_inode_dirty(inode); | 119 | mark_inode_dirty(inode); |
109 | setversion_out: | 120 | setversion_out: |
110 | mnt_drop_write(filp->f_path.mnt); | 121 | mnt_drop_write(filp->f_path.mnt); |
111 | return err; | 122 | break; |
112 | default: | 123 | default: |
113 | return -ENOTTY; | 124 | err = -ENOTTY; |
114 | } | 125 | } |
126 | |||
127 | reiserfs_write_unlock(inode->i_sb); | ||
128 | |||
129 | return err; | ||
115 | } | 130 | } |
116 | 131 | ||
117 | #ifdef CONFIG_COMPAT | 132 | #ifdef CONFIG_COMPAT |
118 | long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, | 133 | long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, |
119 | unsigned long arg) | 134 | unsigned long arg) |
120 | { | 135 | { |
121 | struct inode *inode = file->f_path.dentry->d_inode; | ||
122 | int ret; | ||
123 | |||
124 | /* These are just misnamed, they actually get/put from/to user an int */ | 136 | /* These are just misnamed, they actually get/put from/to user an int */ |
125 | switch (cmd) { | 137 | switch (cmd) { |
126 | case REISERFS_IOC32_UNPACK: | 138 | case REISERFS_IOC32_UNPACK: |
@@ -141,10 +153,8 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, | |||
141 | default: | 153 | default: |
142 | return -ENOIOCTLCMD; | 154 | return -ENOIOCTLCMD; |
143 | } | 155 | } |
144 | lock_kernel(); | 156 | |
145 | ret = reiserfs_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | 157 | return reiserfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); |
146 | unlock_kernel(); | ||
147 | return ret; | ||
148 | } | 158 | } |
149 | #endif | 159 | #endif |
150 | 160 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 90622200b39c..19fbc810e8e7 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/blkdev.h> | 50 | #include <linux/blkdev.h> |
51 | #include <linux/backing-dev.h> | 51 | #include <linux/backing-dev.h> |
52 | #include <linux/uaccess.h> | 52 | #include <linux/uaccess.h> |
53 | #include <linux/slab.h> | ||
53 | 54 | ||
54 | #include <asm/system.h> | 55 | #include <asm/system.h> |
55 | 56 | ||
@@ -429,21 +430,6 @@ static void clear_prepared_bits(struct buffer_head *bh) | |||
429 | clear_buffer_journal_restore_dirty(bh); | 430 | clear_buffer_journal_restore_dirty(bh); |
430 | } | 431 | } |
431 | 432 | ||
432 | /* utility function to force a BUG if it is called without the big | ||
433 | ** kernel lock held. caller is the string printed just before calling BUG() | ||
434 | */ | ||
435 | void reiserfs_check_lock_depth(struct super_block *sb, char *caller) | ||
436 | { | ||
437 | #ifdef CONFIG_SMP | ||
438 | if (current->lock_depth < 0) { | ||
439 | reiserfs_panic(sb, "journal-1", "%s called without kernel " | ||
440 | "lock held", caller); | ||
441 | } | ||
442 | #else | ||
443 | ; | ||
444 | #endif | ||
445 | } | ||
446 | |||
447 | /* return a cnode with same dev, block number and size in table, or null if not found */ | 433 | /* return a cnode with same dev, block number and size in table, or null if not found */ |
448 | static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct | 434 | static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct |
449 | super_block | 435 | super_block |
@@ -556,7 +542,8 @@ static inline void insert_journal_hash(struct reiserfs_journal_cnode **table, | |||
556 | static inline void lock_journal(struct super_block *sb) | 542 | static inline void lock_journal(struct super_block *sb) |
557 | { | 543 | { |
558 | PROC_INFO_INC(sb, journal.lock_journal); | 544 | PROC_INFO_INC(sb, journal.lock_journal); |
559 | mutex_lock(&SB_JOURNAL(sb)->j_mutex); | 545 | |
546 | reiserfs_mutex_lock_safe(&SB_JOURNAL(sb)->j_mutex, sb); | ||
560 | } | 547 | } |
561 | 548 | ||
562 | /* unlock the current transaction */ | 549 | /* unlock the current transaction */ |
@@ -708,7 +695,9 @@ static void check_barrier_completion(struct super_block *s, | |||
708 | disable_barrier(s); | 695 | disable_barrier(s); |
709 | set_buffer_uptodate(bh); | 696 | set_buffer_uptodate(bh); |
710 | set_buffer_dirty(bh); | 697 | set_buffer_dirty(bh); |
698 | reiserfs_write_unlock(s); | ||
711 | sync_dirty_buffer(bh); | 699 | sync_dirty_buffer(bh); |
700 | reiserfs_write_lock(s); | ||
712 | } | 701 | } |
713 | } | 702 | } |
714 | 703 | ||
@@ -996,8 +985,13 @@ static int reiserfs_async_progress_wait(struct super_block *s) | |||
996 | { | 985 | { |
997 | DEFINE_WAIT(wait); | 986 | DEFINE_WAIT(wait); |
998 | struct reiserfs_journal *j = SB_JOURNAL(s); | 987 | struct reiserfs_journal *j = SB_JOURNAL(s); |
999 | if (atomic_read(&j->j_async_throttle)) | 988 | |
989 | if (atomic_read(&j->j_async_throttle)) { | ||
990 | reiserfs_write_unlock(s); | ||
1000 | congestion_wait(BLK_RW_ASYNC, HZ / 10); | 991 | congestion_wait(BLK_RW_ASYNC, HZ / 10); |
992 | reiserfs_write_lock(s); | ||
993 | } | ||
994 | |||
1001 | return 0; | 995 | return 0; |
1002 | } | 996 | } |
1003 | 997 | ||
@@ -1043,7 +1037,8 @@ static int flush_commit_list(struct super_block *s, | |||
1043 | } | 1037 | } |
1044 | 1038 | ||
1045 | /* make sure nobody is trying to flush this one at the same time */ | 1039 | /* make sure nobody is trying to flush this one at the same time */ |
1046 | mutex_lock(&jl->j_commit_mutex); | 1040 | reiserfs_mutex_lock_safe(&jl->j_commit_mutex, s); |
1041 | |||
1047 | if (!journal_list_still_alive(s, trans_id)) { | 1042 | if (!journal_list_still_alive(s, trans_id)) { |
1048 | mutex_unlock(&jl->j_commit_mutex); | 1043 | mutex_unlock(&jl->j_commit_mutex); |
1049 | goto put_jl; | 1044 | goto put_jl; |
@@ -1061,12 +1056,17 @@ static int flush_commit_list(struct super_block *s, | |||
1061 | 1056 | ||
1062 | if (!list_empty(&jl->j_bh_list)) { | 1057 | if (!list_empty(&jl->j_bh_list)) { |
1063 | int ret; | 1058 | int ret; |
1064 | unlock_kernel(); | 1059 | |
1060 | /* | ||
1061 | * We might sleep in numerous places inside | ||
1062 | * write_ordered_buffers. Relax the write lock. | ||
1063 | */ | ||
1064 | reiserfs_write_unlock(s); | ||
1065 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, | 1065 | ret = write_ordered_buffers(&journal->j_dirty_buffers_lock, |
1066 | journal, jl, &jl->j_bh_list); | 1066 | journal, jl, &jl->j_bh_list); |
1067 | if (ret < 0 && retval == 0) | 1067 | if (ret < 0 && retval == 0) |
1068 | retval = ret; | 1068 | retval = ret; |
1069 | lock_kernel(); | 1069 | reiserfs_write_lock(s); |
1070 | } | 1070 | } |
1071 | BUG_ON(!list_empty(&jl->j_bh_list)); | 1071 | BUG_ON(!list_empty(&jl->j_bh_list)); |
1072 | /* | 1072 | /* |
@@ -1085,8 +1085,11 @@ static int flush_commit_list(struct super_block *s, | |||
1085 | SB_ONDISK_JOURNAL_SIZE(s); | 1085 | SB_ONDISK_JOURNAL_SIZE(s); |
1086 | tbh = journal_find_get_block(s, bn); | 1086 | tbh = journal_find_get_block(s, bn); |
1087 | if (tbh) { | 1087 | if (tbh) { |
1088 | if (buffer_dirty(tbh)) | 1088 | if (buffer_dirty(tbh)) { |
1089 | ll_rw_block(WRITE, 1, &tbh) ; | 1089 | reiserfs_write_unlock(s); |
1090 | ll_rw_block(WRITE, 1, &tbh); | ||
1091 | reiserfs_write_lock(s); | ||
1092 | } | ||
1090 | put_bh(tbh) ; | 1093 | put_bh(tbh) ; |
1091 | } | 1094 | } |
1092 | } | 1095 | } |
@@ -1114,12 +1117,19 @@ static int flush_commit_list(struct super_block *s, | |||
1114 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + | 1117 | bn = SB_ONDISK_JOURNAL_1st_BLOCK(s) + |
1115 | (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s); | 1118 | (jl->j_start + i) % SB_ONDISK_JOURNAL_SIZE(s); |
1116 | tbh = journal_find_get_block(s, bn); | 1119 | tbh = journal_find_get_block(s, bn); |
1120 | |||
1121 | reiserfs_write_unlock(s); | ||
1117 | wait_on_buffer(tbh); | 1122 | wait_on_buffer(tbh); |
1123 | reiserfs_write_lock(s); | ||
1118 | // since we're using ll_rw_blk above, it might have skipped over | 1124 | // since we're using ll_rw_blk above, it might have skipped over |
1119 | // a locked buffer. Double check here | 1125 | // a locked buffer. Double check here |
1120 | // | 1126 | // |
1121 | if (buffer_dirty(tbh)) /* redundant, sync_dirty_buffer() checks */ | 1127 | /* redundant, sync_dirty_buffer() checks */ |
1128 | if (buffer_dirty(tbh)) { | ||
1129 | reiserfs_write_unlock(s); | ||
1122 | sync_dirty_buffer(tbh); | 1130 | sync_dirty_buffer(tbh); |
1131 | reiserfs_write_lock(s); | ||
1132 | } | ||
1123 | if (unlikely(!buffer_uptodate(tbh))) { | 1133 | if (unlikely(!buffer_uptodate(tbh))) { |
1124 | #ifdef CONFIG_REISERFS_CHECK | 1134 | #ifdef CONFIG_REISERFS_CHECK |
1125 | reiserfs_warning(s, "journal-601", | 1135 | reiserfs_warning(s, "journal-601", |
@@ -1143,10 +1153,15 @@ static int flush_commit_list(struct super_block *s, | |||
1143 | if (buffer_dirty(jl->j_commit_bh)) | 1153 | if (buffer_dirty(jl->j_commit_bh)) |
1144 | BUG(); | 1154 | BUG(); |
1145 | mark_buffer_dirty(jl->j_commit_bh) ; | 1155 | mark_buffer_dirty(jl->j_commit_bh) ; |
1156 | reiserfs_write_unlock(s); | ||
1146 | sync_dirty_buffer(jl->j_commit_bh) ; | 1157 | sync_dirty_buffer(jl->j_commit_bh) ; |
1158 | reiserfs_write_lock(s); | ||
1147 | } | 1159 | } |
1148 | } else | 1160 | } else { |
1161 | reiserfs_write_unlock(s); | ||
1149 | wait_on_buffer(jl->j_commit_bh); | 1162 | wait_on_buffer(jl->j_commit_bh); |
1163 | reiserfs_write_lock(s); | ||
1164 | } | ||
1150 | 1165 | ||
1151 | check_barrier_completion(s, jl->j_commit_bh); | 1166 | check_barrier_completion(s, jl->j_commit_bh); |
1152 | 1167 | ||
@@ -1286,7 +1301,9 @@ static int _update_journal_header_block(struct super_block *sb, | |||
1286 | 1301 | ||
1287 | if (trans_id >= journal->j_last_flush_trans_id) { | 1302 | if (trans_id >= journal->j_last_flush_trans_id) { |
1288 | if (buffer_locked((journal->j_header_bh))) { | 1303 | if (buffer_locked((journal->j_header_bh))) { |
1304 | reiserfs_write_unlock(sb); | ||
1289 | wait_on_buffer((journal->j_header_bh)); | 1305 | wait_on_buffer((journal->j_header_bh)); |
1306 | reiserfs_write_lock(sb); | ||
1290 | if (unlikely(!buffer_uptodate(journal->j_header_bh))) { | 1307 | if (unlikely(!buffer_uptodate(journal->j_header_bh))) { |
1291 | #ifdef CONFIG_REISERFS_CHECK | 1308 | #ifdef CONFIG_REISERFS_CHECK |
1292 | reiserfs_warning(sb, "journal-699", | 1309 | reiserfs_warning(sb, "journal-699", |
@@ -1312,12 +1329,16 @@ static int _update_journal_header_block(struct super_block *sb, | |||
1312 | disable_barrier(sb); | 1329 | disable_barrier(sb); |
1313 | goto sync; | 1330 | goto sync; |
1314 | } | 1331 | } |
1332 | reiserfs_write_unlock(sb); | ||
1315 | wait_on_buffer(journal->j_header_bh); | 1333 | wait_on_buffer(journal->j_header_bh); |
1334 | reiserfs_write_lock(sb); | ||
1316 | check_barrier_completion(sb, journal->j_header_bh); | 1335 | check_barrier_completion(sb, journal->j_header_bh); |
1317 | } else { | 1336 | } else { |
1318 | sync: | 1337 | sync: |
1319 | set_buffer_dirty(journal->j_header_bh); | 1338 | set_buffer_dirty(journal->j_header_bh); |
1339 | reiserfs_write_unlock(sb); | ||
1320 | sync_dirty_buffer(journal->j_header_bh); | 1340 | sync_dirty_buffer(journal->j_header_bh); |
1341 | reiserfs_write_lock(sb); | ||
1321 | } | 1342 | } |
1322 | if (!buffer_uptodate(journal->j_header_bh)) { | 1343 | if (!buffer_uptodate(journal->j_header_bh)) { |
1323 | reiserfs_warning(sb, "journal-837", | 1344 | reiserfs_warning(sb, "journal-837", |
@@ -1409,7 +1430,7 @@ static int flush_journal_list(struct super_block *s, | |||
1409 | 1430 | ||
1410 | /* if flushall == 0, the lock is already held */ | 1431 | /* if flushall == 0, the lock is already held */ |
1411 | if (flushall) { | 1432 | if (flushall) { |
1412 | mutex_lock(&journal->j_flush_mutex); | 1433 | reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s); |
1413 | } else if (mutex_trylock(&journal->j_flush_mutex)) { | 1434 | } else if (mutex_trylock(&journal->j_flush_mutex)) { |
1414 | BUG(); | 1435 | BUG(); |
1415 | } | 1436 | } |
@@ -1553,7 +1574,11 @@ static int flush_journal_list(struct super_block *s, | |||
1553 | reiserfs_panic(s, "journal-1011", | 1574 | reiserfs_panic(s, "journal-1011", |
1554 | "cn->bh is NULL"); | 1575 | "cn->bh is NULL"); |
1555 | } | 1576 | } |
1577 | |||
1578 | reiserfs_write_unlock(s); | ||
1556 | wait_on_buffer(cn->bh); | 1579 | wait_on_buffer(cn->bh); |
1580 | reiserfs_write_lock(s); | ||
1581 | |||
1557 | if (!cn->bh) { | 1582 | if (!cn->bh) { |
1558 | reiserfs_panic(s, "journal-1012", | 1583 | reiserfs_panic(s, "journal-1012", |
1559 | "cn->bh is NULL"); | 1584 | "cn->bh is NULL"); |
@@ -1769,7 +1794,7 @@ static int kupdate_transactions(struct super_block *s, | |||
1769 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 1794 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
1770 | chunk.nr = 0; | 1795 | chunk.nr = 0; |
1771 | 1796 | ||
1772 | mutex_lock(&journal->j_flush_mutex); | 1797 | reiserfs_mutex_lock_safe(&journal->j_flush_mutex, s); |
1773 | if (!journal_list_still_alive(s, orig_trans_id)) { | 1798 | if (!journal_list_still_alive(s, orig_trans_id)) { |
1774 | goto done; | 1799 | goto done; |
1775 | } | 1800 | } |
@@ -1973,7 +1998,14 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1973 | reiserfs_mounted_fs_count--; | 1998 | reiserfs_mounted_fs_count--; |
1974 | /* wait for all commits to finish */ | 1999 | /* wait for all commits to finish */ |
1975 | cancel_delayed_work(&SB_JOURNAL(sb)->j_work); | 2000 | cancel_delayed_work(&SB_JOURNAL(sb)->j_work); |
2001 | |||
2002 | /* | ||
2003 | * We must release the write lock here because | ||
2004 | * the workqueue job (flush_async_commit) needs this lock | ||
2005 | */ | ||
2006 | reiserfs_write_unlock(sb); | ||
1976 | flush_workqueue(commit_wq); | 2007 | flush_workqueue(commit_wq); |
2008 | |||
1977 | if (!reiserfs_mounted_fs_count) { | 2009 | if (!reiserfs_mounted_fs_count) { |
1978 | destroy_workqueue(commit_wq); | 2010 | destroy_workqueue(commit_wq); |
1979 | commit_wq = NULL; | 2011 | commit_wq = NULL; |
@@ -1981,6 +2013,8 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, | |||
1981 | 2013 | ||
1982 | free_journal_ram(sb); | 2014 | free_journal_ram(sb); |
1983 | 2015 | ||
2016 | reiserfs_write_lock(sb); | ||
2017 | |||
1984 | return 0; | 2018 | return 0; |
1985 | } | 2019 | } |
1986 | 2020 | ||
@@ -2184,6 +2218,15 @@ static int journal_read_transaction(struct super_block *sb, | |||
2184 | brelse(d_bh); | 2218 | brelse(d_bh); |
2185 | return 1; | 2219 | return 1; |
2186 | } | 2220 | } |
2221 | |||
2222 | if (bdev_read_only(sb->s_bdev)) { | ||
2223 | reiserfs_warning(sb, "clm-2076", | ||
2224 | "device is readonly, unable to replay log"); | ||
2225 | brelse(c_bh); | ||
2226 | brelse(d_bh); | ||
2227 | return -EROFS; | ||
2228 | } | ||
2229 | |||
2187 | trans_id = get_desc_trans_id(desc); | 2230 | trans_id = get_desc_trans_id(desc); |
2188 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ | 2231 | /* now we know we've got a good transaction, and it was inside the valid time ranges */ |
2189 | log_blocks = kmalloc(get_desc_trans_len(desc) * | 2232 | log_blocks = kmalloc(get_desc_trans_len(desc) * |
@@ -2243,7 +2286,11 @@ static int journal_read_transaction(struct super_block *sb, | |||
2243 | /* read in the log blocks, memcpy to the corresponding real block */ | 2286 | /* read in the log blocks, memcpy to the corresponding real block */ |
2244 | ll_rw_block(READ, get_desc_trans_len(desc), log_blocks); | 2287 | ll_rw_block(READ, get_desc_trans_len(desc), log_blocks); |
2245 | for (i = 0; i < get_desc_trans_len(desc); i++) { | 2288 | for (i = 0; i < get_desc_trans_len(desc); i++) { |
2289 | |||
2290 | reiserfs_write_unlock(sb); | ||
2246 | wait_on_buffer(log_blocks[i]); | 2291 | wait_on_buffer(log_blocks[i]); |
2292 | reiserfs_write_lock(sb); | ||
2293 | |||
2247 | if (!buffer_uptodate(log_blocks[i])) { | 2294 | if (!buffer_uptodate(log_blocks[i])) { |
2248 | reiserfs_warning(sb, "journal-1212", | 2295 | reiserfs_warning(sb, "journal-1212", |
2249 | "REPLAY FAILURE fsck required! " | 2296 | "REPLAY FAILURE fsck required! " |
@@ -2422,12 +2469,6 @@ static int journal_read(struct super_block *sb) | |||
2422 | goto start_log_replay; | 2469 | goto start_log_replay; |
2423 | } | 2470 | } |
2424 | 2471 | ||
2425 | if (continue_replay && bdev_read_only(sb->s_bdev)) { | ||
2426 | reiserfs_warning(sb, "clm-2076", | ||
2427 | "device is readonly, unable to replay log"); | ||
2428 | return -1; | ||
2429 | } | ||
2430 | |||
2431 | /* ok, there are transactions that need to be replayed. start with the first log block, find | 2472 | /* ok, there are transactions that need to be replayed. start with the first log block, find |
2432 | ** all the valid transactions, and pick out the oldest. | 2473 | ** all the valid transactions, and pick out the oldest. |
2433 | */ | 2474 | */ |
@@ -2722,11 +2763,18 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2722 | struct reiserfs_journal *journal; | 2763 | struct reiserfs_journal *journal; |
2723 | struct reiserfs_journal_list *jl; | 2764 | struct reiserfs_journal_list *jl; |
2724 | char b[BDEVNAME_SIZE]; | 2765 | char b[BDEVNAME_SIZE]; |
2766 | int ret; | ||
2725 | 2767 | ||
2768 | /* | ||
2769 | * Unlock here to avoid various RECLAIM-FS-ON <-> IN-RECLAIM-FS | ||
2770 | * dependency inversion warnings. | ||
2771 | */ | ||
2772 | reiserfs_write_unlock(sb); | ||
2726 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); | 2773 | journal = SB_JOURNAL(sb) = vmalloc(sizeof(struct reiserfs_journal)); |
2727 | if (!journal) { | 2774 | if (!journal) { |
2728 | reiserfs_warning(sb, "journal-1256", | 2775 | reiserfs_warning(sb, "journal-1256", |
2729 | "unable to get memory for journal structure"); | 2776 | "unable to get memory for journal structure"); |
2777 | reiserfs_write_lock(sb); | ||
2730 | return 1; | 2778 | return 1; |
2731 | } | 2779 | } |
2732 | memset(journal, 0, sizeof(struct reiserfs_journal)); | 2780 | memset(journal, 0, sizeof(struct reiserfs_journal)); |
@@ -2735,10 +2783,12 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2735 | INIT_LIST_HEAD(&journal->j_working_list); | 2783 | INIT_LIST_HEAD(&journal->j_working_list); |
2736 | INIT_LIST_HEAD(&journal->j_journal_list); | 2784 | INIT_LIST_HEAD(&journal->j_journal_list); |
2737 | journal->j_persistent_trans = 0; | 2785 | journal->j_persistent_trans = 0; |
2738 | if (reiserfs_allocate_list_bitmaps(sb, | 2786 | ret = reiserfs_allocate_list_bitmaps(sb, journal->j_list_bitmap, |
2739 | journal->j_list_bitmap, | 2787 | reiserfs_bmap_count(sb)); |
2740 | reiserfs_bmap_count(sb))) | 2788 | reiserfs_write_lock(sb); |
2789 | if (ret) | ||
2741 | goto free_and_return; | 2790 | goto free_and_return; |
2791 | |||
2742 | allocate_bitmap_nodes(sb); | 2792 | allocate_bitmap_nodes(sb); |
2743 | 2793 | ||
2744 | /* reserved for journal area support */ | 2794 | /* reserved for journal area support */ |
@@ -2765,11 +2815,27 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2765 | goto free_and_return; | 2815 | goto free_and_return; |
2766 | } | 2816 | } |
2767 | 2817 | ||
2818 | /* | ||
2819 | * We need to unlock here to avoid creating the following | ||
2820 | * dependency: | ||
2821 | * reiserfs_lock -> sysfs_mutex | ||
2822 | * Because the reiserfs mmap path creates the following dependency: | ||
2823 | * mm->mmap -> reiserfs_lock, hence we have | ||
2824 | * mm->mmap -> reiserfs_lock ->sysfs_mutex | ||
2825 | * This would ends up in a circular dependency with sysfs readdir path | ||
2826 | * which does sysfs_mutex -> mm->mmap_sem | ||
2827 | * This is fine because the reiserfs lock is useless in mount path, | ||
2828 | * at least until we call journal_begin. We keep it for paranoid | ||
2829 | * reasons. | ||
2830 | */ | ||
2831 | reiserfs_write_unlock(sb); | ||
2768 | if (journal_init_dev(sb, journal, j_dev_name) != 0) { | 2832 | if (journal_init_dev(sb, journal, j_dev_name) != 0) { |
2833 | reiserfs_write_lock(sb); | ||
2769 | reiserfs_warning(sb, "sh-462", | 2834 | reiserfs_warning(sb, "sh-462", |
2770 | "unable to initialize jornal device"); | 2835 | "unable to initialize jornal device"); |
2771 | goto free_and_return; | 2836 | goto free_and_return; |
2772 | } | 2837 | } |
2838 | reiserfs_write_lock(sb); | ||
2773 | 2839 | ||
2774 | rs = SB_DISK_SUPER_BLOCK(sb); | 2840 | rs = SB_DISK_SUPER_BLOCK(sb); |
2775 | 2841 | ||
@@ -2851,7 +2917,9 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2851 | journal->j_mount_id = 10; | 2917 | journal->j_mount_id = 10; |
2852 | journal->j_state = 0; | 2918 | journal->j_state = 0; |
2853 | atomic_set(&(journal->j_jlock), 0); | 2919 | atomic_set(&(journal->j_jlock), 0); |
2920 | reiserfs_write_unlock(sb); | ||
2854 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); | 2921 | journal->j_cnode_free_list = allocate_cnodes(num_cnodes); |
2922 | reiserfs_write_lock(sb); | ||
2855 | journal->j_cnode_free_orig = journal->j_cnode_free_list; | 2923 | journal->j_cnode_free_orig = journal->j_cnode_free_list; |
2856 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; | 2924 | journal->j_cnode_free = journal->j_cnode_free_list ? num_cnodes : 0; |
2857 | journal->j_cnode_used = 0; | 2925 | journal->j_cnode_used = 0; |
@@ -2881,8 +2949,11 @@ int journal_init(struct super_block *sb, const char *j_dev_name, | |||
2881 | } | 2949 | } |
2882 | 2950 | ||
2883 | reiserfs_mounted_fs_count++; | 2951 | reiserfs_mounted_fs_count++; |
2884 | if (reiserfs_mounted_fs_count <= 1) | 2952 | if (reiserfs_mounted_fs_count <= 1) { |
2953 | reiserfs_write_unlock(sb); | ||
2885 | commit_wq = create_workqueue("reiserfs"); | 2954 | commit_wq = create_workqueue("reiserfs"); |
2955 | reiserfs_write_lock(sb); | ||
2956 | } | ||
2886 | 2957 | ||
2887 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); | 2958 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); |
2888 | journal->j_work_sb = sb; | 2959 | journal->j_work_sb = sb; |
@@ -2964,8 +3035,11 @@ static void queue_log_writer(struct super_block *s) | |||
2964 | init_waitqueue_entry(&wait, current); | 3035 | init_waitqueue_entry(&wait, current); |
2965 | add_wait_queue(&journal->j_join_wait, &wait); | 3036 | add_wait_queue(&journal->j_join_wait, &wait); |
2966 | set_current_state(TASK_UNINTERRUPTIBLE); | 3037 | set_current_state(TASK_UNINTERRUPTIBLE); |
2967 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) | 3038 | if (test_bit(J_WRITERS_QUEUED, &journal->j_state)) { |
3039 | reiserfs_write_unlock(s); | ||
2968 | schedule(); | 3040 | schedule(); |
3041 | reiserfs_write_lock(s); | ||
3042 | } | ||
2969 | __set_current_state(TASK_RUNNING); | 3043 | __set_current_state(TASK_RUNNING); |
2970 | remove_wait_queue(&journal->j_join_wait, &wait); | 3044 | remove_wait_queue(&journal->j_join_wait, &wait); |
2971 | } | 3045 | } |
@@ -2982,7 +3056,9 @@ static void let_transaction_grow(struct super_block *sb, unsigned int trans_id) | |||
2982 | struct reiserfs_journal *journal = SB_JOURNAL(sb); | 3056 | struct reiserfs_journal *journal = SB_JOURNAL(sb); |
2983 | unsigned long bcount = journal->j_bcount; | 3057 | unsigned long bcount = journal->j_bcount; |
2984 | while (1) { | 3058 | while (1) { |
3059 | reiserfs_write_unlock(sb); | ||
2985 | schedule_timeout_uninterruptible(1); | 3060 | schedule_timeout_uninterruptible(1); |
3061 | reiserfs_write_lock(sb); | ||
2986 | journal->j_current_jl->j_state |= LIST_COMMIT_PENDING; | 3062 | journal->j_current_jl->j_state |= LIST_COMMIT_PENDING; |
2987 | while ((atomic_read(&journal->j_wcount) > 0 || | 3063 | while ((atomic_read(&journal->j_wcount) > 0 || |
2988 | atomic_read(&journal->j_jlock)) && | 3064 | atomic_read(&journal->j_jlock)) && |
@@ -3033,7 +3109,9 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th, | |||
3033 | 3109 | ||
3034 | if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) { | 3110 | if (test_bit(J_WRITERS_BLOCKED, &journal->j_state)) { |
3035 | unlock_journal(sb); | 3111 | unlock_journal(sb); |
3112 | reiserfs_write_unlock(sb); | ||
3036 | reiserfs_wait_on_write_block(sb); | 3113 | reiserfs_wait_on_write_block(sb); |
3114 | reiserfs_write_lock(sb); | ||
3037 | PROC_INFO_INC(sb, journal.journal_relock_writers); | 3115 | PROC_INFO_INC(sb, journal.journal_relock_writers); |
3038 | goto relock; | 3116 | goto relock; |
3039 | } | 3117 | } |
@@ -3506,14 +3584,14 @@ static void flush_async_commits(struct work_struct *work) | |||
3506 | struct reiserfs_journal_list *jl; | 3584 | struct reiserfs_journal_list *jl; |
3507 | struct list_head *entry; | 3585 | struct list_head *entry; |
3508 | 3586 | ||
3509 | lock_kernel(); | 3587 | reiserfs_write_lock(sb); |
3510 | if (!list_empty(&journal->j_journal_list)) { | 3588 | if (!list_empty(&journal->j_journal_list)) { |
3511 | /* last entry is the youngest, commit it and you get everything */ | 3589 | /* last entry is the youngest, commit it and you get everything */ |
3512 | entry = journal->j_journal_list.prev; | 3590 | entry = journal->j_journal_list.prev; |
3513 | jl = JOURNAL_LIST_ENTRY(entry); | 3591 | jl = JOURNAL_LIST_ENTRY(entry); |
3514 | flush_commit_list(sb, jl, 1); | 3592 | flush_commit_list(sb, jl, 1); |
3515 | } | 3593 | } |
3516 | unlock_kernel(); | 3594 | reiserfs_write_unlock(sb); |
3517 | } | 3595 | } |
3518 | 3596 | ||
3519 | /* | 3597 | /* |
@@ -4041,7 +4119,7 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4041 | * the new transaction is fully setup, and we've already flushed the | 4119 | * the new transaction is fully setup, and we've already flushed the |
4042 | * ordered bh list | 4120 | * ordered bh list |
4043 | */ | 4121 | */ |
4044 | mutex_lock(&jl->j_commit_mutex); | 4122 | reiserfs_mutex_lock_safe(&jl->j_commit_mutex, sb); |
4045 | 4123 | ||
4046 | /* save the transaction id in case we need to commit it later */ | 4124 | /* save the transaction id in case we need to commit it later */ |
4047 | commit_trans_id = jl->j_trans_id; | 4125 | commit_trans_id = jl->j_trans_id; |
@@ -4156,7 +4234,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4156 | next = cn->next; | 4234 | next = cn->next; |
4157 | free_cnode(sb, cn); | 4235 | free_cnode(sb, cn); |
4158 | cn = next; | 4236 | cn = next; |
4237 | reiserfs_write_unlock(sb); | ||
4159 | cond_resched(); | 4238 | cond_resched(); |
4239 | reiserfs_write_lock(sb); | ||
4160 | } | 4240 | } |
4161 | 4241 | ||
4162 | /* we are done with both the c_bh and d_bh, but | 4242 | /* we are done with both the c_bh and d_bh, but |
@@ -4203,10 +4283,10 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, | |||
4203 | * is lost. | 4283 | * is lost. |
4204 | */ | 4284 | */ |
4205 | if (!list_empty(&jl->j_tail_bh_list)) { | 4285 | if (!list_empty(&jl->j_tail_bh_list)) { |
4206 | unlock_kernel(); | 4286 | reiserfs_write_unlock(sb); |
4207 | write_ordered_buffers(&journal->j_dirty_buffers_lock, | 4287 | write_ordered_buffers(&journal->j_dirty_buffers_lock, |
4208 | journal, jl, &jl->j_tail_bh_list); | 4288 | journal, jl, &jl->j_tail_bh_list); |
4209 | lock_kernel(); | 4289 | reiserfs_write_lock(sb); |
4210 | } | 4290 | } |
4211 | BUG_ON(!list_empty(&jl->j_tail_bh_list)); | 4291 | BUG_ON(!list_empty(&jl->j_tail_bh_list)); |
4212 | mutex_unlock(&jl->j_commit_mutex); | 4292 | mutex_unlock(&jl->j_commit_mutex); |
diff --git a/fs/reiserfs/lock.c b/fs/reiserfs/lock.c new file mode 100644 index 000000000000..b87aa2c1afc1 --- /dev/null +++ b/fs/reiserfs/lock.c | |||
@@ -0,0 +1,97 @@ | |||
1 | #include <linux/reiserfs_fs.h> | ||
2 | #include <linux/mutex.h> | ||
3 | |||
4 | /* | ||
5 | * The previous reiserfs locking scheme was heavily based on | ||
6 | * the tricky properties of the Bkl: | ||
7 | * | ||
8 | * - it was acquired recursively by a same task | ||
9 | * - the performances relied on the release-while-schedule() property | ||
10 | * | ||
11 | * Now that we replace it by a mutex, we still want to keep the same | ||
12 | * recursive property to avoid big changes in the code structure. | ||
13 | * We use our own lock_owner here because the owner field on a mutex | ||
14 | * is only available in SMP or mutex debugging, also we only need this field | ||
15 | * for this mutex, no need for a system wide mutex facility. | ||
16 | * | ||
17 | * Also this lock is often released before a call that could block because | ||
18 | * reiserfs performances were partialy based on the release while schedule() | ||
19 | * property of the Bkl. | ||
20 | */ | ||
21 | void reiserfs_write_lock(struct super_block *s) | ||
22 | { | ||
23 | struct reiserfs_sb_info *sb_i = REISERFS_SB(s); | ||
24 | |||
25 | if (sb_i->lock_owner != current) { | ||
26 | mutex_lock(&sb_i->lock); | ||
27 | sb_i->lock_owner = current; | ||
28 | } | ||
29 | |||
30 | /* No need to protect it, only the current task touches it */ | ||
31 | sb_i->lock_depth++; | ||
32 | } | ||
33 | |||
34 | void reiserfs_write_unlock(struct super_block *s) | ||
35 | { | ||
36 | struct reiserfs_sb_info *sb_i = REISERFS_SB(s); | ||
37 | |||
38 | /* | ||
39 | * Are we unlocking without even holding the lock? | ||
40 | * Such a situation must raise a BUG() if we don't want | ||
41 | * to corrupt the data. | ||
42 | */ | ||
43 | BUG_ON(sb_i->lock_owner != current); | ||
44 | |||
45 | if (--sb_i->lock_depth == -1) { | ||
46 | sb_i->lock_owner = NULL; | ||
47 | mutex_unlock(&sb_i->lock); | ||
48 | } | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * If we already own the lock, just exit and don't increase the depth. | ||
53 | * Useful when we don't want to lock more than once. | ||
54 | * | ||
55 | * We always return the lock_depth we had before calling | ||
56 | * this function. | ||
57 | */ | ||
58 | int reiserfs_write_lock_once(struct super_block *s) | ||
59 | { | ||
60 | struct reiserfs_sb_info *sb_i = REISERFS_SB(s); | ||
61 | |||
62 | if (sb_i->lock_owner != current) { | ||
63 | mutex_lock(&sb_i->lock); | ||
64 | sb_i->lock_owner = current; | ||
65 | return sb_i->lock_depth++; | ||
66 | } | ||
67 | |||
68 | return sb_i->lock_depth; | ||
69 | } | ||
70 | |||
71 | void reiserfs_write_unlock_once(struct super_block *s, int lock_depth) | ||
72 | { | ||
73 | if (lock_depth == -1) | ||
74 | reiserfs_write_unlock(s); | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Utility function to force a BUG if it is called without the superblock | ||
79 | * write lock held. caller is the string printed just before calling BUG() | ||
80 | */ | ||
81 | void reiserfs_check_lock_depth(struct super_block *sb, char *caller) | ||
82 | { | ||
83 | struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); | ||
84 | |||
85 | if (sb_i->lock_depth < 0) | ||
86 | reiserfs_panic(sb, "%s called without kernel lock held %d", | ||
87 | caller); | ||
88 | } | ||
89 | |||
90 | #ifdef CONFIG_REISERFS_CHECK | ||
91 | void reiserfs_lock_check_recursive(struct super_block *sb) | ||
92 | { | ||
93 | struct reiserfs_sb_info *sb_i = REISERFS_SB(sb); | ||
94 | |||
95 | WARN_ONCE((sb_i->lock_depth > 0), "Unwanted recursive reiserfs lock!\n"); | ||
96 | } | ||
97 | #endif | ||
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 271579128634..d0c43cb99ffc 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/time.h> | 14 | #include <linux/time.h> |
15 | #include <linux/bitops.h> | 15 | #include <linux/bitops.h> |
16 | #include <linux/slab.h> | ||
16 | #include <linux/reiserfs_fs.h> | 17 | #include <linux/reiserfs_fs.h> |
17 | #include <linux/reiserfs_acl.h> | 18 | #include <linux/reiserfs_acl.h> |
18 | #include <linux/reiserfs_xattr.h> | 19 | #include <linux/reiserfs_xattr.h> |
@@ -324,6 +325,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
324 | struct nameidata *nd) | 325 | struct nameidata *nd) |
325 | { | 326 | { |
326 | int retval; | 327 | int retval; |
328 | int lock_depth; | ||
327 | struct inode *inode = NULL; | 329 | struct inode *inode = NULL; |
328 | struct reiserfs_dir_entry de; | 330 | struct reiserfs_dir_entry de; |
329 | INITIALIZE_PATH(path_to_entry); | 331 | INITIALIZE_PATH(path_to_entry); |
@@ -331,7 +333,13 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
331 | if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) | 333 | if (REISERFS_MAX_NAME(dir->i_sb->s_blocksize) < dentry->d_name.len) |
332 | return ERR_PTR(-ENAMETOOLONG); | 334 | return ERR_PTR(-ENAMETOOLONG); |
333 | 335 | ||
334 | reiserfs_write_lock(dir->i_sb); | 336 | /* |
337 | * Might be called with or without the write lock, must be careful | ||
338 | * to not recursively hold it in case we want to release the lock | ||
339 | * before rescheduling. | ||
340 | */ | ||
341 | lock_depth = reiserfs_write_lock_once(dir->i_sb); | ||
342 | |||
335 | de.de_gen_number_bit_string = NULL; | 343 | de.de_gen_number_bit_string = NULL; |
336 | retval = | 344 | retval = |
337 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, | 345 | reiserfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len, |
@@ -341,7 +349,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
341 | inode = reiserfs_iget(dir->i_sb, | 349 | inode = reiserfs_iget(dir->i_sb, |
342 | (struct cpu_key *)&(de.de_dir_id)); | 350 | (struct cpu_key *)&(de.de_dir_id)); |
343 | if (!inode || IS_ERR(inode)) { | 351 | if (!inode || IS_ERR(inode)) { |
344 | reiserfs_write_unlock(dir->i_sb); | 352 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
345 | return ERR_PTR(-EACCES); | 353 | return ERR_PTR(-EACCES); |
346 | } | 354 | } |
347 | 355 | ||
@@ -350,7 +358,7 @@ static struct dentry *reiserfs_lookup(struct inode *dir, struct dentry *dentry, | |||
350 | if (IS_PRIVATE(dir)) | 358 | if (IS_PRIVATE(dir)) |
351 | inode->i_flags |= S_PRIVATE; | 359 | inode->i_flags |= S_PRIVATE; |
352 | } | 360 | } |
353 | reiserfs_write_unlock(dir->i_sb); | 361 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
354 | if (retval == IO_ERROR) { | 362 | if (retval == IO_ERROR) { |
355 | return ERR_PTR(-EIO); | 363 | return ERR_PTR(-EIO); |
356 | } | 364 | } |
@@ -539,7 +547,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, | |||
539 | */ | 547 | */ |
540 | static int drop_new_inode(struct inode *inode) | 548 | static int drop_new_inode(struct inode *inode) |
541 | { | 549 | { |
542 | vfs_dq_drop(inode); | 550 | dquot_drop(inode); |
543 | make_bad_inode(inode); | 551 | make_bad_inode(inode); |
544 | inode->i_flags |= S_NOQUOTA; | 552 | inode->i_flags |= S_NOQUOTA; |
545 | iput(inode); | 553 | iput(inode); |
@@ -547,7 +555,7 @@ static int drop_new_inode(struct inode *inode) | |||
547 | } | 555 | } |
548 | 556 | ||
549 | /* utility function that does setup for reiserfs_new_inode. | 557 | /* utility function that does setup for reiserfs_new_inode. |
550 | ** vfs_dq_init needs lots of credits so it's better to have it | 558 | ** dquot_initialize needs lots of credits so it's better to have it |
551 | ** outside of a transaction, so we had to pull some bits of | 559 | ** outside of a transaction, so we had to pull some bits of |
552 | ** reiserfs_new_inode out into this func. | 560 | ** reiserfs_new_inode out into this func. |
553 | */ | 561 | */ |
@@ -570,7 +578,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) | |||
570 | } else { | 578 | } else { |
571 | inode->i_gid = current_fsgid(); | 579 | inode->i_gid = current_fsgid(); |
572 | } | 580 | } |
573 | vfs_dq_init(inode); | 581 | dquot_initialize(inode); |
574 | return 0; | 582 | return 0; |
575 | } | 583 | } |
576 | 584 | ||
@@ -587,6 +595,8 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
587 | struct reiserfs_transaction_handle th; | 595 | struct reiserfs_transaction_handle th; |
588 | struct reiserfs_security_handle security; | 596 | struct reiserfs_security_handle security; |
589 | 597 | ||
598 | dquot_initialize(dir); | ||
599 | |||
590 | if (!(inode = new_inode(dir->i_sb))) { | 600 | if (!(inode = new_inode(dir->i_sb))) { |
591 | return -ENOMEM; | 601 | return -ENOMEM; |
592 | } | 602 | } |
@@ -659,6 +669,8 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
659 | if (!new_valid_dev(rdev)) | 669 | if (!new_valid_dev(rdev)) |
660 | return -EINVAL; | 670 | return -EINVAL; |
661 | 671 | ||
672 | dquot_initialize(dir); | ||
673 | |||
662 | if (!(inode = new_inode(dir->i_sb))) { | 674 | if (!(inode = new_inode(dir->i_sb))) { |
663 | return -ENOMEM; | 675 | return -ENOMEM; |
664 | } | 676 | } |
@@ -725,12 +737,15 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
725 | struct inode *inode; | 737 | struct inode *inode; |
726 | struct reiserfs_transaction_handle th; | 738 | struct reiserfs_transaction_handle th; |
727 | struct reiserfs_security_handle security; | 739 | struct reiserfs_security_handle security; |
740 | int lock_depth; | ||
728 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ | 741 | /* We need blocks for transaction + (user+group)*(quotas for new inode + update of quota for directory owner) */ |
729 | int jbegin_count = | 742 | int jbegin_count = |
730 | JOURNAL_PER_BALANCE_CNT * 3 + | 743 | JOURNAL_PER_BALANCE_CNT * 3 + |
731 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + | 744 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + |
732 | REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); | 745 | REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); |
733 | 746 | ||
747 | dquot_initialize(dir); | ||
748 | |||
734 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES | 749 | #ifdef DISPLACE_NEW_PACKING_LOCALITIES |
735 | /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ | 750 | /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ |
736 | REISERFS_I(dir)->new_packing_locality = 1; | 751 | REISERFS_I(dir)->new_packing_locality = 1; |
@@ -748,7 +763,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
748 | return retval; | 763 | return retval; |
749 | } | 764 | } |
750 | jbegin_count += retval; | 765 | jbegin_count += retval; |
751 | reiserfs_write_lock(dir->i_sb); | 766 | lock_depth = reiserfs_write_lock_once(dir->i_sb); |
752 | 767 | ||
753 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 768 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
754 | if (retval) { | 769 | if (retval) { |
@@ -798,8 +813,8 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
798 | d_instantiate(dentry, inode); | 813 | d_instantiate(dentry, inode); |
799 | unlock_new_inode(inode); | 814 | unlock_new_inode(inode); |
800 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 815 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
801 | out_failed: | 816 | out_failed: |
802 | reiserfs_write_unlock(dir->i_sb); | 817 | reiserfs_write_unlock_once(dir->i_sb, lock_depth); |
803 | return retval; | 818 | return retval; |
804 | } | 819 | } |
805 | 820 | ||
@@ -834,6 +849,8 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
834 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + | 849 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
835 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 850 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
836 | 851 | ||
852 | dquot_initialize(dir); | ||
853 | |||
837 | reiserfs_write_lock(dir->i_sb); | 854 | reiserfs_write_lock(dir->i_sb); |
838 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 855 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
839 | if (retval) | 856 | if (retval) |
@@ -913,6 +930,9 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
913 | struct reiserfs_transaction_handle th; | 930 | struct reiserfs_transaction_handle th; |
914 | int jbegin_count; | 931 | int jbegin_count; |
915 | unsigned long savelink; | 932 | unsigned long savelink; |
933 | int depth; | ||
934 | |||
935 | dquot_initialize(dir); | ||
916 | 936 | ||
917 | inode = dentry->d_inode; | 937 | inode = dentry->d_inode; |
918 | 938 | ||
@@ -924,7 +944,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
924 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + | 944 | JOURNAL_PER_BALANCE_CNT * 2 + 2 + |
925 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 945 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
926 | 946 | ||
927 | reiserfs_write_lock(dir->i_sb); | 947 | depth = reiserfs_write_lock_once(dir->i_sb); |
928 | retval = journal_begin(&th, dir->i_sb, jbegin_count); | 948 | retval = journal_begin(&th, dir->i_sb, jbegin_count); |
929 | if (retval) | 949 | if (retval) |
930 | goto out_unlink; | 950 | goto out_unlink; |
@@ -985,7 +1005,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
985 | 1005 | ||
986 | retval = journal_end(&th, dir->i_sb, jbegin_count); | 1006 | retval = journal_end(&th, dir->i_sb, jbegin_count); |
987 | reiserfs_check_path(&path); | 1007 | reiserfs_check_path(&path); |
988 | reiserfs_write_unlock(dir->i_sb); | 1008 | reiserfs_write_unlock_once(dir->i_sb, depth); |
989 | return retval; | 1009 | return retval; |
990 | 1010 | ||
991 | end_unlink: | 1011 | end_unlink: |
@@ -995,7 +1015,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) | |||
995 | if (err) | 1015 | if (err) |
996 | retval = err; | 1016 | retval = err; |
997 | out_unlink: | 1017 | out_unlink: |
998 | reiserfs_write_unlock(dir->i_sb); | 1018 | reiserfs_write_unlock_once(dir->i_sb, depth); |
999 | return retval; | 1019 | return retval; |
1000 | } | 1020 | } |
1001 | 1021 | ||
@@ -1015,6 +1035,8 @@ static int reiserfs_symlink(struct inode *parent_dir, | |||
1015 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + | 1035 | 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + |
1016 | REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); | 1036 | REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); |
1017 | 1037 | ||
1038 | dquot_initialize(parent_dir); | ||
1039 | |||
1018 | if (!(inode = new_inode(parent_dir->i_sb))) { | 1040 | if (!(inode = new_inode(parent_dir->i_sb))) { |
1019 | return -ENOMEM; | 1041 | return -ENOMEM; |
1020 | } | 1042 | } |
@@ -1102,6 +1124,8 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1102 | JOURNAL_PER_BALANCE_CNT * 3 + | 1124 | JOURNAL_PER_BALANCE_CNT * 3 + |
1103 | 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); | 1125 | 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); |
1104 | 1126 | ||
1127 | dquot_initialize(dir); | ||
1128 | |||
1105 | reiserfs_write_lock(dir->i_sb); | 1129 | reiserfs_write_lock(dir->i_sb); |
1106 | if (inode->i_nlink >= REISERFS_LINK_MAX) { | 1130 | if (inode->i_nlink >= REISERFS_LINK_MAX) { |
1107 | //FIXME: sd_nlink is 32 bit for new files | 1131 | //FIXME: sd_nlink is 32 bit for new files |
@@ -1226,6 +1250,9 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
1226 | JOURNAL_PER_BALANCE_CNT * 3 + 5 + | 1250 | JOURNAL_PER_BALANCE_CNT * 3 + 5 + |
1227 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); | 1251 | 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); |
1228 | 1252 | ||
1253 | dquot_initialize(old_dir); | ||
1254 | dquot_initialize(new_dir); | ||
1255 | |||
1229 | old_inode = old_dentry->d_inode; | 1256 | old_inode = old_dentry->d_inode; |
1230 | new_dentry_inode = new_dentry->d_inode; | 1257 | new_dentry_inode = new_dentry->d_inode; |
1231 | 1258 | ||
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 536eacaeb710..adbc6f538515 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c | |||
@@ -349,10 +349,6 @@ void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...) | |||
349 | 349 | ||
350 | . */ | 350 | . */ |
351 | 351 | ||
352 | #ifdef CONFIG_REISERFS_CHECK | ||
353 | extern struct tree_balance *cur_tb; | ||
354 | #endif | ||
355 | |||
356 | void __reiserfs_panic(struct super_block *sb, const char *id, | 352 | void __reiserfs_panic(struct super_block *sb, const char *id, |
357 | const char *function, const char *fmt, ...) | 353 | const char *function, const char *fmt, ...) |
358 | { | 354 | { |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 9229e5514a4e..7a9981196c1c 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -17,8 +17,6 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
19 | 19 | ||
20 | #ifdef CONFIG_REISERFS_PROC_INFO | ||
21 | |||
22 | /* | 20 | /* |
23 | * LOCKING: | 21 | * LOCKING: |
24 | * | 22 | * |
@@ -48,14 +46,6 @@ static int show_version(struct seq_file *m, struct super_block *sb) | |||
48 | return 0; | 46 | return 0; |
49 | } | 47 | } |
50 | 48 | ||
51 | int reiserfs_global_version_in_proc(char *buffer, char **start, off_t offset, | ||
52 | int count, int *eof, void *data) | ||
53 | { | ||
54 | *start = buffer; | ||
55 | *eof = 1; | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | #define SF( x ) ( r -> x ) | 49 | #define SF( x ) ( r -> x ) |
60 | #define SFP( x ) SF( s_proc_info_data.x ) | 50 | #define SFP( x ) SF( s_proc_info_data.x ) |
61 | #define SFPL( x ) SFP( x[ level ] ) | 51 | #define SFPL( x ) SFP( x[ level ] ) |
@@ -538,19 +528,6 @@ int reiserfs_proc_info_done(struct super_block *sb) | |||
538 | return 0; | 528 | return 0; |
539 | } | 529 | } |
540 | 530 | ||
541 | struct proc_dir_entry *reiserfs_proc_register_global(char *name, | ||
542 | read_proc_t * func) | ||
543 | { | ||
544 | return (proc_info_root) ? create_proc_read_entry(name, 0, | ||
545 | proc_info_root, | ||
546 | func, NULL) : NULL; | ||
547 | } | ||
548 | |||
549 | void reiserfs_proc_unregister_global(const char *name) | ||
550 | { | ||
551 | remove_proc_entry(name, proc_info_root); | ||
552 | } | ||
553 | |||
554 | int reiserfs_proc_info_global_init(void) | 531 | int reiserfs_proc_info_global_init(void) |
555 | { | 532 | { |
556 | if (proc_info_root == NULL) { | 533 | if (proc_info_root == NULL) { |
@@ -572,48 +549,6 @@ int reiserfs_proc_info_global_done(void) | |||
572 | } | 549 | } |
573 | return 0; | 550 | return 0; |
574 | } | 551 | } |
575 | |||
576 | /* REISERFS_PROC_INFO */ | ||
577 | #else | ||
578 | |||
579 | int reiserfs_proc_info_init(struct super_block *sb) | ||
580 | { | ||
581 | return 0; | ||
582 | } | ||
583 | int reiserfs_proc_info_done(struct super_block *sb) | ||
584 | { | ||
585 | return 0; | ||
586 | } | ||
587 | |||
588 | struct proc_dir_entry *reiserfs_proc_register_global(char *name, | ||
589 | read_proc_t * func) | ||
590 | { | ||
591 | return NULL; | ||
592 | } | ||
593 | |||
594 | void reiserfs_proc_unregister_global(const char *name) | ||
595 | {; | ||
596 | } | ||
597 | |||
598 | int reiserfs_proc_info_global_init(void) | ||
599 | { | ||
600 | return 0; | ||
601 | } | ||
602 | int reiserfs_proc_info_global_done(void) | ||
603 | { | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | int reiserfs_global_version_in_proc(char *buffer, char **start, | ||
608 | off_t offset, | ||
609 | int count, int *eof, void *data) | ||
610 | { | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | /* REISERFS_PROC_INFO */ | ||
615 | #endif | ||
616 | |||
617 | /* | 552 | /* |
618 | * Revision 1.1.8.2 2001/07/15 17:08:42 god | 553 | * Revision 1.1.8.2 2001/07/15 17:08:42 god |
619 | * . use get_super() in procfs.c | 554 | * . use get_super() in procfs.c |
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 18b315d3d104..b3a94d20f0fc 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -141,7 +141,9 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
141 | 141 | ||
142 | set_buffer_uptodate(bh); | 142 | set_buffer_uptodate(bh); |
143 | mark_buffer_dirty(bh); | 143 | mark_buffer_dirty(bh); |
144 | reiserfs_write_unlock(s); | ||
144 | sync_dirty_buffer(bh); | 145 | sync_dirty_buffer(bh); |
146 | reiserfs_write_lock(s); | ||
145 | // update bitmap_info stuff | 147 | // update bitmap_info stuff |
146 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; | 148 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; |
147 | brelse(bh); | 149 | brelse(bh); |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index d036ee5b1c81..313d39d639eb 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -222,9 +222,6 @@ static inline int bin_search(const void *key, /* Key to search for. */ | |||
222 | return ITEM_NOT_FOUND; | 222 | return ITEM_NOT_FOUND; |
223 | } | 223 | } |
224 | 224 | ||
225 | #ifdef CONFIG_REISERFS_CHECK | ||
226 | extern struct tree_balance *cur_tb; | ||
227 | #endif | ||
228 | 225 | ||
229 | /* Minimal possible key. It is never in the tree. */ | 226 | /* Minimal possible key. It is never in the tree. */ |
230 | const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} }; | 227 | const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} }; |
@@ -519,25 +516,48 @@ static int is_tree_node(struct buffer_head *bh, int level) | |||
519 | 516 | ||
520 | #define SEARCH_BY_KEY_READA 16 | 517 | #define SEARCH_BY_KEY_READA 16 |
521 | 518 | ||
522 | /* The function is NOT SCHEDULE-SAFE! */ | 519 | /* |
523 | static void search_by_key_reada(struct super_block *s, | 520 | * The function is NOT SCHEDULE-SAFE! |
521 | * It might unlock the write lock if we needed to wait for a block | ||
522 | * to be read. Note that in this case it won't recover the lock to avoid | ||
523 | * high contention resulting from too much lock requests, especially | ||
524 | * the caller (search_by_key) will perform other schedule-unsafe | ||
525 | * operations just after calling this function. | ||
526 | * | ||
527 | * @return true if we have unlocked | ||
528 | */ | ||
529 | static bool search_by_key_reada(struct super_block *s, | ||
524 | struct buffer_head **bh, | 530 | struct buffer_head **bh, |
525 | b_blocknr_t *b, int num) | 531 | b_blocknr_t *b, int num) |
526 | { | 532 | { |
527 | int i, j; | 533 | int i, j; |
534 | bool unlocked = false; | ||
528 | 535 | ||
529 | for (i = 0; i < num; i++) { | 536 | for (i = 0; i < num; i++) { |
530 | bh[i] = sb_getblk(s, b[i]); | 537 | bh[i] = sb_getblk(s, b[i]); |
531 | } | 538 | } |
539 | /* | ||
540 | * We are going to read some blocks on which we | ||
541 | * have a reference. It's safe, though we might be | ||
542 | * reading blocks concurrently changed if we release | ||
543 | * the lock. But it's still fine because we check later | ||
544 | * if the tree changed | ||
545 | */ | ||
532 | for (j = 0; j < i; j++) { | 546 | for (j = 0; j < i; j++) { |
533 | /* | 547 | /* |
534 | * note, this needs attention if we are getting rid of the BKL | 548 | * note, this needs attention if we are getting rid of the BKL |
535 | * you have to make sure the prepared bit isn't set on this buffer | 549 | * you have to make sure the prepared bit isn't set on this buffer |
536 | */ | 550 | */ |
537 | if (!buffer_uptodate(bh[j])) | 551 | if (!buffer_uptodate(bh[j])) { |
552 | if (!unlocked) { | ||
553 | reiserfs_write_unlock(s); | ||
554 | unlocked = true; | ||
555 | } | ||
538 | ll_rw_block(READA, 1, bh + j); | 556 | ll_rw_block(READA, 1, bh + j); |
557 | } | ||
539 | brelse(bh[j]); | 558 | brelse(bh[j]); |
540 | } | 559 | } |
560 | return unlocked; | ||
541 | } | 561 | } |
542 | 562 | ||
543 | /************************************************************************** | 563 | /************************************************************************** |
@@ -625,11 +645,26 @@ int search_by_key(struct super_block *sb, const struct cpu_key *key, /* Key to s | |||
625 | have a pointer to it. */ | 645 | have a pointer to it. */ |
626 | if ((bh = last_element->pe_buffer = | 646 | if ((bh = last_element->pe_buffer = |
627 | sb_getblk(sb, block_number))) { | 647 | sb_getblk(sb, block_number))) { |
648 | bool unlocked = false; | ||
649 | |||
628 | if (!buffer_uptodate(bh) && reada_count > 1) | 650 | if (!buffer_uptodate(bh) && reada_count > 1) |
629 | search_by_key_reada(sb, reada_bh, | 651 | /* may unlock the write lock */ |
652 | unlocked = search_by_key_reada(sb, reada_bh, | ||
630 | reada_blocks, reada_count); | 653 | reada_blocks, reada_count); |
654 | /* | ||
655 | * If we haven't already unlocked the write lock, | ||
656 | * then we need to do that here before reading | ||
657 | * the current block | ||
658 | */ | ||
659 | if (!buffer_uptodate(bh) && !unlocked) { | ||
660 | reiserfs_write_unlock(sb); | ||
661 | unlocked = true; | ||
662 | } | ||
631 | ll_rw_block(READ, 1, &bh); | 663 | ll_rw_block(READ, 1, &bh); |
632 | wait_on_buffer(bh); | 664 | wait_on_buffer(bh); |
665 | |||
666 | if (unlocked) | ||
667 | reiserfs_write_lock(sb); | ||
633 | if (!buffer_uptodate(bh)) | 668 | if (!buffer_uptodate(bh)) |
634 | goto io_error; | 669 | goto io_error; |
635 | } else { | 670 | } else { |
@@ -673,7 +708,7 @@ int search_by_key(struct super_block *sb, const struct cpu_key *key, /* Key to s | |||
673 | !key_in_buffer(search_path, key, sb), | 708 | !key_in_buffer(search_path, key, sb), |
674 | "PAP-5130: key is not in the buffer"); | 709 | "PAP-5130: key is not in the buffer"); |
675 | #ifdef CONFIG_REISERFS_CHECK | 710 | #ifdef CONFIG_REISERFS_CHECK |
676 | if (cur_tb) { | 711 | if (REISERFS_SB(sb)->cur_tb) { |
677 | print_cur_tb("5140"); | 712 | print_cur_tb("5140"); |
678 | reiserfs_panic(sb, "PAP-5140", | 713 | reiserfs_panic(sb, "PAP-5140", |
679 | "schedule occurred in do_balance!"); | 714 | "schedule occurred in do_balance!"); |
@@ -1024,7 +1059,9 @@ static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, st | |||
1024 | reiserfs_free_block(th, inode, block, 1); | 1059 | reiserfs_free_block(th, inode, block, 1); |
1025 | } | 1060 | } |
1026 | 1061 | ||
1062 | reiserfs_write_unlock(sb); | ||
1027 | cond_resched(); | 1063 | cond_resched(); |
1064 | reiserfs_write_lock(sb); | ||
1028 | 1065 | ||
1029 | if (item_moved (&s_ih, path)) { | 1066 | if (item_moved (&s_ih, path)) { |
1030 | need_re_search = 1; | 1067 | need_re_search = 1; |
@@ -1262,7 +1299,7 @@ int reiserfs_delete_item(struct reiserfs_transaction_handle *th, | |||
1262 | "reiserquota delete_item(): freeing %u, id=%u type=%c", | 1299 | "reiserquota delete_item(): freeing %u, id=%u type=%c", |
1263 | quota_cut_bytes, inode->i_uid, head2type(&s_ih)); | 1300 | quota_cut_bytes, inode->i_uid, head2type(&s_ih)); |
1264 | #endif | 1301 | #endif |
1265 | vfs_dq_free_space_nodirty(inode, quota_cut_bytes); | 1302 | dquot_free_space_nodirty(inode, quota_cut_bytes); |
1266 | 1303 | ||
1267 | /* Return deleted body length */ | 1304 | /* Return deleted body length */ |
1268 | return ret_value; | 1305 | return ret_value; |
@@ -1346,7 +1383,7 @@ void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th, | |||
1346 | quota_cut_bytes, inode->i_uid, | 1383 | quota_cut_bytes, inode->i_uid, |
1347 | key2type(key)); | 1384 | key2type(key)); |
1348 | #endif | 1385 | #endif |
1349 | vfs_dq_free_space_nodirty(inode, | 1386 | dquot_free_space_nodirty(inode, |
1350 | quota_cut_bytes); | 1387 | quota_cut_bytes); |
1351 | } | 1388 | } |
1352 | break; | 1389 | break; |
@@ -1696,7 +1733,7 @@ int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th, | |||
1696 | "reiserquota cut_from_item(): freeing %u id=%u type=%c", | 1733 | "reiserquota cut_from_item(): freeing %u id=%u type=%c", |
1697 | quota_cut_bytes, inode->i_uid, '?'); | 1734 | quota_cut_bytes, inode->i_uid, '?'); |
1698 | #endif | 1735 | #endif |
1699 | vfs_dq_free_space_nodirty(inode, quota_cut_bytes); | 1736 | dquot_free_space_nodirty(inode, quota_cut_bytes); |
1700 | return ret_value; | 1737 | return ret_value; |
1701 | } | 1738 | } |
1702 | 1739 | ||
@@ -1931,9 +1968,10 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree | |||
1931 | key2type(&(key->on_disk_key))); | 1968 | key2type(&(key->on_disk_key))); |
1932 | #endif | 1969 | #endif |
1933 | 1970 | ||
1934 | if (vfs_dq_alloc_space_nodirty(inode, pasted_size)) { | 1971 | retval = dquot_alloc_space_nodirty(inode, pasted_size); |
1972 | if (retval) { | ||
1935 | pathrelse(search_path); | 1973 | pathrelse(search_path); |
1936 | return -EDQUOT; | 1974 | return retval; |
1937 | } | 1975 | } |
1938 | init_tb_struct(th, &s_paste_balance, th->t_super, search_path, | 1976 | init_tb_struct(th, &s_paste_balance, th->t_super, search_path, |
1939 | pasted_size); | 1977 | pasted_size); |
@@ -1987,7 +2025,7 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree | |||
1987 | pasted_size, inode->i_uid, | 2025 | pasted_size, inode->i_uid, |
1988 | key2type(&(key->on_disk_key))); | 2026 | key2type(&(key->on_disk_key))); |
1989 | #endif | 2027 | #endif |
1990 | vfs_dq_free_space_nodirty(inode, pasted_size); | 2028 | dquot_free_space_nodirty(inode, pasted_size); |
1991 | return retval; | 2029 | return retval; |
1992 | } | 2030 | } |
1993 | 2031 | ||
@@ -2025,9 +2063,10 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, | |||
2025 | #endif | 2063 | #endif |
2026 | /* We can't dirty inode here. It would be immediately written but | 2064 | /* We can't dirty inode here. It would be immediately written but |
2027 | * appropriate stat item isn't inserted yet... */ | 2065 | * appropriate stat item isn't inserted yet... */ |
2028 | if (vfs_dq_alloc_space_nodirty(inode, quota_bytes)) { | 2066 | retval = dquot_alloc_space_nodirty(inode, quota_bytes); |
2067 | if (retval) { | ||
2029 | pathrelse(path); | 2068 | pathrelse(path); |
2030 | return -EDQUOT; | 2069 | return retval; |
2031 | } | 2070 | } |
2032 | } | 2071 | } |
2033 | init_tb_struct(th, &s_ins_balance, th->t_super, path, | 2072 | init_tb_struct(th, &s_ins_balance, th->t_super, path, |
@@ -2076,6 +2115,6 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, | |||
2076 | quota_bytes, inode->i_uid, head2type(ih)); | 2115 | quota_bytes, inode->i_uid, head2type(ih)); |
2077 | #endif | 2116 | #endif |
2078 | if (inode) | 2117 | if (inode) |
2079 | vfs_dq_free_space_nodirty(inode, quota_bytes); | 2118 | dquot_free_space_nodirty(inode, quota_bytes); |
2080 | return retval; | 2119 | return retval; |
2081 | } | 2120 | } |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f0ad05f38022..59125fb36d42 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/slab.h> | ||
15 | #include <linux/vmalloc.h> | 16 | #include <linux/vmalloc.h> |
16 | #include <linux/time.h> | 17 | #include <linux/time.h> |
17 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
@@ -246,7 +247,7 @@ static int finish_unfinished(struct super_block *s) | |||
246 | retval = remove_save_link_only(s, &save_link_key, 0); | 247 | retval = remove_save_link_only(s, &save_link_key, 0); |
247 | continue; | 248 | continue; |
248 | } | 249 | } |
249 | vfs_dq_init(inode); | 250 | dquot_initialize(inode); |
250 | 251 | ||
251 | if (truncate && S_ISDIR(inode->i_mode)) { | 252 | if (truncate && S_ISDIR(inode->i_mode)) { |
252 | /* We got a truncate request for a dir which is impossible. | 253 | /* We got a truncate request for a dir which is impossible. |
@@ -465,7 +466,7 @@ static void reiserfs_put_super(struct super_block *s) | |||
465 | struct reiserfs_transaction_handle th; | 466 | struct reiserfs_transaction_handle th; |
466 | th.t_trans_id = 0; | 467 | th.t_trans_id = 0; |
467 | 468 | ||
468 | lock_kernel(); | 469 | reiserfs_write_lock(s); |
469 | 470 | ||
470 | if (s->s_dirt) | 471 | if (s->s_dirt) |
471 | reiserfs_write_super(s); | 472 | reiserfs_write_super(s); |
@@ -499,10 +500,10 @@ static void reiserfs_put_super(struct super_block *s) | |||
499 | 500 | ||
500 | reiserfs_proc_info_done(s); | 501 | reiserfs_proc_info_done(s); |
501 | 502 | ||
503 | reiserfs_write_unlock(s); | ||
504 | mutex_destroy(&REISERFS_SB(s)->lock); | ||
502 | kfree(s->s_fs_info); | 505 | kfree(s->s_fs_info); |
503 | s->s_fs_info = NULL; | 506 | s->s_fs_info = NULL; |
504 | |||
505 | unlock_kernel(); | ||
506 | } | 507 | } |
507 | 508 | ||
508 | static struct kmem_cache *reiserfs_inode_cachep; | 509 | static struct kmem_cache *reiserfs_inode_cachep; |
@@ -554,25 +555,33 @@ static void reiserfs_dirty_inode(struct inode *inode) | |||
554 | struct reiserfs_transaction_handle th; | 555 | struct reiserfs_transaction_handle th; |
555 | 556 | ||
556 | int err = 0; | 557 | int err = 0; |
558 | int lock_depth; | ||
559 | |||
557 | if (inode->i_sb->s_flags & MS_RDONLY) { | 560 | if (inode->i_sb->s_flags & MS_RDONLY) { |
558 | reiserfs_warning(inode->i_sb, "clm-6006", | 561 | reiserfs_warning(inode->i_sb, "clm-6006", |
559 | "writing inode %lu on readonly FS", | 562 | "writing inode %lu on readonly FS", |
560 | inode->i_ino); | 563 | inode->i_ino); |
561 | return; | 564 | return; |
562 | } | 565 | } |
563 | reiserfs_write_lock(inode->i_sb); | 566 | lock_depth = reiserfs_write_lock_once(inode->i_sb); |
564 | 567 | ||
565 | /* this is really only used for atime updates, so they don't have | 568 | /* this is really only used for atime updates, so they don't have |
566 | ** to be included in O_SYNC or fsync | 569 | ** to be included in O_SYNC or fsync |
567 | */ | 570 | */ |
568 | err = journal_begin(&th, inode->i_sb, 1); | 571 | err = journal_begin(&th, inode->i_sb, 1); |
569 | if (err) { | 572 | if (err) |
570 | reiserfs_write_unlock(inode->i_sb); | 573 | goto out; |
571 | return; | 574 | |
572 | } | ||
573 | reiserfs_update_sd(&th, inode); | 575 | reiserfs_update_sd(&th, inode); |
574 | journal_end(&th, inode->i_sb, 1); | 576 | journal_end(&th, inode->i_sb, 1); |
575 | reiserfs_write_unlock(inode->i_sb); | 577 | |
578 | out: | ||
579 | reiserfs_write_unlock_once(inode->i_sb, lock_depth); | ||
580 | } | ||
581 | |||
582 | static void reiserfs_clear_inode(struct inode *inode) | ||
583 | { | ||
584 | dquot_drop(inode); | ||
576 | } | 585 | } |
577 | 586 | ||
578 | #ifdef CONFIG_QUOTA | 587 | #ifdef CONFIG_QUOTA |
@@ -587,6 +596,7 @@ static const struct super_operations reiserfs_sops = { | |||
587 | .destroy_inode = reiserfs_destroy_inode, | 596 | .destroy_inode = reiserfs_destroy_inode, |
588 | .write_inode = reiserfs_write_inode, | 597 | .write_inode = reiserfs_write_inode, |
589 | .dirty_inode = reiserfs_dirty_inode, | 598 | .dirty_inode = reiserfs_dirty_inode, |
599 | .clear_inode = reiserfs_clear_inode, | ||
590 | .delete_inode = reiserfs_delete_inode, | 600 | .delete_inode = reiserfs_delete_inode, |
591 | .put_super = reiserfs_put_super, | 601 | .put_super = reiserfs_put_super, |
592 | .write_super = reiserfs_write_super, | 602 | .write_super = reiserfs_write_super, |
@@ -613,13 +623,6 @@ static int reiserfs_write_info(struct super_block *, int); | |||
613 | static int reiserfs_quota_on(struct super_block *, int, int, char *, int); | 623 | static int reiserfs_quota_on(struct super_block *, int, int, char *, int); |
614 | 624 | ||
615 | static const struct dquot_operations reiserfs_quota_operations = { | 625 | static const struct dquot_operations reiserfs_quota_operations = { |
616 | .initialize = dquot_initialize, | ||
617 | .drop = dquot_drop, | ||
618 | .alloc_space = dquot_alloc_space, | ||
619 | .alloc_inode = dquot_alloc_inode, | ||
620 | .free_space = dquot_free_space, | ||
621 | .free_inode = dquot_free_inode, | ||
622 | .transfer = dquot_transfer, | ||
623 | .write_dquot = reiserfs_write_dquot, | 626 | .write_dquot = reiserfs_write_dquot, |
624 | .acquire_dquot = reiserfs_acquire_dquot, | 627 | .acquire_dquot = reiserfs_acquire_dquot, |
625 | .release_dquot = reiserfs_release_dquot, | 628 | .release_dquot = reiserfs_release_dquot, |
@@ -1168,11 +1171,14 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1168 | unsigned int qfmt = 0; | 1171 | unsigned int qfmt = 0; |
1169 | #ifdef CONFIG_QUOTA | 1172 | #ifdef CONFIG_QUOTA |
1170 | int i; | 1173 | int i; |
1174 | #endif | ||
1175 | |||
1176 | reiserfs_write_lock(s); | ||
1171 | 1177 | ||
1178 | #ifdef CONFIG_QUOTA | ||
1172 | memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names)); | 1179 | memcpy(qf_names, REISERFS_SB(s)->s_qf_names, sizeof(qf_names)); |
1173 | #endif | 1180 | #endif |
1174 | 1181 | ||
1175 | lock_kernel(); | ||
1176 | rs = SB_DISK_SUPER_BLOCK(s); | 1182 | rs = SB_DISK_SUPER_BLOCK(s); |
1177 | 1183 | ||
1178 | if (!reiserfs_parse_options | 1184 | if (!reiserfs_parse_options |
@@ -1295,12 +1301,12 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) | |||
1295 | 1301 | ||
1296 | out_ok: | 1302 | out_ok: |
1297 | replace_mount_options(s, new_opts); | 1303 | replace_mount_options(s, new_opts); |
1298 | unlock_kernel(); | 1304 | reiserfs_write_unlock(s); |
1299 | return 0; | 1305 | return 0; |
1300 | 1306 | ||
1301 | out_err: | 1307 | out_err: |
1302 | kfree(new_opts); | 1308 | kfree(new_opts); |
1303 | unlock_kernel(); | 1309 | reiserfs_write_unlock(s); |
1304 | return err; | 1310 | return err; |
1305 | } | 1311 | } |
1306 | 1312 | ||
@@ -1404,7 +1410,9 @@ static int read_super_block(struct super_block *s, int offset) | |||
1404 | static int reread_meta_blocks(struct super_block *s) | 1410 | static int reread_meta_blocks(struct super_block *s) |
1405 | { | 1411 | { |
1406 | ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); | 1412 | ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))); |
1413 | reiserfs_write_unlock(s); | ||
1407 | wait_on_buffer(SB_BUFFER_WITH_SB(s)); | 1414 | wait_on_buffer(SB_BUFFER_WITH_SB(s)); |
1415 | reiserfs_write_lock(s); | ||
1408 | if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { | 1416 | if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { |
1409 | reiserfs_warning(s, "reiserfs-2504", "error reading the super"); | 1417 | reiserfs_warning(s, "reiserfs-2504", "error reading the super"); |
1410 | return 1; | 1418 | return 1; |
@@ -1611,10 +1619,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1611 | save_mount_options(s, data); | 1619 | save_mount_options(s, data); |
1612 | 1620 | ||
1613 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); | 1621 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); |
1614 | if (!sbi) { | 1622 | if (!sbi) |
1615 | errval = -ENOMEM; | 1623 | return -ENOMEM; |
1616 | goto error; | ||
1617 | } | ||
1618 | s->s_fs_info = sbi; | 1624 | s->s_fs_info = sbi; |
1619 | /* Set default values for options: non-aggressive tails, RO on errors */ | 1625 | /* Set default values for options: non-aggressive tails, RO on errors */ |
1620 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); | 1626 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); |
@@ -1627,6 +1633,20 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1627 | /* setup default block allocator options */ | 1633 | /* setup default block allocator options */ |
1628 | reiserfs_init_alloc_options(s); | 1634 | reiserfs_init_alloc_options(s); |
1629 | 1635 | ||
1636 | mutex_init(&REISERFS_SB(s)->lock); | ||
1637 | REISERFS_SB(s)->lock_depth = -1; | ||
1638 | |||
1639 | /* | ||
1640 | * This function is called with the bkl, which also was the old | ||
1641 | * locking used here. | ||
1642 | * do_journal_begin() will soon check if we hold the lock (ie: was the | ||
1643 | * bkl). This is likely because do_journal_begin() has several another | ||
1644 | * callers because at this time, it doesn't seem to be necessary to | ||
1645 | * protect against anything. | ||
1646 | * Anyway, let's be conservative and lock for now. | ||
1647 | */ | ||
1648 | reiserfs_write_lock(s); | ||
1649 | |||
1630 | jdev_name = NULL; | 1650 | jdev_name = NULL; |
1631 | if (reiserfs_parse_options | 1651 | if (reiserfs_parse_options |
1632 | (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name, | 1652 | (s, (char *)data, &(sbi->s_mount_opt), &blocks, &jdev_name, |
@@ -1852,6 +1872,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1852 | init_waitqueue_head(&(sbi->s_wait)); | 1872 | init_waitqueue_head(&(sbi->s_wait)); |
1853 | spin_lock_init(&sbi->bitmap_lock); | 1873 | spin_lock_init(&sbi->bitmap_lock); |
1854 | 1874 | ||
1875 | reiserfs_write_unlock(s); | ||
1876 | |||
1855 | return (0); | 1877 | return (0); |
1856 | 1878 | ||
1857 | error: | 1879 | error: |
@@ -1859,6 +1881,8 @@ error: | |||
1859 | journal_release_error(NULL, s); | 1881 | journal_release_error(NULL, s); |
1860 | } | 1882 | } |
1861 | 1883 | ||
1884 | reiserfs_write_unlock(s); | ||
1885 | |||
1862 | reiserfs_free_bitmap_cache(s); | 1886 | reiserfs_free_bitmap_cache(s); |
1863 | if (SB_BUFFER_WITH_SB(s)) | 1887 | if (SB_BUFFER_WITH_SB(s)) |
1864 | brelse(SB_BUFFER_WITH_SB(s)); | 1888 | brelse(SB_BUFFER_WITH_SB(s)); |
@@ -2196,8 +2220,6 @@ static int __init init_reiserfs_fs(void) | |||
2196 | } | 2220 | } |
2197 | 2221 | ||
2198 | reiserfs_proc_info_global_init(); | 2222 | reiserfs_proc_info_global_init(); |
2199 | reiserfs_proc_register_global("version", | ||
2200 | reiserfs_global_version_in_proc); | ||
2201 | 2223 | ||
2202 | ret = register_filesystem(&reiserfs_fs_type); | 2224 | ret = register_filesystem(&reiserfs_fs_type); |
2203 | 2225 | ||
@@ -2205,7 +2227,6 @@ static int __init init_reiserfs_fs(void) | |||
2205 | return 0; | 2227 | return 0; |
2206 | } | 2228 | } |
2207 | 2229 | ||
2208 | reiserfs_proc_unregister_global("version"); | ||
2209 | reiserfs_proc_info_global_done(); | 2230 | reiserfs_proc_info_global_done(); |
2210 | destroy_inodecache(); | 2231 | destroy_inodecache(); |
2211 | 2232 | ||
@@ -2214,7 +2235,6 @@ static int __init init_reiserfs_fs(void) | |||
2214 | 2235 | ||
2215 | static void __exit exit_reiserfs_fs(void) | 2236 | static void __exit exit_reiserfs_fs(void) |
2216 | { | 2237 | { |
2217 | reiserfs_proc_unregister_global("version"); | ||
2218 | reiserfs_proc_info_global_done(); | 2238 | reiserfs_proc_info_global_done(); |
2219 | unregister_filesystem(&reiserfs_fs_type); | 2239 | unregister_filesystem(&reiserfs_fs_type); |
2220 | destroy_inodecache(); | 2240 | destroy_inodecache(); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 6925b835a43b..e7cc00e636dc 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/dcache.h> | 38 | #include <linux/dcache.h> |
39 | #include <linux/namei.h> | 39 | #include <linux/namei.h> |
40 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
41 | #include <linux/gfp.h> | ||
41 | #include <linux/fs.h> | 42 | #include <linux/fs.h> |
42 | #include <linux/file.h> | 43 | #include <linux/file.h> |
43 | #include <linux/pagemap.h> | 44 | #include <linux/pagemap.h> |
@@ -48,6 +49,7 @@ | |||
48 | #include <net/checksum.h> | 49 | #include <net/checksum.h> |
49 | #include <linux/stat.h> | 50 | #include <linux/stat.h> |
50 | #include <linux/quotaops.h> | 51 | #include <linux/quotaops.h> |
52 | #include <linux/security.h> | ||
51 | 53 | ||
52 | #define PRIVROOT_NAME ".reiserfs_priv" | 54 | #define PRIVROOT_NAME ".reiserfs_priv" |
53 | #define XAROOT_NAME "xattrs" | 55 | #define XAROOT_NAME "xattrs" |
@@ -60,7 +62,6 @@ | |||
60 | static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) | 62 | static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) |
61 | { | 63 | { |
62 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 64 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
63 | vfs_dq_init(dir); | ||
64 | return dir->i_op->create(dir, dentry, mode, NULL); | 65 | return dir->i_op->create(dir, dentry, mode, NULL); |
65 | } | 66 | } |
66 | #endif | 67 | #endif |
@@ -68,7 +69,6 @@ static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) | |||
68 | static int xattr_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 69 | static int xattr_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
69 | { | 70 | { |
70 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 71 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
71 | vfs_dq_init(dir); | ||
72 | return dir->i_op->mkdir(dir, dentry, mode); | 72 | return dir->i_op->mkdir(dir, dentry, mode); |
73 | } | 73 | } |
74 | 74 | ||
@@ -80,9 +80,9 @@ static int xattr_unlink(struct inode *dir, struct dentry *dentry) | |||
80 | { | 80 | { |
81 | int error; | 81 | int error; |
82 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 82 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
83 | vfs_dq_init(dir); | ||
84 | 83 | ||
85 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 84 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
85 | I_MUTEX_CHILD, dir->i_sb); | ||
86 | error = dir->i_op->unlink(dir, dentry); | 86 | error = dir->i_op->unlink(dir, dentry); |
87 | mutex_unlock(&dentry->d_inode->i_mutex); | 87 | mutex_unlock(&dentry->d_inode->i_mutex); |
88 | 88 | ||
@@ -95,9 +95,9 @@ static int xattr_rmdir(struct inode *dir, struct dentry *dentry) | |||
95 | { | 95 | { |
96 | int error; | 96 | int error; |
97 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); | 97 | BUG_ON(!mutex_is_locked(&dir->i_mutex)); |
98 | vfs_dq_init(dir); | ||
99 | 98 | ||
100 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | 99 | reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, |
100 | I_MUTEX_CHILD, dir->i_sb); | ||
101 | dentry_unhash(dentry); | 101 | dentry_unhash(dentry); |
102 | error = dir->i_op->rmdir(dir, dentry); | 102 | error = dir->i_op->rmdir(dir, dentry); |
103 | if (!error) | 103 | if (!error) |
@@ -234,16 +234,22 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
234 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) | 234 | if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1) |
235 | return 0; | 235 | return 0; |
236 | 236 | ||
237 | reiserfs_write_unlock(inode->i_sb); | ||
237 | dir = open_xa_dir(inode, XATTR_REPLACE); | 238 | dir = open_xa_dir(inode, XATTR_REPLACE); |
238 | if (IS_ERR(dir)) { | 239 | if (IS_ERR(dir)) { |
239 | err = PTR_ERR(dir); | 240 | err = PTR_ERR(dir); |
241 | reiserfs_write_lock(inode->i_sb); | ||
240 | goto out; | 242 | goto out; |
241 | } else if (!dir->d_inode) { | 243 | } else if (!dir->d_inode) { |
242 | err = 0; | 244 | err = 0; |
245 | reiserfs_write_lock(inode->i_sb); | ||
243 | goto out_dir; | 246 | goto out_dir; |
244 | } | 247 | } |
245 | 248 | ||
246 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 249 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
250 | |||
251 | reiserfs_write_lock(inode->i_sb); | ||
252 | |||
247 | buf.xadir = dir; | 253 | buf.xadir = dir; |
248 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); | 254 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); |
249 | while ((err == 0 || err == -ENOSPC) && buf.count) { | 255 | while ((err == 0 || err == -ENOSPC) && buf.count) { |
@@ -282,8 +288,9 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
282 | err = journal_begin(&th, inode->i_sb, blocks); | 288 | err = journal_begin(&th, inode->i_sb, blocks); |
283 | if (!err) { | 289 | if (!err) { |
284 | int jerror; | 290 | int jerror; |
285 | mutex_lock_nested(&dir->d_parent->d_inode->i_mutex, | 291 | reiserfs_mutex_lock_nested_safe( |
286 | I_MUTEX_XATTR); | 292 | &dir->d_parent->d_inode->i_mutex, |
293 | I_MUTEX_XATTR, inode->i_sb); | ||
287 | err = action(dir, data); | 294 | err = action(dir, data); |
288 | jerror = journal_end(&th, inode->i_sb, blocks); | 295 | jerror = journal_end(&th, inode->i_sb, blocks); |
289 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); | 296 | mutex_unlock(&dir->d_parent->d_inode->i_mutex); |
@@ -442,7 +449,9 @@ static int lookup_and_delete_xattr(struct inode *inode, const char *name) | |||
442 | } | 449 | } |
443 | 450 | ||
444 | if (dentry->d_inode) { | 451 | if (dentry->d_inode) { |
452 | reiserfs_write_lock(inode->i_sb); | ||
445 | err = xattr_unlink(xadir->d_inode, dentry); | 453 | err = xattr_unlink(xadir->d_inode, dentry); |
454 | reiserfs_write_unlock(inode->i_sb); | ||
446 | update_ctime(inode); | 455 | update_ctime(inode); |
447 | } | 456 | } |
448 | 457 | ||
@@ -476,15 +485,24 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
476 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | 485 | if (get_inode_sd_version(inode) == STAT_DATA_V1) |
477 | return -EOPNOTSUPP; | 486 | return -EOPNOTSUPP; |
478 | 487 | ||
479 | if (!buffer) | 488 | reiserfs_write_unlock(inode->i_sb); |
480 | return lookup_and_delete_xattr(inode, name); | 489 | |
490 | if (!buffer) { | ||
491 | err = lookup_and_delete_xattr(inode, name); | ||
492 | reiserfs_write_lock(inode->i_sb); | ||
493 | return err; | ||
494 | } | ||
481 | 495 | ||
482 | dentry = xattr_lookup(inode, name, flags); | 496 | dentry = xattr_lookup(inode, name, flags); |
483 | if (IS_ERR(dentry)) | 497 | if (IS_ERR(dentry)) { |
498 | reiserfs_write_lock(inode->i_sb); | ||
484 | return PTR_ERR(dentry); | 499 | return PTR_ERR(dentry); |
500 | } | ||
485 | 501 | ||
486 | down_write(&REISERFS_I(inode)->i_xattr_sem); | 502 | down_write(&REISERFS_I(inode)->i_xattr_sem); |
487 | 503 | ||
504 | reiserfs_write_lock(inode->i_sb); | ||
505 | |||
488 | xahash = xattr_hash(buffer, buffer_size); | 506 | xahash = xattr_hash(buffer, buffer_size); |
489 | while (buffer_pos < buffer_size || buffer_pos == 0) { | 507 | while (buffer_pos < buffer_size || buffer_pos == 0) { |
490 | size_t chunk; | 508 | size_t chunk; |
@@ -536,11 +554,15 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th, | |||
536 | if (!err && new_size < i_size_read(dentry->d_inode)) { | 554 | if (!err && new_size < i_size_read(dentry->d_inode)) { |
537 | struct iattr newattrs = { | 555 | struct iattr newattrs = { |
538 | .ia_ctime = current_fs_time(inode->i_sb), | 556 | .ia_ctime = current_fs_time(inode->i_sb), |
539 | .ia_size = buffer_size, | 557 | .ia_size = new_size, |
540 | .ia_valid = ATTR_SIZE | ATTR_CTIME, | 558 | .ia_valid = ATTR_SIZE | ATTR_CTIME, |
541 | }; | 559 | }; |
560 | |||
561 | reiserfs_write_unlock(inode->i_sb); | ||
542 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); | 562 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); |
543 | down_write(&dentry->d_inode->i_alloc_sem); | 563 | down_write(&dentry->d_inode->i_alloc_sem); |
564 | reiserfs_write_lock(inode->i_sb); | ||
565 | |||
544 | err = reiserfs_setattr(dentry, &newattrs); | 566 | err = reiserfs_setattr(dentry, &newattrs); |
545 | up_write(&dentry->d_inode->i_alloc_sem); | 567 | up_write(&dentry->d_inode->i_alloc_sem); |
546 | mutex_unlock(&dentry->d_inode->i_mutex); | 568 | mutex_unlock(&dentry->d_inode->i_mutex); |
@@ -726,15 +748,14 @@ ssize_t | |||
726 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | 748 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, |
727 | size_t size) | 749 | size_t size) |
728 | { | 750 | { |
729 | struct inode *inode = dentry->d_inode; | ||
730 | struct xattr_handler *handler; | 751 | struct xattr_handler *handler; |
731 | 752 | ||
732 | handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | 753 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
733 | 754 | ||
734 | if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | 755 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
735 | return -EOPNOTSUPP; | 756 | return -EOPNOTSUPP; |
736 | 757 | ||
737 | return handler->get(inode, name, buffer, size); | 758 | return handler->get(dentry, name, buffer, size, handler->flags); |
738 | } | 759 | } |
739 | 760 | ||
740 | /* | 761 | /* |
@@ -746,15 +767,14 @@ int | |||
746 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 767 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
747 | size_t size, int flags) | 768 | size_t size, int flags) |
748 | { | 769 | { |
749 | struct inode *inode = dentry->d_inode; | ||
750 | struct xattr_handler *handler; | 770 | struct xattr_handler *handler; |
751 | 771 | ||
752 | handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | 772 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
753 | 773 | ||
754 | if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | 774 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
755 | return -EOPNOTSUPP; | 775 | return -EOPNOTSUPP; |
756 | 776 | ||
757 | return handler->set(inode, name, value, size, flags); | 777 | return handler->set(dentry, name, value, size, flags, handler->flags); |
758 | } | 778 | } |
759 | 779 | ||
760 | /* | 780 | /* |
@@ -764,21 +784,20 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |||
764 | */ | 784 | */ |
765 | int reiserfs_removexattr(struct dentry *dentry, const char *name) | 785 | int reiserfs_removexattr(struct dentry *dentry, const char *name) |
766 | { | 786 | { |
767 | struct inode *inode = dentry->d_inode; | ||
768 | struct xattr_handler *handler; | 787 | struct xattr_handler *handler; |
769 | handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | 788 | handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); |
770 | 789 | ||
771 | if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | 790 | if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) |
772 | return -EOPNOTSUPP; | 791 | return -EOPNOTSUPP; |
773 | 792 | ||
774 | return handler->set(inode, name, NULL, 0, XATTR_REPLACE); | 793 | return handler->set(dentry, name, NULL, 0, XATTR_REPLACE, handler->flags); |
775 | } | 794 | } |
776 | 795 | ||
777 | struct listxattr_buf { | 796 | struct listxattr_buf { |
778 | size_t size; | 797 | size_t size; |
779 | size_t pos; | 798 | size_t pos; |
780 | char *buf; | 799 | char *buf; |
781 | struct inode *inode; | 800 | struct dentry *dentry; |
782 | }; | 801 | }; |
783 | 802 | ||
784 | static int listxattr_filler(void *buf, const char *name, int namelen, | 803 | static int listxattr_filler(void *buf, const char *name, int namelen, |
@@ -789,17 +808,19 @@ static int listxattr_filler(void *buf, const char *name, int namelen, | |||
789 | if (name[0] != '.' || | 808 | if (name[0] != '.' || |
790 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { | 809 | (namelen != 1 && (name[1] != '.' || namelen != 2))) { |
791 | struct xattr_handler *handler; | 810 | struct xattr_handler *handler; |
792 | handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr, | 811 | handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, |
793 | name); | 812 | name); |
794 | if (!handler) /* Unsupported xattr name */ | 813 | if (!handler) /* Unsupported xattr name */ |
795 | return 0; | 814 | return 0; |
796 | if (b->buf) { | 815 | if (b->buf) { |
797 | size = handler->list(b->inode, b->buf + b->pos, | 816 | size = handler->list(b->dentry, b->buf + b->pos, |
798 | b->size, name, namelen); | 817 | b->size, name, namelen, |
818 | handler->flags); | ||
799 | if (size > b->size) | 819 | if (size > b->size) |
800 | return -ERANGE; | 820 | return -ERANGE; |
801 | } else { | 821 | } else { |
802 | size = handler->list(b->inode, NULL, 0, name, namelen); | 822 | size = handler->list(b->dentry, NULL, 0, name, |
823 | namelen, handler->flags); | ||
803 | } | 824 | } |
804 | 825 | ||
805 | b->pos += size; | 826 | b->pos += size; |
@@ -820,7 +841,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
820 | int err = 0; | 841 | int err = 0; |
821 | loff_t pos = 0; | 842 | loff_t pos = 0; |
822 | struct listxattr_buf buf = { | 843 | struct listxattr_buf buf = { |
823 | .inode = dentry->d_inode, | 844 | .dentry = dentry, |
824 | .buf = buffer, | 845 | .buf = buffer, |
825 | .size = buffer ? size : 0, | 846 | .size = buffer ? size : 0, |
826 | }; | 847 | }; |
@@ -952,21 +973,13 @@ int reiserfs_permission(struct inode *inode, int mask) | |||
952 | return generic_permission(inode, mask, NULL); | 973 | return generic_permission(inode, mask, NULL); |
953 | } | 974 | } |
954 | 975 | ||
955 | /* This will catch lookups from the fs root to .reiserfs_priv */ | 976 | static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) |
956 | static int | ||
957 | xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name) | ||
958 | { | 977 | { |
959 | struct dentry *priv_root = REISERFS_SB(dentry->d_sb)->priv_root; | 978 | return -EPERM; |
960 | if (container_of(q1, struct dentry, d_name) == priv_root) | ||
961 | return -ENOENT; | ||
962 | if (q1->len == name->len && | ||
963 | !memcmp(q1->name, name->name, name->len)) | ||
964 | return 0; | ||
965 | return 1; | ||
966 | } | 979 | } |
967 | 980 | ||
968 | static const struct dentry_operations xattr_lookup_poison_ops = { | 981 | static const struct dentry_operations xattr_lookup_poison_ops = { |
969 | .d_compare = xattr_lookup_poison, | 982 | .d_revalidate = xattr_hide_revalidate, |
970 | }; | 983 | }; |
971 | 984 | ||
972 | int reiserfs_lookup_privroot(struct super_block *s) | 985 | int reiserfs_lookup_privroot(struct super_block *s) |
@@ -975,13 +988,12 @@ int reiserfs_lookup_privroot(struct super_block *s) | |||
975 | int err = 0; | 988 | int err = 0; |
976 | 989 | ||
977 | /* If we don't have the privroot located yet - go find it */ | 990 | /* If we don't have the privroot located yet - go find it */ |
978 | mutex_lock(&s->s_root->d_inode->i_mutex); | 991 | reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s); |
979 | dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, | 992 | dentry = lookup_one_len(PRIVROOT_NAME, s->s_root, |
980 | strlen(PRIVROOT_NAME)); | 993 | strlen(PRIVROOT_NAME)); |
981 | if (!IS_ERR(dentry)) { | 994 | if (!IS_ERR(dentry)) { |
982 | REISERFS_SB(s)->priv_root = dentry; | 995 | REISERFS_SB(s)->priv_root = dentry; |
983 | if (!reiserfs_expose_privroot(s)) | 996 | dentry->d_op = &xattr_lookup_poison_ops; |
984 | s->s_root->d_op = &xattr_lookup_poison_ops; | ||
985 | if (dentry->d_inode) | 997 | if (dentry->d_inode) |
986 | dentry->d_inode->i_flags |= S_PRIVATE; | 998 | dentry->d_inode->i_flags |= S_PRIVATE; |
987 | } else | 999 | } else |
@@ -1004,14 +1016,14 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
1004 | goto error; | 1016 | goto error; |
1005 | 1017 | ||
1006 | if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) { | 1018 | if (!privroot->d_inode && !(mount_flags & MS_RDONLY)) { |
1007 | mutex_lock(&s->s_root->d_inode->i_mutex); | 1019 | reiserfs_mutex_lock_safe(&s->s_root->d_inode->i_mutex, s); |
1008 | err = create_privroot(REISERFS_SB(s)->priv_root); | 1020 | err = create_privroot(REISERFS_SB(s)->priv_root); |
1009 | mutex_unlock(&s->s_root->d_inode->i_mutex); | 1021 | mutex_unlock(&s->s_root->d_inode->i_mutex); |
1010 | } | 1022 | } |
1011 | 1023 | ||
1012 | if (privroot->d_inode) { | 1024 | if (privroot->d_inode) { |
1013 | s->s_xattr = reiserfs_xattr_handlers; | 1025 | s->s_xattr = reiserfs_xattr_handlers; |
1014 | mutex_lock(&privroot->d_inode->i_mutex); | 1026 | reiserfs_mutex_lock_safe(&privroot->d_inode->i_mutex, s); |
1015 | if (!REISERFS_SB(s)->xattr_root) { | 1027 | if (!REISERFS_SB(s)->xattr_root) { |
1016 | struct dentry *dentry; | 1028 | struct dentry *dentry; |
1017 | dentry = lookup_one_len(XAROOT_NAME, privroot, | 1029 | dentry = lookup_one_len(XAROOT_NAME, privroot, |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 35d6e672a279..9cdb759645a9 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/errno.h> | 5 | #include <linux/errno.h> |
6 | #include <linux/pagemap.h> | 6 | #include <linux/pagemap.h> |
7 | #include <linux/xattr.h> | 7 | #include <linux/xattr.h> |
8 | #include <linux/slab.h> | ||
8 | #include <linux/posix_acl_xattr.h> | 9 | #include <linux/posix_acl_xattr.h> |
9 | #include <linux/reiserfs_xattr.h> | 10 | #include <linux/reiserfs_xattr.h> |
10 | #include <linux/reiserfs_acl.h> | 11 | #include <linux/reiserfs_acl.h> |
@@ -15,8 +16,10 @@ static int reiserfs_set_acl(struct reiserfs_transaction_handle *th, | |||
15 | struct posix_acl *acl); | 16 | struct posix_acl *acl); |
16 | 17 | ||
17 | static int | 18 | static int |
18 | xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) | 19 | posix_acl_set(struct dentry *dentry, const char *name, const void *value, |
20 | size_t size, int flags, int type) | ||
19 | { | 21 | { |
22 | struct inode *inode = dentry->d_inode; | ||
20 | struct posix_acl *acl; | 23 | struct posix_acl *acl; |
21 | int error, error2; | 24 | int error, error2; |
22 | struct reiserfs_transaction_handle th; | 25 | struct reiserfs_transaction_handle th; |
@@ -60,15 +63,16 @@ xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) | |||
60 | } | 63 | } |
61 | 64 | ||
62 | static int | 65 | static int |
63 | xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) | 66 | posix_acl_get(struct dentry *dentry, const char *name, void *buffer, |
67 | size_t size, int type) | ||
64 | { | 68 | { |
65 | struct posix_acl *acl; | 69 | struct posix_acl *acl; |
66 | int error; | 70 | int error; |
67 | 71 | ||
68 | if (!reiserfs_posixacl(inode->i_sb)) | 72 | if (!reiserfs_posixacl(dentry->d_sb)) |
69 | return -EOPNOTSUPP; | 73 | return -EOPNOTSUPP; |
70 | 74 | ||
71 | acl = reiserfs_get_acl(inode, type); | 75 | acl = reiserfs_get_acl(dentry->d_inode, type); |
72 | if (IS_ERR(acl)) | 76 | if (IS_ERR(acl)) |
73 | return PTR_ERR(acl); | 77 | return PTR_ERR(acl); |
74 | if (acl == NULL) | 78 | if (acl == NULL) |
@@ -452,7 +456,9 @@ int reiserfs_acl_chmod(struct inode *inode) | |||
452 | return 0; | 456 | return 0; |
453 | } | 457 | } |
454 | 458 | ||
459 | reiserfs_write_unlock(inode->i_sb); | ||
455 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); | 460 | acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS); |
461 | reiserfs_write_lock(inode->i_sb); | ||
456 | if (!acl) | 462 | if (!acl) |
457 | return 0; | 463 | return 0; |
458 | if (IS_ERR(acl)) | 464 | if (IS_ERR(acl)) |
@@ -482,30 +488,12 @@ int reiserfs_acl_chmod(struct inode *inode) | |||
482 | return error; | 488 | return error; |
483 | } | 489 | } |
484 | 490 | ||
485 | static int | 491 | static size_t posix_acl_access_list(struct dentry *dentry, char *list, |
486 | posix_acl_access_get(struct inode *inode, const char *name, | ||
487 | void *buffer, size_t size) | ||
488 | { | ||
489 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) | ||
490 | return -EINVAL; | ||
491 | return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); | ||
492 | } | ||
493 | |||
494 | static int | ||
495 | posix_acl_access_set(struct inode *inode, const char *name, | ||
496 | const void *value, size_t size, int flags) | ||
497 | { | ||
498 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) | ||
499 | return -EINVAL; | ||
500 | return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); | ||
501 | } | ||
502 | |||
503 | static size_t posix_acl_access_list(struct inode *inode, char *list, | ||
504 | size_t list_size, const char *name, | 492 | size_t list_size, const char *name, |
505 | size_t name_len) | 493 | size_t name_len, int type) |
506 | { | 494 | { |
507 | const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); | 495 | const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); |
508 | if (!reiserfs_posixacl(inode->i_sb)) | 496 | if (!reiserfs_posixacl(dentry->d_sb)) |
509 | return 0; | 497 | return 0; |
510 | if (list && size <= list_size) | 498 | if (list && size <= list_size) |
511 | memcpy(list, POSIX_ACL_XATTR_ACCESS, size); | 499 | memcpy(list, POSIX_ACL_XATTR_ACCESS, size); |
@@ -514,35 +502,18 @@ static size_t posix_acl_access_list(struct inode *inode, char *list, | |||
514 | 502 | ||
515 | struct xattr_handler reiserfs_posix_acl_access_handler = { | 503 | struct xattr_handler reiserfs_posix_acl_access_handler = { |
516 | .prefix = POSIX_ACL_XATTR_ACCESS, | 504 | .prefix = POSIX_ACL_XATTR_ACCESS, |
517 | .get = posix_acl_access_get, | 505 | .flags = ACL_TYPE_ACCESS, |
518 | .set = posix_acl_access_set, | 506 | .get = posix_acl_get, |
507 | .set = posix_acl_set, | ||
519 | .list = posix_acl_access_list, | 508 | .list = posix_acl_access_list, |
520 | }; | 509 | }; |
521 | 510 | ||
522 | static int | 511 | static size_t posix_acl_default_list(struct dentry *dentry, char *list, |
523 | posix_acl_default_get(struct inode *inode, const char *name, | ||
524 | void *buffer, size_t size) | ||
525 | { | ||
526 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) | ||
527 | return -EINVAL; | ||
528 | return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); | ||
529 | } | ||
530 | |||
531 | static int | ||
532 | posix_acl_default_set(struct inode *inode, const char *name, | ||
533 | const void *value, size_t size, int flags) | ||
534 | { | ||
535 | if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) | ||
536 | return -EINVAL; | ||
537 | return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); | ||
538 | } | ||
539 | |||
540 | static size_t posix_acl_default_list(struct inode *inode, char *list, | ||
541 | size_t list_size, const char *name, | 512 | size_t list_size, const char *name, |
542 | size_t name_len) | 513 | size_t name_len, int type) |
543 | { | 514 | { |
544 | const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); | 515 | const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); |
545 | if (!reiserfs_posixacl(inode->i_sb)) | 516 | if (!reiserfs_posixacl(dentry->d_sb)) |
546 | return 0; | 517 | return 0; |
547 | if (list && size <= list_size) | 518 | if (list && size <= list_size) |
548 | memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); | 519 | memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); |
@@ -551,7 +522,8 @@ static size_t posix_acl_default_list(struct inode *inode, char *list, | |||
551 | 522 | ||
552 | struct xattr_handler reiserfs_posix_acl_default_handler = { | 523 | struct xattr_handler reiserfs_posix_acl_default_handler = { |
553 | .prefix = POSIX_ACL_XATTR_DEFAULT, | 524 | .prefix = POSIX_ACL_XATTR_DEFAULT, |
554 | .get = posix_acl_default_get, | 525 | .flags = ACL_TYPE_DEFAULT, |
555 | .set = posix_acl_default_set, | 526 | .get = posix_acl_get, |
527 | .set = posix_acl_set, | ||
556 | .list = posix_acl_default_list, | 528 | .list = posix_acl_default_list, |
557 | }; | 529 | }; |
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index a92c8792c0f6..7271a477c041 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c | |||
@@ -3,41 +3,43 @@ | |||
3 | #include <linux/fs.h> | 3 | #include <linux/fs.h> |
4 | #include <linux/pagemap.h> | 4 | #include <linux/pagemap.h> |
5 | #include <linux/xattr.h> | 5 | #include <linux/xattr.h> |
6 | #include <linux/slab.h> | ||
6 | #include <linux/reiserfs_xattr.h> | 7 | #include <linux/reiserfs_xattr.h> |
7 | #include <linux/security.h> | 8 | #include <linux/security.h> |
8 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
9 | 10 | ||
10 | static int | 11 | static int |
11 | security_get(struct inode *inode, const char *name, void *buffer, size_t size) | 12 | security_get(struct dentry *dentry, const char *name, void *buffer, size_t size, |
13 | int handler_flags) | ||
12 | { | 14 | { |
13 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 15 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
14 | return -EINVAL; | 16 | return -EINVAL; |
15 | 17 | ||
16 | if (IS_PRIVATE(inode)) | 18 | if (IS_PRIVATE(dentry->d_inode)) |
17 | return -EPERM; | 19 | return -EPERM; |
18 | 20 | ||
19 | return reiserfs_xattr_get(inode, name, buffer, size); | 21 | return reiserfs_xattr_get(dentry->d_inode, name, buffer, size); |
20 | } | 22 | } |
21 | 23 | ||
22 | static int | 24 | static int |
23 | security_set(struct inode *inode, const char *name, const void *buffer, | 25 | security_set(struct dentry *dentry, const char *name, const void *buffer, |
24 | size_t size, int flags) | 26 | size_t size, int flags, int handler_flags) |
25 | { | 27 | { |
26 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | 28 | if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) |
27 | return -EINVAL; | 29 | return -EINVAL; |
28 | 30 | ||
29 | if (IS_PRIVATE(inode)) | 31 | if (IS_PRIVATE(dentry->d_inode)) |
30 | return -EPERM; | 32 | return -EPERM; |
31 | 33 | ||
32 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | 34 | return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags); |
33 | } | 35 | } |
34 | 36 | ||
35 | static size_t security_list(struct inode *inode, char *list, size_t list_len, | 37 | static size_t security_list(struct dentry *dentry, char *list, size_t list_len, |
36 | const char *name, size_t namelen) | 38 | const char *name, size_t namelen, int handler_flags) |
37 | { | 39 | { |
38 | const size_t len = namelen + 1; | 40 | const size_t len = namelen + 1; |
39 | 41 | ||
40 | if (IS_PRIVATE(inode)) | 42 | if (IS_PRIVATE(dentry->d_inode)) |
41 | return 0; | 43 | return 0; |
42 | 44 | ||
43 | if (list && len <= list_len) { | 45 | if (list && len <= list_len) { |
@@ -75,7 +77,7 @@ int reiserfs_security_init(struct inode *dir, struct inode *inode, | |||
75 | return error; | 77 | return error; |
76 | } | 78 | } |
77 | 79 | ||
78 | if (sec->length) { | 80 | if (sec->length && reiserfs_xattrs_initialized(inode->i_sb)) { |
79 | blocks = reiserfs_xattr_jcreate_nblocks(inode) + | 81 | blocks = reiserfs_xattr_jcreate_nblocks(inode) + |
80 | reiserfs_xattr_nblocks(inode, sec->length); | 82 | reiserfs_xattr_nblocks(inode, sec->length); |
81 | /* We don't want to count the directories twice if we have | 83 | /* We don't want to count the directories twice if we have |
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index a865042f75e2..5b08aaca3daf 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c | |||
@@ -8,36 +8,37 @@ | |||
8 | #include <asm/uaccess.h> | 8 | #include <asm/uaccess.h> |
9 | 9 | ||
10 | static int | 10 | static int |
11 | trusted_get(struct inode *inode, const char *name, void *buffer, size_t size) | 11 | trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size, |
12 | int handler_flags) | ||
12 | { | 13 | { |
13 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | 14 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) |
14 | return -EINVAL; | 15 | return -EINVAL; |
15 | 16 | ||
16 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | 17 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode)) |
17 | return -EPERM; | 18 | return -EPERM; |
18 | 19 | ||
19 | return reiserfs_xattr_get(inode, name, buffer, size); | 20 | return reiserfs_xattr_get(dentry->d_inode, name, buffer, size); |
20 | } | 21 | } |
21 | 22 | ||
22 | static int | 23 | static int |
23 | trusted_set(struct inode *inode, const char *name, const void *buffer, | 24 | trusted_set(struct dentry *dentry, const char *name, const void *buffer, |
24 | size_t size, int flags) | 25 | size_t size, int flags, int handler_flags) |
25 | { | 26 | { |
26 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | 27 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) |
27 | return -EINVAL; | 28 | return -EINVAL; |
28 | 29 | ||
29 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | 30 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode)) |
30 | return -EPERM; | 31 | return -EPERM; |
31 | 32 | ||
32 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | 33 | return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags); |
33 | } | 34 | } |
34 | 35 | ||
35 | static size_t trusted_list(struct inode *inode, char *list, size_t list_size, | 36 | static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size, |
36 | const char *name, size_t name_len) | 37 | const char *name, size_t name_len, int handler_flags) |
37 | { | 38 | { |
38 | const size_t len = name_len + 1; | 39 | const size_t len = name_len + 1; |
39 | 40 | ||
40 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | 41 | if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode)) |
41 | return 0; | 42 | return 0; |
42 | 43 | ||
43 | if (list && len <= list_size) { | 44 | if (list && len <= list_size) { |
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index e3238dc4f3db..75d59c49b911 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c | |||
@@ -7,34 +7,35 @@ | |||
7 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
8 | 8 | ||
9 | static int | 9 | static int |
10 | user_get(struct inode *inode, const char *name, void *buffer, size_t size) | 10 | user_get(struct dentry *dentry, const char *name, void *buffer, size_t size, |
11 | int handler_flags) | ||
11 | { | 12 | { |
12 | 13 | ||
13 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | 14 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) |
14 | return -EINVAL; | 15 | return -EINVAL; |
15 | if (!reiserfs_xattrs_user(inode->i_sb)) | 16 | if (!reiserfs_xattrs_user(dentry->d_sb)) |
16 | return -EOPNOTSUPP; | 17 | return -EOPNOTSUPP; |
17 | return reiserfs_xattr_get(inode, name, buffer, size); | 18 | return reiserfs_xattr_get(dentry->d_inode, name, buffer, size); |
18 | } | 19 | } |
19 | 20 | ||
20 | static int | 21 | static int |
21 | user_set(struct inode *inode, const char *name, const void *buffer, | 22 | user_set(struct dentry *dentry, const char *name, const void *buffer, |
22 | size_t size, int flags) | 23 | size_t size, int flags, int handler_flags) |
23 | { | 24 | { |
24 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | 25 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) |
25 | return -EINVAL; | 26 | return -EINVAL; |
26 | 27 | ||
27 | if (!reiserfs_xattrs_user(inode->i_sb)) | 28 | if (!reiserfs_xattrs_user(dentry->d_sb)) |
28 | return -EOPNOTSUPP; | 29 | return -EOPNOTSUPP; |
29 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | 30 | return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags); |
30 | } | 31 | } |
31 | 32 | ||
32 | static size_t user_list(struct inode *inode, char *list, size_t list_size, | 33 | static size_t user_list(struct dentry *dentry, char *list, size_t list_size, |
33 | const char *name, size_t name_len) | 34 | const char *name, size_t name_len, int handler_flags) |
34 | { | 35 | { |
35 | const size_t len = name_len + 1; | 36 | const size_t len = name_len + 1; |
36 | 37 | ||
37 | if (!reiserfs_xattrs_user(inode->i_sb)) | 38 | if (!reiserfs_xattrs_user(dentry->d_sb)) |
38 | return 0; | 39 | return 0; |
39 | if (list && len <= list_size) { | 40 | if (list && len <= list_size) { |
40 | memcpy(list, name, name_len); | 41 | memcpy(list, name, name_len); |