Merge branch 'xen-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
[sfrench/cifs-2.6.git] / fs / ext2 / ioctl.c
index 3bcd25422ee4879781a2785ec92a0f512e0c2567..c2324d5fe4ac149a5672bad13134d4775c815100 100644 (file)
@@ -22,6 +22,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
 {
        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);
 
@@ -83,6 +84,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;
        }