aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/coda/dir.c57
1 files changed, 22 insertions, 35 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 47ac9e21a590..0c6c48ca7496 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -97,58 +97,45 @@ const struct file_operations coda_dir_operations = {
97/* access routines: lookup, readlink, permission */ 97/* access routines: lookup, readlink, permission */
98static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) 98static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
99{ 99{
100 struct inode *res_inode = NULL; 100 struct inode *inode = NULL;
101 struct CodaFid resfid = { { 0, } }; 101 struct CodaFid resfid = { { 0, } };
102 int dropme = 0; /* to indicate entry should not be cached */
103 int type = 0; 102 int type = 0;
104 int error = 0; 103 int error = 0;
105 const char *name = entry->d_name.name; 104 const char *name = entry->d_name.name;
106 size_t length = entry->d_name.len; 105 size_t length = entry->d_name.len;
107 106
108 if ( length > CODA_MAXNAMLEN ) { 107 if (length > CODA_MAXNAMLEN) {
109 printk("name too long: lookup, %s (%*s)\n", 108 printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
110 coda_i2s(dir), (int)length, name); 109 coda_i2s(dir), (int)length, name);
111 return ERR_PTR(-ENAMETOOLONG); 110 return ERR_PTR(-ENAMETOOLONG);
112 } 111 }
113 112
113 /* control object, create inode on the fly */
114 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
115 error = coda_cnode_makectl(&inode, dir->i_sb);
116 type = CODA_NOCACHE;
117 goto exit;
118 }
119
114 lock_kernel(); 120 lock_kernel();
115 /* control object, create inode on the fly */
116 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
117 error = coda_cnode_makectl(&res_inode, dir->i_sb);
118 dropme = 1;
119 goto exit;
120 }
121 121
122 error = venus_lookup(dir->i_sb, coda_i2f(dir), 122 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
123 (const char *)name, length, &type, &resfid); 123 &type, &resfid);
124 if (!error)
125 error = coda_cnode_make(&inode, &resfid, dir->i_sb);
124 126
125 res_inode = NULL; 127 unlock_kernel();
126 if (!error) {
127 if (type & CODA_NOCACHE) {
128 type &= (~CODA_NOCACHE);
129 dropme = 1;
130 }
131 128
132 error = coda_cnode_make(&res_inode, &resfid, dir->i_sb); 129 if (error && error != -ENOENT)
133 if (error) {
134 unlock_kernel();
135 return ERR_PTR(error);
136 }
137 } else if (error != -ENOENT) {
138 unlock_kernel();
139 return ERR_PTR(error); 130 return ERR_PTR(error);
140 }
141 131
142exit: 132exit:
143 entry->d_time = 0;
144 entry->d_op = &coda_dentry_operations; 133 entry->d_op = &coda_dentry_operations;
145 d_add(entry, res_inode); 134
146 if ( dropme ) { 135 if (inode && (type & CODA_NOCACHE))
147 d_drop(entry); 136 coda_flag_inode(inode, C_VATTR | C_PURGE);
148 coda_flag_inode(res_inode, C_VATTR); 137
149 } 138 return d_splice_alias(inode, entry);
150 unlock_kernel();
151 return NULL;
152} 139}
153 140
154 141