hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/ubifs/xattr.c
....@@ -1,20 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * This file is part of UBIFS.
34 *
45 * Copyright (C) 2006-2008 Nokia Corporation.
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms of the GNU General Public License version 2 as published by
8
- * the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but WITHOUT
11
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- * more details.
14
- *
15
- * You should have received a copy of the GNU General Public License along with
16
- * this program; if not, write to the Free Software Foundation, Inc., 51
17
- * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
186 *
197 * Authors: Artem Bityutskiy (Битюцкий Артём)
208 * Adrian Hunter
....@@ -61,12 +49,6 @@
6149 #include <linux/xattr.h>
6250
6351 /*
64
- * Limit the number of extended attributes per inode so that the total size
65
- * (@xattr_size) is guaranteeded to fit in an 'unsigned int'.
66
- */
67
-#define MAX_XATTRS_PER_INODE 65535
68
-
69
-/*
7052 * Extended attribute type constants.
7153 *
7254 * USER_XATTR: user extended attribute ("user.*")
....@@ -106,7 +88,7 @@
10688 .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1,
10789 .dirtied_ino_d = ALIGN(host_ui->data_len, 8) };
10890
109
- if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) {
91
+ if (host_ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) {
11092 ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more",
11193 host->i_ino, host_ui->xattr_cnt);
11294 return -ENOSPC;
....@@ -303,6 +285,7 @@
303285 if (!xent)
304286 return -ENOMEM;
305287
288
+ down_write(&ubifs_inode(host)->xattr_sem);
306289 /*
307290 * The extended attribute entries are stored in LNC, so multiple
308291 * look-ups do not involve reading the flash.
....@@ -337,6 +320,7 @@
337320 iput(inode);
338321
339322 out_free:
323
+ up_write(&ubifs_inode(host)->xattr_sem);
340324 kfree(xent);
341325 return err;
342326 }
....@@ -359,18 +343,19 @@
359343 if (!xent)
360344 return -ENOMEM;
361345
346
+ down_read(&ubifs_inode(host)->xattr_sem);
362347 xent_key_init(c, &key, host->i_ino, &nm);
363348 err = ubifs_tnc_lookup_nm(c, &key, xent, &nm);
364349 if (err) {
365350 if (err == -ENOENT)
366351 err = -ENODATA;
367
- goto out_unlock;
352
+ goto out_cleanup;
368353 }
369354
370355 inode = iget_xattr(c, le64_to_cpu(xent->inum));
371356 if (IS_ERR(inode)) {
372357 err = PTR_ERR(inode);
373
- goto out_unlock;
358
+ goto out_cleanup;
374359 }
375360
376361 ui = ubifs_inode(inode);
....@@ -392,7 +377,8 @@
392377 out_iput:
393378 mutex_unlock(&ui->ui_mutex);
394379 iput(inode);
395
-out_unlock:
380
+out_cleanup:
381
+ up_read(&ubifs_inode(host)->xattr_sem);
396382 kfree(xent);
397383 return err;
398384 }
....@@ -424,16 +410,21 @@
424410 dbg_gen("ino %lu ('%pd'), buffer size %zd", host->i_ino,
425411 dentry, size);
426412
413
+ down_read(&host_ui->xattr_sem);
427414 len = host_ui->xattr_names + host_ui->xattr_cnt;
428
- if (!buffer)
415
+ if (!buffer) {
429416 /*
430417 * We should return the minimum buffer size which will fit a
431418 * null-terminated list of all the extended attribute names.
432419 */
433
- return len;
420
+ err = len;
421
+ goto out_err;
422
+ }
434423
435
- if (len > size)
436
- return -ERANGE;
424
+ if (len > size) {
425
+ err = -ERANGE;
426
+ goto out_err;
427
+ }
437428
438429 lowest_xent_key(c, &key, host->i_ino);
439430 while (1) {
....@@ -455,8 +446,9 @@
455446 pxent = xent;
456447 key_read(c, &xent->key, &key);
457448 }
458
-
459449 kfree(pxent);
450
+ up_read(&host_ui->xattr_sem);
451
+
460452 if (err != -ENOENT) {
461453 ubifs_err(c, "cannot find next direntry, error %d", err);
462454 return err;
....@@ -464,6 +456,10 @@
464456
465457 ubifs_assert(c, written <= size);
466458 return written;
459
+
460
+out_err:
461
+ up_read(&host_ui->xattr_sem);
462
+ return err;
467463 }
468464
469465 static int remove_xattr(struct ubifs_info *c, struct inode *host,
....@@ -507,6 +503,77 @@
507503 return err;
508504 }
509505
506
+int ubifs_purge_xattrs(struct inode *host)
507
+{
508
+ union ubifs_key key;
509
+ struct ubifs_info *c = host->i_sb->s_fs_info;
510
+ struct ubifs_dent_node *xent, *pxent = NULL;
511
+ struct inode *xino;
512
+ struct fscrypt_name nm = {0};
513
+ int err;
514
+
515
+ if (ubifs_inode(host)->xattr_cnt <= ubifs_xattr_max_cnt(c))
516
+ return 0;
517
+
518
+ ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion",
519
+ host->i_ino);
520
+
521
+ down_write(&ubifs_inode(host)->xattr_sem);
522
+ lowest_xent_key(c, &key, host->i_ino);
523
+ while (1) {
524
+ xent = ubifs_tnc_next_ent(c, &key, &nm);
525
+ if (IS_ERR(xent)) {
526
+ err = PTR_ERR(xent);
527
+ break;
528
+ }
529
+
530
+ fname_name(&nm) = xent->name;
531
+ fname_len(&nm) = le16_to_cpu(xent->nlen);
532
+
533
+ xino = ubifs_iget(c->vfs_sb, le64_to_cpu(xent->inum));
534
+ if (IS_ERR(xino)) {
535
+ err = PTR_ERR(xino);
536
+ ubifs_err(c, "dead directory entry '%s', error %d",
537
+ xent->name, err);
538
+ ubifs_ro_mode(c, err);
539
+ kfree(pxent);
540
+ kfree(xent);
541
+ goto out_err;
542
+ }
543
+
544
+ ubifs_assert(c, ubifs_inode(xino)->xattr);
545
+
546
+ clear_nlink(xino);
547
+ err = remove_xattr(c, host, xino, &nm);
548
+ if (err) {
549
+ kfree(pxent);
550
+ kfree(xent);
551
+ iput(xino);
552
+ ubifs_err(c, "cannot remove xattr, error %d", err);
553
+ goto out_err;
554
+ }
555
+
556
+ iput(xino);
557
+
558
+ kfree(pxent);
559
+ pxent = xent;
560
+ key_read(c, &xent->key, &key);
561
+ }
562
+ kfree(pxent);
563
+ up_write(&ubifs_inode(host)->xattr_sem);
564
+
565
+ if (err != -ENOENT) {
566
+ ubifs_err(c, "cannot find next direntry, error %d", err);
567
+ return err;
568
+ }
569
+
570
+ return 0;
571
+
572
+out_err:
573
+ up_write(&ubifs_inode(host)->xattr_sem);
574
+ return err;
575
+}
576
+
510577 /**
511578 * ubifs_evict_xattr_inode - Evict an xattr inode.
512579 * @c: UBIFS file-system description object
....@@ -547,6 +614,7 @@
547614 if (!xent)
548615 return -ENOMEM;
549616
617
+ down_write(&ubifs_inode(host)->xattr_sem);
550618 xent_key_init(c, &key, host->i_ino, &nm);
551619 err = ubifs_tnc_lookup_nm(c, &key, xent, &nm);
552620 if (err) {
....@@ -571,6 +639,7 @@
571639 iput(inode);
572640
573641 out_free:
642
+ up_write(&ubifs_inode(host)->xattr_sem);
574643 kfree(xent);
575644 return err;
576645 }
....@@ -624,7 +693,8 @@
624693
625694 static int xattr_get(const struct xattr_handler *handler,
626695 struct dentry *dentry, struct inode *inode,
627
- const char *name, void *buffer, size_t size)
696
+ const char *name, void *buffer, size_t size,
697
+ int flags)
628698 {
629699 dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name,
630700 inode->i_ino, dentry, size);