aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs')
-rw-r--r--fs/reiserfs/bitmap.c8
-rw-r--r--fs/reiserfs/dir.c13
-rw-r--r--fs/reiserfs/file.c10
-rw-r--r--fs/reiserfs/inode.c13
-rw-r--r--fs/reiserfs/journal.c13
-rw-r--r--fs/reiserfs/namei.c4
-rw-r--r--fs/reiserfs/resize.c6
-rw-r--r--fs/reiserfs/super.c28
-rw-r--r--fs/reiserfs/xattr.c36
-rw-r--r--fs/reiserfs/xattr_acl.c77
10 files changed, 83 insertions, 125 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 483442e66ed..d1aca1df4f9 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -214,7 +214,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
214 } 214 }
215 /* otherwise we clear all bit were set ... */ 215 /* otherwise we clear all bit were set ... */
216 while (--i >= *beg) 216 while (--i >= *beg)
217 reiserfs_test_and_clear_le_bit 217 reiserfs_clear_le_bit
218 (i, bh->b_data); 218 (i, bh->b_data);
219 reiserfs_restore_prepared_buffer(s, bh); 219 reiserfs_restore_prepared_buffer(s, bh);
220 *beg = org; 220 *beg = org;
@@ -1222,15 +1222,11 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb,
1222 info->free_count = 0; 1222 info->free_count = 0;
1223 1223
1224 while (--cur >= (unsigned long *)bh->b_data) { 1224 while (--cur >= (unsigned long *)bh->b_data) {
1225 int i;
1226
1227 /* 0 and ~0 are special, we can optimize for them */ 1225 /* 0 and ~0 are special, we can optimize for them */
1228 if (*cur == 0) 1226 if (*cur == 0)
1229 info->free_count += BITS_PER_LONG; 1227 info->free_count += BITS_PER_LONG;
1230 else if (*cur != ~0L) /* A mix, investigate */ 1228 else if (*cur != ~0L) /* A mix, investigate */
1231 for (i = BITS_PER_LONG - 1; i >= 0; i--) 1229 info->free_count += BITS_PER_LONG - hweight_long(*cur);
1232 if (!reiserfs_test_le_bit(i, cur))
1233 info->free_count++;
1234 } 1230 }
1235} 1231}
1236 1232
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 198dabf1b2b..133e9355dc6 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -14,7 +14,8 @@
14extern const struct reiserfs_key MIN_KEY; 14extern const struct reiserfs_key MIN_KEY;
15 15
16static int reiserfs_readdir(struct file *, void *, filldir_t); 16static int reiserfs_readdir(struct file *, void *, filldir_t);
17static int reiserfs_dir_fsync(struct file *filp, int datasync); 17static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
18 int datasync);
18 19
19const struct file_operations reiserfs_dir_operations = { 20const struct file_operations reiserfs_dir_operations = {
20 .llseek = generic_file_llseek, 21 .llseek = generic_file_llseek,
@@ -27,13 +28,21 @@ const struct file_operations reiserfs_dir_operations = {
27#endif 28#endif
28}; 29};
29 30
30static int reiserfs_dir_fsync(struct file *filp, int datasync) 31static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
32 int datasync)
31{ 33{
32 struct inode *inode = filp->f_mapping->host; 34 struct inode *inode = filp->f_mapping->host;
33 int err; 35 int err;
36
37 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
38 if (err)
39 return err;
40
41 mutex_lock(&inode->i_mutex);
34 reiserfs_write_lock(inode->i_sb); 42 reiserfs_write_lock(inode->i_sb);
35 err = reiserfs_commit_for_inode(inode); 43 err = reiserfs_commit_for_inode(inode);
36 reiserfs_write_unlock(inode->i_sb); 44 reiserfs_write_unlock(inode->i_sb);
45 mutex_unlock(&inode->i_mutex);
37 if (err < 0) 46 if (err < 0)
38 return err; 47 return err;
39 return 0; 48 return 0;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 91f080cc76c..ace635053a3 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -140,12 +140,18 @@ static void reiserfs_vfs_truncate_file(struct inode *inode)
140 * be removed... 140 * be removed...
141 */ 141 */
142 142
143static int reiserfs_sync_file(struct file *filp, int datasync) 143static int reiserfs_sync_file(struct file *filp, loff_t start, loff_t end,
144 int datasync)
144{ 145{
145 struct inode *inode = filp->f_mapping->host; 146 struct inode *inode = filp->f_mapping->host;
146 int err; 147 int err;
147 int barrier_done; 148 int barrier_done;
148 149
150 err = filemap_write_and_wait_range(inode->i_mapping, start, end);
151 if (err)
152 return err;
153
154 mutex_lock(&inode->i_mutex);
149 BUG_ON(!S_ISREG(inode->i_mode)); 155 BUG_ON(!S_ISREG(inode->i_mode));
150 err = sync_mapping_buffers(inode->i_mapping); 156 err = sync_mapping_buffers(inode->i_mapping);
151 reiserfs_write_lock(inode->i_sb); 157 reiserfs_write_lock(inode->i_sb);
@@ -153,6 +159,7 @@ static int reiserfs_sync_file(struct file *filp, int datasync)
153 reiserfs_write_unlock(inode->i_sb); 159 reiserfs_write_unlock(inode->i_sb);
154 if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb)) 160 if (barrier_done != 1 && reiserfs_barrier_flush(inode->i_sb))
155 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); 161 blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
162 mutex_unlock(&inode->i_mutex);
156 if (barrier_done < 0) 163 if (barrier_done < 0)
157 return barrier_done; 164 return barrier_done;
158 return (err < 0) ? -EIO : 0; 165 return (err < 0) ? -EIO : 0;
@@ -312,4 +319,5 @@ const struct inode_operations reiserfs_file_inode_operations = {
312 .listxattr = reiserfs_listxattr, 319 .listxattr = reiserfs_listxattr,
313 .removexattr = reiserfs_removexattr, 320 .removexattr = reiserfs_removexattr,
314 .permission = reiserfs_permission, 321 .permission = reiserfs_permission,
322 .get_acl = reiserfs_get_acl,
315}; 323};
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 4fd5bb33dbb..9b0d4b78b4f 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1475,6 +1475,11 @@ void reiserfs_read_locked_inode(struct inode *inode,
1475 1475
1476 reiserfs_check_path(&path_to_sd); /* init inode should be relsing */ 1476 reiserfs_check_path(&path_to_sd); /* init inode should be relsing */
1477 1477
1478 /*
1479 * Stat data v1 doesn't support ACLs.
1480 */
1481 if (get_inode_sd_version(inode) == STAT_DATA_V1)
1482 cache_no_acl(inode);
1478} 1483}
1479 1484
1480/** 1485/**
@@ -3068,9 +3073,8 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
3068 struct inode *inode = file->f_mapping->host; 3073 struct inode *inode = file->f_mapping->host;
3069 ssize_t ret; 3074 ssize_t ret;
3070 3075
3071 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 3076 ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
3072 offset, nr_segs, 3077 reiserfs_get_blocks_direct_io);
3073 reiserfs_get_blocks_direct_io, NULL);
3074 3078
3075 /* 3079 /*
3076 * In case of error extending write may have instantiated a few 3080 * In case of error extending write may have instantiated a few
@@ -3114,6 +3118,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
3114 error = -EFBIG; 3118 error = -EFBIG;
3115 goto out; 3119 goto out;
3116 } 3120 }
3121
3122 inode_dio_wait(inode);
3123
3117 /* fill in hole pointers in the expanding truncate case. */ 3124 /* fill in hole pointers in the expanding truncate case. */
3118 if (attr->ia_size > inode->i_size) { 3125 if (attr->ia_size > inode->i_size) {
3119 error = generic_cont_expand_simple(inode, attr->ia_size); 3126 error = generic_cont_expand_simple(inode, attr->ia_size);
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index c5e82ece7c6..a159ba5a35e 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -678,23 +678,19 @@ struct buffer_chunk {
678static void write_chunk(struct buffer_chunk *chunk) 678static void write_chunk(struct buffer_chunk *chunk)
679{ 679{
680 int i; 680 int i;
681 get_fs_excl();
682 for (i = 0; i < chunk->nr; i++) { 681 for (i = 0; i < chunk->nr; i++) {
683 submit_logged_buffer(chunk->bh[i]); 682 submit_logged_buffer(chunk->bh[i]);
684 } 683 }
685 chunk->nr = 0; 684 chunk->nr = 0;
686 put_fs_excl();
687} 685}
688 686
689static void write_ordered_chunk(struct buffer_chunk *chunk) 687static void write_ordered_chunk(struct buffer_chunk *chunk)
690{ 688{
691 int i; 689 int i;
692 get_fs_excl();
693 for (i = 0; i < chunk->nr; i++) { 690 for (i = 0; i < chunk->nr; i++) {
694 submit_ordered_buffer(chunk->bh[i]); 691 submit_ordered_buffer(chunk->bh[i]);
695 } 692 }
696 chunk->nr = 0; 693 chunk->nr = 0;
697 put_fs_excl();
698} 694}
699 695
700static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh, 696static int add_to_chunk(struct buffer_chunk *chunk, struct buffer_head *bh,
@@ -986,8 +982,6 @@ static int flush_commit_list(struct super_block *s,
986 return 0; 982 return 0;
987 } 983 }
988 984
989 get_fs_excl();
990
991 /* before we can put our commit blocks on disk, we have to make sure everyone older than 985 /* before we can put our commit blocks on disk, we have to make sure everyone older than
992 ** us is on disk too 986 ** us is on disk too
993 */ 987 */
@@ -1145,7 +1139,6 @@ static int flush_commit_list(struct super_block *s,
1145 if (retval) 1139 if (retval)
1146 reiserfs_abort(s, retval, "Journal write error in %s", 1140 reiserfs_abort(s, retval, "Journal write error in %s",
1147 __func__); 1141 __func__);
1148 put_fs_excl();
1149 return retval; 1142 return retval;
1150} 1143}
1151 1144
@@ -1374,8 +1367,6 @@ static int flush_journal_list(struct super_block *s,
1374 return 0; 1367 return 0;
1375 } 1368 }
1376 1369
1377 get_fs_excl();
1378
1379 /* if all the work is already done, get out of here */ 1370 /* if all the work is already done, get out of here */
1380 if (atomic_read(&(jl->j_nonzerolen)) <= 0 && 1371 if (atomic_read(&(jl->j_nonzerolen)) <= 0 &&
1381 atomic_read(&(jl->j_commit_left)) <= 0) { 1372 atomic_read(&(jl->j_commit_left)) <= 0) {
@@ -1597,7 +1588,6 @@ static int flush_journal_list(struct super_block *s,
1597 put_journal_list(s, jl); 1588 put_journal_list(s, jl);
1598 if (flushall) 1589 if (flushall)
1599 mutex_unlock(&journal->j_flush_mutex); 1590 mutex_unlock(&journal->j_flush_mutex);
1600 put_fs_excl();
1601 return err; 1591 return err;
1602} 1592}
1603 1593
@@ -3108,7 +3098,6 @@ static int do_journal_begin_r(struct reiserfs_transaction_handle *th,
3108 th->t_trans_id = journal->j_trans_id; 3098 th->t_trans_id = journal->j_trans_id;
3109 unlock_journal(sb); 3099 unlock_journal(sb);
3110 INIT_LIST_HEAD(&th->t_list); 3100 INIT_LIST_HEAD(&th->t_list);
3111 get_fs_excl();
3112 return 0; 3101 return 0;
3113 3102
3114 out_fail: 3103 out_fail:
@@ -3964,7 +3953,6 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
3964 flush = flags & FLUSH_ALL; 3953 flush = flags & FLUSH_ALL;
3965 wait_on_commit = flags & WAIT; 3954 wait_on_commit = flags & WAIT;
3966 3955
3967 put_fs_excl();
3968 current->journal_info = th->t_handle_save; 3956 current->journal_info = th->t_handle_save;
3969 reiserfs_check_lock_depth(sb, "journal end"); 3957 reiserfs_check_lock_depth(sb, "journal end");
3970 if (journal->j_len == 0) { 3958 if (journal->j_len == 0) {
@@ -4316,4 +4304,3 @@ void reiserfs_abort_journal(struct super_block *sb, int errno)
4316 dump_stack(); 4304 dump_stack();
4317#endif 4305#endif
4318} 4306}
4319
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 118662690cd..ef392324bbf 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -1529,6 +1529,7 @@ const struct inode_operations reiserfs_dir_inode_operations = {
1529 .listxattr = reiserfs_listxattr, 1529 .listxattr = reiserfs_listxattr,
1530 .removexattr = reiserfs_removexattr, 1530 .removexattr = reiserfs_removexattr,
1531 .permission = reiserfs_permission, 1531 .permission = reiserfs_permission,
1532 .get_acl = reiserfs_get_acl,
1532}; 1533};
1533 1534
1534/* 1535/*
@@ -1545,6 +1546,7 @@ const struct inode_operations reiserfs_symlink_inode_operations = {
1545 .listxattr = reiserfs_listxattr, 1546 .listxattr = reiserfs_listxattr,
1546 .removexattr = reiserfs_removexattr, 1547 .removexattr = reiserfs_removexattr,
1547 .permission = reiserfs_permission, 1548 .permission = reiserfs_permission,
1549 .get_acl = reiserfs_get_acl,
1548 1550
1549}; 1551};
1550 1552
@@ -1558,5 +1560,5 @@ const struct inode_operations reiserfs_special_inode_operations = {
1558 .listxattr = reiserfs_listxattr, 1560 .listxattr = reiserfs_listxattr,
1559 .removexattr = reiserfs_removexattr, 1561 .removexattr = reiserfs_removexattr,
1560 .permission = reiserfs_permission, 1562 .permission = reiserfs_permission,
1561 1563 .get_acl = reiserfs_get_acl,
1562}; 1564};
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index b3a94d20f0f..b6b9b1fe33b 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -136,7 +136,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
136 return -EIO; 136 return -EIO;
137 } 137 }
138 memset(bh->b_data, 0, sb_blocksize(sb)); 138 memset(bh->b_data, 0, sb_blocksize(sb));
139 reiserfs_test_and_set_le_bit(0, bh->b_data); 139 reiserfs_set_le_bit(0, bh->b_data);
140 reiserfs_cache_bitmap_metadata(s, bh, bitmap + i); 140 reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
141 141
142 set_buffer_uptodate(bh); 142 set_buffer_uptodate(bh);
@@ -172,7 +172,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
172 172
173 reiserfs_prepare_for_journal(s, bh, 1); 173 reiserfs_prepare_for_journal(s, bh, 1);
174 for (i = block_r; i < s->s_blocksize * 8; i++) 174 for (i = block_r; i < s->s_blocksize * 8; i++)
175 reiserfs_test_and_clear_le_bit(i, bh->b_data); 175 reiserfs_clear_le_bit(i, bh->b_data);
176 info->free_count += s->s_blocksize * 8 - block_r; 176 info->free_count += s->s_blocksize * 8 - block_r;
177 177
178 journal_mark_dirty(&th, s, bh); 178 journal_mark_dirty(&th, s, bh);
@@ -190,7 +190,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
190 190
191 reiserfs_prepare_for_journal(s, bh, 1); 191 reiserfs_prepare_for_journal(s, bh, 1);
192 for (i = block_r_new; i < s->s_blocksize * 8; i++) 192 for (i = block_r_new; i < s->s_blocksize * 8; i++)
193 reiserfs_test_and_set_le_bit(i, bh->b_data); 193 reiserfs_set_le_bit(i, bh->b_data);
194 journal_mark_dirty(&th, s, bh); 194 journal_mark_dirty(&th, s, bh);
195 brelse(bh); 195 brelse(bh);
196 196
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index aa91089162c..5e3527be114 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -453,16 +453,20 @@ int remove_save_link(struct inode *inode, int truncate)
453static void reiserfs_kill_sb(struct super_block *s) 453static void reiserfs_kill_sb(struct super_block *s)
454{ 454{
455 if (REISERFS_SB(s)) { 455 if (REISERFS_SB(s)) {
456 if (REISERFS_SB(s)->xattr_root) { 456 /*
457 d_invalidate(REISERFS_SB(s)->xattr_root); 457 * Force any pending inode evictions to occur now. Any
458 dput(REISERFS_SB(s)->xattr_root); 458 * inodes to be removed that have extended attributes
459 REISERFS_SB(s)->xattr_root = NULL; 459 * associated with them need to clean them up before
460 } 460 * we can release the extended attribute root dentries.
461 if (REISERFS_SB(s)->priv_root) { 461 * shrink_dcache_for_umount will BUG if we don't release
462 d_invalidate(REISERFS_SB(s)->priv_root); 462 * those before it's called so ->put_super is too late.
463 dput(REISERFS_SB(s)->priv_root); 463 */
464 REISERFS_SB(s)->priv_root = NULL; 464 shrink_dcache_sb(s);
465 } 465
466 dput(REISERFS_SB(s)->xattr_root);
467 REISERFS_SB(s)->xattr_root = NULL;
468 dput(REISERFS_SB(s)->priv_root);
469 REISERFS_SB(s)->priv_root = NULL;
466 } 470 }
467 471
468 kill_block_super(s); 472 kill_block_super(s);
@@ -1164,7 +1168,8 @@ static void handle_quota_files(struct super_block *s, char **qf_names,
1164 kfree(REISERFS_SB(s)->s_qf_names[i]); 1168 kfree(REISERFS_SB(s)->s_qf_names[i]);
1165 REISERFS_SB(s)->s_qf_names[i] = qf_names[i]; 1169 REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
1166 } 1170 }
1167 REISERFS_SB(s)->s_jquota_fmt = *qfmt; 1171 if (*qfmt)
1172 REISERFS_SB(s)->s_jquota_fmt = *qfmt;
1168} 1173}
1169#endif 1174#endif
1170 1175
@@ -1643,6 +1648,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1643 /* Set default values for options: non-aggressive tails, RO on errors */ 1648 /* Set default values for options: non-aggressive tails, RO on errors */
1644 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); 1649 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL);
1645 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); 1650 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO);
1651 REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_BARRIER_FLUSH);
1646 /* no preallocation minimum, be smart in 1652 /* no preallocation minimum, be smart in
1647 reiserfs_file_write instead */ 1653 reiserfs_file_write instead */
1648 REISERFS_SB(s)->s_alloc_options.preallocmin = 0; 1654 REISERFS_SB(s)->s_alloc_options.preallocmin = 0;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d7808969096..6bc346c160e 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -555,11 +555,10 @@ reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
555 555
556 reiserfs_write_unlock(inode->i_sb); 556 reiserfs_write_unlock(inode->i_sb);
557 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); 557 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR);
558 down_write(&dentry->d_inode->i_alloc_sem); 558 inode_dio_wait(dentry->d_inode);
559 reiserfs_write_lock(inode->i_sb); 559 reiserfs_write_lock(inode->i_sb);
560 560
561 err = reiserfs_setattr(dentry, &newattrs); 561 err = reiserfs_setattr(dentry, &newattrs);
562 up_write(&dentry->d_inode->i_alloc_sem);
563 mutex_unlock(&dentry->d_inode->i_mutex); 562 mutex_unlock(&dentry->d_inode->i_mutex);
564 } else 563 } else
565 update_ctime(inode); 564 update_ctime(inode);
@@ -868,27 +867,6 @@ out:
868 return err; 867 return err;
869} 868}
870 869
871static int reiserfs_check_acl(struct inode *inode, int mask, unsigned int flags)
872{
873 struct posix_acl *acl;
874 int error = -EAGAIN; /* do regular unix permission checks by default */
875
876 if (flags & IPERM_FLAG_RCU)
877 return -ECHILD;
878
879 acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
880
881 if (acl) {
882 if (!IS_ERR(acl)) {
883 error = posix_acl_permission(inode, acl, mask);
884 posix_acl_release(acl);
885 } else if (PTR_ERR(acl) != -ENODATA)
886 error = PTR_ERR(acl);
887 }
888
889 return error;
890}
891
892static int create_privroot(struct dentry *dentry) 870static int create_privroot(struct dentry *dentry)
893{ 871{
894 int err; 872 int err;
@@ -952,7 +930,7 @@ static int xattr_mount_check(struct super_block *s)
952 return 0; 930 return 0;
953} 931}
954 932
955int reiserfs_permission(struct inode *inode, int mask, unsigned int flags) 933int reiserfs_permission(struct inode *inode, int mask)
956{ 934{
957 /* 935 /*
958 * We don't do permission checks on the internal objects. 936 * We don't do permission checks on the internal objects.
@@ -961,15 +939,7 @@ int reiserfs_permission(struct inode *inode, int mask, unsigned int flags)
961 if (IS_PRIVATE(inode)) 939 if (IS_PRIVATE(inode))
962 return 0; 940 return 0;
963 941
964#ifdef CONFIG_REISERFS_FS_XATTR 942 return generic_permission(inode, mask);
965 /*
966 * Stat data v1 doesn't support ACLs.
967 */
968 if (get_inode_sd_version(inode) != STAT_DATA_V1)
969 return generic_permission(inode, mask, flags,
970 reiserfs_check_acl);
971#endif
972 return generic_permission(inode, mask, flags, NULL);
973} 943}
974 944
975static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd) 945static int xattr_hide_revalidate(struct dentry *dentry, struct nameidata *nd)
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 3dc38f1206f..6da0396e505 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -272,12 +272,10 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
272 case ACL_TYPE_ACCESS: 272 case ACL_TYPE_ACCESS:
273 name = POSIX_ACL_XATTR_ACCESS; 273 name = POSIX_ACL_XATTR_ACCESS;
274 if (acl) { 274 if (acl) {
275 mode_t mode = inode->i_mode; 275 error = posix_acl_equiv_mode(acl, &inode->i_mode);
276 error = posix_acl_equiv_mode(acl, &mode);
277 if (error < 0) 276 if (error < 0)
278 return error; 277 return error;
279 else { 278 else {
280 inode->i_mode = mode;
281 if (error == 0) 279 if (error == 0)
282 acl = NULL; 280 acl = NULL;
283 } 281 }
@@ -354,10 +352,6 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
354 return PTR_ERR(acl); 352 return PTR_ERR(acl);
355 353
356 if (acl) { 354 if (acl) {
357 struct posix_acl *acl_copy;
358 mode_t mode = inode->i_mode;
359 int need_acl;
360
361 /* Copy the default ACL to the default ACL of a new directory */ 355 /* Copy the default ACL to the default ACL of a new directory */
362 if (S_ISDIR(inode->i_mode)) { 356 if (S_ISDIR(inode->i_mode)) {
363 err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT, 357 err = reiserfs_set_acl(th, inode, ACL_TYPE_DEFAULT,
@@ -368,29 +362,13 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th,
368 362
369 /* Now we reconcile the new ACL and the mode, 363 /* Now we reconcile the new ACL and the mode,
370 potentially modifying both */ 364 potentially modifying both */
371 acl_copy = posix_acl_clone(acl, GFP_NOFS); 365 err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode);
372 if (!acl_copy) { 366 if (err < 0)
373 err = -ENOMEM; 367 return err;
374 goto cleanup;
375 }
376
377 need_acl = posix_acl_create_masq(acl_copy, &mode);
378 if (need_acl >= 0) {
379 if (mode != inode->i_mode) {
380 inode->i_mode = mode;
381 }
382 368
383 /* If we need an ACL.. */ 369 /* If we need an ACL.. */
384 if (need_acl > 0) { 370 if (err > 0)
385 err = reiserfs_set_acl(th, inode, 371 err = reiserfs_set_acl(th, inode, ACL_TYPE_ACCESS, acl);
386 ACL_TYPE_ACCESS,
387 acl_copy);
388 if (err)
389 goto cleanup_copy;
390 }
391 }
392 cleanup_copy:
393 posix_acl_release(acl_copy);
394 cleanup: 372 cleanup:
395 posix_acl_release(acl); 373 posix_acl_release(acl);
396 } else { 374 } else {
@@ -445,7 +423,10 @@ int reiserfs_cache_default_acl(struct inode *inode)
445 423
446int reiserfs_acl_chmod(struct inode *inode) 424int reiserfs_acl_chmod(struct inode *inode)
447{ 425{
448 struct posix_acl *acl, *clone; 426 struct reiserfs_transaction_handle th;
427 struct posix_acl *acl;
428 size_t size;
429 int depth;
449 int error; 430 int error;
450 431
451 if (S_ISLNK(inode->i_mode)) 432 if (S_ISLNK(inode->i_mode))
@@ -463,30 +444,22 @@ int reiserfs_acl_chmod(struct inode *inode)
463 return 0; 444 return 0;
464 if (IS_ERR(acl)) 445 if (IS_ERR(acl))
465 return PTR_ERR(acl); 446 return PTR_ERR(acl);
466 clone = posix_acl_clone(acl, GFP_NOFS); 447 error = posix_acl_chmod(&acl, GFP_NOFS, inode->i_mode);
467 posix_acl_release(acl); 448 if (error)
468 if (!clone) 449 return error;
469 return -ENOMEM; 450
470 error = posix_acl_chmod_masq(clone, inode->i_mode); 451 size = reiserfs_xattr_nblocks(inode, reiserfs_acl_size(acl->a_count));
452 depth = reiserfs_write_lock_once(inode->i_sb);
453 error = journal_begin(&th, inode->i_sb, size * 2);
471 if (!error) { 454 if (!error) {
472 struct reiserfs_transaction_handle th; 455 int error2;
473 size_t size = reiserfs_xattr_nblocks(inode, 456 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS, acl);
474 reiserfs_acl_size(clone->a_count)); 457 error2 = journal_end(&th, inode->i_sb, size * 2);
475 int depth; 458 if (error2)
476 459 error = error2;
477 depth = reiserfs_write_lock_once(inode->i_sb);
478 error = journal_begin(&th, inode->i_sb, size * 2);
479 if (!error) {
480 int error2;
481 error = reiserfs_set_acl(&th, inode, ACL_TYPE_ACCESS,
482 clone);
483 error2 = journal_end(&th, inode->i_sb, size * 2);
484 if (error2)
485 error = error2;
486 }
487 reiserfs_write_unlock_once(inode->i_sb, depth);
488 } 460 }
489 posix_acl_release(clone); 461 reiserfs_write_unlock_once(inode->i_sb, depth);
462 posix_acl_release(acl);
490 return error; 463 return error;
491} 464}
492 465