diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-03-13 07:44:32 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-02 00:17:07 -0400 |
commit | 2f276c511137d97e56b19e29865e1e6569315ccb (patch) | |
tree | f29a8088a6f312ec40f03b96d96b34e69154627a /fs/ceph/super.h | |
parent | 8a166d05369f6a0369bb194a795e6e3928ac6e34 (diff) |
ceph: use i_release_count to indicate dir's completeness
Current ceph code tracks directory's completeness in two places.
ceph_readdir() checks i_release_count to decide if it can set the
I_COMPLETE flag in i_ceph_flags. All other places check the I_COMPLETE
flag. This indirection introduces locking complexity.
This patch adds a new variable i_complete_count to ceph_inode_info.
Set i_release_count's value to it when marking a directory complete.
By comparing the two variables, we know if a directory is complete
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs/ceph/super.h')
-rw-r--r-- | fs/ceph/super.h | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index a04eda714df4..8696be2ff679 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -244,7 +244,8 @@ struct ceph_inode_info { | |||
244 | u32 i_time_warp_seq; | 244 | u32 i_time_warp_seq; |
245 | 245 | ||
246 | unsigned i_ceph_flags; | 246 | unsigned i_ceph_flags; |
247 | unsigned long i_release_count; | 247 | atomic_t i_release_count; |
248 | atomic_t i_complete_count; | ||
248 | 249 | ||
249 | struct ceph_dir_layout i_dir_layout; | 250 | struct ceph_dir_layout i_dir_layout; |
250 | struct ceph_file_layout i_layout; | 251 | struct ceph_file_layout i_layout; |
@@ -254,7 +255,7 @@ struct ceph_inode_info { | |||
254 | struct timespec i_rctime; | 255 | struct timespec i_rctime; |
255 | u64 i_rbytes, i_rfiles, i_rsubdirs; | 256 | u64 i_rbytes, i_rfiles, i_rsubdirs; |
256 | u64 i_files, i_subdirs; | 257 | u64 i_files, i_subdirs; |
257 | u64 i_max_offset; /* largest readdir offset, set with I_COMPLETE */ | 258 | u64 i_max_offset; /* largest readdir offset, set with complete dir */ |
258 | 259 | ||
259 | struct rb_root i_fragtree; | 260 | struct rb_root i_fragtree; |
260 | struct mutex i_fragtree_mutex; | 261 | struct mutex i_fragtree_mutex; |
@@ -419,38 +420,35 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, | |||
419 | /* | 420 | /* |
420 | * Ceph inode. | 421 | * Ceph inode. |
421 | */ | 422 | */ |
422 | #define CEPH_I_COMPLETE 1 /* we have complete directory cached */ | ||
423 | #define CEPH_I_NODELAY 4 /* do not delay cap release */ | 423 | #define CEPH_I_NODELAY 4 /* do not delay cap release */ |
424 | #define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */ | 424 | #define CEPH_I_FLUSH 8 /* do not delay flush of dirty metadata */ |
425 | #define CEPH_I_NOFLUSH 16 /* do not flush dirty caps */ | 425 | #define CEPH_I_NOFLUSH 16 /* do not flush dirty caps */ |
426 | 426 | ||
427 | static inline void ceph_i_clear(struct inode *inode, unsigned mask) | 427 | static inline void __ceph_dir_set_complete(struct ceph_inode_info *ci, |
428 | int release_count) | ||
428 | { | 429 | { |
429 | struct ceph_inode_info *ci = ceph_inode(inode); | 430 | atomic_set(&ci->i_complete_count, release_count); |
430 | |||
431 | spin_lock(&ci->i_ceph_lock); | ||
432 | ci->i_ceph_flags &= ~mask; | ||
433 | spin_unlock(&ci->i_ceph_lock); | ||
434 | } | 431 | } |
435 | 432 | ||
436 | static inline void ceph_i_set(struct inode *inode, unsigned mask) | 433 | static inline void __ceph_dir_clear_complete(struct ceph_inode_info *ci) |
437 | { | 434 | { |
438 | struct ceph_inode_info *ci = ceph_inode(inode); | 435 | atomic_inc(&ci->i_release_count); |
436 | } | ||
439 | 437 | ||
440 | spin_lock(&ci->i_ceph_lock); | 438 | static inline bool __ceph_dir_is_complete(struct ceph_inode_info *ci) |
441 | ci->i_ceph_flags |= mask; | 439 | { |
442 | spin_unlock(&ci->i_ceph_lock); | 440 | return atomic_read(&ci->i_complete_count) == |
441 | atomic_read(&ci->i_release_count); | ||
443 | } | 442 | } |
444 | 443 | ||
445 | static inline bool ceph_i_test(struct inode *inode, unsigned mask) | 444 | static inline void ceph_dir_clear_complete(struct inode *inode) |
446 | { | 445 | { |
447 | struct ceph_inode_info *ci = ceph_inode(inode); | 446 | __ceph_dir_clear_complete(ceph_inode(inode)); |
448 | bool r; | 447 | } |
449 | 448 | ||
450 | spin_lock(&ci->i_ceph_lock); | 449 | static inline bool ceph_dir_is_complete(struct inode *inode) |
451 | r = (ci->i_ceph_flags & mask) == mask; | 450 | { |
452 | spin_unlock(&ci->i_ceph_lock); | 451 | return __ceph_dir_is_complete(ceph_inode(inode)); |
453 | return r; | ||
454 | } | 452 | } |
455 | 453 | ||
456 | 454 | ||
@@ -565,7 +563,7 @@ struct ceph_file_info { | |||
565 | u64 next_offset; /* offset of next chunk (last_name's + 1) */ | 563 | u64 next_offset; /* offset of next chunk (last_name's + 1) */ |
566 | char *last_name; /* last entry in previous chunk */ | 564 | char *last_name; /* last entry in previous chunk */ |
567 | struct dentry *dentry; /* next dentry (for dcache readdir) */ | 565 | struct dentry *dentry; /* next dentry (for dcache readdir) */ |
568 | unsigned long dir_release_count; | 566 | int dir_release_count; |
569 | 567 | ||
570 | /* used for -o dirstat read() on directory thing */ | 568 | /* used for -o dirstat read() on directory thing */ |
571 | char *dir_info; | 569 | char *dir_info; |