Merge branch 'master' into upstream
[sfrench/cifs-2.6.git] / fs / open.c
index 303f06d2a7b92e8e001489cf2b1db17bdae6bd0c..304c1c7814cbacfec0695e8714c5557ea8ee0e9b 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -546,7 +546,8 @@ asmlinkage long sys_chdir(const char __user * filename)
        struct nameidata nd;
        int error;
 
-       error = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
+       error = __user_walk(filename,
+                           LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
        if (error)
                goto out;
 
@@ -1172,6 +1173,7 @@ asmlinkage long sys_close(unsigned int fd)
        struct file * filp;
        struct files_struct *files = current->files;
        struct fdtable *fdt;
+       int retval;
 
        spin_lock(&files->file_lock);
        fdt = files_fdtable(files);
@@ -1184,7 +1186,16 @@ asmlinkage long sys_close(unsigned int fd)
        FD_CLR(fd, fdt->close_on_exec);
        __put_unused_fd(files, fd);
        spin_unlock(&files->file_lock);
-       return filp_close(filp, files);
+       retval = filp_close(filp, files);
+
+       /* can't restart close syscall because file table entry was cleared */
+       if (unlikely(retval == -ERESTARTSYS ||
+                    retval == -ERESTARTNOINTR ||
+                    retval == -ERESTARTNOHAND ||
+                    retval == -ERESTART_RESTARTBLOCK))
+               retval = -EINTR;
+
+       return retval;
 
 out_unlock:
        spin_unlock(&files->file_lock);