diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:55 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:28 -0500 |
commit | fb045adb99d9b7c562dc7fef834857f78249daa1 (patch) | |
tree | 1fd6a4024fffeec568abe100d730589bfdb81c38 /fs/namei.c | |
parent | 5f57cbcc02cf18f6b22ef4066bb10afeb8f930ff (diff) |
fs: dcache reduce branches in lookup path
Reduce some branches and memory accesses in dcache lookup by adding dentry
flags to indicate common d_ops are set, rather than having to check them.
This saves a pointer memory access (dentry->d_op) in common path lookup
situations, and saves another pointer load and branch in cases where we
have d_op but not the particular operation.
Patched with:
git grep -E '[.>]([[:space:]])*d_op([[:space:]])*=' | xargs sed -e 's/\([^\t ]*\)->d_op = \(.*\);/d_set_d_op(\1, \2);/' -e 's/\([^\t ]*\)\.d_op = \(.*\);/d_set_d_op(\&\1, \2);/' -i
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/namei.c b/fs/namei.c index c731b50a6184..90bd2873e117 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -587,6 +587,17 @@ do_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
587 | return dentry; | 587 | return dentry; |
588 | } | 588 | } |
589 | 589 | ||
590 | static inline int need_reval_dot(struct dentry *dentry) | ||
591 | { | ||
592 | if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE))) | ||
593 | return 0; | ||
594 | |||
595 | if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))) | ||
596 | return 0; | ||
597 | |||
598 | return 1; | ||
599 | } | ||
600 | |||
590 | /* | 601 | /* |
591 | * force_reval_path - force revalidation of a dentry | 602 | * force_reval_path - force revalidation of a dentry |
592 | * | 603 | * |
@@ -610,10 +621,9 @@ force_reval_path(struct path *path, struct nameidata *nd) | |||
610 | 621 | ||
611 | /* | 622 | /* |
612 | * only check on filesystems where it's possible for the dentry to | 623 | * only check on filesystems where it's possible for the dentry to |
613 | * become stale. It's assumed that if this flag is set then the | 624 | * become stale. |
614 | * d_revalidate op will also be defined. | ||
615 | */ | 625 | */ |
616 | if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) | 626 | if (!need_reval_dot(dentry)) |
617 | return 0; | 627 | return 0; |
618 | 628 | ||
619 | status = dentry->d_op->d_revalidate(dentry, nd); | 629 | status = dentry->d_op->d_revalidate(dentry, nd); |
@@ -1003,7 +1013,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1003 | * See if the low-level filesystem might want | 1013 | * See if the low-level filesystem might want |
1004 | * to use its own hash.. | 1014 | * to use its own hash.. |
1005 | */ | 1015 | */ |
1006 | if (parent->d_op && parent->d_op->d_hash) { | 1016 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { |
1007 | int err = parent->d_op->d_hash(parent, nd->inode, name); | 1017 | int err = parent->d_op->d_hash(parent, nd->inode, name); |
1008 | if (err < 0) | 1018 | if (err < 0) |
1009 | return err; | 1019 | return err; |
@@ -1029,7 +1039,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1029 | return -ECHILD; | 1039 | return -ECHILD; |
1030 | 1040 | ||
1031 | nd->seq = seq; | 1041 | nd->seq = seq; |
1032 | if (dentry->d_op && dentry->d_op->d_revalidate) { | 1042 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) { |
1033 | /* We commonly drop rcu-walk here */ | 1043 | /* We commonly drop rcu-walk here */ |
1034 | if (nameidata_dentry_drop_rcu(nd, dentry)) | 1044 | if (nameidata_dentry_drop_rcu(nd, dentry)) |
1035 | return -ECHILD; | 1045 | return -ECHILD; |
@@ -1043,7 +1053,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
1043 | if (!dentry) | 1053 | if (!dentry) |
1044 | goto need_lookup; | 1054 | goto need_lookup; |
1045 | found: | 1055 | found: |
1046 | if (dentry->d_op && dentry->d_op->d_revalidate) | 1056 | if (dentry->d_flags & DCACHE_OP_REVALIDATE) |
1047 | goto need_revalidate; | 1057 | goto need_revalidate; |
1048 | done: | 1058 | done: |
1049 | path->mnt = mnt; | 1059 | path->mnt = mnt; |
@@ -1281,8 +1291,7 @@ return_reval: | |||
1281 | * We bypassed the ordinary revalidation routines. | 1291 | * We bypassed the ordinary revalidation routines. |
1282 | * We may need to check the cached dentry for staleness. | 1292 | * We may need to check the cached dentry for staleness. |
1283 | */ | 1293 | */ |
1284 | if (nd->path.dentry && nd->path.dentry->d_sb && | 1294 | if (need_reval_dot(nd->path.dentry)) { |
1285 | (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { | ||
1286 | if (nameidata_drop_rcu_maybe(nd)) | 1295 | if (nameidata_drop_rcu_maybe(nd)) |
1287 | return -ECHILD; | 1296 | return -ECHILD; |
1288 | err = -ESTALE; | 1297 | err = -ESTALE; |
@@ -1602,7 +1611,7 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1602 | * See if the low-level filesystem might want | 1611 | * See if the low-level filesystem might want |
1603 | * to use its own hash.. | 1612 | * to use its own hash.. |
1604 | */ | 1613 | */ |
1605 | if (base->d_op && base->d_op->d_hash) { | 1614 | if (base->d_flags & DCACHE_OP_HASH) { |
1606 | err = base->d_op->d_hash(base, inode, name); | 1615 | err = base->d_op->d_hash(base, inode, name); |
1607 | dentry = ERR_PTR(err); | 1616 | dentry = ERR_PTR(err); |
1608 | if (err < 0) | 1617 | if (err < 0) |
@@ -1616,7 +1625,7 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1616 | */ | 1625 | */ |
1617 | dentry = d_lookup(base, name); | 1626 | dentry = d_lookup(base, name); |
1618 | 1627 | ||
1619 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | 1628 | if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE)) |
1620 | dentry = do_revalidate(dentry, nd); | 1629 | dentry = do_revalidate(dentry, nd); |
1621 | 1630 | ||
1622 | if (!dentry) | 1631 | if (!dentry) |
@@ -2070,7 +2079,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2070 | follow_dotdot(nd); | 2079 | follow_dotdot(nd); |
2071 | dir = nd->path.dentry; | 2080 | dir = nd->path.dentry; |
2072 | case LAST_DOT: | 2081 | case LAST_DOT: |
2073 | if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) { | 2082 | if (need_reval_dot(dir)) { |
2074 | if (!dir->d_op->d_revalidate(dir, nd)) { | 2083 | if (!dir->d_op->d_revalidate(dir, nd)) { |
2075 | error = -ESTALE; | 2084 | error = -ESTALE; |
2076 | goto exit; | 2085 | goto exit; |