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>
23 #include <linux/ext2_fs.h>
25 static int ocfs2_get_inode_attr(struct inode
*inode
, unsigned *flags
)
29 status
= ocfs2_meta_lock(inode
, NULL
, 0);
34 *flags
= OCFS2_I(inode
)->ip_attr
;
35 ocfs2_meta_unlock(inode
, 0);
41 static int ocfs2_set_inode_attr(struct inode
*inode
, unsigned flags
,
44 struct ocfs2_inode_info
*ocfs2_inode
= OCFS2_I(inode
);
45 struct ocfs2_super
*osb
= OCFS2_SB(inode
->i_sb
);
46 handle_t
*handle
= NULL
;
47 struct buffer_head
*bh
= NULL
;
51 mutex_lock(&inode
->i_mutex
);
53 status
= ocfs2_meta_lock(inode
, &bh
, 1);
64 if ((current
->fsuid
!= inode
->i_uid
) && !capable(CAP_FOWNER
))
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_meta_unlock(inode
, 1);
103 mutex_unlock(&inode
->i_mutex
);
112 int ocfs2_ioctl(struct inode
* inode
, struct file
* filp
,
113 unsigned int cmd
, unsigned long arg
)
119 case OCFS2_IOC_GETFLAGS
:
120 status
= ocfs2_get_inode_attr(inode
, &flags
);
124 flags
&= OCFS2_FL_VISIBLE
;
125 return put_user(flags
, (int __user
*) arg
);
126 case OCFS2_IOC_SETFLAGS
:
127 if (get_user(flags
, (int __user
*) arg
))
130 return ocfs2_set_inode_attr(inode
, flags
,
131 OCFS2_FL_MODIFIABLE
);