Re: [PATCH v2 2/4] ceph: consider inode's last read/write when calculating wanted caps

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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);





[Index of Archives]     [CEPH Users]     [Ceph Large]     [Ceph Dev]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux