orangefs: Cache getattr results.

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>
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
index c5fbc62..69b4d8a 100644
--- a/fs/orangefs/orangefs-utils.c
+++ b/fs/orangefs/orangefs-utils.c
@@ -251,7 +251,7 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 		ClearMtimeFlag(orangefs_inode);
 		ClearCtimeFlag(orangefs_inode);
 		ClearModeFlag(orangefs_inode);
+		orangefs_inode->getattr_time = 0;
 	}
 
 	return ret;