aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/namei.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2006-09-08 17:21:03 -0400
committerMark Fasheh <mark.fasheh@oracle.com>2006-09-24 16:50:43 -0400
commit379dfe9d0db99ed33fb089fcb9c07f5f92566e9e (patch)
tree8f04d8dbf97fa70d8f02fcbb037e7b318cd7143e /fs/ocfs2/namei.c
parent80c05846f604bab6d61e9732c262420ee9f5f358 (diff)
ocfs2: Hook rest of the file system into dentry locking API
Actually replace the vote calls with the new dentry operations. Make any necessary adjustments to get the scheme to work. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/namei.c')
-rw-r--r--fs/ocfs2/namei.c116
1 files changed, 82 insertions, 34 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 0d3e939b1f56..5a942e0123ea 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -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, 0);
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, 1);
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,13 @@ 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 0);
759 if (err) {
760 mlog_errno(err);
761 goto bail;
762 }
763
728 atomic_inc(&inode->i_count); 764 atomic_inc(&inode->i_count);
729 dentry->d_op = &ocfs2_dentry_ops; 765 dentry->d_op = &ocfs2_dentry_ops;
730 d_instantiate(dentry, inode); 766 d_instantiate(dentry, inode);
@@ -743,6 +779,23 @@ bail:
743 return err; 779 return err;
744} 780}
745 781
782/*
783 * Takes and drops an exclusive lock on the given dentry. This will
784 * force other nodes to drop it.
785 */
786static int ocfs2_remote_dentry_delete(struct dentry *dentry)
787{
788 int ret;
789
790 ret = ocfs2_dentry_lock(dentry, 1);
791 if (ret)
792 mlog_errno(ret);
793 else
794 ocfs2_dentry_unlock(dentry, 1);
795
796 return ret;
797}
798
746static int ocfs2_unlink(struct inode *dir, 799static int ocfs2_unlink(struct inode *dir,
747 struct dentry *dentry) 800 struct dentry *dentry)
748{ 801{
@@ -832,8 +885,7 @@ static int ocfs2_unlink(struct inode *dir,
832 else 885 else
833 inode->i_nlink--; 886 inode->i_nlink--;
834 887
835 status = ocfs2_request_unlink_vote(inode, dentry, 888 status = ocfs2_remote_dentry_delete(dentry);
836 (unsigned int) inode->i_nlink);
837 if (status < 0) { 889 if (status < 0) {
838 /* This vote should succeed under all normal 890 /* This vote should succeed under all normal
839 * circumstances. */ 891 * circumstances. */
@@ -1019,7 +1071,6 @@ static int ocfs2_rename(struct inode *old_dir,
1019 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1071 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
1020 // this is the 1st dirent bh 1072 // this is the 1st dirent bh
1021 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; 1073 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
1022 unsigned int links_count;
1023 1074
1024 /* At some point it might be nice to break this function up a 1075 /* At some point it might be nice to break this function up a
1025 * bit. */ 1076 * bit. */
@@ -1093,23 +1144,26 @@ static int ocfs2_rename(struct inode *old_dir,
1093 } 1144 }
1094 } 1145 }
1095 1146
1096 if (S_ISDIR(old_inode->i_mode)) { 1147 /*
1097 /* Directories actually require metadata updates to 1148 * Though we don't require an inode meta data update if
1098 * the directory info so we can't get away with not 1149 * old_inode is not a directory, we lock anyway here to ensure
1099 * doing node locking on it. */ 1150 * the vote thread on other nodes won't have to concurrently
1100 status = ocfs2_meta_lock(old_inode, handle, NULL, 1); 1151 * downconvert the inode and the dentry locks.
1101 if (status < 0) { 1152 */
1102 if (status != -ENOENT) 1153 status = ocfs2_meta_lock(old_inode, handle, NULL, 1);
1103 mlog_errno(status); 1154 if (status < 0) {
1104 goto bail; 1155 if (status != -ENOENT)
1105 }
1106
1107 status = ocfs2_request_rename_vote(old_inode, old_dentry);
1108 if (status < 0) {
1109 mlog_errno(status); 1156 mlog_errno(status);
1110 goto bail; 1157 goto bail;
1111 } 1158 }
1159
1160 status = ocfs2_remote_dentry_delete(old_dentry);
1161 if (status < 0) {
1162 mlog_errno(status);
1163 goto bail;
1164 }
1112 1165
1166 if (S_ISDIR(old_inode->i_mode)) {
1113 status = -EIO; 1167 status = -EIO;
1114 old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0); 1168 old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0);
1115 if (!old_inode_de_bh) 1169 if (!old_inode_de_bh)
@@ -1123,14 +1177,6 @@ static int ocfs2_rename(struct inode *old_dir,
1123 if (!new_inode && new_dir!=old_dir && 1177 if (!new_inode && new_dir!=old_dir &&
1124 new_dir->i_nlink >= OCFS2_LINK_MAX) 1178 new_dir->i_nlink >= OCFS2_LINK_MAX)
1125 goto bail; 1179 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 } 1180 }
1135 1181
1136 status = -ENOENT; 1182 status = -ENOENT;
@@ -1202,13 +1248,7 @@ static int ocfs2_rename(struct inode *old_dir,
1202 goto bail; 1248 goto bail;
1203 } 1249 }
1204 1250
1205 if (S_ISDIR(new_inode->i_mode)) 1251 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) { 1252 if (status < 0) {
1213 mlog_errno(status); 1253 mlog_errno(status);
1214 goto bail; 1254 goto bail;
@@ -1387,6 +1427,7 @@ static int ocfs2_rename(struct inode *old_dir,
1387 } 1427 }
1388 } 1428 }
1389 1429
1430 ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
1390 status = 0; 1431 status = 0;
1391bail: 1432bail:
1392 if (rename_lock) 1433 if (rename_lock)
@@ -1675,6 +1716,13 @@ static int ocfs2_symlink(struct inode *dir,
1675 goto bail; 1716 goto bail;
1676 } 1717 }
1677 1718
1719 status = ocfs2_dentry_attach_lock(dentry, inode,
1720 OCFS2_I(dir)->ip_blkno, 1);
1721 if (status) {
1722 mlog_errno(status);
1723 goto bail;
1724 }
1725
1678 insert_inode_hash(inode); 1726 insert_inode_hash(inode);
1679 dentry->d_op = &ocfs2_dentry_ops; 1727 dentry->d_op = &ocfs2_dentry_ops;
1680 d_instantiate(dentry, inode); 1728 d_instantiate(dentry, inode);