diff options
author | Martin Brandenburg <martin@omnibond.com> | 2016-06-09 16:32:38 -0400 |
---|---|---|
committer | Martin Brandenburg <martin@omnibond.com> | 2016-08-02 15:38:45 -0400 |
commit | 71680c18c8f22deafbaaf76d1c2d0eed2899a3d2 (patch) | |
tree | 19a4fae045bbbb083983bfdc0c76ad417db744df | |
parent | 31b7c1ab4ed14d3aeb658e11a114860a64290fea (diff) |
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>
-rw-r--r-- | fs/orangefs/inode.c | 6 | ||||
-rw-r--r-- | fs/orangefs/namei.c | 7 | ||||
-rw-r--r-- | fs/orangefs/orangefs-kernel.h | 4 | ||||
-rw-r--r-- | fs/orangefs/orangefs-utils.c | 38 | ||||
-rw-r--r-- | fs/orangefs/protocol.h | 8 |
5 files changed, 34 insertions, 29 deletions
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 2e63e6d0a68e..28a0557a69be 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c | |||
@@ -262,7 +262,7 @@ int orangefs_getattr(struct vfsmount *mnt, | |||
262 | "orangefs_getattr: called on %s\n", | 262 | "orangefs_getattr: called on %s\n", |
263 | dentry->d_name.name); | 263 | dentry->d_name.name); |
264 | 264 | ||
265 | ret = orangefs_inode_getattr(inode, 0, 1); | 265 | ret = orangefs_inode_getattr(inode, 0, 0); |
266 | if (ret == 0) { | 266 | if (ret == 0) { |
267 | generic_fillattr(inode, kstat); | 267 | generic_fillattr(inode, kstat); |
268 | 268 | ||
@@ -384,7 +384,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref | |||
384 | if (!inode || !(inode->i_state & I_NEW)) | 384 | if (!inode || !(inode->i_state & I_NEW)) |
385 | return inode; | 385 | return inode; |
386 | 386 | ||
387 | error = orangefs_inode_getattr(inode, 1, 0); | 387 | error = orangefs_inode_getattr(inode, 1, 1); |
388 | if (error) { | 388 | if (error) { |
389 | iget_failed(inode); | 389 | iget_failed(inode); |
390 | return ERR_PTR(error); | 390 | return ERR_PTR(error); |
@@ -429,7 +429,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, | |||
429 | orangefs_set_inode(inode, ref); | 429 | orangefs_set_inode(inode, ref); |
430 | inode->i_ino = hash; /* needed for stat etc */ | 430 | inode->i_ino = hash; /* needed for stat etc */ |
431 | 431 | ||
432 | error = orangefs_inode_getattr(inode, 1, 0); | 432 | error = orangefs_inode_getattr(inode, 1, 1); |
433 | if (error) | 433 | if (error) |
434 | goto out_iput; | 434 | goto out_iput; |
435 | 435 | ||
diff --git a/fs/orangefs/namei.c b/fs/orangefs/namei.c index b37f80bf0bec..dde6c36f5a69 100644 --- a/fs/orangefs/namei.c +++ b/fs/orangefs/namei.c | |||
@@ -73,6 +73,7 @@ static int orangefs_create(struct inode *dir, | |||
73 | d_instantiate(dentry, inode); | 73 | d_instantiate(dentry, inode); |
74 | unlock_new_inode(inode); | 74 | unlock_new_inode(inode); |
75 | dentry->d_time = jiffies + HZ; | 75 | dentry->d_time = jiffies + HZ; |
76 | ORANGEFS_I(inode)->getattr_time = 0; | ||
76 | 77 | ||
77 | gossip_debug(GOSSIP_NAME_DEBUG, | 78 | gossip_debug(GOSSIP_NAME_DEBUG, |
78 | "%s: dentry instantiated for %s\n", | 79 | "%s: dentry instantiated for %s\n", |
@@ -192,6 +193,8 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry, | |||
192 | goto out; | 193 | goto out; |
193 | } | 194 | } |
194 | 195 | ||
196 | ORANGEFS_I(inode)->getattr_time = 0; | ||
197 | |||
195 | gossip_debug(GOSSIP_NAME_DEBUG, | 198 | gossip_debug(GOSSIP_NAME_DEBUG, |
196 | "%s:%s:%d " | 199 | "%s:%s:%d " |
197 | "Found good inode [%lu] with count [%d]\n", | 200 | "Found good inode [%lu] with count [%d]\n", |
@@ -320,6 +323,7 @@ static int orangefs_symlink(struct inode *dir, | |||
320 | d_instantiate(dentry, inode); | 323 | d_instantiate(dentry, inode); |
321 | unlock_new_inode(inode); | 324 | unlock_new_inode(inode); |
322 | dentry->d_time = jiffies + HZ; | 325 | dentry->d_time = jiffies + HZ; |
326 | ORANGEFS_I(inode)->getattr_time = 0; | ||
323 | 327 | ||
324 | gossip_debug(GOSSIP_NAME_DEBUG, | 328 | gossip_debug(GOSSIP_NAME_DEBUG, |
325 | "Inode (Symlink) %pU -> %s\n", | 329 | "Inode (Symlink) %pU -> %s\n", |
@@ -383,6 +387,7 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode | |||
383 | d_instantiate(dentry, inode); | 387 | d_instantiate(dentry, inode); |
384 | unlock_new_inode(inode); | 388 | unlock_new_inode(inode); |
385 | dentry->d_time = jiffies + HZ; | 389 | dentry->d_time = jiffies + HZ; |
390 | ORANGEFS_I(inode)->getattr_time = 0; | ||
386 | 391 | ||
387 | gossip_debug(GOSSIP_NAME_DEBUG, | 392 | gossip_debug(GOSSIP_NAME_DEBUG, |
388 | "Inode (Directory) %pU -> %s\n", | 393 | "Inode (Directory) %pU -> %s\n", |
@@ -413,6 +418,8 @@ static int orangefs_rename(struct inode *old_dir, | |||
413 | "orangefs_rename: called (%pd2 => %pd2) ct=%d\n", | 418 | "orangefs_rename: called (%pd2 => %pd2) ct=%d\n", |
414 | old_dentry, new_dentry, d_count(new_dentry)); | 419 | old_dentry, new_dentry, d_count(new_dentry)); |
415 | 420 | ||
421 | ORANGEFS_I(new_dentry->d_parent->d_inode)->getattr_time = 0; | ||
422 | |||
416 | new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); | 423 | new_op = op_alloc(ORANGEFS_VFS_OP_RENAME); |
417 | if (!new_op) | 424 | if (!new_op) |
418 | return -EINVAL; | 425 | return -EINVAL; |
diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 4b6e132d5a0f..9338fe64820d 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h | |||
@@ -246,6 +246,8 @@ struct orangefs_inode_s { | |||
246 | * with this object | 246 | * with this object |
247 | */ | 247 | */ |
248 | unsigned long pinode_flags; | 248 | unsigned long pinode_flags; |
249 | |||
250 | unsigned long getattr_time; | ||
249 | }; | 251 | }; |
250 | 252 | ||
251 | #define P_ATIME_FLAG 0 | 253 | #define P_ATIME_FLAG 0 |
@@ -527,7 +529,7 @@ int orangefs_inode_setxattr(struct inode *inode, | |||
527 | size_t size, | 529 | size_t size, |
528 | int flags); | 530 | int flags); |
529 | 531 | ||
530 | int orangefs_inode_getattr(struct inode *inode, int new, int size); | 532 | int orangefs_inode_getattr(struct inode *inode, int new, int bypass); |
531 | 533 | ||
532 | int orangefs_inode_check_changed(struct inode *inode); | 534 | int orangefs_inode_check_changed(struct inode *inode); |
533 | 535 | ||
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index c5fbc62357c6..69b4d8af8d81 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c | |||
@@ -251,7 +251,7 @@ static int orangefs_inode_is_stale(struct inode *inode, int new, | |||
251 | return 0; | 251 | return 0; |
252 | } | 252 | } |
253 | 253 | ||
254 | int orangefs_inode_getattr(struct inode *inode, int new, int size) | 254 | int orangefs_inode_getattr(struct inode *inode, int new, int bypass) |
255 | { | 255 | { |
256 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); | 256 | struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); |
257 | struct orangefs_kernel_op_s *new_op; | 257 | struct orangefs_kernel_op_s *new_op; |
@@ -261,12 +261,16 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size) | |||
261 | gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, | 261 | gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, |
262 | get_khandle_from_ino(inode)); | 262 | get_khandle_from_ino(inode)); |
263 | 263 | ||
264 | if (!new && !bypass) { | ||
265 | if (orangefs_inode->getattr_time > jiffies) | ||
266 | return 0; | ||
267 | } | ||
268 | |||
264 | new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); | 269 | new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); |
265 | if (!new_op) | 270 | if (!new_op) |
266 | return -ENOMEM; | 271 | return -ENOMEM; |
267 | new_op->upcall.req.getattr.refn = orangefs_inode->refn; | 272 | new_op->upcall.req.getattr.refn = orangefs_inode->refn; |
268 | new_op->upcall.req.getattr.mask = size ? | 273 | new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT; |
269 | ORANGEFS_ATTR_SYS_ALL_NOHINT : ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE; | ||
270 | 274 | ||
271 | ret = service_operation(new_op, __func__, | 275 | ret = service_operation(new_op, __func__, |
272 | get_interruptible_flag(inode)); | 276 | get_interruptible_flag(inode)); |
@@ -287,20 +291,18 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size) | |||
287 | case S_IFREG: | 291 | case S_IFREG: |
288 | inode->i_flags = orangefs_inode_flags(&new_op-> | 292 | inode->i_flags = orangefs_inode_flags(&new_op-> |
289 | downcall.resp.getattr.attributes); | 293 | downcall.resp.getattr.attributes); |
290 | if (size) { | 294 | inode_size = (loff_t)new_op-> |
291 | inode_size = (loff_t)new_op-> | 295 | downcall.resp.getattr.attributes.size; |
292 | downcall.resp.getattr.attributes.size; | 296 | rounded_up_size = |
293 | rounded_up_size = | 297 | (inode_size + (4096 - (inode_size % 4096))); |
294 | (inode_size + (4096 - (inode_size % 4096))); | 298 | inode->i_size = inode_size; |
295 | inode->i_size = inode_size; | 299 | orangefs_inode->blksize = |
296 | orangefs_inode->blksize = | 300 | new_op->downcall.resp.getattr.attributes.blksize; |
297 | new_op->downcall.resp.getattr.attributes.blksize; | 301 | spin_lock(&inode->i_lock); |
298 | spin_lock(&inode->i_lock); | 302 | inode->i_bytes = inode_size; |
299 | inode->i_bytes = inode_size; | 303 | inode->i_blocks = |
300 | inode->i_blocks = | 304 | (unsigned long)(rounded_up_size / 512); |
301 | (unsigned long)(rounded_up_size / 512); | 305 | spin_unlock(&inode->i_lock); |
302 | spin_unlock(&inode->i_lock); | ||
303 | } | ||
304 | break; | 306 | break; |
305 | case S_IFDIR: | 307 | case S_IFDIR: |
306 | inode->i_size = PAGE_SIZE; | 308 | inode->i_size = PAGE_SIZE; |
@@ -345,6 +347,7 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size) | |||
345 | inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) | | 347 | inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) | |
346 | orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes); | 348 | orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes); |
347 | 349 | ||
350 | orangefs_inode->getattr_time = jiffies + HZ; | ||
348 | ret = 0; | 351 | ret = 0; |
349 | out: | 352 | out: |
350 | op_release(new_op); | 353 | op_release(new_op); |
@@ -418,6 +421,7 @@ int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr) | |||
418 | ClearMtimeFlag(orangefs_inode); | 421 | ClearMtimeFlag(orangefs_inode); |
419 | ClearCtimeFlag(orangefs_inode); | 422 | ClearCtimeFlag(orangefs_inode); |
420 | ClearModeFlag(orangefs_inode); | 423 | ClearModeFlag(orangefs_inode); |
424 | orangefs_inode->getattr_time = 0; | ||
421 | } | 425 | } |
422 | 426 | ||
423 | return ret; | 427 | return ret; |
diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h index 1efc6f8a5224..3d7418c728f5 100644 --- a/fs/orangefs/protocol.h +++ b/fs/orangefs/protocol.h | |||
@@ -207,14 +207,6 @@ typedef __s64 ORANGEFS_offset; | |||
207 | ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ | 207 | ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ |
208 | ORANGEFS_ATTR_SYS_BLKSIZE) | 208 | ORANGEFS_ATTR_SYS_BLKSIZE) |
209 | 209 | ||
210 | #define ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE \ | ||
211 | (ORANGEFS_ATTR_SYS_COMMON_ALL | \ | ||
212 | ORANGEFS_ATTR_SYS_LNK_TARGET | \ | ||
213 | ORANGEFS_ATTR_SYS_DFILE_COUNT | \ | ||
214 | ORANGEFS_ATTR_SYS_MIRROR_COPIES_COUNT | \ | ||
215 | ORANGEFS_ATTR_SYS_DIRENT_COUNT | \ | ||
216 | ORANGEFS_ATTR_SYS_BLKSIZE) | ||
217 | |||
218 | #define ORANGEFS_XATTR_REPLACE 0x2 | 210 | #define ORANGEFS_XATTR_REPLACE 0x2 |
219 | #define ORANGEFS_XATTR_CREATE 0x1 | 211 | #define ORANGEFS_XATTR_CREATE 0x1 |
220 | #define ORANGEFS_MAX_SERVER_ADDR_LEN 256 | 212 | #define ORANGEFS_MAX_SERVER_ADDR_LEN 256 |