aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/cluster/tcp_internal.h5
-rw-r--r--fs/ocfs2/export.c4
-rw-r--r--fs/ocfs2/inode.c10
-rw-r--r--fs/ocfs2/namei.c116
4 files changed, 94 insertions, 41 deletions
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h
index ff9e2e2104c2..da42b515cd1d 100644
--- a/fs/ocfs2/cluster/tcp_internal.h
+++ b/fs/ocfs2/cluster/tcp_internal.h
@@ -44,11 +44,14 @@
44 * locking semantics of the file system using the protocol. It should 44 * locking semantics of the file system using the protocol. It should
45 * be somewhere else, I'm sure, but right now it isn't. 45 * be somewhere else, I'm sure, but right now it isn't.
46 * 46 *
47 * New in version 3:
48 * - Replace dentry votes with a cluster lock
49 *
47 * New in version 2: 50 * New in version 2:
48 * - full 64 bit i_size in the metadata lock lvbs 51 * - full 64 bit i_size in the metadata lock lvbs
49 * - introduction of "rw" lock and pushing meta/data locking down 52 * - introduction of "rw" lock and pushing meta/data locking down
50 */ 53 */
51#define O2NET_PROTOCOL_VERSION 2ULL 54#define O2NET_PROTOCOL_VERSION 3ULL
52struct o2net_handshake { 55struct o2net_handshake {
53 __be64 protocol_version; 56 __be64 protocol_version;
54 __be64 connector_id; 57 __be64 connector_id;
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index ec55ab3c1214..ffcd79749e0d 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -33,6 +33,7 @@
33 33
34#include "dir.h" 34#include "dir.h"
35#include "dlmglue.h" 35#include "dlmglue.h"
36#include "dcache.h"
36#include "export.h" 37#include "export.h"
37#include "inode.h" 38#include "inode.h"
38 39
@@ -77,6 +78,7 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
77 mlog_errno(-ENOMEM); 78 mlog_errno(-ENOMEM);
78 return ERR_PTR(-ENOMEM); 79 return ERR_PTR(-ENOMEM);
79 } 80 }
81 result->d_op = &ocfs2_dentry_ops;
80 82
81 mlog_exit_ptr(result); 83 mlog_exit_ptr(result);
82 return result; 84 return result;
@@ -127,6 +129,8 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
127 parent = ERR_PTR(-ENOMEM); 129 parent = ERR_PTR(-ENOMEM);
128 } 130 }
129 131
132 parent->d_op = &ocfs2_dentry_ops;
133
130bail_unlock: 134bail_unlock:
131 ocfs2_meta_unlock(dir, 0); 135 ocfs2_meta_unlock(dir, 0);
132 136
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 7bcf69154592..66ca7a82b68a 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -1025,12 +1025,10 @@ void ocfs2_drop_inode(struct inode *inode)
1025 /* Testing ip_orphaned_slot here wouldn't work because we may 1025 /* Testing ip_orphaned_slot here wouldn't work because we may
1026 * not have gotten a delete_inode vote from any other nodes 1026 * not have gotten a delete_inode vote from any other nodes
1027 * yet. */ 1027 * yet. */
1028 if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) { 1028 if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)
1029 mlog(0, "Inode was orphaned on another node, clearing nlink.\n"); 1029 generic_delete_inode(inode);
1030 inode->i_nlink = 0; 1030 else
1031 } 1031 generic_drop_inode(inode);
1032
1033 generic_drop_inode(inode);
1034 1032
1035 mlog_exit_void(); 1033 mlog_exit_void();
1036} 1034}
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);