aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2012-03-12 11:41:28 -0400
committerGrant Likely <grant.likely@secretlab.ca>2012-03-12 11:41:28 -0400
commite2aa4177264c1a459779d6e35fae22adf17a9232 (patch)
treebeba4b40aa90f6f033eb261cf5a5453c5957c87c /fs/namei.c
parent25db711df3258d125dc1209800317e5c0ef3c870 (diff)
parentfde7d9049e55ab85a390be7f415d74c9f62dd0f9 (diff)
Merge tag 'v3.3-rc7' into gpio/next
Linux 3.3-rc7. Merged into the gpio branch to pick up gpio bugfixes already in mainline before queueing up move v3.4 patches
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c70
1 files changed, 47 insertions, 23 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 208c6aa4a989..e2ba62820a0f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1095,8 +1095,10 @@ static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentr
1095 struct dentry *old; 1095 struct dentry *old;
1096 1096
1097 /* Don't create child dentry for a dead directory. */ 1097 /* Don't create child dentry for a dead directory. */
1098 if (unlikely(IS_DEADDIR(inode))) 1098 if (unlikely(IS_DEADDIR(inode))) {
1099 dput(dentry);
1099 return ERR_PTR(-ENOENT); 1100 return ERR_PTR(-ENOENT);
1101 }
1100 1102
1101 old = inode->i_op->lookup(inode, dentry, nd); 1103 old = inode->i_op->lookup(inode, dentry, nd);
1102 if (unlikely(old)) { 1104 if (unlikely(old)) {
@@ -1372,6 +1374,34 @@ static inline int can_lookup(struct inode *inode)
1372 return 1; 1374 return 1;
1373} 1375}
1374 1376
1377unsigned int full_name_hash(const unsigned char *name, unsigned int len)
1378{
1379 unsigned long hash = init_name_hash();
1380 while (len--)
1381 hash = partial_name_hash(*name++, hash);
1382 return end_name_hash(hash);
1383}
1384EXPORT_SYMBOL(full_name_hash);
1385
1386/*
1387 * We know there's a real path component here of at least
1388 * one character.
1389 */
1390static inline unsigned long hash_name(const char *name, unsigned int *hashp)
1391{
1392 unsigned long hash = init_name_hash();
1393 unsigned long len = 0, c;
1394
1395 c = (unsigned char)*name;
1396 do {
1397 len++;
1398 hash = partial_name_hash(c, hash);
1399 c = (unsigned char)name[len];
1400 } while (c && c != '/');
1401 *hashp = end_name_hash(hash);
1402 return len;
1403}
1404
1375/* 1405/*
1376 * Name resolution. 1406 * Name resolution.
1377 * This is the basic name resolution function, turning a pathname into 1407 * This is the basic name resolution function, turning a pathname into
@@ -1392,31 +1422,22 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1392 1422
1393 /* At this point we know we have a real path component. */ 1423 /* At this point we know we have a real path component. */
1394 for(;;) { 1424 for(;;) {
1395 unsigned long hash;
1396 struct qstr this; 1425 struct qstr this;
1397 unsigned int c; 1426 long len;
1398 int type; 1427 int type;
1399 1428
1400 err = may_lookup(nd); 1429 err = may_lookup(nd);
1401 if (err) 1430 if (err)
1402 break; 1431 break;
1403 1432
1433 len = hash_name(name, &this.hash);
1404 this.name = name; 1434 this.name = name;
1405 c = *(const unsigned char *)name; 1435 this.len = len;
1406
1407 hash = init_name_hash();
1408 do {
1409 name++;
1410 hash = partial_name_hash(c, hash);
1411 c = *(const unsigned char *)name;
1412 } while (c && (c != '/'));
1413 this.len = name - (const char *) this.name;
1414 this.hash = end_name_hash(hash);
1415 1436
1416 type = LAST_NORM; 1437 type = LAST_NORM;
1417 if (this.name[0] == '.') switch (this.len) { 1438 if (name[0] == '.') switch (len) {
1418 case 2: 1439 case 2:
1419 if (this.name[1] == '.') { 1440 if (name[1] == '.') {
1420 type = LAST_DOTDOT; 1441 type = LAST_DOTDOT;
1421 nd->flags |= LOOKUP_JUMPED; 1442 nd->flags |= LOOKUP_JUMPED;
1422 } 1443 }
@@ -1435,12 +1456,18 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1435 } 1456 }
1436 } 1457 }
1437 1458
1438 /* remove trailing slashes? */ 1459 if (!name[len])
1439 if (!c)
1440 goto last_component; 1460 goto last_component;
1441 while (*++name == '/'); 1461 /*
1442 if (!*name) 1462 * If it wasn't NUL, we know it was '/'. Skip that
1463 * slash, and continue until no more slashes.
1464 */
1465 do {
1466 len++;
1467 } while (unlikely(name[len] == '/'));
1468 if (!name[len])
1443 goto last_component; 1469 goto last_component;
1470 name += len;
1444 1471
1445 err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW); 1472 err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);
1446 if (err < 0) 1473 if (err < 0)
@@ -1773,24 +1800,21 @@ static struct dentry *lookup_hash(struct nameidata *nd)
1773struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) 1800struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
1774{ 1801{
1775 struct qstr this; 1802 struct qstr this;
1776 unsigned long hash;
1777 unsigned int c; 1803 unsigned int c;
1778 1804
1779 WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); 1805 WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
1780 1806
1781 this.name = name; 1807 this.name = name;
1782 this.len = len; 1808 this.len = len;
1809 this.hash = full_name_hash(name, len);
1783 if (!len) 1810 if (!len)
1784 return ERR_PTR(-EACCES); 1811 return ERR_PTR(-EACCES);
1785 1812
1786 hash = init_name_hash();
1787 while (len--) { 1813 while (len--) {
1788 c = *(const unsigned char *)name++; 1814 c = *(const unsigned char *)name++;
1789 if (c == '/' || c == '\0') 1815 if (c == '/' || c == '\0')
1790 return ERR_PTR(-EACCES); 1816 return ERR_PTR(-EACCES);
1791 hash = partial_name_hash(c, hash);
1792 } 1817 }
1793 this.hash = end_name_hash(hash);
1794 /* 1818 /*
1795 * See if the low-level filesystem might want 1819 * See if the low-level filesystem might want
1796 * to use its own hash.. 1820 * to use its own hash..