Leave mangled flag only for setting nd.intent.open.flag
[linux-2.6.git] / fs / namei.c
index 976fc32..f5e4397 100644 (file)
@@ -1591,13 +1591,13 @@ static int open_will_truncate(int flag, struct inode *inode)
 }
 
 static struct file *finish_open(struct nameidata *nd,
-                               int open_flag, int flag, int acc_mode)
+                               int open_flag, int acc_mode)
 {
        struct file *filp;
        int will_truncate;
        int error;
 
-       will_truncate = open_will_truncate(flag, nd->path.dentry->d_inode);
+       will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
        if (will_truncate) {
                error = mnt_want_write(nd->path.mnt);
                if (error)
@@ -1646,7 +1646,7 @@ exit:
 }
 
 static struct file *do_last(struct nameidata *nd, struct path *path,
-                           int open_flag, int flag, int acc_mode,
+                           int open_flag, int acc_mode,
                            int mode, const char *pathname,
                            int *is_link)
 {
@@ -1656,6 +1656,10 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 
        *is_link = 0;
 
+       error = -EISDIR;
+       if (nd->last_type != LAST_NORM || nd->last.name[nd->last.len])
+               goto exit;
+
        mutex_lock(&dir->d_inode->i_mutex);
 
        path->dentry = lookup_hash(nd);
@@ -1708,12 +1712,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        audit_inode(pathname, path->dentry);
 
        error = -EEXIST;
-       if (flag & O_EXCL)
+       if (open_flag & O_EXCL)
                goto exit_dput;
 
        if (__follow_mount(path)) {
                error = -ELOOP;
-               if (flag & O_NOFOLLOW)
+               if (open_flag & O_NOFOLLOW)
                        goto exit_dput;
        }
 
@@ -1729,7 +1733,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        error = -EISDIR;
        if (S_ISDIR(path->dentry->d_inode->i_mode))
                goto exit;
-       filp = finish_open(nd, open_flag, flag, acc_mode);
+       filp = finish_open(nd, open_flag, acc_mode);
        return filp;
 
 exit_mutex_unlock:
@@ -1773,18 +1777,18 @@ struct file *do_filp_open(int dfd, const char *pathname,
                acc_mode = MAY_OPEN | ACC_MODE(open_flag);
 
        /* O_TRUNC implies we need access checks for write permissions */
-       if (flag & O_TRUNC)
+       if (open_flag & O_TRUNC)
                acc_mode |= MAY_WRITE;
 
        /* Allow the LSM permission hook to distinguish append 
           access from general write access. */
-       if (flag & O_APPEND)
+       if (open_flag & O_APPEND)
                acc_mode |= MAY_APPEND;
 
        /*
         * The simplest case - just a plain lookup.
         */
-       if (!(flag & O_CREAT)) {
+       if (!(open_flag & O_CREAT)) {
                filp = get_empty_filp();
 
                if (filp == NULL)
@@ -1794,7 +1798,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
                nd.intent.open.flags = flag;
                nd.intent.open.create_mode = 0;
                error = do_path_lookup(dfd, pathname,
-                                       lookup_flags(flag)|LOOKUP_OPEN, &nd);
+                                       lookup_flags(open_flag)|LOOKUP_OPEN, &nd);
                if (IS_ERR(nd.intent.open.file)) {
                        if (error == 0) {
                                error = PTR_ERR(nd.intent.open.file);
@@ -1826,13 +1830,8 @@ reval:
                audit_inode(pathname, nd.path.dentry);
 
        /*
-        * We have the parent and last component. First of all, check
-        * that we are not asked to creat(2) an obvious directory - that
-        * will not do.
+        * We have the parent and last component.
         */
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len])
-               goto exit_parent;
 
        error = -ENFILE;
        filp = get_empty_filp();
@@ -1844,9 +1843,9 @@ reval:
        nd.intent.open.create_mode = mode;
        nd.flags &= ~LOOKUP_PARENT;
        nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN;
-       if (flag & O_EXCL)
+       if (open_flag & O_EXCL)
                nd.flags |= LOOKUP_EXCL;
-       filp = do_last(&nd, &path, open_flag, flag, acc_mode, mode,
+       filp = do_last(&nd, &path, open_flag, acc_mode, mode,
                       pathname, &is_link);
        if (is_link)
                goto do_link;
@@ -1855,7 +1854,7 @@ reval:
        return filp;
 
 ok:
-       filp = finish_open(&nd, open_flag, flag, acc_mode);
+       filp = finish_open(&nd, open_flag, acc_mode);
        if (nd.root.mnt)
                path_put(&nd.root);
        return filp;
@@ -1873,7 +1872,7 @@ exit_parent:
 
 do_link:
        error = -ELOOP;
-       if (flag & O_NOFOLLOW)
+       if ((open_flag & O_NOFOLLOW) || count++ == 32)
                goto exit_dput;
        /*
         * This is subtle. Instead of calling do_follow_link() we do the
@@ -1908,21 +1907,10 @@ do_link:
        nd.flags &= ~LOOKUP_PARENT;
        if (nd.last_type == LAST_BIND)
                goto ok;
-       error = -EISDIR;
-       if (nd.last_type != LAST_NORM)
-               goto exit;
-       if (nd.last.name[nd.last.len]) {
-               __putname(nd.last.name);
-               goto exit;
-       }
-       error = -ELOOP;
-       if (count++==32) {
-               __putname(nd.last.name);
-               goto exit;
-       }
-       filp = do_last(&nd, &path, open_flag, flag, acc_mode, mode,
+       filp = do_last(&nd, &path, open_flag, acc_mode, mode,
                       pathname, &is_link);
-       __putname(nd.last.name);
+       if (nd.last_type == LAST_NORM)
+               __putname(nd.last.name);
        if (is_link)
                goto do_link;
        if (nd.root.mnt)