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>
11 #define MLOG_MASK_PREFIX ML_INODE
12 #include <cluster/masklog.h>
25 #include <linux/ext2_fs.h>
27 static int ocfs2_get_inode_attr(struct inode
*inode
, unsigned *flags
)
31 status
= ocfs2_inode_lock(inode
, NULL
, 0);
36 ocfs2_get_inode_flags(OCFS2_I(inode
));
37 *flags
= OCFS2_I(inode
)->ip_attr
;
38 ocfs2_inode_unlock(inode
, 0);
44 static int ocfs2_set_inode_attr(struct inode
*inode
, unsigned flags
,
47 struct ocfs2_inode_info
*ocfs2_inode
= OCFS2_I(inode
);
48 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
49 handle_t
*handle
= NULL
;
50 struct buffer_head
*bh
= NULL
;
54 mutex_lock(&inode
->i_mutex
);
56 status
= ocfs2_inode_lock(inode
, &bh
, 1);
67 if (!is_owner_or_cap(inode
))
70 if (!S_ISDIR(inode
->i_mode
))
71 flags
&= ~OCFS2_DIRSYNC_FL
;
73 handle
= ocfs2_start_trans(osb
, OCFS2_INODE_UPDATE_CREDITS
);
75 status
= PTR_ERR(handle
);
80 oldflags
= ocfs2_inode
->ip_attr
;
82 flags
|= oldflags
& ~mask
;
85 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
86 * the relevant capability.
89 if ((oldflags
& OCFS2_IMMUTABLE_FL
) || ((flags
^ oldflags
) &
90 (OCFS2_APPEND_FL
| OCFS2_IMMUTABLE_FL
))) {
91 if (!capable(CAP_LINUX_IMMUTABLE
))
95 ocfs2_inode
->ip_attr
= flags
;
96 ocfs2_set_inode_flags(inode
);
98 status
= ocfs2_mark_inode_dirty(handle
, inode
, bh
);
102 ocfs2_commit_trans(osb
, handle
);
104 ocfs2_inode_unlock(inode
, 1);
106 mutex_unlock(&inode
->i_mutex
);
115 int ocfs2_ioctl(struct inode
* inode
, struct file
* filp
,
116 unsigned int cmd
, unsigned long arg
)
121 struct ocfs2_space_resv sr
;
122 struct ocfs2_new_group_input input
;
125 case OCFS2_IOC_GETFLAGS
:
126 status
= ocfs2_get_inode_attr(inode
, &flags
);
130 flags
&= OCFS2_FL_VISIBLE
;
131 return put_user(flags
, (int __user
*) arg
);
132 case OCFS2_IOC_SETFLAGS
:
133 if (get_user(flags
, (int __user
*) arg
))
136 return ocfs2_set_inode_attr(inode
, flags
,
137 OCFS2_FL_MODIFIABLE
);
138 case OCFS2_IOC_RESVSP
:
139 case OCFS2_IOC_RESVSP64
:
140 case OCFS2_IOC_UNRESVSP
:
141 case OCFS2_IOC_UNRESVSP64
:
142 if (copy_from_user(&sr
, (int __user
*) arg
, sizeof(sr
)))
145 return ocfs2_change_file_space(filp
, cmd
, &sr
);
146 case OCFS2_IOC_GROUP_EXTEND
:
147 if (!capable(CAP_SYS_RESOURCE
))
150 if (get_user(new_clusters
, (int __user
*)arg
))
153 return ocfs2_group_extend(inode
, new_clusters
);
154 case OCFS2_IOC_GROUP_ADD
:
155 case OCFS2_IOC_GROUP_ADD64
:
156 if (!capable(CAP_SYS_RESOURCE
))
159 if (copy_from_user(&input
, (int __user
*) arg
, sizeof(input
)))
162 return ocfs2_group_add(inode
, &input
);
169 long ocfs2_compat_ioctl(struct file
*file
, unsigned cmd
, unsigned long arg
)
171 struct inode
*inode
= file
->f_path
.dentry
->d_inode
;
175 case OCFS2_IOC32_GETFLAGS
:
176 cmd
= OCFS2_IOC_GETFLAGS
;
178 case OCFS2_IOC32_SETFLAGS
:
179 cmd
= OCFS2_IOC_SETFLAGS
;
181 case OCFS2_IOC_RESVSP
:
182 case OCFS2_IOC_RESVSP64
:
183 case OCFS2_IOC_UNRESVSP
:
184 case OCFS2_IOC_UNRESVSP64
:
185 case OCFS2_IOC_GROUP_EXTEND
:
186 case OCFS2_IOC_GROUP_ADD
:
187 case OCFS2_IOC_GROUP_ADD64
:
194 ret
= ocfs2_ioctl(inode
, file
, cmd
, arg
);