aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/dir.c')
-rw-r--r--fs/coda/dir.c286
1 files changed, 140 insertions, 146 deletions
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 898a86dde8f5..04a3dd84c993 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -25,7 +25,6 @@
25#include <linux/coda_psdev.h> 25#include <linux/coda_psdev.h>
26#include <linux/coda_fs_i.h> 26#include <linux/coda_fs_i.h>
27#include <linux/coda_cache.h> 27#include <linux/coda_cache.h>
28#include <linux/coda_proc.h>
29 28
30#include "coda_int.h" 29#include "coda_int.h"
31 30
@@ -43,15 +42,15 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
43 struct inode *new_inode, struct dentry *new_dentry); 42 struct inode *new_inode, struct dentry *new_dentry);
44 43
45/* dir file-ops */ 44/* dir file-ops */
46static int coda_readdir(struct file *file, void *dirent, filldir_t filldir); 45static int coda_readdir(struct file *file, void *buf, filldir_t filldir);
47 46
48/* dentry ops */ 47/* dentry ops */
49static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd); 48static int coda_dentry_revalidate(struct dentry *de, struct nameidata *nd);
50static int coda_dentry_delete(struct dentry *); 49static int coda_dentry_delete(struct dentry *);
51 50
52/* support routines */ 51/* support routines */
53static int coda_venus_readdir(struct file *filp, filldir_t filldir, 52static int coda_venus_readdir(struct file *coda_file, void *buf,
54 void *dirent, struct dentry *dir); 53 filldir_t filldir);
55 54
56/* same as fs/bad_inode.c */ 55/* same as fs/bad_inode.c */
57static int coda_return_EIO(void) 56static int coda_return_EIO(void)
@@ -97,58 +96,45 @@ const struct file_operations coda_dir_operations = {
97/* access routines: lookup, readlink, permission */ 96/* access routines: lookup, readlink, permission */
98static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd) 97static struct dentry *coda_lookup(struct inode *dir, struct dentry *entry, struct nameidata *nd)
99{ 98{
100 struct inode *res_inode = NULL; 99 struct inode *inode = NULL;
101 struct CodaFid resfid = { { 0, } }; 100 struct CodaFid resfid = { { 0, } };
102 int dropme = 0; /* to indicate entry should not be cached */
103 int type = 0; 101 int type = 0;
104 int error = 0; 102 int error = 0;
105 const char *name = entry->d_name.name; 103 const char *name = entry->d_name.name;
106 size_t length = entry->d_name.len; 104 size_t length = entry->d_name.len;
107 105
108 if ( length > CODA_MAXNAMLEN ) { 106 if (length > CODA_MAXNAMLEN) {
109 printk("name too long: lookup, %s (%*s)\n", 107 printk(KERN_ERR "name too long: lookup, %s (%*s)\n",
110 coda_i2s(dir), (int)length, name); 108 coda_i2s(dir), (int)length, name);
111 return ERR_PTR(-ENAMETOOLONG); 109 return ERR_PTR(-ENAMETOOLONG);
112 } 110 }
113 111
112 /* control object, create inode on the fly */
113 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
114 error = coda_cnode_makectl(&inode, dir->i_sb);
115 type = CODA_NOCACHE;
116 goto exit;
117 }
118
114 lock_kernel(); 119 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 120
122 error = venus_lookup(dir->i_sb, coda_i2f(dir), 121 error = venus_lookup(dir->i_sb, coda_i2f(dir), name, length,
123 (const char *)name, length, &type, &resfid); 122 &type, &resfid);
123 if (!error)
124 error = coda_cnode_make(&inode, &resfid, dir->i_sb);
124 125
125 res_inode = NULL; 126 unlock_kernel();
126 if (!error) {
127 if (type & CODA_NOCACHE) {
128 type &= (~CODA_NOCACHE);
129 dropme = 1;
130 }
131 127
132 error = coda_cnode_make(&res_inode, &resfid, dir->i_sb); 128 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); 129 return ERR_PTR(error);
140 }
141 130
142exit: 131exit:
143 entry->d_time = 0;
144 entry->d_op = &coda_dentry_operations; 132 entry->d_op = &coda_dentry_operations;
145 d_add(entry, res_inode); 133
146 if ( dropme ) { 134 if (inode && (type & CODA_NOCACHE))
147 d_drop(entry); 135 coda_flag_inode(inode, C_VATTR | C_PURGE);
148 coda_flag_inode(res_inode, C_VATTR); 136
149 } 137 return d_splice_alias(inode, entry);
150 unlock_kernel();
151 return NULL;
152} 138}
153 139
154 140
@@ -161,8 +147,6 @@ int coda_permission(struct inode *inode, int mask, struct nameidata *nd)
161 147
162 lock_kernel(); 148 lock_kernel();
163 149
164 coda_vfs_stat.permission++;
165
166 if (coda_cache_check(inode, mask)) 150 if (coda_cache_check(inode, mask))
167 goto out; 151 goto out;
168 152
@@ -173,12 +157,11 @@ int coda_permission(struct inode *inode, int mask, struct nameidata *nd)
173 157
174 out: 158 out:
175 unlock_kernel(); 159 unlock_kernel();
176 160 return error;
177 return error;
178} 161}
179 162
180 163
181static inline void coda_dir_changed(struct inode *dir, int link) 164static inline void coda_dir_update_mtime(struct inode *dir)
182{ 165{
183#ifdef REQUERY_VENUS_FOR_MTIME 166#ifdef REQUERY_VENUS_FOR_MTIME
184 /* invalidate the directory cnode's attributes so we refetch the 167 /* invalidate the directory cnode's attributes so we refetch the
@@ -186,12 +169,27 @@ static inline void coda_dir_changed(struct inode *dir, int link)
186 coda_flag_inode(dir, C_VATTR); 169 coda_flag_inode(dir, C_VATTR);
187#else 170#else
188 /* optimistically we can also act as if our nose bleeds. The 171 /* optimistically we can also act as if our nose bleeds. The
189 * granularity of the mtime is coarse anyways so we might actually be 172 * granularity of the mtime is coarse anyways so we might actually be
190 * right most of the time. Note: we only do this for directories. */ 173 * right most of the time. Note: we only do this for directories. */
191 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 174 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
192#endif 175#endif
193 if (link) 176}
194 dir->i_nlink += link; 177
178/* we have to wrap inc_nlink/drop_nlink because sometimes userspace uses a
179 * trick to fool GNU find's optimizations. If we can't be sure of the link
180 * (because of volume mount points) we set i_nlink to 1 which forces find
181 * to consider every child as a possible directory. We should also never
182 * see an increment or decrement for deleted directories where i_nlink == 0 */
183static inline void coda_dir_inc_nlink(struct inode *dir)
184{
185 if (dir->i_nlink >= 2)
186 inc_nlink(dir);
187}
188
189static inline void coda_dir_drop_nlink(struct inode *dir)
190{
191 if (dir->i_nlink > 2)
192 drop_nlink(dir);
195} 193}
196 194
197/* creation routines: create, mknod, mkdir, link, symlink */ 195/* creation routines: create, mknod, mkdir, link, symlink */
@@ -205,7 +203,6 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode, struct na
205 struct coda_vattr attrs; 203 struct coda_vattr attrs;
206 204
207 lock_kernel(); 205 lock_kernel();
208 coda_vfs_stat.create++;
209 206
210 if (coda_isroot(dir) && coda_iscontrol(name, length)) { 207 if (coda_isroot(dir) && coda_iscontrol(name, length)) {
211 unlock_kernel(); 208 unlock_kernel();
@@ -229,10 +226,10 @@ static int coda_create(struct inode *dir, struct dentry *de, int mode, struct na
229 } 226 }
230 227
231 /* invalidate the directory cnode's attributes */ 228 /* invalidate the directory cnode's attributes */
232 coda_dir_changed(dir, 0); 229 coda_dir_update_mtime(dir);
233 unlock_kernel(); 230 unlock_kernel();
234 d_instantiate(de, inode); 231 d_instantiate(de, inode);
235 return 0; 232 return 0;
236} 233}
237 234
238static int coda_mkdir(struct inode *dir, struct dentry *de, int mode) 235static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
@@ -245,7 +242,6 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
245 struct CodaFid newfid; 242 struct CodaFid newfid;
246 243
247 lock_kernel(); 244 lock_kernel();
248 coda_vfs_stat.mkdir++;
249 245
250 if (coda_isroot(dir) && coda_iscontrol(name, len)) { 246 if (coda_isroot(dir) && coda_iscontrol(name, len)) {
251 unlock_kernel(); 247 unlock_kernel();
@@ -268,12 +264,13 @@ static int coda_mkdir(struct inode *dir, struct dentry *de, int mode)
268 d_drop(de); 264 d_drop(de);
269 return PTR_ERR(inode); 265 return PTR_ERR(inode);
270 } 266 }
271 267
272 /* invalidate the directory cnode's attributes */ 268 /* invalidate the directory cnode's attributes */
273 coda_dir_changed(dir, 1); 269 coda_dir_inc_nlink(dir);
270 coda_dir_update_mtime(dir);
274 unlock_kernel(); 271 unlock_kernel();
275 d_instantiate(de, inode); 272 d_instantiate(de, inode);
276 return 0; 273 return 0;
277} 274}
278 275
279/* try to make de an entry in dir_inodde linked to source_de */ 276/* try to make de an entry in dir_inodde linked to source_de */
@@ -286,7 +283,6 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
286 int error; 283 int error;
287 284
288 lock_kernel(); 285 lock_kernel();
289 coda_vfs_stat.link++;
290 286
291 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { 287 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
292 unlock_kernel(); 288 unlock_kernel();
@@ -296,16 +292,16 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
296 error = venus_link(dir_inode->i_sb, coda_i2f(inode), 292 error = venus_link(dir_inode->i_sb, coda_i2f(inode),
297 coda_i2f(dir_inode), (const char *)name, len); 293 coda_i2f(dir_inode), (const char *)name, len);
298 294
299 if (error) { 295 if (error) {
300 d_drop(de); 296 d_drop(de);
301 goto out; 297 goto out;
302 } 298 }
303 299
304 coda_dir_changed(dir_inode, 0); 300 coda_dir_update_mtime(dir_inode);
305 atomic_inc(&inode->i_count); 301 atomic_inc(&inode->i_count);
306 d_instantiate(de, inode); 302 d_instantiate(de, inode);
307 inc_nlink(inode); 303 inc_nlink(inode);
308 304
309out: 305out:
310 unlock_kernel(); 306 unlock_kernel();
311 return(error); 307 return(error);
@@ -318,10 +314,9 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
318 const char *name = de->d_name.name; 314 const char *name = de->d_name.name;
319 int len = de->d_name.len; 315 int len = de->d_name.len;
320 int symlen; 316 int symlen;
321 int error=0; 317 int error = 0;
322 318
323 lock_kernel(); 319 lock_kernel();
324 coda_vfs_stat.symlink++;
325 320
326 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) { 321 if (coda_isroot(dir_inode) && coda_iscontrol(name, len)) {
327 unlock_kernel(); 322 unlock_kernel();
@@ -336,18 +331,18 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de,
336 331
337 /* 332 /*
338 * This entry is now negative. Since we do not create 333 * This entry is now negative. Since we do not create
339 * an inode for the entry we have to drop it. 334 * an inode for the entry we have to drop it.
340 */ 335 */
341 d_drop(de); 336 d_drop(de);
342 error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len, 337 error = venus_symlink(dir_inode->i_sb, coda_i2f(dir_inode), name, len,
343 symname, symlen); 338 symname, symlen);
344 339
345 /* mtime is no good anymore */ 340 /* mtime is no good anymore */
346 if ( !error ) 341 if ( !error )
347 coda_dir_changed(dir_inode, 0); 342 coda_dir_update_mtime(dir_inode);
348 343
349 unlock_kernel(); 344 unlock_kernel();
350 return error; 345 return error;
351} 346}
352 347
353/* destruction routines: unlink, rmdir */ 348/* destruction routines: unlink, rmdir */
@@ -358,79 +353,70 @@ int coda_unlink(struct inode *dir, struct dentry *de)
358 int len = de->d_name.len; 353 int len = de->d_name.len;
359 354
360 lock_kernel(); 355 lock_kernel();
361 coda_vfs_stat.unlink++;
362 356
363 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len); 357 error = venus_remove(dir->i_sb, coda_i2f(dir), name, len);
364 if ( error ) { 358 if ( error ) {
365 unlock_kernel(); 359 unlock_kernel();
366 return error; 360 return error;
367 } 361 }
368 362
369 coda_dir_changed(dir, 0); 363 coda_dir_update_mtime(dir);
370 drop_nlink(de->d_inode); 364 drop_nlink(de->d_inode);
371 unlock_kernel(); 365 unlock_kernel();
372 366 return 0;
373 return 0;
374} 367}
375 368
376int coda_rmdir(struct inode *dir, struct dentry *de) 369int coda_rmdir(struct inode *dir, struct dentry *de)
377{ 370{
378 const char *name = de->d_name.name; 371 const char *name = de->d_name.name;
379 int len = de->d_name.len; 372 int len = de->d_name.len;
380 int error; 373 int error;
381 374
382 lock_kernel(); 375 lock_kernel();
383 coda_vfs_stat.rmdir++;
384 376
385 if (!d_unhashed(de)) {
386 unlock_kernel();
387 return -EBUSY;
388 }
389 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len); 377 error = venus_rmdir(dir->i_sb, coda_i2f(dir), name, len);
378 if (!error) {
379 /* VFS may delete the child */
380 if (de->d_inode)
381 de->d_inode->i_nlink = 0;
390 382
391 if ( error ) { 383 /* fix the link count of the parent */
392 unlock_kernel(); 384 coda_dir_drop_nlink(dir);
393 return error; 385 coda_dir_update_mtime(dir);
394 } 386 }
395
396 coda_dir_changed(dir, -1);
397 drop_nlink(de->d_inode);
398 d_delete(de);
399 unlock_kernel(); 387 unlock_kernel();
400 388 return error;
401 return 0;
402} 389}
403 390
404/* rename */ 391/* rename */
405static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, 392static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
406 struct inode *new_dir, struct dentry *new_dentry) 393 struct inode *new_dir, struct dentry *new_dentry)
407{ 394{
408 const char *old_name = old_dentry->d_name.name; 395 const char *old_name = old_dentry->d_name.name;
409 const char *new_name = new_dentry->d_name.name; 396 const char *new_name = new_dentry->d_name.name;
410 int old_length = old_dentry->d_name.len; 397 int old_length = old_dentry->d_name.len;
411 int new_length = new_dentry->d_name.len; 398 int new_length = new_dentry->d_name.len;
412 int link_adjust = 0; 399 int error;
413 int error;
414 400
415 lock_kernel(); 401 lock_kernel();
416 coda_vfs_stat.rename++;
417 402
418 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir), 403 error = venus_rename(old_dir->i_sb, coda_i2f(old_dir),
419 coda_i2f(new_dir), old_length, new_length, 404 coda_i2f(new_dir), old_length, new_length,
420 (const char *) old_name, (const char *)new_name); 405 (const char *) old_name, (const char *)new_name);
421 406
422 if ( !error ) { 407 if ( !error ) {
423 if ( new_dentry->d_inode ) { 408 if ( new_dentry->d_inode ) {
424 if ( S_ISDIR(new_dentry->d_inode->i_mode) ) 409 if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
425 link_adjust = 1; 410 coda_dir_drop_nlink(old_dir);
426 411 coda_dir_inc_nlink(new_dir);
427 coda_dir_changed(old_dir, -link_adjust); 412 }
428 coda_dir_changed(new_dir, link_adjust); 413 coda_dir_update_mtime(old_dir);
414 coda_dir_update_mtime(new_dir);
429 coda_flag_inode(new_dentry->d_inode, C_VATTR); 415 coda_flag_inode(new_dentry->d_inode, C_VATTR);
430 } else { 416 } else {
431 coda_flag_inode(old_dir, C_VATTR); 417 coda_flag_inode(old_dir, C_VATTR);
432 coda_flag_inode(new_dir, C_VATTR); 418 coda_flag_inode(new_dir, C_VATTR);
433 } 419 }
434 } 420 }
435 unlock_kernel(); 421 unlock_kernel();
436 422
@@ -439,44 +425,41 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry,
439 425
440 426
441/* file operations for directories */ 427/* file operations for directories */
442int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) 428int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir)
443{ 429{
444 struct dentry *coda_dentry = coda_file->f_path.dentry;
445 struct coda_file_info *cfi; 430 struct coda_file_info *cfi;
446 struct file *host_file; 431 struct file *host_file;
447 struct inode *host_inode;
448 int ret; 432 int ret;
449 433
450 cfi = CODA_FTOC(coda_file); 434 cfi = CODA_FTOC(coda_file);
451 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); 435 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
452 host_file = cfi->cfi_container; 436 host_file = cfi->cfi_container;
453 437
454 coda_vfs_stat.readdir++; 438 if (!host_file->f_op)
439 return -ENOTDIR;
455 440
456 host_inode = host_file->f_path.dentry->d_inode; 441 if (host_file->f_op->readdir)
457 mutex_lock(&host_inode->i_mutex); 442 {
458 host_file->f_pos = coda_file->f_pos; 443 /* potemkin case: we were handed a directory inode.
444 * We can't use vfs_readdir because we have to keep the file
445 * position in sync between the coda_file and the host_file.
446 * and as such we need grab the inode mutex. */
447 struct inode *host_inode = host_file->f_path.dentry->d_inode;
459 448
460 if (!host_file->f_op->readdir) { 449 mutex_lock(&host_inode->i_mutex);
461 /* Venus: we must read Venus dirents from the file */ 450 host_file->f_pos = coda_file->f_pos;
462 ret = coda_venus_readdir(host_file, filldir, dirent, coda_dentry);
463 } else {
464 /* potemkin case: we were handed a directory inode. */
465 /* Yuk, we can't call vfs_readdir because we are already
466 * holding the inode semaphore. */
467 ret = -ENOTDIR;
468 if (!host_file->f_op || !host_file->f_op->readdir)
469 goto out;
470 451
471 ret = -ENOENT; 452 ret = -ENOENT;
472 if (!IS_DEADDIR(host_inode)) { 453 if (!IS_DEADDIR(host_inode)) {
473 ret = host_file->f_op->readdir(host_file, dirent, filldir); 454 ret = host_file->f_op->readdir(host_file, buf, filldir);
474 file_accessed(host_file); 455 file_accessed(host_file);
475 } 456 }
457
458 coda_file->f_pos = host_file->f_pos;
459 mutex_unlock(&host_inode->i_mutex);
476 } 460 }
477out: 461 else /* Venus: we must read Venus dirents from a file */
478 coda_file->f_pos = host_file->f_pos; 462 ret = coda_venus_readdir(coda_file, buf, filldir);
479 mutex_unlock(&host_inode->i_mutex);
480 463
481 return ret; 464 return ret;
482} 465}
@@ -501,57 +484,68 @@ static inline unsigned int CDT2DT(unsigned char cdt)
501} 484}
502 485
503/* support routines */ 486/* support routines */
504static int coda_venus_readdir(struct file *filp, filldir_t filldir, 487static int coda_venus_readdir(struct file *coda_file, void *buf,
505 void *dirent, struct dentry *dir) 488 filldir_t filldir)
506{ 489{
507 int result = 0; /* # of entries returned */ 490 int result = 0; /* # of entries returned */
491 struct coda_file_info *cfi;
492 struct coda_inode_info *cii;
493 struct file *host_file;
494 struct dentry *de;
508 struct venus_dirent *vdir; 495 struct venus_dirent *vdir;
509 unsigned long vdir_size = 496 unsigned long vdir_size =
510 (unsigned long)(&((struct venus_dirent *)0)->d_name); 497 (unsigned long)(&((struct venus_dirent *)0)->d_name);
511 unsigned int type; 498 unsigned int type;
512 struct qstr name; 499 struct qstr name;
513 ino_t ino; 500 ino_t ino;
514 int ret, i; 501 int ret;
502
503 cfi = CODA_FTOC(coda_file);
504 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
505 host_file = cfi->cfi_container;
506
507 de = coda_file->f_path.dentry;
508 cii = ITOC(de->d_inode);
515 509
516 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL); 510 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
517 if (!vdir) return -ENOMEM; 511 if (!vdir) return -ENOMEM;
518 512
519 i = filp->f_pos; 513 switch (coda_file->f_pos) {
520 switch(i) {
521 case 0: 514 case 0:
522 ret = filldir(dirent, ".", 1, 0, dir->d_inode->i_ino, DT_DIR); 515 ret = filldir(buf, ".", 1, 0, de->d_inode->i_ino, DT_DIR);
523 if (ret < 0) break; 516 if (ret < 0) break;
524 result++; 517 result++;
525 filp->f_pos++; 518 coda_file->f_pos++;
526 /* fallthrough */ 519 /* fallthrough */
527 case 1: 520 case 1:
528 ret = filldir(dirent, "..", 2, 1, dir->d_parent->d_inode->i_ino, DT_DIR); 521 ret = filldir(buf, "..", 2, 1, de->d_parent->d_inode->i_ino, DT_DIR);
529 if (ret < 0) break; 522 if (ret < 0) break;
530 result++; 523 result++;
531 filp->f_pos++; 524 coda_file->f_pos++;
532 /* fallthrough */ 525 /* fallthrough */
533 default: 526 default:
534 while (1) { 527 while (1) {
535 /* read entries from the directory file */ 528 /* read entries from the directory file */
536 ret = kernel_read(filp, filp->f_pos - 2, (char *)vdir, 529 ret = kernel_read(host_file, coda_file->f_pos - 2, (char *)vdir,
537 sizeof(*vdir)); 530 sizeof(*vdir));
538 if (ret < 0) { 531 if (ret < 0) {
539 printk("coda_venus_readdir: read dir failed %d\n", ret); 532 printk(KERN_ERR "coda readdir: read dir %s failed %d\n",
533 coda_f2s(&cii->c_fid), ret);
540 break; 534 break;
541 } 535 }
542 if (ret == 0) break; /* end of directory file reached */ 536 if (ret == 0) break; /* end of directory file reached */
543 537
544 /* catch truncated reads */ 538 /* catch truncated reads */
545 if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) { 539 if (ret < vdir_size || ret < vdir_size + vdir->d_namlen) {
546 printk("coda_venus_readdir: short read: %ld\n", 540 printk(KERN_ERR "coda readdir: short read on %s\n",
547 filp->f_path.dentry->d_inode->i_ino); 541 coda_f2s(&cii->c_fid));
548 ret = -EBADF; 542 ret = -EBADF;
549 break; 543 break;
550 } 544 }
551 /* validate whether the directory file actually makes sense */ 545 /* validate whether the directory file actually makes sense */
552 if (vdir->d_reclen < vdir_size + vdir->d_namlen) { 546 if (vdir->d_reclen < vdir_size + vdir->d_namlen) {
553 printk("coda_venus_readdir: Invalid dir: %ld\n", 547 printk(KERN_ERR "coda readdir: invalid dir %s\n",
554 filp->f_path.dentry->d_inode->i_ino); 548 coda_f2s(&cii->c_fid));
555 ret = -EBADF; 549 ret = -EBADF;
556 break; 550 break;
557 } 551 }
@@ -570,21 +564,21 @@ static int coda_venus_readdir(struct file *filp, filldir_t filldir,
570 * userspace doesn't have to worry about breaking 564 * userspace doesn't have to worry about breaking
571 * getcwd by having mismatched inode numbers for 565 * getcwd by having mismatched inode numbers for
572 * internal volume mountpoints. */ 566 * internal volume mountpoints. */
573 ino = find_inode_number(dir, &name); 567 ino = find_inode_number(de, &name);
574 if (!ino) ino = vdir->d_fileno; 568 if (!ino) ino = vdir->d_fileno;
575 569
576 type = CDT2DT(vdir->d_type); 570 type = CDT2DT(vdir->d_type);
577 ret = filldir(dirent, name.name, name.len, filp->f_pos, 571 ret = filldir(buf, name.name, name.len,
578 ino, type); 572 coda_file->f_pos, ino, type);
579 /* failure means no space for filling in this round */ 573 /* failure means no space for filling in this round */
580 if (ret < 0) break; 574 if (ret < 0) break;
581 result++; 575 result++;
582 } 576 }
583 /* we'll always have progress because d_reclen is unsigned and 577 /* we'll always have progress because d_reclen is unsigned and
584 * we've already established it is non-zero. */ 578 * we've already established it is non-zero. */
585 filp->f_pos += vdir->d_reclen; 579 coda_file->f_pos += vdir->d_reclen;
580 }
586 } 581 }
587 }
588 kfree(vdir); 582 kfree(vdir);
589 return result ? result : ret; 583 return result ? result : ret;
590} 584}