aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-24 12:44:26 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-24 12:44:26 -0400
commitf68cad0f9eb3c3cc100635bd0ea191ee093cf887 (patch)
tree081f6eeaff6e03ca2d002d49822fdac10e517875 /fs/btrfs
parentc62a1920ced752e86f57ab1d4ad0ec65012bce4d (diff)
Btrfs: fixup dirty_inode related deadlocks
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/super.c109
1 files changed, 56 insertions, 53 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index c076474c8bff..5bbccbc7e3cc 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -120,6 +120,58 @@ make_bad:
120 make_bad_inode(inode); 120 make_bad_inode(inode);
121} 121}
122 122
123static void fill_inode_item(struct btrfs_inode_item *item,
124 struct inode *inode)
125{
126 btrfs_set_inode_uid(item, inode->i_uid);
127 btrfs_set_inode_gid(item, inode->i_gid);
128 btrfs_set_inode_size(item, inode->i_size);
129 btrfs_set_inode_mode(item, inode->i_mode);
130 btrfs_set_inode_nlink(item, inode->i_nlink);
131 btrfs_set_timespec_sec(&item->atime, inode->i_atime.tv_sec);
132 btrfs_set_timespec_nsec(&item->atime, inode->i_atime.tv_nsec);
133 btrfs_set_timespec_sec(&item->mtime, inode->i_mtime.tv_sec);
134 btrfs_set_timespec_nsec(&item->mtime, inode->i_mtime.tv_nsec);
135 btrfs_set_timespec_sec(&item->ctime, inode->i_ctime.tv_sec);
136 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec);
137 btrfs_set_inode_nblocks(item, inode->i_blocks);
138 btrfs_set_inode_generation(item, inode->i_generation);
139}
140
141
142static int btrfs_update_inode(struct btrfs_trans_handle *trans,
143 struct btrfs_root *root,
144 struct inode *inode)
145{
146 struct btrfs_inode_item *inode_item;
147 struct btrfs_path *path;
148 int ret;
149
150 path = btrfs_alloc_path();
151 BUG_ON(!path);
152 btrfs_init_path(path);
153 ret = btrfs_lookup_inode(trans, root, path,
154 &BTRFS_I(inode)->location, 1);
155 if (ret) {
156 if (ret > 0)
157 ret = -ENOENT;
158 goto failed;
159 }
160
161 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
162 path->slots[0],
163 struct btrfs_inode_item);
164
165 fill_inode_item(inode_item, inode);
166 btrfs_mark_buffer_dirty(path->nodes[0]);
167 ret = 0;
168failed:
169 btrfs_release_path(root, path);
170 btrfs_free_path(path);
171 return ret;
172}
173
174
123static int btrfs_unlink_trans(struct btrfs_trans_handle *trans, 175static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
124 struct btrfs_root *root, 176 struct btrfs_root *root,
125 struct inode *dir, 177 struct inode *dir,
@@ -166,10 +218,11 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
166 dentry->d_inode->i_ctime = dir->i_ctime; 218 dentry->d_inode->i_ctime = dir->i_ctime;
167err: 219err:
168 btrfs_free_path(path); 220 btrfs_free_path(path);
169 if (ret == 0) { 221 if (!ret) {
170 inode_dec_link_count(dentry->d_inode);
171 dir->i_size -= name_len * 2; 222 dir->i_size -= name_len * 2;
172 mark_inode_dirty(dir); 223 btrfs_update_inode(trans, root, dir);
224 drop_nlink(dentry->d_inode);
225 btrfs_update_inode(trans, root, dentry->d_inode);
173 } 226 }
174 return ret; 227 return ret;
175} 228}
@@ -668,56 +721,6 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
668 return 0; 721 return 0;
669} 722}
670 723
671static void fill_inode_item(struct btrfs_inode_item *item,
672 struct inode *inode)
673{
674 btrfs_set_inode_uid(item, inode->i_uid);
675 btrfs_set_inode_gid(item, inode->i_gid);
676 btrfs_set_inode_size(item, inode->i_size);
677 btrfs_set_inode_mode(item, inode->i_mode);
678 btrfs_set_inode_nlink(item, inode->i_nlink);
679 btrfs_set_timespec_sec(&item->atime, inode->i_atime.tv_sec);
680 btrfs_set_timespec_nsec(&item->atime, inode->i_atime.tv_nsec);
681 btrfs_set_timespec_sec(&item->mtime, inode->i_mtime.tv_sec);
682 btrfs_set_timespec_nsec(&item->mtime, inode->i_mtime.tv_nsec);
683 btrfs_set_timespec_sec(&item->ctime, inode->i_ctime.tv_sec);
684 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec);
685 btrfs_set_inode_nblocks(item, inode->i_blocks);
686 btrfs_set_inode_generation(item, inode->i_generation);
687}
688
689static int btrfs_update_inode(struct btrfs_trans_handle *trans,
690 struct btrfs_root *root,
691 struct inode *inode)
692{
693 struct btrfs_inode_item *inode_item;
694 struct btrfs_path *path;
695 int ret;
696
697 path = btrfs_alloc_path();
698 BUG_ON(!path);
699 btrfs_init_path(path);
700 ret = btrfs_lookup_inode(trans, root, path,
701 &BTRFS_I(inode)->location, 1);
702 if (ret) {
703 if (ret > 0)
704 ret = -ENOENT;
705 goto failed;
706 }
707
708 inode_item = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
709 path->slots[0],
710 struct btrfs_inode_item);
711
712 fill_inode_item(inode_item, inode);
713 btrfs_mark_buffer_dirty(path->nodes[0]);
714 ret = 0;
715failed:
716 btrfs_release_path(root, path);
717 btrfs_free_path(path);
718 return ret;
719}
720
721static int btrfs_write_inode(struct inode *inode, int wait) 724static int btrfs_write_inode(struct inode *inode, int wait)
722{ 725{
723 struct btrfs_root *root = BTRFS_I(inode)->root; 726 struct btrfs_root *root = BTRFS_I(inode)->root;