2001-10-22 18:39:12 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2013-06-03 01:27:34 +04:00
* Copyright ( C ) 2004 - 2013 Red Hat , Inc . All rights reserved .
2001-10-22 18:39:12 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-10-22 18:39:12 +04:00
*/
2002-11-18 17:01:16 +03:00
# include "lib.h"
2013-08-14 02:26:58 +04:00
# include "filter.h"
2001-10-22 18:39:12 +04:00
static int _and_p ( struct dev_filter * f , struct device * dev )
{
2013-06-03 10:38:07 +04:00
struct dev_filter * * filters ;
2001-10-22 18:39:12 +04:00
2013-06-03 10:38:07 +04:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters )
2001-10-22 18:39:12 +04:00
if ( ! ( * filters ) - > passes_filter ( * filters , dev ) )
2013-08-14 02:26:58 +04:00
return 0 ; /* No 'stack': a filter, not an error. */
2003-01-08 19:41:22 +03:00
2001-10-22 18:39:12 +04:00
return 1 ;
}
2014-12-15 17:12:42 +03:00
static int _and_p_with_dev_ext_info ( struct dev_filter * f , struct device * dev )
{
int r ;
2014-12-15 18:27:33 +03:00
dev_ext_enable ( dev , external_device_info_source ( ) ) ;
2014-12-15 17:12:42 +03:00
r = _and_p ( f , dev ) ;
dev_ext_disable ( dev ) ;
return r ;
}
2006-04-19 19:33:07 +04:00
static void _composite_destroy ( struct dev_filter * f )
2001-10-22 18:39:12 +04:00
{
2013-06-03 10:38:07 +04:00
struct dev_filter * * filters ;
2001-10-22 18:39:12 +04:00
2010-09-22 05:36:13 +04:00
if ( f - > use_count )
log_error ( INTERNAL_ERROR " Destroying composite filter while in use %u times. " , f - > use_count ) ;
2013-06-03 10:38:07 +04:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters )
2001-10-22 18:39:12 +04:00
( * filters ) - > destroy ( * filters ) ;
2005-10-17 03:03:59 +04:00
dm_free ( f - > private ) ;
dm_free ( f ) ;
2001-10-22 18:39:12 +04:00
}
2018-01-02 23:40:18 +03:00
static int _dump ( struct dev_filter * f , struct dm_pool * mem , int merge_existing )
2013-05-27 02:49:40 +04:00
{
2013-06-03 01:27:34 +04:00
struct dev_filter * * filters ;
2013-05-27 02:49:40 +04:00
2013-06-03 01:27:34 +04:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters )
if ( ( * filters ) - > dump & &
2018-01-02 23:40:18 +03:00
! ( * filters ) - > dump ( * filters , mem , merge_existing ) )
2013-06-03 01:27:34 +04:00
return_0 ;
return 1 ;
2013-05-27 02:49:40 +04:00
}
2013-06-02 23:59:57 +04:00
static void _wipe ( struct dev_filter * f )
{
struct dev_filter * * filters ;
2013-06-03 10:38:07 +04:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters )
2013-06-02 23:59:57 +04:00
if ( ( * filters ) - > wipe )
( * filters ) - > wipe ( * filters ) ;
}
2014-12-15 17:12:42 +03:00
struct dev_filter * composite_filter_create ( int n , int use_dev_ext_info , struct dev_filter * * filters )
2001-10-22 18:39:12 +04:00
{
2004-05-04 22:28:15 +04:00
struct dev_filter * * filters_copy , * cft ;
2001-10-22 18:39:12 +04:00
2008-01-30 16:19:47 +03:00
if ( ! filters )
return_NULL ;
2001-10-22 18:39:12 +04:00
2005-10-17 03:03:59 +04:00
if ( ! ( filters_copy = dm_malloc ( sizeof ( * filters ) * ( n + 1 ) ) ) ) {
2013-06-03 10:38:07 +04:00
log_error ( " Composite filters allocation failed. " ) ;
2001-10-22 18:39:12 +04:00
return NULL ;
}
2004-02-13 17:46:04 +03:00
memcpy ( filters_copy , filters , sizeof ( * filters ) * n ) ;
filters_copy [ n ] = NULL ;
2012-08-18 20:59:07 +04:00
if ( ! ( cft = dm_zalloc ( sizeof ( * cft ) ) ) ) {
2013-06-03 10:38:07 +04:00
log_error ( " Composite filters allocation failed. " ) ;
2005-10-17 03:03:59 +04:00
dm_free ( filters_copy ) ;
2004-02-13 17:46:04 +03:00
return NULL ;
2001-10-22 18:39:12 +04:00
}
2014-12-15 17:12:42 +03:00
cft - > passes_filter = use_dev_ext_info ? _and_p_with_dev_ext_info : _and_p ;
2006-04-19 19:33:07 +04:00
cft - > destroy = _composite_destroy ;
2013-05-27 02:49:40 +04:00
cft - > dump = _dump ;
2013-06-02 23:59:57 +04:00
cft - > wipe = _wipe ;
2010-09-22 05:36:13 +04:00
cft - > use_count = 0 ;
2004-05-04 22:28:15 +04:00
cft - > private = filters_copy ;
2001-10-22 18:39:12 +04:00
2013-08-14 02:26:58 +04:00
log_debug_devs ( " Composite filter initialised. " ) ;
2004-05-04 22:28:15 +04:00
return cft ;
2001-10-22 18:39:12 +04:00
}