@@ -310,6 +310,7 @@ static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
310
310
* @name: name of dentry to create
311
311
* @parent: parent directory for this dentry
312
312
* @target: if symlink, symlink target string
313
+ * @private: private data
313
314
* @iops: struct of inode_operations that should be used
314
315
*
315
316
* If @target parameter is %NULL, then the @iops parameter needs to be
@@ -318,17 +319,17 @@ static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
318
319
static struct dentry * aafs_create_symlink (const char * name ,
319
320
struct dentry * parent ,
320
321
const char * target ,
322
+ void * private ,
321
323
const struct inode_operations * iops )
322
324
{
323
325
struct dentry * dent ;
324
326
char * link = NULL ;
325
327
326
328
if (target ) {
327
- link = kstrdup (target , GFP_KERNEL );
328
329
if (!link )
329
330
return ERR_PTR (- ENOMEM );
330
331
}
331
- dent = aafs_create (name , S_IFLNK | 0444 , parent , NULL , link , NULL ,
332
+ dent = aafs_create (name , S_IFLNK | 0444 , parent , private , link , NULL ,
332
333
iops );
333
334
if (IS_ERR (dent ))
334
335
kfree (link );
@@ -1479,26 +1480,95 @@ static int profile_depth(struct aa_profile *profile)
1479
1480
return depth ;
1480
1481
}
1481
1482
1482
- static int gen_symlink_name (char * buffer , size_t bsize , int depth ,
1483
- const char * dirname , const char * fname )
1483
+ static char * gen_symlink_name (int depth , const char * dirname , const char * fname )
1484
1484
{
1485
+ char * buffer , * s ;
1485
1486
int error ;
1487
+ int size = depth * 6 + strlen (dirname ) + strlen (fname ) + 11 ;
1488
+
1489
+ s = buffer = kmalloc (size , GFP_KERNEL );
1490
+ if (!buffer )
1491
+ return ERR_PTR (- ENOMEM );
1486
1492
1487
1493
for (; depth > 0 ; depth -- ) {
1488
- if (bsize < 7 )
1489
- return - ENAMETOOLONG ;
1490
- strcpy (buffer , "../../" );
1491
- buffer += 6 ;
1492
- bsize -= 6 ;
1494
+ strcpy (s , "../../" );
1495
+ s += 6 ;
1496
+ size -= 6 ;
1493
1497
}
1494
1498
1495
- error = snprintf (buffer , bsize , "raw_data/%s/%s" , dirname , fname );
1496
- if (error >= bsize || error < 0 )
1497
- return - ENAMETOOLONG ;
1499
+ error = snprintf (s , size , "raw_data/%s/%s" , dirname , fname );
1500
+ if (error >= size || error < 0 )
1501
+ return ERR_PTR ( - ENAMETOOLONG ) ;
1498
1502
1499
- return 0 ;
1503
+ return buffer ;
1504
+ }
1505
+
1506
+ static void rawdata_link_cb (void * arg )
1507
+ {
1508
+ kfree (arg );
1509
+ }
1510
+
1511
+ static const char * rawdata_get_link_base (struct dentry * dentry ,
1512
+ struct inode * inode ,
1513
+ struct delayed_call * done ,
1514
+ const char * name )
1515
+ {
1516
+ struct aa_proxy * proxy = inode -> i_private ;
1517
+ struct aa_label * label ;
1518
+ struct aa_profile * profile ;
1519
+ char * target ;
1520
+ int depth ;
1521
+
1522
+ if (!dentry )
1523
+ return ERR_PTR (- ECHILD );
1524
+
1525
+ label = aa_get_label_rcu (& proxy -> label );
1526
+ profile = labels_profile (label );
1527
+ depth = profile_depth (profile );
1528
+ target = gen_symlink_name (depth , profile -> rawdata -> name , name );
1529
+ aa_put_label (label );
1530
+
1531
+ if (IS_ERR (target ))
1532
+ return target ;
1533
+
1534
+ set_delayed_call (done , rawdata_link_cb , target );
1535
+
1536
+ return target ;
1500
1537
}
1501
1538
1539
+ static const char * rawdata_get_link_sha1 (struct dentry * dentry ,
1540
+ struct inode * inode ,
1541
+ struct delayed_call * done )
1542
+ {
1543
+ return rawdata_get_link_base (dentry , inode , done , "sha1" );
1544
+ }
1545
+
1546
+ static const char * rawdata_get_link_abi (struct dentry * dentry ,
1547
+ struct inode * inode ,
1548
+ struct delayed_call * done )
1549
+ {
1550
+ return rawdata_get_link_base (dentry , inode , done , "abi" );
1551
+ }
1552
+
1553
+ static const char * rawdata_get_link_data (struct dentry * dentry ,
1554
+ struct inode * inode ,
1555
+ struct delayed_call * done )
1556
+ {
1557
+ return rawdata_get_link_base (dentry , inode , done , "raw_data" );
1558
+ }
1559
+
1560
+ static const struct inode_operations rawdata_link_sha1_iops = {
1561
+ .get_link = rawdata_get_link_sha1 ,
1562
+ };
1563
+
1564
+ static const struct inode_operations rawdata_link_abi_iops = {
1565
+ .get_link = rawdata_get_link_abi ,
1566
+ };
1567
+ static const struct inode_operations rawdata_link_data_iops = {
1568
+ .get_link = rawdata_get_link_data ,
1569
+ };
1570
+
1571
+
1502
1572
/*
1503
1573
* Requires: @profile->ns->lock held
1504
1574
*/
@@ -1569,34 +1639,28 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
1569
1639
}
1570
1640
1571
1641
if (profile -> rawdata ) {
1572
- char target [64 ];
1573
- int depth = profile_depth (profile );
1574
-
1575
- error = gen_symlink_name (target , sizeof (target ), depth ,
1576
- profile -> rawdata -> name , "sha1" );
1577
- if (error < 0 )
1578
- goto fail2 ;
1579
- dent = aafs_create_symlink ("raw_sha1" , dir , target , NULL );
1642
+ dent = aafs_create_symlink ("raw_sha1" , dir , NULL ,
1643
+ profile -> label .proxy ,
1644
+ & rawdata_link_sha1_iops );
1580
1645
if (IS_ERR (dent ))
1581
1646
goto fail ;
1647
+ aa_get_proxy (profile -> label .proxy );
1582
1648
profile -> dents [AAFS_PROF_RAW_HASH ] = dent ;
1583
1649
1584
- error = gen_symlink_name (target , sizeof (target ), depth ,
1585
- profile -> rawdata -> name , "abi" );
1586
- if (error < 0 )
1587
- goto fail2 ;
1588
- dent = aafs_create_symlink ("raw_abi" , dir , target , NULL );
1650
+ dent = aafs_create_symlink ("raw_abi" , dir , NULL ,
1651
+ profile -> label .proxy ,
1652
+ & rawdata_link_abi_iops );
1589
1653
if (IS_ERR (dent ))
1590
1654
goto fail ;
1655
+ aa_get_proxy (profile -> label .proxy );
1591
1656
profile -> dents [AAFS_PROF_RAW_ABI ] = dent ;
1592
1657
1593
- error = gen_symlink_name (target , sizeof (target ), depth ,
1594
- profile -> rawdata -> name , "raw_data" );
1595
- if (error < 0 )
1596
- goto fail2 ;
1597
- dent = aafs_create_symlink ("raw_data" , dir , target , NULL );
1658
+ dent = aafs_create_symlink ("raw_data" , dir , NULL ,
1659
+ profile -> label .proxy ,
1660
+ & rawdata_link_data_iops );
1598
1661
if (IS_ERR (dent ))
1599
1662
goto fail ;
1663
+ aa_get_proxy (profile -> label .proxy );
1600
1664
profile -> dents [AAFS_PROF_RAW_DATA ] = dent ;
1601
1665
}
1602
1666
0 commit comments