aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r--fs/ocfs2/namei.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 849c3b4bb94a..259155f0eb2e 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -429,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir,
429 mlog_errno(status); 429 mlog_errno(status);
430 goto leave; 430 goto leave;
431 } 431 }
432 dir->i_nlink++; 432 inc_nlink(dir);
433 } 433 }
434 434
435 status = ocfs2_add_entry(handle, dentry, inode, 435 status = ocfs2_add_entry(handle, dentry, inode,
@@ -730,7 +730,7 @@ static int ocfs2_link(struct dentry *old_dentry,
730 goto bail; 730 goto bail;
731 } 731 }
732 732
733 inode->i_nlink++; 733 inc_nlink(inode);
734 inode->i_ctime = CURRENT_TIME; 734 inode->i_ctime = CURRENT_TIME;
735 fe->i_links_count = cpu_to_le16(inode->i_nlink); 735 fe->i_links_count = cpu_to_le16(inode->i_nlink);
736 fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); 736 fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
@@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry,
739 err = ocfs2_journal_dirty(handle, fe_bh); 739 err = ocfs2_journal_dirty(handle, fe_bh);
740 if (err < 0) { 740 if (err < 0) {
741 le16_add_cpu(&fe->i_links_count, -1); 741 le16_add_cpu(&fe->i_links_count, -1);
742 inode->i_nlink--; 742 drop_nlink(inode);
743 mlog_errno(err); 743 mlog_errno(err);
744 goto bail; 744 goto bail;
745 } 745 }
@@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry,
749 parent_fe_bh, de_bh); 749 parent_fe_bh, de_bh);
750 if (err) { 750 if (err) {
751 le16_add_cpu(&fe->i_links_count, -1); 751 le16_add_cpu(&fe->i_links_count, -1);
752 inode->i_nlink--; 752 drop_nlink(inode);
753 mlog_errno(err); 753 mlog_errno(err);
754 goto bail; 754 goto bail;
755 } 755 }
@@ -795,11 +795,23 @@ static int ocfs2_remote_dentry_delete(struct dentry *dentry)
795 return ret; 795 return ret;
796} 796}
797 797
798static inline int inode_is_unlinkable(struct inode *inode)
799{
800 if (S_ISDIR(inode->i_mode)) {
801 if (inode->i_nlink == 2)
802 return 1;
803 return 0;
804 }
805
806 if (inode->i_nlink == 1)
807 return 1;
808 return 0;
809}
810
798static int ocfs2_unlink(struct inode *dir, 811static int ocfs2_unlink(struct inode *dir,
799 struct dentry *dentry) 812 struct dentry *dentry)
800{ 813{
801 int status; 814 int status;
802 unsigned int saved_nlink = 0;
803 struct inode *inode = dentry->d_inode; 815 struct inode *inode = dentry->d_inode;
804 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); 816 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
805 u64 blkno; 817 u64 blkno;
@@ -874,16 +886,6 @@ static int ocfs2_unlink(struct inode *dir,
874 } 886 }
875 } 887 }
876 888
877 /* There are still a few steps left until we can consider the
878 * unlink to have succeeded. Save off nlink here before
879 * modification so we can set it back in case we hit an issue
880 * before commit. */
881 saved_nlink = inode->i_nlink;
882 if (S_ISDIR(inode->i_mode))
883 inode->i_nlink = 0;
884 else
885 inode->i_nlink--;
886
887 status = ocfs2_remote_dentry_delete(dentry); 889 status = ocfs2_remote_dentry_delete(dentry);
888 if (status < 0) { 890 if (status < 0) {
889 /* This vote should succeed under all normal 891 /* This vote should succeed under all normal
@@ -892,7 +894,7 @@ static int ocfs2_unlink(struct inode *dir,
892 goto leave; 894 goto leave;
893 } 895 }
894 896
895 if (!inode->i_nlink) { 897 if (inode_is_unlinkable(inode)) {
896 status = ocfs2_prepare_orphan_dir(osb, handle, inode, 898 status = ocfs2_prepare_orphan_dir(osb, handle, inode,
897 orphan_name, 899 orphan_name,
898 &orphan_entry_bh); 900 &orphan_entry_bh);
@@ -919,7 +921,7 @@ static int ocfs2_unlink(struct inode *dir,
919 921
920 fe = (struct ocfs2_dinode *) fe_bh->b_data; 922 fe = (struct ocfs2_dinode *) fe_bh->b_data;
921 923
922 if (!inode->i_nlink) { 924 if (inode_is_unlinkable(inode)) {
923 status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, 925 status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
924 orphan_entry_bh); 926 orphan_entry_bh);
925 if (status < 0) { 927 if (status < 0) {
@@ -935,10 +937,10 @@ static int ocfs2_unlink(struct inode *dir,
935 goto leave; 937 goto leave;
936 } 938 }
937 939
938 /* We can set nlink on the dinode now. clear the saved version 940 if (S_ISDIR(inode->i_mode))
939 * so that it doesn't get set later. */ 941 drop_nlink(inode);
942 drop_nlink(inode);
940 fe->i_links_count = cpu_to_le16(inode->i_nlink); 943 fe->i_links_count = cpu_to_le16(inode->i_nlink);
941 saved_nlink = 0;
942 944
943 status = ocfs2_journal_dirty(handle, fe_bh); 945 status = ocfs2_journal_dirty(handle, fe_bh);
944 if (status < 0) { 946 if (status < 0) {
@@ -947,19 +949,16 @@ static int ocfs2_unlink(struct inode *dir,
947 } 949 }
948 950
949 if (S_ISDIR(inode->i_mode)) { 951 if (S_ISDIR(inode->i_mode)) {
950 dir->i_nlink--; 952 drop_nlink(dir);
951 status = ocfs2_mark_inode_dirty(handle, dir, 953 status = ocfs2_mark_inode_dirty(handle, dir,
952 parent_node_bh); 954 parent_node_bh);
953 if (status < 0) { 955 if (status < 0) {
954 mlog_errno(status); 956 mlog_errno(status);
955 dir->i_nlink++; 957 inc_nlink(dir);
956 } 958 }
957 } 959 }
958 960
959leave: 961leave:
960 if (status < 0 && saved_nlink)
961 inode->i_nlink = saved_nlink;
962
963 if (handle) 962 if (handle)
964 ocfs2_commit_trans(handle); 963 ocfs2_commit_trans(handle);
965 964
@@ -1382,7 +1381,7 @@ static int ocfs2_rename(struct inode *old_dir,
1382 if (new_inode) { 1381 if (new_inode) {
1383 new_inode->i_nlink--; 1382 new_inode->i_nlink--;
1384 } else { 1383 } else {
1385 new_dir->i_nlink++; 1384 inc_nlink(new_dir);
1386 mark_inode_dirty(new_dir); 1385 mark_inode_dirty(new_dir);
1387 } 1386 }
1388 } 1387 }