headers: smp_lock.h redux
[safe/jmp/linux-2.6] / fs / ocfs2 / ioctl.c
index f3ad21a..467b413 100644 (file)
 #include "ocfs2.h"
 #include "alloc.h"
 #include "dlmglue.h"
+#include "file.h"
 #include "inode.h"
 #include "journal.h"
 
 #include "ocfs2_fs.h"
 #include "ioctl.h"
+#include "resize.h"
 
 #include <linux/ext2_fs.h>
 
@@ -26,14 +28,14 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
 {
        int status;
 
-       status = ocfs2_meta_lock(inode, NULL, 0);
+       status = ocfs2_inode_lock(inode, NULL, 0);
        if (status < 0) {
                mlog_errno(status);
                return status;
        }
        ocfs2_get_inode_flags(OCFS2_I(inode));
        *flags = OCFS2_I(inode)->ip_attr;
-       ocfs2_meta_unlock(inode, 0);
+       ocfs2_inode_unlock(inode, 0);
 
        mlog_exit(status);
        return status;
@@ -51,18 +53,14 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
 
        mutex_lock(&inode->i_mutex);
 
-       status = ocfs2_meta_lock(inode, &bh, 1);
+       status = ocfs2_inode_lock(inode, &bh, 1);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
-       status = -EROFS;
-       if (IS_RDONLY(inode))
-               goto bail_unlock;
-
        status = -EACCES;
-       if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
+       if (!is_owner_or_cap(inode))
                goto bail_unlock;
 
        if (!S_ISDIR(inode->i_mode))
@@ -99,22 +97,24 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
 
        ocfs2_commit_trans(osb, handle);
 bail_unlock:
-       ocfs2_meta_unlock(inode, 1);
+       ocfs2_inode_unlock(inode, 1);
 bail:
        mutex_unlock(&inode->i_mutex);
 
-       if (bh)
-               brelse(bh);
+       brelse(bh);
 
        mlog_exit(status);
        return status;
 }
 
-int ocfs2_ioctl(struct inode * inode, struct file * filp,
-       unsigned int cmd, unsigned long arg)
+long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
+       struct inode *inode = filp->f_path.dentry->d_inode;
        unsigned int flags;
+       int new_clusters;
        int status;
+       struct ocfs2_space_resv sr;
+       struct ocfs2_new_group_input input;
 
        switch (cmd) {
        case OCFS2_IOC_GETFLAGS:
@@ -128,8 +128,38 @@ int ocfs2_ioctl(struct inode * inode, struct file * filp,
                if (get_user(flags, (int __user *) arg))
                        return -EFAULT;
 
-               return ocfs2_set_inode_attr(inode, flags,
+               status = mnt_want_write(filp->f_path.mnt);
+               if (status)
+                       return status;
+               status = ocfs2_set_inode_attr(inode, flags,
                        OCFS2_FL_MODIFIABLE);
+               mnt_drop_write(filp->f_path.mnt);
+               return status;
+       case OCFS2_IOC_RESVSP:
+       case OCFS2_IOC_RESVSP64:
+       case OCFS2_IOC_UNRESVSP:
+       case OCFS2_IOC_UNRESVSP64:
+               if (copy_from_user(&sr, (int __user *) arg, sizeof(sr)))
+                       return -EFAULT;
+
+               return ocfs2_change_file_space(filp, cmd, &sr);
+       case OCFS2_IOC_GROUP_EXTEND:
+               if (!capable(CAP_SYS_RESOURCE))
+                       return -EPERM;
+
+               if (get_user(new_clusters, (int __user *)arg))
+                       return -EFAULT;
+
+               return ocfs2_group_extend(inode, new_clusters);
+       case OCFS2_IOC_GROUP_ADD:
+       case OCFS2_IOC_GROUP_ADD64:
+               if (!capable(CAP_SYS_RESOURCE))
+                       return -EPERM;
+
+               if (copy_from_user(&input, (int __user *) arg, sizeof(input)))
+                       return -EFAULT;
+
+               return ocfs2_group_add(inode, &input);
        default:
                return -ENOTTY;
        }
@@ -138,9 +168,6 @@ int ocfs2_ioctl(struct inode * inode, struct file * filp,
 #ifdef CONFIG_COMPAT
 long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       int ret;
-
        switch (cmd) {
        case OCFS2_IOC32_GETFLAGS:
                cmd = OCFS2_IOC_GETFLAGS;
@@ -148,13 +175,18 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        case OCFS2_IOC32_SETFLAGS:
                cmd = OCFS2_IOC_SETFLAGS;
                break;
+       case OCFS2_IOC_RESVSP:
+       case OCFS2_IOC_RESVSP64:
+       case OCFS2_IOC_UNRESVSP:
+       case OCFS2_IOC_UNRESVSP64:
+       case OCFS2_IOC_GROUP_EXTEND:
+       case OCFS2_IOC_GROUP_ADD:
+       case OCFS2_IOC_GROUP_ADD64:
+               break;
        default:
                return -ENOIOCTLCMD;
        }
 
-       lock_kernel();
-       ret = ocfs2_ioctl(inode, file, cmd, arg);
-       unlock_kernel();
-       return ret;
+       return ocfs2_ioctl(file, cmd, arg);
 }
 #endif