2 * linux/fs/ocfs2/ioctl.c
4 * Copyright (C) 2006 Herbert Poetzl
5 * adapted from Remy Card's ext2/ioctl.c
9 #include <linux/mount.h>
10 #include <linux/smp_lock.h>
12 #define MLOG_MASK_PREFIX ML_INODE
13 #include <cluster/masklog.h>
26 #include <linux/ext2_fs.h>
28 static int ocfs2_get_inode_attr(struct inode
*inode
, unsigned *flags
)
32 status
= ocfs2_inode_lock(inode
, NULL
, 0);
37 ocfs2_get_inode_flags(OCFS2_I(inode
));
38 *flags
= OCFS2_I(inode
)->ip_attr
;
39 ocfs2_inode_unlock(inode
, 0);
45 static int ocfs2_set_inode_attr(struct inode
*inode
, unsigned flags
,
48 struct ocfs2_inode_info
*ocfs2_inode
= OCFS2_I(inode
);
49 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
50 handle_t
*handle
= NULL
;
51 struct buffer_head
*bh
= NULL
;
55 mutex_lock(&inode
->i_mutex
);
57 status
= ocfs2_inode_lock(inode
, &bh
, 1);
64 if (!is_owner_or_cap(inode
))
67 if (!S_ISDIR(inode
->i_mode
))
68 flags
&= ~OCFS2_DIRSYNC_FL
;
70 handle
= ocfs2_start_trans(osb
, OCFS2_INODE_UPDATE_CREDITS
);
72 status
= PTR_ERR(handle
);
77 oldflags
= ocfs2_inode
->ip_attr
;
79 flags
|= oldflags
& ~mask
;
82 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
83 * the relevant capability.
86 if ((oldflags
& OCFS2_IMMUTABLE_FL
) || ((flags
^ oldflags
) &
87 (OCFS2_APPEND_FL
| OCFS2_IMMUTABLE_FL
))) {
88 if (!capable(CAP_LINUX_IMMUTABLE
))
92 ocfs2_inode
->ip_attr
= flags
;
93 ocfs2_set_inode_flags(inode
);
95 status
= ocfs2_mark_inode_dirty(handle
, inode
, bh
);
99 ocfs2_commit_trans(osb
, handle
);
101 ocfs2_inode_unlock(inode
, 1);
103 mutex_unlock(&inode
->i_mutex
);
112 long ocfs2_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
114 struct inode
*inode
= filp
->f_path
.dentry
->d_inode
;
118 struct ocfs2_space_resv sr
;
119 struct ocfs2_new_group_input input
;
122 case OCFS2_IOC_GETFLAGS
:
123 status
= ocfs2_get_inode_attr(inode
, &flags
);
127 flags
&= OCFS2_FL_VISIBLE
;
128 return put_user(flags
, (int __user
*) arg
);
129 case OCFS2_IOC_SETFLAGS
:
130 if (get_user(flags
, (int __user
*) arg
))
133 status
= mnt_want_write(filp
->f_path
.mnt
);
136 status
= ocfs2_set_inode_attr(inode
, flags
,
137 OCFS2_FL_MODIFIABLE
);
138 mnt_drop_write(filp
->f_path
.mnt
);
140 case OCFS2_IOC_RESVSP
:
141 case OCFS2_IOC_RESVSP64
:
142 case OCFS2_IOC_UNRESVSP
:
143 case OCFS2_IOC_UNRESVSP64
:
144 if (copy_from_user(&sr
, (int __user
*) arg
, sizeof(sr
)))
147 return ocfs2_change_file_space(filp
, cmd
, &sr
);
148 case OCFS2_IOC_GROUP_EXTEND
:
149 if (!capable(CAP_SYS_RESOURCE
))
152 if (get_user(new_clusters
, (int __user
*)arg
))
155 return ocfs2_group_extend(inode
, new_clusters
);
156 case OCFS2_IOC_GROUP_ADD
:
157 case OCFS2_IOC_GROUP_ADD64
:
158 if (!capable(CAP_SYS_RESOURCE
))
161 if (copy_from_user(&input
, (int __user
*) arg
, sizeof(input
)))
164 return ocfs2_group_add(inode
, &input
);
171 long ocfs2_compat_ioctl(struct file
*file
, unsigned cmd
, unsigned long arg
)
174 case OCFS2_IOC32_GETFLAGS
:
175 cmd
= OCFS2_IOC_GETFLAGS
;
177 case OCFS2_IOC32_SETFLAGS
:
178 cmd
= OCFS2_IOC_SETFLAGS
;
180 case OCFS2_IOC_RESVSP
:
181 case OCFS2_IOC_RESVSP64
:
182 case OCFS2_IOC_UNRESVSP
:
183 case OCFS2_IOC_UNRESVSP64
:
184 case OCFS2_IOC_GROUP_EXTEND
:
185 case OCFS2_IOC_GROUP_ADD
:
186 case OCFS2_IOC_GROUP_ADD64
:
192 return ocfs2_ioctl(file
, cmd
, arg
);