1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Pocessing of EA's
4 *
5 * Part of this file is based on code from the NTFS-3G.
6 *
7 * Copyright (c) 2014-2021 Jean-Pierre Andre
8 * Copyright (c) 2025 LG Electronics Co., Ltd.
9 */
10
11 #include <linux/fs.h>
12 #include <linux/posix_acl.h>
13 #include <linux/posix_acl_xattr.h>
14 #include <linux/xattr.h>
15
16 #include "layout.h"
17 #include "attrib.h"
18 #include "index.h"
19 #include "dir.h"
20 #include "ea.h"
21
ntfs_write_ea(struct ntfs_inode * ni,__le32 type,char * value,s64 ea_off,s64 ea_size,bool need_truncate)22 static int ntfs_write_ea(struct ntfs_inode *ni, __le32 type, char *value, s64 ea_off,
23 s64 ea_size, bool need_truncate)
24 {
25 struct inode *ea_vi;
26 int err = 0;
27 s64 written;
28
29 ea_vi = ntfs_attr_iget(VFS_I(ni), type, AT_UNNAMED, 0);
30 if (IS_ERR(ea_vi))
31 return PTR_ERR(ea_vi);
32
33 written = ntfs_inode_attr_pwrite(ea_vi, ea_off, ea_size, value, false);
34 if (written != ea_size)
35 err = -EIO;
36 else {
37 struct ntfs_inode *ea_ni = NTFS_I(ea_vi);
38
39 if (need_truncate && ea_ni->data_size > ea_off + ea_size)
40 ntfs_attr_truncate(ea_ni, ea_off + ea_size);
41 mark_mft_record_dirty(ni);
42 }
43
44 iput(ea_vi);
45 return err;
46 }
47
ntfs_ea_lookup(char * ea_buf,s64 ea_buf_size,const char * name,int name_len,s64 * ea_offset,s64 * ea_size)48 static int ntfs_ea_lookup(char *ea_buf, s64 ea_buf_size, const char *name,
49 int name_len, s64 *ea_offset, s64 *ea_size)
50 {
51 const struct ea_attr *p_ea;
52 size_t actual_size;
53 loff_t offset, p_ea_size;
54 unsigned int next;
55
56 if (ea_buf_size < sizeof(struct ea_attr))
57 goto out;
58
59 offset = 0;
60 do {
61 p_ea = (const struct ea_attr *)&ea_buf[offset];
62 next = le32_to_cpu(p_ea->next_entry_offset);
63 p_ea_size = next ? next : (ea_buf_size - offset);
64
65 if (p_ea_size < sizeof(struct ea_attr) ||
66 offset + p_ea_size > ea_buf_size)
67 break;
68
69 if ((s64)p_ea->ea_name_length + 1 >
70 p_ea_size - offsetof(struct ea_attr, ea_name))
71 break;
72
73 actual_size = ALIGN(struct_size(p_ea, ea_name, 1 + p_ea->ea_name_length +
74 le16_to_cpu(p_ea->ea_value_length)), 4);
75 if (actual_size > p_ea_size)
76 break;
77
78 if (p_ea->ea_name_length == name_len &&
79 !memcmp(p_ea->ea_name, name, name_len)) {
80 *ea_offset = offset;
81 *ea_size = next ? next : actual_size;
82
83 if (ea_buf_size < *ea_offset + *ea_size)
84 goto out;
85
86 return 0;
87 }
88 offset += next;
89 } while (next > 0 && offset < ea_buf_size);
90
91 out:
92 return -ENOENT;
93 }
94
95 /*
96 * Return the existing EA
97 *
98 * The EA_INFORMATION is not examined and the consistency of the
99 * existing EA is not checked.
100 *
101 * If successful, the full attribute is returned unchanged
102 * and its size is returned.
103 * If the designated buffer is too small, the needed size is
104 * returned, and the buffer is left unchanged.
105 * If there is an error, a negative value is returned and errno
106 * is set according to the error.
107 */
ntfs_get_ea(struct inode * inode,const char * name,size_t name_len,void * buffer,size_t size)108 static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
109 void *buffer, size_t size)
110 {
111 struct ntfs_inode *ni = NTFS_I(inode);
112 const struct ea_attr *p_ea;
113 char *ea_buf;
114 s64 ea_off, ea_size, all_ea_size, ea_info_size;
115 int err;
116 u32 ea_info_qlen;
117 u16 ea_value_len;
118 struct ea_information *p_ea_info;
119
120 if (!NInoHasEA(ni))
121 return -ENODATA;
122
123 p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
124 &ea_info_size);
125 if (!p_ea_info || ea_info_size != sizeof(struct ea_information)) {
126 kvfree(p_ea_info);
127 return -ENODATA;
128 }
129
130 ea_info_qlen = le32_to_cpu(p_ea_info->ea_query_length);
131 kvfree(p_ea_info);
132
133 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
134 if (!ea_buf)
135 return -ENODATA;
136
137 if (ea_info_qlen > all_ea_size) {
138 err = -EIO;
139 goto free_ea_buf;
140 }
141
142 err = ntfs_ea_lookup(ea_buf, ea_info_qlen, name, name_len, &ea_off,
143 &ea_size);
144 if (!err) {
145 p_ea = (struct ea_attr *)&ea_buf[ea_off];
146 ea_value_len = le16_to_cpu(p_ea->ea_value_length);
147 if (!buffer) {
148 kvfree(ea_buf);
149 return ea_value_len;
150 }
151
152 if (ea_value_len > size) {
153 err = -ERANGE;
154 goto free_ea_buf;
155 }
156
157 memcpy(buffer, &p_ea->ea_name[p_ea->ea_name_length + 1],
158 ea_value_len);
159 kvfree(ea_buf);
160 return ea_value_len;
161 }
162
163 err = -ENODATA;
164 free_ea_buf:
165 kvfree(ea_buf);
166 return err;
167 }
168
ea_packed_size(const struct ea_attr * p_ea)169 static inline int ea_packed_size(const struct ea_attr *p_ea)
170 {
171 /*
172 * 4 bytes for header (flags and lengths) + name length + 1 +
173 * value length.
174 */
175 return 5 + p_ea->ea_name_length + le16_to_cpu(p_ea->ea_value_length);
176 }
177
178 /*
179 * Set a new EA, and set EA_INFORMATION accordingly
180 *
181 * This is roughly the same as ZwSetEaFile() on Windows, however
182 * the "offset to next" of the last EA should not be cleared.
183 *
184 * Consistency of the new EA is first checked.
185 *
186 * EA_INFORMATION is set first, and it is restored to its former
187 * state if setting EA fails.
188 */
ntfs_set_ea(struct inode * inode,const char * name,size_t name_len,const void * value,size_t val_size,int flags,__le16 * packed_ea_size)189 static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
190 const void *value, size_t val_size, int flags,
191 __le16 *packed_ea_size)
192 {
193 struct ntfs_inode *ni = NTFS_I(inode);
194 struct ea_information *p_ea_info = NULL;
195 int ea_packed, err = 0;
196 struct ea_attr *p_ea;
197 u32 ea_info_qsize = 0;
198 char *ea_buf = NULL;
199 size_t new_ea_size = ALIGN(struct_size(p_ea, ea_name, 1 + name_len + val_size), 4);
200 s64 ea_off, ea_info_size, all_ea_size, ea_size;
201
202 if (name_len > 255)
203 return -ENAMETOOLONG;
204
205 if (ntfs_attr_exist(ni, AT_EA_INFORMATION, AT_UNNAMED, 0)) {
206 p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
207 &ea_info_size);
208 if (!p_ea_info || ea_info_size != sizeof(struct ea_information))
209 goto out;
210
211 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
212 if (!ea_buf) {
213 ea_info_qsize = 0;
214 kvfree(p_ea_info);
215 goto create_ea_info;
216 }
217
218 ea_info_qsize = le32_to_cpu(p_ea_info->ea_query_length);
219 } else {
220 create_ea_info:
221 p_ea_info = kzalloc(sizeof(struct ea_information), GFP_NOFS);
222 if (!p_ea_info)
223 return -ENOMEM;
224
225 ea_info_qsize = 0;
226 err = ntfs_attr_add(ni, AT_EA_INFORMATION, AT_UNNAMED, 0,
227 (char *)p_ea_info, sizeof(struct ea_information));
228 if (err)
229 goto out;
230
231 if (ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
232 err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
233 if (err)
234 goto out;
235 }
236
237 goto alloc_new_ea;
238 }
239
240 if (ea_info_qsize > all_ea_size) {
241 err = -EIO;
242 goto out;
243 }
244
245 err = ntfs_ea_lookup(ea_buf, ea_info_qsize, name, name_len, &ea_off,
246 &ea_size);
247 if (ea_info_qsize && !err) {
248 if (flags & XATTR_CREATE) {
249 err = -EEXIST;
250 goto out;
251 }
252
253 p_ea = (struct ea_attr *)(ea_buf + ea_off);
254
255 if (val_size &&
256 le16_to_cpu(p_ea->ea_value_length) == val_size &&
257 !memcmp(p_ea->ea_name + p_ea->ea_name_length + 1, value,
258 val_size))
259 goto out;
260
261 le16_add_cpu(&p_ea_info->ea_length, 0 - ea_packed_size(p_ea));
262
263 if (p_ea->flags & NEED_EA)
264 le16_add_cpu(&p_ea_info->need_ea_count, -1);
265
266 memmove((char *)p_ea, (char *)p_ea + ea_size, ea_info_qsize - (ea_off + ea_size));
267 ea_info_qsize -= ea_size;
268 p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize);
269
270 err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info, 0,
271 sizeof(struct ea_information), false);
272 if (err)
273 goto out;
274
275 err = ntfs_write_ea(ni, AT_EA, ea_buf, 0, ea_info_qsize, true);
276 if (err)
277 goto out;
278
279 if ((flags & XATTR_REPLACE) && !val_size) {
280 /* Remove xattr. */
281 goto out;
282 }
283 } else {
284 if (flags & XATTR_REPLACE) {
285 err = -ENODATA;
286 goto out;
287 }
288 }
289 kvfree(ea_buf);
290
291 alloc_new_ea:
292 ea_buf = kzalloc(new_ea_size, GFP_NOFS);
293 if (!ea_buf) {
294 err = -ENOMEM;
295 goto out;
296 }
297
298 /*
299 * EA and REPARSE_POINT compatibility not checked any more,
300 * required by Windows 10, but having both may lead to
301 * problems with earlier versions.
302 */
303 p_ea = (struct ea_attr *)ea_buf;
304 memcpy(p_ea->ea_name, name, name_len);
305 p_ea->ea_name_length = name_len;
306 p_ea->ea_name[name_len] = 0;
307 memcpy(p_ea->ea_name + name_len + 1, value, val_size);
308 p_ea->ea_value_length = cpu_to_le16(val_size);
309 p_ea->next_entry_offset = cpu_to_le32(new_ea_size);
310
311 ea_packed = le16_to_cpu(p_ea_info->ea_length) + ea_packed_size(p_ea);
312 p_ea_info->ea_length = cpu_to_le16(ea_packed);
313 p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize + new_ea_size);
314
315 if (ea_packed > 0xffff ||
316 ntfs_attr_size_bounds_check(ni->vol, AT_EA, new_ea_size)) {
317 err = -EFBIG;
318 goto out;
319 }
320
321 /*
322 * no EA or EA_INFORMATION : add them
323 */
324 if (!ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
325 err = ntfs_attr_add(ni, AT_EA, AT_UNNAMED, 0, (char *)p_ea,
326 new_ea_size);
327 if (err)
328 goto out;
329 } else {
330 err = ntfs_write_ea(ni, AT_EA, (char *)p_ea, ea_info_qsize,
331 new_ea_size, false);
332 if (err)
333 goto out;
334 }
335
336 err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info, 0,
337 sizeof(struct ea_information), false);
338 if (err)
339 goto out;
340
341 if (packed_ea_size)
342 *packed_ea_size = p_ea_info->ea_length;
343 mark_mft_record_dirty(ni);
344 out:
345 if (ea_info_qsize > 0)
346 NInoSetHasEA(ni);
347 else
348 NInoClearHasEA(ni);
349
350 kvfree(ea_buf);
351 kvfree(p_ea_info);
352
353 return err;
354 }
355
356 /*
357 * Check for the presence of an EA "$LXDEV" (used by WSL)
358 * and return its value as a device address
359 */
ntfs_ea_get_wsl_inode(struct inode * inode,dev_t * rdevp,unsigned int flags)360 int ntfs_ea_get_wsl_inode(struct inode *inode, dev_t *rdevp, unsigned int flags)
361 {
362 int err;
363 __le32 v;
364
365 if (!(flags & NTFS_VOL_UID)) {
366 /* Load uid to lxuid EA */
367 err = ntfs_get_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
368 sizeof(v));
369 if (err < 0)
370 return err;
371 if (err != sizeof(v))
372 return -EIO;
373 i_uid_write(inode, le32_to_cpu(v));
374 }
375
376 if (!(flags & NTFS_VOL_GID)) {
377 /* Load gid to lxgid EA */
378 err = ntfs_get_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
379 sizeof(v));
380 if (err < 0)
381 return err;
382 if (err != sizeof(v))
383 return -EIO;
384 i_gid_write(inode, le32_to_cpu(v));
385 }
386
387 /* Load mode to lxmod EA */
388 err = ntfs_get_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v, sizeof(v));
389 if (err == sizeof(v)) {
390 inode->i_mode = le32_to_cpu(v);
391 } else {
392 /* Everyone gets all permissions. */
393 inode->i_mode |= 0777;
394 }
395
396 /* Load mode to lxdev EA */
397 err = ntfs_get_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v));
398 if (err == sizeof(v))
399 *rdevp = le32_to_cpu(v);
400 err = 0;
401
402 return err;
403 }
404
ntfs_ea_set_wsl_inode(struct inode * inode,dev_t rdev,__le16 * ea_size,unsigned int flags)405 int ntfs_ea_set_wsl_inode(struct inode *inode, dev_t rdev, __le16 *ea_size,
406 unsigned int flags)
407 {
408 __le32 v;
409 int err = 0;
410
411 if (ea_size)
412 *ea_size = 0;
413
414 if (flags & NTFS_EA_UID) {
415 /* Store uid to lxuid EA */
416 v = cpu_to_le32(i_uid_read(inode));
417 err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
418 sizeof(v), 0, ea_size);
419 if (err)
420 return err;
421 }
422
423 if (flags & NTFS_EA_GID) {
424 /* Store gid to lxgid EA */
425 v = cpu_to_le32(i_gid_read(inode));
426 err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
427 sizeof(v), 0, ea_size);
428 if (err)
429 return err;
430 }
431
432 if (flags & NTFS_EA_MODE) {
433 /* Store mode to lxmod EA */
434 v = cpu_to_le32(inode->i_mode);
435 err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v,
436 sizeof(v), 0, ea_size);
437 if (err)
438 return err;
439 }
440
441 if (rdev) {
442 v = cpu_to_le32(rdev);
443 err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v),
444 0, ea_size);
445 }
446
447 return err;
448 }
449
ntfs_listxattr(struct dentry * dentry,char * buffer,size_t size)450 ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
451 {
452 struct inode *inode = d_inode(dentry);
453 struct ntfs_inode *ni = NTFS_I(inode);
454 const struct ea_attr *p_ea;
455 s64 offset, ea_buf_size, ea_info_size;
456 s64 ea_size;
457 u32 next;
458 int err = 0;
459 u32 ea_info_qsize;
460 char *ea_buf = NULL;
461 ssize_t ret = 0;
462 struct ea_information *ea_info;
463
464 if (!NInoHasEA(ni))
465 return 0;
466
467 mutex_lock(&NTFS_I(inode)->mrec_lock);
468 ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
469 &ea_info_size);
470 if (!ea_info || ea_info_size != sizeof(struct ea_information))
471 goto out;
472
473 ea_info_qsize = le32_to_cpu(ea_info->ea_query_length);
474
475 ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &ea_buf_size);
476 if (!ea_buf)
477 goto out;
478
479 if (ea_info_qsize > ea_buf_size || ea_info_qsize == 0)
480 goto out;
481
482 if (ea_info_qsize < sizeof(struct ea_attr)) {
483 err = -EIO;
484 goto out;
485 }
486
487 offset = 0;
488 do {
489 p_ea = (const struct ea_attr *)&ea_buf[offset];
490 next = le32_to_cpu(p_ea->next_entry_offset);
491 ea_size = next ? next : (ea_info_qsize - offset);
492
493 if (ea_size < sizeof(struct ea_attr) ||
494 offset + ea_size > ea_info_qsize) {
495 err = -EIO;
496 goto out;
497 }
498
499 if ((int)p_ea->ea_name_length + 1 >
500 ea_size - offsetof(struct ea_attr, ea_name)) {
501 err = -EIO;
502 goto out;
503 }
504
505 if (buffer) {
506 if (ret + p_ea->ea_name_length + 1 > size) {
507 err = -ERANGE;
508 goto out;
509 }
510
511 memcpy(buffer + ret, p_ea->ea_name, p_ea->ea_name_length);
512 buffer[ret + p_ea->ea_name_length] = 0;
513 }
514
515 ret += p_ea->ea_name_length + 1;
516 offset += ea_size;
517 } while (next > 0 && offset < ea_info_qsize);
518
519 out:
520 mutex_unlock(&NTFS_I(inode)->mrec_lock);
521 kvfree(ea_info);
522 kvfree(ea_buf);
523
524 return err ? err : ret;
525 }
526
527 // clang-format off
528 #define SYSTEM_DOS_ATTRIB "system.dos_attrib"
529 #define SYSTEM_NTFS_ATTRIB "system.ntfs_attrib"
530 #define SYSTEM_NTFS_ATTRIB_BE "system.ntfs_attrib_be"
531 // clang-format on
532
ntfs_getxattr(const struct xattr_handler * handler,struct dentry * unused,struct inode * inode,const char * name,void * buffer,size_t size)533 static int ntfs_getxattr(const struct xattr_handler *handler,
534 struct dentry *unused, struct inode *inode, const char *name,
535 void *buffer, size_t size)
536 {
537 struct ntfs_inode *ni = NTFS_I(inode);
538 int err;
539
540 if (NVolShutdown(ni->vol))
541 return -EIO;
542
543 if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
544 if (!buffer) {
545 err = sizeof(u8);
546 } else if (size < sizeof(u8)) {
547 err = -ENODATA;
548 } else {
549 err = sizeof(u8);
550 *(u8 *)buffer = (u8)(le32_to_cpu(ni->flags) & 0x3F);
551 }
552 goto out;
553 }
554
555 if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
556 !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
557 if (!buffer) {
558 err = sizeof(u32);
559 } else if (size < sizeof(u32)) {
560 err = -ENODATA;
561 } else {
562 err = sizeof(u32);
563 *(u32 *)buffer = le32_to_cpu(ni->flags);
564 if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
565 *(__be32 *)buffer = cpu_to_be32(*(u32 *)buffer);
566 }
567 goto out;
568 }
569
570 mutex_lock(&ni->mrec_lock);
571 err = ntfs_get_ea(inode, name, strlen(name), buffer, size);
572 mutex_unlock(&ni->mrec_lock);
573
574 out:
575 return err;
576 }
577
ntfs_new_attr_flags(struct ntfs_inode * ni,__le32 fattr)578 static int ntfs_new_attr_flags(struct ntfs_inode *ni, __le32 fattr)
579 {
580 struct ntfs_attr_search_ctx *ctx;
581 struct mft_record *m;
582 struct attr_record *a;
583 __le16 new_aflags;
584 int mp_size, mp_ofs, name_ofs, arec_size, err;
585
586 m = map_mft_record(ni);
587 if (IS_ERR(m))
588 return PTR_ERR(m);
589
590 ctx = ntfs_attr_get_search_ctx(ni, m);
591 if (!ctx) {
592 err = -ENOMEM;
593 goto err_out;
594 }
595
596 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
597 CASE_SENSITIVE, 0, NULL, 0, ctx);
598 if (err) {
599 err = -EINVAL;
600 goto err_out;
601 }
602
603 a = ctx->attr;
604 new_aflags = ctx->attr->flags;
605
606 if (fattr & FILE_ATTR_SPARSE_FILE)
607 new_aflags |= ATTR_IS_SPARSE;
608 else
609 new_aflags &= ~ATTR_IS_SPARSE;
610
611 if (fattr & FILE_ATTR_COMPRESSED)
612 new_aflags |= ATTR_IS_COMPRESSED;
613 else
614 new_aflags &= ~ATTR_IS_COMPRESSED;
615
616 if (new_aflags == a->flags)
617 return 0;
618
619 if ((new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) ==
620 (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
621 pr_err("file can't be sparsed and compressed\n");
622 err = -EOPNOTSUPP;
623 goto err_out;
624 }
625
626 if (!a->non_resident)
627 goto out;
628
629 if (a->data.non_resident.data_size) {
630 pr_err("Can't change sparsed/compressed for non-empty file\n");
631 err = -EOPNOTSUPP;
632 goto err_out;
633 }
634
635 if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))
636 name_ofs = (offsetof(struct attr_record,
637 data.non_resident.compressed_size) +
638 sizeof(a->data.non_resident.compressed_size) + 7) & ~7;
639 else
640 name_ofs = (offsetof(struct attr_record,
641 data.non_resident.compressed_size) + 7) & ~7;
642
643 mp_size = ntfs_get_size_for_mapping_pairs(ni->vol, ni->runlist.rl, 0, -1, -1);
644 if (unlikely(mp_size < 0)) {
645 err = mp_size;
646 ntfs_debug("Failed to get size for mapping pairs array, error code %i.\n", err);
647 goto err_out;
648 }
649
650 mp_ofs = (name_ofs + a->name_length * sizeof(__le16) + 7) & ~7;
651 arec_size = (mp_ofs + mp_size + 7) & ~7;
652
653 err = ntfs_attr_record_resize(m, a, arec_size);
654 if (unlikely(err))
655 goto err_out;
656
657 if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
658 a->data.non_resident.compression_unit = 0;
659 if (new_aflags & ATTR_IS_COMPRESSED || ni->vol->major_ver < 3)
660 a->data.non_resident.compression_unit = 4;
661 a->data.non_resident.compressed_size = 0;
662 ni->itype.compressed.size = 0;
663 if (a->data.non_resident.compression_unit) {
664 ni->itype.compressed.block_size = 1U <<
665 (a->data.non_resident.compression_unit +
666 ni->vol->cluster_size_bits);
667 ni->itype.compressed.block_size_bits =
668 ffs(ni->itype.compressed.block_size) -
669 1;
670 ni->itype.compressed.block_clusters = 1U <<
671 a->data.non_resident.compression_unit;
672 } else {
673 ni->itype.compressed.block_size = 0;
674 ni->itype.compressed.block_size_bits = 0;
675 ni->itype.compressed.block_clusters = 0;
676 }
677
678 if (new_aflags & ATTR_IS_SPARSE) {
679 NInoSetSparse(ni);
680 ni->flags |= FILE_ATTR_SPARSE_FILE;
681 }
682
683 if (new_aflags & ATTR_IS_COMPRESSED) {
684 NInoSetCompressed(ni);
685 ni->flags |= FILE_ATTR_COMPRESSED;
686 }
687 } else {
688 ni->flags &= ~(FILE_ATTR_SPARSE_FILE | FILE_ATTR_COMPRESSED);
689 a->data.non_resident.compression_unit = 0;
690 NInoClearSparse(ni);
691 NInoClearCompressed(ni);
692 }
693
694 a->name_offset = cpu_to_le16(name_ofs);
695 a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);
696
697 out:
698 a->flags = new_aflags;
699 mark_mft_record_dirty(ctx->ntfs_ino);
700 err_out:
701 if (ctx)
702 ntfs_attr_put_search_ctx(ctx);
703 unmap_mft_record(ni);
704 return err;
705 }
706
ntfs_setxattr(const struct xattr_handler * handler,struct mnt_idmap * idmap,struct dentry * unused,struct inode * inode,const char * name,const void * value,size_t size,int flags)707 static int ntfs_setxattr(const struct xattr_handler *handler,
708 struct mnt_idmap *idmap, struct dentry *unused,
709 struct inode *inode, const char *name, const void *value,
710 size_t size, int flags)
711 {
712 struct ntfs_inode *ni = NTFS_I(inode);
713 int err;
714 __le32 fattr;
715
716 if (NVolShutdown(ni->vol))
717 return -EIO;
718
719 if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
720 if (sizeof(u8) != size) {
721 err = -EINVAL;
722 goto out;
723 }
724 fattr = cpu_to_le32(*(u8 *)value);
725 goto set_fattr;
726 }
727
728 if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
729 !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
730 if (size != sizeof(u32)) {
731 err = -EINVAL;
732 goto out;
733 }
734 if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
735 fattr = cpu_to_le32(be32_to_cpu(*(__be32 *)value));
736 else
737 fattr = cpu_to_le32(*(u32 *)value);
738
739 if (S_ISREG(inode->i_mode)) {
740 mutex_lock(&ni->mrec_lock);
741 err = ntfs_new_attr_flags(ni, fattr);
742 mutex_unlock(&ni->mrec_lock);
743 if (err)
744 goto out;
745 }
746
747 set_fattr:
748 if (S_ISDIR(inode->i_mode))
749 fattr |= FILE_ATTR_DIRECTORY;
750 else
751 fattr &= ~FILE_ATTR_DIRECTORY;
752
753 if (ni->flags != fattr) {
754 ni->flags = fattr;
755 if (fattr & FILE_ATTR_READONLY)
756 inode->i_mode &= ~0222;
757 else
758 inode->i_mode |= 0222;
759 NInoSetFileNameDirty(ni);
760 mark_inode_dirty(inode);
761 }
762 err = 0;
763 goto out;
764 }
765
766 mutex_lock(&ni->mrec_lock);
767 err = ntfs_set_ea(inode, name, strlen(name), value, size, flags, NULL);
768 mutex_unlock(&ni->mrec_lock);
769
770 out:
771 inode_set_ctime_current(inode);
772 mark_inode_dirty(inode);
773 return err;
774 }
775
ntfs_xattr_user_list(struct dentry * dentry)776 static bool ntfs_xattr_user_list(struct dentry *dentry)
777 {
778 return true;
779 }
780
781 // clang-format off
782 static const struct xattr_handler ntfs_other_xattr_handler = {
783 .prefix = "",
784 .get = ntfs_getxattr,
785 .set = ntfs_setxattr,
786 .list = ntfs_xattr_user_list,
787 };
788
789 const struct xattr_handler * const ntfs_xattr_handlers[] = {
790 &ntfs_other_xattr_handler,
791 NULL,
792 };
793 // clang-format on
794
795 #ifdef CONFIG_NTFS_FS_POSIX_ACL
ntfs_get_acl(struct mnt_idmap * idmap,struct dentry * dentry,int type)796 struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
797 int type)
798 {
799 struct inode *inode = d_inode(dentry);
800 struct ntfs_inode *ni = NTFS_I(inode);
801 const char *name;
802 size_t name_len;
803 struct posix_acl *acl;
804 int err;
805 void *buf;
806
807 buf = kmalloc(PATH_MAX, GFP_KERNEL);
808 if (!buf)
809 return ERR_PTR(-ENOMEM);
810
811 /* Possible values of 'type' was already checked above. */
812 if (type == ACL_TYPE_ACCESS) {
813 name = XATTR_NAME_POSIX_ACL_ACCESS;
814 name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
815 } else {
816 name = XATTR_NAME_POSIX_ACL_DEFAULT;
817 name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
818 }
819
820 mutex_lock(&ni->mrec_lock);
821 err = ntfs_get_ea(inode, name, name_len, buf, PATH_MAX);
822 mutex_unlock(&ni->mrec_lock);
823
824 /* Translate extended attribute to acl. */
825 if (err >= 0)
826 acl = posix_acl_from_xattr(&init_user_ns, buf, err);
827 else if (err == -ENODATA)
828 acl = NULL;
829 else
830 acl = ERR_PTR(err);
831
832 if (!IS_ERR(acl))
833 set_cached_acl(inode, type, acl);
834
835 kfree(buf);
836
837 return acl;
838 }
839
ntfs_set_acl_ex(struct mnt_idmap * idmap,struct inode * inode,struct posix_acl * acl,int type,bool init_acl)840 static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
841 struct inode *inode, struct posix_acl *acl,
842 int type, bool init_acl)
843 {
844 const char *name;
845 size_t size, name_len;
846 void *value;
847 int err;
848 int flags;
849 umode_t mode;
850
851 if (S_ISLNK(inode->i_mode))
852 return -EOPNOTSUPP;
853
854 mode = inode->i_mode;
855 switch (type) {
856 case ACL_TYPE_ACCESS:
857 /* Do not change i_mode if we are in init_acl */
858 if (acl && !init_acl) {
859 err = posix_acl_update_mode(idmap, inode, &mode, &acl);
860 if (err)
861 return err;
862 }
863 name = XATTR_NAME_POSIX_ACL_ACCESS;
864 name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
865 break;
866
867 case ACL_TYPE_DEFAULT:
868 if (!S_ISDIR(inode->i_mode))
869 return acl ? -EACCES : 0;
870 name = XATTR_NAME_POSIX_ACL_DEFAULT;
871 name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
872 break;
873
874 default:
875 return -EINVAL;
876 }
877
878 if (!acl) {
879 /* Remove xattr if it can be presented via mode. */
880 size = 0;
881 value = NULL;
882 flags = XATTR_REPLACE;
883 } else {
884 value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
885 if (!value)
886 return -ENOMEM;
887 flags = 0;
888 }
889
890 mutex_lock(&NTFS_I(inode)->mrec_lock);
891 err = ntfs_set_ea(inode, name, name_len, value, size, flags, NULL);
892 mutex_unlock(&NTFS_I(inode)->mrec_lock);
893 if (err == -ENODATA && !size)
894 err = 0; /* Removing non existed xattr. */
895 if (!err) {
896 __le16 ea_size = 0;
897 umode_t old_mode = inode->i_mode;
898
899 inode->i_mode = mode;
900 mutex_lock(&NTFS_I(inode)->mrec_lock);
901 err = ntfs_ea_set_wsl_inode(inode, 0, &ea_size, NTFS_EA_MODE);
902 if (err) {
903 ntfs_set_ea(inode, name, name_len, NULL, 0,
904 XATTR_REPLACE, NULL);
905 mutex_unlock(&NTFS_I(inode)->mrec_lock);
906 inode->i_mode = old_mode;
907 goto out;
908 }
909 mutex_unlock(&NTFS_I(inode)->mrec_lock);
910
911 set_cached_acl(inode, type, acl);
912 inode_set_ctime_current(inode);
913 mark_inode_dirty(inode);
914 }
915
916 out:
917 kfree(value);
918
919 return err;
920 }
921
ntfs_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)922 int ntfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
923 struct posix_acl *acl, int type)
924 {
925 return ntfs_set_acl_ex(idmap, d_inode(dentry), acl, type, false);
926 }
927
ntfs_init_acl(struct mnt_idmap * idmap,struct inode * inode,struct inode * dir)928 int ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
929 struct inode *dir)
930 {
931 struct posix_acl *default_acl, *acl;
932 int err;
933
934 err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
935 if (err)
936 return err;
937
938 if (default_acl) {
939 err = ntfs_set_acl_ex(idmap, inode, default_acl,
940 ACL_TYPE_DEFAULT, true);
941 posix_acl_release(default_acl);
942 } else {
943 inode->i_default_acl = NULL;
944 }
945
946 if (acl) {
947 if (!err)
948 err = ntfs_set_acl_ex(idmap, inode, acl,
949 ACL_TYPE_ACCESS, true);
950 posix_acl_release(acl);
951 } else {
952 inode->i_acl = NULL;
953 }
954
955 return err;
956 }
957 #endif
958