Loading fs/namei.c +26 −48 Original line number Diff line number Diff line Loading @@ -2048,30 +2048,6 @@ static int handle_truncate(struct file *filp) return error; } /* * Be careful about ever adding any more callers of this * function. Its flags must be in the namei format, not * what get passed to sys_open(). */ static int __open_namei_create(struct nameidata *nd, struct path *path, int open_flag, int mode) { int error; struct dentry *dir = nd->path.dentry; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&nd->path, path->dentry, mode, 0); if (error) goto out_unlock; error = vfs_create(dir->d_inode, path->dentry, mode, nd); out_unlock: mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = path->dentry; return error; } /* * Note that while the flag value (low two bits) for sys_open means: * 00 - read-only Loading @@ -2096,17 +2072,6 @@ static inline int open_to_namei_flags(int flag) return flag; } static int open_will_truncate(int flag, struct inode *inode) { /* * We'll never write to the fs underlying * a device file. */ if (special_file(inode->i_mode)) return 0; return (flag & O_TRUNC); } /* * Handle the last step of open() */ Loading @@ -2114,8 +2079,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, const struct open_flags *op, const char *pathname) { struct dentry *dir = nd->path.dentry; struct dentry *dentry; int open_flag = op->open_flag; int will_truncate; int will_truncate = open_flag & O_TRUNC; int want_write = 0; int skip_perm = 0; struct file *filp; Loading Loading @@ -2207,25 +2173,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path, mutex_lock(&dir->d_inode->i_mutex); path->dentry = lookup_hash(nd); path->mnt = nd->path.mnt; error = PTR_ERR(path->dentry); if (IS_ERR(path->dentry)) { dentry = lookup_hash(nd); error = PTR_ERR(dentry); if (IS_ERR(dentry)) { mutex_unlock(&dir->d_inode->i_mutex); goto exit; } path->dentry = dentry; path->mnt = nd->path.mnt; if (IS_ERR(nd->intent.open.file)) { error = PTR_ERR(nd->intent.open.file); goto exit_mutex_unlock; } /* Negative dentry, just create the file */ if (!path->dentry->d_inode) { if (!dentry->d_inode) { int mode = op->mode; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a * ro->rw transition does not occur between * rw->ro transition does not occur between * the time when the file is created and when * a permanent write count is taken through * the 'struct file' in nameidata_to_filp(). Loading @@ -2234,13 +2204,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (error) goto exit_mutex_unlock; want_write = 1; will_truncate = 0; error = __open_namei_create(nd, path, open_flag, op->mode); if (error) goto exit; /* Don't check for write permission, don't truncate */ open_flag &= ~O_TRUNC; will_truncate = 0; skip_perm = 1; error = security_path_mknod(&nd->path, dentry, mode, 0); if (error) goto exit_mutex_unlock; error = vfs_create(dir->d_inode, dentry, mode, nd); if (error) goto exit_mutex_unlock; mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = dentry; goto common; } Loading Loading @@ -2271,7 +2247,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (S_ISDIR(nd->inode->i_mode)) goto exit; ok: will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode); if (!S_ISREG(nd->inode->i_mode)) will_truncate = 0; if (will_truncate) { error = mnt_want_write(nd->path.mnt); if (error) Loading Loading
fs/namei.c +26 −48 Original line number Diff line number Diff line Loading @@ -2048,30 +2048,6 @@ static int handle_truncate(struct file *filp) return error; } /* * Be careful about ever adding any more callers of this * function. Its flags must be in the namei format, not * what get passed to sys_open(). */ static int __open_namei_create(struct nameidata *nd, struct path *path, int open_flag, int mode) { int error; struct dentry *dir = nd->path.dentry; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&nd->path, path->dentry, mode, 0); if (error) goto out_unlock; error = vfs_create(dir->d_inode, path->dentry, mode, nd); out_unlock: mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = path->dentry; return error; } /* * Note that while the flag value (low two bits) for sys_open means: * 00 - read-only Loading @@ -2096,17 +2072,6 @@ static inline int open_to_namei_flags(int flag) return flag; } static int open_will_truncate(int flag, struct inode *inode) { /* * We'll never write to the fs underlying * a device file. */ if (special_file(inode->i_mode)) return 0; return (flag & O_TRUNC); } /* * Handle the last step of open() */ Loading @@ -2114,8 +2079,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, const struct open_flags *op, const char *pathname) { struct dentry *dir = nd->path.dentry; struct dentry *dentry; int open_flag = op->open_flag; int will_truncate; int will_truncate = open_flag & O_TRUNC; int want_write = 0; int skip_perm = 0; struct file *filp; Loading Loading @@ -2207,25 +2173,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path, mutex_lock(&dir->d_inode->i_mutex); path->dentry = lookup_hash(nd); path->mnt = nd->path.mnt; error = PTR_ERR(path->dentry); if (IS_ERR(path->dentry)) { dentry = lookup_hash(nd); error = PTR_ERR(dentry); if (IS_ERR(dentry)) { mutex_unlock(&dir->d_inode->i_mutex); goto exit; } path->dentry = dentry; path->mnt = nd->path.mnt; if (IS_ERR(nd->intent.open.file)) { error = PTR_ERR(nd->intent.open.file); goto exit_mutex_unlock; } /* Negative dentry, just create the file */ if (!path->dentry->d_inode) { if (!dentry->d_inode) { int mode = op->mode; if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a * ro->rw transition does not occur between * rw->ro transition does not occur between * the time when the file is created and when * a permanent write count is taken through * the 'struct file' in nameidata_to_filp(). Loading @@ -2234,13 +2204,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (error) goto exit_mutex_unlock; want_write = 1; will_truncate = 0; error = __open_namei_create(nd, path, open_flag, op->mode); if (error) goto exit; /* Don't check for write permission, don't truncate */ open_flag &= ~O_TRUNC; will_truncate = 0; skip_perm = 1; error = security_path_mknod(&nd->path, dentry, mode, 0); if (error) goto exit_mutex_unlock; error = vfs_create(dir->d_inode, dentry, mode, nd); if (error) goto exit_mutex_unlock; mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = dentry; goto common; } Loading Loading @@ -2271,7 +2247,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (S_ISDIR(nd->inode->i_mode)) goto exit; ok: will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode); if (!S_ISREG(nd->inode->i_mode)) will_truncate = 0; if (will_truncate) { error = mnt_want_write(nd->path.mnt); if (error) Loading