Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
$B3d$j9~$_$N8eH>It!"%U%!%$%k%7%9%F%`(B
[go: Go Back, main page]

$B3d$j9~$_$N8eH>It!"%U%!%$%k%7%9%F%`(B

					2021$BG/(B02$B7n(B03$BF|(B
$B>pJs2J3XN`(B $B%*%Z%l!<%F%#%s%0%7%9%F%`(B II

                                       $BC^GHBg3X(B $B%7%9%F%`>pJs7O(B 
                                       $B?7>k(B $BLw(B
                                       <yas@cs.tsukuba.ac.jp>

$B$3$N%Z!<%8$O!" http://www.coins.tsukuba.ac.jp/~yas/coins/os2-2020/2021-02-03
$B$"$k$$$O!" http://www.coins.tsukuba.ac.jp/~yas/
http://www.cs.tsukuba.ac.jp/~yas/

$B"#O"Mm;v9`(B

$B;n83$K$D$$$F(B $BIaDL$O!"(BTasklet $B$+(B Work Queue $B$r;H$($P$h$$!#(B

$BCm0U(B1: Tasklet $B$O!"(Btask $B9=B$BN$H$O$^$C$?$/4X78$J$$!#L>A0$,$h$/$J$$!#(B

$BCm0U(B2: Softirq $B$H$$$&MQ8l$r!"3d$j9~$_=hM}$N8eH>It$H$$$&0UL#$G;H$&?M$b$$(B $B$k!#(B

$BCm0U(B3: $BEAE}E*$J(BUnix$B$G$O!"(Btop half $B$O!"%7%9%F%`!&%3!<%k$+$iGI@8$9$k>e0L(B $BAX$N=hM}!"(Bbottom half $B$O!"3d$j9~$_$+$iGI@8$9$k2<0LAX$N=hM}$N0UL#$G;H$o(B $B$l$k$3$H$,$"$k!#(BLinux $B$G$O!"(Btop half, bottom half $B$O!"3d$j9~$_=hM}$NA0(B $BH>ItJ,$H8eH>ItJ,$N0UL#$K;H$&!#(B

$B"#(BTasklet

Tasklet $B$G#1$D$N;E;v$O linux-5.10.3/include/linux/interrupt.h 609: struct tasklet_struct 610: { 611: struct tasklet_struct *next; 612: unsigned long state; 613: atomic_t count; 614: bool use_callback; 615: union { 616: void (*func)(unsigned long data); 617: void (*callback)(struct tasklet_struct *t); 618: }; 619: unsigned long data; 620: };

$BA4BN$H$7$F!"tasklet_vec$B!
$B?^(B? Tasklet$B$K$*$1$k;E;v$N%-%e!<(B

$B"!(BTasklet$B$N9=B$BN$N@k8@(B

$B@EE*$K(B struct tasklet_struct $B$r@k8@$9$k$K$O!" DECLARE_TASKLET(name, func) $BM-8z$J(B(count==0) $B$N(B struct tasklet_struct $B$r@k8@$9$k(B DECLARE_TASKLET_DISABLED(name, func) $BL58z$J(B(count==1) $B$N(B struct tasklet_struct $B$r@k8@$9$k(B $BB>$N9=B$BN$K(B struct tasklet_struct $B$rKd$a9~$`;~$d(B kmalloc()$BEy$GF0E*$K3NJ]$7$?>l9g$K$O!" void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); $B$=$NB>$K!"@8@.>CLGM-8zL58z$K4X$7$F
  • tasklet_disable(): $BL58z2=$9$k!J%-%e!<$K$"$k$,$"$k$, tasklet_disable_nosync(): $BL58z2=$7!" tasklet_enable(): $BM-8z$K$9$k(B
  • tasklet_kill(): $B$G%-%e!<$+$i:o=|$9$k(B

    $B"!(BTasklet$B$N%O%s%I%i(B

    Tasklet $B$N%O%s%I%i$O!" void tasklet_handler(unsigned long data) { ... }

    $B"!(BTasklet$B$N Tasklet $B$N%O%s%I%i$r void tasklet_schedule(struct tasklet_struct *t) Tasklet t $B$rDL>o$NM%@hEY$G%9%1%8%e!<%k$9$k(B void tasklet_hi_schedule(struct tasklet_struct *t) Tasklet t $B$r9bM%@hEY$G%9%1%8%e!<%k$9$k(B $B$9$k$H!"$=$l$O!V$=$N$&$A$K!W(B1$BEY$@$1$B"!(BTasklet$B$NMxMQNc(B

    $BL5@~(BLAN$B$N%I%i%$%P$G$NMxMQNc!#(B
    linux-5.10.3/drivers/net/wireless/ath/ath11k/ce.h
     150:	struct ath11k_ce_pipe {
    ...
     160:	        struct tasklet_struct intr_tq;
    ...
     165:	};
    
    linux-5.10.3/drivers/net/wireless/ath/ath11k/pci.c
     558:	static int ath11k_pci_config_irq(struct ath11k_base *ab)
     559:	{
     560:	        struct ath11k_ce_pipe *ce_pipe;
    ...
     542:	                        ret = request_irq(irq, ath11k_pci_ext_interrupt_handler,
     543:	                                          IRQF_SHARED,
     544:	                                          "DP_EXT_IRQ", irq_grp);
    ...
     584:	                tasklet_init(&ce_pipe->intr_tq, ath11k_pci_ce_tasklet,
     585:	                             (unsigned long)ce_pipe);
    ...
     605:	}
    
  • $B=i4|2=;~$K!"$3$N9=B$BN$r(B tasklet_init() $B$G=i4|2=$7$F$$$k!#(B
    linux-5.10.3/drivers/net/wireless/ath/ath11k/pci.c
     392:	static irqreturn_t ath11k_pci_ce_interrupt_handler(int irq, void *arg)
     393:	{
     394:	        struct ath11k_ce_pipe *ce_pipe = arg;
     395:	
     396:	        ath11k_pci_ce_irq_disable(ce_pipe->ab, ce_pipe->pipe_num);
     397:	        tasklet_schedule(&ce_pipe->intr_tq);
     398:	
     399:	        return IRQ_HANDLED;
     400:	}
    
    linux-5.10.3/drivers/net/wireless/ath/ath11k/pci.c
     383:	static void ath11k_pci_ce_tasklet(unsigned long data)
     384:	{
     385:	        struct ath11k_ce_pipe *ce_pipe = (struct ath11k_ce_pipe *)data;
     386:	
     387:	        ath11k_ce_per_engine_service(ce_pipe->ab, ce_pipe->pipe_num);
     388:	
     389:	        ath11k_pci_ce_irq_enable(ce_pipe->ab, ce_pipe->pipe_num);
     390:	}
    

    $B"#(BWork Queue

    $B3d$j9~$_$K4XO"$7$?=hM}$G!"l9g(B(Tasklet$B$d(BSoftirq $B$G$OIT2DG=$J(B $B>l9g(B)$B$K(BWork Queue$B;H$&!#(B

    $B"!(BWork Queue$B$N%o!<%+!&%9%l%C%I(B

    Work Queue $B$N%o!<%+!&%9%l%C%I$O!"%+!<%M%k!&%l%Y%k$N%9%l%C%I$G!"(B $B3d$j9~$_=hM}$N8eH>ItJ,$N=hM}$r9T$&$3$H$,$G$-$k!#(B ($B3d$j9~$_=hM}0J30$G;H$C$F$b$h$$!#(B)

    workqueue_struct$B!
    $B?^(B? Work Queue$B$K$*$1$k;E;v$N%-%e!<(B

    $B%-%e!<$K$D$J$,$l$k;E;v$O!"(BTasklet $B$N;E;v$H$[$H$s$IF1$8$G!"4X?t$X$N%]%$(B $B%s%?(B func $B$H(B data $B$+$i$J$k!#=hM}$N

    $BHFMQ$N(B Work Queue $B%G%U%)%k%H$N%o!<%+!&%9%l%C%I$O!"(Bkworker/n (n$B$O%W%m%;%C(B $B%5HV9f(B) $B$H$h$P$l!"%W%m%;%C%5$4$H$K:n$i$l$k!##1$D$N%9%l%C%I$G!"MM!9$JMW(B $B5a85$N;E;v$r$3$J$9!#2<$NNc$G$O!"(B1$B$D$N%W%m%;%C%5$K(B5$B8D$N%9%l%C%I$,(B $B:n$i$l$F$$$k!#$=$N$&$A(B2$B$D$O!"(Bnice $BCM$,(B -20 $B$G9bM%@hEY!#(B

    $ ps alx|grep worker|wc [$B
         22     289    1881
    $ ps alx|grep 'worker.*/0' [$B
    1     0  4779     2  20   0      0     0 worker S    ?          0:00 [kworker/0:2]
    1     0  5276     2  20   0      0     0 worker S    ?          0:00 [kworker/0:1]
    1     0  5479     2  20   0      0     0 worker S    ?          0:00 [kworker/0:0]
    5     0 12906     2   0 -20      0     0 worker S<   ?          0:59 [kworker/0:1H]
    5     0 30659     2   0 -20      0     0 worker S<   ?          0:07 [kworker/0:0H]
    0  1013  5803  5611  20   0 117076  1016 pipe_w S+   pts/2      0:00 grep --color=auto worker.*/0
    $ []
    
    $BHFMQ$N(B Work Queue $B$N%o!<%+!&%9%l%C%I$NB>$K!"@lMQ$N%o!<%+!&%9%l%C%I$r:n(B $B$k$3$H$b$G$-$k!#(B

    $B"!(Bwork_struct$B9=B$BN(B

    $B%o!<%/!&%-%e!<$GMQ$$$k(B 1 $B$D$N;E;v$O!"9=B$BN(B struct work_struct $B$GI=8=$5(B $B$l$k!#(B
    linux-5.10.3/include/linux/workqueue.h
      21:	typedef void (*work_func_t)(struct work_struct *work);
    
     102:	struct work_struct {
     103:	        atomic_long_t data;
     104:	        struct list_head entry;
     105:	        work_func_t func;
    ...
     109:	};
    
    $B struct work_struct my_work; ... INIT_WORK(&my_work,my_work_handler);

    $B"!(BWork Queue $B%O%s%I%i(B

    Work Queue $B%O%s%I%i$O!" void my_work_handler(struct work_struct *work) { ... }

    $B"!(BWork $B$N $B%O%s%I%i$r8F$S=P$7$?$$;~$K$O!" schedule_work(&work); $B$3$N7k2L!"(BINIT_WORK() $B$G@_Dj$7$?%O%s%I%i$,%o!<%+!&%9%l%C%I$K$h$j!V$=$N(B $B$&$A!W$K8F$S=P$5$l$k!#(B

    schedule_work() $B$G$O!"B(:B$K/$78e$K schedule_delayed_work(&work, ticks); ticks $B$O!"$I$N$/$i$$4V$r$H$k$+!#C10L$O!"(B ticks (jiffies$B$NC10L(B)$B!#(B $BB?$/$N%7%9%F%`$G(B10$B%_%jIC(B-1$B%_%jIC$G!"@_Dj$K$h$C$F0[$J$k!#(B

    $B"!(Bflush_scheduled_work()

    schedule_work() $B$GMW5a$7$?;E;v$,40N;$7$?$3$H$rBT$C$F!"$B"!(Balloc_workqueue()

    $B@lMQ$N%o!<%+!&%9%l%C%I$r:n$j$?$$;~$K$O!"
  • alloc_workqueue(): $B%o!<%+!&%9%l%C%I$r:n$k!#(B
  • queue_work(), queue_delayed_work():: $B%-%e!<$K;E;v$r2C$($k!#(B

    $B"!(BWork Queue$B$NMxMQNc(B

    x86 CMOS RTC $B$G$N3d$j9~$_%O%s%I%i$NNc!#(B $B:F7G!#(B
    linux-5.10.3/arch/x86/include/asm/mc146818rtc.h
     101:	#define RTC_IRQ 8
    
    linux-5.10.3/drivers/rtc/rtc-cmos.c
      73:	struct cmos_rtc {
      74:	        struct rtc_device       *rtc;
      75:	        struct device           *dev;
      76:	        int                     irq;
    ....
      92:	};
    
     648:	static struct cmos_rtc  cmos_rtc;
    
     706:	static int INITSECTION
     707:	cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
     708:	{
    ...
     798:	        cmos_rtc.rtc = devm_rtc_allocate_device(dev);
    ...
     851:	                        rtc_cmos_int_handler = cmos_interrupt;
    ...
     853:	                retval = request_irq(rtc_irq, rtc_cmos_int_handler,
     854:	                                0, dev_name(&cmos_rtc.rtc->dev),
     855:	                                cmos_rtc.rtc);
    ...
     861:	                cmos_rtc.rtc->ops = &cmos_rtc_ops;
    ...
     867:	        retval = rtc_register_device(cmos_rtc.rtc);
    ...
     898:	}
    
     650:	static irqreturn_t cmos_interrupt(int irq, void *p)
     651:	{
    ...
     653:	        u8              irqstat;
    ...
     665:	        irqstat = CMOS_READ(RTC_INTR_FLAGS);
    ...
     692:	        if (is_intr(irqstat)) {
     693:	                rtc_update_irq(p, 1, irqstat);
     694:	                return IRQ_HANDLED;
     695:	        } else
     696:	                return IRQ_NONE;
     697:	}
    
    $B0J2 linux-5.10.3/include/linux/rtc.h 84: struct rtc_device { ... 109: struct work_struct irqwork; ... 143: }; linux-5.10.3/drivers/rtc/class.c 193: static struct rtc_device *rtc_allocate_device(void) 194: { 195: struct rtc_device *rtc; 196: 197: rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); ... 218: INIT_WORK(&rtc->irqwork, rtc_timer_do_work); ... 228: return rtc; 229: } linux-5.10.3/drivers/rtc/interface.c 900: void rtc_timer_do_work(struct work_struct *work) 901: { ... 966: } 686: void rtc_update_irq(struct rtc_device *rtc, 687: unsigned long num, unsigned long events) 688: { ... 693: schedule_work(&rtc->irqwork); 694: }

    $B"#3d$j9~$_$N8eH>It$NA*Br(B

    $B"#%U%!%$%k%7%9%F%`(B

    $B"!5a$a$i$l$k5!G=(B

    $B%7%9%F%`!&%3!<%k(B $BMM!9$JJ*M}G^BN$H@\B3J}K!$NMxMQ(B $BMM!9$J%G%#%9%/>e$NI=8=(B($B%U%!%$%k%7%9%F%`(B) $BCm0U(B: $B!V%U%!%$%k%7%9%F%`!W$H$$$&8@MU$,!"MM!9$J0UL#$G;H$o$l$k(B $B%U%!%$%k%7%9%F%`8GM-$N=hM}$O!"(B_operations $B$N$B?^(B?$B!!(Bstruct file,struct dentry,struct inode,struct super_block
    $B?^(B? $B%9!<%Q!<%V%m%C%/!"(Binode$B!"(Bdentry$B!"(Bfile

    $B"!(Bstruct file

    struct file $B$O!"%W%m%;%9$,%U%!%$%k$r(B open() $B$7$?;~$K3d$jEv$F$i$l$k!#(B
        int fd1 = open("file1",O_RDONLY);
        int fd2 = open("file1",O_RDONLY);
    
    $B%U%!%$%kL>(B "file1" $B$GI=8=$5$l$k%U%!%$%k$N(B inode $B9=B$BN$O!"(B1 $B8D$G$b!"(B file $B9=B$BN$O!"(B2 $B8D3d$jEv$F$i$l$k!#(B

    $B%G%#%9%/>e$K$OBP1~$9$k%G!<%?9=B$$OB8:_$7$J$$!#(B

    linux-5.10.3/include/linux/fs.h
     916:	struct file {
    ...
     921:	        struct path             f_path;
     922:	        struct inode            *f_inode;       /* cached value */
     923:	        const struct file_operations    *f_op;
     931:	        atomic_long_t           f_count;
     932:	        unsigned int            f_flags;
     933:	        fmode_t                 f_mode;
    ...
     935:	        loff_t                  f_pos;
    ...
     945:	        void                    *private_data;
    ...
     952:	        struct address_space    *f_mapping;
    ...
     955:	} __randomize_layout
     956:	  __attribute__((aligned(4)));  /* lest something weird decides that 2 is OK */
    
    linux-5.10.3/include/linux/path.h
       8:	struct path {
       9:	        struct vfsmount *mnt;
      10:	        struct dentry *dentry;
      11:	} __randomize_layout;
    
    • f_path.dentry: $BBP1~$9$k(B dentry $B%*%V%8%'%/%H$X$N%]%$%s%?!#(B
    • f_mode: open() $B%7%9%F%`!&%3!<%k$N%b!<%I$r>/$7JQ7A$7$?$b$N!#(B FMODE_READ, FMODE_WRITE $BEy!#(B
    • f_pos: $B%U%!%$%k$rFI$_=q$-$9$k0LCV!#%7!<%/%]%$%s%?!#(B
    • f_count: $B;2>H%+%&%s%?!#%U%!%$%k$r3+$/$H(B 1 $B$G!"(Bfork() $B$9$k$H(B $BA}$(!"(B close() $B$9$k$H8:$k!#(B
    • f_mapping: $B%U%!%$%k$NFbMF$r%W%m%;%9$N%"%I%l%96u4V$K%^%C%W$9$k;~$K(B $B;H$&(B($B%Z!<%8%-%c%C%7%e(B)$B!#(B
    • private_data: $B%U%!%$%k%7%9%F%`$K8GM-$N%G!<%?$rJ]B8$9$k!#(B $B!J7Q>5!"0Q>y$N0l

      $B"!7Q>5!&0Q>y$N C$B8@8l$K$h$k%*%V%8%'%/%H;X8~$N7Q>5!&0Q>y$N$B?^(B?

      $B?^(B? $BJ}K!#1(B

      $B?^(B?

      $B?^(B? $BJ}K!#2(B

      $B?^(B?

      $B?^(B? $BJ}K!#3(B

      $B"!(Bstruct file_operations

      $B%G%P%$%9%I%i%$%P$N2s(B $B$G$bEP>l$7$F$$$k!#(B

      struct file$B$NA`:n$O!"$?$H$($P struct file *file; file->f_op->read(file, buf, count, pos); f_op $B$K$O!" linux-5.10.3/include/linux/fs.h 1822: struct file_operations { 1823: struct module *owner; 1824: loff_t (*llseek) (struct file *, loff_t, int); 1825: ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 1826: ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 1827: ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); 1828: ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); 1829: int (*iopoll)(struct kiocb *kiocb, bool spin); 1830: int (*iterate) (struct file *, struct dir_context *); 1831: int (*iterate_shared) (struct file *, struct dir_context *); 1832: __poll_t (*poll) (struct file *, struct poll_table_struct *); 1833: long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 1834: long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 1835: int (*mmap) (struct file *, struct vm_area_struct *); 1836: unsigned long mmap_supported_flags; 1837: int (*open) (struct inode *, struct file *); 1838: int (*flush) (struct file *, fl_owner_t id); 1839: int (*release) (struct inode *, struct file *); 1840: int (*fsync) (struct file *, loff_t, loff_t, int datasync); 1841: int (*fasync) (int, struct file *, int); 1842: int (*lock) (struct file *, int, struct file_lock *); 1843: ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1844: unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1845: int (*check_flags)(int); 1846: int (*flock) (struct file *, int, struct file_lock *); 1847: ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 1848: ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 1849: int (*setlease)(struct file *, long, struct file_lock **, void **); 1850: long (*fallocate)(struct file *file, int mode, loff_t offset, 1851: loff_t len); 1852: void (*show_fdinfo)(struct seq_file *m, struct file *f); 1853: #ifndef CONFIG_MMU 1854: unsigned (*mmap_capabilities)(struct file *); 1855: #endif 1856: ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, 1857: loff_t, size_t, unsigned int); 1858: loff_t (*remap_file_range)(struct file *file_in, loff_t pos_in, 1859: struct file *file_out, loff_t pos_out, 1860: loff_t len, unsigned int remap_flags); 1861: int (*fadvise)(struct file *, loff_t, loff_t, int); 1862: } __randomize_layout; $B

    • $BB?$/$OF1L>$N%7%9%F%`!&%3!<%k$r

      $B"!(Bstruct dentry

      struct dentry $B$O!"%G%#%l%/%H%j$K4^$^$l$F$$$kL>A0$NMWAG(B($B!V(B/$B!W$r4^$^$J$$(B $BL>A0(B)$B$rI=$99=B$BN!#(B struct dentry $B$O!"%a%b%jCf$K$N$_B8:_$9$k!#%G%#%9%/Cf$KBP1~$9$k%G!<%?$O(B $B$J$$!#%G%#%l%/%H%j$GL>A0$r8!:w$7$?$j%U%!%$%k$r:n@.$9$k;~$K%a%b%jCf$K:n(B $B$i$l$k!#(B
      linux-5.10.3/include/linux/dcache.h
        89:	struct dentry {
      ...
        94:	        struct dentry *d_parent;        /* parent directory */
        95:	        struct qstr d_name;
        96:	        struct inode *d_inode;          /* Where the name belongs to - NULL is
        97:	                                         * negative */
        98:	        unsigned char d_iname[DNAME_INLINE_LEN];        /* small names */
        99:	
       100:	        /* Ref lookup also touches following */
       101:	        struct lockref d_lockref;       /* per-dentry lock and refcount */
       102:	        const struct dentry_operations *d_op;
       103:	        struct super_block *d_sb;       /* The root of the dentry tree */
      ...
       105:	        void *d_fsdata;                 /* fs-specific data */
      ...
       111:	        struct list_head d_child;       /* child of parent list */
       112:	        struct list_head d_subdirs;     /* our children */
      ...
       121:	} __randomize_layout;
      
       286:	static inline unsigned d_count(const struct dentry *dentry)
       287:	{
       288:	        return dentry->d_lockref.count;
       289:	}
      
        33:	 #define HASH_LEN_DECLARE u32 hash; u32 len
      
        47:	struct qstr {
        48:	        union {
        49:	                struct {
        50:	                        HASH_LEN_DECLARE;
        51:	                };
        52:	                u64 hash_len;
        53:	        };
        54:	        const unsigned char *name;
        55:	};
      
        83:	#  define DNAME_INLINE_LEN 40 /* 128 bytes */
      
      • d_inode: $B$3$N(B dentry $B$KBP1~$7$F$$$k(B inode $B!#(BNULL $B$J$iBP1~$7$F$$$k(B $B$b$N$,$J$$(B($B%M%,%F%#%V%-%c%C%7%e(B)$B!#(B
      • d_name, d_iname[]: $BJ8;zNs$NL>A0$rJ];}$9$k!#(B $BC;$$$b$N(B(DNAME_INLINE_LEN-1$B0J2<(B)$B$O!"(Bdentry $B9=B$BNCf$N(B d_iname[] $B$KF~$l$k!#D9$$$b$N$O!"(B $BJL$N>l=j$K%a%b%j$r3NJ]$7$FJ]B8$9$k!#(B
      • d_lockref.count: $B;2>H%+%&%s%?!#(B
      • d_op: dentry $B$rA`:n$9$k$?$a$N d_sb: superblock $B$X$N%]%$%s%?(B
      • d_parent: $B$=$N(B dentry $B$r4^$s$G$$$k%G%#%l%/%H%j$N(B dentry $B!#$?$H$($P!"(B /home/yas $B$H$$$&%Q%9L>$G!"(Byas $B$N(B d_parent $B$O!"(Bhome $B$N(B dentry $B$r;X$9!#(B home $B$N(B dentry $B$O!"(B/ $B$N(B dentry $B$r;X$9!#(B
      • d_child: $B6&DL$N(B d_parent $B$K4^$^$l$F$$$k(B d_entry $B$r$D$J$0!#(B
      • d_subdirs: $B<+J,<+?H$N;R6!$N%G%#%l%/%H%j(B
      • d_fsdata: $B%U%!%$%k%7%9%F%`8GM-$N%G!<%?!#(B
      dentry $B$O!"(B $B%9%i%V%"%m%1!<%?(B (kmem_cache_create(),kmem_cache_alloc(),kmem_cache_free())$B$G4IM}$5$l$F(B $B$$$k!#(B

      $B"!(Bdentry$B$N>uBV(B

      • $B;HMQCf(B: count $B$,(B 0 $B0J>e!#M-8z$J(Binode$B$rJ];}!#(B
      • $B6u$-(B: count $B$,(B 0$B!#M-8z$J(Binode$B$rJ];}!#%-%c%C%7%e$H$7$F%a%b%jCf$KB8:_$9$k!#(B $BF1$8%U%!%$%k$r:F$S(B open() $B$7$?;~$K9bB.!#(B $B%a%b%j$,ITB-$7$F$-$?$i>C$5$l$k$3$H$,$"$k(B>
      • $B%M%,%F%#%V!&%-%c%C%7%e(B: count $B$,Ii!#M-8z$J(B inode $B$rJ];}$7$F$$$J$$!#(B $B%U%!%$%k$,:o=|$5$l$?$+!"B8:_$7$J$$%U%!%$%k$r(B open() $B$7$h$&$H$7$?;~$K$=(B $B$N$h$&$J(B dentry $B$,:n$i$l$k!#(B $BB8:_$7$J$$%U%!%$%k$r7+$jJV$7(B open() $B$7$?;~$K%G%#%9%/$K9T$+$J$/$F$b%(%i!<(B ENOENT $B$,JV$;$k(B($B%M%,%F%#%V!&%-%c%C%7%e(B)$B!#(B

      $B"!(Bstruct inode

      struct inode $B$O!"A4$F$N%U%!%$%k!&%7%9%F%`$G6&DL$NMWAG$rJ];}$9$k!"%a%b%j(B $BCf$N9=B$BN!#3F%U%!%$%k!&%7%9%F%`$O!"$3$l$K4^$^$l$k$h$&$J%G!<%?$r$=$l$>(B $B$lFH<+$NJ}K!$G%G%#%9%/$KJ]B8$9$k!#(B
      linux-5.10.3/include/linux/fs.h
       610:	struct inode {
       611:	        umode_t                 i_mode;
       612:	        unsigned short          i_opflags;
       613:	        kuid_t                  i_uid;
       614:	        kgid_t                  i_gid;
      ...
       622:	        const struct inode_operations   *i_op;
       623:	        struct super_block      *i_sb;
      ...
       631:	        unsigned long           i_ino;
      ...
       640:	                const unsigned int i_nlink;
      ...
       643:	        dev_t                   i_rdev;
       644:	        loff_t                  i_size;
       645:	        struct timespec64       i_atime;
       646:	        struct timespec64       i_mtime;
       647:	        struct timespec64       i_ctime;
       648:	        spinlock_t              i_lock; /* i_blocks, i_bytes, maybe i_size */
       649:	        unsigned short          i_bytes;
       650:	        u8                      i_blkbits;
       651:	        u8                      i_write_hint;
       652:	        blkcnt_t                i_blocks;
      ...
       665:	        struct hlist_node       i_hash;
      ...
       679:	                struct hlist_head       i_dentry;
      ...
       684:	        atomic_t                i_count;
      ...
       720:	        void                    *i_private; /* fs or device private pointer */
       721:	} __randomize_layout;
      
      • i_ino: inode$BHV9f!#%U%!%$%k%7%9%F%`$G%f%K!<%/!#(B
      • i_uid, i_gid, i_nlink, i_uid, i_gid, i_rdev, i_blkbits, i_size, i_atime, i_mtime, i_ctime, i_blocks, i_bytes, i_mode: $BB0@-!#(Bstat() $B%7%9%F%`!&%3!<(B $B%k$GJV$5$l$k!#(Bls -l $B$GI=<($5$l$k!#(B
      • i_op: $B$=$N(Binode$B$K8GM-$N i_sb: $BB0$7$F$$$k%U%!%$%k%7%9%F%`$N(B superblock $B$X$N%]%$%s%?!#(B
      • i_state: inode$B$N>uBV(B(dirty $B$+$I$&$+!"%G%#%9%/$X$N(B $B=q$-9~$_$r9T$C$F$$$k$+$I$&$+!"Ey(B)$B$rI=$9!#(B
      • i_hash: $B%U%!%$%k$r3+$/$3$H$N9bB.$N$?$a$N%O%C%7%eI=$r:n$k$?$a$N%U%#!<(B $B%k%I!#!!(B
      • i_dentry: $B$=$N(Binode$B$r4^$s$G$$$k(B dentry $B9=B$BN$N%j%9%H!#(B
      • i_count: $B;2>H%+%&%s%?!#(B0 $B$,L$;HMQ$N0UL#!#(B

      $B"!(Bstruct inode_operations

      inode$B$NA`:n$O!"$?$H$($P struct inode *inode; ... inode->i_op->create(inode, name, mode, true); i_op $B$K$O!" linux-5.10.3/include/linux/fs.h 1864: struct inode_operations { 1865: struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int); 1866: const char * (*get_link) (struct dentry *, struct inode *, struct delayed_call *); 1867: int (*permission) (struct inode *, int); 1868: struct posix_acl * (*get_acl)(struct inode *, int); 1869: 1870: int (*readlink) (struct dentry *, char __user *,int); 1871: 1872: int (*create) (struct inode *,struct dentry *, umode_t, bool); 1873: int (*link) (struct dentry *,struct inode *,struct dentry *); 1874: int (*unlink) (struct inode *,struct dentry *); 1875: int (*symlink) (struct inode *,struct dentry *,const char *); 1876: int (*mkdir) (struct inode *,struct dentry *,umode_t); 1877: int (*rmdir) (struct inode *,struct dentry *); 1878: int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t); 1879: int (*rename) (struct inode *, struct dentry *, 1880: struct inode *, struct dentry *, unsigned int); 1881: int (*setattr) (struct dentry *, struct iattr *); 1882: int (*getattr) (const struct path *, struct kstat *, u32, unsigned int); 1883: ssize_t (*listxattr) (struct dentry *, char *, size_t); 1884: int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 1885: u64 len); 1886: int (*update_time)(struct inode *, struct timespec64 *, int); 1887: int (*atomic_open)(struct inode *, struct dentry *, 1888: struct file *, unsigned open_flag, 1889: umode_t create_mode); 1890: int (*tmpfile) (struct inode *, struct dentry *, umode_t); 1891: int (*set_acl)(struct inode *, struct posix_acl *, int); 1892: } ____cacheline_aligned;
      • $BB?$/$N$b$N$O!"F1L>$N%7%9%F%`!&%3!<%k$H4XO"$7$F$$$k!#(B
      • create(): open() $B%7%9%F%`!&%3!<%k$d(B creat() $B%7%9%F%`!&%3!<%k$G!"%U%!(B $B%$%k$r:n@.$9$k;~$K8F$P$l$k!#0z?t$O!"%G%#%l%/%H%j$N(B inode$B!"$=$N%G%#%l%/(B $B%H%j$NCf$NL>A0$r<($9(B dentry$B!"L>A02r7h$G;H$&%G!<%?!#(B
      • lookup(): $B%U%!%$%kL>$r0z?t$K$9$k%7%9%F%`!&%3!<%k$N follow_link(), put_link(): $B%7%s%\%j%C%/!&%j%s%/$r$?$I$kA`:n$GMQ$$$k!#(B
      • permission(), check_acl(): $B%"%/%;%98"$N%A%'%C%/$GMQ$$$k!#(B
      • kstat, iattr $B$OB0@-!#(B

      $B"!(Bstruct super_block

      $B%9!<%Q!<%V%m%C%/$O!"%U%!%$%k%7%9%F%`$N5/E@$H$J$k%G!<%?9=B$!#$=$N%U%!%$(B $B%k!&%7%9%F%`$K4^$^$l$F$$$k(B inode $B$d(B dentry $B$r4IM}$9$k!#(B
      linux-5.10.3/include/linux/fs.h
      1416:	struct super_block {
      ...
      1421:	        loff_t                  s_maxbytes;     /* Max file size */
      1422:	        struct file_system_type *s_type;
      1423:	        const struct super_operations   *s_op;
      ...
      1430:	        struct dentry           *s_root;
      ...
      1465:	        void                    *s_fs_info;     /* Filesystem private info */
      ...
      1532:	        struct list_lru         s_dentry_lru;
      1533:	        struct list_lru         s_inode_lru;
      ...
      1546:	        struct list_head        s_inodes;       /* all inodes */
      ...
      1550:	} __randomize_layout;
      
      • s_maxbytes: $B:n@.$G$-$k%U%!%$%k$NBg$-$5$N:GBg!#(B
      • s_type: $B%U%!%$%k%7%9%F%`8GM-$N%G!<%?!#%/%i%9JQ?t!#(B
      • s_op: $B%U%!%$%k%7%9%F%`8GM-$N s_fs_info: $B%U%!%$%k%7%9%F%`$N%$%s%9%?%s%9!J%^%&%s%H$4$H$K0[$J$k!K(B $B$K8GM-$N%G!<%?!#%$%s%9%?%s%9JQ?t!#(B
      • s_root: $B$I$3$K%^%&%s%H$7$F$$$k$+$r$7$a$9%G%#%l%/%H%j(B
      • s_inodes, s_dentry_lru, s_inode_lru: $B%U%!%$%k%7%9%F%`$K4^$^$l$F$$(B $B$k(Binode $B$d(B dentry $B$r4IM}$9$k$?$a$N%U%#!<%k%I!#(B

      $B"!(Btask_struct $B$H(B struct file

      struct task_struct $B$+$i;X$5$l$k!#%U%!%$%k5-=R;R(Bfd$B$O!"(Bstruct task_struct *p; $B$N;~!"(Bp->files->fdt->fd[fd] $B$N(B struct file $B$rI=(B $B$9!#3+$$$F$$$k%U%!%$%k$N?t$,>.$5$$;~$O!"(B p->files->fd_array[fd]$B$HF1$8!#(B $BB?$/$N%U%!%$%k$r3+$/%W%m%;%9$G$O!"(B p->files->fd_array[NR_OPEN_DEFAULT]$B$GB-$j$J$/$J$C$?;~$O!"(B expand_files(), expand_fdtable() $B$G3HD%$9$k!#(B $B$3$l$i$N4X?t$G$O!"(Bkmalloc() $BEy$G%a%b%j$r3d$jEv$F$k!#(B
      linux-5.10.3/include/linux/sched.h
       640:	struct task_struct {
      ...
       959:	        struct files_struct             *files;
      ...
      1366:	};
      
      linux-5.10.3/include/linux/fdtable.h
        24:	#define NR_OPEN_DEFAULT BITS_PER_LONG
      
        49:	struct files_struct {
      ...
        57:	        struct fdtable __rcu *fdt;
        58:	        struct fdtable fdtab;
      ...
        67:	        struct file __rcu * fd_array[NR_OPEN_DEFAULT];
        68:	};
      
      linux-5.10.3/include/asm-generic/bitsperlong.h
         8:	#ifdef CONFIG_64BIT
         9:	#define BITS_PER_LONG 64
        10:	#else
        11:	#define BITS_PER_LONG 32
        12:	#endif /* CONFIG_64BIT */
      

      $B?^(B?$B!!(Bp-files->fd_array[fd]">
      $B?^(B? task_struct$B!"%U%!%$%k5-=R;R!"(Bfile$B9=B$BN!"$=$NB>(B

      $B"#(Bread() $B%7%9%F%`%3!<%k$H(B Ext4 $B%U%!%$%k%7%9%F%`(B

      read() $B%7%9%F%`!&%3!<%k$N$B"!(Bread() $B%7%9%F%`!&%3!<%k(B
    • linux-5.10.3/fs/read_write.c
       642:	SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
       643:	{
       644:	        return ksys_read(fd, buf, count);
       645:	}
      
       623:	ssize_t ksys_read(unsigned int fd, char __user *buf, size_t count)
       624:	{
       625:	        struct fd f = fdget_pos(fd);
       626:	        ssize_t ret = -EBADF;
       627:	
       628:	        if (f.file) {
       629:	                loff_t pos, *ppos = file_ppos(f.file);
       630:	                if (ppos) {
       631:	                        pos = *ppos;
       632:	                        ppos = &pos;
       633:	                }
       634:	                ret = vfs_read(f.file, buf, count, ppos);
       635:	                if (ret >= 0 && ppos)
       636:	                        f.file->f_pos = pos;
       637:	                fdput_pos(f);
       638:	        }
       639:	        return ret;
       640:	}
      
      linux-5.10.3/include/linux/file.h
        36:	struct fd {
        37:	        struct file *file;
        38:	        unsigned int flags;
        39:	};
      
      • fdget_pos() $B$G!"(Bfd (int$B7?(B) $B$+$i(B struct file * $B$r4^$`(B struct fd $B$XJQ49$9$k!#(B $BFbItE*$K$O!"(Bcurrent->files->fd_array[fd] $B$H$@$$$?$$F1$8!#(B $B$5$i$K!"(Bpos $B$rA`:n$9$k$?$a$N%m%C%/$b file_ppos() $B$G!"8=:_$NFI$_=q$-$9$k0LCV(B pos $B$X$N%]%$%s%?$rF@!"$5$i$K!"$=$N(B $BFbMF$r%m!<%+%kJQ?t$K(B pos $B$K%3%T!<$9$k!#(B
      • vfs_read() $B$H$$$&(B VFS $BAX$N struct file $B$NCf$K$"$k(B pos $B$r99?7$9$k!#(B
      • fdput_pos() $B$G!"(Bpos $B$rA`:n$9$k$?$a$N%m%C%/$r3+J|$7$F$$$k!#(B

      $B"!(Bvfs_read()

      linux-5.10.3/fs/read_write.c
       476:	ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
       477:	{
       478:	        ssize_t ret;
       479:	
       480:	        if (!(file->f_mode & FMODE_READ))
       481:	                return -EBADF;
       482:	        if (!(file->f_mode & FMODE_CAN_READ))
       483:	                return -EINVAL;
       484:	        if (unlikely(!access_ok(buf, count)))
       485:	                return -EFAULT;
       486:	
       487:	        ret = rw_verify_area(READ, file, pos, count);
       488:	        if (ret)
       489:	                return ret;
       490:	        if (count > MAX_RW_COUNT)
       491:	                count =  MAX_RW_COUNT;
       492:	
       493:	        if (file->f_op->read)
       494:	                ret = file->f_op->read(file, buf, count, pos);
       495:	        else if (file->f_op->read_iter)
       496:	                ret = new_sync_read(file, buf, count, pos);
       497:	        else
       498:	                ret = -EINVAL;
       499:	        if (ret > 0) {
       500:	                fsnotify_access(file);
       501:	                add_rchar(current, ret);
       502:	        }
       503:	        inc_syscr(current);
       504:	        return ret;
       505:	}
      
       404:	static ssize_t new_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
       405:	{
       406:	        struct iovec iov = { .iov_base = buf, .iov_len = len };
      ...
       412:	        kiocb.ki_pos = (ppos ? *ppos : 0);
       413:	        iov_iter_init(&iter, READ, &iov, 1, len);
       414:	
       415:	        ret = call_read_iter(filp, &kiocb, &iter);
      ...
       417:	        if (ppos)
       418:	                *ppos = kiocb.ki_pos;
       419:	        return ret;
       420:	}
      
      linux-5.10.3/include/linux/fs.h
      1894:	static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio,
      1895:	                                     struct iov_iter *iter)
      1896:	{
      1897:	        return file->f_op->read_iter(kio, iter);
      1898:	}
      
      • file->f_mode$B$rD4$Y!"(B $B%U%!%$%k$,FI$_=P$7$G(B open() $B$5$l$F$$$J$1$1$l$P(B()$B!"%(%i! access_ok() $B$G!"7k2L$rJ]B8$9$k%a%b%j(B(buf, count)$B$,=q$-9~$_$G$-$J$$(B $B$H%(%i! rw_verify_area() $B$G!"%U%!%$%k$N$=$N>l=j(B(pos$B$+$i(Bpos+count$B$^$G(B)$B$,B8(B $B:_$9$k$+$r3NG'$9$k!#(B
      • vfs_read() $B$O!"(B__vfs_read() $B$r8F$S=P$9!#(B
      • __vfs_read() $B$O!"(Bfile$B9=B$BN$NA`:n$G(B file->f_op->read $B$H$$$C$? __vfs_read() $B$O!"(Bfile$B9=B$BN$NA`:n$G(B file->f_op->read_iter $B$H$$$C$? new_sync_read() $B$O!"(Bfile->f_op->read_iter() $B$r8F$S=P$9!#(B

      $B"!(BExt4 $B$N(B file_operations

      linux-5.10.3/fs/ext4/file.c
       893:	const struct file_operations ext4_file_operations = {
       894:	        .llseek         = ext4_llseek,
       895:	        .read_iter      = ext4_file_read_iter,
       896:	        .write_iter     = ext4_file_write_iter,
       897:	        .iopoll         = iomap_dio_iopoll,
       898:	        .unlocked_ioctl = ext4_ioctl,
       899:	#ifdef CONFIG_COMPAT
       900:	        .compat_ioctl   = ext4_compat_ioctl,
       901:	#endif
       902:	        .mmap           = ext4_file_mmap,
       903:	        .mmap_supported_flags = MAP_SYNC,
       904:	        .open           = ext4_file_open,
       905:	        .release        = ext4_release_file,
       906:	        .fsync          = ext4_sync_file,
       907:	        .get_unmapped_area = thp_get_unmapped_area,
       908:	        .splice_read    = generic_file_splice_read,
       909:	        .splice_write   = iter_file_splice_write,
       910:	        .fallocate      = ext4_fallocate,
       911:	};
      
       913:	const struct inode_operations ext4_file_inode_operations = {
       914:	        .setattr        = ext4_setattr,
       915:	        .getattr        = ext4_file_getattr,
      ...
       920:	};
      
      linux-5.10.3/fs/ext4/super.c
      1654:	static const struct super_operations ext4_sops = {
      1655:	        .alloc_inode    = ext4_alloc_inode,
      ...
      1675:	};
      
      • file_operations $B9=B$BN$N4X?t$N$&$A!"(B13 $B8D$rDj5A$7$F$$$k!#(B
      • $B generic_ $B$+$i;O$^$k$b$N(B $B$O!"7Q>5!?0Q>y!#(Bext4 $B8G(B $BM-$NA`:n$O$J$/!"0lHLE*$JA`:n$G inode $B$NA`:n!"(Bext4_file_inode_operations $B$b$"$k!#(B
      • $B%9!<%Q!<%V%m%C%/$NA`:n!"(Bext4_sops $B$b$"$k!#(B
      • dentry $B$NA`:n$GFCJL$JA`:n$r9T$&$?$a$N(B struct dentry_operations $B$O!"(B ext4 $B$G$OIaDLL58z(B (CONFIG_UNICODE $B$,Dj5A$5$l$F$$$k$HM-8z(B)$B!#(B

      $B"!(BExt4 $B$N(B inode

      Ext4 $B$G$O!"%a%b%jCf$N%G!<%?$r9=B$BN(B struct ext4_inode_info $B$GI=$9!#(B
      linux-5.10.3/fs/ext4/ext4.h
       994:	struct ext4_inode_info {
      ...
      1083:	        struct inode vfs_inode;
      ...
      1158:	};
      
      1655:	static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
      1656:	{
      1657:	        return container_of(inode, struct ext4_inode_info, vfs_inode);
      1658:	}
      
      linux-5.10.3/include/linux/kernel.h
       844:	/**
       845:	 * container_of - cast a member of a structure out to the containing structure
       846:	 * @ptr:        the pointer to the member.
       847:	 * @type:       the type of the container struct this is embedded in.
       848:	 * @member:     the name of the member within the struct.
       849:	 *
       850:	 */
       851:	#define container_of(ptr, type, member) ({                              \
       852:	        void *__mptr = (void *)(ptr);                                   \
       853:	        BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) &&   \
       854:	                         !__same_type(*(ptr), void),                    \
       855:	                         "pointer type mismatch in container_of()");    \
       856:	        ((type *)(__mptr - offsetof(type, member))); })
       857:	
      
      
      linux-5.4.7/fs/ext4/ext4.h
       952:	struct ext4_inode_info {
      ...
      1019:	        struct inode vfs_inode;
      ...
      1095:	};
      
      1560:	static inline struct ext4_inode_info *EXT4_I(struct inode *inode)
      1561:	{
      1562:	        return container_of(inode, struct ext4_inode_info, vfs_inode);
      1563:	}
      
      • Ext4 $BFH<+$N9=B$BN(B struct ext4_inode_info $B$NFbIt$K$O!"(BLinux $BI8=`$N(B struct inode $B$,$"$k!#(B
      • $BI8=`$N(B struct inode $B$+$i(B Ext4 $BFH<+$N(B struct ext4_inode_info $B$r EXT4_I() $B$O!"(Bcontainer_of() $B%^%/%m$r;H$C$F$$$k!#(B
      • container_of() $B$O!"Ev3:%a%s%P$N%*%U%;%C%H$r0z$-;;$7$F!"30B&$N9=B$(B $BBN$NHVCO$r5a$a$F$$$k!#(B

      $B?^(B?$B!!(Bstruct ext4_inode_info$B!
      $B?^(B? Ext4 $B%U%!%$%k%7%9%F%`$G;H$&9=B$BN(B ext4_inode_info $B$G$N(B struct inode $B$NJ];}(B

      $B"!(BExt4$B$N(Bext4_file_read_iter()

      linux-5.10.3/fs/ext4/file.c
       114:	static ssize_t ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
       115:	{
      ...
       131:	        return generic_file_read_iter(iocb, to);
       132:	}
      
      • $B%U%!%$%k$NFI$_=P$7$O!"(Bfilp->f_op->read_iter() $B$G Ext4 $B$G$O!"(Bread_iter() $B$O!"(Bext4_file_operations $B$GDj5A$5$l$F$$$k$h$&$K!"(B ext4_file_read_iter()$B!#(B
      • $B$3$l$O!"IaDL!"HFMQ$N(B generic_file_read_iter() $B$r8F$V!#(B

      $B"!HFMQ$N(Bgeneric_file_read_iter()

      linux-5.10.3/mm/filemap.c
      2502:	ssize_t
      2503:	generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
      2504:	{
      ...
      2553:	        retval = generic_file_buffered_read(iocb, iter, retval);
      ...
      2556:	}
      
      • generic_file_read_iter() $B$O!"IaDL!"(Bgeneric_file_buffered_read() $B$r8F$V!#(B
      • $B%U%!%$%k$NF~=PNO$H%a%b%j4IM}$,E}9g$5$l$F$$$k!#F~=PNO$N

        $B"!HFMQ$N(Bgeneric_file_buffered_read()

        linux-5.10.3/mm/filemap.c
        2185:	ssize_t generic_file_buffered_read(struct kiocb *iocb,
        2186:	                struct iov_iter *iter, ssize_t written)
        2187:	{
        2188:	        struct file *filp = iocb->ki_filp;
        2189:	        struct address_space *mapping = filp->f_mapping;
        2190:	        struct inode *inode = mapping->host;
        2191:	        struct file_ra_state *ra = &filp->f_ra;
        2192:	        loff_t *ppos = &iocb->ki_pos;
        2193:	        pgoff_t index;
        ...
        2196:	        unsigned long offset;      /* offset into pagecache page */
        ...
        2198:	        int error = 0;
        ...
        2204:	        index = *ppos >> PAGE_SHIFT;
        ...
        2208:	        offset = *ppos & ~PAGE_MASK;
        ...
        2218:	        for (;;) {
        2219:	                struct page *page;
        ...
        2222:	                unsigned long nr, ret;
        ...
        2225:	find_page:
        ...
        2231:	                page = find_get_page(mapping, index);
        2232:	                if (!page) {
        2233:	                        if (iocb->ki_flags & IOCB_NOIO)
        2234:	                                goto would_block;
        2235:	                        page_cache_sync_readahead(mapping,
        2236:	                                        ra, filp,
        2237:	                                        index, last_index - index);
        2238:	                        page = find_get_page(mapping, index);
        2239:	                        if (unlikely(page == NULL))
        2240:	                                goto no_cached_page;
        2241:	                }
        ...
        2292:	page_ok:
        ...
        2310:	                nr = PAGE_SIZE;
        ...
        2318:	                nr = nr - offset;
        ...
        2340:	                ret = copy_page_to_iter(page, offset, nr, iter);
        2341:	                offset += ret;
        2342:	                index += offset >> PAGE_SHIFT;
        2343:	                offset &= ~PAGE_MASK;
        ...
        2346:	                put_page(page);
        2347:	                written += ret;
        2348:	                if (!iov_iter_count(iter))
        2349:	                        goto out;
        ...
        2356:	page_not_up_to_date:
        ...
        2384:	readpage:
        ...
        2445:	no_cached_page:
        ...
        2466:	        }
        ...
        2470:	out:
        ...
        2475:	        *ppos = ((loff_t)index << PAGE_SHIFT) + offset;
        2476:	        file_accessed(filp);
        2477:	        return written ? written : error;
        2478:	}
        
        • generic_file_buffered_read() $B$O!"%Z!<%8C10L$G7+$jJV$9!#(B
        • $B%U%!%$%kCf$NFI$_=q$-$9$k0LCV$r(B *ppos $B$+$i struct page *page $B$O!"J*M}%Z!<%8$H(B 1 $BBP(B 1 $B$KBP1~$9$k9=B$BN!#(B 1$B7n(B13$BF|$N(B $BJ*M}%a%b%j$N4IM}(B $B$G=P$F$-$?!#(B
        • find_get_page() $B$O!"2>A[5-21$N%Z!<%8%U%)!<%k%HF1MM$K!"(B $B%Z!<%8%-%c%C%7%e$rC5$9!#(B
        • $B%Z!<%8%-%c%C%7%e$K$_$D$+$i$J$1$l$P!"(Bpage_cache_sync_readahead() $B$G!"(B $B%U%!%$%k$+$i%Z!<%8$rFI$_=P$9$h$&$K;X<($7!"$b$&0lEY!"(Bfind_get_page() $B$G(B $BC5$9!#(B
        • read a head $B$H$O!"@hFI$_$N0UL#!#%U%!%$%k$r%7!<%1%s%7%c%k$K%"%/%;%9(B $B$9$k;~$K$O!"8=:_FI$_9~$_$?$$%V%m%C%/$h$j$b@h$N%V%m%C%/$bFI$`!#(B
        • copy_page_to_iter() $B$O!"(Bcopy_to_user() $B$HF1MM$K!"%+!<%M%k$G4IM}$7(B $B$F$$$kJ*M}%a%b%j(B(struct page *page)$B$+$i%f!<%66u4VFb$N%a%b%j(B(iter)$B$K%3%T!<(B $B$9$k!#(B

        $B"#(Bmkdir() $B%7%9%F%`%3!<%k(B

        mkdir() $B%7%9%F%`!&%3!<%k$N$B"!(Bmkdir() $B%7%9%F%`!&%3!<%k(B
        linux-5.10.3/fs/namei.c
        3687:	SYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
        3688:	{
        3689:	        return do_mkdirat(AT_FDCWD, pathname, mode);
        3690:	}
        
        3657:	static long do_mkdirat(int dfd, const char __user *pathname, umode_t mode)
        3658:	{
        3659:	        struct dentry *dentry;
        3660:	        struct path path;
        3661:	        int error;
        3662:	        unsigned int lookup_flags = LOOKUP_DIRECTORY;
        3663:	
        3664:	retry:
        3665:	        dentry = user_path_create(dfd, pathname, &path, lookup_flags);
        ...
        3673:	                error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
        ...
        3679:	        return error;
        3680:	}
        
        • namei $B$O!"(Bname to inode $B$G!"L>A0$+$i(B inode $B$r mkdir() $B%7%9%F%`!&%3!<%k$N do_mkdirat() $B$O!"?7$7$/:n@.$9$k%G%#%l%/%H%j$N(B dentry $B$r:n$k!#(B $B$3$N;~E@$G$O!"%U%!%$%kL>$@$1$,@_Dj$5$l$?>uBV$K$J$C$F$*$j!"(Binode $B$O3dEv$F$i$l$F$$$J$$!#(B
        • vfs_mkdir() $B$r8F$S=P$9!#(B $B0z?t$O!"?F%G%#%l%/%H%j$N(B inode$B!"?7$7$/:n$i$l$k%G%#%l%/%H%j$N(B dentry$B!"(B $B%G%#%l%/%H%j$r:n@.$9$k;~$N%Q!<%_%C%7%g%s(B(rwxrwxrwx)$B$rI=$9%b!<%I!#(B

        $B"!(Bvfs_mkdir()

        linux-5.10.3/fs/namei.c
        3631:	int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        3632:	{
        ...
        3639:	        if (!dir->i_op->mkdir)
        3640:	                return -EPERM;
        3641:	
        3642:	        mode &= (S_IRWXUGO|S_ISVTX);
        ...
        3650:	        error = dir->i_op->mkdir(dir, dentry, mode);
        ...
        3653:	        return error;
        3654:	}
        
        • dir->i_op->mkdir()$B!!$H$$$&4X?t$,B8:_$7$J$1$l$P%(%i! $B%b!<%I$N$&$A!"(B 0777|01000 $B$@$1$r;D$9!#(B
        • dir->i_op->mkdir()$B!!$H$$$&4X?t$r8F$V!#(B

        $B"#2A%"%s%1!<%H(B

        $B>pJs2J3XN`$G$O!"650i$N2~A1$N$?$a$K!"3X@8$N3'$5$s$K2A%"%s%1!<%H$r(B $B

        $B%"%s%1!<%H$O(BTwins$B$+$i2sEz$7$F$/$@$5$$!#(B

        $B$J$*!"3'$5$s$NI>2A$,@.@S$K1F6A$9$k$3$H$O0l@Z$"$j$^$;$s!#(B $B$^$?!"I>2A7k2L$r650i$N2~A10J30$NL\E*$KMxMQ$9$k$3$H$O$"$j$^$;$s$7!"(B $BI>2A7k2L$r8x3+$9$k>l9g$K$O8D?M$rFCDj$G$-$k$h$&$J>pJs$O4^$a$^$;$s!#(B

        $B

      • $B%?%$%H%k!V%*%Z%l!<%F%#%s%0%7%9%F%`(BII$B!W(B
      • $B%?%$%H%k!V%*%Z%l!<%F%#%s%0%7%9%F%`(BII-$B8D!9$N2s$4$H$NI>2A!W(B
      2$B7n(B15$BF|(B25$BF|(B$B$^$G$K2sEz$7$F2<$5$$!#(B

      $B"#2]Bj(B5 $B3d$j9~$_$N8eH>It!"%U%!%$%k%7%9%F%`(B

      $B!zLdBj(B(501) Tasklet

      Tasklet $B$r;H$C$F$G8F$S=P$7$?$$!#(B
      void f(int arg) {
         $B>JN,(B;
      }
      
      $B$3$l$r static struct tasklet_struct tl1; void tasklet_handler(unsigned long data) { /* Tasklet $B%O%s%I%i(B */ int arg1, arg2; arg1 = $B>JN,(B; /*$B6uMs(B(a)*/ $B$=$NB>$N;E;v(B; } $B=i4|2=(B { /*$B6uMs(B(b)*/(&tl1, /*$B6uMs(B(c)*/); } $BItJ,(B($B%O!<%I%&%'%"$N3d$j9~$_(B)$B$N0lIt$G$"$k!#(B $B>e$GDj5A$7$?Dj5A$7$?(B Tasklet $B$N%O%s%I%i$r8F$V$h$&$K!"6uMs$rKd$a$J$5$$!#(B
      irqreturn_t irq_handler(int irq, void *dev) {
          /*$B6uMs(B(d)*/
          return IRQ_HANDLED;
      }
      

      $B!zLdBj(B(502) $B%*%V%8%'%/%H;X8~(B

      Linux $B$N(B VFS $B$N
    • $B%*%V%8%'%/%H$NJQ?t$rJ];}$7$F$$$k9=B$BN$NL>A0(B:
    • $B%*%V%8%'%/%H$NJQ?t$NL>A0$NNc(B(1$B$D(B):
    • $B$=$NJQ?t$NLr3d(B:
    • $B%*%V%8%'%/%H$rA`:n$9$k $B$=$N
      Last updated: 2021/02/01 12:00:02
      Yasushi Shinjo / <yas@cs.tsukuba.ac.jp>