当前位置: 首页 > article >正文

linux 4.14内核jffs2文件系统不自动释放空间的bug

        前段时间在做spi-nor flash项目的时候,使用jffs2文件系统,发现在4.14内核下存在无法释放空间的bug,后来进行了修复,修复后功能正常,现将修复patch公开,供后来者学习:

diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 7ebacf148..093ffbd82 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -133,7 +133,8 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)size_t i;*size = jffs2_acl_size(acl->a_count);
-	header = kmalloc(sizeof(*header) + acl->a_count * sizeof(*entry), GFP_KERNEL);
+	header = kmalloc(struct_size(header, a_entries, acl->a_count),
+			GFP_KERNEL);if (!header)return ERR_PTR(-ENOMEM);header->a_version = cpu_to_je32(JFFS2_ACL_VERSION);
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 2e2b5745c..12d0271bd 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -22,6 +22,7 @@ struct jffs2_acl_entry_short {struct jffs2_acl_header {jint32_t	a_version;
+	struct jffs2_acl_entry	a_entries[];};#ifdef CONFIG_JFFS2_FS_POSIX_ACL
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
index 79e771ab6..406d9cc84 100644
--- a/fs/jffs2/compr_rtime.c
+++ b/fs/jffs2/compr_rtime.c
@@ -37,9 +37,6 @@ static int jffs2_rtime_compress(unsigned char *data_in,int outpos = 0;int pos=0;-	if (*dstlen <= 3)
-		return -1;
-memset(positions,0,sizeof(positions));while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index f4a5ec92f..f20cff119 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -227,7 +227,7 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode(dentry));int ret;
-	uint32_t now = get_seconds();
+	uint32_t now = JFFS2_NOW();ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,dentry->d_name.len, dead_f, now);
@@ -260,7 +260,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct detype = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12;if (!type) type = DT_REG;-	now = get_seconds();
+	now = JFFS2_NOW();ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);if (!ret) {
@@ -400,7 +400,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const charrd->pino = cpu_to_je32(dir_i->i_ino);rd->version = cpu_to_je32(++dir_f->highest_version);rd->ino = cpu_to_je32(inode->i_ino);
-	rd->mctime = cpu_to_je32(get_seconds());
+	rd->mctime = cpu_to_je32(JFFS2_NOW());rd->nsize = namelen;rd->type = DT_LNK;rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
@@ -543,7 +543,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, umode_t moderd->pino = cpu_to_je32(dir_i->i_ino);rd->version = cpu_to_je32(++dir_f->highest_version);rd->ino = cpu_to_je32(inode->i_ino);
-	rd->mctime = cpu_to_je32(get_seconds());
+	rd->mctime = cpu_to_je32(JFFS2_NOW());rd->nsize = namelen;rd->type = DT_DIR;rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
@@ -588,16 +588,12 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(dentry));struct jffs2_full_dirent *fd;int ret;
-	uint32_t now = get_seconds();
+	uint32_t now = JFFS2_NOW();-	mutex_lock(&f->sem);for (fd = f->dents ; fd; fd = fd->next) {
-		if (fd->ino) {
-			mutex_unlock(&f->sem);
+		if (fd->ino)return -ENOTEMPTY;
-		}}
-	mutex_unlock(&f->sem);ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,dentry->d_name.len, f, now);
@@ -716,7 +712,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t moderd->pino = cpu_to_je32(dir_i->i_ino);rd->version = cpu_to_je32(++dir_f->highest_version);rd->ino = cpu_to_je32(inode->i_ino);
-	rd->mctime = cpu_to_je32(get_seconds());
+	rd->mctime = cpu_to_je32(JFFS2_NOW());rd->nsize = namelen;/* XXX: This is ugly. */
@@ -801,7 +797,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12;if (!type) type = DT_REG;-	now = get_seconds();
+	now = JFFS2_NOW();ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),d_inode(old_dentry)->i_ino, type,new_dentry->d_name.name, new_dentry->d_name.len, now);
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 4a6cf289b..83b8f06b4 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -21,14 +21,6 @@#include <linux/pagemap.h>#include "nodelist.h"-struct erase_priv_struct {
-	struct jffs2_eraseblock *jeb;
-	struct jffs2_sb_info *c;
-};
-
-#ifndef __ECOS
-static void jffs2_erase_callback(struct erase_info *);
-#endifstatic void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset);static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
@@ -51,7 +43,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n",__func__,jeb->offset, jeb->offset, jeb->offset + c->sector_size);
-	instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
+	instr = kmalloc(sizeof(struct erase_info), GFP_KERNEL);if (!instr) {pr_warn("kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");mutex_lock(&c->erase_free_sem);
@@ -67,18 +59,15 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,memset(instr, 0, sizeof(*instr));-	instr->mtd = c->mtd;instr->addr = jeb->offset;instr->len = c->sector_size;
-	instr->callback = jffs2_erase_callback;
-	instr->priv = (unsigned long)(&instr[1]);
-
-	((struct erase_priv_struct *)instr->priv)->jeb = jeb;
-	((struct erase_priv_struct *)instr->priv)->c = c;ret = mtd_erase(c->mtd, instr);
-	if (!ret)
+	if (!ret) {
+		jffs2_erase_succeeded(c, jeb);
+		kfree(instr);return;
+	}bad_offset = instr->fail_addr;kfree(instr);
@@ -214,22 +203,6 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblockwake_up(&c->erase_wait);}-#ifndef __ECOS
-static void jffs2_erase_callback(struct erase_info *instr)
-{
-	struct erase_priv_struct *priv = (void *)instr->priv;
-
-	if(instr->state != MTD_ERASE_DONE) {
-		pr_warn("Erase at 0x%08llx finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n",
-			(unsigned long long)instr->addr, instr->state);
-		jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr);
-	} else {
-		jffs2_erase_succeeded(priv->c, priv->jeb);
-	}
-	kfree(instr);
-}
-#endif /* !__ECOS */
-/* Hmmm. Maybe we should accept the extra space it takes and makethis a standard doubly-linked list? */static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index bd0428beb..7d8654a14 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -175,7 +175,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,ri.uid = cpu_to_je16(i_uid_read(inode));ri.gid = cpu_to_je16(i_gid_read(inode));ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
-		ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
+		ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());ri.offset = cpu_to_je32(inode->i_size);ri.dsize = cpu_to_je32(pageofs - inode->i_size);ri.csize = cpu_to_je32(0);
@@ -283,7 +283,7 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,ri->uid = cpu_to_je16(i_uid_read(inode));ri->gid = cpu_to_je16(i_gid_read(inode));ri->isize = cpu_to_je32((uint32_t)inode->i_size);
-	ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
+	ri->atime = ri->ctime = ri->mtime = cpu_to_je32(JFFS2_NOW());/* In 2.4, it was already kmapped by generic_file_write(). Doesn'thurt to do it again. The alternative is ifdefs, which are ugly. */
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 3c96f4bdc..eab04eca9 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -408,10 +408,10 @@ int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)mutex_unlock(&c->alloc_sem);}-	if (!(*flags & MS_RDONLY))
+	if (!(*flags & SB_RDONLY))jffs2_start_garbage_collect_thread(c);-	*flags |= MS_NOATIME;
+	*flags |= SB_NOATIME;return 0;}diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 824e61ede..0a2691fcd 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -31,12 +31,19 @@ struct kvec;#define JFFS2_F_I_GID(f) (i_gid_read(OFNI_EDONI_2SFFJ(f)))#define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev)+#define JFFS2_CLAMP_TIME(t) ((uint32_t)clamp_t(time64_t, (t), 0, U32_MAX))
+
+#if BITS_PER_LONG == 32#define ITIME(sec) ((struct timespec){sec, 0})
-#define I_SEC(tv) ((tv).tv_sec)
-#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
-#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
-#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
+#else
+#define ITIME(sec) ((struct timespec64){sec, 0})
+#endif+#define JFFS2_NOW() JFFS2_CLAMP_TIME(ktime_get_real_seconds())
+#define I_SEC(tv) JFFS2_CLAMP_TIME((tv).tv_sec)
+#define JFFS2_F_I_CTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_ctime)
+#define JFFS2_F_I_MTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_mtime)
+#define JFFS2_F_I_ATIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_atime)#define sleep_on_spinunlock(wq, s)				\do {							\DECLARE_WAITQUEUE(__wait, current);		\
@@ -59,7 +66,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)}-#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
+#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & SB_RDONLY)#define SECTOR_ADDR(x) ( (((unsigned long)(x) / c->sector_size) * c->sector_size) )#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index d19483fa1..389ea53ea 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -672,22 +672,6 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_rjffs2_free_full_dirent(fd);return -EIO;}
-
-#ifdef CONFIG_JFFS2_SUMMARY
-		/*
-		 * we use CONFIG_JFFS2_SUMMARY because without it, we
-		 * have checked it while mounting
-		 */
-		crc = crc32(0, fd->name, rd->nsize);
-		if (unlikely(crc != je32_to_cpu(rd->name_crc))) {
-			JFFS2_NOTICE("name CRC failed on dirent node at"
-			   "%#08x: read %#08x,calculated %#08x\n",
-			   ref_offset(ref), je32_to_cpu(rd->node_crc), crc);
-			jffs2_mark_node_obsolete(c, ref);
-			jffs2_free_full_dirent(fd);
-			return 0;
-		}
-#endif}fd->nhash = full_name_hash(NULL, fd->name, rd->nsize);
@@ -1430,6 +1414,11 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);+	if (f->target) {
+		kfree(f->target);
+		f->target = NULL;
+	}
+fds = f->dents;while(fds) {fd = fds;
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 08813789f..90431dd61 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -1075,7 +1075,7 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblomemcpy(&fd->name, rd->name, checkedlen);fd->name[checkedlen] = 0;-	crc = crc32(0, fd->name, checkedlen);
+	crc = crc32(0, fd->name, rd->nsize);if (crc != je32_to_cpu(rd->name_crc)) {pr_notice("%s(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",__func__, ofs, je32_to_cpu(rd->name_crc), crc);
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 4fe645198..be7c8a6a5 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -783,8 +783,6 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblockdbg_summary("Writing unknown RWCOMPAT_COPY node type %x\n",je16_to_cpu(temp->u.nodetype));jffs2_sum_disable_collecting(c->summary);
-					/* The above call removes the list, nothing more to do */
-					goto bail_rwcompat;} else {BUG();	/* unknown node in summary information */}
@@ -796,7 +794,6 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblockc->summary->sum_num--;}
- bail_rwcompat:jffs2_sum_reset_collected(c->summary);diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 9a9f30edd..902a7dd10 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -47,10 +47,7 @@ static struct inode *jffs2_alloc_inode(struct super_block *sb)static void jffs2_i_callback(struct rcu_head *head){struct inode *inode = container_of(head, struct inode, i_rcu);
-	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-
-	kfree(f->target);
-	kmem_cache_free(jffs2_inode_cachep, f);
+	kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));}static void jffs2_destroy_inode(struct inode *inode)
@@ -104,8 +101,7 @@ static int jffs2_sync_fs(struct super_block *sb, int wait)struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
-	if (jffs2_is_writebuffered(c))
-		cancel_delayed_work_sync(&c->wbuf_dwork);
+	cancel_delayed_work_sync(&c->wbuf_dwork);#endifmutex_lock(&c->alloc_sem);
@@ -303,10 +299,10 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)sb->s_op = &jffs2_super_operations;sb->s_export_op = &jffs2_export_ops;
-	sb->s_flags = sb->s_flags | MS_NOATIME;
+	sb->s_flags = sb->s_flags | SB_NOATIME;sb->s_xattr = jffs2_xattr_handlers;#ifdef CONFIG_JFFS2_FS_POSIX_ACL
-	sb->s_flags |= MS_POSIXACL;
+	sb->s_flags |= SB_POSIXACL;#endifret = jffs2_do_fill_super(sb, data, silent);return ret;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 2cfe48770..c6821a509 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -1208,7 +1208,7 @@ int jffs2_nand_flash_setup(struct jffs2_sb_info *c)if (!c->wbuf)return -ENOMEM;-	c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->oobavail, GFP_KERNEL);
+	c->oobbuf = kmalloc_array(NR_OOB_SCAN_PAGES, c->oobavail, GFP_KERNEL);if (!c->oobbuf) {kfree(c->wbuf);return -ENOMEM;
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index cda9a3613..a0eb5f117 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -596,6 +596,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,/* File it. This will mark the old one obsolete. */jffs2_add_fd_to_list(c, fd, &dir_f->dents);
+		//jffs2_complete_reservation(c);mutex_unlock(&dir_f->sem);} else {uint32_t nhash = full_name_hash(NULL, name, namelen);
@@ -660,7 +661,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,mutex_unlock(&dead_f->sem);}-	jffs2_complete_reservation(c);
+	jffs2_complete_reservation(c); //return 0;}

相关文章:

linux 4.14内核jffs2文件系统不自动释放空间的bug

前段时间在做spi-nor flash项目的时候&#xff0c;使用jffs2文件系统&#xff0c;发现在4.14内核下存在无法释放空间的bug&#xff0c;后来进行了修复&#xff0c;修复后功能正常&#xff0c;现将修复patch公开&#xff0c;供后来者学习&#xff1a; diff --git a/fs/jffs2/ac…...

Thymeleaf简介

在Java中&#xff0c;模板引擎可以帮助生成文本输出。常见的模板引擎包括FreeMarker、Velocity和Thymeleaf等 Thymeleaf是一个适用于Web和独立环境的现代服务器端Java模板引擎。 Thymeleaf 和 JSP比较&#xff1a; Thymeleaf目前所作的工作和JSP有相似之处&#xff0c;Thyme…...

uniapp中uni-easyinput 使用@input 不改变绑定的值

只允许输入数字和字母 使用input 正则replace后赋值给A 遇到问题: 当输入任意连续的非法字符时, 输入框不变. 直到输入一个合法字符非法字符才成功被过滤. <uni-forms-item label"纳税人识别号" name"number"><uni-easyinput v-model"numb…...

前端零基础入门到上班:Day7——表单系统实战全解析

&#x1f9e9;前端零基础入门到上班&#xff1a;Day7——表单系统实战全解析 ✅ 目标&#xff1a;不仅掌握 HTML 表单标签&#xff0c;更深入理解其在实战中的作用、验证方式、美化技巧与 JS 联动&#xff0c;为后续接入 Vue、后端接口打下坚实基础。 &#x1f31f; 一、HTML 表…...

【特殊场景应对1】视觉设计:信息密度与美学的博弈——让简历在HR视网膜上蹦迪的科学指南

写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...

o3和o4-mini的升级有哪些亮点?

ChatGPT是基于OpenAI GPT系列的高性能对话生成AI&#xff0c;经过多代迭代不断提升自然语言理解和生成能力。 在过去的一年中&#xff0c;OpenAI先后发布了GPT-4、GPT‑4.1及多种mini版本&#xff0c;为不同使用场景提供灵活选择。​ 随着用户需求向更高效、更精准的推理和视觉…...

影楼精修行业浅见-序言

影楼及商业摄影行业对高效、智能化的图像精修需求日益增长。传统修图流程耗时长、人工成本高&#xff0c;且修图师水平参差不齐影响最终成片质量。AI驱动的影像精修软件通过自动化、批量处理和智能算法&#xff0c;显著提升了修片效率和一致性&#xff0c;成为影楼数字化升级的…...

MATLAB 控制系统设计与仿真 - 36

鲁棒工具箱定义了个新的对象类ureal,可以定义在某个区间内可变的变量。 函数的调用格式为&#xff1a; p ureal(name,nominalvalue) % name为变量名,nominalValue为标称值&#xff0c;默认变化值为/-1 p ureal(name,nominalvalue,PlusMinus,plusminus) p ureal(name,nomin…...

Spring数据访问全解析:ORM整合与JDBC高效实践

目录 一、Spring ORM集成深度剖析 &#x1f31f; ORM模块架构设计 核心集成特性&#xff1a; 整合MyBatis示例配置&#xff1a; 二、Spring JDBC高效实践指南 &#x1f31f; 传统JDBC vs Spring JDBC对比 &#x1f31f; JdbcTemplate核心操作示例 批量操作优化&#xf…...

【HCIA】使用Access port实现简易的VLAN间通信

前言 当我们拥有一台三层交换机与两个vlan&#xff0c;我们可以使用简易的Vlanif配置实现VLAN间通信。 文章目录 前言1. 拓扑图2. 配置交换机3. 配置PC1与PC2的网络4. port link-type后记修改记录 1. 拓扑图 2. 配置交换机 <Huawei>system-view [Huawei]undo info-cent…...

6.VTK 颜色

文章目录 概念RGB示例HSV示例 概念 RGB颜色系统&#xff1a;通过红(R)、绿(G)、蓝(B)三个颜色分量的组合来定义颜色。每个分量的取值范围是0到1&#xff0c;其中(0, 0, 0)代表黑色&#xff0c;而(1, 1, 1)代表白色。可以使用vtkProperty::SetColor(r, g, b)方法为Actor设置颜色…...

shiro使用

shiro是apache提供的一种安全框架。他可以将登录&#xff0c;权限这一方面简单化。 使用shiro需要引入 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.9.0</version></depend…...

光谱相机的成像方式

光谱相机的成像方式决定了其如何获取物体的空间与光谱信息&#xff0c;核心在于分光技术与扫描模式的结合。以下是主要成像方式的分类解析&#xff1a; ‌一、滤光片切换型‌ ‌1. 滤光片轮&#xff08;Filter Wheel&#xff09;‌ ‌原理‌&#xff1a;通过旋转装有多个窄带…...

浅析MySQL事务锁

在 MySQL 中,事务锁是用于确保数据一致性和并发控制的重要机制。事务锁可以帮助防止多个事务同时修改同一数据,从而避免数据不一致和脏读、不可重复读、幻读等问题。 以下是 MySQL 事务锁的关键点总结: 事务锁:用于确保数据一致性和并发控制。锁的类型: 行级锁:InnoDB,粒…...

算法-链表

小细节 初始化问题 我们这样子new一个ListNode 它里面的默认值是0&#xff0c;所以我们不能这样 如果我们为空&#xff0c;我们要返回null 节点结束条件判断&#xff08;多创建节点问题&#xff09; 参考示例3217 解析&#xff1a; 我的答案是多了一个无用节点 这是因为我每…...

ON DUPLICATE KEY UPDATE 更底层解释它的优势

从更底层来看&#xff0c;ON DUPLICATE KEY UPDATE 的优势主要源于以下几个方面&#xff1a; 1. 减少网络往返次数 先查询再更新&#xff1a;这种方式需要客户端和数据库服务器之间进行多次网络通信。首先&#xff0c;客户端发送一个 SELECT 查询请求&#xff0c;然后等待服务…...

3.8/Q1,GBD数据库最新文章解读

文章题目&#xff1a;Regional and National Burden of Traumatic Brain Injury and Spinal Cord Injury in North Africa and Middle East Regions, 1990-2021: A Systematic Analysis for The Global Burden of Disease Study 2021 DOI&#xff1a;10.1007/s44197-025-00372-…...

51单片机实验二:数码管静态显示

目录 一、实验环境与实验器材 二、实验内容及实验步骤 1.单个数码管显示 2.六个数码管依次从0~F变换显示 3.proteus仿真 一、实验环境与实验器材 环境&#xff1a;Keli&#xff0c;STC-ISP烧写软件,Proteus. 器材&#xff1a;TX-1C单片机&#xff08;STC89C52RC…...

Linux驱动开发进阶(八)- GPIO子系统BSP驱动

文章目录 1、前言2、pinctrl子系统3、pinctrl bsp驱动4、gpio子系统5、gpio bsp驱动 1、前言 学习参考书籍以及本文涉及的示例程序&#xff1a;李山文的《Linux驱动开发进阶》本文属于个人学习后的总结&#xff0c;不太具备教学功能。 2、pinctrl子系统 在讨论gpio子系统时&…...

【Windows】安装或者点击OneDrive没有任何反应的解决方案

一些Windows企业版或者神州网信政府版的策略会禁止使用OneDrive&#xff0c;双击OneDrive安装程序或者点击OneDrive软件会没有任何反应。通过下面的设置可以解除相关的限制。 1、修改注册表 打开注册表管理器。依次HKEYLOCAL_MACHINE\Software\Policies\Microsoft\Windows\One…...

Android tinyalsa库函数剖析

1. PCM 流控制函数 打开、关闭及状态检查 pcm_open(unsigned int card, unsigned int device, unsigned int flags, struct pcm_config *config) 打开指定声卡&#xff08;card&#xff09;和设备&#xff08;device&#xff09;的 PCM 流。 flags 参数确定流的方向&#xff1…...

PyCharm Flask 使用 Tailwind CSS v3 配置

安装 Tailwind CSS 步骤 1&#xff1a;初始化项目 在 PyCharm 终端运行&#xff1a;npm init -y安装 Tailwind CSS&#xff1a;npm install -D tailwindcss3 postcss autoprefixer初始化 Tailwind 配置文件&#xff1a;npx tailwindcss init这会生成 tailwind.config.js。 步…...

Python爬虫第17节-动态渲染页面抓取之Selenium使用下篇

目录 引言 一、获取节点信息 1.1 获取属性 1.2 获取文本值 1.3 获取ID、位置、标签名、大小 二、切换Frame 三、延时等待 3.1 隐式等待 3.2 显式等待 四、前进后退 五、Cookies 六、选项卡管理 七、异常处理 引言 这一节我们继续讲解Selenium的使用下篇&#xff0…...

HarmonyOS 第2章 Ability的开发,鸿蒙HarmonyOS 应用开发入门

第2章 Ability的开发 本章内容 本章介绍HarmonyOS的核心组件Ability的开发。 2.1 Ability概述 2.2 FA模型介绍 2.3 Stage模型介绍 2.4 Ability内页面的跳转和数据传递 2.5 Want概述 2.6 实战:显式Want启动Ability 2.7 实战:隐式Want打开应用管理 2.8 小结 2.9 习题 2.1 Abili…...

day2-小白学习JAVA---java第一个程序

java第一个程序 1、新建一个文件&#xff0c;以.java为结尾2、用编辑器打开后写入代码&#xff08;本人写前端&#xff0c;所以用vscode&#xff0c;也可用其他&#xff09;3、编译文件4、运行文件5、HelloWorld代码解释6、文档注释 1、新建一个文件&#xff0c;以.java为结尾 …...

Rockchip 新一代 64 位处理器 RK3562--九鼎开发板

RK3562 是 Rockchip 新一代 64 位处理器 RK3562&#xff08;Quad-core ARM Cortex-A53&#xff0c;主频 最高 2.0GHz&#xff09;&#xff0c;最大支持 8GB 内存&#xff1b;内置独立的 NPU&#xff0c;可用于轻量级人工智能应用&#xff0c;RK3562 拥有 PCIE2.1/USB3.0 OTG/…...

z-library电子图书馆最新地址的查询方法

对于喜欢读书的伙伴们&#xff0c;应该都听说过z站&#xff08;z-library&#xff09;&#xff0c;优点多多&#xff0c;缺点就是地址不稳定&#xff0c;经常会变化网站地址。然后我最近发现了一个工具&#xff0c;可以不间断更新官方可用的z站地址&#xff1a;电子书最新地址...

常见MQ及类MQ对比:Redis Stream、Redis Pub/Sub、RocketMQ、Kafka 和 RabbitMQ

常见MQ及类MQ对比 基于Grok调研 Redis Stream、Redis Pub/Sub、RocketMQ、Kafka 和 RabbitMQ 关键点&#xff1a; Redis Pub/Sub 适合简单实时消息&#xff0c;但不持久化&#xff0c;消息可能丢失。Redis Stream 提供持久化&#xff0c;适合需要消息历史的场景&#xff0c;但…...

Kaggle-Bag of Words Meets Bags of Popcorn-(二分类+NLP+Bert模型)

Bag of Words Meets Bags of Popcorn 题意&#xff1a; 有很多条电影评论记录&#xff0c;问你每一条记录是积极性的评论还是消极性的评论。 数据处理&#xff1a; 1.首先这是文件是zip形式&#xff0c;要先解压&#xff0c;注意sep ‘\t’。 2.加载预训练的 BERT 分词器 …...

Spring Boot 3 + SpringDoc:打造接口文档

1、背景公司 新项目使用SpringBoot3.0以上构建&#xff0c;其中需要对外输出接口文档。接口文档一方面给到前端调试&#xff0c;另一方面给到测试使用。 2、SpringDoc 是什么&#xff1f; SpringDoc 是一个基于 Spring Boot 项目的库&#xff0c;能够自动根据项目中的配置、…...