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.c116
1 files changed, 81 insertions, 35 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 0d3e939b1f56..849c3b4bb94a 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -179,7 +179,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
179 if (status < 0) 179 if (status < 0)
180 goto bail_add; 180 goto bail_add;
181 181
182 inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno); 182 inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0);
183 if (IS_ERR(inode)) { 183 if (IS_ERR(inode)) {
184 mlog(ML_ERROR, "Unable to create inode %llu\n", 184 mlog(ML_ERROR, "Unable to create inode %llu\n",
185 (unsigned long long)blkno); 185 (unsigned long long)blkno);
@@ -199,10 +199,32 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
199 spin_unlock(&oi->ip_lock); 199 spin_unlock(&oi->ip_lock);
200 200
201bail_add: 201bail_add:
202
203 dentry->d_op = &ocfs2_dentry_ops; 202 dentry->d_op = &ocfs2_dentry_ops;
204 ret = d_splice_alias(inode, dentry); 203 ret = d_splice_alias(inode, dentry);
205 204
205 if (inode) {
206 /*
207 * If d_splice_alias() finds a DCACHE_DISCONNECTED
208 * dentry, it will d_move() it on top of ourse. The
209 * return value will indicate this however, so in
210 * those cases, we switch them around for the locking
211 * code.
212 *
213 * NOTE: This dentry already has ->d_op set from
214 * ocfs2_get_parent() and ocfs2_get_dentry()
215 */
216 if (ret)
217 dentry = ret;
218
219 status = ocfs2_dentry_attach_lock(dentry, inode,
220 OCFS2_I(dir)->ip_blkno);
221 if (status) {
222 mlog_errno(status);
223 ret = ERR_PTR(status);
224 goto bail_unlock;
225 }
226 }
227
206bail_unlock: 228bail_unlock:
207 /* Don't drop the cluster lock until *after* the d_add -- 229 /* Don't drop the cluster lock until *after* the d_add --
208 * unlink on another node will message us to remove that 230 * unlink on another node will message us to remove that
@@ -418,6 +440,13 @@ static int ocfs2_mknod(struct inode *dir,
418 goto leave; 440 goto leave;
419 } 441 }
420 442
443 status = ocfs2_dentry_attach_lock(dentry, inode,
444 OCFS2_I(dir)->ip_blkno);
445 if (status) {
446 mlog_errno(status);
447 goto leave;
448 }
449
421 insert_inode_hash(inode); 450 insert_inode_hash(inode);
422 dentry->d_op = &ocfs2_dentry_ops; 451 dentry->d_op = &ocfs2_dentry_ops;
423 d_instantiate(dentry, inode); 452 d_instantiate(dentry, inode);
@@ -725,6 +754,12 @@ static int ocfs2_link(struct dentry *old_dentry,
725 goto bail; 754 goto bail;
726 } 755 }
727 756
757 err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
758 if (err) {
759 mlog_errno(err);
760 goto bail;
761 }
762
728 atomic_inc(&inode->i_count); 763 atomic_inc(&inode->i_count);
729 dentry->d_op = &ocfs2_dentry_ops; 764 dentry->d_op = &ocfs2_dentry_ops;
730 d_instantiate(dentry, inode); 765 d_instantiate(dentry, inode);
@@ -743,6 +778,23 @@ bail:
743 return err; 778 return err;
744} 779}
745 780
781/*
782 * Takes and drops an exclusive lock on the given dentry. This will
783 * force other nodes to drop it.
784 */
785static int ocfs2_remote_dentry_delete(struct dentry *dentry)
786{
787 int ret;
788
789 ret = ocfs2_dentry_lock(dentry, 1);
790 if (ret)
791 mlog_errno(ret);
792 else
793 ocfs2_dentry_unlock(dentry, 1);
794
795 return ret;
796}
797
746static int ocfs2_unlink(struct inode *dir, 798static int ocfs2_unlink(struct inode *dir,
747 struct dentry *dentry) 799 struct dentry *dentry)
748{ 800{
@@ -832,8 +884,7 @@ static int ocfs2_unlink(struct inode *dir,
832 else 884 else
833 inode->i_nlink--; 885 inode->i_nlink--;
834 886
835 status = ocfs2_request_unlink_vote(inode, dentry, 887 status = ocfs2_remote_dentry_delete(dentry);
836 (unsigned int) inode->i_nlink);
837 if (status < 0) { 888 if (status < 0) {
838 /* This vote should succeed under all normal 889 /* This vote should succeed under all normal
839 * circumstances. */ 890 * circumstances. */
@@ -1019,7 +1070,6 @@ static int ocfs2_rename(struct inode *old_dir,
1019 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1070 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
1020 // this is the 1st dirent bh 1071 // this is the 1st dirent bh
1021 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; 1072 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
1022 unsigned int links_count;
1023 1073
1024 /* At some point it might be nice to break this function up a 1074 /* At some point it might be nice to break this function up a
1025 * bit. */ 1075 * bit. */
@@ -1093,23 +1143,26 @@ static int ocfs2_rename(struct inode *old_dir,
1093 } 1143 }
1094 } 1144 }
1095 1145
1096 if (S_ISDIR(old_inode->i_mode)) { 1146 /*
1097 /* Directories actually require metadata updates to 1147 * Though we don't require an inode meta data update if
1098 * the directory info so we can't get away with not 1148 * old_inode is not a directory, we lock anyway here to ensure
1099 * doing node locking on it. */ 1149 * the vote thread on other nodes won't have to concurrently
1100 status = ocfs2_meta_lock(old_inode, handle, NULL, 1); 1150 * downconvert the inode and the dentry locks.
1101 if (status < 0) { 1151 */
1102 if (status != -ENOENT) 1152 status = ocfs2_meta_lock(old_inode, handle, NULL, 1);
1103 mlog_errno(status); 1153 if (status < 0) {
1104 goto bail; 1154 if (status != -ENOENT)
1105 }
1106
1107 status = ocfs2_request_rename_vote(old_inode, old_dentry);
1108 if (status < 0) {
1109 mlog_errno(status); 1155 mlog_errno(status);
1110 goto bail; 1156 goto bail;
1111 } 1157 }
1158
1159 status = ocfs2_remote_dentry_delete(old_dentry);
1160 if (status < 0) {
1161 mlog_errno(status);
1162 goto bail;
1163 }
1112 1164
1165 if (S_ISDIR(old_inode->i_mode)) {
1113 status = -EIO; 1166 status = -EIO;
1114 old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0); 1167 old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0);
1115 if (!old_inode_de_bh) 1168 if (!old_inode_de_bh)
@@ -1123,14 +1176,6 @@ static int ocfs2_rename(struct inode *old_dir,
1123 if (!new_inode && new_dir!=old_dir && 1176 if (!new_inode && new_dir!=old_dir &&
1124 new_dir->i_nlink >= OCFS2_LINK_MAX) 1177 new_dir->i_nlink >= OCFS2_LINK_MAX)
1125 goto bail; 1178 goto bail;
1126 } else {
1127 /* Ah, the simple case - we're a file so just send a
1128 * message. */
1129 status = ocfs2_request_rename_vote(old_inode, old_dentry);
1130 if (status < 0) {
1131 mlog_errno(status);
1132 goto bail;
1133 }
1134 } 1179 }
1135 1180
1136 status = -ENOENT; 1181 status = -ENOENT;
@@ -1202,13 +1247,7 @@ static int ocfs2_rename(struct inode *old_dir,
1202 goto bail; 1247 goto bail;
1203 } 1248 }
1204 1249
1205 if (S_ISDIR(new_inode->i_mode)) 1250 status = ocfs2_remote_dentry_delete(new_dentry);
1206 links_count = 0;
1207 else
1208 links_count = (unsigned int) (new_inode->i_nlink - 1);
1209
1210 status = ocfs2_request_unlink_vote(new_inode, new_dentry,
1211 links_count);
1212 if (status < 0) { 1251 if (status < 0) {
1213 mlog_errno(status); 1252 mlog_errno(status);
1214 goto bail; 1253 goto bail;
@@ -1387,6 +1426,7 @@ static int ocfs2_rename(struct inode *old_dir,
1387 } 1426 }
1388 } 1427 }
1389 1428
1429 ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
1390 status = 0; 1430 status = 0;
1391bail: 1431bail:
1392 if (rename_lock) 1432 if (rename_lock)
@@ -1675,6 +1715,12 @@ static int ocfs2_symlink(struct inode *dir,
1675 goto bail; 1715 goto bail;
1676 } 1716 }
1677 1717
1718 status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
1719 if (status) {
1720 mlog_errno(status);
1721 goto bail;
1722 }
1723
1678 insert_inode_hash(inode); 1724 insert_inode_hash(inode);
1679 dentry->d_op = &ocfs2_dentry_ops; 1725 dentry->d_op = &ocfs2_dentry_ops;
1680 d_instantiate(dentry, inode); 1726 d_instantiate(dentry, inode);