2006-07-04 04:27:12 +04:00
/*
* linux / fs / ocfs2 / ioctl . c
*
* Copyright ( C ) 2006 Herbert Poetzl
* adapted from Remy Card ' s ext2 / ioctl . c
*/
# include <linux/fs.h>
# include <linux/mount.h>
2014-01-22 03:48:34 +04:00
# include <linux/blkdev.h>
2010-01-27 05:21:52 +03:00
# include <linux/compat.h>
2006-07-04 04:27:12 +04:00
# include <cluster/masklog.h>
# include "ocfs2.h"
# include "alloc.h"
# include "dlmglue.h"
2007-03-10 03:53:21 +03:00
# include "file.h"
2006-07-04 04:27:12 +04:00
# include "inode.h"
# include "journal.h"
# include "ocfs2_fs.h"
2006-07-10 03:32:51 +04:00
# include "ioctl.h"
2007-12-18 10:47:03 +03:00
# include "resize.h"
2009-09-21 07:25:14 +04:00
# include "refcounttree.h"
2011-05-24 11:25:54 +04:00
# include "sysfile.h"
# include "dir.h"
# include "buffer_head_io.h"
2011-05-24 11:27:17 +04:00
# include "suballoc.h"
2011-05-25 10:23:43 +04:00
# include "move_extents.h"
2006-07-10 03:32:51 +04:00
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
# define o2info_from_user(a, b) \
copy_from_user ( & ( a ) , ( b ) , sizeof ( a ) )
# define o2info_to_user(a, b) \
copy_to_user ( ( typeof ( a ) __user * ) b , & ( a ) , sizeof ( a ) )
/*
* This call is void because we are already reporting an error that may
* be - EFAULT . The error will be returned from the ioctl ( 2 ) call . It ' s
* just a best - effort to tell userspace that this request caused the error .
*/
2011-05-24 11:22:59 +04:00
static inline void o2info_set_request_error ( struct ocfs2_info_request * kreq ,
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
struct ocfs2_info_request __user * req )
{
kreq - > ir_flags | = OCFS2_INFO_FL_ERROR ;
( void ) put_user ( kreq - > ir_flags , ( __u32 __user * ) & ( req - > ir_flags ) ) ;
}
2011-05-24 11:22:59 +04:00
static inline void o2info_set_request_filled ( struct ocfs2_info_request * req )
2011-01-30 09:25:59 +03:00
{
req - > ir_flags | = OCFS2_INFO_FL_FILLED ;
}
2011-05-24 11:22:59 +04:00
static inline void o2info_clear_request_filled ( struct ocfs2_info_request * req )
2011-01-30 09:25:59 +03:00
{
req - > ir_flags & = ~ OCFS2_INFO_FL_FILLED ;
}
2011-05-24 11:25:54 +04:00
static inline int o2info_coherent ( struct ocfs2_info_request * req )
{
return ( ! ( req - > ir_flags & OCFS2_INFO_FL_NON_COHERENT ) ) ;
}
2011-01-30 09:25:59 +03:00
2006-07-04 04:27:12 +04:00
static int ocfs2_get_inode_attr ( struct inode * inode , unsigned * flags )
{
int status ;
2007-10-19 02:30:42 +04:00
status = ocfs2_inode_lock ( inode , NULL , 0 ) ;
2006-07-04 04:27:12 +04:00
if ( status < 0 ) {
mlog_errno ( status ) ;
return status ;
}
2007-04-27 22:08:01 +04:00
ocfs2_get_inode_flags ( OCFS2_I ( inode ) ) ;
2006-07-04 04:27:12 +04:00
* flags = OCFS2_I ( inode ) - > ip_attr ;
2007-10-19 02:30:42 +04:00
ocfs2_inode_unlock ( inode , 0 ) ;
2006-07-04 04:27:12 +04:00
return status ;
}
static int ocfs2_set_inode_attr ( struct inode * inode , unsigned flags ,
unsigned mask )
{
struct ocfs2_inode_info * ocfs2_inode = OCFS2_I ( inode ) ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
2006-10-10 05:11:45 +04:00
handle_t * handle = NULL ;
2006-07-04 04:27:12 +04:00
struct buffer_head * bh = NULL ;
unsigned oldflags ;
int status ;
mutex_lock ( & inode - > i_mutex ) ;
2007-10-19 02:30:42 +04:00
status = ocfs2_inode_lock ( inode , & bh , 1 ) ;
2006-07-04 04:27:12 +04:00
if ( status < 0 ) {
mlog_errno ( status ) ;
goto bail ;
}
status = - EACCES ;
2011-03-24 02:43:26 +03:00
if ( ! inode_owner_or_capable ( inode ) )
2006-07-04 04:27:12 +04:00
goto bail_unlock ;
if ( ! S_ISDIR ( inode - > i_mode ) )
flags & = ~ OCFS2_DIRSYNC_FL ;
oldflags = ocfs2_inode - > ip_attr ;
flags = flags & mask ;
flags | = oldflags & ~ mask ;
/*
* The IMMUTABLE and APPEND_ONLY flags can only be changed by
* the relevant capability .
*/
status = - EPERM ;
if ( ( oldflags & OCFS2_IMMUTABLE_FL ) | | ( ( flags ^ oldflags ) &
( OCFS2_APPEND_FL | OCFS2_IMMUTABLE_FL ) ) ) {
if ( ! capable ( CAP_LINUX_IMMUTABLE ) )
2013-04-30 02:05:56 +04:00
goto bail_unlock ;
}
handle = ocfs2_start_trans ( osb , OCFS2_INODE_UPDATE_CREDITS ) ;
if ( IS_ERR ( handle ) ) {
status = PTR_ERR ( handle ) ;
mlog_errno ( status ) ;
goto bail_unlock ;
2006-07-04 04:27:12 +04:00
}
ocfs2_inode - > ip_attr = flags ;
ocfs2_set_inode_flags ( inode ) ;
status = ocfs2_mark_inode_dirty ( handle , inode , bh ) ;
if ( status < 0 )
mlog_errno ( status ) ;
2006-10-10 03:48:10 +04:00
ocfs2_commit_trans ( osb , handle ) ;
2013-04-30 02:05:56 +04:00
2006-07-04 04:27:12 +04:00
bail_unlock :
2007-10-19 02:30:42 +04:00
ocfs2_inode_unlock ( inode , 1 ) ;
2006-07-04 04:27:12 +04:00
bail :
mutex_unlock ( & inode - > i_mutex ) ;
2008-10-08 01:25:16 +04:00
brelse ( bh ) ;
2006-07-04 04:27:12 +04:00
return status ;
}
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
int ocfs2_info_handle_blocksize ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_blocksize oib ;
if ( o2info_from_user ( oib , req ) )
goto bail ;
oib . ib_blocksize = inode - > i_sb - > s_blocksize ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oib . ib_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oib , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oib . ib_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_clustersize ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_clustersize oic ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oic , req ) )
goto bail ;
oic . ic_clustersize = osb - > s_clustersize ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oic . ic_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oic , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oic . ic_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_maxslots ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_maxslots oim ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oim , req ) )
goto bail ;
oim . im_max_slots = osb - > max_slots ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oim . im_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oim , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oim . im_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_label ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_label oil ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oil , req ) )
goto bail ;
memcpy ( oil . il_label , osb - > vol_label , OCFS2_MAX_VOL_LABEL_LEN ) ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oil . il_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oil , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oil . il_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_uuid ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_uuid oiu ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oiu , req ) )
goto bail ;
memcpy ( oiu . iu_uuid_str , osb - > uuid_str , OCFS2_TEXT_UUID_LEN + 1 ) ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oiu . iu_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oiu , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oiu . iu_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_fs_features ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_fs_features oif ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oif , req ) )
goto bail ;
oif . if_compat_features = osb - > s_feature_compat ;
oif . if_incompat_features = osb - > s_feature_incompat ;
oif . if_ro_compat_features = osb - > s_feature_ro_compat ;
2011-01-30 09:25:59 +03:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oif . if_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oif , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oif . if_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_journal_size ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_journal_size oij ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
if ( o2info_from_user ( oij , req ) )
goto bail ;
2013-09-12 01:19:45 +04:00
oij . ij_journal_size = i_size_read ( osb - > journal - > j_inode ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
2011-05-24 11:22:59 +04:00
o2info_set_request_filled ( & oij . ij_req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oij , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oij . ij_req , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
2011-05-24 11:25:54 +04:00
int ocfs2_info_scan_inode_alloc ( struct ocfs2_super * osb ,
struct inode * inode_alloc , u64 blkno ,
struct ocfs2_info_freeinode * fi , u32 slot )
{
int status = 0 , unlock = 0 ;
struct buffer_head * bh = NULL ;
struct ocfs2_dinode * dinode_alloc = NULL ;
if ( inode_alloc )
mutex_lock ( & inode_alloc - > i_mutex ) ;
if ( o2info_coherent ( & fi - > ifi_req ) ) {
status = ocfs2_inode_lock ( inode_alloc , & bh , 0 ) ;
if ( status < 0 ) {
mlog_errno ( status ) ;
goto bail ;
}
unlock = 1 ;
} else {
status = ocfs2_read_blocks_sync ( osb , blkno , 1 , & bh ) ;
if ( status < 0 ) {
mlog_errno ( status ) ;
goto bail ;
}
}
dinode_alloc = ( struct ocfs2_dinode * ) bh - > b_data ;
fi - > ifi_stat [ slot ] . lfi_total =
le32_to_cpu ( dinode_alloc - > id1 . bitmap1 . i_total ) ;
fi - > ifi_stat [ slot ] . lfi_free =
le32_to_cpu ( dinode_alloc - > id1 . bitmap1 . i_total ) -
le32_to_cpu ( dinode_alloc - > id1 . bitmap1 . i_used ) ;
bail :
if ( unlock )
ocfs2_inode_unlock ( inode_alloc , 0 ) ;
if ( inode_alloc )
mutex_unlock ( & inode_alloc - > i_mutex ) ;
brelse ( bh ) ;
return status ;
}
int ocfs2_info_handle_freeinode ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
u32 i ;
u64 blkno = - 1 ;
char namebuf [ 40 ] ;
int status = - EFAULT , type = INODE_ALLOC_SYSTEM_INODE ;
struct ocfs2_info_freeinode * oifi = NULL ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
struct inode * inode_alloc = NULL ;
oifi = kzalloc ( sizeof ( struct ocfs2_info_freeinode ) , GFP_KERNEL ) ;
if ( ! oifi ) {
status = - ENOMEM ;
mlog_errno ( status ) ;
2011-05-29 23:57:16 +04:00
goto out_err ;
2011-05-24 11:25:54 +04:00
}
if ( o2info_from_user ( * oifi , req ) )
goto bail ;
oifi - > ifi_slotnum = osb - > max_slots ;
for ( i = 0 ; i < oifi - > ifi_slotnum ; i + + ) {
if ( o2info_coherent ( & oifi - > ifi_req ) ) {
inode_alloc = ocfs2_get_system_file_inode ( osb , type , i ) ;
if ( ! inode_alloc ) {
mlog ( ML_ERROR , " unable to get alloc inode in "
" slot %u \n " , i ) ;
status = - EIO ;
goto bail ;
}
} else {
ocfs2_sprintf_system_inode_name ( namebuf ,
sizeof ( namebuf ) ,
type , i ) ;
status = ocfs2_lookup_ino_from_name ( osb - > sys_root_inode ,
namebuf ,
strlen ( namebuf ) ,
& blkno ) ;
if ( status < 0 ) {
status = - ENOENT ;
goto bail ;
}
}
status = ocfs2_info_scan_inode_alloc ( osb , inode_alloc , blkno , oifi , i ) ;
iput ( inode_alloc ) ;
inode_alloc = NULL ;
2014-04-04 01:47:12 +04:00
if ( status < 0 )
goto bail ;
2011-05-24 11:25:54 +04:00
}
o2info_set_request_filled ( & oifi - > ifi_req ) ;
if ( o2info_to_user ( * oifi , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
o2info_set_request_error ( & oifi - > ifi_req , req ) ;
kfree ( oifi ) ;
2011-05-29 23:57:16 +04:00
out_err :
2011-05-24 11:25:54 +04:00
return status ;
}
2011-05-24 11:27:17 +04:00
static void o2ffg_update_histogram ( struct ocfs2_info_free_chunk_list * hist ,
unsigned int chunksize )
{
int index ;
index = __ilog2_u32 ( chunksize ) ;
if ( index > = OCFS2_INFO_MAX_HIST )
index = OCFS2_INFO_MAX_HIST - 1 ;
hist - > fc_chunks [ index ] + + ;
hist - > fc_clusters [ index ] + = chunksize ;
}
static void o2ffg_update_stats ( struct ocfs2_info_freefrag_stats * stats ,
unsigned int chunksize )
{
if ( chunksize > stats - > ffs_max )
stats - > ffs_max = chunksize ;
if ( chunksize < stats - > ffs_min )
stats - > ffs_min = chunksize ;
stats - > ffs_avg + = chunksize ;
stats - > ffs_free_chunks_real + + ;
}
void ocfs2_info_update_ffg ( struct ocfs2_info_freefrag * ffg ,
unsigned int chunksize )
{
o2ffg_update_histogram ( & ( ffg - > iff_ffs . ffs_fc_hist ) , chunksize ) ;
o2ffg_update_stats ( & ( ffg - > iff_ffs ) , chunksize ) ;
}
int ocfs2_info_freefrag_scan_chain ( struct ocfs2_super * osb ,
struct inode * gb_inode ,
struct ocfs2_dinode * gb_dinode ,
struct ocfs2_chain_rec * rec ,
struct ocfs2_info_freefrag * ffg ,
u32 chunks_in_group )
{
int status = 0 , used ;
u64 blkno ;
struct buffer_head * bh = NULL ;
struct ocfs2_group_desc * bg = NULL ;
unsigned int max_bits , num_clusters ;
unsigned int offset = 0 , cluster , chunk ;
unsigned int chunk_free , last_chunksize = 0 ;
if ( ! le32_to_cpu ( rec - > c_free ) )
goto bail ;
do {
if ( ! bg )
blkno = le64_to_cpu ( rec - > c_blkno ) ;
else
blkno = le64_to_cpu ( bg - > bg_next_group ) ;
if ( bh ) {
brelse ( bh ) ;
bh = NULL ;
}
if ( o2info_coherent ( & ffg - > iff_req ) )
status = ocfs2_read_group_descriptor ( gb_inode ,
gb_dinode ,
blkno , & bh ) ;
else
status = ocfs2_read_blocks_sync ( osb , blkno , 1 , & bh ) ;
if ( status < 0 ) {
mlog ( ML_ERROR , " Can't read the group descriptor # "
" %llu from device. " , ( unsigned long long ) blkno ) ;
status = - EIO ;
goto bail ;
}
bg = ( struct ocfs2_group_desc * ) bh - > b_data ;
if ( ! le16_to_cpu ( bg - > bg_free_bits_count ) )
continue ;
max_bits = le16_to_cpu ( bg - > bg_bits ) ;
offset = 0 ;
for ( chunk = 0 ; chunk < chunks_in_group ; chunk + + ) {
/*
* last chunk may be not an entire one .
*/
if ( ( offset + ffg - > iff_chunksize ) > max_bits )
num_clusters = max_bits - offset ;
else
num_clusters = ffg - > iff_chunksize ;
chunk_free = 0 ;
for ( cluster = 0 ; cluster < num_clusters ; cluster + + ) {
used = ocfs2_test_bit ( offset ,
( unsigned long * ) bg - > bg_bitmap ) ;
/*
* - chunk_free counts free clusters in # N chunk .
* - last_chunksize records the size ( in ) clusters
* for the last real free chunk being counted .
*/
if ( ! used ) {
last_chunksize + + ;
chunk_free + + ;
}
if ( used & & last_chunksize ) {
ocfs2_info_update_ffg ( ffg ,
last_chunksize ) ;
last_chunksize = 0 ;
}
offset + + ;
}
if ( chunk_free = = ffg - > iff_chunksize )
ffg - > iff_ffs . ffs_free_chunks + + ;
}
/*
* need to update the info for last free chunk .
*/
if ( last_chunksize )
ocfs2_info_update_ffg ( ffg , last_chunksize ) ;
} while ( le64_to_cpu ( bg - > bg_next_group ) ) ;
bail :
brelse ( bh ) ;
return status ;
}
int ocfs2_info_freefrag_scan_bitmap ( struct ocfs2_super * osb ,
struct inode * gb_inode , u64 blkno ,
struct ocfs2_info_freefrag * ffg )
{
u32 chunks_in_group ;
int status = 0 , unlock = 0 , i ;
struct buffer_head * bh = NULL ;
struct ocfs2_chain_list * cl = NULL ;
struct ocfs2_chain_rec * rec = NULL ;
struct ocfs2_dinode * gb_dinode = NULL ;
if ( gb_inode )
mutex_lock ( & gb_inode - > i_mutex ) ;
if ( o2info_coherent ( & ffg - > iff_req ) ) {
status = ocfs2_inode_lock ( gb_inode , & bh , 0 ) ;
if ( status < 0 ) {
mlog_errno ( status ) ;
goto bail ;
}
unlock = 1 ;
} else {
status = ocfs2_read_blocks_sync ( osb , blkno , 1 , & bh ) ;
if ( status < 0 ) {
mlog_errno ( status ) ;
goto bail ;
}
}
gb_dinode = ( struct ocfs2_dinode * ) bh - > b_data ;
cl = & ( gb_dinode - > id2 . i_chain ) ;
/*
* Chunksize ( in ) clusters from userspace should be
* less than clusters in a group .
*/
if ( ffg - > iff_chunksize > le16_to_cpu ( cl - > cl_cpg ) ) {
status = - EINVAL ;
goto bail ;
}
memset ( & ffg - > iff_ffs , 0 , sizeof ( struct ocfs2_info_freefrag_stats ) ) ;
ffg - > iff_ffs . ffs_min = ~ 0U ;
ffg - > iff_ffs . ffs_clusters =
le32_to_cpu ( gb_dinode - > id1 . bitmap1 . i_total ) ;
ffg - > iff_ffs . ffs_free_clusters = ffg - > iff_ffs . ffs_clusters -
le32_to_cpu ( gb_dinode - > id1 . bitmap1 . i_used ) ;
chunks_in_group = le16_to_cpu ( cl - > cl_cpg ) / ffg - > iff_chunksize + 1 ;
for ( i = 0 ; i < le16_to_cpu ( cl - > cl_next_free_rec ) ; i + + ) {
rec = & ( cl - > cl_recs [ i ] ) ;
status = ocfs2_info_freefrag_scan_chain ( osb , gb_inode ,
gb_dinode ,
rec , ffg ,
chunks_in_group ) ;
if ( status )
goto bail ;
}
if ( ffg - > iff_ffs . ffs_free_chunks_real )
ffg - > iff_ffs . ffs_avg = ( ffg - > iff_ffs . ffs_avg /
ffg - > iff_ffs . ffs_free_chunks_real ) ;
bail :
if ( unlock )
ocfs2_inode_unlock ( gb_inode , 0 ) ;
if ( gb_inode )
mutex_unlock ( & gb_inode - > i_mutex ) ;
if ( gb_inode )
iput ( gb_inode ) ;
brelse ( bh ) ;
return status ;
}
int ocfs2_info_handle_freefrag ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
u64 blkno = - 1 ;
char namebuf [ 40 ] ;
int status = - EFAULT , type = GLOBAL_BITMAP_SYSTEM_INODE ;
struct ocfs2_info_freefrag * oiff ;
struct ocfs2_super * osb = OCFS2_SB ( inode - > i_sb ) ;
struct inode * gb_inode = NULL ;
oiff = kzalloc ( sizeof ( struct ocfs2_info_freefrag ) , GFP_KERNEL ) ;
if ( ! oiff ) {
status = - ENOMEM ;
mlog_errno ( status ) ;
2011-05-29 23:57:16 +04:00
goto out_err ;
2011-05-24 11:27:17 +04:00
}
if ( o2info_from_user ( * oiff , req ) )
goto bail ;
/*
* chunksize from userspace should be power of 2.
*/
if ( ( oiff - > iff_chunksize & ( oiff - > iff_chunksize - 1 ) ) | |
( ! oiff - > iff_chunksize ) ) {
status = - EINVAL ;
goto bail ;
}
if ( o2info_coherent ( & oiff - > iff_req ) ) {
gb_inode = ocfs2_get_system_file_inode ( osb , type ,
OCFS2_INVALID_SLOT ) ;
if ( ! gb_inode ) {
mlog ( ML_ERROR , " unable to get global_bitmap inode \n " ) ;
status = - EIO ;
goto bail ;
}
} else {
ocfs2_sprintf_system_inode_name ( namebuf , sizeof ( namebuf ) , type ,
OCFS2_INVALID_SLOT ) ;
status = ocfs2_lookup_ino_from_name ( osb - > sys_root_inode ,
namebuf ,
strlen ( namebuf ) ,
& blkno ) ;
if ( status < 0 ) {
status = - ENOENT ;
goto bail ;
}
}
status = ocfs2_info_freefrag_scan_bitmap ( osb , gb_inode , blkno , oiff ) ;
if ( status < 0 )
goto bail ;
o2info_set_request_filled ( & oiff - > iff_req ) ;
2013-04-30 02:05:57 +04:00
if ( o2info_to_user ( * oiff , req ) ) {
status = - EFAULT ;
2011-05-24 11:27:17 +04:00
goto bail ;
2013-04-30 02:05:57 +04:00
}
2011-05-24 11:27:17 +04:00
status = 0 ;
bail :
if ( status )
o2info_set_request_error ( & oiff - > iff_req , req ) ;
kfree ( oiff ) ;
2011-05-29 23:57:16 +04:00
out_err :
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
int ocfs2_info_handle_unknown ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_request oir ;
if ( o2info_from_user ( oir , req ) )
goto bail ;
2011-05-24 11:22:59 +04:00
o2info_clear_request_filled ( & oir ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( o2info_to_user ( oir , req ) )
goto bail ;
status = 0 ;
bail :
if ( status )
2011-05-24 11:22:59 +04:00
o2info_set_request_error ( & oir , req ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return status ;
}
/*
* Validate and distinguish OCFS2_IOC_INFO requests .
*
* - validate the magic number .
* - distinguish different requests .
* - validate size of different requests .
*/
int ocfs2_info_handle_request ( struct inode * inode ,
struct ocfs2_info_request __user * req )
{
int status = - EFAULT ;
struct ocfs2_info_request oir ;
if ( o2info_from_user ( oir , req ) )
goto bail ;
status = - EINVAL ;
if ( oir . ir_magic ! = OCFS2_INFO_MAGIC )
goto bail ;
switch ( oir . ir_code ) {
case OCFS2_INFO_BLOCKSIZE :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_blocksize ) )
status = ocfs2_info_handle_blocksize ( inode , req ) ;
break ;
case OCFS2_INFO_CLUSTERSIZE :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_clustersize ) )
status = ocfs2_info_handle_clustersize ( inode , req ) ;
break ;
case OCFS2_INFO_MAXSLOTS :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_maxslots ) )
status = ocfs2_info_handle_maxslots ( inode , req ) ;
break ;
case OCFS2_INFO_LABEL :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_label ) )
status = ocfs2_info_handle_label ( inode , req ) ;
break ;
case OCFS2_INFO_UUID :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_uuid ) )
status = ocfs2_info_handle_uuid ( inode , req ) ;
break ;
case OCFS2_INFO_FS_FEATURES :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_fs_features ) )
status = ocfs2_info_handle_fs_features ( inode , req ) ;
break ;
case OCFS2_INFO_JOURNAL_SIZE :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_journal_size ) )
status = ocfs2_info_handle_journal_size ( inode , req ) ;
break ;
2011-05-24 11:25:54 +04:00
case OCFS2_INFO_FREEINODE :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_freeinode ) )
status = ocfs2_info_handle_freeinode ( inode , req ) ;
break ;
2011-05-24 11:27:17 +04:00
case OCFS2_INFO_FREEFRAG :
if ( oir . ir_size = = sizeof ( struct ocfs2_info_freefrag ) )
status = ocfs2_info_handle_freefrag ( inode , req ) ;
break ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
default :
status = ocfs2_info_handle_unknown ( inode , req ) ;
break ;
}
bail :
return status ;
}
int ocfs2_get_request_ptr ( struct ocfs2_info * info , int idx ,
u64 * req_addr , int compat_flag )
{
int status = - EFAULT ;
u64 __user * bp = NULL ;
if ( compat_flag ) {
# ifdef CONFIG_COMPAT
/*
* pointer bp stores the base address of a pointers array ,
* which collects all addresses of separate request .
*/
bp = ( u64 __user * ) ( unsigned long ) compat_ptr ( info - > oi_requests ) ;
# else
BUG ( ) ;
# endif
} else
bp = ( u64 __user * ) ( unsigned long ) ( info - > oi_requests ) ;
if ( o2info_from_user ( * req_addr , bp + idx ) )
goto bail ;
status = 0 ;
bail :
return status ;
}
/*
* OCFS2_IOC_INFO handles an array of requests passed from userspace .
*
* ocfs2_info_handle ( ) recevies a large info aggregation , grab and
* validate the request count from header , then break it into small
* pieces , later specific handlers can handle them one by one .
*
* Idea here is to make each separate request small enough to ensure
* a better backward & forward compatibility , since a small piece of
* request will be less likely to be broken if disk layout get changed .
*/
int ocfs2_info_handle ( struct inode * inode , struct ocfs2_info * info ,
int compat_flag )
{
int i , status = 0 ;
u64 req_addr ;
struct ocfs2_info_request __user * reqp ;
if ( ( info - > oi_count > OCFS2_INFO_MAX_REQUEST ) | |
( ! info - > oi_requests ) ) {
status = - EINVAL ;
goto bail ;
}
for ( i = 0 ; i < info - > oi_count ; i + + ) {
status = ocfs2_get_request_ptr ( info , i , & req_addr , compat_flag ) ;
if ( status )
break ;
2012-04-13 03:52:19 +04:00
reqp = ( struct ocfs2_info_request __user * ) ( unsigned long ) req_addr ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
if ( ! reqp ) {
status = - EINVAL ;
goto bail ;
}
status = ocfs2_info_handle_request ( inode , reqp ) ;
if ( status )
break ;
}
bail :
return status ;
}
2008-01-27 05:17:17 +03:00
long ocfs2_ioctl ( struct file * filp , unsigned int cmd , unsigned long arg )
2006-07-04 04:27:12 +04:00
{
2013-01-24 02:07:38 +04:00
struct inode * inode = file_inode ( filp ) ;
2006-07-04 04:27:12 +04:00
unsigned int flags ;
2007-12-18 10:47:03 +03:00
int new_clusters ;
2006-07-04 04:27:12 +04:00
int status ;
2007-03-10 03:53:21 +03:00
struct ocfs2_space_resv sr ;
2007-12-18 10:47:25 +03:00
struct ocfs2_new_group_input input ;
2009-09-21 07:25:14 +04:00
struct reflink_arguments args ;
2012-04-13 03:52:19 +04:00
const char __user * old_path ;
const char __user * new_path ;
2009-09-21 07:25:14 +04:00
bool preserve ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
struct ocfs2_info info ;
2012-04-13 03:52:19 +04:00
void __user * argp = ( void __user * ) arg ;
2006-07-04 04:27:12 +04:00
switch ( cmd ) {
case OCFS2_IOC_GETFLAGS :
status = ocfs2_get_inode_attr ( inode , & flags ) ;
if ( status < 0 )
return status ;
flags & = OCFS2_FL_VISIBLE ;
return put_user ( flags , ( int __user * ) arg ) ;
case OCFS2_IOC_SETFLAGS :
if ( get_user ( flags , ( int __user * ) arg ) )
return - EFAULT ;
2011-11-23 20:57:51 +04:00
status = mnt_want_write_file ( filp ) ;
2008-02-16 01:37:46 +03:00
if ( status )
return status ;
status = ocfs2_set_inode_attr ( inode , flags ,
2006-07-04 04:27:12 +04:00
OCFS2_FL_MODIFIABLE ) ;
2011-12-09 17:06:57 +04:00
mnt_drop_write_file ( filp ) ;
2008-02-16 01:37:46 +03:00
return status ;
2007-03-10 03:53:21 +03:00
case OCFS2_IOC_RESVSP :
case OCFS2_IOC_RESVSP64 :
case OCFS2_IOC_UNRESVSP :
case OCFS2_IOC_UNRESVSP64 :
if ( copy_from_user ( & sr , ( int __user * ) arg , sizeof ( sr ) ) )
return - EFAULT ;
return ocfs2_change_file_space ( filp , cmd , & sr ) ;
2007-12-18 10:47:03 +03:00
case OCFS2_IOC_GROUP_EXTEND :
2007-12-19 05:58:18 +03:00
if ( ! capable ( CAP_SYS_RESOURCE ) )
return - EPERM ;
2007-12-18 10:47:03 +03:00
if ( get_user ( new_clusters , ( int __user * ) arg ) )
return - EFAULT ;
2012-06-12 18:20:40 +04:00
status = mnt_want_write_file ( filp ) ;
if ( status )
return status ;
status = ocfs2_group_extend ( inode , new_clusters ) ;
mnt_drop_write_file ( filp ) ;
return status ;
2007-12-18 10:47:25 +03:00
case OCFS2_IOC_GROUP_ADD :
case OCFS2_IOC_GROUP_ADD64 :
2007-12-19 05:58:18 +03:00
if ( ! capable ( CAP_SYS_RESOURCE ) )
return - EPERM ;
2007-12-18 10:47:25 +03:00
if ( copy_from_user ( & input , ( int __user * ) arg , sizeof ( input ) ) )
return - EFAULT ;
2012-06-12 18:20:40 +04:00
status = mnt_want_write_file ( filp ) ;
if ( status )
return status ;
status = ocfs2_group_add ( inode , & input ) ;
mnt_drop_write_file ( filp ) ;
return status ;
2009-09-21 07:25:14 +04:00
case OCFS2_IOC_REFLINK :
2012-04-13 03:52:19 +04:00
if ( copy_from_user ( & args , argp , sizeof ( args ) ) )
2009-09-21 07:25:14 +04:00
return - EFAULT ;
2012-04-13 03:52:19 +04:00
old_path = ( const char __user * ) ( unsigned long ) args . old_path ;
new_path = ( const char __user * ) ( unsigned long ) args . new_path ;
2009-09-21 07:25:14 +04:00
preserve = ( args . preserve ! = 0 ) ;
return ocfs2_reflink_ioctl ( inode , old_path , new_path , preserve ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
case OCFS2_IOC_INFO :
2012-04-13 03:52:19 +04:00
if ( copy_from_user ( & info , argp , sizeof ( struct ocfs2_info ) ) )
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return - EFAULT ;
return ocfs2_info_handle ( inode , & info , 0 ) ;
2011-05-23 06:36:44 +04:00
case FITRIM :
{
struct super_block * sb = inode - > i_sb ;
2014-01-22 03:48:34 +04:00
struct request_queue * q = bdev_get_queue ( sb - > s_bdev ) ;
2011-05-23 06:36:44 +04:00
struct fstrim_range range ;
int ret = 0 ;
if ( ! capable ( CAP_SYS_ADMIN ) )
return - EPERM ;
2014-01-22 03:48:34 +04:00
if ( ! blk_queue_discard ( q ) )
return - EOPNOTSUPP ;
2012-04-13 03:52:19 +04:00
if ( copy_from_user ( & range , argp , sizeof ( range ) ) )
2011-05-23 06:36:44 +04:00
return - EFAULT ;
2014-01-22 03:48:36 +04:00
range . minlen = max_t ( u64 , q - > limits . discard_granularity ,
range . minlen ) ;
2011-05-23 06:36:44 +04:00
ret = ocfs2_trim_fs ( sb , & range ) ;
if ( ret < 0 )
return ret ;
2012-04-13 03:52:19 +04:00
if ( copy_to_user ( argp , & range , sizeof ( range ) ) )
2011-05-23 06:36:44 +04:00
return - EFAULT ;
return 0 ;
}
2011-05-25 10:23:43 +04:00
case OCFS2_IOC_MOVE_EXT :
2012-04-13 03:52:19 +04:00
return ocfs2_ioctl_move_extents ( filp , argp ) ;
2006-07-04 04:27:12 +04:00
default :
return - ENOTTY ;
}
}
2007-03-10 02:56:28 +03:00
# ifdef CONFIG_COMPAT
long ocfs2_compat_ioctl ( struct file * file , unsigned cmd , unsigned long arg )
{
2010-01-27 05:21:52 +03:00
bool preserve ;
struct reflink_arguments args ;
2013-01-24 02:07:38 +04:00
struct inode * inode = file_inode ( file ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
struct ocfs2_info info ;
2012-04-13 03:52:19 +04:00
void __user * argp = ( void __user * ) arg ;
2010-01-27 05:21:52 +03:00
2007-03-10 02:56:28 +03:00
switch ( cmd ) {
case OCFS2_IOC32_GETFLAGS :
cmd = OCFS2_IOC_GETFLAGS ;
break ;
case OCFS2_IOC32_SETFLAGS :
cmd = OCFS2_IOC_SETFLAGS ;
break ;
2007-03-10 03:53:21 +03:00
case OCFS2_IOC_RESVSP :
case OCFS2_IOC_RESVSP64 :
case OCFS2_IOC_UNRESVSP :
case OCFS2_IOC_UNRESVSP64 :
2007-12-18 10:47:03 +03:00
case OCFS2_IOC_GROUP_EXTEND :
2007-12-18 10:47:25 +03:00
case OCFS2_IOC_GROUP_ADD :
case OCFS2_IOC_GROUP_ADD64 :
2011-05-23 06:36:44 +04:00
case FITRIM :
2007-03-10 03:53:21 +03:00
break ;
2010-01-27 05:21:52 +03:00
case OCFS2_IOC_REFLINK :
2012-04-13 03:52:19 +04:00
if ( copy_from_user ( & args , argp , sizeof ( args ) ) )
2010-01-27 05:21:52 +03:00
return - EFAULT ;
preserve = ( args . preserve ! = 0 ) ;
return ocfs2_reflink_ioctl ( inode , compat_ptr ( args . old_path ) ,
compat_ptr ( args . new_path ) , preserve ) ;
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
case OCFS2_IOC_INFO :
2012-04-13 03:52:19 +04:00
if ( copy_from_user ( & info , argp , sizeof ( struct ocfs2_info ) ) )
Ocfs2: Add new OCFS2_IOC_INFO ioctl for ocfs2 v8.
The reason why we need this ioctl is to offer the none-privileged
end-user a possibility to get filesys info gathering.
We use OCFS2_IOC_INFO to manipulate the new ioctl, userspace passes a
structure to kernel containing an array of request pointers and request
count, such as,
* From userspace:
struct ocfs2_info_blocksize oib = {
.ib_req = {
.ir_magic = OCFS2_INFO_MAGIC,
.ir_code = OCFS2_INFO_BLOCKSIZE,
...
}
...
}
struct ocfs2_info_clustersize oic = {
...
}
uint64_t reqs[2] = {(unsigned long)&oib,
(unsigned long)&oic};
struct ocfs2_info info = {
.oi_requests = reqs,
.oi_count = 2,
}
ret = ioctl(fd, OCFS2_IOC_INFO, &info);
* In kernel:
Get the request pointers from *info*, then handle each request one bye one.
Idea here is to make the spearated request small enough to guarantee
a better backward&forward compatibility since a small piece of request
would be less likely to be broken if filesys on raw disk get changed.
Currently, the following 7 requests are supported per the requirement from
userspace tool o2info, and I believe it will grow over time:-)
OCFS2_INFO_CLUSTERSIZE
OCFS2_INFO_BLOCKSIZE
OCFS2_INFO_MAXSLOTS
OCFS2_INFO_LABEL
OCFS2_INFO_UUID
OCFS2_INFO_FS_FEATURES
OCFS2_INFO_JOURNAL_SIZE
This ioctl is only specific to OCFS2.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
2010-05-22 12:26:33 +04:00
return - EFAULT ;
return ocfs2_info_handle ( inode , & info , 1 ) ;
2011-05-25 10:23:43 +04:00
case OCFS2_IOC_MOVE_EXT :
break ;
2007-03-10 02:56:28 +03:00
default :
return - ENOIOCTLCMD ;
}
2008-01-27 05:17:17 +03:00
return ocfs2_ioctl ( file , cmd , arg ) ;
2007-03-10 02:56:28 +03:00
}
# endif