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>
24 #include <linux/ext2_fs.h>
26 static int ocfs2_get_inode_attr(struct inode
*inode
, unsigned *flags
)
30 status
= ocfs2_meta_lock(inode
, NULL
, 0);
35 ocfs2_get_inode_flags(OCFS2_I(inode
));
36 *flags
= OCFS2_I(inode
)->ip_attr
;
37 ocfs2_meta_unlock(inode
, 0);
43 static int ocfs2_set_inode_attr(struct inode
*inode
, unsigned flags
,
46 struct ocfs2_inode_info
*ocfs2_inode
= OCFS2_I(inode
);
47 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
48 handle_t
*handle
= NULL
;
49 struct buffer_head
*bh
= NULL
;
53 mutex_lock(&inode
->i_mutex
);
55 status
= ocfs2_meta_lock(inode
, &bh
, 1);
66 if (!is_owner_or_cap(inode
))
69 if (!S_ISDIR(inode
->i_mode
))
70 flags
&= ~OCFS2_DIRSYNC_FL
;
72 handle
= ocfs2_start_trans(osb
, OCFS2_INODE_UPDATE_CREDITS
);
74 status
= PTR_ERR(handle
);
79 oldflags
= ocfs2_inode
->ip_attr
;
81 flags
|= oldflags
& ~mask
;
84 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
85 * the relevant capability.
88 if ((oldflags
& OCFS2_IMMUTABLE_FL
) || ((flags
^ oldflags
) &
89 (OCFS2_APPEND_FL
| OCFS2_IMMUTABLE_FL
))) {
90 if (!capable(CAP_LINUX_IMMUTABLE
))
94 ocfs2_inode
->ip_attr
= flags
;
95 ocfs2_set_inode_flags(inode
);
97 status
= ocfs2_mark_inode_dirty(handle
, inode
, bh
);
101 ocfs2_commit_trans(osb
, handle
);
103 ocfs2_meta_unlock(inode
, 1);
105 mutex_unlock(&inode
->i_mutex
);
114 int ocfs2_ioctl(struct inode
* inode
, struct file
* filp
,
115 unsigned int cmd
, unsigned long arg
)
119 struct ocfs2_space_resv sr
;
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 return ocfs2_set_inode_attr(inode
, flags
,
134 OCFS2_FL_MODIFIABLE
);
135 case OCFS2_IOC_RESVSP
:
136 case OCFS2_IOC_RESVSP64
:
137 case OCFS2_IOC_UNRESVSP
:
138 case OCFS2_IOC_UNRESVSP64
:
139 if (copy_from_user(&sr
, (int __user
*) arg
, sizeof(sr
)))
142 return ocfs2_change_file_space(filp
, cmd
, &sr
);
149 long ocfs2_compat_ioctl(struct file
*file
, unsigned cmd
, unsigned long arg
)
151 struct inode
*inode
= file
->f_path
.dentry
->d_inode
;
155 case OCFS2_IOC32_GETFLAGS
:
156 cmd
= OCFS2_IOC_GETFLAGS
;
158 case OCFS2_IOC32_SETFLAGS
:
159 cmd
= OCFS2_IOC_SETFLAGS
;
161 case OCFS2_IOC_RESVSP
:
162 case OCFS2_IOC_RESVSP64
:
163 case OCFS2_IOC_UNRESVSP
:
164 case OCFS2_IOC_UNRESVSP64
:
171 ret
= ocfs2_ioctl(inode
, file
, cmd
, arg
);