Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
fs
ext2
ioctl.c
Go to the documentation of this file.
1
/*
2
* linux/fs/ext2/ioctl.c
3
*
4
* Copyright (C) 1993, 1994, 1995
5
* Remy Card (
[email protected]
)
6
* Laboratoire MASI - Institut Blaise Pascal
7
* Universite Pierre et Marie Curie (Paris VI)
8
*/
9
10
#include "
ext2.h
"
11
#include <linux/capability.h>
12
#include <linux/time.h>
13
#include <linux/sched.h>
14
#include <
linux/compat.h
>
15
#include <
linux/mount.h
>
16
#include <asm/current.h>
17
#include <asm/uaccess.h>
18
19
20
long
ext2_ioctl
(
struct
file
*filp,
unsigned
int
cmd
,
unsigned
long
arg
)
21
{
22
struct
inode
*
inode
= filp->f_dentry->d_inode;
23
struct
ext2_inode_info
*ei = EXT2_I(inode);
24
unsigned
int
flags
;
25
unsigned
short
rsv_window_size;
26
int
ret
;
27
28
ext2_debug
(
"cmd = %u, arg = %lu\n"
, cmd, arg);
29
30
switch
(cmd) {
31
case
EXT2_IOC_GETFLAGS
:
32
ext2_get_inode_flags
(ei);
33
flags = ei->
i_flags
&
EXT2_FL_USER_VISIBLE
;
34
return
put_user
(flags, (
int
__user
*) arg);
35
case
EXT2_IOC_SETFLAGS
: {
36
unsigned
int
oldflags;
37
38
ret =
mnt_want_write_file
(filp);
39
if
(ret)
40
return
ret
;
41
42
if
(!
inode_owner_or_capable
(inode)) {
43
ret = -
EACCES
;
44
goto
setflags_out;
45
}
46
47
if
(
get_user
(flags, (
int
__user
*) arg)) {
48
ret = -
EFAULT
;
49
goto
setflags_out;
50
}
51
52
flags = ext2_mask_flags(inode->
i_mode
, flags);
53
54
mutex_lock
(&inode->
i_mutex
);
55
/* Is it quota file? Do not allow user to mess with it */
56
if
(
IS_NOQUOTA
(inode)) {
57
mutex_unlock
(&inode->
i_mutex
);
58
ret = -
EPERM
;
59
goto
setflags_out;
60
}
61
oldflags = ei->
i_flags
;
62
63
/*
64
* The IMMUTABLE and APPEND_ONLY flags can only be changed by
65
* the relevant capability.
66
*
67
* This test looks nicer. Thanks to Pauline Middelink
68
*/
69
if
((flags ^ oldflags) & (
EXT2_APPEND_FL
|
EXT2_IMMUTABLE_FL
)) {
70
if
(!
capable
(
CAP_LINUX_IMMUTABLE
)) {
71
mutex_unlock
(&inode->
i_mutex
);
72
ret = -
EPERM
;
73
goto
setflags_out;
74
}
75
}
76
77
flags = flags &
EXT2_FL_USER_MODIFIABLE
;
78
flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE;
79
ei->
i_flags
=
flags
;
80
81
ext2_set_inode_flags
(inode);
82
inode->
i_ctime
=
CURRENT_TIME_SEC
;
83
mutex_unlock
(&inode->
i_mutex
);
84
85
mark_inode_dirty(inode);
86
setflags_out:
87
mnt_drop_write_file
(filp);
88
return
ret
;
89
}
90
case
EXT2_IOC_GETVERSION
:
91
return
put_user
(inode->
i_generation
, (
int
__user
*) arg);
92
case
EXT2_IOC_SETVERSION
: {
93
__u32
generation
;
94
95
if
(!
inode_owner_or_capable
(inode))
96
return
-
EPERM
;
97
ret =
mnt_want_write_file
(filp);
98
if
(ret)
99
return
ret
;
100
if
(
get_user
(generation, (
int
__user
*) arg)) {
101
ret = -
EFAULT
;
102
goto
setversion_out;
103
}
104
105
mutex_lock
(&inode->
i_mutex
);
106
inode->
i_ctime
=
CURRENT_TIME_SEC
;
107
inode->
i_generation
=
generation
;
108
mutex_unlock
(&inode->
i_mutex
);
109
110
mark_inode_dirty(inode);
111
setversion_out:
112
mnt_drop_write_file
(filp);
113
return
ret
;
114
}
115
case
EXT2_IOC_GETRSVSZ
:
116
if
(
test_opt
(inode->
i_sb
, RESERVATION)
117
&&
S_ISREG
(inode->
i_mode
)
118
&& ei->
i_block_alloc_info
) {
119
rsv_window_size = ei->
i_block_alloc_info
->rsv_window_node.rsv_goal_size;
120
return
put_user
(rsv_window_size, (
int
__user
*)arg);
121
}
122
return
-
ENOTTY
;
123
case
EXT2_IOC_SETRSVSZ
: {
124
125
if
(!
test_opt
(inode->
i_sb
, RESERVATION) ||!
S_ISREG
(inode->
i_mode
))
126
return
-
ENOTTY
;
127
128
if
(!
inode_owner_or_capable
(inode))
129
return
-
EACCES
;
130
131
if
(
get_user
(rsv_window_size, (
int
__user
*)arg))
132
return
-
EFAULT
;
133
134
ret =
mnt_want_write_file
(filp);
135
if
(ret)
136
return
ret
;
137
138
if
(rsv_window_size >
EXT2_MAX_RESERVE_BLOCKS
)
139
rsv_window_size =
EXT2_MAX_RESERVE_BLOCKS
;
140
141
/*
142
* need to allocate reservation structure for this inode
143
* before set the window size
144
*/
145
/*
146
* XXX What lock should protect the rsv_goal_size?
147
* Accessed in ext2_get_block only. ext3 uses i_truncate.
148
*/
149
mutex_lock
(&ei->
truncate_mutex
);
150
if
(!ei->
i_block_alloc_info
)
151
ext2_init_block_alloc_info
(inode);
152
153
if
(ei->
i_block_alloc_info
){
154
struct
ext2_reserve_window_node
*
rsv
= &ei->
i_block_alloc_info
->rsv_window_node;
155
rsv->
rsv_goal_size
= rsv_window_size;
156
}
157
mutex_unlock
(&ei->
truncate_mutex
);
158
mnt_drop_write_file
(filp);
159
return
0;
160
}
161
default
:
162
return
-
ENOTTY
;
163
}
164
}
165
166
#ifdef CONFIG_COMPAT
167
long
ext2_compat_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
168
{
169
/* These are just misnamed, they actually get/put from/to user an int */
170
switch
(cmd) {
171
case
EXT2_IOC32_GETFLAGS
:
172
cmd =
EXT2_IOC_GETFLAGS
;
173
break
;
174
case
EXT2_IOC32_SETFLAGS
:
175
cmd =
EXT2_IOC_SETFLAGS
;
176
break
;
177
case
EXT2_IOC32_GETVERSION
:
178
cmd =
EXT2_IOC_GETVERSION
;
179
break
;
180
case
EXT2_IOC32_SETVERSION
:
181
cmd =
EXT2_IOC_SETVERSION
;
182
break
;
183
default
:
184
return
-
ENOIOCTLCMD
;
185
}
186
return
ext2_ioctl
(file, cmd, (
unsigned
long
) compat_ptr(arg));
187
}
188
#endif
Generated on Thu Jan 10 2013 13:12:44 for Linux Kernel by
1.8.2