summaryrefslogtreecommitdiffstats
path: root/fs/ceph/dir.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-21 23:03:15 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-21 23:03:15 -0300
commite899966f626f1f657a4a7bac736c0b9ae5a243ea (patch)
treea4bb8362d871da67b41fee27bb85ad0bc83e0591 /fs/ceph/dir.c
parentba0d342ecc21fbbe2f6c178f4479944d1fb34f3b (diff)
parent4b660a7f5c8099d88d1a43d8ae138965112592c7 (diff)
downloadop-kernel-dev-e899966f626f1f657a4a7bac736c0b9ae5a243ea.zip
op-kernel-dev-e899966f626f1f657a4a7bac736c0b9ae5a243ea.tar.gz
Merge tag 'v3.15-rc6' into patchwork
Linux 3.15-rc6 * tag 'v3.15-rc6': (1314 commits) Linux 3.15-rc6 Btrfs: send, fix incorrect ref access when using extrefs Btrfs: fix EIO on reading file after ioctl clone works on it scripts/checksyscalls.sh: Make renameat optional asm-generic: Add renameat2 syscall ia64: add renameat2 syscall parisc: add renameat2 syscall m68k: add renameat2 syscall sysfs: make sure read buffer is zeroed ahci: imx: PLL clock needs 100us to settle down PCI: Wrong register used to check pending traffic target: fix memory leak on XCOPY random: fix BUG_ON caused by accounting simplification clk: tegra: Fix wrong value written to PLLE_AUX staging: rtl8723au: Do not reset wdev->iftype in netdev_close() ACPI / video: Revert native brightness quirk for ThinkPad T530 staging: rtl8723au: Use correct pipe type for USB interrupts crush: decode and initialize chooseleaf_vary_r libceph: fix corruption when using page_count 0 page in rbd arm64: fix pud_huge() for 2-level pagetables ...
Diffstat (limited to 'fs/ceph/dir.c')
-rw-r--r--fs/ceph/dir.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 766410a..c29d6ae 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -141,7 +141,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx,
/* start at beginning? */
if (ctx->pos == 2 || last == NULL ||
- ctx->pos < ceph_dentry(last)->offset) {
+ fpos_cmp(ctx->pos, ceph_dentry(last)->offset) < 0) {
if (list_empty(&parent->d_subdirs))
goto out_unlock;
p = parent->d_subdirs.prev;
@@ -182,9 +182,16 @@ more:
spin_unlock(&dentry->d_lock);
spin_unlock(&parent->d_lock);
+ /* make sure a dentry wasn't dropped while we didn't have parent lock */
+ if (!ceph_dir_is_complete(dir)) {
+ dout(" lost dir complete on %p; falling back to mds\n", dir);
+ dput(dentry);
+ err = -EAGAIN;
+ goto out;
+ }
+
dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos,
dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode);
- ctx->pos = di->offset;
if (!dir_emit(ctx, dentry->d_name.name,
dentry->d_name.len,
ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino),
@@ -198,19 +205,12 @@ more:
return 0;
}
+ ctx->pos = di->offset + 1;
+
if (last)
dput(last);
last = dentry;
- ctx->pos++;
-
- /* make sure a dentry wasn't dropped while we didn't have parent lock */
- if (!ceph_dir_is_complete(dir)) {
- dout(" lost dir complete on %p; falling back to mds\n", dir);
- err = -EAGAIN;
- goto out;
- }
-
spin_lock(&parent->d_lock);
p = p->prev; /* advance to next dentry */
goto more;
@@ -296,6 +296,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
err = __dcache_readdir(file, ctx, shared_gen);
if (err != -EAGAIN)
return err;
+ frag = fpos_frag(ctx->pos);
+ off = fpos_off(ctx->pos);
} else {
spin_unlock(&ci->i_ceph_lock);
}
@@ -446,7 +448,6 @@ more:
if (atomic_read(&ci->i_release_count) == fi->dir_release_count) {
dout(" marking %p complete\n", inode);
__ceph_dir_set_complete(ci, fi->dir_release_count);
- ci->i_max_offset = ctx->pos;
}
spin_unlock(&ci->i_ceph_lock);
@@ -935,14 +936,16 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry,
* to do it here.
*/
- /* d_move screws up d_subdirs order */
- ceph_dir_clear_complete(new_dir);
-
d_move(old_dentry, new_dentry);
/* ensure target dentry is invalidated, despite
rehashing bug in vfs_rename_dir */
ceph_invalidate_dentry_lease(new_dentry);
+
+ /* d_move screws up sibling dentries' offsets */
+ ceph_dir_clear_complete(old_dir);
+ ceph_dir_clear_complete(new_dir);
+
}
ceph_mdsc_put_request(req);
return err;
OpenPOWER on IntegriCloud