Import 2.3.1pre1
[davej-history.git] / fs / ext2 / ioctl.c
blobec21b0c4e23a20d674178d6ac46b82aad0b56910
1 /*
2 * linux/fs/ext2/ioctl.c
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 */
10 #include <asm/uaccess.h>
12 #include <linux/errno.h>
13 #include <linux/fs.h>
14 #include <linux/ext2_fs.h>
15 #include <linux/ioctl.h>
16 #include <linux/sched.h>
17 #include <linux/mm.h>
19 int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
20 unsigned long arg)
22 unsigned int flags;
24 ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
26 switch (cmd) {
27 case EXT2_IOC_GETFLAGS:
28 flags = inode->u.ext2_i.i_flags & EXT2_FL_USER_VISIBLE;
29 return put_user(inode->u.ext2_i.i_flags, (int *) arg);
30 case EXT2_IOC_SETFLAGS:
31 if (get_user(flags, (int *) arg))
32 return -EFAULT;
33 flags = flags & EXT2_FL_USER_MODIFIABLE;
35 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
36 * the super user when the security level is zero.
38 if ((flags & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) ^
39 (inode->u.ext2_i.i_flags &
40 (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL))) {
41 /* This test looks nicer. Thanks to Pauline Middelink */
42 if (!capable(CAP_LINUX_IMMUTABLE))
43 return -EPERM;
44 } else
45 if ((current->fsuid != inode->i_uid) &&
46 !capable(CAP_FOWNER))
47 return -EPERM;
48 if (IS_RDONLY(inode))
49 return -EROFS;
50 inode->u.ext2_i.i_flags = (inode->u.ext2_i.i_flags &
51 ~EXT2_FL_USER_MODIFIABLE) | flags;
52 if (flags & EXT2_SYNC_FL)
53 inode->i_flags |= MS_SYNCHRONOUS;
54 else
55 inode->i_flags &= ~MS_SYNCHRONOUS;
56 if (flags & EXT2_APPEND_FL)
57 inode->i_flags |= S_APPEND;
58 else
59 inode->i_flags &= ~S_APPEND;
60 if (flags & EXT2_IMMUTABLE_FL)
61 inode->i_flags |= S_IMMUTABLE;
62 else
63 inode->i_flags &= ~S_IMMUTABLE;
64 if (flags & EXT2_NOATIME_FL)
65 inode->i_flags |= MS_NOATIME;
66 else
67 inode->i_flags &= ~MS_NOATIME;
68 inode->i_ctime = CURRENT_TIME;
69 mark_inode_dirty(inode);
70 return 0;
71 case EXT2_IOC_GETVERSION:
72 return put_user(inode->i_generation, (int *) arg);
73 case EXT2_IOC_SETVERSION:
74 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
75 return -EPERM;
76 if (IS_RDONLY(inode))
77 return -EROFS;
78 if (get_user(inode->i_generation, (int *) arg))
79 return -EFAULT;
80 inode->i_ctime = CURRENT_TIME;
81 mark_inode_dirty(inode);
82 return 0;
83 default:
84 return -ENOTTY;