0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/compat.h>
0016 #include <linux/mount.h>
0017 #include <linux/fileattr.h>
0018 #include "ubifs.h"
0019
0020
0021 #define UBIFS_SETTABLE_IOCTL_FLAGS \
0022 (FS_COMPR_FL | FS_SYNC_FL | FS_APPEND_FL | \
0023 FS_IMMUTABLE_FL | FS_DIRSYNC_FL)
0024
0025
0026 #define UBIFS_GETTABLE_IOCTL_FLAGS \
0027 (UBIFS_SETTABLE_IOCTL_FLAGS | FS_ENCRYPT_FL)
0028
0029
0030
0031
0032
0033
0034
0035 void ubifs_set_inode_flags(struct inode *inode)
0036 {
0037 unsigned int flags = ubifs_inode(inode)->flags;
0038
0039 inode->i_flags &= ~(S_SYNC | S_APPEND | S_IMMUTABLE | S_DIRSYNC |
0040 S_ENCRYPTED);
0041 if (flags & UBIFS_SYNC_FL)
0042 inode->i_flags |= S_SYNC;
0043 if (flags & UBIFS_APPEND_FL)
0044 inode->i_flags |= S_APPEND;
0045 if (flags & UBIFS_IMMUTABLE_FL)
0046 inode->i_flags |= S_IMMUTABLE;
0047 if (flags & UBIFS_DIRSYNC_FL)
0048 inode->i_flags |= S_DIRSYNC;
0049 if (flags & UBIFS_CRYPT_FL)
0050 inode->i_flags |= S_ENCRYPTED;
0051 }
0052
0053
0054
0055
0056
0057
0058
0059
0060 static int ioctl2ubifs(int ioctl_flags)
0061 {
0062 int ubifs_flags = 0;
0063
0064 if (ioctl_flags & FS_COMPR_FL)
0065 ubifs_flags |= UBIFS_COMPR_FL;
0066 if (ioctl_flags & FS_SYNC_FL)
0067 ubifs_flags |= UBIFS_SYNC_FL;
0068 if (ioctl_flags & FS_APPEND_FL)
0069 ubifs_flags |= UBIFS_APPEND_FL;
0070 if (ioctl_flags & FS_IMMUTABLE_FL)
0071 ubifs_flags |= UBIFS_IMMUTABLE_FL;
0072 if (ioctl_flags & FS_DIRSYNC_FL)
0073 ubifs_flags |= UBIFS_DIRSYNC_FL;
0074
0075 return ubifs_flags;
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085 static int ubifs2ioctl(int ubifs_flags)
0086 {
0087 int ioctl_flags = 0;
0088
0089 if (ubifs_flags & UBIFS_COMPR_FL)
0090 ioctl_flags |= FS_COMPR_FL;
0091 if (ubifs_flags & UBIFS_SYNC_FL)
0092 ioctl_flags |= FS_SYNC_FL;
0093 if (ubifs_flags & UBIFS_APPEND_FL)
0094 ioctl_flags |= FS_APPEND_FL;
0095 if (ubifs_flags & UBIFS_IMMUTABLE_FL)
0096 ioctl_flags |= FS_IMMUTABLE_FL;
0097 if (ubifs_flags & UBIFS_DIRSYNC_FL)
0098 ioctl_flags |= FS_DIRSYNC_FL;
0099 if (ubifs_flags & UBIFS_CRYPT_FL)
0100 ioctl_flags |= FS_ENCRYPT_FL;
0101
0102 return ioctl_flags;
0103 }
0104
0105 static int setflags(struct inode *inode, int flags)
0106 {
0107 int err, release;
0108 struct ubifs_inode *ui = ubifs_inode(inode);
0109 struct ubifs_info *c = inode->i_sb->s_fs_info;
0110 struct ubifs_budget_req req = { .dirtied_ino = 1,
0111 .dirtied_ino_d = ALIGN(ui->data_len, 8) };
0112
0113 err = ubifs_budget_space(c, &req);
0114 if (err)
0115 return err;
0116
0117 mutex_lock(&ui->ui_mutex);
0118 ui->flags &= ~ioctl2ubifs(UBIFS_SETTABLE_IOCTL_FLAGS);
0119 ui->flags |= ioctl2ubifs(flags);
0120 ubifs_set_inode_flags(inode);
0121 inode->i_ctime = current_time(inode);
0122 release = ui->dirty;
0123 mark_inode_dirty_sync(inode);
0124 mutex_unlock(&ui->ui_mutex);
0125
0126 if (release)
0127 ubifs_release_budget(c, &req);
0128 if (IS_SYNC(inode))
0129 err = write_inode_now(inode, 1);
0130 return err;
0131 }
0132
0133 int ubifs_fileattr_get(struct dentry *dentry, struct fileattr *fa)
0134 {
0135 struct inode *inode = d_inode(dentry);
0136 int flags = ubifs2ioctl(ubifs_inode(inode)->flags);
0137
0138 if (d_is_special(dentry))
0139 return -ENOTTY;
0140
0141 dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags);
0142 fileattr_fill_flags(fa, flags);
0143
0144 return 0;
0145 }
0146
0147 int ubifs_fileattr_set(struct user_namespace *mnt_userns,
0148 struct dentry *dentry, struct fileattr *fa)
0149 {
0150 struct inode *inode = d_inode(dentry);
0151 int flags = fa->flags;
0152
0153 if (d_is_special(dentry))
0154 return -ENOTTY;
0155
0156 if (fileattr_has_fsx(fa))
0157 return -EOPNOTSUPP;
0158
0159 if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS)
0160 return -EOPNOTSUPP;
0161
0162 flags &= UBIFS_SETTABLE_IOCTL_FLAGS;
0163
0164 if (!S_ISDIR(inode->i_mode))
0165 flags &= ~FS_DIRSYNC_FL;
0166
0167 dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags);
0168 return setflags(inode, flags);
0169 }
0170
0171 long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0172 {
0173 int err;
0174 struct inode *inode = file_inode(file);
0175
0176 switch (cmd) {
0177 case FS_IOC_SET_ENCRYPTION_POLICY: {
0178 struct ubifs_info *c = inode->i_sb->s_fs_info;
0179
0180 err = ubifs_enable_encryption(c);
0181 if (err)
0182 return err;
0183
0184 return fscrypt_ioctl_set_policy(file, (const void __user *)arg);
0185 }
0186 case FS_IOC_GET_ENCRYPTION_POLICY:
0187 return fscrypt_ioctl_get_policy(file, (void __user *)arg);
0188
0189 case FS_IOC_GET_ENCRYPTION_POLICY_EX:
0190 return fscrypt_ioctl_get_policy_ex(file, (void __user *)arg);
0191
0192 case FS_IOC_ADD_ENCRYPTION_KEY:
0193 return fscrypt_ioctl_add_key(file, (void __user *)arg);
0194
0195 case FS_IOC_REMOVE_ENCRYPTION_KEY:
0196 return fscrypt_ioctl_remove_key(file, (void __user *)arg);
0197
0198 case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
0199 return fscrypt_ioctl_remove_key_all_users(file,
0200 (void __user *)arg);
0201 case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
0202 return fscrypt_ioctl_get_key_status(file, (void __user *)arg);
0203
0204 case FS_IOC_GET_ENCRYPTION_NONCE:
0205 return fscrypt_ioctl_get_nonce(file, (void __user *)arg);
0206
0207 default:
0208 return -ENOTTY;
0209 }
0210 }
0211
0212 #ifdef CONFIG_COMPAT
0213 long ubifs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0214 {
0215 switch (cmd) {
0216 case FS_IOC32_GETFLAGS:
0217 cmd = FS_IOC_GETFLAGS;
0218 break;
0219 case FS_IOC32_SETFLAGS:
0220 cmd = FS_IOC_SETFLAGS;
0221 break;
0222 case FS_IOC_SET_ENCRYPTION_POLICY:
0223 case FS_IOC_GET_ENCRYPTION_POLICY:
0224 case FS_IOC_GET_ENCRYPTION_POLICY_EX:
0225 case FS_IOC_ADD_ENCRYPTION_KEY:
0226 case FS_IOC_REMOVE_ENCRYPTION_KEY:
0227 case FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS:
0228 case FS_IOC_GET_ENCRYPTION_KEY_STATUS:
0229 case FS_IOC_GET_ENCRYPTION_NONCE:
0230 break;
0231 default:
0232 return -ENOIOCTLCMD;
0233 }
0234 return ubifs_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
0235 }
0236 #endif