Aneesh Kumar K.V
2010-Jan-23 20:38 UTC
[PATCH 1/3] btrfs: Drop the link count update from btrfs_unlink_inode
This helps to cleanup the rename and unlink case Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- fs/btrfs/compat.h | 1 + fs/btrfs/inode.c | 12 ++++++++---- fs/btrfs/tree-log.c | 5 ++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/compat.h b/fs/btrfs/compat.h index 7c4503e..19c82bb 100644 --- a/fs/btrfs/compat.h +++ b/fs/btrfs/compat.h @@ -3,5 +3,6 @@ #define btrfs_drop_nlink(inode) drop_nlink(inode) #define btrfs_inc_nlink(inode) inc_nlink(inode) +#define btrfs_clear_nlink(inode) clear_nlink(inode) #endif /* _COMPAT_H_ */ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b330e27..32aa27d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2550,7 +2550,6 @@ err: btrfs_i_size_write(dir, dir->i_size - name_len * 2); inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME; btrfs_update_inode(trans, root, dir); - btrfs_drop_nlink(inode); ret = btrfs_update_inode(trans, root, inode); out: return ret; @@ -2583,9 +2582,10 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) btrfs_set_trans_block_group(trans, dir); btrfs_record_unlink_dir(trans, dir, dentry->d_inode, 0); - ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, dentry->d_name.name, dentry->d_name.len); + btrfs_drop_nlink(dentry->d_inode); + btrfs_update_inode(trans, root, dentry->d_inode); if (inode->i_nlink == 0) ret = btrfs_orphan_add(trans, inode); @@ -2701,8 +2701,11 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) /* now the directory is empty */ err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, dentry->d_name.name, dentry->d_name.len); - if (!err) + if (!err) { btrfs_i_size_write(inode, 0); + btrfs_drop_nlink(inode); + btrfs_update_inode(trans, root, inode); + } out: nr = trans->blocks_used; ret = btrfs_end_transaction_throttle(trans, root); @@ -5575,7 +5578,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, old_dentry->d_name.name, old_dentry->d_name.len); } else { - btrfs_inc_nlink(old_dentry->d_inode); ret = btrfs_unlink_inode(trans, root, old_dir, old_dentry->d_inode, old_dentry->d_name.name, @@ -5598,6 +5600,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, new_dentry->d_inode, new_dentry->d_name.name, new_dentry->d_name.len); + btrfs_drop_nlink(new_dentry->d_inode); + btrfs_update_inode(trans, dest, new_dentry->d_inode); } BUG_ON(ret); if (new_inode->i_nlink == 0) { diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 4a9434b..fb2d6a1 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -671,6 +671,8 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, BUG_ON(ret); ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len); + btrfs_drop_nlink(inode); + btrfs_update_inode(trans, root, inode); BUG_ON(ret); kfree(name); @@ -869,9 +871,7 @@ conflict_again: if (!backref_in_log(log, key, victim_name, victim_name_len)) { - btrfs_inc_nlink(inode); btrfs_release_path(root, path); - ret = btrfs_unlink_inode(trans, root, dir, inode, victim_name, victim_name_len); @@ -1426,7 +1426,6 @@ again: ret = link_to_fixup_dir(trans, root, path, location.objectid); BUG_ON(ret); - btrfs_inc_nlink(inode); ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len); BUG_ON(ret); -- 1.6.6.1.394.gdedc0 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Aneesh Kumar K.V
2010-Jan-23 20:38 UTC
[PATCH 2/3] btrfs: Update directory link count correctly while creation
This patch make sure we update directory link count correctly during mkdir and rename Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- fs/btrfs/inode.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 32aa27d..9a56b3b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4575,6 +4575,10 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) btrfs_set_trans_block_group(trans, inode); btrfs_i_size_write(inode, 0); + /* + * Directories have link count 2 + */ + btrfs_inc_nlink(inode); err = btrfs_update_inode(trans, root, inode); if (err) goto out_fail; @@ -4585,6 +4589,13 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (err) goto out_fail; + /* + * if we are adding a directory we need + * to bump the link count of parent + */ + btrfs_inc_nlink(dentry->d_parent->d_inode); + btrfs_update_inode(trans, root, dentry->d_parent->d_inode); + d_instantiate(dentry, inode); drop_on_err = 0; btrfs_update_inode_block_group(trans, inode); @@ -5613,6 +5624,16 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, ret = btrfs_add_link(trans, new_dir, old_inode, new_dentry->d_name.name, new_dentry->d_name.len, 0, index); + + if (!new_inode && S_ISDIR(old_inode->i_mode)) { + /* + * Bump the parent directory link count, if we + * end up adding a new inode + */ + btrfs_inc_nlink(new_dir); + btrfs_update_inode(trans, dest, new_dir); + } + BUG_ON(ret); if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { -- 1.6.6.1.394.gdedc0 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Aneesh Kumar K.V
2010-Jan-23 20:38 UTC
[PATCH 3/3] btrfs: Update the directory link count correctly
This patch make sure we update the directory link count properly during delete Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> --- fs/btrfs/inode.c | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9a56b3b..12b9d6e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2703,8 +2703,17 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) dentry->d_name.name, dentry->d_name.len); if (!err) { btrfs_i_size_write(inode, 0); - btrfs_drop_nlink(inode); + /* + * Directories have link count 2. + */ + btrfs_clear_nlink(dentry->d_inode); btrfs_update_inode(trans, root, inode); + /* + * If we are removing a directory drop the link count from + * the parent directory + */ + btrfs_drop_nlink(dir); + btrfs_update_inode(trans, root, dir); } out: nr = trans->blocks_used; -- 1.6.6.1.394.gdedc0 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Chris Mason
2010-Jan-24 00:30 UTC
Re: [PATCH 2/3] btrfs: Update directory link count correctly while creation
On Sun, Jan 24, 2010 at 02:08:08AM +0530, Aneesh Kumar K.V wrote:> This patch make sure we update directory link count correctly > during mkdir and renameDirectories always have a link count of 1, this is the widely accepted way of saying: we don''t count subdirs via the link count. -chris -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html