浏览代码

sanitize pathname component hash calculation

Lift it to lookup_one_len() and link_path_walk() resp. into the
same place where we calculated default hash function of the same
name.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Al Viro 14 年之前
父节点
当前提交
5a202bcd75
共有 1 个文件被更改,包括 19 次插入23 次删除
  1. 19 23
      fs/namei.c

+ 19 - 23
fs/namei.c

@@ -1216,16 +1216,6 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
 	struct inode *dir;
 	struct inode *dir;
 	int err;
 	int err;
 
 
-	/*
-	 * See if the low-level filesystem might want
-	 * to use its own hash..
-	 */
-	if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
-		err = parent->d_op->d_hash(parent, nd->inode, name);
-		if (err < 0)
-			return err;
-	}
-
 	/*
 	/*
 	 * Rename seqlock is not required here because in the off chance
 	 * Rename seqlock is not required here because in the off chance
 	 * of a false negative due to a concurrent rename, we're going to
 	 * of a false negative due to a concurrent rename, we're going to
@@ -1414,8 +1404,16 @@ static int link_path_walk(const char *name, struct nameidata *nd)
 			case 1:
 			case 1:
 				type = LAST_DOT;
 				type = LAST_DOT;
 		}
 		}
-		if (likely(type == LAST_NORM))
+		if (likely(type == LAST_NORM)) {
+			struct dentry *parent = nd->path.dentry;
 			nd->flags &= ~LOOKUP_JUMPED;
 			nd->flags &= ~LOOKUP_JUMPED;
+			if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
+				err = parent->d_op->d_hash(parent, nd->inode,
+							   &this);
+				if (err < 0)
+					break;
+			}
+		}
 
 
 		/* remove trailing slashes? */
 		/* remove trailing slashes? */
 		if (!c)
 		if (!c)
@@ -1722,17 +1720,6 @@ static struct dentry *__lookup_hash(struct qstr *name,
 	if (err)
 	if (err)
 		return ERR_PTR(err);
 		return ERR_PTR(err);
 
 
-	/*
-	 * See if the low-level filesystem might want
-	 * to use its own hash..
-	 */
-	if (base->d_flags & DCACHE_OP_HASH) {
-		err = base->d_op->d_hash(base, inode, name);
-		dentry = ERR_PTR(err);
-		if (err < 0)
-			goto out;
-	}
-
 	/*
 	/*
 	 * Don't bother with __d_lookup: callers are for creat as
 	 * Don't bother with __d_lookup: callers are for creat as
 	 * well as unlink, so a lot of the time it would cost
 	 * well as unlink, so a lot of the time it would cost
@@ -1745,7 +1732,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
 
 
 	if (!dentry)
 	if (!dentry)
 		dentry = d_alloc_and_lookup(base, name, nd);
 		dentry = d_alloc_and_lookup(base, name, nd);
-out:
+
 	return dentry;
 	return dentry;
 }
 }
 
 
@@ -1791,6 +1778,15 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 		hash = partial_name_hash(c, hash);
 		hash = partial_name_hash(c, hash);
 	}
 	}
 	this.hash = end_name_hash(hash);
 	this.hash = end_name_hash(hash);
+	/*
+	 * See if the low-level filesystem might want
+	 * to use its own hash..
+	 */
+	if (base->d_flags & DCACHE_OP_HASH) {
+		int err = base->d_op->d_hash(base, base->d_inode, &this);
+		if (err < 0)
+			return ERR_PTR(err);
+	}
 
 
 	return __lookup_hash(&this, base, NULL);
 	return __lookup_hash(&this, base, NULL);
 }
 }