From a36159eec6ca17402b0e146b86efaf76568dc353 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 20 Sep 2024 01:41:23 +0000 Subject: [PATCH] 重命名 AX88772C_eeprom/asix.c 为 asix_mac.c --- kernel/fs/ubifs/xattr.c | 128 +++++++++++++++++++++++++++++++++--------- 1 files changed, 99 insertions(+), 29 deletions(-) diff --git a/kernel/fs/ubifs/xattr.c b/kernel/fs/ubifs/xattr.c index f5ad1ed..b4fc55f 100644 --- a/kernel/fs/ubifs/xattr.c +++ b/kernel/fs/ubifs/xattr.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * This file is part of UBIFS. * * Copyright (C) 2006-2008 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Artem Bityutskiy (Битюцкий Артём) * Adrian Hunter @@ -61,12 +49,6 @@ #include <linux/xattr.h> /* - * Limit the number of extended attributes per inode so that the total size - * (@xattr_size) is guaranteeded to fit in an 'unsigned int'. - */ -#define MAX_XATTRS_PER_INODE 65535 - -/* * Extended attribute type constants. * * USER_XATTR: user extended attribute ("user.*") @@ -106,7 +88,7 @@ .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; - if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) { + if (host_ui->xattr_cnt >= ubifs_xattr_max_cnt(c)) { ubifs_err(c, "inode %lu already has too many xattrs (%d), cannot create more", host->i_ino, host_ui->xattr_cnt); return -ENOSPC; @@ -303,6 +285,7 @@ if (!xent) return -ENOMEM; + down_write(&ubifs_inode(host)->xattr_sem); /* * The extended attribute entries are stored in LNC, so multiple * look-ups do not involve reading the flash. @@ -337,6 +320,7 @@ iput(inode); out_free: + up_write(&ubifs_inode(host)->xattr_sem); kfree(xent); return err; } @@ -359,18 +343,19 @@ if (!xent) return -ENOMEM; + down_read(&ubifs_inode(host)->xattr_sem); xent_key_init(c, &key, host->i_ino, &nm); err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); if (err) { if (err == -ENOENT) err = -ENODATA; - goto out_unlock; + goto out_cleanup; } inode = iget_xattr(c, le64_to_cpu(xent->inum)); if (IS_ERR(inode)) { err = PTR_ERR(inode); - goto out_unlock; + goto out_cleanup; } ui = ubifs_inode(inode); @@ -392,7 +377,8 @@ out_iput: mutex_unlock(&ui->ui_mutex); iput(inode); -out_unlock: +out_cleanup: + up_read(&ubifs_inode(host)->xattr_sem); kfree(xent); return err; } @@ -424,16 +410,21 @@ dbg_gen("ino %lu ('%pd'), buffer size %zd", host->i_ino, dentry, size); + down_read(&host_ui->xattr_sem); len = host_ui->xattr_names + host_ui->xattr_cnt; - if (!buffer) + if (!buffer) { /* * We should return the minimum buffer size which will fit a * null-terminated list of all the extended attribute names. */ - return len; + err = len; + goto out_err; + } - if (len > size) - return -ERANGE; + if (len > size) { + err = -ERANGE; + goto out_err; + } lowest_xent_key(c, &key, host->i_ino); while (1) { @@ -455,8 +446,9 @@ pxent = xent; key_read(c, &xent->key, &key); } - kfree(pxent); + up_read(&host_ui->xattr_sem); + if (err != -ENOENT) { ubifs_err(c, "cannot find next direntry, error %d", err); return err; @@ -464,6 +456,10 @@ ubifs_assert(c, written <= size); return written; + +out_err: + up_read(&host_ui->xattr_sem); + return err; } static int remove_xattr(struct ubifs_info *c, struct inode *host, @@ -507,6 +503,77 @@ return err; } +int ubifs_purge_xattrs(struct inode *host) +{ + union ubifs_key key; + struct ubifs_info *c = host->i_sb->s_fs_info; + struct ubifs_dent_node *xent, *pxent = NULL; + struct inode *xino; + struct fscrypt_name nm = {0}; + int err; + + if (ubifs_inode(host)->xattr_cnt <= ubifs_xattr_max_cnt(c)) + return 0; + + ubifs_warn(c, "inode %lu has too many xattrs, doing a non-atomic deletion", + host->i_ino); + + down_write(&ubifs_inode(host)->xattr_sem); + lowest_xent_key(c, &key, host->i_ino); + while (1) { + xent = ubifs_tnc_next_ent(c, &key, &nm); + if (IS_ERR(xent)) { + err = PTR_ERR(xent); + break; + } + + fname_name(&nm) = xent->name; + fname_len(&nm) = le16_to_cpu(xent->nlen); + + xino = ubifs_iget(c->vfs_sb, le64_to_cpu(xent->inum)); + if (IS_ERR(xino)) { + err = PTR_ERR(xino); + ubifs_err(c, "dead directory entry '%s', error %d", + xent->name, err); + ubifs_ro_mode(c, err); + kfree(pxent); + kfree(xent); + goto out_err; + } + + ubifs_assert(c, ubifs_inode(xino)->xattr); + + clear_nlink(xino); + err = remove_xattr(c, host, xino, &nm); + if (err) { + kfree(pxent); + kfree(xent); + iput(xino); + ubifs_err(c, "cannot remove xattr, error %d", err); + goto out_err; + } + + iput(xino); + + kfree(pxent); + pxent = xent; + key_read(c, &xent->key, &key); + } + kfree(pxent); + up_write(&ubifs_inode(host)->xattr_sem); + + if (err != -ENOENT) { + ubifs_err(c, "cannot find next direntry, error %d", err); + return err; + } + + return 0; + +out_err: + up_write(&ubifs_inode(host)->xattr_sem); + return err; +} + /** * ubifs_evict_xattr_inode - Evict an xattr inode. * @c: UBIFS file-system description object @@ -547,6 +614,7 @@ if (!xent) return -ENOMEM; + down_write(&ubifs_inode(host)->xattr_sem); xent_key_init(c, &key, host->i_ino, &nm); err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); if (err) { @@ -571,6 +639,7 @@ iput(inode); out_free: + up_write(&ubifs_inode(host)->xattr_sem); kfree(xent); return err; } @@ -624,7 +693,8 @@ static int xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, - const char *name, void *buffer, size_t size) + const char *name, void *buffer, size_t size, + int flags) { dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, inode->i_ino, dentry, size); -- Gitblit v1.6.2