diff options
-rw-r--r-- | fs/ocfs2/vote.c | 180 | ||||
-rw-r--r-- | fs/ocfs2/vote.h | 5 |
2 files changed, 2 insertions, 183 deletions
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c index cf70fe2075b8..5b4dca79990b 100644 --- a/fs/ocfs2/vote.c +++ b/fs/ocfs2/vote.c | |||
@@ -74,9 +74,6 @@ struct ocfs2_vote_msg | |||
74 | __be32 v_orphaned_slot; /* Used during delete votes */ | 74 | __be32 v_orphaned_slot; /* Used during delete votes */ |
75 | __be32 v_nlink; /* Used during unlink votes */ | 75 | __be32 v_nlink; /* Used during unlink votes */ |
76 | } md1; /* Message type dependant 1 */ | 76 | } md1; /* Message type dependant 1 */ |
77 | __be32 v_unlink_namelen; | ||
78 | __be64 v_unlink_parent; | ||
79 | u8 v_unlink_dirent[OCFS2_VOTE_FILENAME_LEN]; | ||
80 | }; | 77 | }; |
81 | 78 | ||
82 | /* Responses are given these values to maintain backwards | 79 | /* Responses are given these values to maintain backwards |
@@ -100,8 +97,6 @@ struct ocfs2_vote_work { | |||
100 | enum ocfs2_vote_request { | 97 | enum ocfs2_vote_request { |
101 | OCFS2_VOTE_REQ_INVALID = 0, | 98 | OCFS2_VOTE_REQ_INVALID = 0, |
102 | OCFS2_VOTE_REQ_DELETE, | 99 | OCFS2_VOTE_REQ_DELETE, |
103 | OCFS2_VOTE_REQ_UNLINK, | ||
104 | OCFS2_VOTE_REQ_RENAME, | ||
105 | OCFS2_VOTE_REQ_MOUNT, | 100 | OCFS2_VOTE_REQ_MOUNT, |
106 | OCFS2_VOTE_REQ_UMOUNT, | 101 | OCFS2_VOTE_REQ_UMOUNT, |
107 | OCFS2_VOTE_REQ_LAST | 102 | OCFS2_VOTE_REQ_LAST |
@@ -261,103 +256,13 @@ done: | |||
261 | return response; | 256 | return response; |
262 | } | 257 | } |
263 | 258 | ||
264 | static int ocfs2_match_dentry(struct dentry *dentry, | ||
265 | u64 parent_blkno, | ||
266 | unsigned int namelen, | ||
267 | const char *name) | ||
268 | { | ||
269 | struct inode *parent; | ||
270 | |||
271 | if (!dentry->d_parent) { | ||
272 | mlog(0, "Detached from parent.\n"); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | parent = dentry->d_parent->d_inode; | ||
277 | /* Negative parent dentry? */ | ||
278 | if (!parent) | ||
279 | return 0; | ||
280 | |||
281 | /* Name is in a different directory. */ | ||
282 | if (OCFS2_I(parent)->ip_blkno != parent_blkno) | ||
283 | return 0; | ||
284 | |||
285 | if (dentry->d_name.len != namelen) | ||
286 | return 0; | ||
287 | |||
288 | /* comparison above guarantees this is safe. */ | ||
289 | if (memcmp(dentry->d_name.name, name, namelen)) | ||
290 | return 0; | ||
291 | |||
292 | return 1; | ||
293 | } | ||
294 | |||
295 | static void ocfs2_process_dentry_request(struct inode *inode, | ||
296 | int rename, | ||
297 | unsigned int new_nlink, | ||
298 | u64 parent_blkno, | ||
299 | unsigned int namelen, | ||
300 | const char *name) | ||
301 | { | ||
302 | struct dentry *dentry = NULL; | ||
303 | struct list_head *p; | ||
304 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
305 | |||
306 | mlog(0, "parent %llu, namelen = %u, name = %.*s\n", | ||
307 | (unsigned long long)parent_blkno, namelen, namelen, name); | ||
308 | |||
309 | spin_lock(&dcache_lock); | ||
310 | |||
311 | /* Another node is removing this name from the system. It is | ||
312 | * up to us to find the corresponding dentry and if it exists, | ||
313 | * unhash it from the dcache. */ | ||
314 | list_for_each(p, &inode->i_dentry) { | ||
315 | dentry = list_entry(p, struct dentry, d_alias); | ||
316 | |||
317 | if (ocfs2_match_dentry(dentry, parent_blkno, namelen, name)) { | ||
318 | mlog(0, "dentry found: %.*s\n", | ||
319 | dentry->d_name.len, dentry->d_name.name); | ||
320 | |||
321 | dget_locked(dentry); | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | dentry = NULL; | ||
326 | } | ||
327 | |||
328 | spin_unlock(&dcache_lock); | ||
329 | |||
330 | if (dentry) { | ||
331 | d_delete(dentry); | ||
332 | dput(dentry); | ||
333 | } | ||
334 | |||
335 | /* rename votes don't send link counts */ | ||
336 | if (!rename) { | ||
337 | mlog(0, "new_nlink = %u\n", new_nlink); | ||
338 | |||
339 | /* We don't have the proper locks here to directly | ||
340 | * change i_nlink and besides, the vote is sent | ||
341 | * *before* the operation so it may have failed on the | ||
342 | * other node. This passes a hint to ocfs2_drop_inode | ||
343 | * to force ocfs2_delete_inode, who will take the | ||
344 | * proper cluster locks to sort things out. */ | ||
345 | if (new_nlink == 0) { | ||
346 | spin_lock(&oi->ip_lock); | ||
347 | oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED; | ||
348 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | |||
353 | static void ocfs2_process_vote(struct ocfs2_super *osb, | 259 | static void ocfs2_process_vote(struct ocfs2_super *osb, |
354 | struct ocfs2_vote_msg *msg) | 260 | struct ocfs2_vote_msg *msg) |
355 | { | 261 | { |
356 | int net_status, vote_response; | 262 | int net_status, vote_response; |
357 | int orphaned_slot = 0; | 263 | int orphaned_slot = 0; |
358 | int rename = 0; | 264 | unsigned int node_num, generation; |
359 | unsigned int node_num, generation, new_nlink, namelen; | 265 | u64 blkno; |
360 | u64 blkno, parent_blkno; | ||
361 | enum ocfs2_vote_request request; | 266 | enum ocfs2_vote_request request; |
362 | struct inode *inode = NULL; | 267 | struct inode *inode = NULL; |
363 | struct ocfs2_msg_hdr *hdr = &msg->v_hdr; | 268 | struct ocfs2_msg_hdr *hdr = &msg->v_hdr; |
@@ -437,18 +342,6 @@ static void ocfs2_process_vote(struct ocfs2_super *osb, | |||
437 | vote_response = ocfs2_process_delete_request(inode, | 342 | vote_response = ocfs2_process_delete_request(inode, |
438 | &orphaned_slot); | 343 | &orphaned_slot); |
439 | break; | 344 | break; |
440 | case OCFS2_VOTE_REQ_RENAME: | ||
441 | rename = 1; | ||
442 | /* fall through */ | ||
443 | case OCFS2_VOTE_REQ_UNLINK: | ||
444 | parent_blkno = be64_to_cpu(msg->v_unlink_parent); | ||
445 | namelen = be32_to_cpu(msg->v_unlink_namelen); | ||
446 | /* new_nlink will be ignored in case of a rename vote */ | ||
447 | new_nlink = be32_to_cpu(msg->md1.v_nlink); | ||
448 | ocfs2_process_dentry_request(inode, rename, new_nlink, | ||
449 | parent_blkno, namelen, | ||
450 | msg->v_unlink_dirent); | ||
451 | break; | ||
452 | default: | 345 | default: |
453 | mlog(ML_ERROR, "node %u, invalid request: %u\n", | 346 | mlog(ML_ERROR, "node %u, invalid request: %u\n", |
454 | node_num, request); | 347 | node_num, request); |
@@ -889,75 +782,6 @@ int ocfs2_request_delete_vote(struct inode *inode) | |||
889 | return status; | 782 | return status; |
890 | } | 783 | } |
891 | 784 | ||
892 | static void ocfs2_setup_unlink_vote(struct ocfs2_vote_msg *request, | ||
893 | struct dentry *dentry) | ||
894 | { | ||
895 | struct inode *parent = dentry->d_parent->d_inode; | ||
896 | |||
897 | /* We need some values which will uniquely identify a dentry | ||
898 | * on the other nodes so that they can find it and run | ||
899 | * d_delete against it. Parent directory block and full name | ||
900 | * should suffice. */ | ||
901 | |||
902 | mlog(0, "unlink/rename request: parent: %llu name: %.*s\n", | ||
903 | (unsigned long long)OCFS2_I(parent)->ip_blkno, dentry->d_name.len, | ||
904 | dentry->d_name.name); | ||
905 | |||
906 | request->v_unlink_parent = cpu_to_be64(OCFS2_I(parent)->ip_blkno); | ||
907 | request->v_unlink_namelen = cpu_to_be32(dentry->d_name.len); | ||
908 | memcpy(request->v_unlink_dirent, dentry->d_name.name, | ||
909 | dentry->d_name.len); | ||
910 | } | ||
911 | |||
912 | int ocfs2_request_unlink_vote(struct inode *inode, | ||
913 | struct dentry *dentry, | ||
914 | unsigned int nlink) | ||
915 | { | ||
916 | int status; | ||
917 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
918 | struct ocfs2_vote_msg *request; | ||
919 | |||
920 | if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN) | ||
921 | return -ENAMETOOLONG; | ||
922 | |||
923 | status = -ENOMEM; | ||
924 | request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno, | ||
925 | inode->i_generation, | ||
926 | OCFS2_VOTE_REQ_UNLINK, nlink); | ||
927 | if (request) { | ||
928 | ocfs2_setup_unlink_vote(request, dentry); | ||
929 | |||
930 | status = ocfs2_request_vote(inode, request, NULL); | ||
931 | |||
932 | kfree(request); | ||
933 | } | ||
934 | return status; | ||
935 | } | ||
936 | |||
937 | int ocfs2_request_rename_vote(struct inode *inode, | ||
938 | struct dentry *dentry) | ||
939 | { | ||
940 | int status; | ||
941 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
942 | struct ocfs2_vote_msg *request; | ||
943 | |||
944 | if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN) | ||
945 | return -ENAMETOOLONG; | ||
946 | |||
947 | status = -ENOMEM; | ||
948 | request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno, | ||
949 | inode->i_generation, | ||
950 | OCFS2_VOTE_REQ_RENAME, 0); | ||
951 | if (request) { | ||
952 | ocfs2_setup_unlink_vote(request, dentry); | ||
953 | |||
954 | status = ocfs2_request_vote(inode, request, NULL); | ||
955 | |||
956 | kfree(request); | ||
957 | } | ||
958 | return status; | ||
959 | } | ||
960 | |||
961 | int ocfs2_request_mount_vote(struct ocfs2_super *osb) | 785 | int ocfs2_request_mount_vote(struct ocfs2_super *osb) |
962 | { | 786 | { |
963 | int status; | 787 | int status; |
diff --git a/fs/ocfs2/vote.h b/fs/ocfs2/vote.h index 9cce60703466..53ebc1c69e56 100644 --- a/fs/ocfs2/vote.h +++ b/fs/ocfs2/vote.h | |||
@@ -39,11 +39,6 @@ static inline void ocfs2_kick_vote_thread(struct ocfs2_super *osb) | |||
39 | } | 39 | } |
40 | 40 | ||
41 | int ocfs2_request_delete_vote(struct inode *inode); | 41 | int ocfs2_request_delete_vote(struct inode *inode); |
42 | int ocfs2_request_unlink_vote(struct inode *inode, | ||
43 | struct dentry *dentry, | ||
44 | unsigned int nlink); | ||
45 | int ocfs2_request_rename_vote(struct inode *inode, | ||
46 | struct dentry *dentry); | ||
47 | int ocfs2_request_mount_vote(struct ocfs2_super *osb); | 42 | int ocfs2_request_mount_vote(struct ocfs2_super *osb); |
48 | int ocfs2_request_umount_vote(struct ocfs2_super *osb); | 43 | int ocfs2_request_umount_vote(struct ocfs2_super *osb); |
49 | int ocfs2_register_net_handlers(struct ocfs2_super *osb); | 44 | int ocfs2_register_net_handlers(struct ocfs2_super *osb); |