aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Libenzi <davidel@xmailserver.org>2007-10-17 02:30:19 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:43:00 -0400
commit96fdc72ddfe8aa3eb1f51e78cc13babefbf26dda (patch)
tree58038ee825096fec9f330fe187e615bb7c2e8422
parent5e3c3ac9db432fbdd2da92ce0f12d7912706c689 (diff)
anon-inodes use open coded atomic_inc for the shared inode
Since we know the shared inode count is always >0, we can avoid igrab() and use an open coded atomic_inc(). This also fixes a bug noticed by Yan Zheng <yanzheng@21cn.com>: were checking for an IS_ERR() return from igrab(), but it actually returns NULL on error. Signed-off-by: Davide Libenzi <davidel@xmailserver.org> Cc: Yan Zheng <yanzheng@21cn.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/anon_inodes.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index b4a75880f6fd..23321889d9b0 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -76,7 +76,6 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
76{ 76{
77 struct qstr this; 77 struct qstr this;
78 struct dentry *dentry; 78 struct dentry *dentry;
79 struct inode *inode;
80 struct file *file; 79 struct file *file;
81 int error, fd; 80 int error, fd;
82 81
@@ -86,15 +85,9 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
86 if (!file) 85 if (!file)
87 return -ENFILE; 86 return -ENFILE;
88 87
89 inode = igrab(anon_inode_inode);
90 if (IS_ERR(inode)) {
91 error = PTR_ERR(inode);
92 goto err_put_filp;
93 }
94
95 error = get_unused_fd(); 88 error = get_unused_fd();
96 if (error < 0) 89 if (error < 0)
97 goto err_iput; 90 goto err_put_filp;
98 fd = error; 91 fd = error;
99 92
100 /* 93 /*
@@ -108,14 +101,22 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
108 dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this); 101 dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this);
109 if (!dentry) 102 if (!dentry)
110 goto err_put_unused_fd; 103 goto err_put_unused_fd;
104
105 /*
106 * We know the anon_inode inode count is always greater than zero,
107 * so we can avoid doing an igrab() and we can use an open-coded
108 * atomic_inc().
109 */
110 atomic_inc(&anon_inode_inode->i_count);
111
111 dentry->d_op = &anon_inodefs_dentry_operations; 112 dentry->d_op = &anon_inodefs_dentry_operations;
112 /* Do not publish this dentry inside the global dentry hash table */ 113 /* Do not publish this dentry inside the global dentry hash table */
113 dentry->d_flags &= ~DCACHE_UNHASHED; 114 dentry->d_flags &= ~DCACHE_UNHASHED;
114 d_instantiate(dentry, inode); 115 d_instantiate(dentry, anon_inode_inode);
115 116
116 file->f_path.mnt = mntget(anon_inode_mnt); 117 file->f_path.mnt = mntget(anon_inode_mnt);
117 file->f_path.dentry = dentry; 118 file->f_path.dentry = dentry;
118 file->f_mapping = inode->i_mapping; 119 file->f_mapping = anon_inode_inode->i_mapping;
119 120
120 file->f_pos = 0; 121 file->f_pos = 0;
121 file->f_flags = O_RDWR; 122 file->f_flags = O_RDWR;
@@ -127,14 +128,12 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
127 fd_install(fd, file); 128 fd_install(fd, file);
128 129
129 *pfd = fd; 130 *pfd = fd;
130 *pinode = inode; 131 *pinode = anon_inode_inode;
131 *pfile = file; 132 *pfile = file;
132 return 0; 133 return 0;
133 134
134err_put_unused_fd: 135err_put_unused_fd:
135 put_unused_fd(fd); 136 put_unused_fd(fd);
136err_iput:
137 iput(inode);
138err_put_filp: 137err_put_filp:
139 put_filp(file); 138 put_filp(file);
140 return error; 139 return error;