精华内容
下载资源
问答
  • 磁盘索引节点和内存索引节点I n this post, using examples, we will learn about Garbage Collection, memory management, and memory leaks in Node.JS.在这篇文章中,通过示例,我们将学习有关垃圾收集,内存管理...

    磁盘索引节点和内存索引节点

    I n this post, using examples, we will learn about Garbage Collection, memory management, and memory leaks in Node.JS.

    在这篇文章中,通过示例,我们将学习有关垃圾收集,内存管理和Node.JS中的内存泄漏的信息。

    Let’s start.

    开始吧。

    总览 (Overview)

    JavaScript automatically allocates memory when objects are created and frees it when they are not used anymore (garbage collection). This automatic process is a potential source of confusion: it can give developers the false impression that they don’t need to worry about memory management.

    JavaScript在创建对象时自动分配内存,并在不再使用对象时将其释放(垃圾回收)。 这种自动过程可能会引起混乱:它会给开发人员一种错误的印象,即他们不必担心内存管理。

    记忆模型 (Memory Model)

    堆:(Heap:)

    This is where the V8 Engine stores objects or dynamic data. This is the biggest block of memory area and this is where Garbage Collection(GC) takes place. The entire heap memory is not garbage collected, only the New and Old spaces are managed by garbage collection. Memory allocation is randomly placed. To prevent memory “holes” in the Heap the V8 engine has memory managers that prevent that from occurring. The Heap is further divided into the below:

    V8引擎在这里存储对象或动态数据。 这是最大的内存区域,这是垃圾回收(GC)发生的地方。 整个堆内存不是垃圾回收,只有新空间和旧空间由垃圾回收管理。 内存分配是随机放置的。 为了防止堆中的内存“空洞”,V8引擎提供了内存管理器来防止这种情况的发生。 堆进一步分为以下几类:

    • New Space: This is where new objects live, and most of these objects are short-lived. The New Space is small and designed to be GC’ed (“Scavenge Algorithm”) very quickly, independent of other spaces. New Space size can be controlled using the --min_semi_space_size(Request) and --max_semi_space_size(Limit) V8 flags.

      新空间:这是新对象居住的地方,其中大多数是短暂的。 新空间很小,并且可以快速进行GC(“清除算法”),而与其他空间无关。 可以使用--min_semi_space_size (请求)和--max_semi_space_size (限制)V8标志来控制新的空间大小。

    • Old Space: This is where objects that survived the “New space” for two GC cycles are moved to. This space is managed up by GC (Mark-Sweep & Mark-Compact algorithm) The size of Old Space can be controlled using the --initial_old_space_size(Request) and --max_old_space_size(Limit) V8 flags. The Old Space is divided to:

      旧空间:这是将在两个GC周期中在“新空间”中幸存的对象移动到的地方。 此空间由GC(标记扫描和标记紧凑算法)管理 可以使用--initial_old_space_size (Request)和--max_old_space_size (Limit)V8标志来控制旧空间的大小。 旧空间分为:

      Old Space: This is where objects that survived the “New space” for two GC cycles are moved to. This space is managed up by GC (Mark-Sweep & Mark-Compact algorithm) The size of Old Space can be controlled using the --initial_old_space_size(Request) and --max_old_space_size(Limit) V8 flags. The Old Space is divided to:Old Pointer Space: Contains most objects which may have pointers to other objects.

      旧空间:这是将在两个GC周期中在“新空间”中幸存的对象移动到的地方。 此空间由GC(标记扫描和标记紧凑算法)管理 可以使用--initial_old_space_size (Request)和--max_old_space_size (Limit)V8标志来控制旧空间的大小。 旧空间分为:旧指针空间:包含大多数可能具有指向其他对象的指针的对象。

      Old Space: This is where objects that survived the “New space” for two GC cycles are moved to. This space is managed up by GC (Mark-Sweep & Mark-Compact algorithm) The size of Old Space can be controlled using the --initial_old_space_size(Request) and --max_old_space_size(Limit) V8 flags. The Old Space is divided to:Old Pointer Space: Contains most objects which may have pointers to other objects.Old Data Space: Contains objects which just contain raw data without pointers to other objects.

      旧空间:这是将在两个GC周期中在“新空间”中幸存的对象移动到的地方。 此空间由GC(标记扫描和标记紧凑算法)管理 可以使用--initial_old_space_size (Request)和--max_old_space_size (Limit)V8标志来控制旧空间的大小。 旧空间分为:旧指针空间:包含大多数可能具有指向其他对象的指针的对象。 旧数据空间:包含仅包含原始数据而没有指向其他对象的指针的对象。

    • Large object space: This is where objects which are larger than the size limits of other spaces live. Each object gets its own mmap'd region of memory. Large objects are never moved by the garbage collector.

      较大的对象空间:这是大于其他空间大小限制的对象所在的地方。 每个对象都有自己的mmap'd内存区域。 大对象永远不会被垃圾收集器移动。

    • Code-space: This is where the Just In Time(JIT) compiler stores compiled code Blocks. This is the only space with executable memory (although Codes may be allocated in “Large object space”, and those are executable, too).

      代码空间即时(JIT)编译器此处存储已编译的代码块。 这是唯一具有可执行内存的空间(尽管可以在“大对象空间”中分配Codes ,并且这些代码也是可执行的)。

    • Cell space, property cell space, and map space: These spaces contain Cells, PropertyCells, and Maps, respectively. Each of these spaces contains objects which are all the same size and has some constraints on what kind of objects they point to, which simplifies collection.

      单元空间,属性单元空间和地图空间:这些空间分别包含CellsPropertyCellsMaps 。 这些空间中的每个空间都包含相同大小的对象,并且对它们指向的对象有某种约束,从而简化了收集。

    Each of these spaces is composed of a set of pages. A Page is a contiguous chunk of memory allocated from the operating system with mmap or mapviewoffile(Windows). Each page is 1MB in size, except for Large object space.

    这些空间中的每一个都由一组页面组成。 页面是使用mmap或mapviewoffile(Windows)从操作系统分配的连续内存块。 除较大的对象空间外,每个页面的大小均为1MB。

    堆栈: (Stack:)

    There is one stack per V8 process. This is where static data including method/function frames, primitive values, and pointers to objects are stored. The variables are stored in a LIFO method - the last one in is the first one out.The stack memory limit can be set using the --stack_size V8 flag.

    每个V8进程只有一个堆栈。 在此存储包括方法/功能框,原始值和对象指针的静态数据。 变量存储在LIFO方法中-最后一个输入是第一个输出。可以使用--stack_size V8标志设置堆栈内存限制。

    例: (Example:)

    class Dog {}
    const dog = new Dog()
    let person = {
    name: "John doe"
    }

    In this example we can see that dog and person are reference types, their values are stored in the Heap and they are pushed to the stack with the value of the memory address of the location in Heap.

    在此示例中,我们可以看到dog和person是引用类型,它们的值存储在Heap中,并将它们与Heap中位置的内存地址的值一起推入堆栈。

    扫频算法 (Mark-and-sweep algorithm)

    This algorithm reduces the definition of “an object is no longer needed” to “an object is unreachable”.

    该算法将“不再需要一个对象”的定义简化为“一个无法访问的对象”。

    The algorithm starts from the root of the application. For the browser, the root is the window, and for Node.js it is the global object.

    该算法从应用程序的根目录开始。 对于浏览器,根是窗口,对于Node.js,它是全局对象。

    Using this algorithm, the GC will identify the reachable and unreachable objects. All the unreachable objects will be automatically garbage collected.

    使用此算法,GC将识别可到达和不可到达的对象。 所有无法访问的对象将被自动垃圾收集。

    As of 2012, all modern browsers ship a mark-and-sweep GC.

    自2012年起,所有现代浏览器都附带标记扫掠GC

    Side Note: As of 2020, it is no possible to explicitly or programmatically trigger garbage collection in JavaScript.

    旁注:截至2020年,不可能在JavaScript中显式或以编程方式触发垃圾回收。

    内存泄漏 (Memory Leaks)

    JavaScript memory leaks are caused by invalid logical flow in the code.

    JavaScript内存泄漏是由代码中无效的逻辑流引起的。

    A Memory leak can be defined as a piece of memory that is no longer being used or required by an application but for some reason is not returned back to the OS and is still being occupied needlessly.

    内存泄漏可以定义为不再由应用程序使用或需要的内存,但由于某种原因不会泄漏回操作系统,并且仍被不必要地占用。

    Let’s see some real-life examples for memory leaks:

    让我们来看一些有关内存泄漏的真实示例:

    全局变量 (Global Variables)

    Global variables by definition are not swept away by GC. It is important to remember to use global variables carefully and never forget to either null it or reassign it after their use.

    根据定义,全局变量不会被GC清除。 重要的是要记住要小心使用全局变量,不要忘记在使用全局变量后将其清空或重新分配。

    范围 (Scope)

    The current context of execution. The context in which values and expressions are “visible” or can be referenced. If a variable or other expression is not “in the current scope,” then it is unavailable for use.

    当前执行上下文。 值和表达式“可见”或可以引用的上下文。 如果一个 变量或其他表达式不在“当前范围内”,则无法使用。

    Memory leak in JS often occurs due to scoping rules. A reference to an undeclared variable creates a new variable inside the global object. In the case of browsers, the global object is window.

    JS中的内存泄漏通常是由于作用域规则而发生的。 对未声明变量的引用会在全局对象内创建一个新变量。 对于浏览器,全局对象是window。

    Node.js Example:

    Node.js示例:

    function leak() {
    text = "leak";
    }

    In this example after the leak function called, the text still exists in the global scope variable. That happened because of Hoisting and that can lead to a memory leak.

    在此示例中,在调用泄漏函数之后,文本仍存在于全局范围变量中。 发生这种情况是由于吊装,可能导致内存泄漏。

    How to solve this issue: simply use the keyword var/const/let. When we use those keywords the variable will be created inside the scope of the function’s/object’s, and when the scope is cleared the GC will collect it.

    如何解决此问题:只需使用关键字var/const/let. 当我们使用这些关键字时,变量将在函数/对象的作用域内创建,而当清除作用域时, GC将收集该变量。

    关闭 (Closures)

    A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment)

    闭包是捆绑在一起(封闭)的函数及其周围状态(词汇)的组合。 环境)

    Example:

    例:

    function outer() {
    var data = "Javascript";
    function inner() {
    console.log(data);
    }
    return inner;
    }

    var func = outer();
    func();

    In this example, we can see that the inner function uses the data of the outer function. What happens when the parent (outer) scope of closure is removed?!

    在此示例中,我们可以看到内部函数使用外部函数的数据。 删除父(外部)关闭范围会发生什么?!

    The closure holds a copy of it in memory. Because of this behavior, the callers will still refer to the old variables from the closure’s parent scope.

    闭包将其副本保存在内存中。 由于这种行为,调用者仍将引用闭包的父作用域中的旧变量。

    计时器和事件 (Timers & Events)

    The use of setTimeout, setInterval, Observers and event listeners can cause memory leaks when heavy object references are kept in their callbacks without proper handling.

    如果在没有适当处理的情况下将重对象引用保留在其回调中,则使用setTimeout,setInterval,Observer和事件侦听器可能会导致内存泄漏。

    Let’s review some examples:

    让我们回顾一些例子:

    Interval

    间隔

    var data = {
    text: "data"
    };
    setInterval(function() {
    var stringData = JSON.
    console.log(stringData);
    }, 1000);

    In this example, we can see another potential memory leak. Let’s understand why. The object represented by data may be removed in the future, which will make the whole block inside the interval handler unnecessary. The interval is still active and for that reason cannot be garbage collected and its dependencies cannot be collected either. That means that data, cannot be collected.

    在此示例中,我们可以看到另一个潜在的内存泄漏。 让我们了解为什么。 由data表示的对象将来可能会被删除,这将使间隔处理程序内的整个块不再需要。 该间隔仍处于活动状态,因此无法进行垃圾回收,也无法收集其依赖项。 这意味着, data ,无法收集。

    How to solve this issue: simply use the clearInterval method:

    如何解决此问题:只需使用clearInterval方法:

    var data = {
    text: "data"
    };
    var interval = setInterval(function() {
    var stringData = JSON.
    console.log(stringData);
    }, 1000);
    clearInterval(interval);

    Now the interval is clear and its dependencies will be cleared as well.

    现在,该间隔已清除,并且其依存关系也将被清除。

    Timeout

    超时

    The handler of the timeout will stay active and in memory even after the timeout happened. Because the handler stays active his dependencies cannot be collected either.

    即使发生timeout的处理程序也将保持活动状态并保留在内存中。 由于处理程序保持活动状态,因此也无法收集其依赖项。

    How to solve this issue: simply use the clearTimeout method.

    如何解决此问题:只需使用clearTimeout方法。

    概要 (Summary)

    Let’s summarize what we’ve learned in this post:

    让我们总结一下我们在这篇文章中学到的知识:

    • Memory management

      内存管理
    • Garbage Collection

      垃圾收集
    • Memory leaks with real-life examples.

      带有实际示例的内存泄漏。

    Bonus (: Mozilla has published a nice article about how to find memory leaks in Node.js.

    奖励(: Mozilla发表了一篇不错的文章,关于如何在Node.js中查找内存泄漏

    Thank you for your time, hope you enjoyed this!

    谢谢您的时间,希望您喜欢这个!

    翻译自: https://medium.com/@galbatz/memory-model-memory-leaks-in-node-js-395d63b8ba11

    磁盘索引节点和内存索引节点

    展开全文
  • 如果上面进程在open以后又执行了close()函数,操作系统会删除文件描述符表的第四个条目,和系统文件表的对应条目(若指向它的描述符表唯一),并对内存索引节点表条目中的计数减1,如果自减以后变为0,说明没有...
    本文转自出自 “淡泊明志,宁静致远” 博客,请务必保留此出处http://keren.blog.51cto.com/720558/170822
     
    在C程序中,文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述符。下面重点来说下,文件描述符是如何工作的。
     
    文件描述符相当于一个逻辑句柄,而open,close等函数则是将文件或者物理设备与句柄相关联。句柄是一个整数,可以理解为进程特定的文件描述符表的索引。先介绍下面三个概念,后面讲下open、close等操作以后,文件和文件描述符产生什么关系,以及fork后文件描述符的继承等问题。
     
    文件描述符表:用户区的一部分,除非通过使用文件描述符的函数,否则程序无法对其进行访问。对进程中每个打开的文件,文件描述符表都包含一个条目。
     
    系统文件表:为系统中所有的进程共享。对每个活动的open, 它都包含一个条目。每个系统文件表的条目都包含文件偏移量、访问模式(读、写、or 读-写)以及指向它的文件描述符表的条目计数。
     
    内存索引节点表: 对系统中的每个活动的文件(被某个进程打开了),内存中索引节点表都包含一个条目。几个系统文件表条目可能对应于同一个内存索引节点表(不同进程打开同一个文件)。
     
    1、举例: 执行myfd = open( "/home/lucy/my.dat", O_RDONLY); 以后,上述3个表的关系原理图如下:
    http://keren.blog.51cto.com/
                                                                                      图1
     
    系统文件表包含一个偏移量,给出了文件当前的位置。若2个进程同时打开一个文件(如上图A,B)做读操作,每个进程都有自己相对于文件的偏移量,而且读入整个文件是独立于另一个进程的;如果2个进程打开同一个文件做写操作,写操作是相互独立的,每个进程都可以重写另一个进程写入的内容。
     
    如果上面进程在open以后又执行了close()函数,操作系统会删除文件描述符表的第四个条目,和系统文件表的对应条目(若指向它的描述符表唯一),并对内存索引节点表条目中的计数减1,如果自减以后变为0,说明没有其他进程链接此文件,将索引节点表条目也删除,而这里进程B也在open这个文件,所以索引节点表条目保留。
     
    2、文件描述符的继承
    通过fork()创建子进程时,子进程继承父进程环境和上下文的大部分内容的拷贝,其中就包括文件描述符表。
     
    (1)对于父进程在fork()之前打开的文件来说,子进程都会继承,与父进程共享相同的文件偏移量。如下图所示(0-1-2 表示 标准输入-输出-错误):
                                      图2 fork()之前打开my.dat
     
    系统文件表位于系统空间中,不会被fork()复制,但是系统文件表中的条目会保存指向它的文件描述符表的计数,fork()时需要对这个计数进行维护,以体现子进程对应的新的文件描述符表也指向它。程序关闭文件时,也是将系统文件表条目内部的计数减一,当计数值减为0时,才将其删除。
     
    (2)相反,如果父进程先进程fork,再打开my.dat,这时父子进程关于my.dat 的文件描述符表指向不同的系统文件表条目,也不再共享文件偏移量(fork以后2个进程分别open,在系统文件表中创建2个条目);但是关于标准输入,标准输出,标准错误,父子进程还是共享的。
                          图3   fork()以后打开my.dat

    转载于:https://www.cnblogs.com/FengGettingBetter/p/3357681.html

    展开全文
  • VFS的索引节点

    2016-07-16 11:27:30
    具体文件系统的索引节点是存放在磁盘上的,是一种静态数据结构,要使用他必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点。  VFS索引节点数据结构主要域有  struct inode

                                                 索引节点

           文件系统处理文件所需要的所有信息都放在称为索引节点的数据结构中。文件名可以随时更改,但是索引节点对文件是唯一的,并且随文件的存在而存在。具体文件系统的索引节点是存放在磁盘上的,是一种静态数据结构,要使用他必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点。

           VFS索引节点数据结构主要域有

           struct inode

          {

                struct list_head i_hash;//指向哈希链表的指针

                struct list_head i_list;//指向索引节点链表的指针

                struct list_head i_dentry;//指向目录项链表的指针

     

                unsigned long i_ino;//索引结点号

                umode_t i_mode;//文件类型与访问权限

                kdev_t i_rdev;//实际设备标识号

                uid_t i_uid;//文件拥有者标识号

                gid_t i_gid;//文件拥有者所在组的标识号

     

                struct inode_operations *i_op; //指向对该节点操作的一组函数

                struct super_block *i_sb;//指向该文件系统超级块的指针

                atomic_t i_count;//当前使用该节点的进程数,计数为0表明该节点可以被 丢弃或者可以被重新使用

                struct file_operations *i_fop;//指向文件操作的指针

                struct vm_area_struct *i_op;//指向对该文件进行映射所使用的虚存区指针。

                unsigned long i_state;//索引节点的状态标识

                unsigned int i_flags;//文件系统的安装标志

                union{

                      struct minix_inode_info minix_i;

                      struct ext2_inode_info exit2_i;

                 }

    };

           如果索引节点所代表的并不是常规文件而是某个设备,那就有个设备号,这就是i_rdev.

           i_state域如果为DIRTY,该索引节点就是“脏的”,也就是说对应的磁盘索引节点必须被更新。每个索引节点对象总是出现在下列三个循环双向链表的某个链表中:未用索引节点链表、正在使用的索引节点链表和脏索引节点链表。这三个链表都是通过索引节点的i_list域连接在一起的。

           属于正在使用或脏链表的索引节点对象也存放在一个哈希表中。哈希表加快了对索引节点对象的搜索,前提是内核要知道索引节点号以及对应文件所在文件系统的超快对象的地址。

           与索引节点关联的方法叫做索引节点操作表,由inode_operations结构来描述

           struct inode_operations

           {

                  int (*create)(struct inode*, struct dentry *, int);创建一个新的磁盘索引节点

                  int (*link)(struct dentry *, struct inode *, struct dentry *);创建一个新的硬链接

                  int (*unlink)(struct inode *, struct dentry*);删除一个硬链接

                  int (*symlink)(struct inode *, struct dentry *, const char *);为符号连接创建一个新的索引节点

           }

            对于不同的文件系统,其每个函数的具体实现是不同的,也不是每个函数都必须实现,没有实现的函数对应的域应设为NULL

    展开全文
  • linux VFS 之三:索引节点inode

    千次阅读 2014-04-21 14:31:43
    VFS 中的每个文件、目录等都用且只用一个VFS inode表示,存放关于具体文件...具体文件系统的索引节点是存放在磁盘上的,是一种静态结构,要使用它,必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点

    一、进程与vfs对象之间的关系很重要:



    1、VFS 中的每个文件、目录等都用且只用一个 索引节点inode表示,存放关于具体文件或者目录的一般信息。
    2、每个索引节点对象都有一个索引节点号,这个号唯一地标识某个文件系统中的指定文件。
    3、文件名可以随时更改,但是索引节点对文件是唯一的,并且随文件的存在而存在。每个文件又可以有多个文件名(ln建创链接)。即可以通过不同的文件名访问同一个文件。这里多个文件名对应一个文件的关系在数据结构中表示就是dentry和inode的关系。
    4、具体文件系统的索引节点是存放在磁盘上的,是一种静态结构,要使用它,必须调入内存,填写VFS的索引节点,因此,也称VFS索引节点是动态节点。


    Inode中不存储文件的名字,它只存储节点号;而dentry则保存有名字和与其对应的inode,所以就可以通过不同的dentry访问同一个inode。


    进程每打开一个文件,就会有一个file结构与之对应。同一个进程可以多次打开同一个文件而得到多个不同的file结构,
    多个进程也可以打开同一个文件得到多个不同的file结构。
    file结构描述了被打开文件的属性,读写的偏移指针等等当前信息。


    二、inode结构

    每一个索引节点都由一个“struct inode”结构标识,下面认识一下inode的重要成员:

    struct inode {
    umode_t i_mode;    // 文件类型以及存取权限 
    const struct inode_operations  *i_op;    //索引节点操作的函数指针  
    struct super_block  *i_sb;            //超级块对象指针
    struct address_space *i_mapping;   //address_space对象指针??
    struct address_spacei_data;
    unsigned long i_ino;          // 索引节点号
      dev_t i_rdev;  // 该文件系统的主设备号 
    blkcnt_t i_blocks;          //块为单位的文件长度
    loff_t i_size;       //文件长度

    unsigned long i_state;      //索引节点状态标志
    unsigned long dirtied_when; /* jiffies of first dirtying */

    list_head i_dentry;  //引用索引节点的目录项对象链表头

    const struct file_operations*i_fop; //文件操作函数指针

    struct list_headi_devices;   //块设备指针
     
      struct block_device *i_bdev;    //块设备驱动程序指针

    void *i_private;  // 私有数据指针
    };


    三、inode操作方法

    索引节点关联的方法叫索引节点操作,由一个“structinode_operations”结构标识:

    struct inode_operations {
    struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);       //查找目录项。
    int (*create) (struct inode *,struct dentry *,umode_t,struct nameidata *);  open(2) and creat(2)系统调用调用。
    int (*link) (struct dentry *,struct inode *,struct dentry *);                      创建硬链接
    int (*unlink) (struct inode *,struct dentry *);                                            unlink(2)系统调用调用。
    int (*symlink) (struct inode *,struct dentry *,const char *);             symlink(2)系统调用调用。
    int (*mkdir) (struct inode *,struct dentry *,umode_t);                      系统调用 mkdir(2)调用。
    int (*rmdir) (struct inode *,struct dentry *);                                         
    int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
    int (*rename) (struct inode *, struct dentry *, struct inode *, struct dentry *);  系统调用rename(2)调用
    void (*truncate) (struct inode *);                修改与索引节点相关的文件的文件大小。

    int (*permission) (struct inode *, int);             检查访问权限。
    int (*setattr) (struct dentry *, struct iattr *);
    int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
    .................
    } ____cacheline_aligned;


    四、inode初始化

    inode的查找、创建在《linux VFS 之二:超级块superblock》详细说明了。
    这里以sdcardfs举例说明,inode的初始化,如下代码:

    static struct inode *sdcardfs_iget(struct super_block *sb,
    struct inode *lower_inode)
    {
    struct sdcardfs_inode_info *info;
    struct inode *inode; /* the new inode to return */
    int err;


    /* in order for FAT emulation */
    //struct sdcardfs_sb_info *sb_info = sb->s_fs_info;


    inode = iget5_locked(sb, /* our superblock */     //inode的查找、创建
        /*
         * hashval: we use inode number, but we can
         * also use "(unsigned long)lower_inode"
         * instead.
         */
        lower_inode->i_ino, /* hashval */
        sdcardfs_inode_test,/* inode comparison function */
        sdcardfs_inode_set, /* inode init function */
        lower_inode); /* data passed to test+set fxns */
    if (!inode) {
    err = -EACCES;
    iput(lower_inode);
    return ERR_PTR(err);
    }
    /* if found a cached inode, then just return it */
    if (!(inode->i_state & I_NEW))    // cache的inode,已经初始化过,直接返回。
     return inode;

    inode->i_ino = lower_inode->i_ino;    //初始化索引号
    if (!igrab(lower_inode)) {
    err = -ESTALE;
    return ERR_PTR(err);
    }
    sdcardfs_set_lower_inode(inode, lower_inode);   //记录低层文文件系统的inode,sdcardfs特有


    inode->i_version++;
    //*************初始化inode操作函数指针
    /* use different set of inode ops for symlinks & directories */
    if (S_ISDIR(lower_inode->i_mode))
    inode->i_op = &sdcardfs_dir_iops;

    else if (S_ISLNK(lower_inode->i_mode))
    inode->i_op = &sdcardfs_symlink_iops;
    else
    inode->i_op = &sdcardfs_main_iops;
    //*************初始化file操作函数指针***********//

    /* use different set of file ops for directories */
    if (S_ISDIR(lower_inode->i_mode))
    inode->i_fop = &sdcardfs_dir_fops;
    else
    inode->i_fop = &sdcardfs_main_fops;
    inode->i_mappng->a_ops = &sdcardfs_aops;

    //初始化inode的访问时间
    inode->i_atime.tv_sec = 0;
    inode->i_atime.tv_nsec = 0;
    inode->i_mtime.tv_sec = 0;
    inode->i_mtime.tv_nsec = 0;
    inode->i_ctime.tv_sec = 0;
    inode->i_ctime.tv_nsec = 0;


    //*************这边又初始化file操作函数指针,和上面有冲突?***********//
    /* properly initialize special inodes */
    if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
       S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) {
    init_special_inode(inode, lower_inode->i_mode,
      lower_inode->i_rdev);
    //printk(KERN_INFO "sdcardfs: %s(%d)-> i_mode=%o \n", __FUNCTION__, __LINE__, inode->i_mode);


        }

    //从低层文件系统copy其它属性,用于初始化sdcardfs inode
    /* all well, copy inode attributes */
    fsstack_copy_attr_all(inode, lower_inode);
    fsstack_copy_inode_size(inode, lower_inode);


    fix_fat_permission(inode);

    return inode;
    }


    展开全文
  • 关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享几个情况: 情况一 在公司一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下...
  • linux中所有的设备都被看作是文件,每个文件都关联着一个称作索引节点的数据结构,索引节点以静态形式存在于磁盘上,其形式为struct d_inode ,当内核需要操作索引节点时,会把其对到内存索引节点struct m_inode ...
  • 首先明白这两个概论:下面是我以前写的博客vfs中的话 a. 超级块对象struct super_block: ... 索引节点对象struct inode: 包含了内核在操作文件或目录时需要的全部信息。它表示文件类型、引用计数、访问时间等,如i_
  • 关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享一下: 一、发现问题 在公司一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下...
  • 在EXT3中,与索引节点相关的数据结构有两个:ext3_inode和 ext3_inode_info,ext3_inode_info是ext3_inode在内存中的映像,当我们要创建一个文件或目录时,就要在磁盘上分 配一个ext3_inode结构来表示,此外,由于...
  • 为何需要分析区别? 理解 集群节点 存储类型 有利于理解 集群中各个模式的运行机制; 从而根据自己业务 选择不同存储...内存节点只在内存中存储 内部数据库表, 不包括 消息,消息存储索引,队列索引和其他节点状态; ..
  • 关于磁盘空间中索引节点爆满的问题还是挺多的,自己本想写写处理方案,但是看到了网友们文采不错,对于此问题的处理方法都比较妥当,就借过来跟大家分享下:一、发现问题: 在一台配置较低的Linux服务器(内存、...
  • 关于磁盘空间中索引节点爆满的问题还是挺多的,自己本想写写处理方案,但是看到了网友们文采不错,对于此问题的处理方法都比较妥当,就借过来跟大家分享下:  一、发现问题:  在一台配置较低的Linux服务器...
  • 一、发现问题: 在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建... 二、分析问题: 后来用df -i查看了一下/data分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录...
  • Ext2的索引节点对象

    千次阅读 2010-08-17 22:34:00
    上一篇博文我们详细分析了VFS如何将具体文件系统ext2的超级快对象缓存到内存中,主要是利用了ext2_sb_info数据结构。ext2_fill_super函数最后的时候,会将传入该函数的super_block类型的参数sb赋予以下的值:...
  • Linux索引节点(inode)用满导致的一次故障 一、发现问题  在一台配置较低的Linux服务器(内存、硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命令查看了一下磁盘使用情...
  • DHT索引节点和对等路由器 一种新型的DHT节点,旨在加速IPFS网络上的内容分辨率和内容提供。 一个(可爱的)九头蛇,腹部满是记录,许多头(同伴ID)告诉其他节点有关它们的信息,并配备了火箭助推器,可以更快地...
  • 在本文中,我们提出了一种新的虚拟索引方法,用于估计高速链路的节点连接度。 它基于虚拟连接度草图(VCDS),其中通过为每个网络节点生成多个虚拟位图来构建网络流量的紧凑草图。 每个虚拟位图由固定数量的位数...
  • 创建自己的内存管理

    2015-12-31 11:46:50
    链表对内存索引节点的相关操作比较适合,不管是添加节点还是删除节点都非常方便。在此可选择使用数组和链表互相配合来完成这个机制。 首先用数组记录下访问索引节点是否被使用,以及分配的内存空间大小。 然后使用...
  • 构建一个共享内存的资源池,用于后续的使用创建共享内存资源池的思路:1、申请的内存由表头数据结构(相关统计信息)和节点数据结构组成2、内存节点之间利用索引位置串联而成一个类似双向链表的数据结构3、每次插入...
  • 一、发现问题:  在... <br /> 二、分析问题:  后来用df -i查看了一下/data分区的索引节点(inode),发现已经用满(IUsed=100%),导致系统无法创建新目录和文件。 <br />  inode译成
  • 系统中用到的大量程序和数据,平时总是以文件的形式存放在外存中,需要时调入内存 如果由用户直接管理外存上的文件,不仅要求用户熟悉外存特性,了解各种文件的属性,以及它们在外存上的位置,而且在多用户环境下,...
  • 索引能够有效降低数据的搜索空间、提高内存数据库的查询效率,然而当前它却受到性能和效率的挑战。 基于图形处理器的通用计算(GPGPU)在多个领域具有重要的研究价值和应用前景,也是当前研究的热点。目前图形...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,474
精华内容 589
关键字:

内存索引节点