]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ext2/ioctl.c
[ARM] 4983/1: S3C2412: Add initial memory controller registers
[linux-2.6-omap-h63xx.git] / fs / ext2 / ioctl.c
index 3bcd25422ee4879781a2785ec92a0f512e0c2567..b8ea11fee5c6fc36e059f9dc873564e82a464ab0 100644 (file)
 #include <asm/uaccess.h>
 
 
-int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
-               unsigned long arg)
+long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+       struct inode *inode = filp->f_dentry->d_inode;
        struct ext2_inode_info *ei = EXT2_I(inode);
        unsigned int flags;
+       unsigned short rsv_window_size;
 
        ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
 
@@ -46,6 +47,11 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                        flags &= ~EXT2_DIRSYNC_FL;
 
                mutex_lock(&inode->i_mutex);
+               /* Is it quota file? Do not allow user to mess with it */
+               if (IS_NOQUOTA(inode)) {
+                       mutex_unlock(&inode->i_mutex);
+                       return -EPERM;
+               }
                oldflags = ei->i_flags;
 
                /*
@@ -83,6 +89,50 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
                inode->i_ctime = CURRENT_TIME_SEC;
                mark_inode_dirty(inode);
                return 0;
+       case EXT2_IOC_GETRSVSZ:
+               if (test_opt(inode->i_sb, RESERVATION)
+                       && S_ISREG(inode->i_mode)
+                       && ei->i_block_alloc_info) {
+                       rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
+                       return put_user(rsv_window_size, (int __user *)arg);
+               }
+               return -ENOTTY;
+       case EXT2_IOC_SETRSVSZ: {
+
+               if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
+                       return -ENOTTY;
+
+               if (IS_RDONLY(inode))
+                       return -EROFS;
+
+               if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+                       return -EACCES;
+
+               if (get_user(rsv_window_size, (int __user *)arg))
+                       return -EFAULT;
+
+               if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS)
+                       rsv_window_size = EXT2_MAX_RESERVE_BLOCKS;
+
+               /*
+                * need to allocate reservation structure for this inode
+                * before set the window size
+                */
+               /*
+                * XXX What lock should protect the rsv_goal_size?
+                * Accessed in ext2_get_block only.  ext3 uses i_truncate.
+                */
+               mutex_lock(&ei->truncate_mutex);
+               if (!ei->i_block_alloc_info)
+                       ext2_init_block_alloc_info(inode);
+
+               if (ei->i_block_alloc_info){
+                       struct ext2_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
+                       rsv->rsv_goal_size = rsv_window_size;
+               }
+               mutex_unlock(&ei->truncate_mutex);
+               return 0;
+       }
        default:
                return -ENOTTY;
        }
@@ -91,9 +141,6 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 #ifdef CONFIG_COMPAT
 long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       int ret;
-
        /* These are just misnamed, they actually get/put from/to user an int */
        switch (cmd) {
        case EXT2_IOC32_GETFLAGS:
@@ -111,9 +158,6 @@ long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        default:
                return -ENOIOCTLCMD;
        }
-       lock_kernel();
-       ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg));
-       unlock_kernel();
-       return ret;
+       return ext2_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
 }
 #endif