@@ -224,9 +224,10 @@ getname_kernel(const char * filename)
224
224
if (len <= EMBEDDED_NAME_MAX ) {
225
225
result -> name = (char * )result -> iname ;
226
226
} else if (len <= PATH_MAX ) {
227
+ const size_t size = offsetof(struct filename , iname [1 ]);
227
228
struct filename * tmp ;
228
229
229
- tmp = kmalloc (sizeof ( * tmp ) , GFP_KERNEL );
230
+ tmp = kmalloc (size , GFP_KERNEL );
230
231
if (unlikely (!tmp )) {
231
232
__putname (result );
232
233
return ERR_PTR (- ENOMEM );
@@ -1597,22 +1598,21 @@ static int lookup_fast(struct nameidata *nd,
1597
1598
}
1598
1599
1599
1600
/* Fast lookup failed, do it the slow way */
1600
- static struct dentry * lookup_slow (const struct qstr * name ,
1601
- struct dentry * dir ,
1602
- unsigned int flags )
1601
+ static struct dentry * __lookup_slow (const struct qstr * name ,
1602
+ struct dentry * dir ,
1603
+ unsigned int flags )
1603
1604
{
1604
- struct dentry * dentry = ERR_PTR ( - ENOENT ) , * old ;
1605
+ struct dentry * dentry , * old ;
1605
1606
struct inode * inode = dir -> d_inode ;
1606
1607
DECLARE_WAIT_QUEUE_HEAD_ONSTACK (wq );
1607
1608
1608
- inode_lock_shared (inode );
1609
1609
/* Don't go there if it's already dead */
1610
1610
if (unlikely (IS_DEADDIR (inode )))
1611
- goto out ;
1611
+ return ERR_PTR ( - ENOENT ) ;
1612
1612
again :
1613
1613
dentry = d_alloc_parallel (dir , name , & wq );
1614
1614
if (IS_ERR (dentry ))
1615
- goto out ;
1615
+ return dentry ;
1616
1616
if (unlikely (!d_in_lookup (dentry ))) {
1617
1617
if (!(flags & LOOKUP_NO_REVAL )) {
1618
1618
int error = d_revalidate (dentry , flags );
@@ -1634,11 +1634,21 @@ static struct dentry *lookup_slow(const struct qstr *name,
1634
1634
dentry = old ;
1635
1635
}
1636
1636
}
1637
- out :
1638
- inode_unlock_shared (inode );
1639
1637
return dentry ;
1640
1638
}
1641
1639
1640
+ static struct dentry * lookup_slow (const struct qstr * name ,
1641
+ struct dentry * dir ,
1642
+ unsigned int flags )
1643
+ {
1644
+ struct inode * inode = dir -> d_inode ;
1645
+ struct dentry * res ;
1646
+ inode_lock_shared (inode );
1647
+ res = __lookup_slow (name , dir , flags );
1648
+ inode_unlock_shared (inode );
1649
+ return res ;
1650
+ }
1651
+
1642
1652
static inline int may_lookup (struct nameidata * nd )
1643
1653
{
1644
1654
if (nd -> flags & LOOKUP_RCU ) {
@@ -2421,56 +2431,63 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
2421
2431
}
2422
2432
EXPORT_SYMBOL (vfs_path_lookup );
2423
2433
2424
- /**
2425
- * lookup_one_len - filesystem helper to lookup single pathname component
2426
- * @name: pathname component to lookup
2427
- * @base: base directory to lookup from
2428
- * @len: maximum length @len should be interpreted to
2429
- *
2430
- * Note that this routine is purely a helper for filesystem usage and should
2431
- * not be called by generic code.
2432
- *
2433
- * The caller must hold base->i_mutex.
2434
- */
2435
- struct dentry * lookup_one_len (const char * name , struct dentry * base , int len )
2434
+ static int lookup_one_len_common (const char * name , struct dentry * base ,
2435
+ int len , struct qstr * this )
2436
2436
{
2437
- struct qstr this ;
2438
- unsigned int c ;
2439
- int err ;
2440
-
2441
- WARN_ON_ONCE (!inode_is_locked (base -> d_inode ));
2442
-
2443
- this .name = name ;
2444
- this .len = len ;
2445
- this .hash = full_name_hash (base , name , len );
2437
+ this -> name = name ;
2438
+ this -> len = len ;
2439
+ this -> hash = full_name_hash (base , name , len );
2446
2440
if (!len )
2447
- return ERR_PTR ( - EACCES ) ;
2441
+ return - EACCES ;
2448
2442
2449
2443
if (unlikely (name [0 ] == '.' )) {
2450
2444
if (len < 2 || (len == 2 && name [1 ] == '.' ))
2451
- return ERR_PTR ( - EACCES ) ;
2445
+ return - EACCES ;
2452
2446
}
2453
2447
2454
2448
while (len -- ) {
2455
- c = * (const unsigned char * )name ++ ;
2449
+ unsigned int c = * (const unsigned char * )name ++ ;
2456
2450
if (c == '/' || c == '\0' )
2457
- return ERR_PTR ( - EACCES ) ;
2451
+ return - EACCES ;
2458
2452
}
2459
2453
/*
2460
2454
* See if the low-level filesystem might want
2461
2455
* to use its own hash..
2462
2456
*/
2463
2457
if (base -> d_flags & DCACHE_OP_HASH ) {
2464
- int err = base -> d_op -> d_hash (base , & this );
2458
+ int err = base -> d_op -> d_hash (base , this );
2465
2459
if (err < 0 )
2466
- return ERR_PTR ( err ) ;
2460
+ return err ;
2467
2461
}
2468
2462
2469
- err = inode_permission (base -> d_inode , MAY_EXEC );
2463
+ return inode_permission (base -> d_inode , MAY_EXEC );
2464
+ }
2465
+
2466
+ /**
2467
+ * lookup_one_len - filesystem helper to lookup single pathname component
2468
+ * @name: pathname component to lookup
2469
+ * @base: base directory to lookup from
2470
+ * @len: maximum length @len should be interpreted to
2471
+ *
2472
+ * Note that this routine is purely a helper for filesystem usage and should
2473
+ * not be called by generic code.
2474
+ *
2475
+ * The caller must hold base->i_mutex.
2476
+ */
2477
+ struct dentry * lookup_one_len (const char * name , struct dentry * base , int len )
2478
+ {
2479
+ struct dentry * dentry ;
2480
+ struct qstr this ;
2481
+ int err ;
2482
+
2483
+ WARN_ON_ONCE (!inode_is_locked (base -> d_inode ));
2484
+
2485
+ err = lookup_one_len_common (name , base , len , & this );
2470
2486
if (err )
2471
2487
return ERR_PTR (err );
2472
2488
2473
- return __lookup_hash (& this , base , 0 );
2489
+ dentry = lookup_dcache (& this , base , 0 );
2490
+ return dentry ? dentry : __lookup_slow (& this , base , 0 );
2474
2491
}
2475
2492
EXPORT_SYMBOL (lookup_one_len );
2476
2493
@@ -2490,37 +2507,10 @@ struct dentry *lookup_one_len_unlocked(const char *name,
2490
2507
struct dentry * base , int len )
2491
2508
{
2492
2509
struct qstr this ;
2493
- unsigned int c ;
2494
2510
int err ;
2495
2511
struct dentry * ret ;
2496
2512
2497
- this .name = name ;
2498
- this .len = len ;
2499
- this .hash = full_name_hash (base , name , len );
2500
- if (!len )
2501
- return ERR_PTR (- EACCES );
2502
-
2503
- if (unlikely (name [0 ] == '.' )) {
2504
- if (len < 2 || (len == 2 && name [1 ] == '.' ))
2505
- return ERR_PTR (- EACCES );
2506
- }
2507
-
2508
- while (len -- ) {
2509
- c = * (const unsigned char * )name ++ ;
2510
- if (c == '/' || c == '\0' )
2511
- return ERR_PTR (- EACCES );
2512
- }
2513
- /*
2514
- * See if the low-level filesystem might want
2515
- * to use its own hash..
2516
- */
2517
- if (base -> d_flags & DCACHE_OP_HASH ) {
2518
- int err = base -> d_op -> d_hash (base , & this );
2519
- if (err < 0 )
2520
- return ERR_PTR (err );
2521
- }
2522
-
2523
- err = inode_permission (base -> d_inode , MAY_EXEC );
2513
+ err = lookup_one_len_common (name , base , len , & this );
2524
2514
if (err )
2525
2515
return ERR_PTR (err );
2526
2516
0 commit comments