|
@@ -1725,17 +1725,13 @@ static inline int open_to_namei_flags(int flag)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * open_namei()
|
|
|
- *
|
|
|
- * namei for open - this is in fact almost the whole open-routine.
|
|
|
- *
|
|
|
* Note that the low bits of "flag" aren't the same as in the open
|
|
|
* system call. See open_to_namei_flags().
|
|
|
- * SMP-safe
|
|
|
*/
|
|
|
-int open_namei(int dfd, const char *pathname, int open_flag,
|
|
|
- int mode, struct nameidata *nd)
|
|
|
+struct file *do_filp_open(int dfd, const char *pathname,
|
|
|
+ int open_flag, int mode)
|
|
|
{
|
|
|
+ struct nameidata nd;
|
|
|
int acc_mode, error;
|
|
|
struct path path;
|
|
|
struct dentry *dir;
|
|
@@ -1758,18 +1754,19 @@ int open_namei(int dfd, const char *pathname, int open_flag,
|
|
|
*/
|
|
|
if (!(flag & O_CREAT)) {
|
|
|
error = path_lookup_open(dfd, pathname, lookup_flags(flag),
|
|
|
- nd, flag);
|
|
|
+ &nd, flag);
|
|
|
if (error)
|
|
|
- return error;
|
|
|
+ return ERR_PTR(error);
|
|
|
goto ok;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Create - we need to know the parent.
|
|
|
*/
|
|
|
- error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
|
|
|
+ error = path_lookup_create(dfd, pathname, LOOKUP_PARENT,
|
|
|
+ &nd, flag, mode);
|
|
|
if (error)
|
|
|
- return error;
|
|
|
+ return ERR_PTR(error);
|
|
|
|
|
|
/*
|
|
|
* We have the parent and last component. First of all, check
|
|
@@ -1777,14 +1774,14 @@ int open_namei(int dfd, const char *pathname, int open_flag,
|
|
|
* will not do.
|
|
|
*/
|
|
|
error = -EISDIR;
|
|
|
- if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len])
|
|
|
+ if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len])
|
|
|
goto exit;
|
|
|
|
|
|
- dir = nd->path.dentry;
|
|
|
- nd->flags &= ~LOOKUP_PARENT;
|
|
|
+ dir = nd.path.dentry;
|
|
|
+ nd.flags &= ~LOOKUP_PARENT;
|
|
|
mutex_lock(&dir->d_inode->i_mutex);
|
|
|
- path.dentry = lookup_hash(nd);
|
|
|
- path.mnt = nd->path.mnt;
|
|
|
+ path.dentry = lookup_hash(&nd);
|
|
|
+ path.mnt = nd.path.mnt;
|
|
|
|
|
|
do_last:
|
|
|
error = PTR_ERR(path.dentry);
|
|
@@ -1793,18 +1790,18 @@ do_last:
|
|
|
goto exit;
|
|
|
}
|
|
|
|
|
|
- if (IS_ERR(nd->intent.open.file)) {
|
|
|
+ if (IS_ERR(nd.intent.open.file)) {
|
|
|
mutex_unlock(&dir->d_inode->i_mutex);
|
|
|
- error = PTR_ERR(nd->intent.open.file);
|
|
|
+ error = PTR_ERR(nd.intent.open.file);
|
|
|
goto exit_dput;
|
|
|
}
|
|
|
|
|
|
/* Negative dentry, just create the file */
|
|
|
if (!path.dentry->d_inode) {
|
|
|
- error = __open_namei_create(nd, &path, flag, mode);
|
|
|
+ error = __open_namei_create(&nd, &path, flag, mode);
|
|
|
if (error)
|
|
|
goto exit;
|
|
|
- return 0;
|
|
|
+ return nameidata_to_filp(&nd, open_flag);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1829,23 +1826,23 @@ do_last:
|
|
|
if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
|
|
|
goto do_link;
|
|
|
|
|
|
- path_to_nameidata(&path, nd);
|
|
|
+ path_to_nameidata(&path, &nd);
|
|
|
error = -EISDIR;
|
|
|
if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
|
|
|
goto exit;
|
|
|
ok:
|
|
|
- error = may_open(nd, acc_mode, flag);
|
|
|
+ error = may_open(&nd, acc_mode, flag);
|
|
|
if (error)
|
|
|
goto exit;
|
|
|
- return 0;
|
|
|
+ return nameidata_to_filp(&nd, open_flag);
|
|
|
|
|
|
exit_dput:
|
|
|
- path_put_conditional(&path, nd);
|
|
|
+ path_put_conditional(&path, &nd);
|
|
|
exit:
|
|
|
- if (!IS_ERR(nd->intent.open.file))
|
|
|
- release_open_intent(nd);
|
|
|
- path_put(&nd->path);
|
|
|
- return error;
|
|
|
+ if (!IS_ERR(nd.intent.open.file))
|
|
|
+ release_open_intent(&nd);
|
|
|
+ path_put(&nd.path);
|
|
|
+ return ERR_PTR(error);
|
|
|
|
|
|
do_link:
|
|
|
error = -ELOOP;
|
|
@@ -1861,42 +1858,59 @@ do_link:
|
|
|
* stored in nd->last.name and we will have to putname() it when we
|
|
|
* are done. Procfs-like symlinks just set LAST_BIND.
|
|
|
*/
|
|
|
- nd->flags |= LOOKUP_PARENT;
|
|
|
- error = security_inode_follow_link(path.dentry, nd);
|
|
|
+ nd.flags |= LOOKUP_PARENT;
|
|
|
+ error = security_inode_follow_link(path.dentry, &nd);
|
|
|
if (error)
|
|
|
goto exit_dput;
|
|
|
- error = __do_follow_link(&path, nd);
|
|
|
+ error = __do_follow_link(&path, &nd);
|
|
|
if (error) {
|
|
|
/* Does someone understand code flow here? Or it is only
|
|
|
* me so stupid? Anathema to whoever designed this non-sense
|
|
|
* with "intent.open".
|
|
|
*/
|
|
|
- release_open_intent(nd);
|
|
|
- return error;
|
|
|
+ release_open_intent(&nd);
|
|
|
+ return ERR_PTR(error);
|
|
|
}
|
|
|
- nd->flags &= ~LOOKUP_PARENT;
|
|
|
- if (nd->last_type == LAST_BIND)
|
|
|
+ nd.flags &= ~LOOKUP_PARENT;
|
|
|
+ if (nd.last_type == LAST_BIND)
|
|
|
goto ok;
|
|
|
error = -EISDIR;
|
|
|
- if (nd->last_type != LAST_NORM)
|
|
|
+ if (nd.last_type != LAST_NORM)
|
|
|
goto exit;
|
|
|
- if (nd->last.name[nd->last.len]) {
|
|
|
- __putname(nd->last.name);
|
|
|
+ if (nd.last.name[nd.last.len]) {
|
|
|
+ __putname(nd.last.name);
|
|
|
goto exit;
|
|
|
}
|
|
|
error = -ELOOP;
|
|
|
if (count++==32) {
|
|
|
- __putname(nd->last.name);
|
|
|
+ __putname(nd.last.name);
|
|
|
goto exit;
|
|
|
}
|
|
|
- dir = nd->path.dentry;
|
|
|
+ dir = nd.path.dentry;
|
|
|
mutex_lock(&dir->d_inode->i_mutex);
|
|
|
- path.dentry = lookup_hash(nd);
|
|
|
- path.mnt = nd->path.mnt;
|
|
|
- __putname(nd->last.name);
|
|
|
+ path.dentry = lookup_hash(&nd);
|
|
|
+ path.mnt = nd.path.mnt;
|
|
|
+ __putname(nd.last.name);
|
|
|
goto do_last;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * filp_open - open file and return file pointer
|
|
|
+ *
|
|
|
+ * @filename: path to open
|
|
|
+ * @flags: open flags as per the open(2) second argument
|
|
|
+ * @mode: mode for the new file if O_CREAT is set, else ignored
|
|
|
+ *
|
|
|
+ * This is the helper to open a file from kernelspace if you really
|
|
|
+ * have to. But in generally you should not do this, so please move
|
|
|
+ * along, nothing to see here..
|
|
|
+ */
|
|
|
+struct file *filp_open(const char *filename, int flags, int mode)
|
|
|
+{
|
|
|
+ return do_filp_open(AT_FDCWD, filename, flags, mode);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(filp_open);
|
|
|
+
|
|
|
/**
|
|
|
* lookup_create - lookup a dentry, creating it if it doesn't exist
|
|
|
* @nd: nameidata info
|