1 /* 2 * linux/fs/ext2/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 "ext2.h" 11 #include <linux/capability.h> 12 #include <linux/time.h> 13 #include <linux/sched.h> 14 #include <asm/current.h> 15 #include <asm/uaccess.h> 16 17 18 int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, 19 unsigned long arg) 20 { 21 struct ext2_inode_info *ei = EXT2_I(inode); 22 unsigned int flags; 23 24 ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg); 25 26 switch (cmd) { 27 case EXT2_IOC_GETFLAGS: 28 flags = ei->i_flags & EXT2_FL_USER_VISIBLE; 29 return put_user(flags, (int __user *) arg); 30 case EXT2_IOC_SETFLAGS: { 31 unsigned int oldflags; 32 33 if (IS_RDONLY(inode)) 34 return -EROFS; 35 36 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 37 return -EACCES; 38 39 if (get_user(flags, (int __user *) arg)) 40 return -EFAULT; 41 42 if (!S_ISDIR(inode->i_mode)) 43 flags &= ~EXT2_DIRSYNC_FL; 44 45 oldflags = ei->i_flags; 46 47 /* 48 * The IMMUTABLE and APPEND_ONLY flags can only be changed by 49 * the relevant capability. 50 * 51 * This test looks nicer. Thanks to Pauline Middelink 52 */ 53 if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { 54 if (!capable(CAP_LINUX_IMMUTABLE)) 55 return -EPERM; 56 } 57 58 flags = flags & EXT2_FL_USER_MODIFIABLE; 59 flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; 60 ei->i_flags = flags; 61 62 ext2_set_inode_flags(inode); 63 inode->i_ctime = CURRENT_TIME_SEC; 64 mark_inode_dirty(inode); 65 return 0; 66 } 67 case EXT2_IOC_GETVERSION: 68 return put_user(inode->i_generation, (int __user *) arg); 69 case EXT2_IOC_SETVERSION: 70 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) 71 return -EPERM; 72 if (IS_RDONLY(inode)) 73 return -EROFS; 74 if (get_user(inode->i_generation, (int __user *) arg)) 75 return -EFAULT; 76 inode->i_ctime = CURRENT_TIME_SEC; 77 mark_inode_dirty(inode); 78 return 0; 79 default: 80 return -ENOTTY; 81 } 82 } 83