OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [ext3/] [ioctl.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * linux/fs/ext3/ioctl.c
3
 *
4
 * Copyright (C) 1993, 1994, 1995
5
 * Remy Card (card@masi.ibp.fr)
6
 * Laboratoire MASI - Institut Blaise Pascal
7
 * Universite Pierre et Marie Curie (Paris VI)
8
 */
9
 
10
#include <linux/fs.h>
11
#include <linux/jbd.h>
12
#include <linux/capability.h>
13
#include <linux/ext3_fs.h>
14
#include <linux/ext3_jbd.h>
15
#include <linux/time.h>
16
#include <linux/compat.h>
17
#include <linux/smp_lock.h>
18
#include <asm/uaccess.h>
19
 
20
int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
21
                unsigned long arg)
22
{
23
        struct ext3_inode_info *ei = EXT3_I(inode);
24
        unsigned int flags;
25
        unsigned short rsv_window_size;
26
 
27
        ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg);
28
 
29
        switch (cmd) {
30
        case EXT3_IOC_GETFLAGS:
31
                ext3_get_inode_flags(ei);
32
                flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
33
                return put_user(flags, (int __user *) arg);
34
        case EXT3_IOC_SETFLAGS: {
35
                handle_t *handle = NULL;
36
                int err;
37
                struct ext3_iloc iloc;
38
                unsigned int oldflags;
39
                unsigned int jflag;
40
 
41
                if (IS_RDONLY(inode))
42
                        return -EROFS;
43
 
44
                if (!is_owner_or_cap(inode))
45
                        return -EACCES;
46
 
47
                if (get_user(flags, (int __user *) arg))
48
                        return -EFAULT;
49
 
50
                if (!S_ISDIR(inode->i_mode))
51
                        flags &= ~EXT3_DIRSYNC_FL;
52
 
53
                mutex_lock(&inode->i_mutex);
54
                /* Is it quota file? Do not allow user to mess with it */
55
                if (IS_NOQUOTA(inode)) {
56
                        mutex_unlock(&inode->i_mutex);
57
                        return -EPERM;
58
                }
59
                oldflags = ei->i_flags;
60
 
61
                /* The JOURNAL_DATA flag is modifiable only by root */
62
                jflag = flags & EXT3_JOURNAL_DATA_FL;
63
 
64
                /*
65
                 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
66
                 * the relevant capability.
67
                 *
68
                 * This test looks nicer. Thanks to Pauline Middelink
69
                 */
70
                if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) {
71
                        if (!capable(CAP_LINUX_IMMUTABLE)) {
72
                                mutex_unlock(&inode->i_mutex);
73
                                return -EPERM;
74
                        }
75
                }
76
 
77
                /*
78
                 * The JOURNAL_DATA flag can only be changed by
79
                 * the relevant capability.
80
                 */
81
                if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) {
82
                        if (!capable(CAP_SYS_RESOURCE)) {
83
                                mutex_unlock(&inode->i_mutex);
84
                                return -EPERM;
85
                        }
86
                }
87
 
88
 
89
                handle = ext3_journal_start(inode, 1);
90
                if (IS_ERR(handle)) {
91
                        mutex_unlock(&inode->i_mutex);
92
                        return PTR_ERR(handle);
93
                }
94
                if (IS_SYNC(inode))
95
                        handle->h_sync = 1;
96
                err = ext3_reserve_inode_write(handle, inode, &iloc);
97
                if (err)
98
                        goto flags_err;
99
 
100
                flags = flags & EXT3_FL_USER_MODIFIABLE;
101
                flags |= oldflags & ~EXT3_FL_USER_MODIFIABLE;
102
                ei->i_flags = flags;
103
 
104
                ext3_set_inode_flags(inode);
105
                inode->i_ctime = CURRENT_TIME_SEC;
106
 
107
                err = ext3_mark_iloc_dirty(handle, inode, &iloc);
108
flags_err:
109
                ext3_journal_stop(handle);
110
                if (err) {
111
                        mutex_unlock(&inode->i_mutex);
112
                        return err;
113
                }
114
 
115
                if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL))
116
                        err = ext3_change_inode_journal_flag(inode, jflag);
117
                mutex_unlock(&inode->i_mutex);
118
                return err;
119
        }
120
        case EXT3_IOC_GETVERSION:
121
        case EXT3_IOC_GETVERSION_OLD:
122
                return put_user(inode->i_generation, (int __user *) arg);
123
        case EXT3_IOC_SETVERSION:
124
        case EXT3_IOC_SETVERSION_OLD: {
125
                handle_t *handle;
126
                struct ext3_iloc iloc;
127
                __u32 generation;
128
                int err;
129
 
130
                if (!is_owner_or_cap(inode))
131
                        return -EPERM;
132
                if (IS_RDONLY(inode))
133
                        return -EROFS;
134
                if (get_user(generation, (int __user *) arg))
135
                        return -EFAULT;
136
 
137
                handle = ext3_journal_start(inode, 1);
138
                if (IS_ERR(handle))
139
                        return PTR_ERR(handle);
140
                err = ext3_reserve_inode_write(handle, inode, &iloc);
141
                if (err == 0) {
142
                        inode->i_ctime = CURRENT_TIME_SEC;
143
                        inode->i_generation = generation;
144
                        err = ext3_mark_iloc_dirty(handle, inode, &iloc);
145
                }
146
                ext3_journal_stop(handle);
147
                return err;
148
        }
149
#ifdef CONFIG_JBD_DEBUG
150
        case EXT3_IOC_WAIT_FOR_READONLY:
151
                /*
152
                 * This is racy - by the time we're woken up and running,
153
                 * the superblock could be released.  And the module could
154
                 * have been unloaded.  So sue me.
155
                 *
156
                 * Returns 1 if it slept, else zero.
157
                 */
158
                {
159
                        struct super_block *sb = inode->i_sb;
160
                        DECLARE_WAITQUEUE(wait, current);
161
                        int ret = 0;
162
 
163
                        set_current_state(TASK_INTERRUPTIBLE);
164
                        add_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
165
                        if (timer_pending(&EXT3_SB(sb)->turn_ro_timer)) {
166
                                schedule();
167
                                ret = 1;
168
                        }
169
                        remove_wait_queue(&EXT3_SB(sb)->ro_wait_queue, &wait);
170
                        return ret;
171
                }
172
#endif
173
        case EXT3_IOC_GETRSVSZ:
174
                if (test_opt(inode->i_sb, RESERVATION)
175
                        && S_ISREG(inode->i_mode)
176
                        && ei->i_block_alloc_info) {
177
                        rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
178
                        return put_user(rsv_window_size, (int __user *)arg);
179
                }
180
                return -ENOTTY;
181
        case EXT3_IOC_SETRSVSZ: {
182
 
183
                if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
184
                        return -ENOTTY;
185
 
186
                if (IS_RDONLY(inode))
187
                        return -EROFS;
188
 
189
                if (!is_owner_or_cap(inode))
190
                        return -EACCES;
191
 
192
                if (get_user(rsv_window_size, (int __user *)arg))
193
                        return -EFAULT;
194
 
195
                if (rsv_window_size > EXT3_MAX_RESERVE_BLOCKS)
196
                        rsv_window_size = EXT3_MAX_RESERVE_BLOCKS;
197
 
198
                /*
199
                 * need to allocate reservation structure for this inode
200
                 * before set the window size
201
                 */
202
                mutex_lock(&ei->truncate_mutex);
203
                if (!ei->i_block_alloc_info)
204
                        ext3_init_block_alloc_info(inode);
205
 
206
                if (ei->i_block_alloc_info){
207
                        struct ext3_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
208
                        rsv->rsv_goal_size = rsv_window_size;
209
                }
210
                mutex_unlock(&ei->truncate_mutex);
211
                return 0;
212
        }
213
        case EXT3_IOC_GROUP_EXTEND: {
214
                ext3_fsblk_t n_blocks_count;
215
                struct super_block *sb = inode->i_sb;
216
                int err;
217
 
218
                if (!capable(CAP_SYS_RESOURCE))
219
                        return -EPERM;
220
 
221
                if (IS_RDONLY(inode))
222
                        return -EROFS;
223
 
224
                if (get_user(n_blocks_count, (__u32 __user *)arg))
225
                        return -EFAULT;
226
 
227
                err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count);
228
                journal_lock_updates(EXT3_SB(sb)->s_journal);
229
                journal_flush(EXT3_SB(sb)->s_journal);
230
                journal_unlock_updates(EXT3_SB(sb)->s_journal);
231
 
232
                return err;
233
        }
234
        case EXT3_IOC_GROUP_ADD: {
235
                struct ext3_new_group_data input;
236
                struct super_block *sb = inode->i_sb;
237
                int err;
238
 
239
                if (!capable(CAP_SYS_RESOURCE))
240
                        return -EPERM;
241
 
242
                if (IS_RDONLY(inode))
243
                        return -EROFS;
244
 
245
                if (copy_from_user(&input, (struct ext3_new_group_input __user *)arg,
246
                                sizeof(input)))
247
                        return -EFAULT;
248
 
249
                err = ext3_group_add(sb, &input);
250
                journal_lock_updates(EXT3_SB(sb)->s_journal);
251
                journal_flush(EXT3_SB(sb)->s_journal);
252
                journal_unlock_updates(EXT3_SB(sb)->s_journal);
253
 
254
                return err;
255
        }
256
 
257
 
258
        default:
259
                return -ENOTTY;
260
        }
261
}
262
 
263
#ifdef CONFIG_COMPAT
264
long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
265
{
266
        struct inode *inode = file->f_path.dentry->d_inode;
267
        int ret;
268
 
269
        /* These are just misnamed, they actually get/put from/to user an int */
270
        switch (cmd) {
271
        case EXT3_IOC32_GETFLAGS:
272
                cmd = EXT3_IOC_GETFLAGS;
273
                break;
274
        case EXT3_IOC32_SETFLAGS:
275
                cmd = EXT3_IOC_SETFLAGS;
276
                break;
277
        case EXT3_IOC32_GETVERSION:
278
                cmd = EXT3_IOC_GETVERSION;
279
                break;
280
        case EXT3_IOC32_SETVERSION:
281
                cmd = EXT3_IOC_SETVERSION;
282
                break;
283
        case EXT3_IOC32_GROUP_EXTEND:
284
                cmd = EXT3_IOC_GROUP_EXTEND;
285
                break;
286
        case EXT3_IOC32_GETVERSION_OLD:
287
                cmd = EXT3_IOC_GETVERSION_OLD;
288
                break;
289
        case EXT3_IOC32_SETVERSION_OLD:
290
                cmd = EXT3_IOC_SETVERSION_OLD;
291
                break;
292
#ifdef CONFIG_JBD_DEBUG
293
        case EXT3_IOC32_WAIT_FOR_READONLY:
294
                cmd = EXT3_IOC_WAIT_FOR_READONLY;
295
                break;
296
#endif
297
        case EXT3_IOC32_GETRSVSZ:
298
                cmd = EXT3_IOC_GETRSVSZ;
299
                break;
300
        case EXT3_IOC32_SETRSVSZ:
301
                cmd = EXT3_IOC_SETRSVSZ;
302
                break;
303
        case EXT3_IOC_GROUP_ADD:
304
                break;
305
        default:
306
                return -ENOIOCTLCMD;
307
        }
308
        lock_kernel();
309
        ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
310
        unlock_kernel();
311
        return ret;
312
}
313
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.