@@ -297,6 +297,21 @@ static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
297
297
return rv ;
298
298
}
299
299
300
+ static ssize_t proc_reg_read_iter (struct kiocb * iocb , struct iov_iter * iter )
301
+ {
302
+ struct proc_dir_entry * pde = PDE (file_inode (iocb -> ki_filp ));
303
+ ssize_t ret ;
304
+
305
+ if (pde_is_permanent (pde ))
306
+ return pde -> proc_ops -> proc_read_iter (iocb , iter );
307
+
308
+ if (!use_pde (pde ))
309
+ return - EIO ;
310
+ ret = pde -> proc_ops -> proc_read_iter (iocb , iter );
311
+ unuse_pde (pde );
312
+ return ret ;
313
+ }
314
+
300
315
static ssize_t pde_read (struct proc_dir_entry * pde , struct file * file , char __user * buf , size_t count , loff_t * ppos )
301
316
{
302
317
typeof_member (struct proc_ops , proc_read ) read ;
@@ -578,6 +593,18 @@ static const struct file_operations proc_reg_file_ops = {
578
593
.release = proc_reg_release ,
579
594
};
580
595
596
+ static const struct file_operations proc_iter_file_ops = {
597
+ .llseek = proc_reg_llseek ,
598
+ .read_iter = proc_reg_read_iter ,
599
+ .write = proc_reg_write ,
600
+ .poll = proc_reg_poll ,
601
+ .unlocked_ioctl = proc_reg_unlocked_ioctl ,
602
+ .mmap = proc_reg_mmap ,
603
+ .get_unmapped_area = proc_reg_get_unmapped_area ,
604
+ .open = proc_reg_open ,
605
+ .release = proc_reg_release ,
606
+ };
607
+
581
608
#ifdef CONFIG_COMPAT
582
609
static const struct file_operations proc_reg_file_ops_compat = {
583
610
.llseek = proc_reg_llseek ,
@@ -591,6 +618,19 @@ static const struct file_operations proc_reg_file_ops_compat = {
591
618
.open = proc_reg_open ,
592
619
.release = proc_reg_release ,
593
620
};
621
+
622
+ static const struct file_operations proc_iter_file_ops_compat = {
623
+ .llseek = proc_reg_llseek ,
624
+ .read_iter = proc_reg_read_iter ,
625
+ .write = proc_reg_write ,
626
+ .poll = proc_reg_poll ,
627
+ .unlocked_ioctl = proc_reg_unlocked_ioctl ,
628
+ .compat_ioctl = proc_reg_compat_ioctl ,
629
+ .mmap = proc_reg_mmap ,
630
+ .get_unmapped_area = proc_reg_get_unmapped_area ,
631
+ .open = proc_reg_open ,
632
+ .release = proc_reg_release ,
633
+ };
594
634
#endif
595
635
596
636
static void proc_put_link (void * p )
@@ -642,10 +682,17 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
642
682
643
683
if (S_ISREG (inode -> i_mode )) {
644
684
inode -> i_op = de -> proc_iops ;
645
- inode -> i_fop = & proc_reg_file_ops ;
685
+ if (de -> proc_ops -> proc_read_iter )
686
+ inode -> i_fop = & proc_iter_file_ops ;
687
+ else
688
+ inode -> i_fop = & proc_reg_file_ops ;
646
689
#ifdef CONFIG_COMPAT
647
- if (de -> proc_ops -> proc_compat_ioctl )
648
- inode -> i_fop = & proc_reg_file_ops_compat ;
690
+ if (de -> proc_ops -> proc_compat_ioctl ) {
691
+ if (de -> proc_ops -> proc_read_iter )
692
+ inode -> i_fop = & proc_iter_file_ops_compat ;
693
+ else
694
+ inode -> i_fop = & proc_reg_file_ops_compat ;
695
+ }
649
696
#endif
650
697
} else if (S_ISDIR (inode -> i_mode )) {
651
698
inode -> i_op = de -> proc_iops ;
0 commit comments