@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
293293 return sh ;
294294}
295295
296- static int grow_stripes (raid5_conf_t * conf , int num )
296+ static int grow_one_stripe (raid5_conf_t * conf )
297297{
298298 struct stripe_head * sh ;
299+ sh = kmem_cache_alloc (conf -> slab_cache , GFP_KERNEL );
300+ if (!sh )
301+ return 0 ;
302+ memset (sh , 0 , sizeof (* sh ) + (conf -> raid_disks - 1 )* sizeof (struct r5dev ));
303+ sh -> raid_conf = conf ;
304+ spin_lock_init (& sh -> lock );
305+
306+ if (grow_buffers (sh , conf -> raid_disks )) {
307+ shrink_buffers (sh , conf -> raid_disks );
308+ kmem_cache_free (conf -> slab_cache , sh );
309+ return 0 ;
310+ }
311+ /* we just created an active stripe so... */
312+ atomic_set (& sh -> count , 1 );
313+ atomic_inc (& conf -> active_stripes );
314+ INIT_LIST_HEAD (& sh -> lru );
315+ release_stripe (sh );
316+ return 1 ;
317+ }
318+
319+ static int grow_stripes (raid5_conf_t * conf , int num )
320+ {
299321 kmem_cache_t * sc ;
300322 int devs = conf -> raid_disks ;
301323
@@ -308,43 +330,34 @@ static int grow_stripes(raid5_conf_t *conf, int num)
308330 return 1 ;
309331 conf -> slab_cache = sc ;
310332 while (num -- ) {
311- sh = kmem_cache_alloc (sc , GFP_KERNEL );
312- if (!sh )
313- return 1 ;
314- memset (sh , 0 , sizeof (* sh ) + (devs - 1 )* sizeof (struct r5dev ));
315- sh -> raid_conf = conf ;
316- spin_lock_init (& sh -> lock );
317-
318- if (grow_buffers (sh , conf -> raid_disks )) {
319- shrink_buffers (sh , conf -> raid_disks );
320- kmem_cache_free (sc , sh );
333+ if (!grow_one_stripe (conf ))
321334 return 1 ;
322- }
323- /* we just created an active stripe so... */
324- atomic_set (& sh -> count , 1 );
325- atomic_inc (& conf -> active_stripes );
326- INIT_LIST_HEAD (& sh -> lru );
327- release_stripe (sh );
328335 }
329336 return 0 ;
330337}
331338
332- static void shrink_stripes (raid5_conf_t * conf )
339+ static int drop_one_stripe (raid5_conf_t * conf )
333340{
334341 struct stripe_head * sh ;
335342
336- while (1 ) {
337- spin_lock_irq (& conf -> device_lock );
338- sh = get_free_stripe (conf );
339- spin_unlock_irq (& conf -> device_lock );
340- if (!sh )
341- break ;
342- if (atomic_read (& sh -> count ))
343- BUG ();
344- shrink_buffers (sh , conf -> raid_disks );
345- kmem_cache_free (conf -> slab_cache , sh );
346- atomic_dec (& conf -> active_stripes );
347- }
343+ spin_lock_irq (& conf -> device_lock );
344+ sh = get_free_stripe (conf );
345+ spin_unlock_irq (& conf -> device_lock );
346+ if (!sh )
347+ return 0 ;
348+ if (atomic_read (& sh -> count ))
349+ BUG ();
350+ shrink_buffers (sh , conf -> raid_disks );
351+ kmem_cache_free (conf -> slab_cache , sh );
352+ atomic_dec (& conf -> active_stripes );
353+ return 1 ;
354+ }
355+
356+ static void shrink_stripes (raid5_conf_t * conf )
357+ {
358+ while (drop_one_stripe (conf ))
359+ ;
360+
348361 kmem_cache_destroy (conf -> slab_cache );
349362 conf -> slab_cache = NULL ;
350363}
@@ -1714,6 +1727,108 @@ static void raid5d (mddev_t *mddev)
17141727 PRINTK ("--- raid5d inactive\n" );
17151728}
17161729
1730+ struct raid5_sysfs_entry {
1731+ struct attribute attr ;
1732+ ssize_t (* show )(raid5_conf_t * , char * );
1733+ ssize_t (* store )(raid5_conf_t * , const char * , ssize_t );
1734+ };
1735+
1736+ static ssize_t
1737+ raid5_show_stripe_cache_size (raid5_conf_t * conf , char * page )
1738+ {
1739+ return sprintf (page , "%d\n" , conf -> max_nr_stripes );
1740+ }
1741+
1742+ static ssize_t
1743+ raid5_store_stripe_cache_size (raid5_conf_t * conf , const char * page , ssize_t len )
1744+ {
1745+ char * end ;
1746+ int new ;
1747+ if (len >= PAGE_SIZE )
1748+ return - EINVAL ;
1749+
1750+ new = simple_strtoul (page , & end , 10 );
1751+ if (!* page || (* end && * end != '\n' ) )
1752+ return - EINVAL ;
1753+ if (new <= 16 || new > 32768 )
1754+ return - EINVAL ;
1755+ while (new < conf -> max_nr_stripes ) {
1756+ if (drop_one_stripe (conf ))
1757+ conf -> max_nr_stripes -- ;
1758+ else
1759+ break ;
1760+ }
1761+ while (new > conf -> max_nr_stripes ) {
1762+ if (grow_one_stripe (conf ))
1763+ conf -> max_nr_stripes ++ ;
1764+ else break ;
1765+ }
1766+ return len ;
1767+ }
1768+ static struct raid5_sysfs_entry raid5_stripecache_size = {
1769+ .attr = {.name = "stripe_cache_size" , .mode = S_IRUGO | S_IWUSR },
1770+ .show = raid5_show_stripe_cache_size ,
1771+ .store = raid5_store_stripe_cache_size ,
1772+ };
1773+
1774+ static ssize_t
1775+ raid5_show_stripe_cache_active (raid5_conf_t * conf , char * page )
1776+ {
1777+ return sprintf (page , "%d\n" , atomic_read (& conf -> active_stripes ));
1778+ }
1779+
1780+ static struct raid5_sysfs_entry raid5_stripecache_active = {
1781+ .attr = {.name = "stripe_cache_active" , .mode = S_IRUGO },
1782+ .show = raid5_show_stripe_cache_active ,
1783+ };
1784+
1785+ static struct attribute * raid5_default_attrs [] = {
1786+ & raid5_stripecache_size .attr ,
1787+ & raid5_stripecache_active .attr ,
1788+ NULL ,
1789+ };
1790+
1791+ static ssize_t
1792+ raid5_attr_show (struct kobject * kobj , struct attribute * attr , char * page )
1793+ {
1794+ struct raid5_sysfs_entry * entry = container_of (attr , struct raid5_sysfs_entry , attr );
1795+ raid5_conf_t * conf = container_of (kobj , raid5_conf_t , kobj );
1796+
1797+ if (!entry -> show )
1798+ return - EIO ;
1799+ return entry -> show (conf , page );
1800+ }
1801+
1802+ static ssize_t
1803+ raid5_attr_store (struct kobject * kobj , struct attribute * attr ,
1804+ const char * page , size_t length )
1805+ {
1806+ struct raid5_sysfs_entry * entry = container_of (attr , struct raid5_sysfs_entry , attr );
1807+ raid5_conf_t * conf = container_of (kobj , raid5_conf_t , kobj );
1808+
1809+ if (!entry -> store )
1810+ return - EIO ;
1811+ return entry -> store (conf , page , length );
1812+ }
1813+
1814+ static void raid5_free (struct kobject * ko )
1815+ {
1816+ raid5_conf_t * conf = container_of (ko , raid5_conf_t , kobj );
1817+ kfree (conf );
1818+ }
1819+
1820+
1821+ static struct sysfs_ops raid5_sysfs_ops = {
1822+ .show = raid5_attr_show ,
1823+ .store = raid5_attr_store ,
1824+ };
1825+
1826+ static struct kobj_type raid5_ktype = {
1827+ .release = raid5_free ,
1828+ .sysfs_ops = & raid5_sysfs_ops ,
1829+ .default_attrs = raid5_default_attrs ,
1830+ };
1831+
17171832static int run (mddev_t * mddev )
17181833{
17191834 raid5_conf_t * conf ;
@@ -1855,6 +1970,10 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
18551970 }
18561971
18571972 /* Ok, everything is just fine now */
1973+ conf -> kobj .parent = kobject_get (& mddev -> kobj );
1974+ strcpy (conf -> kobj .name , "raid5" );
1975+ conf -> kobj .ktype = & raid5_ktype ;
1976+ kobject_register (& conf -> kobj );
18581977
18591978 if (mddev -> bitmap )
18601979 mddev -> thread -> timeout = mddev -> bitmap -> daemon_sleep * HZ ;
@@ -1879,7 +1998,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
18791998
18801999
18812000
1882- static int stop (mddev_t * mddev )
2001+ static int stop (mddev_t * mddev )
18832002{
18842003 raid5_conf_t * conf = (raid5_conf_t * ) mddev -> private ;
18852004
@@ -1888,7 +2007,7 @@ static int stop (mddev_t *mddev)
18882007 shrink_stripes (conf );
18892008 free_pages ((unsigned long ) conf -> stripe_hashtbl , HASH_PAGES_ORDER );
18902009 blk_sync_queue (mddev -> queue ); /* the unplug fn references 'conf'*/
1891- kfree ( conf );
2010+ kobject_unregister ( & conf -> kobj );
18922011 mddev -> private = NULL ;
18932012 return 0 ;
18942013}
0 commit comments