orangefs: Cache getattr results.
authorMartin Brandenburg <martin@omnibond.com>
Thu, 9 Jun 2016 20:32:38 +0000 (16:32 -0400)
committerMartin Brandenburg <martin@omnibond.com>
Tue, 2 Aug 2016 19:38:45 +0000 (15:38 -0400)
The userspace component attempts to do this, but this will prevent
us from even needing to go into userspace to satisfy certain getattr
requests.

Signed-off-by: Martin Brandenburg <martin@omnibond.com>
fs/orangefs/inode.c
fs/orangefs/namei.c
fs/orangefs/orangefs-kernel.h
fs/orangefs/orangefs-utils.c
fs/orangefs/protocol.h

index 2e63e6d0a68e514c423d85a5ea27c09f3062f55d..28a0557a69be8bc82795c2136d122f4da77ab2dc 100644 (file)
@@ -262,7 +262,7 @@ int orangefs_getattr(struct vfsmount *mnt,
                     "orangefs_getattr: called on %s\n",
                     dentry->d_name.name);
 
-       ret = orangefs_inode_getattr(inode, 0, 1);
+       ret = orangefs_inode_getattr(inode, 0, 0);
        if (ret == 0) {
                generic_fillattr(inode, kstat);
 
@@ -384,7 +384,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref
        if (!inode || !(inode->i_state & I_NEW))
                return inode;
 
-       error = orangefs_inode_getattr(inode, 1, 0);
+       error = orangefs_inode_getattr(inode, 1, 1);
        if (error) {
                iget_failed(inode);
                return ERR_PTR(error);
@@ -429,7 +429,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir,
        orangefs_set_inode(inode, ref);
        inode->i_ino = hash;    /* needed for stat etc */
 
-       error = orangefs_inode_getattr(inode, 1, 0);
+       error = orangefs_inode_getattr(inode, 1, 1);
        if (error)
                goto out_iput;
 
index b37f80bf0bec375948d437daac3a39ef1e93c83d..dde6c36f5a69073b09b27c442e543e3878bcc4b3 100644 (file)
@@ -73,6 +73,7 @@ static int orangefs_create(struct inode *dir,
        d_instantiate(dentry, inode);
        unlock_new_inode(inode);
        dentry->d_time = jiffies + HZ;
+       ORANGEFS_I(inode)->getattr_time = 0;
 
        gossip_debug(GOSSIP_NAME_DEBUG,
                     "%s: dentry instantiated for %s\n",
@@ -192,6 +193,8 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
                goto out;
        }
 
+       ORANGEFS_I(inode)->getattr_time = 0;
+
        gossip_debug(GOSSIP_NAME_DEBUG,
                     "%s:%s:%d "
                     "Found good inode [%lu] with count [%d]\n",
@@ -320,6 +323,7 @@ static int orangefs_symlink(struct inode *dir,
        d_instantiate(dentry, inode);
        unlock_new_inode(inode);
        dentry->d_time = jiffies + HZ;
+       ORANGEFS_I(inode)->getattr_time = 0;
 
        gossip_debug(GOSSIP_NAME_DEBUG,
                     "Inode (Symlink) %pU -> %s\n",
@@ -383,6 +387,7 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        d_instantiate(dentry, inode);
        unlock_new_inode(inode);
        dentry->d_time = jiffies + HZ;
+       ORANGEFS_I(inode)->getattr_time = 0;
 
        gossip_debug(GOSSIP_NAME_DEBUG,
                     "Inode (Directory) %pU -> %s\n",
@@ -413,6 +418,8 @@ static int orangefs_rename(struct inode *old_dir,
                     "orangefs_rename: called (%pd2 => %pd2) ct=%d\n",
                     old_dentry, new_dentry, d_count(new_dentry));
 
+       ORANGEFS_I(new_dentry->d_parent->d_inode)->getattr_time = 0;
+
        new_op = op_alloc(ORANGEFS_VFS_OP_RENAME);
        if (!new_op)
                return -EINVAL;
index 4b6e132d5a0f59de3556ab207aeab24f70b55d71..9338fe64820d29f10f5eb793954e9cf3b4823952 100644 (file)
@@ -246,6 +246,8 @@ struct orangefs_inode_s {
         * with this object
         */
        unsigned long pinode_flags;
+
+       unsigned long getattr_time;
 };
 
 #define P_ATIME_FLAG 0
@@ -527,7 +529,7 @@ int orangefs_inode_setxattr(struct inode *inode,
                         size_t size,
                         int flags);
 
-int orangefs_inode_getattr(struct inode *inode, int new, int size);
+int orangefs_inode_getattr(struct inode *inode, int new, int bypass);
 
 int orangefs_inode_check_changed(struct inode *inode);
 
index c5fbc62357c6e2dc37d4cebf05289715def98b98..69b4d8af8d81841b7cc54dcdf265b32477b3e10c 100644 (file)
@@ -251,7 +251,7 @@ static int orangefs_inode_is_stale(struct inode *inode, int new,
        return 0;
 }
 
-int orangefs_inode_getattr(struct inode *inode, int new, int size)
+int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
 {
        struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
        struct orangefs_kernel_op_s *new_op;
@@ -261,12 +261,16 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
        gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
            get_khandle_from_ino(inode));
 
+       if (!new && !bypass) {
+               if (orangefs_inode->getattr_time > jiffies)
+                       return 0;
+       }
+
        new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
        if (!new_op)
                return -ENOMEM;
        new_op->upcall.req.getattr.refn = orangefs_inode->refn;
-       new_op->upcall.req.getattr.mask = size ?
-           ORANGEFS_ATTR_SYS_ALL_NOHINT : ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE;
+       new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
 
        ret = service_operation(new_op, __func__,
            get_interruptible_flag(inode));
@@ -287,20 +291,18 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
        case S_IFREG:
                inode->i_flags = orangefs_inode_flags(&new_op->
                    downcall.resp.getattr.attributes);
-               if (size) {
-                       inode_size = (loff_t)new_op->
-                           downcall.resp.getattr.attributes.size;
-                       rounded_up_size =
-                           (inode_size + (4096 - (inode_size % 4096)));
-                       inode->i_size = inode_size;
-                       orangefs_inode->blksize =
-                           new_op->downcall.resp.getattr.attributes.blksize;
-                       spin_lock(&inode->i_lock);
-                       inode->i_bytes = inode_size;
-                       inode->i_blocks =
-                           (unsigned long)(rounded_up_size / 512);
-                       spin_unlock(&inode->i_lock);
-               }
+               inode_size = (loff_t)new_op->
+                   downcall.resp.getattr.attributes.size;
+               rounded_up_size =
+                   (inode_size + (4096 - (inode_size % 4096)));
+               inode->i_size = inode_size;
+               orangefs_inode->blksize =
+                   new_op->downcall.resp.getattr.attributes.blksize;
+               spin_lock(&inode->i_lock);
+               inode->i_bytes = inode_size;
+               inode->i_blocks =
+                   (unsigned long)(rounded_up_size / 512);
+               spin_unlock(&inode->i_lock);
                break;
        case S_IFDIR:
                inode->i_size = PAGE_SIZE;
@@ -345,6 +347,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
        inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
            orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
 
+       orangefs_inode->getattr_time = jiffies + HZ;
        ret = 0;
 out:
        op_release(new_op);
@@ -418,6 +421,7 @@ int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
                ClearMtimeFlag(orangefs_inode);
                ClearCtimeFlag(orangefs_inode);
                ClearModeFlag(orangefs_inode);
+               orangefs_inode->getattr_time = 0;
        }
 
        return ret;
index 1efc6f8a5224cb0cd1ebb84b793cb68042e70442..3d7418c728f57b744286e910934cb5248a53a952 100644 (file)
@@ -207,14 +207,6 @@ typedef __s64 ORANGEFS_offset;
         ORANGEFS_ATTR_SYS_DIRENT_COUNT         |       \
         ORANGEFS_ATTR_SYS_BLKSIZE)
 
-#define ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE            \
-       (ORANGEFS_ATTR_SYS_COMMON_ALL           |       \
-        ORANGEFS_ATTR_SYS_LNK_TARGET           |       \
-        ORANGEFS_ATTR_SYS_DFILE_COUNT          |       \
-        ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT  |       \
-        ORANGEFS_ATTR_SYS_DIRENT_COUNT         |       \
-        ORANGEFS_ATTR_SYS_BLKSIZE)
-
 #define ORANGEFS_XATTR_REPLACE 0x2
 #define ORANGEFS_XATTR_CREATE  0x1
 #define ORANGEFS_MAX_SERVER_ADDR_LEN 256