diff options
author | Nick Piggin <npiggin@kernel.dk> | 2010-08-17 14:37:31 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-08-18 08:35:45 -0400 |
commit | baa0389073eb7beb9d36f6d13df97e16c1bfa626 (patch) | |
tree | 38567c4e315f74fe086e4f7459df2a1cadd9add6 | |
parent | 2e2e88ea8c3bd9e1bd6e42faf047a4ac3fbb3b2f (diff) |
fs: dentry allocation consolidation
fs: dentry allocation consolidation
There are 2 duplicate copies of code in dentry allocation in path lookup.
Consolidate them into a single function.
Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 70 |
1 files changed, 33 insertions, 37 deletions
diff --git a/fs/namei.c b/fs/namei.c index c2742b7dec59..b815a4d2e1d6 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -686,6 +686,35 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
686 | } | 686 | } |
687 | 687 | ||
688 | /* | 688 | /* |
689 | * Allocate a dentry with name and parent, and perform a parent | ||
690 | * directory ->lookup on it. Returns the new dentry, or ERR_PTR | ||
691 | * on error. parent->d_inode->i_mutex must be held. d_lookup must | ||
692 | * have verified that no child exists while under i_mutex. | ||
693 | */ | ||
694 | static struct dentry *d_alloc_and_lookup(struct dentry *parent, | ||
695 | struct qstr *name, struct nameidata *nd) | ||
696 | { | ||
697 | struct inode *inode = parent->d_inode; | ||
698 | struct dentry *dentry; | ||
699 | struct dentry *old; | ||
700 | |||
701 | /* Don't create child dentry for a dead directory. */ | ||
702 | if (unlikely(IS_DEADDIR(inode))) | ||
703 | return ERR_PTR(-ENOENT); | ||
704 | |||
705 | dentry = d_alloc(parent, name); | ||
706 | if (unlikely(!dentry)) | ||
707 | return ERR_PTR(-ENOMEM); | ||
708 | |||
709 | old = inode->i_op->lookup(inode, dentry, nd); | ||
710 | if (unlikely(old)) { | ||
711 | dput(dentry); | ||
712 | dentry = old; | ||
713 | } | ||
714 | return dentry; | ||
715 | } | ||
716 | |||
717 | /* | ||
689 | * It's more convoluted than I'd like it to be, but... it's still fairly | 718 | * It's more convoluted than I'd like it to be, but... it's still fairly |
690 | * small and for now I'd prefer to have fast path as straight as possible. | 719 | * small and for now I'd prefer to have fast path as straight as possible. |
691 | * It _is_ time-critical. | 720 | * It _is_ time-critical. |
@@ -738,30 +767,13 @@ need_lookup: | |||
738 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup | 767 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup |
739 | */ | 768 | */ |
740 | dentry = d_lookup(parent, name); | 769 | dentry = d_lookup(parent, name); |
741 | if (!dentry) { | 770 | if (likely(!dentry)) { |
742 | struct dentry *new; | 771 | dentry = d_alloc_and_lookup(parent, name, nd); |
743 | |||
744 | /* Don't create child dentry for a dead directory. */ | ||
745 | dentry = ERR_PTR(-ENOENT); | ||
746 | if (IS_DEADDIR(dir)) | ||
747 | goto out_unlock; | ||
748 | |||
749 | new = d_alloc(parent, name); | ||
750 | dentry = ERR_PTR(-ENOMEM); | ||
751 | if (new) { | ||
752 | dentry = dir->i_op->lookup(dir, new, nd); | ||
753 | if (dentry) | ||
754 | dput(new); | ||
755 | else | ||
756 | dentry = new; | ||
757 | } | ||
758 | out_unlock: | ||
759 | mutex_unlock(&dir->i_mutex); | 772 | mutex_unlock(&dir->i_mutex); |
760 | if (IS_ERR(dentry)) | 773 | if (IS_ERR(dentry)) |
761 | goto fail; | 774 | goto fail; |
762 | goto done; | 775 | goto done; |
763 | } | 776 | } |
764 | |||
765 | /* | 777 | /* |
766 | * Uhhuh! Nasty case: the cache was re-populated while | 778 | * Uhhuh! Nasty case: the cache was re-populated while |
767 | * we waited on the semaphore. Need to revalidate. | 779 | * we waited on the semaphore. Need to revalidate. |
@@ -1135,24 +1147,8 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1135 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | 1147 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) |
1136 | dentry = do_revalidate(dentry, nd); | 1148 | dentry = do_revalidate(dentry, nd); |
1137 | 1149 | ||
1138 | if (!dentry) { | 1150 | if (!dentry) |
1139 | struct dentry *new; | 1151 | dentry = d_alloc_and_lookup(base, name, nd); |
1140 | |||
1141 | /* Don't create child dentry for a dead directory. */ | ||
1142 | dentry = ERR_PTR(-ENOENT); | ||
1143 | if (IS_DEADDIR(inode)) | ||
1144 | goto out; | ||
1145 | |||
1146 | new = d_alloc(base, name); | ||
1147 | dentry = ERR_PTR(-ENOMEM); | ||
1148 | if (!new) | ||
1149 | goto out; | ||
1150 | dentry = inode->i_op->lookup(inode, new, nd); | ||
1151 | if (!dentry) | ||
1152 | dentry = new; | ||
1153 | else | ||
1154 | dput(new); | ||
1155 | } | ||
1156 | out: | 1152 | out: |
1157 | return dentry; | 1153 | return dentry; |
1158 | } | 1154 | } |