net/mlx4: Fix firmware command timeout during interrupt test
[cascardo/linux.git] / fs / nfs / dir.c
index 177fefb..5f1af4c 100644 (file)
@@ -435,11 +435,11 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
                return 0;
 
        nfsi = NFS_I(inode);
-       if (entry->fattr->fileid == nfsi->fileid)
-               return 1;
-       if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0)
-               return 1;
-       return 0;
+       if (entry->fattr->fileid != nfsi->fileid)
+               return 0;
+       if (entry->fh->size && nfs_compare_fh(entry->fh, &nfsi->fh) != 0)
+               return 0;
+       return 1;
 }
 
 static
@@ -496,6 +496,14 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
                return;
        if (!(entry->fattr->valid & NFS_ATTR_FATTR_FSID))
                return;
+       if (filename.len == 0)
+               return;
+       /* Validate that the name doesn't contain any illegal '\0' */
+       if (strnlen(filename.name, filename.len) != filename.len)
+               return;
+       /* ...or '/' */
+       if (strnchr(filename.name, filename.len, '/'))
+               return;
        if (filename.name[0] == '.') {
                if (filename.len == 1)
                        return;
@@ -517,6 +525,8 @@ again:
                                        &entry->fattr->fsid))
                        goto out;
                if (nfs_same_file(dentry, entry)) {
+                       if (!entry->fh->size)
+                               goto out;
                        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
                        status = nfs_refresh_inode(d_inode(dentry), entry->fattr);
                        if (!status)
@@ -529,6 +539,10 @@ again:
                        goto again;
                }
        }
+       if (!entry->fh->size) {
+               d_lookup_done(dentry);
+               goto out;
+       }
 
        inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
        alias = d_splice_alias(inode, dentry);
@@ -2013,7 +2027,8 @@ EXPORT_SYMBOL_GPL(nfs_link);
  * the rename.
  */
 int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-                     struct inode *new_dir, struct dentry *new_dentry)
+              struct inode *new_dir, struct dentry *new_dentry,
+              unsigned int flags)
 {
        struct inode *old_inode = d_inode(old_dentry);
        struct inode *new_inode = d_inode(new_dentry);
@@ -2021,6 +2036,9 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct rpc_task *task;
        int error = -EBUSY;
 
+       if (flags)
+               return -EINVAL;
+
        dfprintk(VFS, "NFS: rename(%pd2 -> %pd2, ct=%d)\n",
                 old_dentry, new_dentry,
                 d_count(new_dentry));