diff options
Diffstat (limited to 'fs/ceph/dir.c')
-rw-r--r-- | fs/ceph/dir.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index e0a2dc6fcafc..d902948a90d8 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -40,7 +40,8 @@ int ceph_init_dentry(struct dentry *dentry) | |||
40 | if (dentry->d_fsdata) | 40 | if (dentry->d_fsdata) |
41 | return 0; | 41 | return 0; |
42 | 42 | ||
43 | if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) | 43 | if (dentry->d_parent == NULL || /* nfs fh_to_dentry */ |
44 | ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) | ||
44 | dentry->d_op = &ceph_dentry_ops; | 45 | dentry->d_op = &ceph_dentry_ops; |
45 | else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) | 46 | else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) |
46 | dentry->d_op = &ceph_snapdir_dentry_ops; | 47 | dentry->d_op = &ceph_snapdir_dentry_ops; |
@@ -114,8 +115,8 @@ static int __dcache_readdir(struct file *filp, | |||
114 | spin_lock(&dcache_lock); | 115 | spin_lock(&dcache_lock); |
115 | 116 | ||
116 | /* start at beginning? */ | 117 | /* start at beginning? */ |
117 | if (filp->f_pos == 2 || (last && | 118 | if (filp->f_pos == 2 || last == NULL || |
118 | filp->f_pos < ceph_dentry(last)->offset)) { | 119 | filp->f_pos < ceph_dentry(last)->offset) { |
119 | if (list_empty(&parent->d_subdirs)) | 120 | if (list_empty(&parent->d_subdirs)) |
120 | goto out_unlock; | 121 | goto out_unlock; |
121 | p = parent->d_subdirs.prev; | 122 | p = parent->d_subdirs.prev; |
@@ -336,7 +337,10 @@ more: | |||
336 | if (req->r_reply_info.dir_end) { | 337 | if (req->r_reply_info.dir_end) { |
337 | kfree(fi->last_name); | 338 | kfree(fi->last_name); |
338 | fi->last_name = NULL; | 339 | fi->last_name = NULL; |
339 | fi->next_offset = 2; | 340 | if (ceph_frag_is_rightmost(frag)) |
341 | fi->next_offset = 2; | ||
342 | else | ||
343 | fi->next_offset = 0; | ||
340 | } else { | 344 | } else { |
341 | rinfo = &req->r_reply_info; | 345 | rinfo = &req->r_reply_info; |
342 | err = note_last_dentry(fi, | 346 | err = note_last_dentry(fi, |
@@ -355,18 +359,22 @@ more: | |||
355 | u64 pos = ceph_make_fpos(frag, off); | 359 | u64 pos = ceph_make_fpos(frag, off); |
356 | struct ceph_mds_reply_inode *in = | 360 | struct ceph_mds_reply_inode *in = |
357 | rinfo->dir_in[off - fi->offset].in; | 361 | rinfo->dir_in[off - fi->offset].in; |
362 | struct ceph_vino vino; | ||
363 | ino_t ino; | ||
364 | |||
358 | dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", | 365 | dout("readdir off %d (%d/%d) -> %lld '%.*s' %p\n", |
359 | off, off - fi->offset, rinfo->dir_nr, pos, | 366 | off, off - fi->offset, rinfo->dir_nr, pos, |
360 | rinfo->dir_dname_len[off - fi->offset], | 367 | rinfo->dir_dname_len[off - fi->offset], |
361 | rinfo->dir_dname[off - fi->offset], in); | 368 | rinfo->dir_dname[off - fi->offset], in); |
362 | BUG_ON(!in); | 369 | BUG_ON(!in); |
363 | ftype = le32_to_cpu(in->mode) >> 12; | 370 | ftype = le32_to_cpu(in->mode) >> 12; |
371 | vino.ino = le64_to_cpu(in->ino); | ||
372 | vino.snap = le64_to_cpu(in->snapid); | ||
373 | ino = ceph_vino_to_ino(vino); | ||
364 | if (filldir(dirent, | 374 | if (filldir(dirent, |
365 | rinfo->dir_dname[off - fi->offset], | 375 | rinfo->dir_dname[off - fi->offset], |
366 | rinfo->dir_dname_len[off - fi->offset], | 376 | rinfo->dir_dname_len[off - fi->offset], |
367 | pos, | 377 | pos, ino, ftype) < 0) { |
368 | le64_to_cpu(in->ino), | ||
369 | ftype) < 0) { | ||
370 | dout("filldir stopping us...\n"); | 378 | dout("filldir stopping us...\n"); |
371 | return 0; | 379 | return 0; |
372 | } | 380 | } |
@@ -414,6 +422,7 @@ static void reset_readdir(struct ceph_file_info *fi) | |||
414 | fi->last_readdir = NULL; | 422 | fi->last_readdir = NULL; |
415 | } | 423 | } |
416 | kfree(fi->last_name); | 424 | kfree(fi->last_name); |
425 | fi->last_name = NULL; | ||
417 | fi->next_offset = 2; /* compensate for . and .. */ | 426 | fi->next_offset = 2; /* compensate for . and .. */ |
418 | if (fi->dentry) { | 427 | if (fi->dentry) { |
419 | dput(fi->dentry); | 428 | dput(fi->dentry); |