aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-03-09 00:59:59 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-14 09:15:27 -0400
commit6c0d46c493217cf48999b3f8808910ae534aa085 (patch)
tree4c36a27f499ce8a8fb70807c78187c247e79dc65 /fs/namei.c
parentca344a894b41a133dab07dfbbdf652c053f6658c (diff)
fold __open_namei_create() and open_will_truncate() into do_last()
... and clean up a bit more Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c74
1 files changed, 26 insertions, 48 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 63844776484c..441f1106de08 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2049,30 +2049,6 @@ static int handle_truncate(struct file *filp)
2049} 2049}
2050 2050
2051/* 2051/*
2052 * Be careful about ever adding any more callers of this
2053 * function. Its flags must be in the namei format, not
2054 * what get passed to sys_open().
2055 */
2056static int __open_namei_create(struct nameidata *nd, struct path *path,
2057 int open_flag, int mode)
2058{
2059 int error;
2060 struct dentry *dir = nd->path.dentry;
2061
2062 if (!IS_POSIXACL(dir->d_inode))
2063 mode &= ~current_umask();
2064 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
2065 if (error)
2066 goto out_unlock;
2067 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
2068out_unlock:
2069 mutex_unlock(&dir->d_inode->i_mutex);
2070 dput(nd->path.dentry);
2071 nd->path.dentry = path->dentry;
2072 return error;
2073}
2074
2075/*
2076 * Note that while the flag value (low two bits) for sys_open means: 2052 * Note that while the flag value (low two bits) for sys_open means:
2077 * 00 - read-only 2053 * 00 - read-only
2078 * 01 - write-only 2054 * 01 - write-only
@@ -2096,17 +2072,6 @@ static inline int open_to_namei_flags(int flag)
2096 return flag; 2072 return flag;
2097} 2073}
2098 2074
2099static int open_will_truncate(int flag, struct inode *inode)
2100{
2101 /*
2102 * We'll never write to the fs underlying
2103 * a device file.
2104 */
2105 if (special_file(inode->i_mode))
2106 return 0;
2107 return (flag & O_TRUNC);
2108}
2109
2110/* 2075/*
2111 * Handle the last step of open() 2076 * Handle the last step of open()
2112 */ 2077 */
@@ -2114,8 +2079,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2114 const struct open_flags *op, const char *pathname) 2079 const struct open_flags *op, const char *pathname)
2115{ 2080{
2116 struct dentry *dir = nd->path.dentry; 2081 struct dentry *dir = nd->path.dentry;
2082 struct dentry *dentry;
2117 int open_flag = op->open_flag; 2083 int open_flag = op->open_flag;
2118 int will_truncate; 2084 int will_truncate = open_flag & O_TRUNC;
2119 int want_write = 0; 2085 int want_write = 0;
2120 int skip_perm = 0; 2086 int skip_perm = 0;
2121 struct file *filp; 2087 struct file *filp;
@@ -2207,25 +2173,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2207 2173
2208 mutex_lock(&dir->d_inode->i_mutex); 2174 mutex_lock(&dir->d_inode->i_mutex);
2209 2175
2210 path->dentry = lookup_hash(nd); 2176 dentry = lookup_hash(nd);
2211 path->mnt = nd->path.mnt; 2177 error = PTR_ERR(dentry);
2212 2178 if (IS_ERR(dentry)) {
2213 error = PTR_ERR(path->dentry);
2214 if (IS_ERR(path->dentry)) {
2215 mutex_unlock(&dir->d_inode->i_mutex); 2179 mutex_unlock(&dir->d_inode->i_mutex);
2216 goto exit; 2180 goto exit;
2217 } 2181 }
2218 2182
2183 path->dentry = dentry;
2184 path->mnt = nd->path.mnt;
2185
2219 if (IS_ERR(nd->intent.open.file)) { 2186 if (IS_ERR(nd->intent.open.file)) {
2220 error = PTR_ERR(nd->intent.open.file); 2187 error = PTR_ERR(nd->intent.open.file);
2221 goto exit_mutex_unlock; 2188 goto exit_mutex_unlock;
2222 } 2189 }
2223 2190
2224 /* Negative dentry, just create the file */ 2191 /* Negative dentry, just create the file */
2225 if (!path->dentry->d_inode) { 2192 if (!dentry->d_inode) {
2193 int mode = op->mode;
2194 if (!IS_POSIXACL(dir->d_inode))
2195 mode &= ~current_umask();
2226 /* 2196 /*
2227 * This write is needed to ensure that a 2197 * This write is needed to ensure that a
2228 * ro->rw transition does not occur between 2198 * rw->ro transition does not occur between
2229 * the time when the file is created and when 2199 * the time when the file is created and when
2230 * a permanent write count is taken through 2200 * a permanent write count is taken through
2231 * the 'struct file' in nameidata_to_filp(). 2201 * the 'struct file' in nameidata_to_filp().
@@ -2234,13 +2204,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2234 if (error) 2204 if (error)
2235 goto exit_mutex_unlock; 2205 goto exit_mutex_unlock;
2236 want_write = 1; 2206 want_write = 1;
2237 will_truncate = 0;
2238 error = __open_namei_create(nd, path, open_flag, op->mode);
2239 if (error)
2240 goto exit;
2241 /* Don't check for write permission, don't truncate */ 2207 /* Don't check for write permission, don't truncate */
2242 open_flag &= ~O_TRUNC; 2208 open_flag &= ~O_TRUNC;
2209 will_truncate = 0;
2243 skip_perm = 1; 2210 skip_perm = 1;
2211 error = security_path_mknod(&nd->path, dentry, mode, 0);
2212 if (error)
2213 goto exit_mutex_unlock;
2214 error = vfs_create(dir->d_inode, dentry, mode, nd);
2215 if (error)
2216 goto exit_mutex_unlock;
2217 mutex_unlock(&dir->d_inode->i_mutex);
2218 dput(nd->path.dentry);
2219 nd->path.dentry = dentry;
2244 goto common; 2220 goto common;
2245 } 2221 }
2246 2222
@@ -2271,7 +2247,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2271 if (S_ISDIR(nd->inode->i_mode)) 2247 if (S_ISDIR(nd->inode->i_mode))
2272 goto exit; 2248 goto exit;
2273ok: 2249ok:
2274 will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode); 2250 if (!S_ISREG(nd->inode->i_mode))
2251 will_truncate = 0;
2252
2275 if (will_truncate) { 2253 if (will_truncate) {
2276 error = mnt_want_write(nd->path.mnt); 2254 error = mnt_want_write(nd->path.mnt);
2277 if (error) 2255 if (error)