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;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/77245.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue3+vite 实现.env全局配置

首先创建.env文件 VUE_APP_BASE_APIhttp://127.0.0.1/dev-api 然后引入依赖&#xff1a; pnpm install dotenv --save-dev 引入完成后&#xff0c;在vite.config.js配置文件内加入以下内容&#xff1a; const env dotenv.config({ path: ./.env }).parsed define: { // 将…

Oracle 19c部署之手工建库(四)

#Oracle #19c #手工建库 手工创建Oracle数据库&#xff08;也称为手工建库&#xff09;是指在已经安装了Oracle数据库软件的基础上&#xff0c;通过手动执行一系列命令和步骤来创建一个新的数据库实例。这种方法与使用Database Configuration Assistant (DBCA)等工具自动创建数…

【Reading Notes】(8.3)Favorite Articles from 2025 March

【March】 雷军一度登顶中国首富&#xff0c;太厉害了&#xff08;2025年03月02日&#xff09; 早盘&#xff0c;小米港股一路高歌猛进&#xff0c;暴涨4%&#xff0c;股价直接飙到52港元的历史新高。这一波猛如虎的操作&#xff0c;直接把雷军的身家拉到了2980亿元&#xff0c…

【Python爬虫基础篇】--1.基础概念

目录 1.爬虫--定义 2.爬虫--组成 3.爬虫--URL 1.爬虫--定义 网络爬虫&#xff0c;是一种按照一定规则&#xff0c;自动抓取互联网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。随着网络的迅速发展&#xff0c;万维网成为大量信息的载体…

C语言超详细结构体知识

1.自定义类型&#xff1a;结构体的介绍 在之前的博客中&#xff0c;我们简单介绍过了关于结构体的基本知识&#xff0c;这里我们稍微复习一下。 结构体(struct)是C语言中一种重要的复合数据类型&#xff0c;它允许将不同类型的数据组合成一个整体。 1.1结构体的定义 结构体使…

C++学习:六个月从基础到就业——内存管理:new/delete操作符

C学习&#xff1a;六个月从基础到就业——内存管理&#xff1a;new/delete操作符 本文是我C学习之旅系列的第十七篇技术文章&#xff0c;也是第二阶段"C进阶特性"的第二篇&#xff0c;主要介绍C中动态内存管理的核心操作符——new和delete。查看完整系列目录了解更多…

15~30K,3年以上golang开发经验

继续分享最新的面经&#xff0c;前面发的两篇大家也可以看看&#xff1a; 「坐标上海&#xff0c;20K的面试强度」「北京七猫&#xff0c;薪资25~35K&#xff0c;瞧瞧面试强度」 今天分享的是golang开发岗面经&#xff0c;要求是3年以上golang开发经验&#xff0c;薪资为15~3…

Python爬虫实战:获取优志愿专业数据

一、引言 在信息爆炸的当下,数据成为推动各领域发展的关键因素。优志愿网站汇聚了丰富的专业数据,对于教育研究、职业规划等领域具有重要价值。然而,为保护自身数据和资源,许多网站设置了各类反爬机制。因此,如何高效、稳定地从优志愿网站获取计算机专业数据成为一个具有…

ArcPy工具箱制作(下)

在上一篇博客中&#xff0c;我们已经初步了解了如何制作ArcPy工具箱&#xff0c;包括工具箱的基本概念、准备工作、脚本编写以及将脚本转换为工具箱的步骤。今天&#xff0c;我们将继续深入探讨ArcPy工具箱的制作&#xff0c;重点介绍一些进阶技巧和优化方法. 一、优化工具箱的…

不一样的flag 1(迷宫题)

题目 做法 下载压缩包&#xff0c;解压&#xff0c;把解压后的文件拖进Exeinfo PE进行分析 32位&#xff0c;无壳 扔进IDA&#xff08;32位&#xff09;&#xff0c;找到main&#xff0c;F5反编译 没啥关键词&#xff0c;ShiftF12也找不到什么有用的点 从上往下分析吧 puts(…

工程化实践:Flutter项目结构与规范

工程化实践&#xff1a;Flutter项目结构与规范 在Flutter项目开发中&#xff0c;良好的工程化实践对于提高开发效率、保证代码质量和团队协作至关重要。本文将从项目结构、代码规范、CI/CD流程搭建以及包管理等方面&#xff0c;详细介绍Flutter项目的工程化最佳实践。 项目结…

[Java · 初窥门径] Java 语言初识

&#x1f31f; 想系统化学习 Java 编程&#xff1f;看看这个&#xff1a;[编程基础] Java 学习手册 0x01&#xff1a;Java 编程语言简介 Java 是一种高级计算机编程语言&#xff0c;它是由 Sun Microsystems 公司&#xff08;已被 Oracle 公司收购&#xff09;于 1995 年 5 …

1187. 【动态规划】竞赛总分

题目描述 学生在我们USACO的竞赛中的得分越多我们越高兴。我们试着设计我们的竞赛以便人们能尽可能的多得分。 现在要进行一次竞赛&#xff0c;总时间T固定&#xff0c;有若干类型可选择的题目&#xff0c;每种类型题目可选入的数量不限&#xff0c;每种类型题目有一个si(解答…

使用KeilAssistant代替keil的UI界面

目录 一、keil Assistant的优势和缺点 二、使用方法 &#xff08;1&#xff09;配置keil的路径 &#xff08;2&#xff09;导入并使用工程 &#xff08;3&#xff09;默认使用keil自带的ARM编译器而非GUN工具链 一、keil Assistant的优势和缺点 在日常学…

【React】通过 fetch 发起请求,设置 proxy 处理跨域

fetch 基本使用跨域处理 fetch 基本使用 在node使用原生ajax发请求&#xff1a;XMLHttpRequest()1.获取xhr对象 2.注册回调函数 3.设置参数&#xff0c;请求头 4.发起连接原生ajax没有带异步处理 promise&#xff1b;原生ajax封装一下&#xff0c;以便重复调用jQuery&#…

Redis(二) - Redis命令详解

文章目录 前言一、启动Redis并进入客户端1. 启动Redis2. 进入Redis客户端3. 使用IDEA连接Redis 二、查看命令帮助信息1. 查看所有命令2. 查看指定命令帮助 三、键操作命令1. set命令2. mset命令3. keys命令4. get命令5. mget命令6. dump命令7. exists命令8. type命令9. rename命…

【Qt】初识Qt(二)

目录 一、显示hello world1.1 图形化界面1.2 写代码 二、对象树三、使用输入框显示hello world四、使用按钮显示hello world 一、显示hello world 有两种方式实现hello world&#xff1a; 通过图形化界面&#xff0c;在界面上创建出一个控件&#xff0c;显示hello world通过写…

空调制冷量和功率有什么关系?

空调的制冷量和功率是衡量空调性能的两个核心参数,二者既有区别又紧密相关,以下是具体解析: 1. 基本定义 制冷量(Cooling Capacity)指空调在单位时间内从室内环境中移除的热量,单位为 瓦特(W) 或 千卡/小时(kcal/h)。它直接反映空调的制冷能力,数值越大,制冷效果越…

【prometheus+Grafana篇】Prometheus与Grafana:深入了解监控架构与数据可视化分析平台

&#x1f4ab;《博主主页》&#xff1a;奈斯DB-CSDN博客 &#x1f525;《擅长领域》&#xff1a;擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控&#xff1b;并对SQLserver、NoSQL(MongoDB)有了解 &#x1f496;如果觉得文章对你有所帮…

基于n8n的AI应用工作流原理与技术解析

基于n8n的AI应用工作流原理与技术解析 在AI技术深度融入企业数字化转型的今天&#xff0c;开源工作流自动化工具n8n凭借其灵活的架构和强大的集成能力&#xff0c;成为构建智能自动化流程的核心引擎。本文将从技术原理、AI融合机制、典型应用场景三个维度&#xff0c;解析n8n在…