diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/dlm/dlmfs.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/file.c | 28 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 51 |
3 files changed, 41 insertions, 44 deletions
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 0368c6402182..16b8d1ba7066 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -338,7 +338,7 @@ static struct inode *dlmfs_get_root_inode(struct super_block *sb) | |||
338 | inode->i_blocks = 0; | 338 | inode->i_blocks = 0; |
339 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; | 339 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; |
340 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 340 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
341 | inode->i_nlink++; | 341 | inc_nlink(inode); |
342 | 342 | ||
343 | inode->i_fop = &simple_dir_operations; | 343 | inode->i_fop = &simple_dir_operations; |
344 | inode->i_op = &dlmfs_root_inode_operations; | 344 | inode->i_op = &dlmfs_root_inode_operations; |
@@ -395,7 +395,7 @@ static struct inode *dlmfs_get_inode(struct inode *parent, | |||
395 | 395 | ||
396 | /* directory inodes start off with i_nlink == | 396 | /* directory inodes start off with i_nlink == |
397 | * 2 (for "." entry) */ | 397 | * 2 (for "." entry) */ |
398 | inode->i_nlink++; | 398 | inc_nlink(inode); |
399 | break; | 399 | break; |
400 | } | 400 | } |
401 | 401 | ||
@@ -449,7 +449,7 @@ static int dlmfs_mkdir(struct inode * dir, | |||
449 | } | 449 | } |
450 | ip->ip_dlm = dlm; | 450 | ip->ip_dlm = dlm; |
451 | 451 | ||
452 | dir->i_nlink++; | 452 | inc_nlink(dir); |
453 | d_instantiate(dentry, inode); | 453 | d_instantiate(dentry, inode); |
454 | dget(dentry); /* Extra count - pin the dentry in core */ | 454 | dget(dentry); /* Extra count - pin the dentry in core */ |
455 | 455 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 2bbfa17090cf..d9ba0a931a03 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -961,25 +961,23 @@ static inline int ocfs2_write_should_remove_suid(struct inode *inode) | |||
961 | } | 961 | } |
962 | 962 | ||
963 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | 963 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, |
964 | const char __user *buf, | 964 | const struct iovec *iov, |
965 | size_t count, | 965 | unsigned long nr_segs, |
966 | loff_t pos) | 966 | loff_t pos) |
967 | { | 967 | { |
968 | struct iovec local_iov = { .iov_base = (void __user *)buf, | ||
969 | .iov_len = count }; | ||
970 | int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; | 968 | int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; |
971 | u32 clusters; | 969 | u32 clusters; |
972 | struct file *filp = iocb->ki_filp; | 970 | struct file *filp = iocb->ki_filp; |
973 | struct inode *inode = filp->f_dentry->d_inode; | 971 | struct inode *inode = filp->f_dentry->d_inode; |
974 | loff_t newsize, saved_pos; | 972 | loff_t newsize, saved_pos; |
975 | 973 | ||
976 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, | 974 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, |
977 | (unsigned int)count, | 975 | (unsigned int)nr_segs, |
978 | filp->f_dentry->d_name.len, | 976 | filp->f_dentry->d_name.len, |
979 | filp->f_dentry->d_name.name); | 977 | filp->f_dentry->d_name.name); |
980 | 978 | ||
981 | /* happy write of zero bytes */ | 979 | /* happy write of zero bytes */ |
982 | if (count == 0) | 980 | if (iocb->ki_left == 0) |
983 | return 0; | 981 | return 0; |
984 | 982 | ||
985 | if (!inode) { | 983 | if (!inode) { |
@@ -1048,7 +1046,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1048 | } else { | 1046 | } else { |
1049 | saved_pos = iocb->ki_pos; | 1047 | saved_pos = iocb->ki_pos; |
1050 | } | 1048 | } |
1051 | newsize = count + saved_pos; | 1049 | newsize = iocb->ki_left + saved_pos; |
1052 | 1050 | ||
1053 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", | 1051 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", |
1054 | (long long) saved_pos, (long long) newsize, | 1052 | (long long) saved_pos, (long long) newsize, |
@@ -1081,7 +1079,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1081 | if (!clusters) | 1079 | if (!clusters) |
1082 | break; | 1080 | break; |
1083 | 1081 | ||
1084 | ret = ocfs2_extend_file(inode, NULL, newsize, count); | 1082 | ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); |
1085 | if (ret < 0) { | 1083 | if (ret < 0) { |
1086 | if (ret != -ENOSPC) | 1084 | if (ret != -ENOSPC) |
1087 | mlog_errno(ret); | 1085 | mlog_errno(ret); |
@@ -1098,7 +1096,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1098 | /* communicate with ocfs2_dio_end_io */ | 1096 | /* communicate with ocfs2_dio_end_io */ |
1099 | ocfs2_iocb_set_rw_locked(iocb); | 1097 | ocfs2_iocb_set_rw_locked(iocb); |
1100 | 1098 | ||
1101 | ret = generic_file_aio_write_nolock(iocb, &local_iov, 1, &iocb->ki_pos); | 1099 | ret = generic_file_aio_write_nolock(iocb, iov, nr_segs, iocb->ki_pos); |
1102 | 1100 | ||
1103 | /* buffered aio wouldn't have proper lock coverage today */ | 1101 | /* buffered aio wouldn't have proper lock coverage today */ |
1104 | BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); | 1102 | BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT)); |
@@ -1132,16 +1130,16 @@ out: | |||
1132 | } | 1130 | } |
1133 | 1131 | ||
1134 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | 1132 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, |
1135 | char __user *buf, | 1133 | const struct iovec *iov, |
1136 | size_t count, | 1134 | unsigned long nr_segs, |
1137 | loff_t pos) | 1135 | loff_t pos) |
1138 | { | 1136 | { |
1139 | int ret = 0, rw_level = -1, have_alloc_sem = 0; | 1137 | int ret = 0, rw_level = -1, have_alloc_sem = 0; |
1140 | struct file *filp = iocb->ki_filp; | 1138 | struct file *filp = iocb->ki_filp; |
1141 | struct inode *inode = filp->f_dentry->d_inode; | 1139 | struct inode *inode = filp->f_dentry->d_inode; |
1142 | 1140 | ||
1143 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf, | 1141 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, |
1144 | (unsigned int)count, | 1142 | (unsigned int)nr_segs, |
1145 | filp->f_dentry->d_name.len, | 1143 | filp->f_dentry->d_name.len, |
1146 | filp->f_dentry->d_name.name); | 1144 | filp->f_dentry->d_name.name); |
1147 | 1145 | ||
@@ -1185,7 +1183,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
1185 | } | 1183 | } |
1186 | ocfs2_meta_unlock(inode, 0); | 1184 | ocfs2_meta_unlock(inode, 0); |
1187 | 1185 | ||
1188 | ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos); | 1186 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); |
1189 | if (ret == -EINVAL) | 1187 | if (ret == -EINVAL) |
1190 | mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); | 1188 | mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n"); |
1191 | 1189 | ||
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 | ||
798 | static 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 | |||
798 | static int ocfs2_unlink(struct inode *dir, | 811 | static 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 | ||
959 | leave: | 961 | leave: |
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 | } |