aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/xattr.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2009-03-30 14:02:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 15:16:38 -0400
commit0ab2621ebd9a28bf7a524ecd50d492a10579dfcc (patch)
tree62dda6de2fed116aff363190f95a58d56c690e3e /fs/reiserfs/xattr.c
parent48b32a3553a54740d236b79a90f20147a25875e3 (diff)
reiserfs: journaled xattrs
Deadlocks are possible in the xattr code between the journal lock and the xattr sems. This patch implements journalling for xattr operations. The benefit is twofold: * It gets rid of the deadlock possibility by always ensuring that xattr write operations are initiated inside a transaction. * It corrects the problem where xattr backing files aren't considered any differently than normal files, despite the fact they are metadata. I discussed the added journal load with Chris Mason, and we decided that since xattrs (versus other journal activity) is fairly rare, the introduction of larger transactions to support journaled xattrs wouldn't be too big a deal. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/reiserfs/xattr.c')
-rw-r--r--fs/reiserfs/xattr.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d3ce27436605..c2e3a92aaf2b 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -632,8 +632,9 @@ out_dput:
632 * inode->i_mutex: down 632 * inode->i_mutex: down
633 */ 633 */
634int 634int
635__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, 635reiserfs_xattr_set_handle(struct reiserfs_transaction_handle *th,
636 size_t buffer_size, int flags) 636 struct inode *inode, const char *name,
637 const void *buffer, size_t buffer_size, int flags)
637{ 638{
638 int err = 0; 639 int err = 0;
639 struct dentry *dentry; 640 struct dentry *dentry;
@@ -723,14 +724,34 @@ out_unlock:
723 return err; 724 return err;
724} 725}
725 726
726int 727/* We need to start a transaction to maintain lock ordering */
727reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, 728int reiserfs_xattr_set(struct inode *inode, const char *name,
728 size_t buffer_size, int flags) 729 const void *buffer, size_t buffer_size, int flags)
729{ 730{
730 int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags); 731
731 if (err == -ENODATA) 732 struct reiserfs_transaction_handle th;
732 err = 0; 733 int error, error2;
733 return err; 734 size_t jbegin_count = reiserfs_xattr_nblocks(inode, buffer_size);
735
736 if (!(flags & XATTR_REPLACE))
737 jbegin_count += reiserfs_xattr_jcreate_nblocks(inode);
738
739 reiserfs_write_lock(inode->i_sb);
740 error = journal_begin(&th, inode->i_sb, jbegin_count);
741 if (error) {
742 reiserfs_write_unlock(inode->i_sb);
743 return error;
744 }
745
746 error = reiserfs_xattr_set_handle(&th, inode, name,
747 buffer, buffer_size, flags);
748
749 error2 = journal_end(&th, inode->i_sb, jbegin_count);
750 if (error == 0)
751 error = error2;
752 reiserfs_write_unlock(inode->i_sb);
753
754 return error;
734} 755}
735 756
736/* 757/*