2006-01-16 16:50:04 +00:00
/*
* Copyright ( C ) Sistina Software , Inc . 1997 - 2003 All rights reserved .
2006-05-18 15:09:15 -04:00
* Copyright ( C ) 2004 - 2006 Red Hat , Inc . All rights reserved .
2006-01-16 16:50:04 +00:00
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2006-09-01 11:05:15 -04:00
* of the GNU General Public License version 2.
2006-01-16 16:50:04 +00:00
*/
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/spinlock.h>
# include <linux/completion.h>
# include <linux/buffer_head.h>
2009-10-02 11:50:54 +01:00
# include <linux/xattr.h>
2006-01-16 16:50:04 +00:00
# include <linux/posix_acl.h>
# include <linux/posix_acl_xattr.h>
2006-02-27 17:23:27 -05:00
# include <linux/gfs2_ondisk.h>
2006-01-16 16:50:04 +00:00
# include "gfs2.h"
2006-02-27 17:23:27 -05:00
# include "incore.h"
2006-01-16 16:50:04 +00:00
# include "acl.h"
2009-08-26 18:51:04 +01:00
# include "xattr.h"
2006-01-16 16:50:04 +00:00
# include "glock.h"
# include "inode.h"
# include "meta_io.h"
# include "trans.h"
2006-02-27 17:23:27 -05:00
# include "util.h"
2006-01-16 16:50:04 +00:00
2009-10-02 12:00:00 +01:00
static const char * gfs2_acl_name ( int type )
2006-01-16 16:50:04 +00:00
{
2009-10-02 12:00:00 +01:00
switch ( type ) {
case ACL_TYPE_ACCESS :
2015-12-02 14:44:35 +01:00
return XATTR_POSIX_ACL_ACCESS ;
2009-10-02 12:00:00 +01:00
case ACL_TYPE_DEFAULT :
2015-12-02 14:44:35 +01:00
return XATTR_POSIX_ACL_DEFAULT ;
2009-10-02 12:00:00 +01:00
}
return NULL ;
}
2006-01-16 16:50:04 +00:00
2011-11-23 13:31:51 +00:00
struct posix_acl * gfs2_get_acl ( struct inode * inode , int type )
2009-10-02 12:00:00 +01:00
{
2011-11-23 13:31:51 +00:00
struct gfs2_inode * ip = GFS2_I ( inode ) ;
2009-10-02 12:00:00 +01:00
struct posix_acl * acl ;
const char * name ;
char * data ;
int len ;
2009-08-26 18:41:32 +01:00
2008-11-03 14:28:42 +00:00
if ( ! ip - > i_eattr )
2009-10-02 12:00:00 +01:00
return NULL ;
2006-01-16 16:50:04 +00:00
2009-10-02 12:00:00 +01:00
name = gfs2_acl_name ( type ) ;
if ( name = = NULL )
return ERR_PTR ( - EINVAL ) ;
2006-01-16 16:50:04 +00:00
2009-10-02 12:00:00 +01:00
len = gfs2_xattr_acl_get ( ip , name , & data ) ;
if ( len < 0 )
return ERR_PTR ( len ) ;
if ( len = = 0 )
return NULL ;
2006-01-16 16:50:04 +00:00
2012-09-10 20:17:44 -07:00
acl = posix_acl_from_xattr ( & init_user_ns , data , len ) ;
2009-10-02 12:00:00 +01:00
kfree ( data ) ;
return acl ;
2006-01-16 16:50:04 +00:00
}
2013-12-20 05:16:52 -08:00
int gfs2_set_acl ( struct inode * inode , struct posix_acl * acl , int type )
2006-01-16 16:50:04 +00:00
{
int error ;
2009-10-02 12:00:00 +01:00
int len ;
char * data ;
const char * name = gfs2_acl_name ( type ) ;
BUG_ON ( name = = NULL ) ;
2011-07-23 03:10:32 -04:00
2015-02-09 12:53:04 -05:00
if ( acl & & acl - > a_count > GFS2_ACL_MAX_ENTRIES ( GFS2_SB ( inode ) ) )
2014-03-04 11:28:39 +08:00
return - E2BIG ;
2009-10-02 11:50:54 +01:00
if ( type = = ACL_TYPE_ACCESS ) {
2011-07-23 18:56:36 -04:00
umode_t mode = inode - > i_mode ;
2013-12-20 05:16:52 -08:00
2009-10-02 11:50:54 +01:00
error = posix_acl_equiv_mode ( acl , & mode ) ;
2013-12-20 05:16:52 -08:00
if ( error < 0 )
return error ;
2009-10-02 11:50:54 +01:00
2013-12-20 05:16:52 -08:00
if ( error = = 0 )
2009-10-02 11:50:54 +01:00
acl = NULL ;
2014-03-19 11:51:28 -04:00
if ( mode ! = inode - > i_mode ) {
inode - > i_mode = mode ;
mark_inode_dirty ( inode ) ;
}
2009-10-02 11:50:54 +01:00
}
2013-12-20 05:16:52 -08:00
if ( acl ) {
len = posix_acl_to_xattr ( & init_user_ns , acl , NULL , 0 ) ;
if ( len = = 0 )
return 0 ;
data = kmalloc ( len , GFP_NOFS ) ;
if ( data = = NULL )
return - ENOMEM ;
error = posix_acl_to_xattr ( & init_user_ns , acl , data , len ) ;
if ( error < 0 )
goto out ;
} else {
data = NULL ;
len = 0 ;
2009-09-29 16:26:23 +01:00
}
2013-12-20 05:16:52 -08:00
error = __gfs2_xattr_set ( inode , name , data , len , 0 , GFS2_EATYPE_SYS ) ;
if ( error )
goto out ;
2015-02-13 12:16:37 -06:00
set_cached_acl ( inode , type , acl ) ;
2009-10-02 11:50:54 +01:00
out :
2013-12-20 05:16:52 -08:00
kfree ( data ) ;
2009-10-02 11:50:54 +01:00
return error ;
}