|
13 | 13 | #include <linux/compat.h>
|
14 | 14 | #include <linux/falloc.h>
|
15 | 15 | #include <linux/fiemap.h>
|
| 16 | +#include <linux/fileattr.h> |
16 | 17 |
|
17 | 18 | #include "debug.h"
|
18 | 19 | #include "ntfs.h"
|
@@ -48,6 +49,62 @@ static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
|
48 | 49 | return 0;
|
49 | 50 | }
|
50 | 51 |
|
| 52 | +/* |
| 53 | + * ntfs_fileattr_get - inode_operations::fileattr_get |
| 54 | + */ |
| 55 | +int ntfs_fileattr_get(struct dentry *dentry, struct fileattr *fa) |
| 56 | +{ |
| 57 | + struct inode *inode = d_inode(dentry); |
| 58 | + struct ntfs_inode *ni = ntfs_i(inode); |
| 59 | + u32 flags = 0; |
| 60 | + |
| 61 | + if (inode->i_flags & S_IMMUTABLE) |
| 62 | + flags |= FS_IMMUTABLE_FL; |
| 63 | + |
| 64 | + if (inode->i_flags & S_APPEND) |
| 65 | + flags |= FS_APPEND_FL; |
| 66 | + |
| 67 | + if (is_compressed(ni)) |
| 68 | + flags |= FS_COMPR_FL; |
| 69 | + |
| 70 | + if (is_encrypted(ni)) |
| 71 | + flags |= FS_ENCRYPT_FL; |
| 72 | + |
| 73 | + fileattr_fill_flags(fa, flags); |
| 74 | + |
| 75 | + return 0; |
| 76 | +} |
| 77 | + |
| 78 | +/* |
| 79 | + * ntfs_fileattr_set - inode_operations::fileattr_set |
| 80 | + */ |
| 81 | +int ntfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, |
| 82 | + struct fileattr *fa) |
| 83 | +{ |
| 84 | + struct inode *inode = d_inode(dentry); |
| 85 | + u32 flags = fa->flags; |
| 86 | + unsigned int new_fl = 0; |
| 87 | + |
| 88 | + if (fileattr_has_fsx(fa)) |
| 89 | + return -EOPNOTSUPP; |
| 90 | + |
| 91 | + if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL)) |
| 92 | + return -EOPNOTSUPP; |
| 93 | + |
| 94 | + if (flags & FS_IMMUTABLE_FL) |
| 95 | + new_fl |= S_IMMUTABLE; |
| 96 | + |
| 97 | + if (flags & FS_APPEND_FL) |
| 98 | + new_fl |= S_APPEND; |
| 99 | + |
| 100 | + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); |
| 101 | + |
| 102 | + inode_set_ctime_current(inode); |
| 103 | + mark_inode_dirty(inode); |
| 104 | + |
| 105 | + return 0; |
| 106 | +} |
| 107 | + |
51 | 108 | long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
|
52 | 109 | {
|
53 | 110 | struct inode *inode = file_inode(filp);
|
@@ -77,20 +134,27 @@ int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
77 | 134 | struct inode *inode = d_inode(path->dentry);
|
78 | 135 | struct ntfs_inode *ni = ntfs_i(inode);
|
79 | 136 |
|
| 137 | + stat->result_mask |= STATX_BTIME; |
| 138 | + stat->btime = ni->i_crtime; |
| 139 | + stat->blksize = ni->mi.sbi->cluster_size; /* 512, 1K, ..., 2M */ |
| 140 | + |
| 141 | + if (inode->i_flags & S_IMMUTABLE) |
| 142 | + stat->attributes |= STATX_ATTR_IMMUTABLE; |
| 143 | + |
| 144 | + if (inode->i_flags & S_APPEND) |
| 145 | + stat->attributes |= STATX_ATTR_APPEND; |
| 146 | + |
80 | 147 | if (is_compressed(ni))
|
81 | 148 | stat->attributes |= STATX_ATTR_COMPRESSED;
|
82 | 149 |
|
83 | 150 | if (is_encrypted(ni))
|
84 | 151 | stat->attributes |= STATX_ATTR_ENCRYPTED;
|
85 | 152 |
|
86 |
| - stat->attributes_mask |= STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED; |
| 153 | + stat->attributes_mask |= STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED | |
| 154 | + STATX_ATTR_IMMUTABLE | STATX_ATTR_APPEND; |
87 | 155 |
|
88 | 156 | generic_fillattr(idmap, request_mask, inode, stat);
|
89 | 157 |
|
90 |
| - stat->result_mask |= STATX_BTIME; |
91 |
| - stat->btime = ni->i_crtime; |
92 |
| - stat->blksize = ni->mi.sbi->cluster_size; /* 512, 1K, ..., 2M */ |
93 |
| - |
94 | 158 | return 0;
|
95 | 159 | }
|
96 | 160 |
|
@@ -1223,6 +1287,8 @@ const struct inode_operations ntfs_file_inode_operations = {
|
1223 | 1287 | .get_acl = ntfs_get_acl,
|
1224 | 1288 | .set_acl = ntfs_set_acl,
|
1225 | 1289 | .fiemap = ntfs_fiemap,
|
| 1290 | + .fileattr_get = ntfs_fileattr_get, |
| 1291 | + .fileattr_set = ntfs_fileattr_set, |
1226 | 1292 | };
|
1227 | 1293 |
|
1228 | 1294 | const struct file_operations ntfs_file_operations = {
|
|
0 commit comments