On 2/21/20 10:35 PM, Jeff Layton wrote:
On Fri, 2020-02-21 at 09:27 -0500, Jeff Layton wrote:
On Fri, 2020-02-21 at 21:16 +0800, Yan, Zheng wrote:
Add i_last_rd and i_last_wr to ceph_inode_info. These two fields are
used to track inode's last read/write, they are updated when getting
caps for read/write.
If there is no read/write on an inode for 'caps_wanted_delay_max'
seconds, __ceph_caps_file_wanted() does not request caps for read/write
even there are open files.
Signed-off-by: "Yan, Zheng" <zyan@xxxxxxxxxx>
---
fs/ceph/caps.c | 152 ++++++++++++++++++++++++-----------
fs/ceph/file.c | 21 ++---
fs/ceph/inode.c | 10 ++-
fs/ceph/ioctl.c | 2 +
fs/ceph/super.h | 13 ++-
include/linux/ceph/ceph_fs.h | 1 +
6 files changed, 139 insertions(+), 60 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 293920d013ff..2a9df235286d 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -971,18 +971,49 @@ int __ceph_caps_used(struct ceph_inode_info *ci)
return used;
}
+#define FMODE_WAIT_BIAS 1000
+
/*
* wanted, by virtue of open file modes
*/
int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
{
- int i, bits = 0;
- for (i = 0; i < CEPH_FILE_MODE_BITS; i++) {
- if (ci->i_nr_by_mode[i])
- bits |= 1 << i;
+ struct ceph_mount_options *opt =
+ ceph_inode_to_client(&ci->vfs_inode)->mount_options;
+ unsigned long used_cutoff =
+ round_jiffies(jiffies - opt->caps_wanted_delay_max * HZ);
+ unsigned long idle_cutoff =
+ round_jiffies(jiffies - opt->caps_wanted_delay_min * HZ);
+ int bits = 0;
+
+ if (ci->i_nr_by_mode[0] > 0)
+ bits |= CEPH_FILE_MODE_PIN;
+
+ if (ci->i_nr_by_mode[1] > 0) {
+ if (ci->i_nr_by_mode[1] >= FMODE_WAIT_BIAS ||
+ time_after(ci->i_last_rd, used_cutoff))
+ bits |= CEPH_FILE_MODE_RD;
+ } else if (time_after(ci->i_last_rd, idle_cutoff)) {
+ bits |= CEPH_FILE_MODE_RD;
+ }
+
+ if (ci->i_nr_by_mode[2] > 0) {
+ if (ci->i_nr_by_mode[2] >= FMODE_WAIT_BIAS ||
+ time_after(ci->i_last_wr, used_cutoff))
+ bits |= CEPH_FILE_MODE_WR;
+ } else if (time_after(ci->i_last_wr, idle_cutoff)) {
+ bits |= CEPH_FILE_MODE_WR;
}
+
+ /* check lazyio only when read/write is wanted */
+ if ((bits & CEPH_FILE_MODE_RDWR) && ci->i_nr_by_mode[3] > 0)
LAZY is 4. Shouldn't this be?
if ((bits & CEPH_FILE_MODE_RDWR) && ci->i_nr_by_mode[CEPH_FILE_MODE_LAZY] > 0)
Nope, that value was right, but I think we should phrase this in terms
of symbolic constants. Maybe we can squash this patch into your series?
-----------------------8<-----------------------
[PATCH] SQUASH: use symbolic constants in __ceph_caps_file_wanted()
Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
---
fs/ceph/caps.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index ad365cf870f6..1b450f2195fe 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -971,19 +971,19 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
round_jiffies(jiffies - opt->caps_wanted_delay_min * HZ);
int bits = 0;
- if (ci->i_nr_by_mode[0] > 0)
+ if (ci->i_nr_by_mode[CEPH_FILE_MODE_PIN] > 0)
bits |= CEPH_FILE_MODE_PIN;
- if (ci->i_nr_by_mode[1] > 0) {
- if (ci->i_nr_by_mode[1] >= FMODE_WAIT_BIAS ||
+ if (ci->i_nr_by_mode[CEPH_FILE_MODE_RD] > 0) {
+ if (ci->i_nr_by_mode[CEPH_FILE_MODE_RD] >= FMODE_WAIT_BIAS ||
time_after(ci->i_last_rd, used_cutoff))
bits |= CEPH_FILE_MODE_RD;
} else if (time_after(ci->i_last_rd, idle_cutoff)) {
bits |= CEPH_FILE_MODE_RD;
}
- if (ci->i_nr_by_mode[2] > 0) {
- if (ci->i_nr_by_mode[2] >= FMODE_WAIT_BIAS ||
+ if (ci->i_nr_by_mode[CEPH_FILE_MODE_WR] > 0) {
+ if (ci->i_nr_by_mode[CEPH_FILE_MODE_WR] >= FMODE_WAIT_BIAS ||
time_after(ci->i_last_wr, used_cutoff))
bits |= CEPH_FILE_MODE_WR;
} else if (time_after(ci->i_last_wr, idle_cutoff)) {
@@ -991,12 +991,13 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
}
/* check lazyio only when read/write is wanted */
- if ((bits & CEPH_FILE_MODE_RDWR) && ci->i_nr_by_mode[3] > 0)
+ if ((bits & CEPH_FILE_MODE_RDWR) &&
+ ci->i_nr_by_mode[ffs(CEPH_FILE_MODE_LAZY)] > 0)
bits |= CEPH_FILE_MODE_LAZY;
if (bits == 0)
return 0;
- if (bits == 1 && !S_ISDIR(ci->vfs_inode.i_mode))
+ if (bits == (1 << CEPH_FILE_MODE_PIN) && !S_ISDIR(ci->vfs_inode.i_mode))
return 0;
return ceph_caps_for_mode(bits >> 1);
how about something like below. when compile with -O2, gcc optimize out
ffs() functions.
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 2a9df235286d..e1d38ef9478b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -985,33 +985,38 @@ int __ceph_caps_file_wanted(struct ceph_inode_info
*ci)
unsigned long idle_cutoff =
round_jiffies(jiffies - opt->caps_wanted_delay_min * HZ);
int bits = 0;
+ const int PIN_SHIFT = ffs(CEPH_FILE_MODE_PIN);
+ const int RD_SHIFT = ffs(CEPH_FILE_MODE_RD);
+ const int WR_SHIFT= ffs(CEPH_FILE_MODE_WR);
+ const int LAZY_SHIFT = ffs(CEPH_FILE_MODE_LAZY);
- if (ci->i_nr_by_mode[0] > 0)
- bits |= CEPH_FILE_MODE_PIN;
+ if (ci->i_nr_by_mode[PIN_SHIFT] > 0)
+ bits |= 1 << PIN_SHIFT;
- if (ci->i_nr_by_mode[1] > 0) {
- if (ci->i_nr_by_mode[1] >= FMODE_WAIT_BIAS ||
+ if (ci->i_nr_by_mode[RD_SHIFT] > 0) {
+ if (ci->i_nr_by_mode[RD_SHIFT] >= FMODE_WAIT_BIAS ||
time_after(ci->i_last_rd, used_cutoff))
- bits |= CEPH_FILE_MODE_RD;
+ bits |= 1 << RD_SHIFT;
} else if (time_after(ci->i_last_rd, idle_cutoff)) {
- bits |= CEPH_FILE_MODE_RD;
+ bits |= 1 << RD_SHIFT;
}
- if (ci->i_nr_by_mode[2] > 0) {
- if (ci->i_nr_by_mode[2] >= FMODE_WAIT_BIAS ||
+ if (ci->i_nr_by_mode[WR_SHIFT] > 0) {
+ if (ci->i_nr_by_mode[WR_SHIFT] >= FMODE_WAIT_BIAS ||
time_after(ci->i_last_wr, used_cutoff))
- bits |= CEPH_FILE_MODE_WR;
+ bits |= 1 << WR_SHIFT;
} else if (time_after(ci->i_last_wr, idle_cutoff)) {
- bits |= CEPH_FILE_MODE_WR;
+ bits |= 1 << WR_SHIFT;
}
/* check lazyio only when read/write is wanted */
- if ((bits & CEPH_FILE_MODE_RDWR) && ci->i_nr_by_mode[3] > 0)
- bits |= CEPH_FILE_MODE_LAZY;
+ if ((bits & (CEPH_FILE_MODE_RDWR << 1)) &&
+ ci->i_nr_by_mode[LAZY_SHIFT] > 0)
+ bits |= 1 << LAZY_SHIFT;
if (bits == 0)
return 0;
- if (bits == 1 && !S_ISDIR(ci->vfs_inode.i_mode))
+ if (bits == (1 << PIN_SHIFT) && !S_ISDIR(ci->vfs_inode.i_mode))
return 0;
return ceph_caps_for_mode(bits >> 1);