diff options
Diffstat (limited to 'fs/coda/cnode.c')
-rw-r--r-- | fs/coda/cnode.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/coda/cnode.c b/fs/coda/cnode.c index a7a780929eec..6475877b0763 100644 --- a/fs/coda/cnode.c +++ b/fs/coda/cnode.c | |||
@@ -7,9 +7,8 @@ | |||
7 | #include <linux/time.h> | 7 | #include <linux/time.h> |
8 | 8 | ||
9 | #include <linux/coda.h> | 9 | #include <linux/coda.h> |
10 | #include <linux/coda_linux.h> | ||
11 | #include <linux/coda_fs_i.h> | ||
12 | #include <linux/coda_psdev.h> | 10 | #include <linux/coda_psdev.h> |
11 | #include "coda_linux.h" | ||
13 | 12 | ||
14 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) | 13 | static inline int coda_fideq(struct CodaFid *fid1, struct CodaFid *fid2) |
15 | { | 14 | { |
@@ -45,13 +44,15 @@ static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr) | |||
45 | static int coda_test_inode(struct inode *inode, void *data) | 44 | static int coda_test_inode(struct inode *inode, void *data) |
46 | { | 45 | { |
47 | struct CodaFid *fid = (struct CodaFid *)data; | 46 | struct CodaFid *fid = (struct CodaFid *)data; |
48 | return coda_fideq(&(ITOC(inode)->c_fid), fid); | 47 | struct coda_inode_info *cii = ITOC(inode); |
48 | return coda_fideq(&cii->c_fid, fid); | ||
49 | } | 49 | } |
50 | 50 | ||
51 | static int coda_set_inode(struct inode *inode, void *data) | 51 | static int coda_set_inode(struct inode *inode, void *data) |
52 | { | 52 | { |
53 | struct CodaFid *fid = (struct CodaFid *)data; | 53 | struct CodaFid *fid = (struct CodaFid *)data; |
54 | ITOC(inode)->c_fid = *fid; | 54 | struct coda_inode_info *cii = ITOC(inode); |
55 | cii->c_fid = *fid; | ||
55 | return 0; | 56 | return 0; |
56 | } | 57 | } |
57 | 58 | ||
@@ -71,6 +72,7 @@ struct inode * coda_iget(struct super_block * sb, struct CodaFid * fid, | |||
71 | cii = ITOC(inode); | 72 | cii = ITOC(inode); |
72 | /* we still need to set i_ino for things like stat(2) */ | 73 | /* we still need to set i_ino for things like stat(2) */ |
73 | inode->i_ino = hash; | 74 | inode->i_ino = hash; |
75 | /* inode is locked and unique, no need to grab cii->c_lock */ | ||
74 | cii->c_mapcount = 0; | 76 | cii->c_mapcount = 0; |
75 | unlock_new_inode(inode); | 77 | unlock_new_inode(inode); |
76 | } | 78 | } |
@@ -107,14 +109,20 @@ int coda_cnode_make(struct inode **inode, struct CodaFid *fid, struct super_bloc | |||
107 | } | 109 | } |
108 | 110 | ||
109 | 111 | ||
112 | /* Although we treat Coda file identifiers as immutable, there is one | ||
113 | * special case for files created during a disconnection where they may | ||
114 | * not be globally unique. When an identifier collision is detected we | ||
115 | * first try to flush the cached inode from the kernel and finally | ||
116 | * resort to renaming/rehashing in-place. Userspace remembers both old | ||
117 | * and new values of the identifier to handle any in-flight upcalls. | ||
118 | * The real solution is to use globally unique UUIDs as identifiers, but | ||
119 | * retrofitting the existing userspace code for this is non-trivial. */ | ||
110 | void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid, | 120 | void coda_replace_fid(struct inode *inode, struct CodaFid *oldfid, |
111 | struct CodaFid *newfid) | 121 | struct CodaFid *newfid) |
112 | { | 122 | { |
113 | struct coda_inode_info *cii; | 123 | struct coda_inode_info *cii = ITOC(inode); |
114 | unsigned long hash = coda_f2i(newfid); | 124 | unsigned long hash = coda_f2i(newfid); |
115 | 125 | ||
116 | cii = ITOC(inode); | ||
117 | |||
118 | BUG_ON(!coda_fideq(&cii->c_fid, oldfid)); | 126 | BUG_ON(!coda_fideq(&cii->c_fid, oldfid)); |
119 | 127 | ||
120 | /* replace fid and rehash inode */ | 128 | /* replace fid and rehash inode */ |