Merge tag 'nfs-for-4.19-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[sfrench/cifs-2.6.git] / fs / nfs / dir.c
index d7f158c3efc8a18b78f9b592a1466dc7be28b7b6..8bfaa658b2c190ddfa61f8a52acb4895b9f63b1d 100644 (file)
@@ -904,23 +904,29 @@ static loff_t nfs_llseek_dir(struct file *filp, loff_t offset, int whence)
        dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
                        filp, offset, whence);
 
        dfprintk(FILE, "NFS: llseek dir(%pD2, %lld, %d)\n",
                        filp, offset, whence);
 
-       inode_lock(inode);
        switch (whence) {
        switch (whence) {
-               case 1:
-                       offset += filp->f_pos;
-               case 0:
-                       if (offset >= 0)
-                               break;
-               default:
-                       offset = -EINVAL;
-                       goto out;
+       default:
+               return -EINVAL;
+       case SEEK_SET:
+               if (offset < 0)
+                       return -EINVAL;
+               inode_lock(inode);
+               break;
+       case SEEK_CUR:
+               if (offset == 0)
+                       return filp->f_pos;
+               inode_lock(inode);
+               offset += filp->f_pos;
+               if (offset < 0) {
+                       inode_unlock(inode);
+                       return -EINVAL;
+               }
        }
        if (offset != filp->f_pos) {
                filp->f_pos = offset;
                dir_ctx->dir_cookie = 0;
                dir_ctx->duped = 0;
        }
        }
        if (offset != filp->f_pos) {
                filp->f_pos = offset;
                dir_ctx->dir_cookie = 0;
                dir_ctx->duped = 0;
        }
-out:
        inode_unlock(inode);
        return offset;
 }
        inode_unlock(inode);
        return offset;
 }
@@ -1032,7 +1038,7 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
        if (flags & LOOKUP_REVAL)
                goto out_force;
 out:
        if (flags & LOOKUP_REVAL)
                goto out_force;
 out:
-       return (inode->i_nlink == 0) ? -ENOENT : 0;
+       return (inode->i_nlink == 0) ? -ESTALE : 0;
 out_force:
        if (flags & LOOKUP_RCU)
                return -ECHILD;
 out_force:
        if (flags & LOOKUP_RCU)
                return -ECHILD;
@@ -2499,7 +2505,9 @@ static int nfs_execute_ok(struct inode *inode, int mask)
        struct nfs_server *server = NFS_SERVER(inode);
        int ret = 0;
 
        struct nfs_server *server = NFS_SERVER(inode);
        int ret = 0;
 
-       if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS)) {
+       if (S_ISDIR(inode->i_mode))
+               return 0;
+       if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_OTHER)) {
                if (mask & MAY_NOT_BLOCK)
                        return -ECHILD;
                ret = __nfs_revalidate_inode(server, inode);
                if (mask & MAY_NOT_BLOCK)
                        return -ECHILD;
                ret = __nfs_revalidate_inode(server, inode);