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
ubifs
ioctl.c
Go to the documentation of this file.
1
/*
2
* This file is part of UBIFS.
3
*
4
* Copyright (C) 2006-2008 Nokia Corporation.
5
* Copyright (C) 2006, 2007 University of Szeged, Hungary
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License version 2 as published by
9
* the Free Software Foundation.
10
*
11
* This program is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
* more details.
15
*
16
* You should have received a copy of the GNU General Public License along with
17
* this program; if not, write to the Free Software Foundation, Inc., 51
18
* Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
*
20
* Authors: Zoltan Sogor
21
* Artem Bityutskiy (Битюцкий Артём)
22
* Adrian Hunter
23
*/
24
25
/* This file implements EXT2-compatible extended attribute ioctl() calls */
26
27
#include <
linux/compat.h
>
28
#include <
linux/mount.h
>
29
#include "
ubifs.h
"
30
37
void
ubifs_set_inode_flags
(
struct
inode
*
inode
)
38
{
39
unsigned
int
flags
=
ubifs_inode
(inode)->
flags
;
40
41
inode->
i_flags
&= ~(
S_SYNC
|
S_APPEND
|
S_IMMUTABLE
|
S_DIRSYNC
);
42
if
(flags &
UBIFS_SYNC_FL
)
43
inode->
i_flags
|=
S_SYNC
;
44
if
(flags &
UBIFS_APPEND_FL
)
45
inode->
i_flags
|=
S_APPEND
;
46
if
(flags &
UBIFS_IMMUTABLE_FL
)
47
inode->
i_flags
|=
S_IMMUTABLE
;
48
if
(flags &
UBIFS_DIRSYNC_FL
)
49
inode->
i_flags
|=
S_DIRSYNC
;
50
}
51
52
/*
53
* ioctl2ubifs - convert ioctl inode flags to UBIFS inode flags.
54
* @ioctl_flags: flags to convert
55
*
56
* This function convert ioctl flags (@FS_COMPR_FL, etc) to UBIFS inode flags
57
* (@UBIFS_COMPR_FL, etc).
58
*/
59
static
int
ioctl2ubifs(
int
ioctl_flags)
60
{
61
int
ubifs_flags = 0;
62
63
if
(ioctl_flags &
FS_COMPR_FL
)
64
ubifs_flags |=
UBIFS_COMPR_FL
;
65
if
(ioctl_flags &
FS_SYNC_FL
)
66
ubifs_flags |=
UBIFS_SYNC_FL
;
67
if
(ioctl_flags &
FS_APPEND_FL
)
68
ubifs_flags |=
UBIFS_APPEND_FL
;
69
if
(ioctl_flags &
FS_IMMUTABLE_FL
)
70
ubifs_flags |=
UBIFS_IMMUTABLE_FL
;
71
if
(ioctl_flags &
FS_DIRSYNC_FL
)
72
ubifs_flags |=
UBIFS_DIRSYNC_FL
;
73
74
return
ubifs_flags;
75
}
76
77
/*
78
* ubifs2ioctl - convert UBIFS inode flags to ioctl inode flags.
79
* @ubifs_flags: flags to convert
80
*
81
* This function convert UBIFS (@UBIFS_COMPR_FL, etc) to ioctl flags
82
* (@FS_COMPR_FL, etc).
83
*/
84
static
int
ubifs2ioctl(
int
ubifs_flags)
85
{
86
int
ioctl_flags = 0;
87
88
if
(ubifs_flags &
UBIFS_COMPR_FL
)
89
ioctl_flags |=
FS_COMPR_FL
;
90
if
(ubifs_flags &
UBIFS_SYNC_FL
)
91
ioctl_flags |=
FS_SYNC_FL
;
92
if
(ubifs_flags &
UBIFS_APPEND_FL
)
93
ioctl_flags |=
FS_APPEND_FL
;
94
if
(ubifs_flags &
UBIFS_IMMUTABLE_FL
)
95
ioctl_flags |=
FS_IMMUTABLE_FL
;
96
if
(ubifs_flags &
UBIFS_DIRSYNC_FL
)
97
ioctl_flags |=
FS_DIRSYNC_FL
;
98
99
return
ioctl_flags;
100
}
101
102
static
int
setflags(
struct
inode
*
inode
,
int
flags
)
103
{
104
int
oldflags,
err
,
release
;
105
struct
ubifs_inode
*ui =
ubifs_inode
(inode);
106
struct
ubifs_info
*
c
= inode->
i_sb
->s_fs_info;
107
struct
ubifs_budget_req
req
= { .dirtied_ino = 1,
108
.dirtied_ino_d = ui->
data_len
};
109
110
err =
ubifs_budget_space
(c, &req);
111
if
(err)
112
return
err
;
113
114
/*
115
* The IMMUTABLE and APPEND_ONLY flags can only be changed by
116
* the relevant capability.
117
*/
118
mutex_lock
(&ui->
ui_mutex
);
119
oldflags = ubifs2ioctl(ui->
flags
);
120
if
((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {
121
if
(!
capable
(
CAP_LINUX_IMMUTABLE
)) {
122
err = -
EPERM
;
123
goto
out_unlock;
124
}
125
}
126
127
ui->
flags
= ioctl2ubifs(flags);
128
ubifs_set_inode_flags
(inode);
129
inode->
i_ctime
= ubifs_current_time(inode);
130
release = ui->
dirty
;
131
mark_inode_dirty_sync(inode);
132
mutex_unlock
(&ui->
ui_mutex
);
133
134
if
(release)
135
ubifs_release_budget
(c, &req);
136
if
(
IS_SYNC
(inode))
137
err =
write_inode_now
(inode, 1);
138
return
err
;
139
140
out_unlock:
141
ubifs_err
(
"can't modify inode %lu attributes"
, inode->
i_ino
);
142
mutex_unlock
(&ui->
ui_mutex
);
143
ubifs_release_budget
(c, &req);
144
return
err
;
145
}
146
147
long
ubifs_ioctl
(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
148
{
149
int
flags
,
err
;
150
struct
inode *inode = file->
f_path
.dentry->d_inode;
151
152
switch
(cmd) {
153
case
FS_IOC_GETFLAGS
:
154
flags = ubifs2ioctl(
ubifs_inode
(inode)->flags);
155
156
dbg_gen
(
"get flags: %#x, i_flags %#x"
, flags, inode->
i_flags
);
157
return
put_user
(flags, (
int
__user
*) arg);
158
159
case
FS_IOC_SETFLAGS
: {
160
if
(
IS_RDONLY
(inode))
161
return
-
EROFS
;
162
163
if
(!
inode_owner_or_capable
(inode))
164
return
-
EACCES
;
165
166
if
(
get_user
(flags, (
int
__user
*) arg))
167
return
-
EFAULT
;
168
169
if
(!
S_ISDIR
(inode->
i_mode
))
170
flags &= ~
FS_DIRSYNC_FL
;
171
172
/*
173
* Make sure the file-system is read-write and make sure it
174
* will not become read-only while we are changing the flags.
175
*/
176
err =
mnt_want_write_file
(file);
177
if
(err)
178
return
err
;
179
dbg_gen
(
"set flags: %#x, i_flags %#x"
, flags, inode->
i_flags
);
180
err = setflags(inode, flags);
181
mnt_drop_write_file
(file);
182
return
err
;
183
}
184
185
default
:
186
return
-
ENOTTY
;
187
}
188
}
189
190
#ifdef CONFIG_COMPAT
191
long
ubifs_compat_ioctl(
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
192
{
193
switch
(cmd) {
194
case
FS_IOC32_GETFLAGS
:
195
cmd =
FS_IOC_GETFLAGS
;
196
break
;
197
case
FS_IOC32_SETFLAGS
:
198
cmd =
FS_IOC_SETFLAGS
;
199
break
;
200
default
:
201
return
-
ENOIOCTLCMD
;
202
}
203
return
ubifs_ioctl
(file, cmd, (
unsigned
long
)compat_ptr(arg));
204
}
205
#endif
Generated on Thu Jan 10 2013 13:12:47 for Linux Kernel by
1.8.2