diff options
author | Denis V. Lunev <den@openvz.org> | 2008-04-29 04:02:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:22 -0400 |
commit | c7705f3449c7edd5c1744871097f93977227afc4 (patch) | |
tree | d2f121a4b1ae3ae458db76ec0210ea2172c31e5a | |
parent | 1b50221738108c438d5f25c7a043fb89e9e27044 (diff) |
drivers: use non-racy method for proc entries creation (2)
Use proc_create()/proc_create_data() to make sure that ->proc_fops and ->data
be setup before gluing PDE to main tree.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Peter Osterlund <petero2@telia.com>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: Dmitry Torokhov <dtor@mail.ru>
Cc: Neil Brown <neilb@suse.de>
Cc: Mauro Carvalho Chehab <mchehab@infradead.org>
Cc: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | drivers/block/pktcdvd.c | 7 | ||||
-rw-r--r-- | drivers/cdrom/viocd.c | 10 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 7 | ||||
-rw-r--r-- | drivers/input/input.c | 12 | ||||
-rw-r--r-- | drivers/md/md.c | 6 | ||||
-rw-r--r-- | drivers/media/video/zoran_procfs.c | 7 | ||||
-rw-r--r-- | drivers/message/i2o/i2o_proc.c | 6 | ||||
-rw-r--r-- | drivers/misc/hdpuftrs/hdpu_cpustate.c | 5 | ||||
-rw-r--r-- | drivers/misc/hdpuftrs/hdpu_nexus.c | 13 | ||||
-rw-r--r-- | drivers/pci/proc.c | 13 | ||||
-rw-r--r-- | drivers/pnp/isapnp/proc.c | 7 | ||||
-rw-r--r-- | drivers/rtc/rtc-proc.c | 8 |
12 files changed, 33 insertions, 68 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 0431e5977bcb..fd0472996df8 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2744,7 +2744,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2744 | int i; | 2744 | int i; |
2745 | int ret = 0; | 2745 | int ret = 0; |
2746 | char b[BDEVNAME_SIZE]; | 2746 | char b[BDEVNAME_SIZE]; |
2747 | struct proc_dir_entry *proc; | ||
2748 | struct block_device *bdev; | 2747 | struct block_device *bdev; |
2749 | 2748 | ||
2750 | if (pd->pkt_dev == dev) { | 2749 | if (pd->pkt_dev == dev) { |
@@ -2788,11 +2787,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
2788 | goto out_mem; | 2787 | goto out_mem; |
2789 | } | 2788 | } |
2790 | 2789 | ||
2791 | proc = create_proc_entry(pd->name, 0, pkt_proc); | 2790 | proc_create_data(pd->name, 0, pkt_proc, &pkt_proc_fops, pd); |
2792 | if (proc) { | ||
2793 | proc->data = pd; | ||
2794 | proc->proc_fops = &pkt_proc_fops; | ||
2795 | } | ||
2796 | DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); | 2791 | DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); |
2797 | return 0; | 2792 | return 0; |
2798 | 2793 | ||
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index b74b6c2768a8..5245a4a0ba74 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -144,6 +144,7 @@ static int proc_viocd_open(struct inode *inode, struct file *file) | |||
144 | } | 144 | } |
145 | 145 | ||
146 | static const struct file_operations proc_viocd_operations = { | 146 | static const struct file_operations proc_viocd_operations = { |
147 | .owner = THIS_MODULE, | ||
147 | .open = proc_viocd_open, | 148 | .open = proc_viocd_open, |
148 | .read = seq_read, | 149 | .read = seq_read, |
149 | .llseek = seq_lseek, | 150 | .llseek = seq_lseek, |
@@ -679,7 +680,6 @@ static struct vio_driver viocd_driver = { | |||
679 | 680 | ||
680 | static int __init viocd_init(void) | 681 | static int __init viocd_init(void) |
681 | { | 682 | { |
682 | struct proc_dir_entry *e; | ||
683 | int ret = 0; | 683 | int ret = 0; |
684 | 684 | ||
685 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) | 685 | if (!firmware_has_feature(FW_FEATURE_ISERIES)) |
@@ -719,12 +719,8 @@ static int __init viocd_init(void) | |||
719 | if (ret) | 719 | if (ret) |
720 | goto out_free_info; | 720 | goto out_free_info; |
721 | 721 | ||
722 | e = create_proc_entry("iSeries/viocd", S_IFREG|S_IRUGO, NULL); | 722 | proc_create("iSeries/viocd", S_IFREG|S_IRUGO, NULL, |
723 | if (e) { | 723 | &proc_viocd_operations); |
724 | e->owner = THIS_MODULE; | ||
725 | e->proc_fops = &proc_viocd_operations; | ||
726 | } | ||
727 | |||
728 | return 0; | 724 | return 0; |
729 | 725 | ||
730 | out_free_info: | 726 | out_free_info: |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 7b2f3815a838..8d6ad812a014 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -822,6 +822,7 @@ static int ide_drivers_open(struct inode *inode, struct file *file) | |||
822 | } | 822 | } |
823 | 823 | ||
824 | static const struct file_operations ide_drivers_operations = { | 824 | static const struct file_operations ide_drivers_operations = { |
825 | .owner = THIS_MODULE, | ||
825 | .open = ide_drivers_open, | 826 | .open = ide_drivers_open, |
826 | .read = seq_read, | 827 | .read = seq_read, |
827 | .llseek = seq_lseek, | 828 | .llseek = seq_lseek, |
@@ -830,16 +831,12 @@ static const struct file_operations ide_drivers_operations = { | |||
830 | 831 | ||
831 | void proc_ide_create(void) | 832 | void proc_ide_create(void) |
832 | { | 833 | { |
833 | struct proc_dir_entry *entry; | ||
834 | |||
835 | proc_ide_root = proc_mkdir("ide", NULL); | 834 | proc_ide_root = proc_mkdir("ide", NULL); |
836 | 835 | ||
837 | if (!proc_ide_root) | 836 | if (!proc_ide_root) |
838 | return; | 837 | return; |
839 | 838 | ||
840 | entry = create_proc_entry("drivers", 0, proc_ide_root); | 839 | proc_create("drivers", 0, proc_ide_root, &ide_drivers_operations); |
841 | if (entry) | ||
842 | entry->proc_fops = &ide_drivers_operations; | ||
843 | } | 840 | } |
844 | 841 | ||
845 | void proc_ide_destroy(void) | 842 | void proc_ide_destroy(void) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 11426604d8a2..27006fc18305 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -904,20 +904,16 @@ static int __init input_proc_init(void) | |||
904 | 904 | ||
905 | proc_bus_input_dir->owner = THIS_MODULE; | 905 | proc_bus_input_dir->owner = THIS_MODULE; |
906 | 906 | ||
907 | entry = create_proc_entry("devices", 0, proc_bus_input_dir); | 907 | entry = proc_create("devices", 0, proc_bus_input_dir, |
908 | &input_devices_fileops); | ||
908 | if (!entry) | 909 | if (!entry) |
909 | goto fail1; | 910 | goto fail1; |
910 | 911 | ||
911 | entry->owner = THIS_MODULE; | 912 | entry = proc_create("handlers", 0, proc_bus_input_dir, |
912 | entry->proc_fops = &input_devices_fileops; | 913 | &input_handlers_fileops); |
913 | |||
914 | entry = create_proc_entry("handlers", 0, proc_bus_input_dir); | ||
915 | if (!entry) | 914 | if (!entry) |
916 | goto fail2; | 915 | goto fail2; |
917 | 916 | ||
918 | entry->owner = THIS_MODULE; | ||
919 | entry->proc_fops = &input_handlers_fileops; | ||
920 | |||
921 | return 0; | 917 | return 0; |
922 | 918 | ||
923 | fail2: remove_proc_entry("devices", proc_bus_input_dir); | 919 | fail2: remove_proc_entry("devices", proc_bus_input_dir); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 87620b705bee..6fe4a769c854 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -5947,13 +5947,9 @@ static struct notifier_block md_notifier = { | |||
5947 | 5947 | ||
5948 | static void md_geninit(void) | 5948 | static void md_geninit(void) |
5949 | { | 5949 | { |
5950 | struct proc_dir_entry *p; | ||
5951 | |||
5952 | dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); | 5950 | dprintk("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t)); |
5953 | 5951 | ||
5954 | p = create_proc_entry("mdstat", S_IRUGO, NULL); | 5952 | proc_create("mdstat", S_IRUGO, NULL, &md_seq_fops); |
5955 | if (p) | ||
5956 | p->proc_fops = &md_seq_fops; | ||
5957 | } | 5953 | } |
5958 | 5954 | ||
5959 | static int __init md_init(void) | 5955 | static int __init md_init(void) |
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c index 328ed6e7ac6a..870bc5a70e3f 100644 --- a/drivers/media/video/zoran_procfs.c +++ b/drivers/media/video/zoran_procfs.c | |||
@@ -180,6 +180,7 @@ static ssize_t zoran_write(struct file *file, const char __user *buffer, | |||
180 | } | 180 | } |
181 | 181 | ||
182 | static const struct file_operations zoran_operations = { | 182 | static const struct file_operations zoran_operations = { |
183 | .owner = THIS_MODULE, | ||
183 | .open = zoran_open, | 184 | .open = zoran_open, |
184 | .read = seq_read, | 185 | .read = seq_read, |
185 | .write = zoran_write, | 186 | .write = zoran_write, |
@@ -195,10 +196,8 @@ zoran_proc_init (struct zoran *zr) | |||
195 | char name[8]; | 196 | char name[8]; |
196 | 197 | ||
197 | snprintf(name, 7, "zoran%d", zr->id); | 198 | snprintf(name, 7, "zoran%d", zr->id); |
198 | if ((zr->zoran_proc = create_proc_entry(name, 0, NULL))) { | 199 | zr->zoran_proc = proc_create_data(name, 0, NULL, &zoran_operations, zr); |
199 | zr->zoran_proc->data = zr; | 200 | if (zr->zoran_proc != NULL) { |
200 | zr->zoran_proc->owner = THIS_MODULE; | ||
201 | zr->zoran_proc->proc_fops = &zoran_operations; | ||
202 | dprintk(2, | 201 | dprintk(2, |
203 | KERN_INFO | 202 | KERN_INFO |
204 | "%s: procfs entry /proc/%s allocated. data=%p\n", | 203 | "%s: procfs entry /proc/%s allocated. data=%p\n", |
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 6fdd072201f9..54a3016ff45d 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c | |||
@@ -1893,13 +1893,11 @@ static int i2o_proc_create_entries(struct proc_dir_entry *dir, | |||
1893 | struct proc_dir_entry *tmp; | 1893 | struct proc_dir_entry *tmp; |
1894 | 1894 | ||
1895 | while (i2o_pe->name) { | 1895 | while (i2o_pe->name) { |
1896 | tmp = create_proc_entry(i2o_pe->name, i2o_pe->mode, dir); | 1896 | tmp = proc_create_data(i2o_pe->name, i2o_pe->mode, dir, |
1897 | i2o_pe->fops, data); | ||
1897 | if (!tmp) | 1898 | if (!tmp) |
1898 | return -1; | 1899 | return -1; |
1899 | 1900 | ||
1900 | tmp->data = data; | ||
1901 | tmp->proc_fops = i2o_pe->fops; | ||
1902 | |||
1903 | i2o_pe++; | 1901 | i2o_pe++; |
1904 | } | 1902 | } |
1905 | 1903 | ||
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 154155c9b638..ff51ab67231c 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c | |||
@@ -210,13 +210,10 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) | |||
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | proc_de = create_proc_entry("sky_cpustate", 0666, NULL); | 213 | proc_de = proc_create("sky_cpustate", 0666, NULL, &proc_cpustate); |
214 | if (!proc_de) { | 214 | if (!proc_de) { |
215 | printk(KERN_WARNING "sky_cpustate: " | 215 | printk(KERN_WARNING "sky_cpustate: " |
216 | "Unable to create proc entry\n"); | 216 | "Unable to create proc entry\n"); |
217 | } else { | ||
218 | proc_de->proc_fops = &proc_cpustate; | ||
219 | proc_de->owner = THIS_MODULE; | ||
220 | } | 217 | } |
221 | 218 | ||
222 | printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); | 219 | printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); |
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index e92b7efccc72..08e26beefe64 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c | |||
@@ -102,22 +102,17 @@ static int hdpu_nexus_probe(struct platform_device *pdev) | |||
102 | printk(KERN_ERR "sky_nexus: Could not map slot id\n"); | 102 | printk(KERN_ERR "sky_nexus: Could not map slot id\n"); |
103 | } | 103 | } |
104 | 104 | ||
105 | hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, NULL); | 105 | hdpu_slot_id = proc_create("sky_slot_id", 0666, NULL, &proc_slot_id); |
106 | if (!hdpu_slot_id) | 106 | if (!hdpu_slot_id) { |
107 | printk(KERN_WARNING "sky_nexus: " | 107 | printk(KERN_WARNING "sky_nexus: " |
108 | "Unable to create proc dir entry: sky_slot_id\n"); | 108 | "Unable to create proc dir entry: sky_slot_id\n"); |
109 | } else { | ||
110 | hdpu_slot_id->proc_fops = &proc_slot_id; | ||
111 | hdpu_slot_id->owner = THIS_MODULE; | ||
112 | } | 109 | } |
113 | 110 | ||
114 | hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, NULL); | 111 | hdpu_chassis_id = proc_create("sky_chassis_id", 0666, NULL, |
112 | &proc_chassis_id); | ||
115 | if (!hdpu_chassis_id) | 113 | if (!hdpu_chassis_id) |
116 | printk(KERN_WARNING "sky_nexus: " | 114 | printk(KERN_WARNING "sky_nexus: " |
117 | "Unable to create proc dir entry: sky_chassis_id\n"); | 115 | "Unable to create proc dir entry: sky_chassis_id\n"); |
118 | } else { | ||
119 | hdpu_chassis_id->proc_fops = &proc_chassis_id; | ||
120 | hdpu_chassis_id->owner = THIS_MODULE; | ||
121 | } | 116 | } |
122 | 117 | ||
123 | return 0; | 118 | return 0; |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 7b5e45b2fd16..963a97642ae9 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -293,6 +293,7 @@ static int proc_bus_pci_release(struct inode *inode, struct file *file) | |||
293 | #endif /* HAVE_PCI_MMAP */ | 293 | #endif /* HAVE_PCI_MMAP */ |
294 | 294 | ||
295 | static const struct file_operations proc_bus_pci_operations = { | 295 | static const struct file_operations proc_bus_pci_operations = { |
296 | .owner = THIS_MODULE, | ||
296 | .llseek = proc_bus_pci_lseek, | 297 | .llseek = proc_bus_pci_lseek, |
297 | .read = proc_bus_pci_read, | 298 | .read = proc_bus_pci_read, |
298 | .write = proc_bus_pci_write, | 299 | .write = proc_bus_pci_write, |
@@ -406,11 +407,10 @@ int pci_proc_attach_device(struct pci_dev *dev) | |||
406 | } | 407 | } |
407 | 408 | ||
408 | sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | 409 | sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); |
409 | e = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir); | 410 | e = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir, |
411 | &proc_bus_pci_operations, dev); | ||
410 | if (!e) | 412 | if (!e) |
411 | return -ENOMEM; | 413 | return -ENOMEM; |
412 | e->proc_fops = &proc_bus_pci_operations; | ||
413 | e->data = dev; | ||
414 | e->size = dev->cfg_size; | 414 | e->size = dev->cfg_size; |
415 | dev->procent = e; | 415 | dev->procent = e; |
416 | 416 | ||
@@ -462,6 +462,7 @@ static int proc_bus_pci_dev_open(struct inode *inode, struct file *file) | |||
462 | return seq_open(file, &proc_bus_pci_devices_op); | 462 | return seq_open(file, &proc_bus_pci_devices_op); |
463 | } | 463 | } |
464 | static const struct file_operations proc_bus_pci_dev_operations = { | 464 | static const struct file_operations proc_bus_pci_dev_operations = { |
465 | .owner = THIS_MODULE, | ||
465 | .open = proc_bus_pci_dev_open, | 466 | .open = proc_bus_pci_dev_open, |
466 | .read = seq_read, | 467 | .read = seq_read, |
467 | .llseek = seq_lseek, | 468 | .llseek = seq_lseek, |
@@ -470,12 +471,10 @@ static const struct file_operations proc_bus_pci_dev_operations = { | |||
470 | 471 | ||
471 | static int __init pci_proc_init(void) | 472 | static int __init pci_proc_init(void) |
472 | { | 473 | { |
473 | struct proc_dir_entry *entry; | ||
474 | struct pci_dev *dev = NULL; | 474 | struct pci_dev *dev = NULL; |
475 | proc_bus_pci_dir = proc_mkdir("bus/pci", NULL); | 475 | proc_bus_pci_dir = proc_mkdir("bus/pci", NULL); |
476 | entry = create_proc_entry("devices", 0, proc_bus_pci_dir); | 476 | proc_create("devices", 0, proc_bus_pci_dir, |
477 | if (entry) | 477 | &proc_bus_pci_dev_operations); |
478 | entry->proc_fops = &proc_bus_pci_dev_operations; | ||
479 | proc_initialized = 1; | 478 | proc_initialized = 1; |
480 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 479 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
481 | pci_proc_attach_device(dev); | 480 | pci_proc_attach_device(dev); |
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c index e1d1f2a10947..3f94edab25fa 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c | |||
@@ -85,6 +85,7 @@ static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf, | |||
85 | } | 85 | } |
86 | 86 | ||
87 | static const struct file_operations isapnp_proc_bus_file_operations = { | 87 | static const struct file_operations isapnp_proc_bus_file_operations = { |
88 | .owner = THIS_MODULE, | ||
88 | .llseek = isapnp_proc_bus_lseek, | 89 | .llseek = isapnp_proc_bus_lseek, |
89 | .read = isapnp_proc_bus_read, | 90 | .read = isapnp_proc_bus_read, |
90 | }; | 91 | }; |
@@ -102,12 +103,10 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev) | |||
102 | return -ENOMEM; | 103 | return -ENOMEM; |
103 | } | 104 | } |
104 | sprintf(name, "%02x", dev->number); | 105 | sprintf(name, "%02x", dev->number); |
105 | e = dev->procent = create_proc_entry(name, S_IFREG | S_IRUGO, de); | 106 | e = dev->procent = proc_create_data(name, S_IFREG | S_IRUGO, de, |
107 | &isapnp_proc_bus_file_operations, dev); | ||
106 | if (!e) | 108 | if (!e) |
107 | return -ENOMEM; | 109 | return -ENOMEM; |
108 | e->proc_fops = &isapnp_proc_bus_file_operations; | ||
109 | e->owner = THIS_MODULE; | ||
110 | e->data = dev; | ||
111 | e->size = 256; | 110 | e->size = 256; |
112 | return 0; | 111 | return 0; |
113 | } | 112 | } |
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c index 8d300e6d0d9e..0c6257a034ff 100644 --- a/drivers/rtc/rtc-proc.c +++ b/drivers/rtc/rtc-proc.c | |||
@@ -108,12 +108,10 @@ void rtc_proc_add_device(struct rtc_device *rtc) | |||
108 | if (rtc->id == 0) { | 108 | if (rtc->id == 0) { |
109 | struct proc_dir_entry *ent; | 109 | struct proc_dir_entry *ent; |
110 | 110 | ||
111 | ent = create_proc_entry("driver/rtc", 0, NULL); | 111 | ent = proc_create_data("driver/rtc", 0, NULL, |
112 | if (ent) { | 112 | &rtc_proc_fops, rtc); |
113 | ent->proc_fops = &rtc_proc_fops; | 113 | if (ent) |
114 | ent->owner = rtc->owner; | 114 | ent->owner = rtc->owner; |
115 | ent->data = rtc; | ||
116 | } | ||
117 | } | 115 | } |
118 | } | 116 | } |
119 | 117 | ||