patch-2.4.3 linux/fs/smbfs/cache.c

Next file: linux/fs/smbfs/inode.c
Previous file: linux/fs/smbfs/ChangeLog
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.2/linux/fs/smbfs/cache.c linux/fs/smbfs/cache.c
@@ -48,6 +48,7 @@
 	UnlockPage(page);
 	page_cache_release(page);
 out:
+	return;
 }
 
 /*
@@ -71,47 +72,6 @@
 	spin_unlock(&dcache_lock);
 }
 
-
-static int
-smb_d_validate(struct dentry *dentry)
-{
-	unsigned long dent_addr = (unsigned long) dentry;
-	unsigned long min_addr = PAGE_OFFSET;
-	unsigned long align_mask = 0x0F;
-	unsigned int len;
-	int valid = 0;
-
-	if (dent_addr < min_addr)
-		goto bad_addr;
-	if (dent_addr > (unsigned long)high_memory - sizeof(struct dentry))
-		goto bad_addr;
-	if ((dent_addr & ~align_mask) != dent_addr)
-		goto bad_align;
-	if ((!kern_addr_valid(dent_addr)) || (!kern_addr_valid(dent_addr -1 +
-						       sizeof(struct dentry))))
-		goto bad_addr;
-	/*
-	 * Looks safe enough to dereference ...
-	 */
-	len = dentry->d_name.len;
-	if (len > SMB_MAXPATHLEN)
-		goto out;
-	/*
-	 * Note: d_validate doesn't dereference the parent pointer ...
-	 * just combines it with the name hash to find the hash chain.
-	 */
-	valid = d_validate(dentry, dentry->d_parent, dentry->d_name.hash, len);
-out:
-	return valid;
-
-bad_addr:
-	printk(KERN_ERR "smb_d_validate: invalid address %lx\n", dent_addr);
-	goto out;
-bad_align:
-	printk(KERN_ERR "smb_d_validate: unaligned address %lx\n", dent_addr);
-	goto out;
-}
-
 /*
  * dget, but require that fpos and parent matches what the dentry contains.
  * dentry is not known to be a valid pointer at entry.
@@ -122,8 +82,8 @@
 	struct dentry *dent = dentry;
 	struct list_head *next;
 
-	if (smb_d_validate(dent)) {
-		if (dent->d_parent == parent &&
+	if (d_validate(dent, parent)) {
+		if (dent->d_name.len <= SMB_MAXPATHLEN &&
 		    (unsigned long)dent->d_fsdata == fpos) {
 			if (!dent->d_inode) {
 				dput(dent);
@@ -167,6 +127,7 @@
 	struct inode *newino, *inode = dentry->d_inode;
 	struct smb_cache_control ctl = *ctrl;
 	int valid = 0;
+	int hashed = 0;
 	ino_t ino = 0;
 
 	qname->hash = full_name_hash(qname->name, qname->len);
@@ -181,9 +142,11 @@
 		newdent = d_alloc(dentry, qname);
 		if (!newdent)
 			goto end_advance;
-	} else
+	} else {
+		hashed = 1;
 		memcpy((char *) newdent->d_name.name, qname->name,
 		       newdent->d_name.len);
+	}
 
 	if (!newdent->d_inode) {
 		smb_renew_times(newdent);
@@ -191,7 +154,9 @@
 		newino = smb_iget(inode->i_sb, entry);
 		if (newino) {
 			smb_new_dentry(newdent);
-			d_add(newdent, newino);
+			d_instantiate(newdent, newino);
+			if (!hashed)
+				d_rehash(newdent);
 		}
 	} else
 		smb_set_inode_attr(newdent->d_inode, entry);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)