diff options
120 files changed, 6738 insertions, 4317 deletions
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 470db6efaeb..a031d99becb 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -176,7 +176,7 @@ static void __init pseries_mpic_init_IRQ(void) | |||
176 | return; | 176 | return; |
177 | 177 | ||
178 | cascade_irq = irq_of_parse_and_map(cascade, 0); | 178 | cascade_irq = irq_of_parse_and_map(cascade, 0); |
179 | if (cascade == NO_IRQ) { | 179 | if (cascade_irq == NO_IRQ) { |
180 | printk(KERN_ERR "mpic: failed to map cascade interrupt"); | 180 | printk(KERN_ERR "mpic: failed to map cascade interrupt"); |
181 | return; | 181 | return; |
182 | } | 182 | } |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 68441e0e74b..143ed8e154a 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -19,7 +19,7 @@ CFLAGS += -m31 | |||
19 | AFLAGS += -m31 | 19 | AFLAGS += -m31 |
20 | UTS_MACHINE := s390 | 20 | UTS_MACHINE := s390 |
21 | STACK_SIZE := 8192 | 21 | STACK_SIZE := 8192 |
22 | CHECKFLAGS += -D__s390__ | 22 | CHECKFLAGS += -D__s390__ -msize-long |
23 | else | 23 | else |
24 | LDFLAGS := -m elf64_s390 | 24 | LDFLAGS := -m elf64_s390 |
25 | MODFLAGS += -fpic -D__PIC__ | 25 | MODFLAGS += -fpic -D__PIC__ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 9a13b24ee1a..8b8f136d9cc 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -295,8 +295,8 @@ static ssize_t sys_ipl_device_show(struct kset *kset, char *page) | |||
295 | static struct subsys_attribute sys_ipl_device_attr = | 295 | static struct subsys_attribute sys_ipl_device_attr = |
296 | __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); | 296 | __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); |
297 | 297 | ||
298 | static ssize_t ipl_parameter_read(struct kobject *kobj, char *buf, loff_t off, | 298 | static ssize_t ipl_parameter_read(struct kobject *kobj, struct bin_attribute *attr, |
299 | size_t count) | 299 | char *buf, loff_t off, size_t count) |
300 | { | 300 | { |
301 | unsigned int size = IPL_PARMBLOCK_SIZE; | 301 | unsigned int size = IPL_PARMBLOCK_SIZE; |
302 | 302 | ||
@@ -317,8 +317,8 @@ static struct bin_attribute ipl_parameter_attr = { | |||
317 | .read = &ipl_parameter_read, | 317 | .read = &ipl_parameter_read, |
318 | }; | 318 | }; |
319 | 319 | ||
320 | static ssize_t ipl_scp_data_read(struct kobject *kobj, char *buf, loff_t off, | 320 | static ssize_t ipl_scp_data_read(struct kobject *kobj, struct bin_attribute *attr, |
321 | size_t count) | 321 | char *buf, loff_t off, size_t count) |
322 | { | 322 | { |
323 | unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; | 323 | unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len; |
324 | void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; | 324 | void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data; |
@@ -337,7 +337,7 @@ static struct bin_attribute ipl_scp_data_attr = { | |||
337 | .mode = S_IRUGO, | 337 | .mode = S_IRUGO, |
338 | }, | 338 | }, |
339 | .size = PAGE_SIZE, | 339 | .size = PAGE_SIZE, |
340 | .read = &ipl_scp_data_read, | 340 | .read = ipl_scp_data_read, |
341 | }; | 341 | }; |
342 | 342 | ||
343 | /* FCP ipl device attributes */ | 343 | /* FCP ipl device attributes */ |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index fcde9bab5b9..1c77e14480d 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -560,7 +560,7 @@ config I2C_VERSATILE | |||
560 | will be called i2c-versatile. | 560 | will be called i2c-versatile. |
561 | 561 | ||
562 | config I2C_ACORN | 562 | config I2C_ACORN |
563 | bool "Acorn IOC/IOMD I2C bus support" | 563 | tristate "Acorn IOC/IOMD I2C bus support" |
564 | depends on ARCH_ACORN | 564 | depends on ARCH_ACORN |
565 | default y | 565 | default y |
566 | select I2C_ALGOBIT | 566 | select I2C_ALGOBIT |
diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c index 09bd7f40b90..7c2be3558a2 100644 --- a/drivers/i2c/busses/i2c-acorn.c +++ b/drivers/i2c/busses/i2c-acorn.c | |||
@@ -94,4 +94,4 @@ static int __init i2c_ioc_init(void) | |||
94 | return i2c_bit_add_bus(&ioc_ops); | 94 | return i2c_bit_add_bus(&ioc_ops); |
95 | } | 95 | } |
96 | 96 | ||
97 | __initcall(i2c_ioc_init); | 97 | module_init(i2c_ioc_init); |
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c index 25fd4676fb1..5879f0f2549 100644 --- a/drivers/i2c/chips/ds1682.c +++ b/drivers/i2c/chips/ds1682.c | |||
@@ -140,8 +140,8 @@ static const struct attribute_group ds1682_group = { | |||
140 | /* | 140 | /* |
141 | * User data attribute | 141 | * User data attribute |
142 | */ | 142 | */ |
143 | static ssize_t ds1682_eeprom_read(struct kobject *kobj, char *buf, loff_t off, | 143 | static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr, |
144 | size_t count) | 144 | char *buf, loff_t off, size_t count) |
145 | { | 145 | { |
146 | struct i2c_client *client = kobj_to_i2c_client(kobj); | 146 | struct i2c_client *client = kobj_to_i2c_client(kobj); |
147 | int rc; | 147 | int rc; |
@@ -163,8 +163,8 @@ static ssize_t ds1682_eeprom_read(struct kobject *kobj, char *buf, loff_t off, | |||
163 | return count; | 163 | return count; |
164 | } | 164 | } |
165 | 165 | ||
166 | static ssize_t ds1682_eeprom_write(struct kobject *kobj, char *buf, loff_t off, | 166 | static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr, |
167 | size_t count) | 167 | char *buf, loff_t off, size_t count) |
168 | { | 168 | { |
169 | struct i2c_client *client = kobj_to_i2c_client(kobj); | 169 | struct i2c_client *client = kobj_to_i2c_client(kobj); |
170 | 170 | ||
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 444a0b84f5b..c89b5f4b2d0 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
@@ -18,10 +18,10 @@ | |||
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/scatterlist.h> | 20 | #include <linux/scatterlist.h> |
21 | #include <linux/io.h> | ||
21 | 22 | ||
22 | #include <asm/dma.h> | 23 | #include <asm/dma.h> |
23 | #include <asm/ecard.h> | 24 | #include <asm/ecard.h> |
24 | #include <asm/io.h> | ||
25 | 25 | ||
26 | #define ICS_IDENT_OFFSET 0x2280 | 26 | #define ICS_IDENT_OFFSET 0x2280 |
27 | 27 | ||
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index c4d3d4131f0..51a12062ed3 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -283,7 +283,7 @@ static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attr | |||
283 | memcpy(buf, \ | 283 | memcpy(buf, \ |
284 | CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(class->td_kv), \ | 284 | CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(class->td_kv), \ |
285 | len); \ | 285 | len); \ |
286 | while ((buf + len - 1) == '\0') \ | 286 | while (buf[len - 1] == '\0') \ |
287 | len--; \ | 287 | len--; \ |
288 | buf[len++] = '\n'; \ | 288 | buf[len++] = '\n'; \ |
289 | buf[len] = '\0'; \ | 289 | buf[len] = '\0'; \ |
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index d19874bf070..1d882360b34 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c | |||
@@ -459,7 +459,7 @@ static int ax_open(struct net_device *dev) | |||
459 | struct ei_device *ei_local = netdev_priv(dev); | 459 | struct ei_device *ei_local = netdev_priv(dev); |
460 | int ret; | 460 | int ret; |
461 | 461 | ||
462 | dev_dbg(ax->dev, "%s: open\n", dev->name); | 462 | dev_dbg(&ax->dev->dev, "%s: open\n", dev->name); |
463 | 463 | ||
464 | ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev); | 464 | ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev); |
465 | if (ret) | 465 | if (ret) |
@@ -492,7 +492,7 @@ static int ax_close(struct net_device *dev) | |||
492 | struct ax_device *ax = to_ax_dev(dev); | 492 | struct ax_device *ax = to_ax_dev(dev); |
493 | struct ei_device *ei_local = netdev_priv(dev); | 493 | struct ei_device *ei_local = netdev_priv(dev); |
494 | 494 | ||
495 | dev_dbg(ax->dev, "%s: close\n", dev->name); | 495 | dev_dbg(&ax->dev->dev, "%s: close\n", dev->name); |
496 | 496 | ||
497 | /* turn the phy off */ | 497 | /* turn the phy off */ |
498 | 498 | ||
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 7dcd138b0fe..f87d76981ab 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1274,7 +1274,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1274 | if (pdev->vendor == 0x1282 && pdev->device == 0x9100) | 1274 | if (pdev->vendor == 0x1282 && pdev->device == 0x9100) |
1275 | { | 1275 | { |
1276 | /* Read Chip revision */ | 1276 | /* Read Chip revision */ |
1277 | if (pdev->revision < 0x02000030) | 1277 | if (pdev->revision < 0x30) |
1278 | { | 1278 | { |
1279 | printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); | 1279 | printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n"); |
1280 | return -ENODEV; | 1280 | return -ENODEV; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 740a2194fdd..ca24299a26c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <asm/unaligned.h> | ||
19 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
20 | #include <linux/init.h> | 19 | #include <linux/init.h> |
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -26,6 +25,7 @@ | |||
26 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
27 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
28 | #include <net/ieee80211.h> | 27 | #include <net/ieee80211.h> |
28 | #include <asm/unaligned.h> | ||
29 | 29 | ||
30 | #include "zd_def.h" | 30 | #include "zd_def.h" |
31 | #include "zd_netdev.h" | 31 | #include "zd_netdev.h" |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index ab9c3e5a7c1..3f6e176e6ea 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -16,6 +16,7 @@ config POWER_SUPPLY_DEBUG | |||
16 | 16 | ||
17 | config PDA_POWER | 17 | config PDA_POWER |
18 | tristate "Generic PDA/phone power driver" | 18 | tristate "Generic PDA/phone power driver" |
19 | depends on !S390 | ||
19 | help | 20 | help |
20 | Say Y here to enable generic power driver for PDAs and phones with | 21 | Say Y here to enable generic power driver for PDAs and phones with |
21 | one or two external power supplies (AC/USB) connected to main and | 22 | one or two external power supplies (AC/USB) connected to main and |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index c0a962bb5f2..0174a322e00 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -937,6 +937,7 @@ static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
937 | *m66592->ep0_buf = status; | 937 | *m66592->ep0_buf = status; |
938 | m66592->ep0_req->buf = m66592->ep0_buf; | 938 | m66592->ep0_req->buf = m66592->ep0_buf; |
939 | m66592->ep0_req->length = 2; | 939 | m66592->ep0_req->length = 2; |
940 | /* AV: what happens if we get called again before that gets through? */ | ||
940 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); | 941 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); |
941 | } | 942 | } |
942 | 943 | ||
@@ -1254,24 +1255,6 @@ static void m66592_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
1254 | kfree(req); | 1255 | kfree(req); |
1255 | } | 1256 | } |
1256 | 1257 | ||
1257 | static void *m66592_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | ||
1258 | dma_addr_t *dma, gfp_t gfp_flags) | ||
1259 | { | ||
1260 | void *buf; | ||
1261 | |||
1262 | buf = kzalloc(bytes, gfp_flags); | ||
1263 | if (dma) | ||
1264 | *dma = virt_to_bus(buf); | ||
1265 | |||
1266 | return buf; | ||
1267 | } | ||
1268 | |||
1269 | static void m66592_free_buffer(struct usb_ep *_ep, void *buf, | ||
1270 | dma_addr_t dma, unsigned bytes) | ||
1271 | { | ||
1272 | kfree(buf); | ||
1273 | } | ||
1274 | |||
1275 | static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | 1258 | static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, |
1276 | gfp_t gfp_flags) | 1259 | gfp_t gfp_flags) |
1277 | { | 1260 | { |
@@ -1378,9 +1361,6 @@ static struct usb_ep_ops m66592_ep_ops = { | |||
1378 | .alloc_request = m66592_alloc_request, | 1361 | .alloc_request = m66592_alloc_request, |
1379 | .free_request = m66592_free_request, | 1362 | .free_request = m66592_free_request, |
1380 | 1363 | ||
1381 | .alloc_buffer = m66592_alloc_buffer, | ||
1382 | .free_buffer = m66592_free_buffer, | ||
1383 | |||
1384 | .queue = m66592_queue, | 1364 | .queue = m66592_queue, |
1385 | .dequeue = m66592_dequeue, | 1365 | .dequeue = m66592_dequeue, |
1386 | 1366 | ||
@@ -1603,11 +1583,12 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1603 | 1583 | ||
1604 | the_controller = m66592; | 1584 | the_controller = m66592; |
1605 | 1585 | ||
1586 | /* AV: leaks */ | ||
1606 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); | 1587 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); |
1607 | if (m66592->ep0_req == NULL) | 1588 | if (m66592->ep0_req == NULL) |
1608 | goto clean_up; | 1589 | goto clean_up; |
1609 | m66592->ep0_buf = m66592_alloc_buffer(&m66592->ep[0].ep, 2, NULL, | 1590 | /* AV: leaks, and do we really need it separately allocated? */ |
1610 | GFP_KERNEL); | 1591 | m66592->ep0_buf = kzalloc(2, GFP_KERNEL); |
1611 | if (m66592->ep0_buf == NULL) | 1592 | if (m66592->ep0_buf == NULL) |
1612 | goto clean_up; | 1593 | goto clean_up; |
1613 | 1594 | ||
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 88a37fbccc3..1f2b1a4d5fb 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c | |||
@@ -68,8 +68,8 @@ int w1_ds2760_write(struct device *dev, char *buf, int addr, size_t count) | |||
68 | return w1_ds2760_io(dev, buf, addr, count, 1); | 68 | return w1_ds2760_io(dev, buf, addr, count, 1); |
69 | } | 69 | } |
70 | 70 | ||
71 | static ssize_t w1_ds2760_read_bin(struct kobject *kobj, char *buf, loff_t off, | 71 | static ssize_t w1_ds2760_read_bin(struct kobject *kobj, struct bin_attribute *attr, |
72 | size_t count) | 72 | char *buf, loff_t off, size_t count) |
73 | { | 73 | { |
74 | struct device *dev = container_of(kobj, struct device, kobj); | 74 | struct device *dev = container_of(kobj, struct device, kobj); |
75 | return w1_ds2760_read(dev, buf, off, count); | 75 | return w1_ds2760_read(dev, buf, off, count); |
diff --git a/fs/9p/9p.h b/fs/9p/9p.h deleted file mode 100644 index 94e2f92ab2e..00000000000 --- a/fs/9p/9p.h +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/9p.h | ||
3 | * | ||
4 | * 9P protocol definitions. | ||
5 | * | ||
6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | /* Message Types */ | ||
28 | enum { | ||
29 | TVERSION = 100, | ||
30 | RVERSION, | ||
31 | TAUTH = 102, | ||
32 | RAUTH, | ||
33 | TATTACH = 104, | ||
34 | RATTACH, | ||
35 | TERROR = 106, | ||
36 | RERROR, | ||
37 | TFLUSH = 108, | ||
38 | RFLUSH, | ||
39 | TWALK = 110, | ||
40 | RWALK, | ||
41 | TOPEN = 112, | ||
42 | ROPEN, | ||
43 | TCREATE = 114, | ||
44 | RCREATE, | ||
45 | TREAD = 116, | ||
46 | RREAD, | ||
47 | TWRITE = 118, | ||
48 | RWRITE, | ||
49 | TCLUNK = 120, | ||
50 | RCLUNK, | ||
51 | TREMOVE = 122, | ||
52 | RREMOVE, | ||
53 | TSTAT = 124, | ||
54 | RSTAT, | ||
55 | TWSTAT = 126, | ||
56 | RWSTAT, | ||
57 | }; | ||
58 | |||
59 | /* modes */ | ||
60 | enum { | ||
61 | V9FS_OREAD = 0x00, | ||
62 | V9FS_OWRITE = 0x01, | ||
63 | V9FS_ORDWR = 0x02, | ||
64 | V9FS_OEXEC = 0x03, | ||
65 | V9FS_OEXCL = 0x04, | ||
66 | V9FS_OTRUNC = 0x10, | ||
67 | V9FS_OREXEC = 0x20, | ||
68 | V9FS_ORCLOSE = 0x40, | ||
69 | V9FS_OAPPEND = 0x80, | ||
70 | }; | ||
71 | |||
72 | /* permissions */ | ||
73 | enum { | ||
74 | V9FS_DMDIR = 0x80000000, | ||
75 | V9FS_DMAPPEND = 0x40000000, | ||
76 | V9FS_DMEXCL = 0x20000000, | ||
77 | V9FS_DMMOUNT = 0x10000000, | ||
78 | V9FS_DMAUTH = 0x08000000, | ||
79 | V9FS_DMTMP = 0x04000000, | ||
80 | V9FS_DMSYMLINK = 0x02000000, | ||
81 | V9FS_DMLINK = 0x01000000, | ||
82 | /* 9P2000.u extensions */ | ||
83 | V9FS_DMDEVICE = 0x00800000, | ||
84 | V9FS_DMNAMEDPIPE = 0x00200000, | ||
85 | V9FS_DMSOCKET = 0x00100000, | ||
86 | V9FS_DMSETUID = 0x00080000, | ||
87 | V9FS_DMSETGID = 0x00040000, | ||
88 | }; | ||
89 | |||
90 | /* qid.types */ | ||
91 | enum { | ||
92 | V9FS_QTDIR = 0x80, | ||
93 | V9FS_QTAPPEND = 0x40, | ||
94 | V9FS_QTEXCL = 0x20, | ||
95 | V9FS_QTMOUNT = 0x10, | ||
96 | V9FS_QTAUTH = 0x08, | ||
97 | V9FS_QTTMP = 0x04, | ||
98 | V9FS_QTSYMLINK = 0x02, | ||
99 | V9FS_QTLINK = 0x01, | ||
100 | V9FS_QTFILE = 0x00, | ||
101 | }; | ||
102 | |||
103 | #define V9FS_NOTAG (u16)(~0) | ||
104 | #define V9FS_NOFID (u32)(~0) | ||
105 | #define V9FS_MAXWELEM 16 | ||
106 | |||
107 | /* ample room for Twrite/Rread header (iounit) */ | ||
108 | #define V9FS_IOHDRSZ 24 | ||
109 | |||
110 | struct v9fs_str { | ||
111 | u16 len; | ||
112 | char *str; | ||
113 | }; | ||
114 | |||
115 | /* qids are the unique ID for a file (like an inode */ | ||
116 | struct v9fs_qid { | ||
117 | u8 type; | ||
118 | u32 version; | ||
119 | u64 path; | ||
120 | }; | ||
121 | |||
122 | /* Plan 9 file metadata (stat) structure */ | ||
123 | struct v9fs_stat { | ||
124 | u16 size; | ||
125 | u16 type; | ||
126 | u32 dev; | ||
127 | struct v9fs_qid qid; | ||
128 | u32 mode; | ||
129 | u32 atime; | ||
130 | u32 mtime; | ||
131 | u64 length; | ||
132 | struct v9fs_str name; | ||
133 | struct v9fs_str uid; | ||
134 | struct v9fs_str gid; | ||
135 | struct v9fs_str muid; | ||
136 | struct v9fs_str extension; /* 9p2000.u extensions */ | ||
137 | u32 n_uid; /* 9p2000.u extensions */ | ||
138 | u32 n_gid; /* 9p2000.u extensions */ | ||
139 | u32 n_muid; /* 9p2000.u extensions */ | ||
140 | }; | ||
141 | |||
142 | /* file metadata (stat) structure used to create Twstat message | ||
143 | The is similar to v9fs_stat, but the strings don't point to | ||
144 | the same memory block and should be freed separately | ||
145 | */ | ||
146 | struct v9fs_wstat { | ||
147 | u16 size; | ||
148 | u16 type; | ||
149 | u32 dev; | ||
150 | struct v9fs_qid qid; | ||
151 | u32 mode; | ||
152 | u32 atime; | ||
153 | u32 mtime; | ||
154 | u64 length; | ||
155 | char *name; | ||
156 | char *uid; | ||
157 | char *gid; | ||
158 | char *muid; | ||
159 | char *extension; /* 9p2000.u extensions */ | ||
160 | u32 n_uid; /* 9p2000.u extensions */ | ||
161 | u32 n_gid; /* 9p2000.u extensions */ | ||
162 | u32 n_muid; /* 9p2000.u extensions */ | ||
163 | }; | ||
164 | |||
165 | /* Structures for Protocol Operations */ | ||
166 | |||
167 | struct Tversion { | ||
168 | u32 msize; | ||
169 | struct v9fs_str version; | ||
170 | }; | ||
171 | |||
172 | struct Rversion { | ||
173 | u32 msize; | ||
174 | struct v9fs_str version; | ||
175 | }; | ||
176 | |||
177 | struct Tauth { | ||
178 | u32 afid; | ||
179 | struct v9fs_str uname; | ||
180 | struct v9fs_str aname; | ||
181 | }; | ||
182 | |||
183 | struct Rauth { | ||
184 | struct v9fs_qid qid; | ||
185 | }; | ||
186 | |||
187 | struct Rerror { | ||
188 | struct v9fs_str error; | ||
189 | u32 errno; /* 9p2000.u extension */ | ||
190 | }; | ||
191 | |||
192 | struct Tflush { | ||
193 | u16 oldtag; | ||
194 | }; | ||
195 | |||
196 | struct Rflush { | ||
197 | }; | ||
198 | |||
199 | struct Tattach { | ||
200 | u32 fid; | ||
201 | u32 afid; | ||
202 | struct v9fs_str uname; | ||
203 | struct v9fs_str aname; | ||
204 | }; | ||
205 | |||
206 | struct Rattach { | ||
207 | struct v9fs_qid qid; | ||
208 | }; | ||
209 | |||
210 | struct Twalk { | ||
211 | u32 fid; | ||
212 | u32 newfid; | ||
213 | u16 nwname; | ||
214 | struct v9fs_str wnames[16]; | ||
215 | }; | ||
216 | |||
217 | struct Rwalk { | ||
218 | u16 nwqid; | ||
219 | struct v9fs_qid wqids[16]; | ||
220 | }; | ||
221 | |||
222 | struct Topen { | ||
223 | u32 fid; | ||
224 | u8 mode; | ||
225 | }; | ||
226 | |||
227 | struct Ropen { | ||
228 | struct v9fs_qid qid; | ||
229 | u32 iounit; | ||
230 | }; | ||
231 | |||
232 | struct Tcreate { | ||
233 | u32 fid; | ||
234 | struct v9fs_str name; | ||
235 | u32 perm; | ||
236 | u8 mode; | ||
237 | struct v9fs_str extension; | ||
238 | }; | ||
239 | |||
240 | struct Rcreate { | ||
241 | struct v9fs_qid qid; | ||
242 | u32 iounit; | ||
243 | }; | ||
244 | |||
245 | struct Tread { | ||
246 | u32 fid; | ||
247 | u64 offset; | ||
248 | u32 count; | ||
249 | }; | ||
250 | |||
251 | struct Rread { | ||
252 | u32 count; | ||
253 | u8 *data; | ||
254 | }; | ||
255 | |||
256 | struct Twrite { | ||
257 | u32 fid; | ||
258 | u64 offset; | ||
259 | u32 count; | ||
260 | u8 *data; | ||
261 | }; | ||
262 | |||
263 | struct Rwrite { | ||
264 | u32 count; | ||
265 | }; | ||
266 | |||
267 | struct Tclunk { | ||
268 | u32 fid; | ||
269 | }; | ||
270 | |||
271 | struct Rclunk { | ||
272 | }; | ||
273 | |||
274 | struct Tremove { | ||
275 | u32 fid; | ||
276 | }; | ||
277 | |||
278 | struct Rremove { | ||
279 | }; | ||
280 | |||
281 | struct Tstat { | ||
282 | u32 fid; | ||
283 | }; | ||
284 | |||
285 | struct Rstat { | ||
286 | struct v9fs_stat stat; | ||
287 | }; | ||
288 | |||
289 | struct Twstat { | ||
290 | u32 fid; | ||
291 | struct v9fs_stat stat; | ||
292 | }; | ||
293 | |||
294 | struct Rwstat { | ||
295 | }; | ||
296 | |||
297 | /* | ||
298 | * fcall is the primary packet structure | ||
299 | * | ||
300 | */ | ||
301 | |||
302 | struct v9fs_fcall { | ||
303 | u32 size; | ||
304 | u8 id; | ||
305 | u16 tag; | ||
306 | void *sdata; | ||
307 | |||
308 | union { | ||
309 | struct Tversion tversion; | ||
310 | struct Rversion rversion; | ||
311 | struct Tauth tauth; | ||
312 | struct Rauth rauth; | ||
313 | struct Rerror rerror; | ||
314 | struct Tflush tflush; | ||
315 | struct Rflush rflush; | ||
316 | struct Tattach tattach; | ||
317 | struct Rattach rattach; | ||
318 | struct Twalk twalk; | ||
319 | struct Rwalk rwalk; | ||
320 | struct Topen topen; | ||
321 | struct Ropen ropen; | ||
322 | struct Tcreate tcreate; | ||
323 | struct Rcreate rcreate; | ||
324 | struct Tread tread; | ||
325 | struct Rread rread; | ||
326 | struct Twrite twrite; | ||
327 | struct Rwrite rwrite; | ||
328 | struct Tclunk tclunk; | ||
329 | struct Rclunk rclunk; | ||
330 | struct Tremove tremove; | ||
331 | struct Rremove rremove; | ||
332 | struct Tstat tstat; | ||
333 | struct Rstat rstat; | ||
334 | struct Twstat twstat; | ||
335 | struct Rwstat rwstat; | ||
336 | } params; | ||
337 | }; | ||
338 | |||
339 | #define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \ | ||
340 | fcall?fcall->params.rerror.error.len:0, \ | ||
341 | fcall?fcall->params.rerror.error.str:""); | ||
342 | |||
343 | int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, | ||
344 | char *version, struct v9fs_fcall **rcall); | ||
345 | |||
346 | int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, | ||
347 | u32 fid, u32 afid, struct v9fs_fcall **rcall); | ||
348 | |||
349 | int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid); | ||
350 | |||
351 | int v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, | ||
352 | struct v9fs_fcall **rcall); | ||
353 | |||
354 | int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, | ||
355 | struct v9fs_wstat *wstat, struct v9fs_fcall **rcall); | ||
356 | |||
357 | int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, | ||
358 | char *name, struct v9fs_fcall **rcall); | ||
359 | |||
360 | int v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, | ||
361 | struct v9fs_fcall **rcall); | ||
362 | |||
363 | int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | ||
364 | struct v9fs_fcall **rcall); | ||
365 | |||
366 | int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | ||
367 | u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall); | ||
368 | |||
369 | int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, | ||
370 | u64 offset, u32 count, struct v9fs_fcall **rcall); | ||
371 | |||
372 | int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, | ||
373 | u32 count, const char __user * data, | ||
374 | struct v9fs_fcall **rcall); | ||
375 | int v9fs_printfcall(char *, int, struct v9fs_fcall *, int); | ||
diff --git a/fs/9p/Makefile b/fs/9p/Makefile index 87897f84dfb..bc7f0d1551e 100644 --- a/fs/9p/Makefile +++ b/fs/9p/Makefile | |||
@@ -1,18 +1,12 @@ | |||
1 | obj-$(CONFIG_9P_FS) := 9p.o | 1 | obj-$(CONFIG_9P_FS) := 9p.o |
2 | 2 | ||
3 | 9p-objs := \ | 3 | 9p-objs := \ |
4 | trans_fd.o \ | ||
5 | mux.o \ | ||
6 | fcall.o \ | ||
7 | conv.o \ | ||
8 | vfs_super.o \ | 4 | vfs_super.o \ |
9 | vfs_inode.o \ | 5 | vfs_inode.o \ |
10 | vfs_addr.o \ | 6 | vfs_addr.o \ |
11 | vfs_file.o \ | 7 | vfs_file.o \ |
12 | vfs_dir.o \ | 8 | vfs_dir.o \ |
13 | vfs_dentry.o \ | 9 | vfs_dentry.o \ |
14 | error.o \ | ||
15 | v9fs.o \ | 10 | v9fs.o \ |
16 | fid.o \ | 11 | fid.o \ |
17 | fcprint.o | ||
18 | 12 | ||
diff --git a/fs/9p/conv.h b/fs/9p/conv.h deleted file mode 100644 index dd5b6b1b610..00000000000 --- a/fs/9p/conv.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/conv.h | ||
3 | * | ||
4 | * 9P protocol conversion definitions. | ||
5 | * | ||
6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | ||
28 | int extended); | ||
29 | int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | ||
30 | int extended); | ||
31 | |||
32 | void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag); | ||
33 | |||
34 | struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version); | ||
35 | struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname, | ||
36 | char *aname); | ||
37 | struct v9fs_fcall *v9fs_create_tflush(u16 oldtag); | ||
38 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | ||
39 | char **wnames); | ||
40 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); | ||
41 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | ||
42 | char *extension, int extended); | ||
43 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); | ||
44 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | ||
45 | const char __user *data); | ||
46 | struct v9fs_fcall *v9fs_create_tclunk(u32 fid); | ||
47 | struct v9fs_fcall *v9fs_create_tremove(u32 fid); | ||
48 | struct v9fs_fcall *v9fs_create_tstat(u32 fid); | ||
49 | struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, | ||
50 | int extended); | ||
diff --git a/fs/9p/debug.h b/fs/9p/debug.h deleted file mode 100644 index 4228c0bb3c3..00000000000 --- a/fs/9p/debug.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/debug.h - V9FS Debug Definitions | ||
3 | * | ||
4 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
5 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 | ||
9 | * as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to: | ||
18 | * Free Software Foundation | ||
19 | * 51 Franklin Street, Fifth Floor | ||
20 | * Boston, MA 02111-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #define DEBUG_ERROR (1<<0) | ||
25 | #define DEBUG_CURRENT (1<<1) | ||
26 | #define DEBUG_9P (1<<2) | ||
27 | #define DEBUG_VFS (1<<3) | ||
28 | #define DEBUG_CONV (1<<4) | ||
29 | #define DEBUG_MUX (1<<5) | ||
30 | #define DEBUG_TRANS (1<<6) | ||
31 | #define DEBUG_SLABS (1<<7) | ||
32 | #define DEBUG_FCALL (1<<8) | ||
33 | |||
34 | #define DEBUG_DUMP_PKT 0 | ||
35 | |||
36 | extern int v9fs_debug_level; | ||
37 | |||
38 | #define dprintk(level, format, arg...) \ | ||
39 | do { \ | ||
40 | if((v9fs_debug_level & level)==level) \ | ||
41 | printk(KERN_NOTICE "-- %s (%d): " \ | ||
42 | format , __FUNCTION__, current->pid , ## arg); \ | ||
43 | } while(0) | ||
44 | |||
45 | #define eprintk(level, format, arg...) \ | ||
46 | do { \ | ||
47 | printk(level "v9fs: %s (%d): " \ | ||
48 | format , __FUNCTION__, current->pid , ## arg); \ | ||
49 | } while(0) | ||
50 | |||
51 | #if DEBUG_DUMP_PKT | ||
52 | static inline void dump_data(const unsigned char *data, unsigned int datalen) | ||
53 | { | ||
54 | int i, n; | ||
55 | char buf[5*8]; | ||
56 | |||
57 | n = 0; | ||
58 | i = 0; | ||
59 | while (i < datalen) { | ||
60 | n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]); | ||
61 | if (i%4 == 0) | ||
62 | n += snprintf(buf+n, sizeof(buf)-n, " "); | ||
63 | |||
64 | if (i%16 == 0) { | ||
65 | dprintk(DEBUG_ERROR, "%s\n", buf); | ||
66 | n = 0; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | dprintk(DEBUG_ERROR, "%s\n", buf); | ||
71 | } | ||
72 | #else /* DEBUG_DUMP_PKT */ | ||
73 | static inline void dump_data(const unsigned char *data, unsigned int datalen) | ||
74 | { | ||
75 | |||
76 | } | ||
77 | #endif /* DEBUG_DUMP_PKT */ | ||
diff --git a/fs/9p/error.c b/fs/9p/error.c deleted file mode 100644 index 0d7fa4e0881..00000000000 --- a/fs/9p/error.c +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/error.c | ||
3 | * | ||
4 | * Error string handling | ||
5 | * | ||
6 | * Plan 9 uses error strings, Unix uses error numbers. These functions | ||
7 | * try to help manage that and provide for dynamically adding error | ||
8 | * mappings. | ||
9 | * | ||
10 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
11 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 | ||
15 | * as published by the Free Software Foundation. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to: | ||
24 | * Free Software Foundation | ||
25 | * 51 Franklin Street, Fifth Floor | ||
26 | * Boston, MA 02111-1301 USA | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | |||
32 | #include <linux/list.h> | ||
33 | #include <linux/jhash.h> | ||
34 | |||
35 | #include "debug.h" | ||
36 | #include "error.h" | ||
37 | |||
38 | /** | ||
39 | * v9fs_error_init - preload | ||
40 | * @errstr: error string | ||
41 | * | ||
42 | */ | ||
43 | |||
44 | int v9fs_error_init(void) | ||
45 | { | ||
46 | struct errormap *c; | ||
47 | int bucket; | ||
48 | |||
49 | /* initialize hash table */ | ||
50 | for (bucket = 0; bucket < ERRHASHSZ; bucket++) | ||
51 | INIT_HLIST_HEAD(&hash_errmap[bucket]); | ||
52 | |||
53 | /* load initial error map into hash table */ | ||
54 | for (c = errmap; c->name != NULL; c++) { | ||
55 | c->namelen = strlen(c->name); | ||
56 | bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; | ||
57 | INIT_HLIST_NODE(&c->list); | ||
58 | hlist_add_head(&c->list, &hash_errmap[bucket]); | ||
59 | } | ||
60 | |||
61 | return 1; | ||
62 | } | ||
63 | |||
64 | /** | ||
65 | * errstr2errno - convert error string to error number | ||
66 | * @errstr: error string | ||
67 | * | ||
68 | */ | ||
69 | |||
70 | int v9fs_errstr2errno(char *errstr, int len) | ||
71 | { | ||
72 | int errno = 0; | ||
73 | struct hlist_node *p = NULL; | ||
74 | struct errormap *c = NULL; | ||
75 | int bucket = jhash(errstr, len, 0) % ERRHASHSZ; | ||
76 | |||
77 | hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { | ||
78 | if (c->namelen==len && !memcmp(c->name, errstr, len)) { | ||
79 | errno = c->val; | ||
80 | break; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | if (errno == 0) { | ||
85 | /* TODO: if error isn't found, add it dynamically */ | ||
86 | errstr[len] = 0; | ||
87 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, | ||
88 | errstr); | ||
89 | errno = 1; | ||
90 | } | ||
91 | |||
92 | return -errno; | ||
93 | } | ||
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c deleted file mode 100644 index dc336a67592..00000000000 --- a/fs/9p/fcall.c +++ /dev/null | |||
@@ -1,427 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/fcall.c | ||
3 | * | ||
4 | * This file contains functions to perform synchronous 9P calls | ||
5 | * | ||
6 | * Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/fs.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/idr.h> | ||
32 | |||
33 | #include "debug.h" | ||
34 | #include "v9fs.h" | ||
35 | #include "9p.h" | ||
36 | #include "conv.h" | ||
37 | #include "mux.h" | ||
38 | |||
39 | /** | ||
40 | * v9fs_t_version - negotiate protocol parameters with sever | ||
41 | * @v9ses: 9P2000 session information | ||
42 | * @msize: requested max size packet | ||
43 | * @version: requested version.extension string | ||
44 | * @fcall: pointer to response fcall pointer | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | int | ||
49 | v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize, | ||
50 | char *version, struct v9fs_fcall **rcp) | ||
51 | { | ||
52 | int ret; | ||
53 | struct v9fs_fcall *tc; | ||
54 | |||
55 | dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version); | ||
56 | tc = v9fs_create_tversion(msize, version); | ||
57 | |||
58 | if (!IS_ERR(tc)) { | ||
59 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
60 | kfree(tc); | ||
61 | } else | ||
62 | ret = PTR_ERR(tc); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * v9fs_t_attach - mount the server | ||
69 | * @v9ses: 9P2000 session information | ||
70 | * @uname: user name doing the attach | ||
71 | * @aname: remote name being attached to | ||
72 | * @fid: mount fid to attatch to root node | ||
73 | * @afid: authentication fid (in this case result key) | ||
74 | * @fcall: pointer to response fcall pointer | ||
75 | * | ||
76 | */ | ||
77 | |||
78 | int | ||
79 | v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname, | ||
80 | u32 fid, u32 afid, struct v9fs_fcall **rcp) | ||
81 | { | ||
82 | int ret; | ||
83 | struct v9fs_fcall* tc; | ||
84 | |||
85 | dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname, | ||
86 | aname, fid, afid); | ||
87 | |||
88 | tc = v9fs_create_tattach(fid, afid, uname, aname); | ||
89 | if (!IS_ERR(tc)) { | ||
90 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
91 | kfree(tc); | ||
92 | } else | ||
93 | ret = PTR_ERR(tc); | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, | ||
99 | struct v9fs_fcall *rc, int err) | ||
100 | { | ||
101 | int fid, id; | ||
102 | struct v9fs_session_info *v9ses; | ||
103 | |||
104 | id = 0; | ||
105 | fid = tc->params.tclunk.fid; | ||
106 | if (rc) | ||
107 | id = rc->id; | ||
108 | |||
109 | kfree(tc); | ||
110 | kfree(rc); | ||
111 | if (id == RCLUNK) { | ||
112 | v9ses = a; | ||
113 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * v9fs_t_clunk - release a fid (finish a transaction) | ||
119 | * @v9ses: 9P2000 session information | ||
120 | * @fid: fid to release | ||
121 | * @fcall: pointer to response fcall pointer | ||
122 | * | ||
123 | */ | ||
124 | |||
125 | int | ||
126 | v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid) | ||
127 | { | ||
128 | int ret; | ||
129 | struct v9fs_fcall *tc, *rc; | ||
130 | |||
131 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
132 | |||
133 | rc = NULL; | ||
134 | tc = v9fs_create_tclunk(fid); | ||
135 | if (!IS_ERR(tc)) | ||
136 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
137 | else | ||
138 | ret = PTR_ERR(tc); | ||
139 | |||
140 | if (ret) | ||
141 | dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret); | ||
142 | |||
143 | v9fs_t_clunk_cb(v9ses, tc, rc, ret); | ||
144 | return ret; | ||
145 | } | ||
146 | |||
147 | #if 0 | ||
148 | /** | ||
149 | * v9fs_v9fs_t_flush - flush a pending transaction | ||
150 | * @v9ses: 9P2000 session information | ||
151 | * @tag: tag to release | ||
152 | * | ||
153 | */ | ||
154 | int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) | ||
155 | { | ||
156 | int ret; | ||
157 | struct v9fs_fcall *tc; | ||
158 | |||
159 | dprintk(DEBUG_9P, "oldtag %d\n", oldtag); | ||
160 | |||
161 | tc = v9fs_create_tflush(oldtag); | ||
162 | if (!IS_ERR(tc)) { | ||
163 | ret = v9fs_mux_rpc(v9ses->mux, tc, NULL); | ||
164 | kfree(tc); | ||
165 | } else | ||
166 | ret = PTR_ERR(tc); | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | #endif | ||
171 | |||
172 | /** | ||
173 | * v9fs_t_stat - read a file's meta-data | ||
174 | * @v9ses: 9P2000 session information | ||
175 | * @fid: fid pointing to file or directory to get info about | ||
176 | * @fcall: pointer to response fcall | ||
177 | * | ||
178 | */ | ||
179 | |||
180 | int | ||
181 | v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp) | ||
182 | { | ||
183 | int ret; | ||
184 | struct v9fs_fcall *tc; | ||
185 | |||
186 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
187 | |||
188 | ret = -ENOMEM; | ||
189 | tc = v9fs_create_tstat(fid); | ||
190 | if (!IS_ERR(tc)) { | ||
191 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
192 | kfree(tc); | ||
193 | } else | ||
194 | ret = PTR_ERR(tc); | ||
195 | |||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * v9fs_t_wstat - write a file's meta-data | ||
201 | * @v9ses: 9P2000 session information | ||
202 | * @fid: fid pointing to file or directory to write info about | ||
203 | * @stat: metadata | ||
204 | * @fcall: pointer to response fcall | ||
205 | * | ||
206 | */ | ||
207 | |||
208 | int | ||
209 | v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid, | ||
210 | struct v9fs_wstat *wstat, struct v9fs_fcall **rcp) | ||
211 | { | ||
212 | int ret; | ||
213 | struct v9fs_fcall *tc; | ||
214 | |||
215 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
216 | |||
217 | tc = v9fs_create_twstat(fid, wstat, v9ses->extended); | ||
218 | if (!IS_ERR(tc)) { | ||
219 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
220 | kfree(tc); | ||
221 | } else | ||
222 | ret = PTR_ERR(tc); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * v9fs_t_walk - walk a fid to a new file or directory | ||
229 | * @v9ses: 9P2000 session information | ||
230 | * @fid: fid to walk | ||
231 | * @newfid: new fid (for clone operations) | ||
232 | * @name: path to walk fid to | ||
233 | * @fcall: pointer to response fcall | ||
234 | * | ||
235 | */ | ||
236 | |||
237 | /* TODO: support multiple walk */ | ||
238 | |||
239 | int | ||
240 | v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid, | ||
241 | char *name, struct v9fs_fcall **rcp) | ||
242 | { | ||
243 | int ret; | ||
244 | struct v9fs_fcall *tc; | ||
245 | int nwname; | ||
246 | |||
247 | dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name); | ||
248 | |||
249 | if (name) | ||
250 | nwname = 1; | ||
251 | else | ||
252 | nwname = 0; | ||
253 | |||
254 | tc = v9fs_create_twalk(fid, newfid, nwname, &name); | ||
255 | if (!IS_ERR(tc)) { | ||
256 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
257 | kfree(tc); | ||
258 | } else | ||
259 | ret = PTR_ERR(tc); | ||
260 | |||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * v9fs_t_open - open a file | ||
266 | * | ||
267 | * @v9ses - 9P2000 session information | ||
268 | * @fid - fid to open | ||
269 | * @mode - mode to open file (R, RW, etc) | ||
270 | * @fcall - pointer to response fcall | ||
271 | * | ||
272 | */ | ||
273 | |||
274 | int | ||
275 | v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode, | ||
276 | struct v9fs_fcall **rcp) | ||
277 | { | ||
278 | int ret; | ||
279 | struct v9fs_fcall *tc; | ||
280 | |||
281 | dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode); | ||
282 | |||
283 | tc = v9fs_create_topen(fid, mode); | ||
284 | if (!IS_ERR(tc)) { | ||
285 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
286 | kfree(tc); | ||
287 | } else | ||
288 | ret = PTR_ERR(tc); | ||
289 | |||
290 | return ret; | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * v9fs_t_remove - remove a file or directory | ||
295 | * @v9ses: 9P2000 session information | ||
296 | * @fid: fid to remove | ||
297 | * @fcall: pointer to response fcall | ||
298 | * | ||
299 | */ | ||
300 | |||
301 | int | ||
302 | v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid, | ||
303 | struct v9fs_fcall **rcp) | ||
304 | { | ||
305 | int ret; | ||
306 | struct v9fs_fcall *tc; | ||
307 | |||
308 | dprintk(DEBUG_9P, "fid %d\n", fid); | ||
309 | |||
310 | tc = v9fs_create_tremove(fid); | ||
311 | if (!IS_ERR(tc)) { | ||
312 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
313 | kfree(tc); | ||
314 | } else | ||
315 | ret = PTR_ERR(tc); | ||
316 | |||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | /** | ||
321 | * v9fs_t_create - create a file or directory | ||
322 | * @v9ses: 9P2000 session information | ||
323 | * @fid: fid to create | ||
324 | * @name: name of the file or directory to create | ||
325 | * @perm: permissions to create with | ||
326 | * @mode: mode to open file (R, RW, etc) | ||
327 | * @fcall: pointer to response fcall | ||
328 | * | ||
329 | */ | ||
330 | |||
331 | int | ||
332 | v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm, | ||
333 | u8 mode, char *extension, struct v9fs_fcall **rcp) | ||
334 | { | ||
335 | int ret; | ||
336 | struct v9fs_fcall *tc; | ||
337 | |||
338 | dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", | ||
339 | fid, name, perm, mode); | ||
340 | |||
341 | tc = v9fs_create_tcreate(fid, name, perm, mode, extension, | ||
342 | v9ses->extended); | ||
343 | |||
344 | if (!IS_ERR(tc)) { | ||
345 | ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); | ||
346 | kfree(tc); | ||
347 | } else | ||
348 | ret = PTR_ERR(tc); | ||
349 | |||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * v9fs_t_read - read data | ||
355 | * @v9ses: 9P2000 session information | ||
356 | * @fid: fid to read from | ||
357 | * @offset: offset to start read at | ||
358 | * @count: how many bytes to read | ||
359 | * @fcall: pointer to response fcall (with data) | ||
360 | * | ||
361 | */ | ||
362 | |||
363 | int | ||
364 | v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset, | ||
365 | u32 count, struct v9fs_fcall **rcp) | ||
366 | { | ||
367 | int ret; | ||
368 | struct v9fs_fcall *tc, *rc; | ||
369 | |||
370 | dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, | ||
371 | (long long unsigned) offset, count); | ||
372 | |||
373 | tc = v9fs_create_tread(fid, offset, count); | ||
374 | if (!IS_ERR(tc)) { | ||
375 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
376 | if (!ret) | ||
377 | ret = rc->params.rread.count; | ||
378 | if (rcp) | ||
379 | *rcp = rc; | ||
380 | else | ||
381 | kfree(rc); | ||
382 | |||
383 | kfree(tc); | ||
384 | } else | ||
385 | ret = PTR_ERR(tc); | ||
386 | |||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * v9fs_t_write - write data | ||
392 | * @v9ses: 9P2000 session information | ||
393 | * @fid: fid to write to | ||
394 | * @offset: offset to start write at | ||
395 | * @count: how many bytes to write | ||
396 | * @fcall: pointer to response fcall | ||
397 | * | ||
398 | */ | ||
399 | |||
400 | int | ||
401 | v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count, | ||
402 | const char __user *data, struct v9fs_fcall **rcp) | ||
403 | { | ||
404 | int ret; | ||
405 | struct v9fs_fcall *tc, *rc; | ||
406 | |||
407 | dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid, | ||
408 | (long long unsigned) offset, count); | ||
409 | |||
410 | tc = v9fs_create_twrite(fid, offset, count, data); | ||
411 | if (!IS_ERR(tc)) { | ||
412 | ret = v9fs_mux_rpc(v9ses->mux, tc, &rc); | ||
413 | |||
414 | if (!ret) | ||
415 | ret = rc->params.rwrite.count; | ||
416 | if (rcp) | ||
417 | *rcp = rc; | ||
418 | else | ||
419 | kfree(rc); | ||
420 | |||
421 | kfree(tc); | ||
422 | } else | ||
423 | ret = PTR_ERR(tc); | ||
424 | |||
425 | return ret; | ||
426 | } | ||
427 | |||
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 90419715c7e..08fa320b7e6 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -26,10 +26,10 @@ | |||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
29 | #include <net/9p/9p.h> | ||
30 | #include <net/9p/client.h> | ||
29 | 31 | ||
30 | #include "debug.h" | ||
31 | #include "v9fs.h" | 32 | #include "v9fs.h" |
32 | #include "9p.h" | ||
33 | #include "v9fs_vfs.h" | 33 | #include "v9fs_vfs.h" |
34 | #include "fid.h" | 34 | #include "fid.h" |
35 | 35 | ||
@@ -40,67 +40,29 @@ | |||
40 | * | 40 | * |
41 | */ | 41 | */ |
42 | 42 | ||
43 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry) | 43 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid) |
44 | { | 44 | { |
45 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; | 45 | struct v9fs_dentry *dent; |
46 | dprintk(DEBUG_9P, "fid %d (%p) dentry %s (%p)\n", fid->fid, fid, | ||
47 | dentry->d_iname, dentry); | ||
48 | if (dentry->d_fsdata == NULL) { | ||
49 | dentry->d_fsdata = | ||
50 | kmalloc(sizeof(struct list_head), GFP_KERNEL); | ||
51 | if (dentry->d_fsdata == NULL) { | ||
52 | dprintk(DEBUG_ERROR, "Out of memory\n"); | ||
53 | return -ENOMEM; | ||
54 | } | ||
55 | fid_list = (struct list_head *)dentry->d_fsdata; | ||
56 | INIT_LIST_HEAD(fid_list); /* Initialize list head */ | ||
57 | } | ||
58 | 46 | ||
59 | fid->uid = current->uid; | 47 | P9_DPRINTK(P9_DEBUG_VFS, "fid %d dentry %s\n", |
60 | list_add(&fid->list, fid_list); | 48 | fid->fid, dentry->d_iname); |
61 | return 0; | ||
62 | } | ||
63 | 49 | ||
64 | /** | 50 | dent = dentry->d_fsdata; |
65 | * v9fs_fid_create - allocate a FID structure | 51 | if (!dent) { |
66 | * @dentry - dentry to link newly created fid to | 52 | dent = kmalloc(sizeof(struct v9fs_dentry), GFP_KERNEL); |
67 | * | 53 | if (!dent) |
68 | */ | 54 | return -ENOMEM; |
69 | |||
70 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid) | ||
71 | { | ||
72 | struct v9fs_fid *new; | ||
73 | 55 | ||
74 | dprintk(DEBUG_9P, "fid create fid %d\n", fid); | 56 | spin_lock_init(&dent->lock); |
75 | new = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); | 57 | INIT_LIST_HEAD(&dent->fidlist); |
76 | if (new == NULL) { | 58 | dentry->d_fsdata = dent; |
77 | dprintk(DEBUG_ERROR, "Out of Memory\n"); | ||
78 | return ERR_PTR(-ENOMEM); | ||
79 | } | 59 | } |
80 | 60 | ||
81 | new->fid = fid; | 61 | spin_lock(&dent->lock); |
82 | new->v9ses = v9ses; | 62 | list_add(&fid->dlist, &dent->fidlist); |
83 | new->fidopen = 0; | 63 | spin_unlock(&dent->lock); |
84 | new->fidclunked = 0; | ||
85 | new->iounit = 0; | ||
86 | new->rdir_pos = 0; | ||
87 | new->rdir_fcall = NULL; | ||
88 | init_MUTEX(&new->lock); | ||
89 | INIT_LIST_HEAD(&new->list); | ||
90 | |||
91 | return new; | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * v9fs_fid_destroy - deallocate a FID structure | ||
96 | * @fid: fid to destroy | ||
97 | * | ||
98 | */ | ||
99 | 64 | ||
100 | void v9fs_fid_destroy(struct v9fs_fid *fid) | 65 | return 0; |
101 | { | ||
102 | list_del(&fid->list); | ||
103 | kfree(fid); | ||
104 | } | 66 | } |
105 | 67 | ||
106 | /** | 68 | /** |
@@ -114,30 +76,42 @@ void v9fs_fid_destroy(struct v9fs_fid *fid) | |||
114 | * | 76 | * |
115 | */ | 77 | */ |
116 | 78 | ||
117 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | 79 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) |
118 | { | 80 | { |
119 | struct list_head *fid_list = (struct list_head *)dentry->d_fsdata; | 81 | struct v9fs_dentry *dent; |
120 | struct v9fs_fid *return_fid = NULL; | 82 | struct p9_fid *fid; |
121 | 83 | ||
122 | dprintk(DEBUG_9P, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 84 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
123 | 85 | dent = dentry->d_fsdata; | |
124 | if (fid_list) | 86 | if (dent) |
125 | return_fid = list_entry(fid_list->next, struct v9fs_fid, list); | 87 | fid = list_entry(dent->fidlist.next, struct p9_fid, dlist); |
88 | else | ||
89 | fid = ERR_PTR(-EBADF); | ||
90 | |||
91 | P9_DPRINTK(P9_DEBUG_VFS, " fid: %p\n", fid); | ||
92 | return fid; | ||
93 | } | ||
126 | 94 | ||
127 | if (!return_fid) { | 95 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry) |
128 | dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); | 96 | { |
129 | return_fid = ERR_PTR(-EBADF); | 97 | struct p9_fid *fid; |
98 | struct v9fs_dentry *dent; | ||
99 | |||
100 | dent = dentry->d_fsdata; | ||
101 | fid = v9fs_fid_lookup(dentry); | ||
102 | if (!IS_ERR(fid)) { | ||
103 | spin_lock(&dent->lock); | ||
104 | list_del(&fid->dlist); | ||
105 | spin_unlock(&dent->lock); | ||
130 | } | 106 | } |
131 | 107 | ||
132 | if(down_interruptible(&return_fid->lock)) | 108 | return fid; |
133 | return ERR_PTR(-EINTR); | ||
134 | |||
135 | return return_fid; | ||
136 | } | 109 | } |
137 | 110 | ||
111 | |||
138 | /** | 112 | /** |
139 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and | 113 | * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and |
140 | * release it | 114 | * release it |
141 | * @dentry: dentry to look for fid in | 115 | * @dentry: dentry to look for fid in |
142 | * | 116 | * |
143 | * find a fid in the dentry and then clone to a new private fid | 117 | * find a fid in the dentry and then clone to a new private fid |
@@ -146,49 +120,15 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
146 | * | 120 | * |
147 | */ | 121 | */ |
148 | 122 | ||
149 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry) | 123 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry) |
150 | { | 124 | { |
151 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 125 | struct p9_fid *ofid, *fid; |
152 | struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF); | ||
153 | struct v9fs_fcall *fcall = NULL; | ||
154 | int fid, err; | ||
155 | |||
156 | base_fid = v9fs_fid_lookup(dentry); | ||
157 | |||
158 | if(IS_ERR(base_fid)) | ||
159 | return base_fid; | ||
160 | |||
161 | if(base_fid) { /* clone fid */ | ||
162 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
163 | if (fid < 0) { | ||
164 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
165 | new_fid = ERR_PTR(-ENOSPC); | ||
166 | goto Release_Fid; | ||
167 | } | ||
168 | |||
169 | err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall); | ||
170 | if (err < 0) { | ||
171 | dprintk(DEBUG_ERROR, "clone walk didn't work\n"); | ||
172 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
173 | new_fid = ERR_PTR(err); | ||
174 | goto Free_Fcall; | ||
175 | } | ||
176 | new_fid = v9fs_fid_create(v9ses, fid); | ||
177 | if (new_fid == NULL) { | ||
178 | dprintk(DEBUG_ERROR, "out of memory\n"); | ||
179 | new_fid = ERR_PTR(-ENOMEM); | ||
180 | } | ||
181 | Free_Fcall: | ||
182 | kfree(fcall); | ||
183 | } | ||
184 | 126 | ||
185 | Release_Fid: | 127 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
186 | up(&base_fid->lock); | 128 | ofid = v9fs_fid_lookup(dentry); |
187 | return new_fid; | 129 | if (IS_ERR(ofid)) |
188 | } | 130 | return ofid; |
189 | 131 | ||
190 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid) | 132 | fid = p9_client_walk(ofid, 0, NULL, 1); |
191 | { | 133 | return fid; |
192 | v9fs_t_clunk(v9ses, fid->fid); | ||
193 | v9fs_fid_destroy(fid); | ||
194 | } | 134 | } |
diff --git a/fs/9p/fid.h b/fs/9p/fid.h index 48fc170c26c..47a0ba74287 100644 --- a/fs/9p/fid.h +++ b/fs/9p/fid.h | |||
@@ -22,41 +22,12 @@ | |||
22 | 22 | ||
23 | #include <linux/list.h> | 23 | #include <linux/list.h> |
24 | 24 | ||
25 | #define FID_OP 0 | 25 | struct v9fs_dentry { |
26 | #define FID_WALK 1 | 26 | spinlock_t lock; /* protect fidlist */ |
27 | #define FID_CREATE 2 | 27 | struct list_head fidlist; |
28 | |||
29 | struct v9fs_fid { | ||
30 | struct list_head list; /* list of fids associated with a dentry */ | ||
31 | struct list_head active; /* XXX - debug */ | ||
32 | |||
33 | struct semaphore lock; | ||
34 | |||
35 | u32 fid; | ||
36 | unsigned char fidopen; /* set when fid is opened */ | ||
37 | unsigned char fidclunked; /* set when fid has already been clunked */ | ||
38 | |||
39 | struct v9fs_qid qid; | ||
40 | u32 iounit; | ||
41 | |||
42 | /* readdir stuff */ | ||
43 | int rdir_fpos; | ||
44 | loff_t rdir_pos; | ||
45 | struct v9fs_fcall *rdir_fcall; | ||
46 | |||
47 | /* management stuff */ | ||
48 | uid_t uid; /* user associated with this fid */ | ||
49 | |||
50 | /* private data */ | ||
51 | struct file *filp; /* backpointer to File struct for open files */ | ||
52 | struct v9fs_session_info *v9ses; /* session info for this FID */ | ||
53 | }; | 28 | }; |
54 | 29 | ||
55 | struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry); | 30 | struct p9_fid *v9fs_fid_lookup(struct dentry *dentry); |
56 | struct v9fs_fid *v9fs_fid_get_created(struct dentry *); | 31 | struct p9_fid *v9fs_fid_lookup_remove(struct dentry *dentry); |
57 | void v9fs_fid_destroy(struct v9fs_fid *fid); | 32 | struct p9_fid *v9fs_fid_clone(struct dentry *dentry); |
58 | struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); | 33 | int v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid); |
59 | int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); | ||
60 | struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry); | ||
61 | void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid); | ||
62 | |||
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c deleted file mode 100644 index 34d43355beb..00000000000 --- a/fs/9p/trans_fd.c +++ /dev/null | |||
@@ -1,308 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/trans_fd.c | ||
3 | * | ||
4 | * Fd transport layer. Includes deprecated socket layer. | ||
5 | * | ||
6 | * Copyright (C) 2006 by Russ Cox <rsc@swtch.com> | ||
7 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
8 | * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com> | ||
9 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 | ||
13 | * as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to: | ||
22 | * Free Software Foundation | ||
23 | * 51 Franklin Street, Fifth Floor | ||
24 | * Boston, MA 02111-1301 USA | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/in.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/net.h> | ||
31 | #include <linux/ipv6.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/un.h> | ||
35 | #include <asm/uaccess.h> | ||
36 | #include <linux/inet.h> | ||
37 | #include <linux/idr.h> | ||
38 | #include <linux/file.h> | ||
39 | |||
40 | #include "debug.h" | ||
41 | #include "v9fs.h" | ||
42 | #include "transport.h" | ||
43 | |||
44 | #define V9FS_PORT 564 | ||
45 | |||
46 | struct v9fs_trans_fd { | ||
47 | struct file *rd; | ||
48 | struct file *wr; | ||
49 | }; | ||
50 | |||
51 | /** | ||
52 | * v9fs_fd_read- read from a fd | ||
53 | * @v9ses: session information | ||
54 | * @v: buffer to receive data into | ||
55 | * @len: size of receive buffer | ||
56 | * | ||
57 | */ | ||
58 | static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len) | ||
59 | { | ||
60 | int ret; | ||
61 | struct v9fs_trans_fd *ts; | ||
62 | |||
63 | if (!trans || trans->status == Disconnected || !(ts = trans->priv)) | ||
64 | return -EREMOTEIO; | ||
65 | |||
66 | if (!(ts->rd->f_flags & O_NONBLOCK)) | ||
67 | dprintk(DEBUG_ERROR, "blocking read ...\n"); | ||
68 | |||
69 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | ||
70 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
71 | trans->status = Disconnected; | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * v9fs_fd_write - write to a socket | ||
77 | * @v9ses: session information | ||
78 | * @v: buffer to send data from | ||
79 | * @len: size of send buffer | ||
80 | * | ||
81 | */ | ||
82 | static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len) | ||
83 | { | ||
84 | int ret; | ||
85 | mm_segment_t oldfs; | ||
86 | struct v9fs_trans_fd *ts; | ||
87 | |||
88 | if (!trans || trans->status == Disconnected || !(ts = trans->priv)) | ||
89 | return -EREMOTEIO; | ||
90 | |||
91 | if (!(ts->wr->f_flags & O_NONBLOCK)) | ||
92 | dprintk(DEBUG_ERROR, "blocking write ...\n"); | ||
93 | |||
94 | oldfs = get_fs(); | ||
95 | set_fs(get_ds()); | ||
96 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
97 | ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); | ||
98 | set_fs(oldfs); | ||
99 | |||
100 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
101 | trans->status = Disconnected; | ||
102 | return ret; | ||
103 | } | ||
104 | |||
105 | static unsigned int | ||
106 | v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) | ||
107 | { | ||
108 | int ret, n; | ||
109 | struct v9fs_trans_fd *ts; | ||
110 | mm_segment_t oldfs; | ||
111 | |||
112 | if (!trans || trans->status != Connected || !(ts = trans->priv)) | ||
113 | return -EREMOTEIO; | ||
114 | |||
115 | if (!ts->rd->f_op || !ts->rd->f_op->poll) | ||
116 | return -EIO; | ||
117 | |||
118 | if (!ts->wr->f_op || !ts->wr->f_op->poll) | ||
119 | return -EIO; | ||
120 | |||
121 | oldfs = get_fs(); | ||
122 | set_fs(get_ds()); | ||
123 | |||
124 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
125 | if (ret < 0) | ||
126 | goto end; | ||
127 | |||
128 | if (ts->rd != ts->wr) { | ||
129 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
130 | if (n < 0) { | ||
131 | ret = n; | ||
132 | goto end; | ||
133 | } | ||
134 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); | ||
135 | } | ||
136 | |||
137 | end: | ||
138 | set_fs(oldfs); | ||
139 | return ret; | ||
140 | } | ||
141 | |||
142 | static int v9fs_fd_open(struct v9fs_session_info *v9ses, int rfd, int wfd) | ||
143 | { | ||
144 | struct v9fs_transport *trans = v9ses->transport; | ||
145 | struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd), | ||
146 | GFP_KERNEL); | ||
147 | if (!ts) | ||
148 | return -ENOMEM; | ||
149 | |||
150 | ts->rd = fget(rfd); | ||
151 | ts->wr = fget(wfd); | ||
152 | if (!ts->rd || !ts->wr) { | ||
153 | if (ts->rd) | ||
154 | fput(ts->rd); | ||
155 | if (ts->wr) | ||
156 | fput(ts->wr); | ||
157 | kfree(ts); | ||
158 | return -EIO; | ||
159 | } | ||
160 | |||
161 | trans->priv = ts; | ||
162 | trans->status = Connected; | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static int v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, | ||
168 | char *data) | ||
169 | { | ||
170 | if (v9ses->rfdno == ~0 || v9ses->wfdno == ~0) { | ||
171 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); | ||
172 | return -ENOPROTOOPT; | ||
173 | } | ||
174 | |||
175 | return v9fs_fd_open(v9ses, v9ses->rfdno, v9ses->wfdno); | ||
176 | } | ||
177 | |||
178 | static int v9fs_socket_open(struct v9fs_session_info *v9ses, | ||
179 | struct socket *csocket) | ||
180 | { | ||
181 | int fd, ret; | ||
182 | |||
183 | csocket->sk->sk_allocation = GFP_NOIO; | ||
184 | if ((fd = sock_map_fd(csocket)) < 0) { | ||
185 | eprintk(KERN_ERR, "v9fs_socket_open: failed to map fd\n"); | ||
186 | ret = fd; | ||
187 | release_csocket: | ||
188 | sock_release(csocket); | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) { | ||
193 | sockfd_put(csocket); | ||
194 | eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n"); | ||
195 | goto release_csocket; | ||
196 | } | ||
197 | |||
198 | ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |= | ||
199 | O_NONBLOCK; | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, | ||
204 | char *data) | ||
205 | { | ||
206 | int ret; | ||
207 | struct socket *csocket = NULL; | ||
208 | struct sockaddr_in sin_server; | ||
209 | |||
210 | sin_server.sin_family = AF_INET; | ||
211 | sin_server.sin_addr.s_addr = in_aton(addr); | ||
212 | sin_server.sin_port = htons(v9ses->port); | ||
213 | sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); | ||
214 | |||
215 | if (!csocket) { | ||
216 | eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n"); | ||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | ret = csocket->ops->connect(csocket, | ||
221 | (struct sockaddr *)&sin_server, | ||
222 | sizeof(struct sockaddr_in), 0); | ||
223 | if (ret < 0) { | ||
224 | eprintk(KERN_ERR, | ||
225 | "v9fs_trans_tcp: problem connecting socket to %s\n", | ||
226 | addr); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | return v9fs_socket_open(v9ses, csocket); | ||
231 | } | ||
232 | |||
233 | static int | ||
234 | v9fs_unix_init(struct v9fs_session_info *v9ses, const char *addr, char *data) | ||
235 | { | ||
236 | int ret; | ||
237 | struct socket *csocket; | ||
238 | struct sockaddr_un sun_server; | ||
239 | |||
240 | if (strlen(addr) > UNIX_PATH_MAX) { | ||
241 | eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n", | ||
242 | addr); | ||
243 | return -ENAMETOOLONG; | ||
244 | } | ||
245 | |||
246 | sun_server.sun_family = PF_UNIX; | ||
247 | strcpy(sun_server.sun_path, addr); | ||
248 | sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); | ||
249 | ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, | ||
250 | sizeof(struct sockaddr_un) - 1, 0); | ||
251 | if (ret < 0) { | ||
252 | eprintk(KERN_ERR, | ||
253 | "v9fs_trans_unix: problem connecting socket: %s: %d\n", | ||
254 | addr, ret); | ||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | return v9fs_socket_open(v9ses, csocket); | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * v9fs_sock_close - shutdown socket | ||
263 | * @trans: private socket structure | ||
264 | * | ||
265 | */ | ||
266 | static void v9fs_fd_close(struct v9fs_transport *trans) | ||
267 | { | ||
268 | struct v9fs_trans_fd *ts; | ||
269 | |||
270 | if (!trans) | ||
271 | return; | ||
272 | |||
273 | ts = xchg(&trans->priv, NULL); | ||
274 | |||
275 | if (!ts) | ||
276 | return; | ||
277 | |||
278 | trans->status = Disconnected; | ||
279 | if (ts->rd) | ||
280 | fput(ts->rd); | ||
281 | if (ts->wr) | ||
282 | fput(ts->wr); | ||
283 | kfree(ts); | ||
284 | } | ||
285 | |||
286 | struct v9fs_transport v9fs_trans_fd = { | ||
287 | .init = v9fs_fd_init, | ||
288 | .write = v9fs_fd_write, | ||
289 | .read = v9fs_fd_read, | ||
290 | .close = v9fs_fd_close, | ||
291 | .poll = v9fs_fd_poll, | ||
292 | }; | ||
293 | |||
294 | struct v9fs_transport v9fs_trans_tcp = { | ||
295 | .init = v9fs_tcp_init, | ||
296 | .write = v9fs_fd_write, | ||
297 | .read = v9fs_fd_read, | ||
298 | .close = v9fs_fd_close, | ||
299 | .poll = v9fs_fd_poll, | ||
300 | }; | ||
301 | |||
302 | struct v9fs_transport v9fs_trans_unix = { | ||
303 | .init = v9fs_unix_init, | ||
304 | .write = v9fs_fd_write, | ||
305 | .read = v9fs_fd_read, | ||
306 | .close = v9fs_fd_close, | ||
307 | .poll = v9fs_fd_poll, | ||
308 | }; | ||
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 6ad6f192b6e..45c35986d49 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -29,16 +29,12 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
32 | 32 | #include <net/9p/9p.h> | |
33 | #include "debug.h" | 33 | #include <net/9p/transport.h> |
34 | #include <net/9p/conn.h> | ||
35 | #include <net/9p/client.h> | ||
34 | #include "v9fs.h" | 36 | #include "v9fs.h" |
35 | #include "9p.h" | ||
36 | #include "v9fs_vfs.h" | 37 | #include "v9fs_vfs.h" |
37 | #include "transport.h" | ||
38 | #include "mux.h" | ||
39 | |||
40 | /* TODO: sysfs or debugfs interface */ | ||
41 | int v9fs_debug_level = 0; /* feature-rific global debug level */ | ||
42 | 38 | ||
43 | /* | 39 | /* |
44 | * Option Parsing (code inspired by NFS code) | 40 | * Option Parsing (code inspired by NFS code) |
@@ -47,12 +43,12 @@ int v9fs_debug_level = 0; /* feature-rific global debug level */ | |||
47 | 43 | ||
48 | enum { | 44 | enum { |
49 | /* Options that take integer arguments */ | 45 | /* Options that take integer arguments */ |
50 | Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, | 46 | Opt_debug, Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, |
51 | Opt_rfdno, Opt_wfdno, | 47 | Opt_rfdno, Opt_wfdno, |
52 | /* String options */ | 48 | /* String options */ |
53 | Opt_uname, Opt_remotename, | 49 | Opt_uname, Opt_remotename, |
54 | /* Options that take no arguments */ | 50 | /* Options that take no arguments */ |
55 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, | 51 | Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, Opt_pci, |
56 | /* Cache options */ | 52 | /* Cache options */ |
57 | Opt_cache_loose, | 53 | Opt_cache_loose, |
58 | /* Error token */ | 54 | /* Error token */ |
@@ -60,6 +56,7 @@ enum { | |||
60 | }; | 56 | }; |
61 | 57 | ||
62 | static match_table_t tokens = { | 58 | static match_table_t tokens = { |
59 | {Opt_debug, "debug=%x"}, | ||
63 | {Opt_port, "port=%u"}, | 60 | {Opt_port, "port=%u"}, |
64 | {Opt_msize, "msize=%u"}, | 61 | {Opt_msize, "msize=%u"}, |
65 | {Opt_uid, "uid=%u"}, | 62 | {Opt_uid, "uid=%u"}, |
@@ -67,12 +64,14 @@ static match_table_t tokens = { | |||
67 | {Opt_afid, "afid=%u"}, | 64 | {Opt_afid, "afid=%u"}, |
68 | {Opt_rfdno, "rfdno=%u"}, | 65 | {Opt_rfdno, "rfdno=%u"}, |
69 | {Opt_wfdno, "wfdno=%u"}, | 66 | {Opt_wfdno, "wfdno=%u"}, |
70 | {Opt_debug, "debug=%x"}, | ||
71 | {Opt_uname, "uname=%s"}, | 67 | {Opt_uname, "uname=%s"}, |
72 | {Opt_remotename, "aname=%s"}, | 68 | {Opt_remotename, "aname=%s"}, |
73 | {Opt_unix, "proto=unix"}, | 69 | {Opt_unix, "proto=unix"}, |
74 | {Opt_tcp, "proto=tcp"}, | 70 | {Opt_tcp, "proto=tcp"}, |
75 | {Opt_fd, "proto=fd"}, | 71 | {Opt_fd, "proto=fd"}, |
72 | #ifdef CONFIG_PCI_9P | ||
73 | {Opt_pci, "proto=pci"}, | ||
74 | #endif | ||
76 | {Opt_tcp, "tcp"}, | 75 | {Opt_tcp, "tcp"}, |
77 | {Opt_unix, "unix"}, | 76 | {Opt_unix, "unix"}, |
78 | {Opt_fd, "fd"}, | 77 | {Opt_fd, "fd"}, |
@@ -83,6 +82,8 @@ static match_table_t tokens = { | |||
83 | {Opt_err, NULL} | 82 | {Opt_err, NULL} |
84 | }; | 83 | }; |
85 | 84 | ||
85 | extern struct p9_transport *p9pci_trans_create(void); | ||
86 | |||
86 | /* | 87 | /* |
87 | * Parse option string. | 88 | * Parse option string. |
88 | */ | 89 | */ |
@@ -122,12 +123,16 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
122 | token = match_token(p, tokens, args); | 123 | token = match_token(p, tokens, args); |
123 | if (token < Opt_uname) { | 124 | if (token < Opt_uname) { |
124 | if ((ret = match_int(&args[0], &option)) < 0) { | 125 | if ((ret = match_int(&args[0], &option)) < 0) { |
125 | dprintk(DEBUG_ERROR, | 126 | P9_DPRINTK(P9_DEBUG_ERROR, |
126 | "integer field, but no integer?\n"); | 127 | "integer field, but no integer?\n"); |
127 | continue; | 128 | continue; |
128 | } | 129 | } |
129 | } | 130 | } |
130 | switch (token) { | 131 | switch (token) { |
132 | case Opt_debug: | ||
133 | v9ses->debug = option; | ||
134 | p9_debug_level = option; | ||
135 | break; | ||
131 | case Opt_port: | 136 | case Opt_port: |
132 | v9ses->port = option; | 137 | v9ses->port = option; |
133 | break; | 138 | break; |
@@ -149,15 +154,15 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
149 | case Opt_wfdno: | 154 | case Opt_wfdno: |
150 | v9ses->wfdno = option; | 155 | v9ses->wfdno = option; |
151 | break; | 156 | break; |
152 | case Opt_debug: | ||
153 | v9ses->debug = option; | ||
154 | break; | ||
155 | case Opt_tcp: | 157 | case Opt_tcp: |
156 | v9ses->proto = PROTO_TCP; | 158 | v9ses->proto = PROTO_TCP; |
157 | break; | 159 | break; |
158 | case Opt_unix: | 160 | case Opt_unix: |
159 | v9ses->proto = PROTO_UNIX; | 161 | v9ses->proto = PROTO_UNIX; |
160 | break; | 162 | break; |
163 | case Opt_pci: | ||
164 | v9ses->proto = PROTO_PCI; | ||
165 | break; | ||
161 | case Opt_fd: | 166 | case Opt_fd: |
162 | v9ses->proto = PROTO_FD; | 167 | v9ses->proto = PROTO_FD; |
163 | break; | 168 | break; |
@@ -183,82 +188,6 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses) | |||
183 | } | 188 | } |
184 | 189 | ||
185 | /** | 190 | /** |
186 | * v9fs_inode2v9ses - safely extract v9fs session info from super block | ||
187 | * @inode: inode to extract information from | ||
188 | * | ||
189 | * Paranoid function to extract v9ses information from superblock, | ||
190 | * if anything is missing it will report an error. | ||
191 | * | ||
192 | */ | ||
193 | |||
194 | struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) | ||
195 | { | ||
196 | return (inode->i_sb->s_fs_info); | ||
197 | } | ||
198 | |||
199 | /** | ||
200 | * v9fs_get_idpool - allocate numeric id from pool | ||
201 | * @p - pool to allocate from | ||
202 | * | ||
203 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
204 | * the lock included in struct idr? | ||
205 | */ | ||
206 | |||
207 | int v9fs_get_idpool(struct v9fs_idpool *p) | ||
208 | { | ||
209 | int i = 0; | ||
210 | int error; | ||
211 | |||
212 | retry: | ||
213 | if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) | ||
214 | return 0; | ||
215 | |||
216 | if (down_interruptible(&p->lock) == -EINTR) { | ||
217 | eprintk(KERN_WARNING, "Interrupted while locking\n"); | ||
218 | return -1; | ||
219 | } | ||
220 | |||
221 | /* no need to store exactly p, we just need something non-null */ | ||
222 | error = idr_get_new(&p->pool, p, &i); | ||
223 | up(&p->lock); | ||
224 | |||
225 | if (error == -EAGAIN) | ||
226 | goto retry; | ||
227 | else if (error) | ||
228 | return -1; | ||
229 | |||
230 | return i; | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * v9fs_put_idpool - release numeric id from pool | ||
235 | * @p - pool to allocate from | ||
236 | * | ||
237 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
238 | * the lock included in struct idr? | ||
239 | */ | ||
240 | |||
241 | void v9fs_put_idpool(int id, struct v9fs_idpool *p) | ||
242 | { | ||
243 | if (down_interruptible(&p->lock) == -EINTR) { | ||
244 | eprintk(KERN_WARNING, "Interrupted while locking\n"); | ||
245 | return; | ||
246 | } | ||
247 | idr_remove(&p->pool, id); | ||
248 | up(&p->lock); | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * v9fs_check_idpool - check if the specified id is available | ||
253 | * @id - id to check | ||
254 | * @p - pool | ||
255 | */ | ||
256 | int v9fs_check_idpool(int id, struct v9fs_idpool *p) | ||
257 | { | ||
258 | return idr_find(&p->pool, id) != NULL; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * v9fs_session_init - initialize session | 191 | * v9fs_session_init - initialize session |
263 | * @v9ses: session information structure | 192 | * @v9ses: session information structure |
264 | * @dev_name: device being mounted | 193 | * @dev_name: device being mounted |
@@ -266,25 +195,21 @@ int v9fs_check_idpool(int id, struct v9fs_idpool *p) | |||
266 | * | 195 | * |
267 | */ | 196 | */ |
268 | 197 | ||
269 | int | 198 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, |
270 | v9fs_session_init(struct v9fs_session_info *v9ses, | ||
271 | const char *dev_name, char *data) | 199 | const char *dev_name, char *data) |
272 | { | 200 | { |
273 | struct v9fs_fcall *fcall = NULL; | ||
274 | struct v9fs_transport *trans_proto; | ||
275 | int n = 0; | ||
276 | int newfid = -1; | ||
277 | int retval = -EINVAL; | 201 | int retval = -EINVAL; |
278 | struct v9fs_str *version; | 202 | struct p9_transport *trans; |
203 | struct p9_fid *fid; | ||
279 | 204 | ||
280 | v9ses->name = __getname(); | 205 | v9ses->name = __getname(); |
281 | if (!v9ses->name) | 206 | if (!v9ses->name) |
282 | return -ENOMEM; | 207 | return ERR_PTR(-ENOMEM); |
283 | 208 | ||
284 | v9ses->remotename = __getname(); | 209 | v9ses->remotename = __getname(); |
285 | if (!v9ses->remotename) { | 210 | if (!v9ses->remotename) { |
286 | __putname(v9ses->name); | 211 | __putname(v9ses->name); |
287 | return -ENOMEM; | 212 | return ERR_PTR(-ENOMEM); |
288 | } | 213 | } |
289 | 214 | ||
290 | strcpy(v9ses->name, V9FS_DEFUSER); | 215 | strcpy(v9ses->name, V9FS_DEFUSER); |
@@ -292,130 +217,60 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
292 | 217 | ||
293 | v9fs_parse_options(data, v9ses); | 218 | v9fs_parse_options(data, v9ses); |
294 | 219 | ||
295 | /* set global debug level */ | ||
296 | v9fs_debug_level = v9ses->debug; | ||
297 | |||
298 | /* id pools that are session-dependent: fids and tags */ | ||
299 | idr_init(&v9ses->fidpool.pool); | ||
300 | init_MUTEX(&v9ses->fidpool.lock); | ||
301 | |||
302 | switch (v9ses->proto) { | 220 | switch (v9ses->proto) { |
303 | case PROTO_TCP: | 221 | case PROTO_TCP: |
304 | trans_proto = &v9fs_trans_tcp; | 222 | trans = p9_trans_create_tcp(dev_name, v9ses->port); |
305 | break; | 223 | break; |
306 | case PROTO_UNIX: | 224 | case PROTO_UNIX: |
307 | trans_proto = &v9fs_trans_unix; | 225 | trans = p9_trans_create_unix(dev_name); |
308 | *v9ses->remotename = 0; | 226 | *v9ses->remotename = 0; |
309 | break; | 227 | break; |
310 | case PROTO_FD: | 228 | case PROTO_FD: |
311 | trans_proto = &v9fs_trans_fd; | 229 | trans = p9_trans_create_fd(v9ses->rfdno, v9ses->wfdno); |
312 | *v9ses->remotename = 0; | 230 | *v9ses->remotename = 0; |
313 | break; | 231 | break; |
232 | #ifdef CONFIG_PCI_9P | ||
233 | case PROTO_PCI: | ||
234 | trans = p9pci_trans_create(); | ||
235 | *v9ses->remotename = 0; | ||
236 | break; | ||
237 | #endif | ||
314 | default: | 238 | default: |
315 | printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); | 239 | printk(KERN_ERR "v9fs: Bad mount protocol %d\n", v9ses->proto); |
316 | retval = -ENOPROTOOPT; | 240 | retval = -ENOPROTOOPT; |
317 | goto SessCleanUp; | 241 | goto error; |
318 | }; | 242 | }; |
319 | 243 | ||
320 | v9ses->transport = kmalloc(sizeof(*v9ses->transport), GFP_KERNEL); | 244 | if (IS_ERR(trans)) { |
321 | if (!v9ses->transport) { | 245 | retval = PTR_ERR(trans); |
322 | retval = -ENOMEM; | 246 | trans = NULL; |
323 | goto SessCleanUp; | 247 | goto error; |
324 | } | 248 | } |
325 | 249 | ||
326 | memmove(v9ses->transport, trans_proto, sizeof(*v9ses->transport)); | 250 | v9ses->clnt = p9_client_create(trans, v9ses->maxdata + P9_IOHDRSZ, |
251 | v9ses->extended); | ||
327 | 252 | ||
328 | if ((retval = v9ses->transport->init(v9ses, dev_name, data)) < 0) { | 253 | if (IS_ERR(v9ses->clnt)) { |
329 | eprintk(KERN_ERR, "problem initializing transport\n"); | 254 | retval = PTR_ERR(v9ses->clnt); |
330 | goto SessCleanUp; | 255 | v9ses->clnt = NULL; |
256 | P9_DPRINTK(P9_DEBUG_ERROR, "problem initializing 9p client\n"); | ||
257 | goto error; | ||
331 | } | 258 | } |
332 | 259 | ||
333 | v9ses->inprogress = 0; | 260 | fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, |
334 | v9ses->shutdown = 0; | 261 | v9ses->remotename); |
335 | v9ses->session_hung = 0; | 262 | if (IS_ERR(fid)) { |
336 | 263 | retval = PTR_ERR(fid); | |
337 | v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ, | 264 | fid = NULL; |
338 | &v9ses->extended); | 265 | P9_DPRINTK(P9_DEBUG_ERROR, "cannot attach\n"); |
339 | 266 | goto error; | |
340 | if (IS_ERR(v9ses->mux)) { | ||
341 | retval = PTR_ERR(v9ses->mux); | ||
342 | v9ses->mux = NULL; | ||
343 | dprintk(DEBUG_ERROR, "problem initializing mux\n"); | ||
344 | goto SessCleanUp; | ||
345 | } | 267 | } |
346 | 268 | ||
347 | if (v9ses->afid == ~0) { | 269 | return fid; |
348 | if (v9ses->extended) | ||
349 | retval = | ||
350 | v9fs_t_version(v9ses, v9ses->maxdata, "9P2000.u", | ||
351 | &fcall); | ||
352 | else | ||
353 | retval = v9fs_t_version(v9ses, v9ses->maxdata, "9P2000", | ||
354 | &fcall); | ||
355 | |||
356 | if (retval < 0) { | ||
357 | dprintk(DEBUG_ERROR, "v9fs_t_version failed\n"); | ||
358 | goto FreeFcall; | ||
359 | } | ||
360 | |||
361 | version = &fcall->params.rversion.version; | ||
362 | if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) { | ||
363 | dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n"); | ||
364 | v9ses->extended = 1; | ||
365 | } else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) { | ||
366 | dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n"); | ||
367 | v9ses->extended = 0; | ||
368 | } else { | ||
369 | retval = -EREMOTEIO; | ||
370 | goto FreeFcall; | ||
371 | } | ||
372 | 270 | ||
373 | n = fcall->params.rversion.msize; | 271 | error: |
374 | kfree(fcall); | ||
375 | |||
376 | if (n < v9ses->maxdata) | ||
377 | v9ses->maxdata = n; | ||
378 | } | ||
379 | |||
380 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
381 | if (newfid < 0) { | ||
382 | eprintk(KERN_WARNING, "couldn't allocate FID\n"); | ||
383 | retval = -ENOMEM; | ||
384 | goto SessCleanUp; | ||
385 | } | ||
386 | /* it is a little bit ugly, but we have to prevent newfid */ | ||
387 | /* being the same as afid, so if it is, get a new fid */ | ||
388 | if (v9ses->afid != ~0 && newfid == v9ses->afid) { | ||
389 | newfid = v9fs_get_idpool(&v9ses->fidpool); | ||
390 | if (newfid < 0) { | ||
391 | eprintk(KERN_WARNING, "couldn't allocate FID\n"); | ||
392 | retval = -ENOMEM; | ||
393 | goto SessCleanUp; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | if ((retval = | ||
398 | v9fs_t_attach(v9ses, v9ses->name, v9ses->remotename, newfid, | ||
399 | v9ses->afid, NULL)) | ||
400 | < 0) { | ||
401 | dprintk(DEBUG_ERROR, "cannot attach\n"); | ||
402 | goto SessCleanUp; | ||
403 | } | ||
404 | |||
405 | if (v9ses->afid != ~0) { | ||
406 | dprintk(DEBUG_ERROR, "afid not equal to ~0\n"); | ||
407 | if (v9fs_t_clunk(v9ses, v9ses->afid)) | ||
408 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
409 | } | ||
410 | |||
411 | return newfid; | ||
412 | |||
413 | FreeFcall: | ||
414 | kfree(fcall); | ||
415 | |||
416 | SessCleanUp: | ||
417 | v9fs_session_close(v9ses); | 272 | v9fs_session_close(v9ses); |
418 | return retval; | 273 | return ERR_PTR(retval); |
419 | } | 274 | } |
420 | 275 | ||
421 | /** | 276 | /** |
@@ -426,15 +281,9 @@ v9fs_session_init(struct v9fs_session_info *v9ses, | |||
426 | 281 | ||
427 | void v9fs_session_close(struct v9fs_session_info *v9ses) | 282 | void v9fs_session_close(struct v9fs_session_info *v9ses) |
428 | { | 283 | { |
429 | if (v9ses->mux) { | 284 | if (v9ses->clnt) { |
430 | v9fs_mux_destroy(v9ses->mux); | 285 | p9_client_destroy(v9ses->clnt); |
431 | v9ses->mux = NULL; | 286 | v9ses->clnt = NULL; |
432 | } | ||
433 | |||
434 | if (v9ses->transport) { | ||
435 | v9ses->transport->close(v9ses->transport); | ||
436 | kfree(v9ses->transport); | ||
437 | v9ses->transport = NULL; | ||
438 | } | 287 | } |
439 | 288 | ||
440 | __putname(v9ses->name); | 289 | __putname(v9ses->name); |
@@ -446,9 +295,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
446 | * and cancel all pending requests. | 295 | * and cancel all pending requests. |
447 | */ | 296 | */ |
448 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { | 297 | void v9fs_session_cancel(struct v9fs_session_info *v9ses) { |
449 | dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses); | 298 | P9_DPRINTK(P9_DEBUG_ERROR, "cancel session %p\n", v9ses); |
450 | v9ses->transport->status = Disconnected; | 299 | p9_client_disconnect(v9ses->clnt); |
451 | v9fs_mux_cancel(v9ses->mux, -EIO); | ||
452 | } | 300 | } |
453 | 301 | ||
454 | extern int v9fs_error_init(void); | 302 | extern int v9fs_error_init(void); |
@@ -460,24 +308,9 @@ extern int v9fs_error_init(void); | |||
460 | 308 | ||
461 | static int __init init_v9fs(void) | 309 | static int __init init_v9fs(void) |
462 | { | 310 | { |
463 | int ret; | ||
464 | |||
465 | v9fs_error_init(); | ||
466 | |||
467 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); | 311 | printk(KERN_INFO "Installing v9fs 9p2000 file system support\n"); |
468 | 312 | ||
469 | ret = v9fs_mux_global_init(); | 313 | return register_filesystem(&v9fs_fs_type); |
470 | if (ret) { | ||
471 | printk(KERN_WARNING "v9fs: starting mux failed\n"); | ||
472 | return ret; | ||
473 | } | ||
474 | ret = register_filesystem(&v9fs_fs_type); | ||
475 | if (ret) { | ||
476 | printk(KERN_WARNING "v9fs: registering file system failed\n"); | ||
477 | v9fs_mux_global_exit(); | ||
478 | } | ||
479 | |||
480 | return ret; | ||
481 | } | 314 | } |
482 | 315 | ||
483 | /** | 316 | /** |
@@ -487,13 +320,13 @@ static int __init init_v9fs(void) | |||
487 | 320 | ||
488 | static void __exit exit_v9fs(void) | 321 | static void __exit exit_v9fs(void) |
489 | { | 322 | { |
490 | v9fs_mux_global_exit(); | ||
491 | unregister_filesystem(&v9fs_fs_type); | 323 | unregister_filesystem(&v9fs_fs_type); |
492 | } | 324 | } |
493 | 325 | ||
494 | module_init(init_v9fs) | 326 | module_init(init_v9fs) |
495 | module_exit(exit_v9fs) | 327 | module_exit(exit_v9fs) |
496 | 328 | ||
329 | MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); | ||
497 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); | 330 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); |
498 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); | 331 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); |
499 | MODULE_LICENSE("GPL"); | 332 | MODULE_LICENSE("GPL"); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index 820bf5ca35d..abc4b1668ac 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -22,16 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * Idpool structure provides lock and id management | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | struct v9fs_idpool { | ||
30 | struct semaphore lock; | ||
31 | struct idr pool; | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * Session structure provides information for an opened session | 25 | * Session structure provides information for an opened session |
36 | * | 26 | * |
37 | */ | 27 | */ |
@@ -54,15 +44,7 @@ struct v9fs_session_info { | |||
54 | unsigned int uid; /* default uid/muid for legacy support */ | 44 | unsigned int uid; /* default uid/muid for legacy support */ |
55 | unsigned int gid; /* default gid for legacy support */ | 45 | unsigned int gid; /* default gid for legacy support */ |
56 | 46 | ||
57 | /* book keeping */ | 47 | struct p9_client *clnt; /* 9p client */ |
58 | struct v9fs_idpool fidpool; /* The FID pool for file descriptors */ | ||
59 | |||
60 | struct v9fs_transport *transport; | ||
61 | struct v9fs_mux_data *mux; | ||
62 | |||
63 | int inprogress; /* session in progress => true */ | ||
64 | int shutdown; /* session shutting down. no more attaches. */ | ||
65 | unsigned char session_hung; | ||
66 | struct dentry *debugfs_dir; | 48 | struct dentry *debugfs_dir; |
67 | }; | 49 | }; |
68 | 50 | ||
@@ -71,6 +53,7 @@ enum { | |||
71 | PROTO_TCP, | 53 | PROTO_TCP, |
72 | PROTO_UNIX, | 54 | PROTO_UNIX, |
73 | PROTO_FD, | 55 | PROTO_FD, |
56 | PROTO_PCI, | ||
74 | }; | 57 | }; |
75 | 58 | ||
76 | /* possible values of ->cache */ | 59 | /* possible values of ->cache */ |
@@ -82,12 +65,9 @@ enum { | |||
82 | 65 | ||
83 | extern struct dentry *v9fs_debugfs_root; | 66 | extern struct dentry *v9fs_debugfs_root; |
84 | 67 | ||
85 | int v9fs_session_init(struct v9fs_session_info *, const char *, char *); | 68 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
86 | struct v9fs_session_info *v9fs_inode2v9ses(struct inode *); | 69 | char *); |
87 | void v9fs_session_close(struct v9fs_session_info *v9ses); | 70 | void v9fs_session_close(struct v9fs_session_info *v9ses); |
88 | int v9fs_get_idpool(struct v9fs_idpool *p); | ||
89 | void v9fs_put_idpool(int id, struct v9fs_idpool *p); | ||
90 | int v9fs_check_idpool(int id, struct v9fs_idpool *p); | ||
91 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); | 71 | void v9fs_session_cancel(struct v9fs_session_info *v9ses); |
92 | 72 | ||
93 | #define V9FS_MAGIC 0x01021997 | 73 | #define V9FS_MAGIC 0x01021997 |
@@ -97,3 +77,7 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses); | |||
97 | #define V9FS_DEFUSER "nobody" | 77 | #define V9FS_DEFUSER "nobody" |
98 | #define V9FS_DEFANAME "" | 78 | #define V9FS_DEFANAME "" |
99 | 79 | ||
80 | static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode) | ||
81 | { | ||
82 | return (inode->i_sb->s_fs_info); | ||
83 | } | ||
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 6a82d39dc49..fd01d90cada 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -45,10 +45,10 @@ extern struct dentry_operations v9fs_dentry_operations; | |||
45 | extern struct dentry_operations v9fs_cached_dentry_operations; | 45 | extern struct dentry_operations v9fs_cached_dentry_operations; |
46 | 46 | ||
47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); | 47 | struct inode *v9fs_get_inode(struct super_block *sb, int mode); |
48 | ino_t v9fs_qid2ino(struct v9fs_qid *qid); | 48 | ino_t v9fs_qid2ino(struct p9_qid *qid); |
49 | void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *); | 49 | void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *); |
50 | int v9fs_dir_release(struct inode *inode, struct file *filp); | 50 | int v9fs_dir_release(struct inode *inode, struct file *filp); |
51 | int v9fs_file_open(struct inode *inode, struct file *file); | 51 | int v9fs_file_open(struct inode *inode, struct file *file); |
52 | void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat); | 52 | void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat); |
53 | void v9fs_dentry_release(struct dentry *); | 53 | void v9fs_dentry_release(struct dentry *); |
54 | int v9fs_uflags2omode(int uflags); | 54 | int v9fs_uflags2omode(int uflags); |
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 9ac4ffe9ac7..6248f0e727a 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
@@ -33,10 +33,10 @@ | |||
33 | #include <linux/pagemap.h> | 33 | #include <linux/pagemap.h> |
34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <net/9p/9p.h> | ||
37 | #include <net/9p/client.h> | ||
36 | 38 | ||
37 | #include "debug.h" | ||
38 | #include "v9fs.h" | 39 | #include "v9fs.h" |
39 | #include "9p.h" | ||
40 | #include "v9fs_vfs.h" | 40 | #include "v9fs_vfs.h" |
41 | #include "fid.h" | 41 | #include "fid.h" |
42 | 42 | ||
@@ -50,55 +50,26 @@ | |||
50 | 50 | ||
51 | static int v9fs_vfs_readpage(struct file *filp, struct page *page) | 51 | static int v9fs_vfs_readpage(struct file *filp, struct page *page) |
52 | { | 52 | { |
53 | char *buffer = NULL; | 53 | int retval; |
54 | int retval = -EIO; | 54 | loff_t offset; |
55 | loff_t offset = page_offset(page); | 55 | char *buffer; |
56 | int count = PAGE_CACHE_SIZE; | 56 | struct p9_fid *fid; |
57 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
58 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||
59 | int rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
60 | struct v9fs_fid *v9f = filp->private_data; | ||
61 | struct v9fs_fcall *fcall = NULL; | ||
62 | int fid = v9f->fid; | ||
63 | int total = 0; | ||
64 | int result = 0; | ||
65 | |||
66 | dprintk(DEBUG_VFS, "\n"); | ||
67 | 57 | ||
58 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | ||
59 | fid = filp->private_data; | ||
68 | buffer = kmap(page); | 60 | buffer = kmap(page); |
69 | do { | 61 | offset = page_offset(page); |
70 | if (count < rsize) | ||
71 | rsize = count; | ||
72 | |||
73 | result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall); | ||
74 | |||
75 | if (result < 0) { | ||
76 | printk(KERN_ERR "v9fs_t_read returned %d\n", | ||
77 | result); | ||
78 | |||
79 | kfree(fcall); | ||
80 | goto UnmapAndUnlock; | ||
81 | } else | ||
82 | offset += result; | ||
83 | |||
84 | memcpy(buffer, fcall->params.rread.data, result); | ||
85 | |||
86 | count -= result; | ||
87 | buffer += result; | ||
88 | total += result; | ||
89 | |||
90 | kfree(fcall); | ||
91 | 62 | ||
92 | if (result < rsize) | 63 | retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE); |
93 | break; | 64 | if (retval < 0) |
94 | } while (count); | 65 | goto done; |
95 | 66 | ||
96 | memset(buffer, 0, count); | 67 | memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); |
97 | flush_dcache_page(page); | 68 | flush_dcache_page(page); |
98 | SetPageUptodate(page); | 69 | SetPageUptodate(page); |
99 | retval = 0; | 70 | retval = 0; |
100 | 71 | ||
101 | UnmapAndUnlock: | 72 | done: |
102 | kunmap(page); | 73 | kunmap(page); |
103 | unlock_page(page); | 74 | unlock_page(page); |
104 | return retval; | 75 | return retval; |
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c index d93960429c0..f9534f18df0 100644 --- a/fs/9p/vfs_dentry.c +++ b/fs/9p/vfs_dentry.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <net/9p/9p.h> | ||
38 | #include <net/9p/client.h> | ||
37 | 39 | ||
38 | #include "debug.h" | ||
39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
40 | #include "9p.h" | ||
41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
42 | #include "fid.h" | 42 | #include "fid.h" |
43 | 43 | ||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | static int v9fs_dentry_delete(struct dentry *dentry) | 53 | static int v9fs_dentry_delete(struct dentry *dentry) |
54 | { | 54 | { |
55 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 55 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
56 | 56 | ||
57 | return 1; | 57 | return 1; |
58 | } | 58 | } |
@@ -69,7 +69,7 @@ static int v9fs_dentry_delete(struct dentry *dentry) | |||
69 | static int v9fs_cached_dentry_delete(struct dentry *dentry) | 69 | static int v9fs_cached_dentry_delete(struct dentry *dentry) |
70 | { | 70 | { |
71 | struct inode *inode = dentry->d_inode; | 71 | struct inode *inode = dentry->d_inode; |
72 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 72 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
73 | 73 | ||
74 | if(!inode) | 74 | if(!inode) |
75 | return 1; | 75 | return 1; |
@@ -85,26 +85,19 @@ static int v9fs_cached_dentry_delete(struct dentry *dentry) | |||
85 | 85 | ||
86 | void v9fs_dentry_release(struct dentry *dentry) | 86 | void v9fs_dentry_release(struct dentry *dentry) |
87 | { | 87 | { |
88 | int err; | 88 | struct v9fs_dentry *dent; |
89 | 89 | struct p9_fid *temp, *current_fid; | |
90 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 90 | |
91 | 91 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | |
92 | if (dentry->d_fsdata != NULL) { | 92 | dent = dentry->d_fsdata; |
93 | struct list_head *fid_list = dentry->d_fsdata; | 93 | if (dent) { |
94 | struct v9fs_fid *temp = NULL; | 94 | list_for_each_entry_safe(current_fid, temp, &dent->fidlist, |
95 | struct v9fs_fid *current_fid = NULL; | 95 | dlist) { |
96 | 96 | p9_client_clunk(current_fid); | |
97 | list_for_each_entry_safe(current_fid, temp, fid_list, list) { | ||
98 | err = v9fs_t_clunk(current_fid->v9ses, current_fid->fid); | ||
99 | |||
100 | if (err < 0) | ||
101 | dprintk(DEBUG_ERROR, "clunk failed: %d name %s\n", | ||
102 | err, dentry->d_iname); | ||
103 | |||
104 | v9fs_fid_destroy(current_fid); | ||
105 | } | 97 | } |
106 | 98 | ||
107 | kfree(dentry->d_fsdata); /* free the list_head */ | 99 | kfree(dent); |
100 | dentry->d_fsdata = NULL; | ||
108 | } | 101 | } |
109 | } | 102 | } |
110 | 103 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 1dd86ee90bc..0924d4477da 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -32,11 +32,10 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
35 | #include <net/9p/9p.h> | ||
36 | #include <net/9p/client.h> | ||
35 | 37 | ||
36 | #include "debug.h" | ||
37 | #include "v9fs.h" | 38 | #include "v9fs.h" |
38 | #include "9p.h" | ||
39 | #include "conv.h" | ||
40 | #include "v9fs_vfs.h" | 39 | #include "v9fs_vfs.h" |
41 | #include "fid.h" | 40 | #include "fid.h" |
42 | 41 | ||
@@ -46,14 +45,14 @@ | |||
46 | * | 45 | * |
47 | */ | 46 | */ |
48 | 47 | ||
49 | static inline int dt_type(struct v9fs_stat *mistat) | 48 | static inline int dt_type(struct p9_stat *mistat) |
50 | { | 49 | { |
51 | unsigned long perm = mistat->mode; | 50 | unsigned long perm = mistat->mode; |
52 | int rettype = DT_REG; | 51 | int rettype = DT_REG; |
53 | 52 | ||
54 | if (perm & V9FS_DMDIR) | 53 | if (perm & P9_DMDIR) |
55 | rettype = DT_DIR; | 54 | rettype = DT_DIR; |
56 | if (perm & V9FS_DMSYMLINK) | 55 | if (perm & P9_DMSYMLINK) |
57 | rettype = DT_LNK; | 56 | rettype = DT_LNK; |
58 | 57 | ||
59 | return rettype; | 58 | return rettype; |
@@ -69,106 +68,36 @@ static inline int dt_type(struct v9fs_stat *mistat) | |||
69 | 68 | ||
70 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | 69 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) |
71 | { | 70 | { |
72 | struct v9fs_fcall *fcall = NULL; | 71 | int over; |
73 | struct inode *inode = filp->f_path.dentry->d_inode; | 72 | struct p9_fid *fid; |
74 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 73 | struct v9fs_session_info *v9ses; |
75 | struct v9fs_fid *file = filp->private_data; | 74 | struct inode *inode; |
76 | unsigned int i, n, s; | 75 | struct p9_stat *st; |
77 | int fid = -1; | 76 | |
78 | int ret = 0; | 77 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); |
79 | struct v9fs_stat stat; | 78 | inode = filp->f_path.dentry->d_inode; |
80 | int over = 0; | 79 | v9ses = v9fs_inode2v9ses(inode); |
81 | 80 | fid = filp->private_data; | |
82 | dprintk(DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); | 81 | while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) { |
83 | 82 | if (IS_ERR(st)) | |
84 | fid = file->fid; | 83 | return PTR_ERR(st); |
85 | 84 | ||
86 | if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { | 85 | over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, |
87 | kfree(file->rdir_fcall); | 86 | v9fs_qid2ino(&st->qid), dt_type(st)); |
88 | file->rdir_fcall = NULL; | 87 | |
89 | } | 88 | if (over) |
90 | |||
91 | if (file->rdir_fcall) { | ||
92 | n = file->rdir_fcall->params.rread.count; | ||
93 | i = file->rdir_fpos; | ||
94 | while (i < n) { | ||
95 | s = v9fs_deserialize_stat( | ||
96 | file->rdir_fcall->params.rread.data + i, | ||
97 | n - i, &stat, v9ses->extended); | ||
98 | |||
99 | if (s == 0) { | ||
100 | dprintk(DEBUG_ERROR, | ||
101 | "error while deserializing stat\n"); | ||
102 | ret = -EIO; | ||
103 | goto FreeStructs; | ||
104 | } | ||
105 | |||
106 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
107 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
108 | dt_type(&stat)); | ||
109 | |||
110 | if (over) { | ||
111 | file->rdir_fpos = i; | ||
112 | file->rdir_pos = filp->f_pos; | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | i += s; | ||
117 | filp->f_pos += s; | ||
118 | } | ||
119 | |||
120 | if (!over) { | ||
121 | kfree(file->rdir_fcall); | ||
122 | file->rdir_fcall = NULL; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | while (!over) { | ||
127 | ret = v9fs_t_read(v9ses, fid, filp->f_pos, | ||
128 | v9ses->maxdata-V9FS_IOHDRSZ, &fcall); | ||
129 | if (ret < 0) { | ||
130 | dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", | ||
131 | ret, fcall); | ||
132 | goto FreeStructs; | ||
133 | } else if (ret == 0) | ||
134 | break; | 89 | break; |
135 | 90 | ||
136 | n = ret; | 91 | filp->f_pos += st->size; |
137 | i = 0; | 92 | kfree(st); |
138 | while (i < n) { | 93 | st = NULL; |
139 | s = v9fs_deserialize_stat(fcall->params.rread.data + i, | ||
140 | n - i, &stat, v9ses->extended); | ||
141 | |||
142 | if (s == 0) { | ||
143 | dprintk(DEBUG_ERROR, | ||
144 | "error while deserializing stat\n"); | ||
145 | return -EIO; | ||
146 | } | ||
147 | |||
148 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
149 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
150 | dt_type(&stat)); | ||
151 | |||
152 | if (over) { | ||
153 | file->rdir_fcall = fcall; | ||
154 | file->rdir_fpos = i; | ||
155 | file->rdir_pos = filp->f_pos; | ||
156 | fcall = NULL; | ||
157 | break; | ||
158 | } | ||
159 | |||
160 | i += s; | ||
161 | filp->f_pos += s; | ||
162 | } | ||
163 | |||
164 | kfree(fcall); | ||
165 | } | 94 | } |
166 | 95 | ||
167 | FreeStructs: | 96 | kfree(st); |
168 | kfree(fcall); | 97 | return 0; |
169 | return ret; | ||
170 | } | 98 | } |
171 | 99 | ||
100 | |||
172 | /** | 101 | /** |
173 | * v9fs_dir_release - close a directory | 102 | * v9fs_dir_release - close a directory |
174 | * @inode: inode of the directory | 103 | * @inode: inode of the directory |
@@ -178,29 +107,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
178 | 107 | ||
179 | int v9fs_dir_release(struct inode *inode, struct file *filp) | 108 | int v9fs_dir_release(struct inode *inode, struct file *filp) |
180 | { | 109 | { |
181 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 110 | struct p9_fid *fid; |
182 | struct v9fs_fid *fid = filp->private_data; | ||
183 | int fidnum = -1; | ||
184 | |||
185 | dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, | ||
186 | fid->fid); | ||
187 | fidnum = fid->fid; | ||
188 | 111 | ||
112 | fid = filp->private_data; | ||
113 | P9_DPRINTK(P9_DEBUG_VFS, | ||
114 | "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); | ||
189 | filemap_write_and_wait(inode->i_mapping); | 115 | filemap_write_and_wait(inode->i_mapping); |
190 | 116 | p9_client_clunk(fid); | |
191 | if (fidnum >= 0) { | ||
192 | dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, | ||
193 | fid->fid); | ||
194 | |||
195 | if (v9fs_t_clunk(v9ses, fidnum)) | ||
196 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
197 | |||
198 | kfree(fid->rdir_fcall); | ||
199 | kfree(fid); | ||
200 | |||
201 | filp->private_data = NULL; | ||
202 | } | ||
203 | |||
204 | return 0; | 117 | return 0; |
205 | } | 118 | } |
206 | 119 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 6e7678e4852..2a40c2946d0 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <linux/idr.h> | 36 | #include <linux/idr.h> |
37 | #include <net/9p/9p.h> | ||
38 | #include <net/9p/client.h> | ||
37 | 39 | ||
38 | #include "debug.h" | ||
39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
40 | #include "9p.h" | ||
41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
42 | #include "fid.h" | 42 | #include "fid.h" |
43 | 43 | ||
@@ -52,48 +52,40 @@ static const struct file_operations v9fs_cached_file_operations; | |||
52 | 52 | ||
53 | int v9fs_file_open(struct inode *inode, struct file *file) | 53 | int v9fs_file_open(struct inode *inode, struct file *file) |
54 | { | 54 | { |
55 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||
56 | struct v9fs_fid *vfid; | ||
57 | struct v9fs_fcall *fcall = NULL; | ||
58 | int omode; | ||
59 | int err; | 55 | int err; |
56 | struct v9fs_session_info *v9ses; | ||
57 | struct p9_fid *fid; | ||
58 | int omode; | ||
60 | 59 | ||
61 | dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); | 60 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p \n", inode, file); |
62 | 61 | v9ses = v9fs_inode2v9ses(inode); | |
63 | vfid = v9fs_fid_clone(file->f_path.dentry); | ||
64 | if (IS_ERR(vfid)) | ||
65 | return PTR_ERR(vfid); | ||
66 | |||
67 | omode = v9fs_uflags2omode(file->f_flags); | 62 | omode = v9fs_uflags2omode(file->f_flags); |
68 | err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall); | 63 | fid = file->private_data; |
69 | if (err < 0) { | 64 | if (!fid) { |
70 | PRINT_FCALL_ERROR("open failed", fcall); | 65 | fid = v9fs_fid_clone(file->f_path.dentry); |
71 | goto Clunk_Fid; | 66 | if (IS_ERR(fid)) |
67 | return PTR_ERR(fid); | ||
68 | |||
69 | err = p9_client_open(fid, omode); | ||
70 | if (err < 0) { | ||
71 | p9_client_clunk(fid); | ||
72 | return err; | ||
73 | } | ||
74 | if (omode & P9_OTRUNC) { | ||
75 | inode->i_size = 0; | ||
76 | inode->i_blocks = 0; | ||
77 | } | ||
72 | } | 78 | } |
73 | 79 | ||
74 | file->private_data = vfid; | 80 | file->private_data = fid; |
75 | vfid->fidopen = 1; | 81 | if ((fid->qid.version) && (v9ses->cache)) { |
76 | vfid->fidclunked = 0; | 82 | P9_DPRINTK(P9_DEBUG_VFS, "cached"); |
77 | vfid->iounit = fcall->params.ropen.iounit; | ||
78 | vfid->rdir_pos = 0; | ||
79 | vfid->rdir_fcall = NULL; | ||
80 | vfid->filp = file; | ||
81 | kfree(fcall); | ||
82 | |||
83 | if((vfid->qid.version) && (v9ses->cache)) { | ||
84 | dprintk(DEBUG_VFS, "cached"); | ||
85 | /* enable cached file options */ | 83 | /* enable cached file options */ |
86 | if(file->f_op == &v9fs_file_operations) | 84 | if(file->f_op == &v9fs_file_operations) |
87 | file->f_op = &v9fs_cached_file_operations; | 85 | file->f_op = &v9fs_cached_file_operations; |
88 | } | 86 | } |
89 | 87 | ||
90 | return 0; | 88 | return 0; |
91 | |||
92 | Clunk_Fid: | ||
93 | v9fs_fid_clunk(v9ses, vfid); | ||
94 | kfree(fcall); | ||
95 | |||
96 | return err; | ||
97 | } | 89 | } |
98 | 90 | ||
99 | /** | 91 | /** |
@@ -110,7 +102,7 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
110 | int res = 0; | 102 | int res = 0; |
111 | struct inode *inode = filp->f_path.dentry->d_inode; | 103 | struct inode *inode = filp->f_path.dentry->d_inode; |
112 | 104 | ||
113 | dprintk(DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); | 105 | P9_DPRINTK(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); |
114 | 106 | ||
115 | /* No mandatory locks */ | 107 | /* No mandatory locks */ |
116 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 108 | if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
@@ -136,55 +128,16 @@ static ssize_t | |||
136 | v9fs_file_read(struct file *filp, char __user * data, size_t count, | 128 | v9fs_file_read(struct file *filp, char __user * data, size_t count, |
137 | loff_t * offset) | 129 | loff_t * offset) |
138 | { | 130 | { |
139 | struct inode *inode = filp->f_path.dentry->d_inode; | 131 | int ret; |
140 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 132 | struct p9_fid *fid; |
141 | struct v9fs_fid *v9f = filp->private_data; | ||
142 | struct v9fs_fcall *fcall = NULL; | ||
143 | int fid = v9f->fid; | ||
144 | int rsize = 0; | ||
145 | int result = 0; | ||
146 | int total = 0; | ||
147 | int n; | ||
148 | |||
149 | dprintk(DEBUG_VFS, "\n"); | ||
150 | |||
151 | rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
152 | if (v9f->iounit != 0 && rsize > v9f->iounit) | ||
153 | rsize = v9f->iounit; | ||
154 | |||
155 | do { | ||
156 | if (count < rsize) | ||
157 | rsize = count; | ||
158 | 133 | ||
159 | result = v9fs_t_read(v9ses, fid, *offset, rsize, &fcall); | 134 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
135 | fid = filp->private_data; | ||
136 | ret = p9_client_uread(fid, data, *offset, count); | ||
137 | if (ret > 0) | ||
138 | *offset += ret; | ||
160 | 139 | ||
161 | if (result < 0) { | 140 | return ret; |
162 | printk(KERN_ERR "9P2000: v9fs_t_read returned %d\n", | ||
163 | result); | ||
164 | |||
165 | kfree(fcall); | ||
166 | return total; | ||
167 | } else | ||
168 | *offset += result; | ||
169 | |||
170 | n = copy_to_user(data, fcall->params.rread.data, result); | ||
171 | if (n) { | ||
172 | dprintk(DEBUG_ERROR, "Problem copying to user %d\n", n); | ||
173 | kfree(fcall); | ||
174 | return -EFAULT; | ||
175 | } | ||
176 | |||
177 | count -= result; | ||
178 | data += result; | ||
179 | total += result; | ||
180 | |||
181 | kfree(fcall); | ||
182 | |||
183 | if (result < rsize) | ||
184 | break; | ||
185 | } while (count); | ||
186 | |||
187 | return total; | ||
188 | } | 141 | } |
189 | 142 | ||
190 | /** | 143 | /** |
@@ -200,50 +153,25 @@ static ssize_t | |||
200 | v9fs_file_write(struct file *filp, const char __user * data, | 153 | v9fs_file_write(struct file *filp, const char __user * data, |
201 | size_t count, loff_t * offset) | 154 | size_t count, loff_t * offset) |
202 | { | 155 | { |
156 | int ret; | ||
157 | struct p9_fid *fid; | ||
203 | struct inode *inode = filp->f_path.dentry->d_inode; | 158 | struct inode *inode = filp->f_path.dentry->d_inode; |
204 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||
205 | struct v9fs_fid *v9fid = filp->private_data; | ||
206 | struct v9fs_fcall *fcall; | ||
207 | int fid = v9fid->fid; | ||
208 | int result = -EIO; | ||
209 | int rsize = 0; | ||
210 | int total = 0; | ||
211 | |||
212 | dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count, | ||
213 | (int)*offset); | ||
214 | rsize = v9ses->maxdata - V9FS_IOHDRSZ; | ||
215 | if (v9fid->iounit != 0 && rsize > v9fid->iounit) | ||
216 | rsize = v9fid->iounit; | ||
217 | |||
218 | do { | ||
219 | if (count < rsize) | ||
220 | rsize = count; | ||
221 | 159 | ||
222 | result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall); | 160 | P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data, |
223 | if (result < 0) { | 161 | (int)count, (int)*offset); |
224 | PRINT_FCALL_ERROR("error while writing", fcall); | ||
225 | kfree(fcall); | ||
226 | return result; | ||
227 | } else | ||
228 | *offset += result; | ||
229 | 162 | ||
230 | kfree(fcall); | 163 | fid = filp->private_data; |
231 | fcall = NULL; | 164 | ret = p9_client_uwrite(fid, data, *offset, count); |
165 | if (ret > 0) | ||
166 | *offset += ret; | ||
232 | 167 | ||
233 | if (result != rsize) { | 168 | if (*offset > inode->i_size) { |
234 | eprintk(KERN_ERR, | 169 | inode->i_size = *offset; |
235 | "short write: v9fs_t_write returned %d\n", | 170 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; |
236 | result); | 171 | } |
237 | break; | ||
238 | } | ||
239 | |||
240 | count -= result; | ||
241 | data += result; | ||
242 | total += result; | ||
243 | } while (count); | ||
244 | 172 | ||
245 | invalidate_inode_pages2(inode->i_mapping); | 173 | invalidate_inode_pages2(inode->i_mapping); |
246 | return total; | 174 | return ret; |
247 | } | 175 | } |
248 | 176 | ||
249 | static const struct file_operations v9fs_cached_file_operations = { | 177 | static const struct file_operations v9fs_cached_file_operations = { |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index c76cd8fa3f6..e5c45eed58a 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <net/9p/9p.h> | ||
38 | #include <net/9p/client.h> | ||
37 | 39 | ||
38 | #include "debug.h" | ||
39 | #include "v9fs.h" | 40 | #include "v9fs.h" |
40 | #include "9p.h" | ||
41 | #include "v9fs_vfs.h" | 41 | #include "v9fs_vfs.h" |
42 | #include "fid.h" | 42 | #include "fid.h" |
43 | 43 | ||
@@ -58,27 +58,27 @@ static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode) | |||
58 | int res; | 58 | int res; |
59 | res = mode & 0777; | 59 | res = mode & 0777; |
60 | if (S_ISDIR(mode)) | 60 | if (S_ISDIR(mode)) |
61 | res |= V9FS_DMDIR; | 61 | res |= P9_DMDIR; |
62 | if (v9ses->extended) { | 62 | if (v9ses->extended) { |
63 | if (S_ISLNK(mode)) | 63 | if (S_ISLNK(mode)) |
64 | res |= V9FS_DMSYMLINK; | 64 | res |= P9_DMSYMLINK; |
65 | if (v9ses->nodev == 0) { | 65 | if (v9ses->nodev == 0) { |
66 | if (S_ISSOCK(mode)) | 66 | if (S_ISSOCK(mode)) |
67 | res |= V9FS_DMSOCKET; | 67 | res |= P9_DMSOCKET; |
68 | if (S_ISFIFO(mode)) | 68 | if (S_ISFIFO(mode)) |
69 | res |= V9FS_DMNAMEDPIPE; | 69 | res |= P9_DMNAMEDPIPE; |
70 | if (S_ISBLK(mode)) | 70 | if (S_ISBLK(mode)) |
71 | res |= V9FS_DMDEVICE; | 71 | res |= P9_DMDEVICE; |
72 | if (S_ISCHR(mode)) | 72 | if (S_ISCHR(mode)) |
73 | res |= V9FS_DMDEVICE; | 73 | res |= P9_DMDEVICE; |
74 | } | 74 | } |
75 | 75 | ||
76 | if ((mode & S_ISUID) == S_ISUID) | 76 | if ((mode & S_ISUID) == S_ISUID) |
77 | res |= V9FS_DMSETUID; | 77 | res |= P9_DMSETUID; |
78 | if ((mode & S_ISGID) == S_ISGID) | 78 | if ((mode & S_ISGID) == S_ISGID) |
79 | res |= V9FS_DMSETGID; | 79 | res |= P9_DMSETGID; |
80 | if ((mode & V9FS_DMLINK)) | 80 | if ((mode & P9_DMLINK)) |
81 | res |= V9FS_DMLINK; | 81 | res |= P9_DMLINK; |
82 | } | 82 | } |
83 | 83 | ||
84 | return res; | 84 | return res; |
@@ -97,27 +97,27 @@ static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode) | |||
97 | 97 | ||
98 | res = mode & 0777; | 98 | res = mode & 0777; |
99 | 99 | ||
100 | if ((mode & V9FS_DMDIR) == V9FS_DMDIR) | 100 | if ((mode & P9_DMDIR) == P9_DMDIR) |
101 | res |= S_IFDIR; | 101 | res |= S_IFDIR; |
102 | else if ((mode & V9FS_DMSYMLINK) && (v9ses->extended)) | 102 | else if ((mode & P9_DMSYMLINK) && (v9ses->extended)) |
103 | res |= S_IFLNK; | 103 | res |= S_IFLNK; |
104 | else if ((mode & V9FS_DMSOCKET) && (v9ses->extended) | 104 | else if ((mode & P9_DMSOCKET) && (v9ses->extended) |
105 | && (v9ses->nodev == 0)) | 105 | && (v9ses->nodev == 0)) |
106 | res |= S_IFSOCK; | 106 | res |= S_IFSOCK; |
107 | else if ((mode & V9FS_DMNAMEDPIPE) && (v9ses->extended) | 107 | else if ((mode & P9_DMNAMEDPIPE) && (v9ses->extended) |
108 | && (v9ses->nodev == 0)) | 108 | && (v9ses->nodev == 0)) |
109 | res |= S_IFIFO; | 109 | res |= S_IFIFO; |
110 | else if ((mode & V9FS_DMDEVICE) && (v9ses->extended) | 110 | else if ((mode & P9_DMDEVICE) && (v9ses->extended) |
111 | && (v9ses->nodev == 0)) | 111 | && (v9ses->nodev == 0)) |
112 | res |= S_IFBLK; | 112 | res |= S_IFBLK; |
113 | else | 113 | else |
114 | res |= S_IFREG; | 114 | res |= S_IFREG; |
115 | 115 | ||
116 | if (v9ses->extended) { | 116 | if (v9ses->extended) { |
117 | if ((mode & V9FS_DMSETUID) == V9FS_DMSETUID) | 117 | if ((mode & P9_DMSETUID) == P9_DMSETUID) |
118 | res |= S_ISUID; | 118 | res |= S_ISUID; |
119 | 119 | ||
120 | if ((mode & V9FS_DMSETGID) == V9FS_DMSETGID) | 120 | if ((mode & P9_DMSETGID) == P9_DMSETGID) |
121 | res |= S_ISGID; | 121 | res |= S_ISGID; |
122 | } | 122 | } |
123 | 123 | ||
@@ -132,26 +132,26 @@ int v9fs_uflags2omode(int uflags) | |||
132 | switch (uflags&3) { | 132 | switch (uflags&3) { |
133 | default: | 133 | default: |
134 | case O_RDONLY: | 134 | case O_RDONLY: |
135 | ret = V9FS_OREAD; | 135 | ret = P9_OREAD; |
136 | break; | 136 | break; |
137 | 137 | ||
138 | case O_WRONLY: | 138 | case O_WRONLY: |
139 | ret = V9FS_OWRITE; | 139 | ret = P9_OWRITE; |
140 | break; | 140 | break; |
141 | 141 | ||
142 | case O_RDWR: | 142 | case O_RDWR: |
143 | ret = V9FS_ORDWR; | 143 | ret = P9_ORDWR; |
144 | break; | 144 | break; |
145 | } | 145 | } |
146 | 146 | ||
147 | if (uflags & O_EXCL) | 147 | if (uflags & O_EXCL) |
148 | ret |= V9FS_OEXCL; | 148 | ret |= P9_OEXCL; |
149 | 149 | ||
150 | if (uflags & O_TRUNC) | 150 | if (uflags & O_TRUNC) |
151 | ret |= V9FS_OTRUNC; | 151 | ret |= P9_OTRUNC; |
152 | 152 | ||
153 | if (uflags & O_APPEND) | 153 | if (uflags & O_APPEND) |
154 | ret |= V9FS_OAPPEND; | 154 | ret |= P9_OAPPEND; |
155 | 155 | ||
156 | return ret; | 156 | return ret; |
157 | } | 157 | } |
@@ -164,7 +164,7 @@ int v9fs_uflags2omode(int uflags) | |||
164 | */ | 164 | */ |
165 | 165 | ||
166 | static void | 166 | static void |
167 | v9fs_blank_wstat(struct v9fs_wstat *wstat) | 167 | v9fs_blank_wstat(struct p9_wstat *wstat) |
168 | { | 168 | { |
169 | wstat->type = ~0; | 169 | wstat->type = ~0; |
170 | wstat->dev = ~0; | 170 | wstat->dev = ~0; |
@@ -197,7 +197,7 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
197 | struct inode *inode; | 197 | struct inode *inode; |
198 | struct v9fs_session_info *v9ses = sb->s_fs_info; | 198 | struct v9fs_session_info *v9ses = sb->s_fs_info; |
199 | 199 | ||
200 | dprintk(DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); | 200 | P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode); |
201 | 201 | ||
202 | inode = new_inode(sb); | 202 | inode = new_inode(sb); |
203 | if (inode) { | 203 | if (inode) { |
@@ -215,7 +215,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
215 | case S_IFCHR: | 215 | case S_IFCHR: |
216 | case S_IFSOCK: | 216 | case S_IFSOCK: |
217 | if(!v9ses->extended) { | 217 | if(!v9ses->extended) { |
218 | dprintk(DEBUG_ERROR, "special files without extended mode\n"); | 218 | P9_DPRINTK(P9_DEBUG_ERROR, |
219 | "special files without extended mode\n"); | ||
219 | return ERR_PTR(-EINVAL); | 220 | return ERR_PTR(-EINVAL); |
220 | } | 221 | } |
221 | init_special_inode(inode, inode->i_mode, | 222 | init_special_inode(inode, inode->i_mode, |
@@ -227,7 +228,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
227 | break; | 228 | break; |
228 | case S_IFLNK: | 229 | case S_IFLNK: |
229 | if(!v9ses->extended) { | 230 | if(!v9ses->extended) { |
230 | dprintk(DEBUG_ERROR, "extended modes used w/o 9P2000.u\n"); | 231 | P9_DPRINTK(P9_DEBUG_ERROR, |
232 | "extended modes used w/o 9P2000.u\n"); | ||
231 | return ERR_PTR(-EINVAL); | 233 | return ERR_PTR(-EINVAL); |
232 | } | 234 | } |
233 | inode->i_op = &v9fs_symlink_inode_operations; | 235 | inode->i_op = &v9fs_symlink_inode_operations; |
@@ -241,71 +243,19 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
241 | inode->i_fop = &v9fs_dir_operations; | 243 | inode->i_fop = &v9fs_dir_operations; |
242 | break; | 244 | break; |
243 | default: | 245 | default: |
244 | dprintk(DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n", | 246 | P9_DPRINTK(P9_DEBUG_ERROR, |
247 | "BAD mode 0x%x S_IFMT 0x%x\n", | ||
245 | mode, mode & S_IFMT); | 248 | mode, mode & S_IFMT); |
246 | return ERR_PTR(-EINVAL); | 249 | return ERR_PTR(-EINVAL); |
247 | } | 250 | } |
248 | } else { | 251 | } else { |
249 | eprintk(KERN_WARNING, "Problem allocating inode\n"); | 252 | P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n"); |
250 | return ERR_PTR(-ENOMEM); | 253 | return ERR_PTR(-ENOMEM); |
251 | } | 254 | } |
252 | return inode; | 255 | return inode; |
253 | } | 256 | } |
254 | 257 | ||
255 | static int | 258 | /* |
256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, | ||
257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | ||
258 | { | ||
259 | int fid; | ||
260 | int err; | ||
261 | struct v9fs_fcall *fcall; | ||
262 | |||
263 | fid = v9fs_get_idpool(&v9ses->fidpool); | ||
264 | if (fid < 0) { | ||
265 | eprintk(KERN_WARNING, "no free fids available\n"); | ||
266 | return -ENOSPC; | ||
267 | } | ||
268 | |||
269 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); | ||
270 | if (err < 0) { | ||
271 | PRINT_FCALL_ERROR("clone error", fcall); | ||
272 | if (fcall && fcall->id == RWALK) | ||
273 | goto clunk_fid; | ||
274 | else | ||
275 | goto put_fid; | ||
276 | } | ||
277 | kfree(fcall); | ||
278 | |||
279 | err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall); | ||
280 | if (err < 0) { | ||
281 | PRINT_FCALL_ERROR("create fails", fcall); | ||
282 | goto clunk_fid; | ||
283 | } | ||
284 | |||
285 | if (iounit) | ||
286 | *iounit = fcall->params.rcreate.iounit; | ||
287 | |||
288 | if (qid) | ||
289 | *qid = fcall->params.rcreate.qid; | ||
290 | |||
291 | if (fidp) | ||
292 | *fidp = fid; | ||
293 | |||
294 | kfree(fcall); | ||
295 | return 0; | ||
296 | |||
297 | clunk_fid: | ||
298 | v9fs_t_clunk(v9ses, fid); | ||
299 | fid = V9FS_NOFID; | ||
300 | |||
301 | put_fid: | ||
302 | if (fid != V9FS_NOFID) | ||
303 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
304 | |||
305 | kfree(fcall); | ||
306 | return err; | ||
307 | } | ||
308 | |||
309 | static struct v9fs_fid* | 259 | static struct v9fs_fid* |
310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) | 260 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) |
311 | { | 261 | { |
@@ -355,23 +305,25 @@ error: | |||
355 | kfree(fcall); | 305 | kfree(fcall); |
356 | return ERR_PTR(err); | 306 | return ERR_PTR(err); |
357 | } | 307 | } |
308 | */ | ||
358 | 309 | ||
359 | static struct inode * | 310 | static struct inode * |
360 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | 311 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, |
361 | struct super_block *sb) | 312 | struct super_block *sb) |
362 | { | 313 | { |
363 | int err, umode; | 314 | int err, umode; |
364 | struct inode *ret; | 315 | struct inode *ret; |
365 | struct v9fs_fcall *fcall; | 316 | struct p9_stat *st; |
366 | 317 | ||
367 | ret = NULL; | 318 | ret = NULL; |
368 | err = v9fs_t_stat(v9ses, fid, &fcall); | 319 | st = p9_client_stat(fid); |
369 | if (err) { | 320 | if (IS_ERR(st)) { |
370 | PRINT_FCALL_ERROR("stat error", fcall); | 321 | err = PTR_ERR(st); |
322 | st = NULL; | ||
371 | goto error; | 323 | goto error; |
372 | } | 324 | } |
373 | 325 | ||
374 | umode = p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode); | 326 | umode = p9mode2unixmode(v9ses, st->mode); |
375 | ret = v9fs_get_inode(sb, umode); | 327 | ret = v9fs_get_inode(sb, umode); |
376 | if (IS_ERR(ret)) { | 328 | if (IS_ERR(ret)) { |
377 | err = PTR_ERR(ret); | 329 | err = PTR_ERR(ret); |
@@ -379,12 +331,13 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | |||
379 | goto error; | 331 | goto error; |
380 | } | 332 | } |
381 | 333 | ||
382 | v9fs_stat2inode(&fcall->params.rstat.stat, ret, sb); | 334 | v9fs_stat2inode(st, ret, sb); |
383 | kfree(fcall); | 335 | ret->i_ino = v9fs_qid2ino(&st->qid); |
336 | kfree(st); | ||
384 | return ret; | 337 | return ret; |
385 | 338 | ||
386 | error: | 339 | error: |
387 | kfree(fcall); | 340 | kfree(st); |
388 | if (ret) | 341 | if (ret) |
389 | iput(ret); | 342 | iput(ret); |
390 | 343 | ||
@@ -401,43 +354,20 @@ error: | |||
401 | 354 | ||
402 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 355 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) |
403 | { | 356 | { |
404 | struct v9fs_fcall *fcall = NULL; | 357 | struct inode *file_inode; |
405 | struct super_block *sb = NULL; | 358 | struct v9fs_session_info *v9ses; |
406 | struct v9fs_session_info *v9ses = NULL; | 359 | struct p9_fid *v9fid; |
407 | struct v9fs_fid *v9fid = NULL; | ||
408 | struct inode *file_inode = NULL; | ||
409 | int fid = -1; | ||
410 | int result = 0; | ||
411 | 360 | ||
412 | dprintk(DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, | 361 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, |
413 | rmdir); | 362 | rmdir); |
414 | 363 | ||
415 | file_inode = file->d_inode; | 364 | file_inode = file->d_inode; |
416 | sb = file_inode->i_sb; | ||
417 | v9ses = v9fs_inode2v9ses(file_inode); | 365 | v9ses = v9fs_inode2v9ses(file_inode); |
418 | v9fid = v9fs_fid_clone(file); | 366 | v9fid = v9fs_fid_clone(file); |
419 | if(IS_ERR(v9fid)) | 367 | if(IS_ERR(v9fid)) |
420 | return PTR_ERR(v9fid); | 368 | return PTR_ERR(v9fid); |
421 | 369 | ||
422 | fid = v9fid->fid; | 370 | return p9_client_remove(v9fid); |
423 | if (fid < 0) { | ||
424 | dprintk(DEBUG_ERROR, "inode #%lu, no fid!\n", | ||
425 | file_inode->i_ino); | ||
426 | return -EBADF; | ||
427 | } | ||
428 | |||
429 | result = v9fs_t_remove(v9ses, fid, &fcall); | ||
430 | if (result < 0) { | ||
431 | PRINT_FCALL_ERROR("remove fails", fcall); | ||
432 | goto Error; | ||
433 | } | ||
434 | |||
435 | v9fs_put_idpool(fid, &v9ses->fidpool); | ||
436 | v9fs_fid_destroy(v9fid); | ||
437 | |||
438 | Error: | ||
439 | kfree(fcall); | ||
440 | return result; | ||
441 | } | 371 | } |
442 | 372 | ||
443 | static int | 373 | static int |
@@ -446,61 +376,59 @@ v9fs_open_created(struct inode *inode, struct file *file) | |||
446 | return 0; | 376 | return 0; |
447 | } | 377 | } |
448 | 378 | ||
379 | |||
449 | /** | 380 | /** |
450 | * v9fs_vfs_create - VFS hook to create files | 381 | * v9fs_create - Create a file |
451 | * @inode: directory inode that is being deleted | 382 | * @dentry: dentry that is being created |
452 | * @dentry: dentry that is being deleted | 383 | * @perm: create permissions |
453 | * @mode: create permissions | 384 | * @mode: open mode |
454 | * @nd: path information | ||
455 | * | 385 | * |
456 | */ | 386 | */ |
457 | 387 | static struct p9_fid * | |
458 | static int | 388 | v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, |
459 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | 389 | struct dentry *dentry, char *extension, u32 perm, u8 mode) |
460 | struct nameidata *nd) | ||
461 | { | 390 | { |
462 | int err; | 391 | int err; |
463 | u32 fid, perm, iounit; | 392 | char *name; |
464 | int flags; | 393 | struct p9_fid *dfid, *ofid, *fid; |
465 | struct v9fs_session_info *v9ses; | ||
466 | struct v9fs_fid *dfid, *vfid, *ffid; | ||
467 | struct inode *inode; | 394 | struct inode *inode; |
468 | struct v9fs_qid qid; | ||
469 | struct file *filp; | ||
470 | 395 | ||
471 | inode = NULL; | 396 | err = 0; |
472 | vfid = NULL; | 397 | ofid = NULL; |
473 | v9ses = v9fs_inode2v9ses(dir); | 398 | fid = NULL; |
399 | name = (char *) dentry->d_name.name; | ||
474 | dfid = v9fs_fid_clone(dentry->d_parent); | 400 | dfid = v9fs_fid_clone(dentry->d_parent); |
475 | if(IS_ERR(dfid)) { | 401 | if(IS_ERR(dfid)) { |
476 | err = PTR_ERR(dfid); | 402 | err = PTR_ERR(dfid); |
403 | dfid = NULL; | ||
477 | goto error; | 404 | goto error; |
478 | } | 405 | } |
479 | 406 | ||
480 | perm = unixmode2p9mode(v9ses, mode); | 407 | /* clone a fid to use for creation */ |
481 | if (nd && nd->flags & LOOKUP_OPEN) | 408 | ofid = p9_client_walk(dfid, 0, NULL, 1); |
482 | flags = nd->intent.open.flags - 1; | 409 | if (IS_ERR(ofid)) { |
483 | else | 410 | err = PTR_ERR(ofid); |
484 | flags = O_RDWR; | 411 | ofid = NULL; |
485 | 412 | goto error; | |
486 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 413 | } |
487 | perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); | ||
488 | 414 | ||
489 | if (err) | 415 | err = p9_client_fcreate(ofid, name, perm, mode, extension); |
490 | goto clunk_dfid; | 416 | if (err < 0) |
417 | goto error; | ||
491 | 418 | ||
492 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 419 | /* now walk from the parent so we can get unopened fid */ |
493 | v9fs_fid_clunk(v9ses, dfid); | 420 | fid = p9_client_walk(dfid, 1, &name, 0); |
494 | if (IS_ERR(vfid)) { | 421 | if (IS_ERR(fid)) { |
495 | err = PTR_ERR(vfid); | 422 | err = PTR_ERR(fid); |
496 | vfid = NULL; | 423 | fid = NULL; |
497 | goto error; | 424 | goto error; |
498 | } | 425 | } else |
426 | dfid = NULL; | ||
499 | 427 | ||
500 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | 428 | /* instantiate inode and assign the unopened fid to the dentry */ |
429 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); | ||
501 | if (IS_ERR(inode)) { | 430 | if (IS_ERR(inode)) { |
502 | err = PTR_ERR(inode); | 431 | err = PTR_ERR(inode); |
503 | inode = NULL; | ||
504 | goto error; | 432 | goto error; |
505 | } | 433 | } |
506 | 434 | ||
@@ -508,35 +436,78 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
508 | dentry->d_op = &v9fs_cached_dentry_operations; | 436 | dentry->d_op = &v9fs_cached_dentry_operations; |
509 | else | 437 | else |
510 | dentry->d_op = &v9fs_dentry_operations; | 438 | dentry->d_op = &v9fs_dentry_operations; |
439 | |||
511 | d_instantiate(dentry, inode); | 440 | d_instantiate(dentry, inode); |
441 | v9fs_fid_add(dentry, fid); | ||
442 | return ofid; | ||
512 | 443 | ||
513 | if (nd && nd->flags & LOOKUP_OPEN) { | 444 | error: |
514 | ffid = v9fs_fid_create(v9ses, fid); | 445 | if (dfid) |
515 | if (!ffid) | 446 | p9_client_clunk(dfid); |
516 | return -ENOMEM; | 447 | |
448 | if (ofid) | ||
449 | p9_client_clunk(ofid); | ||
450 | |||
451 | if (fid) | ||
452 | p9_client_clunk(fid); | ||
453 | |||
454 | return ERR_PTR(err); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * v9fs_vfs_create - VFS hook to create files | ||
459 | * @inode: directory inode that is being created | ||
460 | * @dentry: dentry that is being deleted | ||
461 | * @mode: create permissions | ||
462 | * @nd: path information | ||
463 | * | ||
464 | */ | ||
517 | 465 | ||
466 | static int | ||
467 | v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode, | ||
468 | struct nameidata *nd) | ||
469 | { | ||
470 | int err; | ||
471 | u32 perm; | ||
472 | int flags; | ||
473 | struct v9fs_session_info *v9ses; | ||
474 | struct p9_fid *fid; | ||
475 | struct file *filp; | ||
476 | |||
477 | err = 0; | ||
478 | fid = NULL; | ||
479 | v9ses = v9fs_inode2v9ses(dir); | ||
480 | perm = unixmode2p9mode(v9ses, mode); | ||
481 | if (nd && nd->flags & LOOKUP_OPEN) | ||
482 | flags = nd->intent.open.flags - 1; | ||
483 | else | ||
484 | flags = O_RDWR; | ||
485 | |||
486 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, | ||
487 | v9fs_uflags2omode(flags)); | ||
488 | if (IS_ERR(fid)) { | ||
489 | err = PTR_ERR(fid); | ||
490 | fid = NULL; | ||
491 | goto error; | ||
492 | } | ||
493 | |||
494 | /* if we are opening a file, assign the open fid to the file */ | ||
495 | if (nd && nd->flags & LOOKUP_OPEN) { | ||
518 | filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); | 496 | filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created); |
519 | if (IS_ERR(filp)) { | 497 | if (IS_ERR(filp)) { |
520 | v9fs_fid_destroy(ffid); | 498 | err = PTR_ERR(filp); |
521 | return PTR_ERR(filp); | 499 | goto error; |
522 | } | 500 | } |
523 | 501 | ||
524 | ffid->rdir_pos = 0; | 502 | filp->private_data = fid; |
525 | ffid->rdir_fcall = NULL; | 503 | } else |
526 | ffid->fidopen = 1; | 504 | p9_client_clunk(fid); |
527 | ffid->iounit = iounit; | ||
528 | ffid->filp = filp; | ||
529 | filp->private_data = ffid; | ||
530 | } | ||
531 | 505 | ||
532 | return 0; | 506 | return 0; |
533 | 507 | ||
534 | clunk_dfid: | ||
535 | v9fs_fid_clunk(v9ses, dfid); | ||
536 | |||
537 | error: | 508 | error: |
538 | if (vfid) | 509 | if (fid) |
539 | v9fs_fid_destroy(vfid); | 510 | p9_client_clunk(fid); |
540 | 511 | ||
541 | return err; | 512 | return err; |
542 | } | 513 | } |
@@ -552,57 +523,23 @@ error: | |||
552 | static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 523 | static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
553 | { | 524 | { |
554 | int err; | 525 | int err; |
555 | u32 fid, perm; | 526 | u32 perm; |
556 | struct v9fs_session_info *v9ses; | 527 | struct v9fs_session_info *v9ses; |
557 | struct v9fs_fid *dfid, *vfid; | 528 | struct p9_fid *fid; |
558 | struct inode *inode; | ||
559 | 529 | ||
560 | inode = NULL; | 530 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name); |
561 | vfid = NULL; | 531 | err = 0; |
562 | v9ses = v9fs_inode2v9ses(dir); | 532 | v9ses = v9fs_inode2v9ses(dir); |
563 | dfid = v9fs_fid_clone(dentry->d_parent); | ||
564 | if(IS_ERR(dfid)) { | ||
565 | err = PTR_ERR(dfid); | ||
566 | goto error; | ||
567 | } | ||
568 | |||
569 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); | 533 | perm = unixmode2p9mode(v9ses, mode | S_IFDIR); |
570 | 534 | fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD); | |
571 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 535 | if (IS_ERR(fid)) { |
572 | perm, V9FS_OREAD, NULL, &fid, NULL, NULL); | 536 | err = PTR_ERR(fid); |
573 | 537 | fid = NULL; | |
574 | if (err) { | ||
575 | dprintk(DEBUG_ERROR, "create error %d\n", err); | ||
576 | goto clean_up_dfid; | ||
577 | } | 538 | } |
578 | 539 | ||
579 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | 540 | if (fid) |
580 | if (IS_ERR(vfid)) { | 541 | p9_client_clunk(fid); |
581 | err = PTR_ERR(vfid); | ||
582 | vfid = NULL; | ||
583 | goto clean_up_dfid; | ||
584 | } | ||
585 | 542 | ||
586 | v9fs_fid_clunk(v9ses, dfid); | ||
587 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | ||
588 | if (IS_ERR(inode)) { | ||
589 | err = PTR_ERR(inode); | ||
590 | inode = NULL; | ||
591 | v9fs_fid_destroy(vfid); | ||
592 | goto error; | ||
593 | } | ||
594 | |||
595 | if(v9ses->cache) | ||
596 | dentry->d_op = &v9fs_cached_dentry_operations; | ||
597 | else | ||
598 | dentry->d_op = &v9fs_dentry_operations; | ||
599 | d_instantiate(dentry, inode); | ||
600 | return 0; | ||
601 | |||
602 | clean_up_dfid: | ||
603 | v9fs_fid_clunk(v9ses, dfid); | ||
604 | |||
605 | error: | ||
606 | return err; | 543 | return err; |
607 | } | 544 | } |
608 | 545 | ||
@@ -619,104 +556,54 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
619 | { | 556 | { |
620 | struct super_block *sb; | 557 | struct super_block *sb; |
621 | struct v9fs_session_info *v9ses; | 558 | struct v9fs_session_info *v9ses; |
622 | struct v9fs_fid *dirfid; | 559 | struct p9_fid *dfid, *fid; |
623 | struct v9fs_fid *fid; | ||
624 | struct inode *inode; | 560 | struct inode *inode; |
625 | struct v9fs_fcall *fcall = NULL; | 561 | char *name; |
626 | int dirfidnum = -1; | ||
627 | int newfid = -1; | ||
628 | int result = 0; | 562 | int result = 0; |
629 | 563 | ||
630 | dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 564 | P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", |
631 | dir, dentry->d_name.name, dentry, nameidata); | 565 | dir, dentry->d_name.name, dentry, nameidata); |
632 | 566 | ||
633 | sb = dir->i_sb; | 567 | sb = dir->i_sb; |
634 | v9ses = v9fs_inode2v9ses(dir); | 568 | v9ses = v9fs_inode2v9ses(dir); |
635 | dirfid = v9fs_fid_lookup(dentry->d_parent); | 569 | dfid = v9fs_fid_lookup(dentry->d_parent); |
636 | 570 | if (IS_ERR(dfid)) | |
637 | if(IS_ERR(dirfid)) | 571 | return ERR_PTR(PTR_ERR(dfid)); |
638 | return ERR_PTR(PTR_ERR(dirfid)); | 572 | |
639 | 573 | name = (char *) dentry->d_name.name; | |
640 | dirfidnum = dirfid->fid; | 574 | fid = p9_client_walk(dfid, 1, &name, 1); |
641 | 575 | if (IS_ERR(fid)) { | |
642 | newfid = v9fs_get_idpool(&v9ses->fidpool); | 576 | result = PTR_ERR(fid); |
643 | if (newfid < 0) { | ||
644 | eprintk(KERN_WARNING, "newfid fails!\n"); | ||
645 | result = -ENOSPC; | ||
646 | goto Release_Dirfid; | ||
647 | } | ||
648 | |||
649 | result = v9fs_t_walk(v9ses, dirfidnum, newfid, | ||
650 | (char *)dentry->d_name.name, &fcall); | ||
651 | |||
652 | up(&dirfid->lock); | ||
653 | |||
654 | if (result < 0) { | ||
655 | if (fcall && fcall->id == RWALK) | ||
656 | v9fs_t_clunk(v9ses, newfid); | ||
657 | else | ||
658 | v9fs_put_idpool(newfid, &v9ses->fidpool); | ||
659 | |||
660 | if (result == -ENOENT) { | 577 | if (result == -ENOENT) { |
661 | d_add(dentry, NULL); | 578 | d_add(dentry, NULL); |
662 | dprintk(DEBUG_VFS, | ||
663 | "Return negative dentry %p count %d\n", | ||
664 | dentry, atomic_read(&dentry->d_count)); | ||
665 | kfree(fcall); | ||
666 | return NULL; | 579 | return NULL; |
667 | } | 580 | } |
668 | dprintk(DEBUG_ERROR, "walk error:%d\n", result); | ||
669 | goto FreeFcall; | ||
670 | } | ||
671 | kfree(fcall); | ||
672 | |||
673 | result = v9fs_t_stat(v9ses, newfid, &fcall); | ||
674 | if (result < 0) { | ||
675 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
676 | goto FreeFcall; | ||
677 | } | ||
678 | |||
679 | inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses, | ||
680 | fcall->params.rstat.stat.mode)); | ||
681 | 581 | ||
682 | if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) { | 582 | return ERR_PTR(result); |
683 | eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n", | ||
684 | PTR_ERR(inode)); | ||
685 | |||
686 | result = -ENOSPC; | ||
687 | goto FreeFcall; | ||
688 | } | 583 | } |
689 | 584 | ||
690 | inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid); | 585 | inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb); |
691 | 586 | if (IS_ERR(inode)) { | |
692 | fid = v9fs_fid_create(v9ses, newfid); | 587 | result = PTR_ERR(inode); |
693 | if (fid == NULL) { | 588 | inode = NULL; |
694 | dprintk(DEBUG_ERROR, "couldn't insert\n"); | 589 | goto error; |
695 | result = -ENOMEM; | ||
696 | goto FreeFcall; | ||
697 | } | 590 | } |
698 | 591 | ||
699 | result = v9fs_fid_insert(fid, dentry); | 592 | result = v9fs_fid_add(dentry, fid); |
700 | if (result < 0) | 593 | if (result < 0) |
701 | goto FreeFcall; | 594 | goto error; |
702 | 595 | ||
703 | fid->qid = fcall->params.rstat.stat.qid; | ||
704 | v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb); | ||
705 | if((fid->qid.version)&&(v9ses->cache)) | 596 | if((fid->qid.version)&&(v9ses->cache)) |
706 | dentry->d_op = &v9fs_cached_dentry_operations; | 597 | dentry->d_op = &v9fs_cached_dentry_operations; |
707 | else | 598 | else |
708 | dentry->d_op = &v9fs_dentry_operations; | 599 | dentry->d_op = &v9fs_dentry_operations; |
709 | 600 | ||
710 | d_add(dentry, inode); | 601 | d_add(dentry, inode); |
711 | kfree(fcall); | ||
712 | |||
713 | return NULL; | 602 | return NULL; |
714 | 603 | ||
715 | Release_Dirfid: | 604 | error: |
716 | up(&dirfid->lock); | 605 | if (fid) |
717 | 606 | p9_client_clunk(fid); | |
718 | FreeFcall: | ||
719 | kfree(fcall); | ||
720 | 607 | ||
721 | return ERR_PTR(result); | 608 | return ERR_PTR(result); |
722 | } | 609 | } |
@@ -758,73 +645,54 @@ static int | |||
758 | v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | 645 | v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry, |
759 | struct inode *new_dir, struct dentry *new_dentry) | 646 | struct inode *new_dir, struct dentry *new_dentry) |
760 | { | 647 | { |
761 | struct inode *old_inode = old_dentry->d_inode; | 648 | struct inode *old_inode; |
762 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); | 649 | struct v9fs_session_info *v9ses; |
763 | struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); | 650 | struct p9_fid *oldfid; |
764 | struct v9fs_fid *olddirfid; | 651 | struct p9_fid *olddirfid; |
765 | struct v9fs_fid *newdirfid; | 652 | struct p9_fid *newdirfid; |
766 | struct v9fs_wstat wstat; | 653 | struct p9_wstat wstat; |
767 | struct v9fs_fcall *fcall = NULL; | 654 | int retval; |
768 | int fid = -1; | ||
769 | int olddirfidnum = -1; | ||
770 | int newdirfidnum = -1; | ||
771 | int retval = 0; | ||
772 | |||
773 | dprintk(DEBUG_VFS, "\n"); | ||
774 | 655 | ||
656 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); | ||
657 | retval = 0; | ||
658 | old_inode = old_dentry->d_inode; | ||
659 | v9ses = v9fs_inode2v9ses(old_inode); | ||
660 | oldfid = v9fs_fid_lookup(old_dentry); | ||
775 | if(IS_ERR(oldfid)) | 661 | if(IS_ERR(oldfid)) |
776 | return PTR_ERR(oldfid); | 662 | return PTR_ERR(oldfid); |
777 | 663 | ||
778 | olddirfid = v9fs_fid_clone(old_dentry->d_parent); | 664 | olddirfid = v9fs_fid_clone(old_dentry->d_parent); |
779 | if(IS_ERR(olddirfid)) { | 665 | if(IS_ERR(olddirfid)) { |
780 | retval = PTR_ERR(olddirfid); | 666 | retval = PTR_ERR(olddirfid); |
781 | goto Release_lock; | 667 | goto done; |
782 | } | 668 | } |
783 | 669 | ||
784 | newdirfid = v9fs_fid_clone(new_dentry->d_parent); | 670 | newdirfid = v9fs_fid_clone(new_dentry->d_parent); |
785 | if(IS_ERR(newdirfid)) { | 671 | if(IS_ERR(newdirfid)) { |
786 | retval = PTR_ERR(newdirfid); | 672 | retval = PTR_ERR(newdirfid); |
787 | goto Clunk_olddir; | 673 | goto clunk_olddir; |
788 | } | 674 | } |
789 | 675 | ||
790 | /* 9P can only handle file rename in the same directory */ | 676 | /* 9P can only handle file rename in the same directory */ |
791 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { | 677 | if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { |
792 | dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); | 678 | P9_DPRINTK(P9_DEBUG_ERROR, |
679 | "old dir and new dir are different\n"); | ||
793 | retval = -EXDEV; | 680 | retval = -EXDEV; |
794 | goto Clunk_newdir; | 681 | goto clunk_newdir; |
795 | } | ||
796 | |||
797 | fid = oldfid->fid; | ||
798 | olddirfidnum = olddirfid->fid; | ||
799 | newdirfidnum = newdirfid->fid; | ||
800 | |||
801 | if (fid < 0) { | ||
802 | dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", | ||
803 | old_inode->i_ino); | ||
804 | retval = -EBADF; | ||
805 | goto Clunk_newdir; | ||
806 | } | 682 | } |
807 | 683 | ||
808 | v9fs_blank_wstat(&wstat); | 684 | v9fs_blank_wstat(&wstat); |
809 | wstat.muid = v9ses->name; | 685 | wstat.muid = v9ses->name; |
810 | wstat.name = (char *) new_dentry->d_name.name; | 686 | wstat.name = (char *) new_dentry->d_name.name; |
687 | retval = p9_client_wstat(oldfid, &wstat); | ||
811 | 688 | ||
812 | retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); | 689 | clunk_newdir: |
690 | p9_client_clunk(olddirfid); | ||
813 | 691 | ||
814 | if (retval < 0) | 692 | clunk_olddir: |
815 | PRINT_FCALL_ERROR("wstat error", fcall); | 693 | p9_client_clunk(newdirfid); |
816 | |||
817 | kfree(fcall); | ||
818 | |||
819 | Clunk_newdir: | ||
820 | v9fs_fid_clunk(v9ses, newdirfid); | ||
821 | |||
822 | Clunk_olddir: | ||
823 | v9fs_fid_clunk(v9ses, olddirfid); | ||
824 | |||
825 | Release_lock: | ||
826 | up(&oldfid->lock); | ||
827 | 694 | ||
695 | done: | ||
828 | return retval; | 696 | return retval; |
829 | } | 697 | } |
830 | 698 | ||
@@ -840,28 +708,30 @@ static int | |||
840 | v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | 708 | v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
841 | struct kstat *stat) | 709 | struct kstat *stat) |
842 | { | 710 | { |
843 | struct v9fs_fcall *fcall = NULL; | 711 | int err; |
844 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 712 | struct v9fs_session_info *v9ses; |
845 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 713 | struct p9_fid *fid; |
846 | int err = -EPERM; | 714 | struct p9_stat *st; |
847 | 715 | ||
848 | dprintk(DEBUG_VFS, "dentry: %p\n", dentry); | 716 | P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry); |
849 | if(IS_ERR(fid)) | 717 | err = -EPERM; |
718 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
719 | if (v9ses->cache == CACHE_LOOSE) | ||
720 | return simple_getattr(mnt, dentry, stat); | ||
721 | |||
722 | fid = v9fs_fid_lookup(dentry); | ||
723 | if (IS_ERR(fid)) | ||
850 | return PTR_ERR(fid); | 724 | return PTR_ERR(fid); |
851 | 725 | ||
852 | err = v9fs_t_stat(v9ses, fid->fid, &fcall); | 726 | st = p9_client_stat(fid); |
727 | if (IS_ERR(st)) | ||
728 | return PTR_ERR(st); | ||
853 | 729 | ||
854 | if (err < 0) | 730 | v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb); |
855 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
856 | else { | ||
857 | v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode, | ||
858 | dentry->d_inode->i_sb); | ||
859 | generic_fillattr(dentry->d_inode, stat); | 731 | generic_fillattr(dentry->d_inode, stat); |
860 | } | ||
861 | 732 | ||
862 | kfree(fcall); | 733 | kfree(st); |
863 | v9fs_fid_clunk(v9ses, fid); | 734 | return 0; |
864 | return err; | ||
865 | } | 735 | } |
866 | 736 | ||
867 | /** | 737 | /** |
@@ -873,13 +743,15 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
873 | 743 | ||
874 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | 744 | static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) |
875 | { | 745 | { |
876 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 746 | int retval; |
877 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 747 | struct v9fs_session_info *v9ses; |
878 | struct v9fs_fcall *fcall = NULL; | 748 | struct p9_fid *fid; |
879 | struct v9fs_wstat wstat; | 749 | struct p9_wstat wstat; |
880 | int res = -EPERM; | ||
881 | 750 | ||
882 | dprintk(DEBUG_VFS, "\n"); | 751 | P9_DPRINTK(P9_DEBUG_VFS, "\n"); |
752 | retval = -EPERM; | ||
753 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
754 | fid = v9fs_fid_lookup(dentry); | ||
883 | if(IS_ERR(fid)) | 755 | if(IS_ERR(fid)) |
884 | return PTR_ERR(fid); | 756 | return PTR_ERR(fid); |
885 | 757 | ||
@@ -904,17 +776,11 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
904 | wstat.n_gid = iattr->ia_gid; | 776 | wstat.n_gid = iattr->ia_gid; |
905 | } | 777 | } |
906 | 778 | ||
907 | res = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall); | 779 | retval = p9_client_wstat(fid, &wstat); |
780 | if (retval >= 0) | ||
781 | retval = inode_setattr(dentry->d_inode, iattr); | ||
908 | 782 | ||
909 | if (res < 0) | 783 | return retval; |
910 | PRINT_FCALL_ERROR("wstat error", fcall); | ||
911 | |||
912 | kfree(fcall); | ||
913 | if (res >= 0) | ||
914 | res = inode_setattr(dentry->d_inode, iattr); | ||
915 | |||
916 | v9fs_fid_clunk(v9ses, fid); | ||
917 | return res; | ||
918 | } | 784 | } |
919 | 785 | ||
920 | /** | 786 | /** |
@@ -926,7 +792,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
926 | */ | 792 | */ |
927 | 793 | ||
928 | void | 794 | void |
929 | v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | 795 | v9fs_stat2inode(struct p9_stat *stat, struct inode *inode, |
930 | struct super_block *sb) | 796 | struct super_block *sb) |
931 | { | 797 | { |
932 | int n; | 798 | int n; |
@@ -967,8 +833,9 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
967 | case 'b': | 833 | case 'b': |
968 | break; | 834 | break; |
969 | default: | 835 | default: |
970 | dprintk(DEBUG_ERROR, "Unknown special type %c (%.*s)\n", | 836 | P9_DPRINTK(P9_DEBUG_ERROR, |
971 | type, stat->extension.len, stat->extension.str); | 837 | "Unknown special type %c (%.*s)\n", type, |
838 | stat->extension.len, stat->extension.str); | ||
972 | }; | 839 | }; |
973 | inode->i_rdev = MKDEV(major, minor); | 840 | inode->i_rdev = MKDEV(major, minor); |
974 | } else | 841 | } else |
@@ -976,8 +843,8 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
976 | 843 | ||
977 | inode->i_size = stat->length; | 844 | inode->i_size = stat->length; |
978 | 845 | ||
979 | inode->i_blocks = | 846 | /* not real number of blocks, but 512 byte ones ... */ |
980 | (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; | 847 | inode->i_blocks = (inode->i_size + 512 - 1) >> 9; |
981 | } | 848 | } |
982 | 849 | ||
983 | /** | 850 | /** |
@@ -987,7 +854,7 @@ v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode, | |||
987 | * BUG: potential for inode number collisions? | 854 | * BUG: potential for inode number collisions? |
988 | */ | 855 | */ |
989 | 856 | ||
990 | ino_t v9fs_qid2ino(struct v9fs_qid *qid) | 857 | ino_t v9fs_qid2ino(struct p9_qid *qid) |
991 | { | 858 | { |
992 | u64 path = qid->path + 2; | 859 | u64 path = qid->path + 2; |
993 | ino_t i = 0; | 860 | ino_t i = 0; |
@@ -1010,56 +877,46 @@ ino_t v9fs_qid2ino(struct v9fs_qid *qid) | |||
1010 | 877 | ||
1011 | static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | 878 | static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) |
1012 | { | 879 | { |
1013 | int retval = -EPERM; | 880 | int retval; |
1014 | 881 | ||
1015 | struct v9fs_fcall *fcall = NULL; | 882 | struct v9fs_session_info *v9ses; |
1016 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); | 883 | struct p9_fid *fid; |
1017 | struct v9fs_fid *fid = v9fs_fid_clone(dentry); | 884 | struct p9_stat *st; |
1018 | 885 | ||
886 | P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name); | ||
887 | retval = -EPERM; | ||
888 | v9ses = v9fs_inode2v9ses(dentry->d_inode); | ||
889 | fid = v9fs_fid_lookup(dentry); | ||
1019 | if(IS_ERR(fid)) | 890 | if(IS_ERR(fid)) |
1020 | return PTR_ERR(fid); | 891 | return PTR_ERR(fid); |
1021 | 892 | ||
1022 | if (!v9ses->extended) { | 893 | if (!v9ses->extended) |
1023 | retval = -EBADF; | 894 | return -EBADF; |
1024 | dprintk(DEBUG_ERROR, "not extended\n"); | ||
1025 | goto ClunkFid; | ||
1026 | } | ||
1027 | |||
1028 | dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); | ||
1029 | retval = v9fs_t_stat(v9ses, fid->fid, &fcall); | ||
1030 | |||
1031 | if (retval < 0) { | ||
1032 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
1033 | goto FreeFcall; | ||
1034 | } | ||
1035 | 895 | ||
1036 | if (!fcall) { | 896 | st = p9_client_stat(fid); |
1037 | retval = -EIO; | 897 | if (IS_ERR(st)) |
1038 | goto ClunkFid; | 898 | return PTR_ERR(st); |
1039 | } | ||
1040 | 899 | ||
1041 | if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { | 900 | if (!(st->mode & P9_DMSYMLINK)) { |
1042 | retval = -EINVAL; | 901 | retval = -EINVAL; |
1043 | goto FreeFcall; | 902 | goto done; |
1044 | } | 903 | } |
1045 | 904 | ||
1046 | /* copy extension buffer into buffer */ | 905 | /* copy extension buffer into buffer */ |
1047 | if (fcall->params.rstat.stat.extension.len < buflen) | 906 | if (st->extension.len < buflen) |
1048 | buflen = fcall->params.rstat.stat.extension.len + 1; | 907 | buflen = st->extension.len + 1; |
1049 | 908 | ||
1050 | memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); | 909 | memmove(buffer, st->extension.str, buflen - 1); |
1051 | buffer[buflen-1] = 0; | 910 | buffer[buflen-1] = 0; |
1052 | 911 | ||
1053 | dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len, | 912 | P9_DPRINTK(P9_DEBUG_VFS, |
1054 | fcall->params.rstat.stat.extension.str, buffer); | 913 | "%s -> %.*s (%s)\n", dentry->d_name.name, st->extension.len, |
1055 | retval = buflen; | 914 | st->extension.str, buffer); |
1056 | 915 | ||
1057 | FreeFcall: | 916 | retval = buflen; |
1058 | kfree(fcall); | ||
1059 | |||
1060 | ClunkFid: | ||
1061 | v9fs_fid_clunk(v9ses, fid); | ||
1062 | 917 | ||
918 | done: | ||
919 | kfree(st); | ||
1063 | return retval; | 920 | return retval; |
1064 | } | 921 | } |
1065 | 922 | ||
@@ -1084,14 +941,14 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer, | |||
1084 | if (buflen > PATH_MAX) | 941 | if (buflen > PATH_MAX) |
1085 | buflen = PATH_MAX; | 942 | buflen = PATH_MAX; |
1086 | 943 | ||
1087 | dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); | 944 | P9_DPRINTK(P9_DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); |
1088 | 945 | ||
1089 | retval = v9fs_readlink(dentry, link, buflen); | 946 | retval = v9fs_readlink(dentry, link, buflen); |
1090 | 947 | ||
1091 | if (retval > 0) { | 948 | if (retval > 0) { |
1092 | if ((ret = copy_to_user(buffer, link, retval)) != 0) { | 949 | if ((ret = copy_to_user(buffer, link, retval)) != 0) { |
1093 | dprintk(DEBUG_ERROR, "problem copying to user: %d\n", | 950 | P9_DPRINTK(P9_DEBUG_ERROR, |
1094 | ret); | 951 | "problem copying to user: %d\n", ret); |
1095 | retval = ret; | 952 | retval = ret; |
1096 | } | 953 | } |
1097 | } | 954 | } |
@@ -1112,7 +969,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
1112 | int len = 0; | 969 | int len = 0; |
1113 | char *link = __getname(); | 970 | char *link = __getname(); |
1114 | 971 | ||
1115 | dprintk(DEBUG_VFS, "%s n", dentry->d_name.name); | 972 | P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name); |
1116 | 973 | ||
1117 | if (!link) | 974 | if (!link) |
1118 | link = ERR_PTR(-ENOMEM); | 975 | link = ERR_PTR(-ENOMEM); |
@@ -1141,7 +998,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void | |||
1141 | { | 998 | { |
1142 | char *s = nd_get_link(nd); | 999 | char *s = nd_get_link(nd); |
1143 | 1000 | ||
1144 | dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); | 1001 | P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s); |
1145 | if (!IS_ERR(s)) | 1002 | if (!IS_ERR(s)) |
1146 | __putname(s); | 1003 | __putname(s); |
1147 | } | 1004 | } |
@@ -1149,66 +1006,24 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void | |||
1149 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, | 1006 | static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry, |
1150 | int mode, const char *extension) | 1007 | int mode, const char *extension) |
1151 | { | 1008 | { |
1152 | int err; | 1009 | u32 perm; |
1153 | u32 fid, perm; | ||
1154 | struct v9fs_session_info *v9ses; | 1010 | struct v9fs_session_info *v9ses; |
1155 | struct v9fs_fid *dfid, *vfid = NULL; | 1011 | struct p9_fid *fid; |
1156 | struct inode *inode = NULL; | ||
1157 | 1012 | ||
1158 | v9ses = v9fs_inode2v9ses(dir); | 1013 | v9ses = v9fs_inode2v9ses(dir); |
1159 | if (!v9ses->extended) { | 1014 | if (!v9ses->extended) { |
1160 | dprintk(DEBUG_ERROR, "not extended\n"); | 1015 | P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n"); |
1161 | return -EPERM; | 1016 | return -EPERM; |
1162 | } | 1017 | } |
1163 | 1018 | ||
1164 | dfid = v9fs_fid_clone(dentry->d_parent); | ||
1165 | if(IS_ERR(dfid)) { | ||
1166 | err = PTR_ERR(dfid); | ||
1167 | goto error; | ||
1168 | } | ||
1169 | |||
1170 | perm = unixmode2p9mode(v9ses, mode); | 1019 | perm = unixmode2p9mode(v9ses, mode); |
1020 | fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm, | ||
1021 | P9_OREAD); | ||
1022 | if (IS_ERR(fid)) | ||
1023 | return PTR_ERR(fid); | ||
1171 | 1024 | ||
1172 | err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, | 1025 | p9_client_clunk(fid); |
1173 | perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); | ||
1174 | |||
1175 | if (err) | ||
1176 | goto clunk_dfid; | ||
1177 | |||
1178 | err = v9fs_t_clunk(v9ses, fid); | ||
1179 | if (err) | ||
1180 | goto clunk_dfid; | ||
1181 | |||
1182 | vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); | ||
1183 | if (IS_ERR(vfid)) { | ||
1184 | err = PTR_ERR(vfid); | ||
1185 | vfid = NULL; | ||
1186 | goto clunk_dfid; | ||
1187 | } | ||
1188 | |||
1189 | inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); | ||
1190 | if (IS_ERR(inode)) { | ||
1191 | err = PTR_ERR(inode); | ||
1192 | inode = NULL; | ||
1193 | goto free_vfid; | ||
1194 | } | ||
1195 | |||
1196 | if(v9ses->cache) | ||
1197 | dentry->d_op = &v9fs_cached_dentry_operations; | ||
1198 | else | ||
1199 | dentry->d_op = &v9fs_dentry_operations; | ||
1200 | d_instantiate(dentry, inode); | ||
1201 | return 0; | 1026 | return 0; |
1202 | |||
1203 | free_vfid: | ||
1204 | v9fs_fid_destroy(vfid); | ||
1205 | |||
1206 | clunk_dfid: | ||
1207 | v9fs_fid_clunk(v9ses, dfid); | ||
1208 | |||
1209 | error: | ||
1210 | return err; | ||
1211 | |||
1212 | } | 1027 | } |
1213 | 1028 | ||
1214 | /** | 1029 | /** |
@@ -1224,8 +1039,8 @@ error: | |||
1224 | static int | 1039 | static int |
1225 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | 1040 | v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) |
1226 | { | 1041 | { |
1227 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1042 | P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, |
1228 | symname); | 1043 | dentry->d_name.name, symname); |
1229 | 1044 | ||
1230 | return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); | 1045 | return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname); |
1231 | } | 1046 | } |
@@ -1247,11 +1062,11 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1247 | struct dentry *dentry) | 1062 | struct dentry *dentry) |
1248 | { | 1063 | { |
1249 | int retval; | 1064 | int retval; |
1250 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); | 1065 | struct p9_fid *oldfid; |
1251 | struct v9fs_fid *oldfid; | ||
1252 | char *name; | 1066 | char *name; |
1253 | 1067 | ||
1254 | dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | 1068 | P9_DPRINTK(P9_DEBUG_VFS, |
1069 | " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, | ||
1255 | old_dentry->d_name.name); | 1070 | old_dentry->d_name.name); |
1256 | 1071 | ||
1257 | oldfid = v9fs_fid_clone(old_dentry); | 1072 | oldfid = v9fs_fid_clone(old_dentry); |
@@ -1265,11 +1080,11 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir, | |||
1265 | } | 1080 | } |
1266 | 1081 | ||
1267 | sprintf(name, "%d\n", oldfid->fid); | 1082 | sprintf(name, "%d\n", oldfid->fid); |
1268 | retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); | 1083 | retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name); |
1269 | __putname(name); | 1084 | __putname(name); |
1270 | 1085 | ||
1271 | clunk_fid: | 1086 | clunk_fid: |
1272 | v9fs_fid_clunk(v9ses, oldfid); | 1087 | p9_client_clunk(oldfid); |
1273 | return retval; | 1088 | return retval; |
1274 | } | 1089 | } |
1275 | 1090 | ||
@@ -1288,7 +1103,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) | |||
1288 | int retval; | 1103 | int retval; |
1289 | char *name; | 1104 | char *name; |
1290 | 1105 | ||
1291 | dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | 1106 | P9_DPRINTK(P9_DEBUG_VFS, |
1107 | " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, | ||
1292 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); | 1108 | dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev)); |
1293 | 1109 | ||
1294 | if (!new_valid_dev(rdev)) | 1110 | if (!new_valid_dev(rdev)) |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 7bdf8b32684..ba904371218 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -37,10 +37,10 @@ | |||
37 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
38 | #include <linux/idr.h> | 38 | #include <linux/idr.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <net/9p/9p.h> | ||
41 | #include <net/9p/client.h> | ||
40 | 42 | ||
41 | #include "debug.h" | ||
42 | #include "v9fs.h" | 43 | #include "v9fs.h" |
43 | #include "9p.h" | ||
44 | #include "v9fs_vfs.h" | 44 | #include "v9fs_vfs.h" |
45 | #include "fid.h" | 45 | #include "fid.h" |
46 | 46 | ||
@@ -107,41 +107,48 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
107 | struct vfsmount *mnt) | 107 | struct vfsmount *mnt) |
108 | { | 108 | { |
109 | struct super_block *sb = NULL; | 109 | struct super_block *sb = NULL; |
110 | struct v9fs_fcall *fcall = NULL; | ||
111 | struct inode *inode = NULL; | 110 | struct inode *inode = NULL; |
112 | struct dentry *root = NULL; | 111 | struct dentry *root = NULL; |
113 | struct v9fs_session_info *v9ses = NULL; | 112 | struct v9fs_session_info *v9ses = NULL; |
114 | struct v9fs_fid *root_fid = NULL; | 113 | struct p9_stat *st = NULL; |
115 | int mode = S_IRWXUGO | S_ISVTX; | 114 | int mode = S_IRWXUGO | S_ISVTX; |
116 | uid_t uid = current->fsuid; | 115 | uid_t uid = current->fsuid; |
117 | gid_t gid = current->fsgid; | 116 | gid_t gid = current->fsgid; |
118 | int stat_result = 0; | 117 | struct p9_fid *fid; |
119 | int newfid = 0; | ||
120 | int retval = 0; | 118 | int retval = 0; |
121 | 119 | ||
122 | dprintk(DEBUG_VFS, " \n"); | 120 | P9_DPRINTK(P9_DEBUG_VFS, " \n"); |
123 | 121 | ||
124 | v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); | 122 | v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); |
125 | if (!v9ses) | 123 | if (!v9ses) |
126 | return -ENOMEM; | 124 | return -ENOMEM; |
127 | 125 | ||
128 | if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) { | 126 | fid = v9fs_session_init(v9ses, dev_name, data); |
129 | dprintk(DEBUG_ERROR, "problem initiating session\n"); | 127 | if (IS_ERR(fid)) { |
130 | retval = newfid; | 128 | retval = PTR_ERR(fid); |
131 | goto out_free_session; | 129 | fid = NULL; |
130 | kfree(v9ses); | ||
131 | v9ses = NULL; | ||
132 | goto error; | ||
133 | } | ||
134 | |||
135 | st = p9_client_stat(fid); | ||
136 | if (IS_ERR(st)) { | ||
137 | retval = PTR_ERR(st); | ||
138 | goto error; | ||
132 | } | 139 | } |
133 | 140 | ||
134 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); | 141 | sb = sget(fs_type, NULL, v9fs_set_super, v9ses); |
135 | if (IS_ERR(sb)) { | 142 | if (IS_ERR(sb)) { |
136 | retval = PTR_ERR(sb); | 143 | retval = PTR_ERR(sb); |
137 | goto out_close_session; | 144 | goto error; |
138 | } | 145 | } |
139 | v9fs_fill_super(sb, v9ses, flags); | 146 | v9fs_fill_super(sb, v9ses, flags); |
140 | 147 | ||
141 | inode = v9fs_get_inode(sb, S_IFDIR | mode); | 148 | inode = v9fs_get_inode(sb, S_IFDIR | mode); |
142 | if (IS_ERR(inode)) { | 149 | if (IS_ERR(inode)) { |
143 | retval = PTR_ERR(inode); | 150 | retval = PTR_ERR(inode); |
144 | goto put_back_sb; | 151 | goto error; |
145 | } | 152 | } |
146 | 153 | ||
147 | inode->i_uid = uid; | 154 | inode->i_uid = uid; |
@@ -150,54 +157,30 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
150 | root = d_alloc_root(inode); | 157 | root = d_alloc_root(inode); |
151 | if (!root) { | 158 | if (!root) { |
152 | retval = -ENOMEM; | 159 | retval = -ENOMEM; |
153 | goto put_back_sb; | 160 | goto error; |
154 | } | 161 | } |
155 | 162 | ||
156 | sb->s_root = root; | 163 | sb->s_root = root; |
164 | root->d_inode->i_ino = v9fs_qid2ino(&st->qid); | ||
165 | v9fs_stat2inode(st, root->d_inode, sb); | ||
166 | v9fs_fid_add(root, fid); | ||
157 | 167 | ||
158 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); | 168 | return simple_set_mnt(mnt, sb); |
159 | if (stat_result < 0) { | ||
160 | dprintk(DEBUG_ERROR, "stat error\n"); | ||
161 | v9fs_t_clunk(v9ses, newfid); | ||
162 | } else { | ||
163 | /* Setup the Root Inode */ | ||
164 | root_fid = v9fs_fid_create(v9ses, newfid); | ||
165 | if (root_fid == NULL) { | ||
166 | retval = -ENOMEM; | ||
167 | goto put_back_sb; | ||
168 | } | ||
169 | |||
170 | retval = v9fs_fid_insert(root_fid, root); | ||
171 | if (retval < 0) { | ||
172 | kfree(fcall); | ||
173 | goto put_back_sb; | ||
174 | } | ||
175 | |||
176 | root_fid->qid = fcall->params.rstat.stat.qid; | ||
177 | root->d_inode->i_ino = | ||
178 | v9fs_qid2ino(&fcall->params.rstat.stat.qid); | ||
179 | v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb); | ||
180 | } | ||
181 | 169 | ||
182 | kfree(fcall); | 170 | error: |
171 | if (fid) | ||
172 | p9_client_clunk(fid); | ||
183 | 173 | ||
184 | if (stat_result < 0) { | 174 | if (v9ses) { |
185 | retval = stat_result; | 175 | v9fs_session_close(v9ses); |
186 | goto put_back_sb; | 176 | kfree(v9ses); |
187 | } | 177 | } |
188 | 178 | ||
189 | return simple_set_mnt(mnt, sb); | 179 | if (sb) { |
190 | 180 | up_write(&sb->s_umount); | |
191 | out_close_session: | 181 | deactivate_super(sb); |
192 | v9fs_session_close(v9ses); | 182 | } |
193 | out_free_session: | ||
194 | kfree(v9ses); | ||
195 | return retval; | ||
196 | 183 | ||
197 | put_back_sb: | ||
198 | /* deactivate_super calls v9fs_kill_super which will frees the rest */ | ||
199 | up_write(&sb->s_umount); | ||
200 | deactivate_super(sb); | ||
201 | return retval; | 184 | return retval; |
202 | } | 185 | } |
203 | 186 | ||
@@ -211,7 +194,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
211 | { | 194 | { |
212 | struct v9fs_session_info *v9ses = s->s_fs_info; | 195 | struct v9fs_session_info *v9ses = s->s_fs_info; |
213 | 196 | ||
214 | dprintk(DEBUG_VFS, " %p\n", s); | 197 | P9_DPRINTK(P9_DEBUG_VFS, " %p\n", s); |
215 | 198 | ||
216 | v9fs_dentry_release(s->s_root); /* clunk root */ | 199 | v9fs_dentry_release(s->s_root); /* clunk root */ |
217 | 200 | ||
@@ -219,7 +202,7 @@ static void v9fs_kill_super(struct super_block *s) | |||
219 | 202 | ||
220 | v9fs_session_close(v9ses); | 203 | v9fs_session_close(v9ses); |
221 | kfree(v9ses); | 204 | kfree(v9ses); |
222 | dprintk(DEBUG_VFS, "exiting kill_super\n"); | 205 | P9_DPRINTK(P9_DEBUG_VFS, "exiting kill_super\n"); |
223 | } | 206 | } |
224 | 207 | ||
225 | /** | 208 | /** |
@@ -234,7 +217,7 @@ static int v9fs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
234 | struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; | 217 | struct v9fs_session_info *v9ses = mnt->mnt_sb->s_fs_info; |
235 | 218 | ||
236 | if (v9ses->debug != 0) | 219 | if (v9ses->debug != 0) |
237 | seq_printf(m, ",debug=%u", v9ses->debug); | 220 | seq_printf(m, ",debug=%x", v9ses->debug); |
238 | if (v9ses->port != V9FS_PORT) | 221 | if (v9ses->port != V9FS_PORT) |
239 | seq_printf(m, ",port=%u", v9ses->port); | 222 | seq_printf(m, ",port=%u", v9ses->port); |
240 | if (v9ses->maxdata != 9000) | 223 | if (v9ses->maxdata != 9000) |
diff --git a/fs/Kconfig b/fs/Kconfig index 0fa0c1193e8..94b9d861bf9 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -2048,7 +2048,7 @@ config AFS_DEBUG | |||
2048 | 2048 | ||
2049 | config 9P_FS | 2049 | config 9P_FS |
2050 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" | 2050 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" |
2051 | depends on INET && EXPERIMENTAL | 2051 | depends on INET && NET_9P && EXPERIMENTAL |
2052 | help | 2052 | help |
2053 | If you say Y here, you will get experimental support for | 2053 | If you say Y here, you will get experimental support for |
2054 | Plan 9 resource sharing via the 9P2000 protocol. | 2054 | Plan 9 resource sharing via the 9P2000 protocol. |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index 9ddf5ed6216..898a86dde8f 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -470,7 +470,7 @@ int coda_readdir(struct file *coda_file, void *dirent, filldir_t filldir) | |||
470 | 470 | ||
471 | ret = -ENOENT; | 471 | ret = -ENOENT; |
472 | if (!IS_DEADDIR(host_inode)) { | 472 | if (!IS_DEADDIR(host_inode)) { |
473 | ret = host_file->f_op->readdir(host_file, filldir, dirent); | 473 | ret = host_file->f_op->readdir(host_file, dirent, filldir); |
474 | file_accessed(host_file); | 474 | file_accessed(host_file); |
475 | } | 475 | } |
476 | } | 476 | } |
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index b49989bb89a..e7a9a83f008 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -64,6 +64,7 @@ xfs-y += xfs_alloc.o \ | |||
64 | xfs_dir2_sf.o \ | 64 | xfs_dir2_sf.o \ |
65 | xfs_error.o \ | 65 | xfs_error.o \ |
66 | xfs_extfree_item.o \ | 66 | xfs_extfree_item.o \ |
67 | xfs_filestream.o \ | ||
67 | xfs_fsops.o \ | 68 | xfs_fsops.o \ |
68 | xfs_ialloc.o \ | 69 | xfs_ialloc.o \ |
69 | xfs_ialloc_btree.o \ | 70 | xfs_ialloc_btree.o \ |
@@ -77,6 +78,7 @@ xfs-y += xfs_alloc.o \ | |||
77 | xfs_log.o \ | 78 | xfs_log.o \ |
78 | xfs_log_recover.o \ | 79 | xfs_log_recover.o \ |
79 | xfs_mount.o \ | 80 | xfs_mount.o \ |
81 | xfs_mru_cache.o \ | ||
80 | xfs_rename.o \ | 82 | xfs_rename.o \ |
81 | xfs_trans.o \ | 83 | xfs_trans.o \ |
82 | xfs_trans_ail.o \ | 84 | xfs_trans_ail.o \ |
diff --git a/fs/xfs/linux-2.6/kmem.h b/fs/xfs/linux-2.6/kmem.h index 9ebabdf7829..4b6470cf87f 100644 --- a/fs/xfs/linux-2.6/kmem.h +++ b/fs/xfs/linux-2.6/kmem.h | |||
@@ -100,25 +100,6 @@ kmem_zone_destroy(kmem_zone_t *zone) | |||
100 | extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast); | 100 | extern void *kmem_zone_alloc(kmem_zone_t *, unsigned int __nocast); |
101 | extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast); | 101 | extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast); |
102 | 102 | ||
103 | /* | ||
104 | * Low memory cache shrinkers | ||
105 | */ | ||
106 | |||
107 | typedef struct shrinker *kmem_shaker_t; | ||
108 | typedef int (*kmem_shake_func_t)(int, gfp_t); | ||
109 | |||
110 | static inline kmem_shaker_t | ||
111 | kmem_shake_register(kmem_shake_func_t sfunc) | ||
112 | { | ||
113 | return set_shrinker(DEFAULT_SEEKS, sfunc); | ||
114 | } | ||
115 | |||
116 | static inline void | ||
117 | kmem_shake_deregister(kmem_shaker_t shrinker) | ||
118 | { | ||
119 | remove_shrinker(shrinker); | ||
120 | } | ||
121 | |||
122 | static inline int | 103 | static inline int |
123 | kmem_shake_allow(gfp_t gfp_mask) | 104 | kmem_shake_allow(gfp_t gfp_mask) |
124 | { | 105 | { |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 7361861e3aa..fd4105d662e 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -108,14 +108,19 @@ xfs_page_trace( | |||
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Schedule IO completion handling on a xfsdatad if this was | 110 | * Schedule IO completion handling on a xfsdatad if this was |
111 | * the final hold on this ioend. | 111 | * the final hold on this ioend. If we are asked to wait, |
112 | * flush the workqueue. | ||
112 | */ | 113 | */ |
113 | STATIC void | 114 | STATIC void |
114 | xfs_finish_ioend( | 115 | xfs_finish_ioend( |
115 | xfs_ioend_t *ioend) | 116 | xfs_ioend_t *ioend, |
117 | int wait) | ||
116 | { | 118 | { |
117 | if (atomic_dec_and_test(&ioend->io_remaining)) | 119 | if (atomic_dec_and_test(&ioend->io_remaining)) { |
118 | queue_work(xfsdatad_workqueue, &ioend->io_work); | 120 | queue_work(xfsdatad_workqueue, &ioend->io_work); |
121 | if (wait) | ||
122 | flush_workqueue(xfsdatad_workqueue); | ||
123 | } | ||
119 | } | 124 | } |
120 | 125 | ||
121 | /* | 126 | /* |
@@ -156,6 +161,8 @@ xfs_setfilesize( | |||
156 | xfs_fsize_t bsize; | 161 | xfs_fsize_t bsize; |
157 | 162 | ||
158 | ip = xfs_vtoi(ioend->io_vnode); | 163 | ip = xfs_vtoi(ioend->io_vnode); |
164 | if (!ip) | ||
165 | return; | ||
159 | 166 | ||
160 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); | 167 | ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); |
161 | ASSERT(ioend->io_type != IOMAP_READ); | 168 | ASSERT(ioend->io_type != IOMAP_READ); |
@@ -334,7 +341,7 @@ xfs_end_bio( | |||
334 | bio->bi_end_io = NULL; | 341 | bio->bi_end_io = NULL; |
335 | bio_put(bio); | 342 | bio_put(bio); |
336 | 343 | ||
337 | xfs_finish_ioend(ioend); | 344 | xfs_finish_ioend(ioend, 0); |
338 | return 0; | 345 | return 0; |
339 | } | 346 | } |
340 | 347 | ||
@@ -470,7 +477,7 @@ xfs_submit_ioend( | |||
470 | } | 477 | } |
471 | if (bio) | 478 | if (bio) |
472 | xfs_submit_ioend_bio(ioend, bio); | 479 | xfs_submit_ioend_bio(ioend, bio); |
473 | xfs_finish_ioend(ioend); | 480 | xfs_finish_ioend(ioend, 0); |
474 | } while ((ioend = next) != NULL); | 481 | } while ((ioend = next) != NULL); |
475 | } | 482 | } |
476 | 483 | ||
@@ -1003,6 +1010,8 @@ xfs_page_state_convert( | |||
1003 | if (buffer_unwritten(bh) || buffer_delay(bh) || | 1010 | if (buffer_unwritten(bh) || buffer_delay(bh) || |
1004 | ((buffer_uptodate(bh) || PageUptodate(page)) && | 1011 | ((buffer_uptodate(bh) || PageUptodate(page)) && |
1005 | !buffer_mapped(bh) && (unmapped || startio))) { | 1012 | !buffer_mapped(bh) && (unmapped || startio))) { |
1013 | int new_ioend = 0; | ||
1014 | |||
1006 | /* | 1015 | /* |
1007 | * Make sure we don't use a read-only iomap | 1016 | * Make sure we don't use a read-only iomap |
1008 | */ | 1017 | */ |
@@ -1021,6 +1030,15 @@ xfs_page_state_convert( | |||
1021 | } | 1030 | } |
1022 | 1031 | ||
1023 | if (!iomap_valid) { | 1032 | if (!iomap_valid) { |
1033 | /* | ||
1034 | * if we didn't have a valid mapping then we | ||
1035 | * need to ensure that we put the new mapping | ||
1036 | * in a new ioend structure. This needs to be | ||
1037 | * done to ensure that the ioends correctly | ||
1038 | * reflect the block mappings at io completion | ||
1039 | * for unwritten extent conversion. | ||
1040 | */ | ||
1041 | new_ioend = 1; | ||
1024 | if (type == IOMAP_NEW) { | 1042 | if (type == IOMAP_NEW) { |
1025 | size = xfs_probe_cluster(inode, | 1043 | size = xfs_probe_cluster(inode, |
1026 | page, bh, head, 0); | 1044 | page, bh, head, 0); |
@@ -1040,7 +1058,7 @@ xfs_page_state_convert( | |||
1040 | if (startio) { | 1058 | if (startio) { |
1041 | xfs_add_to_ioend(inode, bh, offset, | 1059 | xfs_add_to_ioend(inode, bh, offset, |
1042 | type, &ioend, | 1060 | type, &ioend, |
1043 | !iomap_valid); | 1061 | new_ioend); |
1044 | } else { | 1062 | } else { |
1045 | set_buffer_dirty(bh); | 1063 | set_buffer_dirty(bh); |
1046 | unlock_buffer(bh); | 1064 | unlock_buffer(bh); |
@@ -1416,6 +1434,13 @@ xfs_end_io_direct( | |||
1416 | * This is not necessary for synchronous direct I/O, but we do | 1434 | * This is not necessary for synchronous direct I/O, but we do |
1417 | * it anyway to keep the code uniform and simpler. | 1435 | * it anyway to keep the code uniform and simpler. |
1418 | * | 1436 | * |
1437 | * Well, if only it were that simple. Because synchronous direct I/O | ||
1438 | * requires extent conversion to occur *before* we return to userspace, | ||
1439 | * we have to wait for extent conversion to complete. Look at the | ||
1440 | * iocb that has been passed to us to determine if this is AIO or | ||
1441 | * not. If it is synchronous, tell xfs_finish_ioend() to kick the | ||
1442 | * workqueue and wait for it to complete. | ||
1443 | * | ||
1419 | * The core direct I/O code might be changed to always call the | 1444 | * The core direct I/O code might be changed to always call the |
1420 | * completion handler in the future, in which case all this can | 1445 | * completion handler in the future, in which case all this can |
1421 | * go away. | 1446 | * go away. |
@@ -1423,9 +1448,9 @@ xfs_end_io_direct( | |||
1423 | ioend->io_offset = offset; | 1448 | ioend->io_offset = offset; |
1424 | ioend->io_size = size; | 1449 | ioend->io_size = size; |
1425 | if (ioend->io_type == IOMAP_READ) { | 1450 | if (ioend->io_type == IOMAP_READ) { |
1426 | xfs_finish_ioend(ioend); | 1451 | xfs_finish_ioend(ioend, 0); |
1427 | } else if (private && size > 0) { | 1452 | } else if (private && size > 0) { |
1428 | xfs_finish_ioend(ioend); | 1453 | xfs_finish_ioend(ioend, is_sync_kiocb(iocb)); |
1429 | } else { | 1454 | } else { |
1430 | /* | 1455 | /* |
1431 | * A direct I/O write ioend starts it's life in unwritten | 1456 | * A direct I/O write ioend starts it's life in unwritten |
@@ -1434,7 +1459,7 @@ xfs_end_io_direct( | |||
1434 | * handler. | 1459 | * handler. |
1435 | */ | 1460 | */ |
1436 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); | 1461 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); |
1437 | xfs_finish_ioend(ioend); | 1462 | xfs_finish_ioend(ioend, 0); |
1438 | } | 1463 | } |
1439 | 1464 | ||
1440 | /* | 1465 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index fe4f66a5af1..2df63622354 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
36 | 36 | ||
37 | static kmem_zone_t *xfs_buf_zone; | 37 | static kmem_zone_t *xfs_buf_zone; |
38 | static kmem_shaker_t xfs_buf_shake; | 38 | static struct shrinker *xfs_buf_shake; |
39 | STATIC int xfsbufd(void *); | 39 | STATIC int xfsbufd(void *); |
40 | STATIC int xfsbufd_wakeup(int, gfp_t); | 40 | STATIC int xfsbufd_wakeup(int, gfp_t); |
41 | STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); | 41 | STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); |
@@ -314,7 +314,7 @@ xfs_buf_free( | |||
314 | 314 | ||
315 | ASSERT(list_empty(&bp->b_hash_list)); | 315 | ASSERT(list_empty(&bp->b_hash_list)); |
316 | 316 | ||
317 | if (bp->b_flags & _XBF_PAGE_CACHE) { | 317 | if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) { |
318 | uint i; | 318 | uint i; |
319 | 319 | ||
320 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) | 320 | if ((bp->b_flags & XBF_MAPPED) && (bp->b_page_count > 1)) |
@@ -323,18 +323,11 @@ xfs_buf_free( | |||
323 | for (i = 0; i < bp->b_page_count; i++) { | 323 | for (i = 0; i < bp->b_page_count; i++) { |
324 | struct page *page = bp->b_pages[i]; | 324 | struct page *page = bp->b_pages[i]; |
325 | 325 | ||
326 | ASSERT(!PagePrivate(page)); | 326 | if (bp->b_flags & _XBF_PAGE_CACHE) |
327 | ASSERT(!PagePrivate(page)); | ||
327 | page_cache_release(page); | 328 | page_cache_release(page); |
328 | } | 329 | } |
329 | _xfs_buf_free_pages(bp); | 330 | _xfs_buf_free_pages(bp); |
330 | } else if (bp->b_flags & _XBF_KMEM_ALLOC) { | ||
331 | /* | ||
332 | * XXX(hch): bp->b_count_desired might be incorrect (see | ||
333 | * xfs_buf_associate_memory for details), but fortunately | ||
334 | * the Linux version of kmem_free ignores the len argument.. | ||
335 | */ | ||
336 | kmem_free(bp->b_addr, bp->b_count_desired); | ||
337 | _xfs_buf_free_pages(bp); | ||
338 | } | 331 | } |
339 | 332 | ||
340 | xfs_buf_deallocate(bp); | 333 | xfs_buf_deallocate(bp); |
@@ -764,43 +757,44 @@ xfs_buf_get_noaddr( | |||
764 | size_t len, | 757 | size_t len, |
765 | xfs_buftarg_t *target) | 758 | xfs_buftarg_t *target) |
766 | { | 759 | { |
767 | size_t malloc_len = len; | 760 | unsigned long page_count = PAGE_ALIGN(len) >> PAGE_SHIFT; |
761 | int error, i; | ||
768 | xfs_buf_t *bp; | 762 | xfs_buf_t *bp; |
769 | void *data; | ||
770 | int error; | ||
771 | 763 | ||
772 | bp = xfs_buf_allocate(0); | 764 | bp = xfs_buf_allocate(0); |
773 | if (unlikely(bp == NULL)) | 765 | if (unlikely(bp == NULL)) |
774 | goto fail; | 766 | goto fail; |
775 | _xfs_buf_initialize(bp, target, 0, len, 0); | 767 | _xfs_buf_initialize(bp, target, 0, len, 0); |
776 | 768 | ||
777 | try_again: | 769 | error = _xfs_buf_get_pages(bp, page_count, 0); |
778 | data = kmem_alloc(malloc_len, KM_SLEEP | KM_MAYFAIL | KM_LARGE); | 770 | if (error) |
779 | if (unlikely(data == NULL)) | ||
780 | goto fail_free_buf; | 771 | goto fail_free_buf; |
781 | 772 | ||
782 | /* check whether alignment matches.. */ | 773 | for (i = 0; i < page_count; i++) { |
783 | if ((__psunsigned_t)data != | 774 | bp->b_pages[i] = alloc_page(GFP_KERNEL); |
784 | ((__psunsigned_t)data & ~target->bt_smask)) { | 775 | if (!bp->b_pages[i]) |
785 | /* .. else double the size and try again */ | 776 | goto fail_free_mem; |
786 | kmem_free(data, malloc_len); | ||
787 | malloc_len <<= 1; | ||
788 | goto try_again; | ||
789 | } | 777 | } |
778 | bp->b_flags |= _XBF_PAGES; | ||
790 | 779 | ||
791 | error = xfs_buf_associate_memory(bp, data, len); | 780 | error = _xfs_buf_map_pages(bp, XBF_MAPPED); |
792 | if (error) | 781 | if (unlikely(error)) { |
782 | printk(KERN_WARNING "%s: failed to map pages\n", | ||
783 | __FUNCTION__); | ||
793 | goto fail_free_mem; | 784 | goto fail_free_mem; |
794 | bp->b_flags |= _XBF_KMEM_ALLOC; | 785 | } |
795 | 786 | ||
796 | xfs_buf_unlock(bp); | 787 | xfs_buf_unlock(bp); |
797 | 788 | ||
798 | XB_TRACE(bp, "no_daddr", data); | 789 | XB_TRACE(bp, "no_daddr", len); |
799 | return bp; | 790 | return bp; |
791 | |||
800 | fail_free_mem: | 792 | fail_free_mem: |
801 | kmem_free(data, malloc_len); | 793 | while (--i >= 0) |
794 | __free_page(bp->b_pages[i]); | ||
795 | _xfs_buf_free_pages(bp); | ||
802 | fail_free_buf: | 796 | fail_free_buf: |
803 | xfs_buf_free(bp); | 797 | xfs_buf_deallocate(bp); |
804 | fail: | 798 | fail: |
805 | return NULL; | 799 | return NULL; |
806 | } | 800 | } |
@@ -1453,6 +1447,7 @@ xfs_free_buftarg( | |||
1453 | int external) | 1447 | int external) |
1454 | { | 1448 | { |
1455 | xfs_flush_buftarg(btp, 1); | 1449 | xfs_flush_buftarg(btp, 1); |
1450 | xfs_blkdev_issue_flush(btp); | ||
1456 | if (external) | 1451 | if (external) |
1457 | xfs_blkdev_put(btp->bt_bdev); | 1452 | xfs_blkdev_put(btp->bt_bdev); |
1458 | xfs_free_bufhash(btp); | 1453 | xfs_free_bufhash(btp); |
@@ -1837,7 +1832,7 @@ xfs_buf_init(void) | |||
1837 | if (!xfsdatad_workqueue) | 1832 | if (!xfsdatad_workqueue) |
1838 | goto out_destroy_xfslogd_workqueue; | 1833 | goto out_destroy_xfslogd_workqueue; |
1839 | 1834 | ||
1840 | xfs_buf_shake = kmem_shake_register(xfsbufd_wakeup); | 1835 | xfs_buf_shake = set_shrinker(DEFAULT_SEEKS, xfsbufd_wakeup); |
1841 | if (!xfs_buf_shake) | 1836 | if (!xfs_buf_shake) |
1842 | goto out_destroy_xfsdatad_workqueue; | 1837 | goto out_destroy_xfsdatad_workqueue; |
1843 | 1838 | ||
@@ -1859,7 +1854,7 @@ xfs_buf_init(void) | |||
1859 | void | 1854 | void |
1860 | xfs_buf_terminate(void) | 1855 | xfs_buf_terminate(void) |
1861 | { | 1856 | { |
1862 | kmem_shake_deregister(xfs_buf_shake); | 1857 | remove_shrinker(xfs_buf_shake); |
1863 | destroy_workqueue(xfsdatad_workqueue); | 1858 | destroy_workqueue(xfsdatad_workqueue); |
1864 | destroy_workqueue(xfslogd_workqueue); | 1859 | destroy_workqueue(xfslogd_workqueue); |
1865 | kmem_zone_destroy(xfs_buf_zone); | 1860 | kmem_zone_destroy(xfs_buf_zone); |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index b6241f6201a..b5908a34b15 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -63,7 +63,7 @@ typedef enum { | |||
63 | 63 | ||
64 | /* flags used only internally */ | 64 | /* flags used only internally */ |
65 | _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */ | 65 | _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */ |
66 | _XBF_KMEM_ALLOC = (1 << 18),/* backed by kmem_alloc() */ | 66 | _XBF_PAGES = (1 << 18), /* backed by refcounted pages */ |
67 | _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ | 67 | _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */ |
68 | _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ | 68 | _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */ |
69 | } xfs_buf_flags_t; | 69 | } xfs_buf_flags_t; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 8c43cd2e237..cbcd40c8c2a 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -184,15 +184,6 @@ xfs_file_open( | |||
184 | } | 184 | } |
185 | 185 | ||
186 | STATIC int | 186 | STATIC int |
187 | xfs_file_close( | ||
188 | struct file *filp, | ||
189 | fl_owner_t id) | ||
190 | { | ||
191 | return -bhv_vop_close(vn_from_inode(filp->f_path.dentry->d_inode), 0, | ||
192 | file_count(filp) > 1 ? L_FALSE : L_TRUE, NULL); | ||
193 | } | ||
194 | |||
195 | STATIC int | ||
196 | xfs_file_release( | 187 | xfs_file_release( |
197 | struct inode *inode, | 188 | struct inode *inode, |
198 | struct file *filp) | 189 | struct file *filp) |
@@ -436,7 +427,6 @@ const struct file_operations xfs_file_operations = { | |||
436 | #endif | 427 | #endif |
437 | .mmap = xfs_file_mmap, | 428 | .mmap = xfs_file_mmap, |
438 | .open = xfs_file_open, | 429 | .open = xfs_file_open, |
439 | .flush = xfs_file_close, | ||
440 | .release = xfs_file_release, | 430 | .release = xfs_file_release, |
441 | .fsync = xfs_file_fsync, | 431 | .fsync = xfs_file_fsync, |
442 | #ifdef HAVE_FOP_OPEN_EXEC | 432 | #ifdef HAVE_FOP_OPEN_EXEC |
@@ -458,7 +448,6 @@ const struct file_operations xfs_invis_file_operations = { | |||
458 | #endif | 448 | #endif |
459 | .mmap = xfs_file_mmap, | 449 | .mmap = xfs_file_mmap, |
460 | .open = xfs_file_open, | 450 | .open = xfs_file_open, |
461 | .flush = xfs_file_close, | ||
462 | .release = xfs_file_release, | 451 | .release = xfs_file_release, |
463 | .fsync = xfs_file_fsync, | 452 | .fsync = xfs_file_fsync, |
464 | }; | 453 | }; |
diff --git a/fs/xfs/linux-2.6/xfs_globals.c b/fs/xfs/linux-2.6/xfs_globals.c index ed3a5e1b4b6..bb72c3d4141 100644 --- a/fs/xfs/linux-2.6/xfs_globals.c +++ b/fs/xfs/linux-2.6/xfs_globals.c | |||
@@ -46,6 +46,7 @@ xfs_param_t xfs_params = { | |||
46 | .inherit_nosym = { 0, 0, 1 }, | 46 | .inherit_nosym = { 0, 0, 1 }, |
47 | .rotorstep = { 1, 1, 255 }, | 47 | .rotorstep = { 1, 1, 255 }, |
48 | .inherit_nodfrg = { 0, 1, 1 }, | 48 | .inherit_nodfrg = { 0, 1, 1 }, |
49 | .fstrm_timer = { 1, 50, 3600*100}, | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* | 52 | /* |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index ff5c41ff8d4..5917808abbd 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -1019,7 +1019,7 @@ xfs_ioc_bulkstat( | |||
1019 | 1019 | ||
1020 | if (cmd == XFS_IOC_FSINUMBERS) | 1020 | if (cmd == XFS_IOC_FSINUMBERS) |
1021 | error = xfs_inumbers(mp, &inlast, &count, | 1021 | error = xfs_inumbers(mp, &inlast, &count, |
1022 | bulkreq.ubuffer); | 1022 | bulkreq.ubuffer, xfs_inumbers_fmt); |
1023 | else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) | 1023 | else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) |
1024 | error = xfs_bulkstat_single(mp, &inlast, | 1024 | error = xfs_bulkstat_single(mp, &inlast, |
1025 | bulkreq.ubuffer, &done); | 1025 | bulkreq.ubuffer, &done); |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index b83cebc165f..141cf15067c 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
@@ -23,10 +23,25 @@ | |||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
25 | #include "xfs.h" | 25 | #include "xfs.h" |
26 | #include "xfs_types.h" | ||
27 | #include "xfs_fs.h" | 26 | #include "xfs_fs.h" |
27 | #include "xfs_bit.h" | ||
28 | #include "xfs_log.h" | ||
29 | #include "xfs_inum.h" | ||
30 | #include "xfs_trans.h" | ||
31 | #include "xfs_sb.h" | ||
32 | #include "xfs_ag.h" | ||
33 | #include "xfs_dir2.h" | ||
34 | #include "xfs_dmapi.h" | ||
35 | #include "xfs_mount.h" | ||
36 | #include "xfs_bmap_btree.h" | ||
37 | #include "xfs_attr_sf.h" | ||
38 | #include "xfs_dir2_sf.h" | ||
28 | #include "xfs_vfs.h" | 39 | #include "xfs_vfs.h" |
29 | #include "xfs_vnode.h" | 40 | #include "xfs_vnode.h" |
41 | #include "xfs_dinode.h" | ||
42 | #include "xfs_inode.h" | ||
43 | #include "xfs_itable.h" | ||
44 | #include "xfs_error.h" | ||
30 | #include "xfs_dfrag.h" | 45 | #include "xfs_dfrag.h" |
31 | 46 | ||
32 | #define _NATIVE_IOC(cmd, type) \ | 47 | #define _NATIVE_IOC(cmd, type) \ |
@@ -34,6 +49,7 @@ | |||
34 | 49 | ||
35 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) | 50 | #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) |
36 | #define BROKEN_X86_ALIGNMENT | 51 | #define BROKEN_X86_ALIGNMENT |
52 | #define _PACKED __attribute__((packed)) | ||
37 | /* on ia32 l_start is on a 32-bit boundary */ | 53 | /* on ia32 l_start is on a 32-bit boundary */ |
38 | typedef struct xfs_flock64_32 { | 54 | typedef struct xfs_flock64_32 { |
39 | __s16 l_type; | 55 | __s16 l_type; |
@@ -75,35 +91,276 @@ xfs_ioctl32_flock( | |||
75 | return (unsigned long)p; | 91 | return (unsigned long)p; |
76 | } | 92 | } |
77 | 93 | ||
94 | typedef struct compat_xfs_fsop_geom_v1 { | ||
95 | __u32 blocksize; /* filesystem (data) block size */ | ||
96 | __u32 rtextsize; /* realtime extent size */ | ||
97 | __u32 agblocks; /* fsblocks in an AG */ | ||
98 | __u32 agcount; /* number of allocation groups */ | ||
99 | __u32 logblocks; /* fsblocks in the log */ | ||
100 | __u32 sectsize; /* (data) sector size, bytes */ | ||
101 | __u32 inodesize; /* inode size in bytes */ | ||
102 | __u32 imaxpct; /* max allowed inode space(%) */ | ||
103 | __u64 datablocks; /* fsblocks in data subvolume */ | ||
104 | __u64 rtblocks; /* fsblocks in realtime subvol */ | ||
105 | __u64 rtextents; /* rt extents in realtime subvol*/ | ||
106 | __u64 logstart; /* starting fsblock of the log */ | ||
107 | unsigned char uuid[16]; /* unique id of the filesystem */ | ||
108 | __u32 sunit; /* stripe unit, fsblocks */ | ||
109 | __u32 swidth; /* stripe width, fsblocks */ | ||
110 | __s32 version; /* structure version */ | ||
111 | __u32 flags; /* superblock version flags */ | ||
112 | __u32 logsectsize; /* log sector size, bytes */ | ||
113 | __u32 rtsectsize; /* realtime sector size, bytes */ | ||
114 | __u32 dirblocksize; /* directory block size, bytes */ | ||
115 | } __attribute__((packed)) compat_xfs_fsop_geom_v1_t; | ||
116 | |||
117 | #define XFS_IOC_FSGEOMETRY_V1_32 \ | ||
118 | _IOR ('X', 100, struct compat_xfs_fsop_geom_v1) | ||
119 | |||
120 | STATIC unsigned long xfs_ioctl32_geom_v1(unsigned long arg) | ||
121 | { | ||
122 | compat_xfs_fsop_geom_v1_t __user *p32 = (void __user *)arg; | ||
123 | xfs_fsop_geom_v1_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
124 | |||
125 | if (copy_in_user(p, p32, sizeof(*p32))) | ||
126 | return -EFAULT; | ||
127 | return (unsigned long)p; | ||
128 | } | ||
129 | |||
130 | typedef struct compat_xfs_inogrp { | ||
131 | __u64 xi_startino; /* starting inode number */ | ||
132 | __s32 xi_alloccount; /* # bits set in allocmask */ | ||
133 | __u64 xi_allocmask; /* mask of allocated inodes */ | ||
134 | } __attribute__((packed)) compat_xfs_inogrp_t; | ||
135 | |||
136 | STATIC int xfs_inumbers_fmt_compat( | ||
137 | void __user *ubuffer, | ||
138 | const xfs_inogrp_t *buffer, | ||
139 | long count, | ||
140 | long *written) | ||
141 | { | ||
142 | compat_xfs_inogrp_t *p32 = ubuffer; | ||
143 | long i; | ||
144 | |||
145 | for (i = 0; i < count; i++) { | ||
146 | if (put_user(buffer[i].xi_startino, &p32[i].xi_startino) || | ||
147 | put_user(buffer[i].xi_alloccount, &p32[i].xi_alloccount) || | ||
148 | put_user(buffer[i].xi_allocmask, &p32[i].xi_allocmask)) | ||
149 | return -EFAULT; | ||
150 | } | ||
151 | *written = count * sizeof(*p32); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
78 | #else | 155 | #else |
79 | 156 | ||
80 | typedef struct xfs_fsop_bulkreq32 { | 157 | #define xfs_inumbers_fmt_compat xfs_inumbers_fmt |
158 | #define _PACKED | ||
159 | |||
160 | #endif | ||
161 | |||
162 | /* XFS_IOC_FSBULKSTAT and friends */ | ||
163 | |||
164 | typedef struct compat_xfs_bstime { | ||
165 | __s32 tv_sec; /* seconds */ | ||
166 | __s32 tv_nsec; /* and nanoseconds */ | ||
167 | } compat_xfs_bstime_t; | ||
168 | |||
169 | STATIC int xfs_bstime_store_compat( | ||
170 | compat_xfs_bstime_t __user *p32, | ||
171 | const xfs_bstime_t *p) | ||
172 | { | ||
173 | __s32 sec32; | ||
174 | |||
175 | sec32 = p->tv_sec; | ||
176 | if (put_user(sec32, &p32->tv_sec) || | ||
177 | put_user(p->tv_nsec, &p32->tv_nsec)) | ||
178 | return -EFAULT; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | typedef struct compat_xfs_bstat { | ||
183 | __u64 bs_ino; /* inode number */ | ||
184 | __u16 bs_mode; /* type and mode */ | ||
185 | __u16 bs_nlink; /* number of links */ | ||
186 | __u32 bs_uid; /* user id */ | ||
187 | __u32 bs_gid; /* group id */ | ||
188 | __u32 bs_rdev; /* device value */ | ||
189 | __s32 bs_blksize; /* block size */ | ||
190 | __s64 bs_size; /* file size */ | ||
191 | compat_xfs_bstime_t bs_atime; /* access time */ | ||
192 | compat_xfs_bstime_t bs_mtime; /* modify time */ | ||
193 | compat_xfs_bstime_t bs_ctime; /* inode change time */ | ||
194 | int64_t bs_blocks; /* number of blocks */ | ||
195 | __u32 bs_xflags; /* extended flags */ | ||
196 | __s32 bs_extsize; /* extent size */ | ||
197 | __s32 bs_extents; /* number of extents */ | ||
198 | __u32 bs_gen; /* generation count */ | ||
199 | __u16 bs_projid; /* project id */ | ||
200 | unsigned char bs_pad[14]; /* pad space, unused */ | ||
201 | __u32 bs_dmevmask; /* DMIG event mask */ | ||
202 | __u16 bs_dmstate; /* DMIG state info */ | ||
203 | __u16 bs_aextents; /* attribute number of extents */ | ||
204 | } _PACKED compat_xfs_bstat_t; | ||
205 | |||
206 | STATIC int xfs_bulkstat_one_fmt_compat( | ||
207 | void __user *ubuffer, | ||
208 | const xfs_bstat_t *buffer) | ||
209 | { | ||
210 | compat_xfs_bstat_t __user *p32 = ubuffer; | ||
211 | |||
212 | if (put_user(buffer->bs_ino, &p32->bs_ino) || | ||
213 | put_user(buffer->bs_mode, &p32->bs_mode) || | ||
214 | put_user(buffer->bs_nlink, &p32->bs_nlink) || | ||
215 | put_user(buffer->bs_uid, &p32->bs_uid) || | ||
216 | put_user(buffer->bs_gid, &p32->bs_gid) || | ||
217 | put_user(buffer->bs_rdev, &p32->bs_rdev) || | ||
218 | put_user(buffer->bs_blksize, &p32->bs_blksize) || | ||
219 | put_user(buffer->bs_size, &p32->bs_size) || | ||
220 | xfs_bstime_store_compat(&p32->bs_atime, &buffer->bs_atime) || | ||
221 | xfs_bstime_store_compat(&p32->bs_mtime, &buffer->bs_mtime) || | ||
222 | xfs_bstime_store_compat(&p32->bs_ctime, &buffer->bs_ctime) || | ||
223 | put_user(buffer->bs_blocks, &p32->bs_blocks) || | ||
224 | put_user(buffer->bs_xflags, &p32->bs_xflags) || | ||
225 | put_user(buffer->bs_extsize, &p32->bs_extsize) || | ||
226 | put_user(buffer->bs_extents, &p32->bs_extents) || | ||
227 | put_user(buffer->bs_gen, &p32->bs_gen) || | ||
228 | put_user(buffer->bs_projid, &p32->bs_projid) || | ||
229 | put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) || | ||
230 | put_user(buffer->bs_dmstate, &p32->bs_dmstate) || | ||
231 | put_user(buffer->bs_aextents, &p32->bs_aextents)) | ||
232 | return -EFAULT; | ||
233 | return sizeof(*p32); | ||
234 | } | ||
235 | |||
236 | |||
237 | |||
238 | typedef struct compat_xfs_fsop_bulkreq { | ||
81 | compat_uptr_t lastip; /* last inode # pointer */ | 239 | compat_uptr_t lastip; /* last inode # pointer */ |
82 | __s32 icount; /* count of entries in buffer */ | 240 | __s32 icount; /* count of entries in buffer */ |
83 | compat_uptr_t ubuffer; /* user buffer for inode desc. */ | 241 | compat_uptr_t ubuffer; /* user buffer for inode desc. */ |
84 | __s32 ocount; /* output count pointer */ | 242 | compat_uptr_t ocount; /* output count pointer */ |
85 | } xfs_fsop_bulkreq32_t; | 243 | } compat_xfs_fsop_bulkreq_t; |
86 | 244 | ||
87 | STATIC unsigned long | 245 | #define XFS_IOC_FSBULKSTAT_32 \ |
88 | xfs_ioctl32_bulkstat( | 246 | _IOWR('X', 101, struct compat_xfs_fsop_bulkreq) |
89 | unsigned long arg) | 247 | #define XFS_IOC_FSBULKSTAT_SINGLE_32 \ |
248 | _IOWR('X', 102, struct compat_xfs_fsop_bulkreq) | ||
249 | #define XFS_IOC_FSINUMBERS_32 \ | ||
250 | _IOWR('X', 103, struct compat_xfs_fsop_bulkreq) | ||
251 | |||
252 | /* copied from xfs_ioctl.c */ | ||
253 | STATIC int | ||
254 | xfs_ioc_bulkstat_compat( | ||
255 | xfs_mount_t *mp, | ||
256 | unsigned int cmd, | ||
257 | void __user *arg) | ||
90 | { | 258 | { |
91 | xfs_fsop_bulkreq32_t __user *p32 = (void __user *)arg; | 259 | compat_xfs_fsop_bulkreq_t __user *p32 = (void __user *)arg; |
92 | xfs_fsop_bulkreq_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
93 | u32 addr; | 260 | u32 addr; |
261 | xfs_fsop_bulkreq_t bulkreq; | ||
262 | int count; /* # of records returned */ | ||
263 | xfs_ino_t inlast; /* last inode number */ | ||
264 | int done; | ||
265 | int error; | ||
266 | |||
267 | /* done = 1 if there are more stats to get and if bulkstat */ | ||
268 | /* should be called again (unused here, but used in dmapi) */ | ||
269 | |||
270 | if (!capable(CAP_SYS_ADMIN)) | ||
271 | return -EPERM; | ||
272 | |||
273 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
274 | return -XFS_ERROR(EIO); | ||
275 | |||
276 | if (get_user(addr, &p32->lastip)) | ||
277 | return -EFAULT; | ||
278 | bulkreq.lastip = compat_ptr(addr); | ||
279 | if (get_user(bulkreq.icount, &p32->icount) || | ||
280 | get_user(addr, &p32->ubuffer)) | ||
281 | return -EFAULT; | ||
282 | bulkreq.ubuffer = compat_ptr(addr); | ||
283 | if (get_user(addr, &p32->ocount)) | ||
284 | return -EFAULT; | ||
285 | bulkreq.ocount = compat_ptr(addr); | ||
286 | |||
287 | if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) | ||
288 | return -XFS_ERROR(EFAULT); | ||
289 | |||
290 | if ((count = bulkreq.icount) <= 0) | ||
291 | return -XFS_ERROR(EINVAL); | ||
292 | |||
293 | if (cmd == XFS_IOC_FSINUMBERS) | ||
294 | error = xfs_inumbers(mp, &inlast, &count, | ||
295 | bulkreq.ubuffer, xfs_inumbers_fmt_compat); | ||
296 | else { | ||
297 | /* declare a var to get a warning in case the type changes */ | ||
298 | bulkstat_one_fmt_pf formatter = xfs_bulkstat_one_fmt_compat; | ||
299 | error = xfs_bulkstat(mp, &inlast, &count, | ||
300 | xfs_bulkstat_one, formatter, | ||
301 | sizeof(compat_xfs_bstat_t), bulkreq.ubuffer, | ||
302 | BULKSTAT_FG_QUICK, &done); | ||
303 | } | ||
304 | if (error) | ||
305 | return -error; | ||
306 | |||
307 | if (bulkreq.ocount != NULL) { | ||
308 | if (copy_to_user(bulkreq.lastip, &inlast, | ||
309 | sizeof(xfs_ino_t))) | ||
310 | return -XFS_ERROR(EFAULT); | ||
311 | |||
312 | if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) | ||
313 | return -XFS_ERROR(EFAULT); | ||
314 | } | ||
315 | |||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | |||
320 | |||
321 | typedef struct compat_xfs_fsop_handlereq { | ||
322 | __u32 fd; /* fd for FD_TO_HANDLE */ | ||
323 | compat_uptr_t path; /* user pathname */ | ||
324 | __u32 oflags; /* open flags */ | ||
325 | compat_uptr_t ihandle; /* user supplied handle */ | ||
326 | __u32 ihandlen; /* user supplied length */ | ||
327 | compat_uptr_t ohandle; /* user buffer for handle */ | ||
328 | compat_uptr_t ohandlen; /* user buffer length */ | ||
329 | } compat_xfs_fsop_handlereq_t; | ||
330 | |||
331 | #define XFS_IOC_PATH_TO_FSHANDLE_32 \ | ||
332 | _IOWR('X', 104, struct compat_xfs_fsop_handlereq) | ||
333 | #define XFS_IOC_PATH_TO_HANDLE_32 \ | ||
334 | _IOWR('X', 105, struct compat_xfs_fsop_handlereq) | ||
335 | #define XFS_IOC_FD_TO_HANDLE_32 \ | ||
336 | _IOWR('X', 106, struct compat_xfs_fsop_handlereq) | ||
337 | #define XFS_IOC_OPEN_BY_HANDLE_32 \ | ||
338 | _IOWR('X', 107, struct compat_xfs_fsop_handlereq) | ||
339 | #define XFS_IOC_READLINK_BY_HANDLE_32 \ | ||
340 | _IOWR('X', 108, struct compat_xfs_fsop_handlereq) | ||
341 | |||
342 | STATIC unsigned long xfs_ioctl32_fshandle(unsigned long arg) | ||
343 | { | ||
344 | compat_xfs_fsop_handlereq_t __user *p32 = (void __user *)arg; | ||
345 | xfs_fsop_handlereq_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
346 | u32 addr; | ||
94 | 347 | ||
95 | if (get_user(addr, &p32->lastip) || | 348 | if (copy_in_user(&p->fd, &p32->fd, sizeof(__u32)) || |
96 | put_user(compat_ptr(addr), &p->lastip) || | 349 | get_user(addr, &p32->path) || |
97 | copy_in_user(&p->icount, &p32->icount, sizeof(s32)) || | 350 | put_user(compat_ptr(addr), &p->path) || |
98 | get_user(addr, &p32->ubuffer) || | 351 | copy_in_user(&p->oflags, &p32->oflags, sizeof(__u32)) || |
99 | put_user(compat_ptr(addr), &p->ubuffer) || | 352 | get_user(addr, &p32->ihandle) || |
100 | get_user(addr, &p32->ocount) || | 353 | put_user(compat_ptr(addr), &p->ihandle) || |
101 | put_user(compat_ptr(addr), &p->ocount)) | 354 | copy_in_user(&p->ihandlen, &p32->ihandlen, sizeof(__u32)) || |
355 | get_user(addr, &p32->ohandle) || | ||
356 | put_user(compat_ptr(addr), &p->ohandle) || | ||
357 | get_user(addr, &p32->ohandlen) || | ||
358 | put_user(compat_ptr(addr), &p->ohandlen)) | ||
102 | return -EFAULT; | 359 | return -EFAULT; |
103 | 360 | ||
104 | return (unsigned long)p; | 361 | return (unsigned long)p; |
105 | } | 362 | } |
106 | #endif | 363 | |
107 | 364 | ||
108 | STATIC long | 365 | STATIC long |
109 | xfs_compat_ioctl( | 366 | xfs_compat_ioctl( |
@@ -118,7 +375,6 @@ xfs_compat_ioctl( | |||
118 | 375 | ||
119 | switch (cmd) { | 376 | switch (cmd) { |
120 | case XFS_IOC_DIOINFO: | 377 | case XFS_IOC_DIOINFO: |
121 | case XFS_IOC_FSGEOMETRY_V1: | ||
122 | case XFS_IOC_FSGEOMETRY: | 378 | case XFS_IOC_FSGEOMETRY: |
123 | case XFS_IOC_GETVERSION: | 379 | case XFS_IOC_GETVERSION: |
124 | case XFS_IOC_GETXFLAGS: | 380 | case XFS_IOC_GETXFLAGS: |
@@ -131,12 +387,7 @@ xfs_compat_ioctl( | |||
131 | case XFS_IOC_GETBMAPA: | 387 | case XFS_IOC_GETBMAPA: |
132 | case XFS_IOC_GETBMAPX: | 388 | case XFS_IOC_GETBMAPX: |
133 | /* not handled | 389 | /* not handled |
134 | case XFS_IOC_FD_TO_HANDLE: | ||
135 | case XFS_IOC_PATH_TO_HANDLE: | ||
136 | case XFS_IOC_PATH_TO_FSHANDLE: | ||
137 | case XFS_IOC_OPEN_BY_HANDLE: | ||
138 | case XFS_IOC_FSSETDM_BY_HANDLE: | 390 | case XFS_IOC_FSSETDM_BY_HANDLE: |
139 | case XFS_IOC_READLINK_BY_HANDLE: | ||
140 | case XFS_IOC_ATTRLIST_BY_HANDLE: | 391 | case XFS_IOC_ATTRLIST_BY_HANDLE: |
141 | case XFS_IOC_ATTRMULTI_BY_HANDLE: | 392 | case XFS_IOC_ATTRMULTI_BY_HANDLE: |
142 | */ | 393 | */ |
@@ -166,6 +417,10 @@ xfs_compat_ioctl( | |||
166 | arg = xfs_ioctl32_flock(arg); | 417 | arg = xfs_ioctl32_flock(arg); |
167 | cmd = _NATIVE_IOC(cmd, struct xfs_flock64); | 418 | cmd = _NATIVE_IOC(cmd, struct xfs_flock64); |
168 | break; | 419 | break; |
420 | case XFS_IOC_FSGEOMETRY_V1_32: | ||
421 | arg = xfs_ioctl32_geom_v1(arg); | ||
422 | cmd = _NATIVE_IOC(cmd, struct xfs_fsop_geom_v1); | ||
423 | break; | ||
169 | 424 | ||
170 | #else /* These are handled fine if no alignment issues */ | 425 | #else /* These are handled fine if no alignment issues */ |
171 | case XFS_IOC_ALLOCSP: | 426 | case XFS_IOC_ALLOCSP: |
@@ -176,18 +431,28 @@ xfs_compat_ioctl( | |||
176 | case XFS_IOC_FREESP64: | 431 | case XFS_IOC_FREESP64: |
177 | case XFS_IOC_RESVSP64: | 432 | case XFS_IOC_RESVSP64: |
178 | case XFS_IOC_UNRESVSP64: | 433 | case XFS_IOC_UNRESVSP64: |
434 | case XFS_IOC_FSGEOMETRY_V1: | ||
179 | break; | 435 | break; |
180 | 436 | ||
181 | /* xfs_bstat_t still has wrong u32 vs u64 alignment */ | 437 | /* xfs_bstat_t still has wrong u32 vs u64 alignment */ |
182 | case XFS_IOC_SWAPEXT: | 438 | case XFS_IOC_SWAPEXT: |
183 | break; | 439 | break; |
184 | 440 | ||
185 | case XFS_IOC_FSBULKSTAT_SINGLE: | ||
186 | case XFS_IOC_FSBULKSTAT: | ||
187 | case XFS_IOC_FSINUMBERS: | ||
188 | arg = xfs_ioctl32_bulkstat(arg); | ||
189 | break; | ||
190 | #endif | 441 | #endif |
442 | case XFS_IOC_FSBULKSTAT_32: | ||
443 | case XFS_IOC_FSBULKSTAT_SINGLE_32: | ||
444 | case XFS_IOC_FSINUMBERS_32: | ||
445 | cmd = _NATIVE_IOC(cmd, struct xfs_fsop_bulkreq); | ||
446 | return xfs_ioc_bulkstat_compat(XFS_BHVTOI(VNHEAD(vp))->i_mount, | ||
447 | cmd, (void*)arg); | ||
448 | case XFS_IOC_FD_TO_HANDLE_32: | ||
449 | case XFS_IOC_PATH_TO_HANDLE_32: | ||
450 | case XFS_IOC_PATH_TO_FSHANDLE_32: | ||
451 | case XFS_IOC_OPEN_BY_HANDLE_32: | ||
452 | case XFS_IOC_READLINK_BY_HANDLE_32: | ||
453 | arg = xfs_ioctl32_fshandle(arg); | ||
454 | cmd = _NATIVE_IOC(cmd, struct xfs_fsop_handlereq); | ||
455 | break; | ||
191 | default: | 456 | default: |
192 | return -ENOIOCTLCMD; | 457 | return -ENOIOCTLCMD; |
193 | } | 458 | } |
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index af24a457d3a..330c4ba9d40 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h | |||
@@ -123,6 +123,7 @@ | |||
123 | #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val | 123 | #define xfs_inherit_nosymlinks xfs_params.inherit_nosym.val |
124 | #define xfs_rotorstep xfs_params.rotorstep.val | 124 | #define xfs_rotorstep xfs_params.rotorstep.val |
125 | #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val | 125 | #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val |
126 | #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val | ||
126 | 127 | ||
127 | #define current_cpu() (raw_smp_processor_id()) | 128 | #define current_cpu() (raw_smp_processor_id()) |
128 | #define current_pid() (current->pid) | 129 | #define current_pid() (current->pid) |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index bf9a9d5909b..06894cf00b1 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -547,7 +547,8 @@ vfs_sync_worker( | |||
547 | 547 | ||
548 | if (!(vfsp->vfs_flag & VFS_RDONLY)) | 548 | if (!(vfsp->vfs_flag & VFS_RDONLY)) |
549 | error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \ | 549 | error = bhv_vfs_sync(vfsp, SYNC_FSDATA | SYNC_BDFLUSH | \ |
550 | SYNC_ATTR | SYNC_REFCACHE, NULL); | 550 | SYNC_ATTR | SYNC_REFCACHE | SYNC_SUPER, |
551 | NULL); | ||
551 | vfsp->vfs_sync_seq++; | 552 | vfsp->vfs_sync_seq++; |
552 | wake_up(&vfsp->vfs_wait_single_sync_task); | 553 | wake_up(&vfsp->vfs_wait_single_sync_task); |
553 | } | 554 | } |
@@ -663,7 +664,7 @@ xfs_fs_sync_super( | |||
663 | * occur here so don't bother flushing the buftarg (i.e | 664 | * occur here so don't bother flushing the buftarg (i.e |
664 | * SYNC_QUIESCE) because it'll just get dirty again. | 665 | * SYNC_QUIESCE) because it'll just get dirty again. |
665 | */ | 666 | */ |
666 | flags = SYNC_FSDATA | SYNC_DELWRI | SYNC_WAIT | SYNC_IOWAIT; | 667 | flags = SYNC_DATA_QUIESCE; |
667 | } else | 668 | } else |
668 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); | 669 | flags = SYNC_FSDATA | (wait ? SYNC_WAIT : 0); |
669 | 670 | ||
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c index cd6eaa44aa2..bb997d75c05 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.c +++ b/fs/xfs/linux-2.6/xfs_sysctl.c | |||
@@ -210,6 +210,17 @@ static ctl_table xfs_table[] = { | |||
210 | .extra1 = &xfs_params.inherit_nodfrg.min, | 210 | .extra1 = &xfs_params.inherit_nodfrg.min, |
211 | .extra2 = &xfs_params.inherit_nodfrg.max | 211 | .extra2 = &xfs_params.inherit_nodfrg.max |
212 | }, | 212 | }, |
213 | { | ||
214 | .ctl_name = XFS_FILESTREAM_TIMER, | ||
215 | .procname = "filestream_centisecs", | ||
216 | .data = &xfs_params.fstrm_timer.val, | ||
217 | .maxlen = sizeof(int), | ||
218 | .mode = 0644, | ||
219 | .proc_handler = &proc_dointvec_minmax, | ||
220 | .strategy = &sysctl_intvec, | ||
221 | .extra1 = &xfs_params.fstrm_timer.min, | ||
222 | .extra2 = &xfs_params.fstrm_timer.max, | ||
223 | }, | ||
213 | /* please keep this the last entry */ | 224 | /* please keep this the last entry */ |
214 | #ifdef CONFIG_PROC_FS | 225 | #ifdef CONFIG_PROC_FS |
215 | { | 226 | { |
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.h b/fs/xfs/linux-2.6/xfs_sysctl.h index a631fb8cc5a..98b97e399d6 100644 --- a/fs/xfs/linux-2.6/xfs_sysctl.h +++ b/fs/xfs/linux-2.6/xfs_sysctl.h | |||
@@ -47,6 +47,7 @@ typedef struct xfs_param { | |||
47 | xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ | 47 | xfs_sysctl_val_t inherit_nosym; /* Inherit the "nosymlinks" flag. */ |
48 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ | 48 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ |
49 | xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ | 49 | xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ |
50 | xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */ | ||
50 | } xfs_param_t; | 51 | } xfs_param_t; |
51 | 52 | ||
52 | /* | 53 | /* |
@@ -86,6 +87,7 @@ enum { | |||
86 | XFS_INHERIT_NOSYM = 19, | 87 | XFS_INHERIT_NOSYM = 19, |
87 | XFS_ROTORSTEP = 20, | 88 | XFS_ROTORSTEP = 20, |
88 | XFS_INHERIT_NODFRG = 21, | 89 | XFS_INHERIT_NODFRG = 21, |
90 | XFS_FILESTREAM_TIMER = 22, | ||
89 | }; | 91 | }; |
90 | 92 | ||
91 | extern xfs_param_t xfs_params; | 93 | extern xfs_param_t xfs_params; |
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h index e2c2ce98ab5..dca3481aaaf 100644 --- a/fs/xfs/linux-2.6/xfs_vfs.h +++ b/fs/xfs/linux-2.6/xfs_vfs.h | |||
@@ -92,6 +92,21 @@ typedef enum { | |||
92 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ | 92 | #define SYNC_REFCACHE 0x0040 /* prune some of the nfs ref cache */ |
93 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ | 93 | #define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ |
94 | #define SYNC_IOWAIT 0x0100 /* wait for all I/O to complete */ | 94 | #define SYNC_IOWAIT 0x0100 /* wait for all I/O to complete */ |
95 | #define SYNC_SUPER 0x0200 /* flush superblock to disk */ | ||
96 | |||
97 | /* | ||
98 | * When remounting a filesystem read-only or freezing the filesystem, | ||
99 | * we have two phases to execute. This first phase is syncing the data | ||
100 | * before we quiesce the fielsystem, and the second is flushing all the | ||
101 | * inodes out after we've waited for all the transactions created by | ||
102 | * the first phase to complete. The second phase uses SYNC_INODE_QUIESCE | ||
103 | * to ensure that the inodes are written to their location on disk | ||
104 | * rather than just existing in transactions in the log. This means | ||
105 | * after a quiesce there is no log replay required to write the inodes | ||
106 | * to disk (this is the main difference between a sync and a quiesce). | ||
107 | */ | ||
108 | #define SYNC_DATA_QUIESCE (SYNC_DELWRI|SYNC_FSDATA|SYNC_WAIT|SYNC_IOWAIT) | ||
109 | #define SYNC_INODE_QUIESCE (SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT) | ||
95 | 110 | ||
96 | #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ | 111 | #define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */ |
97 | #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ | 112 | #define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */ |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 013048a9264..5742d65f078 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -129,10 +129,7 @@ typedef enum bhv_vchange { | |||
129 | VCHANGE_FLAGS_IOEXCL_COUNT = 4 | 129 | VCHANGE_FLAGS_IOEXCL_COUNT = 4 |
130 | } bhv_vchange_t; | 130 | } bhv_vchange_t; |
131 | 131 | ||
132 | typedef enum { L_FALSE, L_TRUE } lastclose_t; | ||
133 | |||
134 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); | 132 | typedef int (*vop_open_t)(bhv_desc_t *, struct cred *); |
135 | typedef int (*vop_close_t)(bhv_desc_t *, int, lastclose_t, struct cred *); | ||
136 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, | 133 | typedef ssize_t (*vop_read_t)(bhv_desc_t *, struct kiocb *, |
137 | const struct iovec *, unsigned int, | 134 | const struct iovec *, unsigned int, |
138 | loff_t *, int, struct cred *); | 135 | loff_t *, int, struct cred *); |
@@ -200,7 +197,6 @@ typedef int (*vop_iflush_t)(bhv_desc_t *, int); | |||
200 | typedef struct bhv_vnodeops { | 197 | typedef struct bhv_vnodeops { |
201 | bhv_position_t vn_position; /* position within behavior chain */ | 198 | bhv_position_t vn_position; /* position within behavior chain */ |
202 | vop_open_t vop_open; | 199 | vop_open_t vop_open; |
203 | vop_close_t vop_close; | ||
204 | vop_read_t vop_read; | 200 | vop_read_t vop_read; |
205 | vop_write_t vop_write; | 201 | vop_write_t vop_write; |
206 | vop_splice_read_t vop_splice_read; | 202 | vop_splice_read_t vop_splice_read; |
@@ -245,7 +241,6 @@ typedef struct bhv_vnodeops { | |||
245 | #define VNHEAD(vp) ((vp)->v_bh.bh_first) | 241 | #define VNHEAD(vp) ((vp)->v_bh.bh_first) |
246 | #define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op) | 242 | #define VOP(op, vp) (*((bhv_vnodeops_t *)VNHEAD(vp)->bd_ops)->op) |
247 | #define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr) | 243 | #define bhv_vop_open(vp, cr) VOP(vop_open, vp)(VNHEAD(vp),cr) |
248 | #define bhv_vop_close(vp, f,last,cr) VOP(vop_close, vp)(VNHEAD(vp),f,last,cr) | ||
249 | #define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \ | 244 | #define bhv_vop_read(vp,file,iov,segs,offset,ioflags,cr) \ |
250 | VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) | 245 | VOP(vop_read, vp)(VNHEAD(vp),file,iov,segs,offset,ioflags,cr) |
251 | #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ | 246 | #define bhv_vop_write(vp,file,iov,segs,offset,ioflags,cr) \ |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 3e4a8ad8a34..7def4c69934 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -62,10 +62,9 @@ uint ndquot; | |||
62 | 62 | ||
63 | kmem_zone_t *qm_dqzone; | 63 | kmem_zone_t *qm_dqzone; |
64 | kmem_zone_t *qm_dqtrxzone; | 64 | kmem_zone_t *qm_dqtrxzone; |
65 | static kmem_shaker_t xfs_qm_shaker; | 65 | static struct shrinker *xfs_qm_shaker; |
66 | 66 | ||
67 | static cred_t xfs_zerocr; | 67 | static cred_t xfs_zerocr; |
68 | static xfs_inode_t xfs_zeroino; | ||
69 | 68 | ||
70 | STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); | 69 | STATIC void xfs_qm_list_init(xfs_dqlist_t *, char *, int); |
71 | STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); | 70 | STATIC void xfs_qm_list_destroy(xfs_dqlist_t *); |
@@ -150,7 +149,7 @@ xfs_Gqm_init(void) | |||
150 | } else | 149 | } else |
151 | xqm->qm_dqzone = qm_dqzone; | 150 | xqm->qm_dqzone = qm_dqzone; |
152 | 151 | ||
153 | xfs_qm_shaker = kmem_shake_register(xfs_qm_shake); | 152 | xfs_qm_shaker = set_shrinker(DEFAULT_SEEKS, xfs_qm_shake); |
154 | 153 | ||
155 | /* | 154 | /* |
156 | * The t_dqinfo portion of transactions. | 155 | * The t_dqinfo portion of transactions. |
@@ -182,7 +181,7 @@ xfs_qm_destroy( | |||
182 | 181 | ||
183 | ASSERT(xqm != NULL); | 182 | ASSERT(xqm != NULL); |
184 | ASSERT(xqm->qm_nrefs == 0); | 183 | ASSERT(xqm->qm_nrefs == 0); |
185 | kmem_shake_deregister(xfs_qm_shaker); | 184 | remove_shrinker(xfs_qm_shaker); |
186 | hsize = xqm->qm_dqhashmask + 1; | 185 | hsize = xqm->qm_dqhashmask + 1; |
187 | for (i = 0; i < hsize; i++) { | 186 | for (i = 0; i < hsize; i++) { |
188 | xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i])); | 187 | xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i])); |
@@ -1415,7 +1414,7 @@ xfs_qm_qino_alloc( | |||
1415 | return error; | 1414 | return error; |
1416 | } | 1415 | } |
1417 | 1416 | ||
1418 | if ((error = xfs_dir_ialloc(&tp, &xfs_zeroino, S_IFREG, 1, 0, | 1417 | if ((error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, |
1419 | &xfs_zerocr, 0, 1, ip, &committed))) { | 1418 | &xfs_zerocr, 0, 1, ip, &committed))) { |
1420 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | | 1419 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | |
1421 | XFS_TRANS_ABORT); | 1420 | XFS_TRANS_ABORT); |
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index bf0a12040b1..b5a7d92c684 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #define XFS_RW_TRACE 1 | 38 | #define XFS_RW_TRACE 1 |
39 | #define XFS_BUF_TRACE 1 | 39 | #define XFS_BUF_TRACE 1 |
40 | #define XFS_VNODE_TRACE 1 | 40 | #define XFS_VNODE_TRACE 1 |
41 | #define XFS_FILESTREAMS_TRACE 1 | ||
41 | #endif | 42 | #endif |
42 | 43 | ||
43 | #include <linux-2.6/xfs_linux.h> | 44 | #include <linux-2.6/xfs_linux.h> |
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 9ece7f87ec5..51c09c114a2 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -68,6 +68,7 @@ typedef struct xfs_agf { | |||
68 | __be32 agf_flcount; /* count of blocks in freelist */ | 68 | __be32 agf_flcount; /* count of blocks in freelist */ |
69 | __be32 agf_freeblks; /* total free blocks */ | 69 | __be32 agf_freeblks; /* total free blocks */ |
70 | __be32 agf_longest; /* longest free space */ | 70 | __be32 agf_longest; /* longest free space */ |
71 | __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ | ||
71 | } xfs_agf_t; | 72 | } xfs_agf_t; |
72 | 73 | ||
73 | #define XFS_AGF_MAGICNUM 0x00000001 | 74 | #define XFS_AGF_MAGICNUM 0x00000001 |
@@ -81,7 +82,8 @@ typedef struct xfs_agf { | |||
81 | #define XFS_AGF_FLCOUNT 0x00000100 | 82 | #define XFS_AGF_FLCOUNT 0x00000100 |
82 | #define XFS_AGF_FREEBLKS 0x00000200 | 83 | #define XFS_AGF_FREEBLKS 0x00000200 |
83 | #define XFS_AGF_LONGEST 0x00000400 | 84 | #define XFS_AGF_LONGEST 0x00000400 |
84 | #define XFS_AGF_NUM_BITS 11 | 85 | #define XFS_AGF_BTREEBLKS 0x00000800 |
86 | #define XFS_AGF_NUM_BITS 12 | ||
85 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) | 87 | #define XFS_AGF_ALL_BITS ((1 << XFS_AGF_NUM_BITS) - 1) |
86 | 88 | ||
87 | /* disk block (xfs_daddr_t) in the AG */ | 89 | /* disk block (xfs_daddr_t) in the AG */ |
@@ -186,12 +188,15 @@ typedef struct xfs_perag | |||
186 | __uint32_t pagf_flcount; /* count of blocks in freelist */ | 188 | __uint32_t pagf_flcount; /* count of blocks in freelist */ |
187 | xfs_extlen_t pagf_freeblks; /* total free blocks */ | 189 | xfs_extlen_t pagf_freeblks; /* total free blocks */ |
188 | xfs_extlen_t pagf_longest; /* longest free space */ | 190 | xfs_extlen_t pagf_longest; /* longest free space */ |
191 | __uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */ | ||
189 | xfs_agino_t pagi_freecount; /* number of free inodes */ | 192 | xfs_agino_t pagi_freecount; /* number of free inodes */ |
193 | xfs_agino_t pagi_count; /* number of allocated inodes */ | ||
194 | int pagb_count; /* pagb slots in use */ | ||
190 | #ifdef __KERNEL__ | 195 | #ifdef __KERNEL__ |
191 | lock_t pagb_lock; /* lock for pagb_list */ | 196 | lock_t pagb_lock; /* lock for pagb_list */ |
192 | #endif | 197 | #endif |
193 | int pagb_count; /* pagb slots in use */ | ||
194 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ | 198 | xfs_perag_busy_t *pagb_list; /* unstable blocks */ |
199 | atomic_t pagf_fstrms; /* # of filestreams active in this AG */ | ||
195 | } xfs_perag_t; | 200 | } xfs_perag_t; |
196 | 201 | ||
197 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) | 202 | #define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels) |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 8e9a40aa0cd..012a649a19c 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -55,17 +55,17 @@ xfs_alloc_search_busy(xfs_trans_t *tp, | |||
55 | ktrace_t *xfs_alloc_trace_buf; | 55 | ktrace_t *xfs_alloc_trace_buf; |
56 | 56 | ||
57 | #define TRACE_ALLOC(s,a) \ | 57 | #define TRACE_ALLOC(s,a) \ |
58 | xfs_alloc_trace_alloc(fname, s, a, __LINE__) | 58 | xfs_alloc_trace_alloc(__FUNCTION__, s, a, __LINE__) |
59 | #define TRACE_FREE(s,a,b,x,f) \ | 59 | #define TRACE_FREE(s,a,b,x,f) \ |
60 | xfs_alloc_trace_free(fname, s, mp, a, b, x, f, __LINE__) | 60 | xfs_alloc_trace_free(__FUNCTION__, s, mp, a, b, x, f, __LINE__) |
61 | #define TRACE_MODAGF(s,a,f) \ | 61 | #define TRACE_MODAGF(s,a,f) \ |
62 | xfs_alloc_trace_modagf(fname, s, mp, a, f, __LINE__) | 62 | xfs_alloc_trace_modagf(__FUNCTION__, s, mp, a, f, __LINE__) |
63 | #define TRACE_BUSY(fname,s,ag,agb,l,sl,tp) \ | 63 | #define TRACE_BUSY(__FUNCTION__,s,ag,agb,l,sl,tp) \ |
64 | xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__) | 64 | xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSY, __LINE__) |
65 | #define TRACE_UNBUSY(fname,s,ag,sl,tp) \ | 65 | #define TRACE_UNBUSY(__FUNCTION__,s,ag,sl,tp) \ |
66 | xfs_alloc_trace_busy(fname, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__) | 66 | xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, -1, -1, sl, tp, XFS_ALLOC_KTRACE_UNBUSY, __LINE__) |
67 | #define TRACE_BUSYSEARCH(fname,s,ag,agb,l,sl,tp) \ | 67 | #define TRACE_BUSYSEARCH(__FUNCTION__,s,ag,agb,l,sl,tp) \ |
68 | xfs_alloc_trace_busy(fname, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__) | 68 | xfs_alloc_trace_busy(__FUNCTION__, s, mp, ag, agb, l, sl, tp, XFS_ALLOC_KTRACE_BUSYSEARCH, __LINE__) |
69 | #else | 69 | #else |
70 | #define TRACE_ALLOC(s,a) | 70 | #define TRACE_ALLOC(s,a) |
71 | #define TRACE_FREE(s,a,b,x,f) | 71 | #define TRACE_FREE(s,a,b,x,f) |
@@ -420,7 +420,7 @@ xfs_alloc_read_agfl( | |||
420 | */ | 420 | */ |
421 | STATIC void | 421 | STATIC void |
422 | xfs_alloc_trace_alloc( | 422 | xfs_alloc_trace_alloc( |
423 | char *name, /* function tag string */ | 423 | const char *name, /* function tag string */ |
424 | char *str, /* additional string */ | 424 | char *str, /* additional string */ |
425 | xfs_alloc_arg_t *args, /* allocation argument structure */ | 425 | xfs_alloc_arg_t *args, /* allocation argument structure */ |
426 | int line) /* source line number */ | 426 | int line) /* source line number */ |
@@ -453,7 +453,7 @@ xfs_alloc_trace_alloc( | |||
453 | */ | 453 | */ |
454 | STATIC void | 454 | STATIC void |
455 | xfs_alloc_trace_free( | 455 | xfs_alloc_trace_free( |
456 | char *name, /* function tag string */ | 456 | const char *name, /* function tag string */ |
457 | char *str, /* additional string */ | 457 | char *str, /* additional string */ |
458 | xfs_mount_t *mp, /* file system mount point */ | 458 | xfs_mount_t *mp, /* file system mount point */ |
459 | xfs_agnumber_t agno, /* allocation group number */ | 459 | xfs_agnumber_t agno, /* allocation group number */ |
@@ -479,7 +479,7 @@ xfs_alloc_trace_free( | |||
479 | */ | 479 | */ |
480 | STATIC void | 480 | STATIC void |
481 | xfs_alloc_trace_modagf( | 481 | xfs_alloc_trace_modagf( |
482 | char *name, /* function tag string */ | 482 | const char *name, /* function tag string */ |
483 | char *str, /* additional string */ | 483 | char *str, /* additional string */ |
484 | xfs_mount_t *mp, /* file system mount point */ | 484 | xfs_mount_t *mp, /* file system mount point */ |
485 | xfs_agf_t *agf, /* new agf value */ | 485 | xfs_agf_t *agf, /* new agf value */ |
@@ -507,7 +507,7 @@ xfs_alloc_trace_modagf( | |||
507 | 507 | ||
508 | STATIC void | 508 | STATIC void |
509 | xfs_alloc_trace_busy( | 509 | xfs_alloc_trace_busy( |
510 | char *name, /* function tag string */ | 510 | const char *name, /* function tag string */ |
511 | char *str, /* additional string */ | 511 | char *str, /* additional string */ |
512 | xfs_mount_t *mp, /* file system mount point */ | 512 | xfs_mount_t *mp, /* file system mount point */ |
513 | xfs_agnumber_t agno, /* allocation group number */ | 513 | xfs_agnumber_t agno, /* allocation group number */ |
@@ -549,9 +549,6 @@ xfs_alloc_ag_vextent( | |||
549 | xfs_alloc_arg_t *args) /* argument structure for allocation */ | 549 | xfs_alloc_arg_t *args) /* argument structure for allocation */ |
550 | { | 550 | { |
551 | int error=0; | 551 | int error=0; |
552 | #ifdef XFS_ALLOC_TRACE | ||
553 | static char fname[] = "xfs_alloc_ag_vextent"; | ||
554 | #endif | ||
555 | 552 | ||
556 | ASSERT(args->minlen > 0); | 553 | ASSERT(args->minlen > 0); |
557 | ASSERT(args->maxlen > 0); | 554 | ASSERT(args->maxlen > 0); |
@@ -635,9 +632,6 @@ xfs_alloc_ag_vextent_exact( | |||
635 | xfs_agblock_t fbno; /* start block of found extent */ | 632 | xfs_agblock_t fbno; /* start block of found extent */ |
636 | xfs_agblock_t fend; /* end block of found extent */ | 633 | xfs_agblock_t fend; /* end block of found extent */ |
637 | xfs_extlen_t flen; /* length of found extent */ | 634 | xfs_extlen_t flen; /* length of found extent */ |
638 | #ifdef XFS_ALLOC_TRACE | ||
639 | static char fname[] = "xfs_alloc_ag_vextent_exact"; | ||
640 | #endif | ||
641 | int i; /* success/failure of operation */ | 635 | int i; /* success/failure of operation */ |
642 | xfs_agblock_t maxend; /* end of maximal extent */ | 636 | xfs_agblock_t maxend; /* end of maximal extent */ |
643 | xfs_agblock_t minend; /* end of minimal extent */ | 637 | xfs_agblock_t minend; /* end of minimal extent */ |
@@ -737,9 +731,6 @@ xfs_alloc_ag_vextent_near( | |||
737 | xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ | 731 | xfs_btree_cur_t *bno_cur_gt; /* cursor for bno btree, right side */ |
738 | xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ | 732 | xfs_btree_cur_t *bno_cur_lt; /* cursor for bno btree, left side */ |
739 | xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ | 733 | xfs_btree_cur_t *cnt_cur; /* cursor for count btree */ |
740 | #ifdef XFS_ALLOC_TRACE | ||
741 | static char fname[] = "xfs_alloc_ag_vextent_near"; | ||
742 | #endif | ||
743 | xfs_agblock_t gtbno; /* start bno of right side entry */ | 734 | xfs_agblock_t gtbno; /* start bno of right side entry */ |
744 | xfs_agblock_t gtbnoa; /* aligned ... */ | 735 | xfs_agblock_t gtbnoa; /* aligned ... */ |
745 | xfs_extlen_t gtdiff; /* difference to right side entry */ | 736 | xfs_extlen_t gtdiff; /* difference to right side entry */ |
@@ -1270,9 +1261,6 @@ xfs_alloc_ag_vextent_size( | |||
1270 | int error; /* error result */ | 1261 | int error; /* error result */ |
1271 | xfs_agblock_t fbno; /* start of found freespace */ | 1262 | xfs_agblock_t fbno; /* start of found freespace */ |
1272 | xfs_extlen_t flen; /* length of found freespace */ | 1263 | xfs_extlen_t flen; /* length of found freespace */ |
1273 | #ifdef XFS_ALLOC_TRACE | ||
1274 | static char fname[] = "xfs_alloc_ag_vextent_size"; | ||
1275 | #endif | ||
1276 | int i; /* temp status variable */ | 1264 | int i; /* temp status variable */ |
1277 | xfs_agblock_t rbno; /* returned block number */ | 1265 | xfs_agblock_t rbno; /* returned block number */ |
1278 | xfs_extlen_t rlen; /* length of returned extent */ | 1266 | xfs_extlen_t rlen; /* length of returned extent */ |
@@ -1427,9 +1415,6 @@ xfs_alloc_ag_vextent_small( | |||
1427 | int error; | 1415 | int error; |
1428 | xfs_agblock_t fbno; | 1416 | xfs_agblock_t fbno; |
1429 | xfs_extlen_t flen; | 1417 | xfs_extlen_t flen; |
1430 | #ifdef XFS_ALLOC_TRACE | ||
1431 | static char fname[] = "xfs_alloc_ag_vextent_small"; | ||
1432 | #endif | ||
1433 | int i; | 1418 | int i; |
1434 | 1419 | ||
1435 | if ((error = xfs_alloc_decrement(ccur, 0, &i))) | 1420 | if ((error = xfs_alloc_decrement(ccur, 0, &i))) |
@@ -1447,7 +1432,8 @@ xfs_alloc_ag_vextent_small( | |||
1447 | else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && | 1432 | else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && |
1448 | (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) | 1433 | (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) |
1449 | > args->minleft)) { | 1434 | > args->minleft)) { |
1450 | if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno))) | 1435 | error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); |
1436 | if (error) | ||
1451 | goto error0; | 1437 | goto error0; |
1452 | if (fbno != NULLAGBLOCK) { | 1438 | if (fbno != NULLAGBLOCK) { |
1453 | if (args->userdata) { | 1439 | if (args->userdata) { |
@@ -1515,9 +1501,6 @@ xfs_free_ag_extent( | |||
1515 | xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ | 1501 | xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ |
1516 | xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ | 1502 | xfs_btree_cur_t *cnt_cur; /* cursor for by-size btree */ |
1517 | int error; /* error return value */ | 1503 | int error; /* error return value */ |
1518 | #ifdef XFS_ALLOC_TRACE | ||
1519 | static char fname[] = "xfs_free_ag_extent"; | ||
1520 | #endif | ||
1521 | xfs_agblock_t gtbno; /* start of right neighbor block */ | 1504 | xfs_agblock_t gtbno; /* start of right neighbor block */ |
1522 | xfs_extlen_t gtlen; /* length of right neighbor block */ | 1505 | xfs_extlen_t gtlen; /* length of right neighbor block */ |
1523 | int haveleft; /* have a left neighbor block */ | 1506 | int haveleft; /* have a left neighbor block */ |
@@ -1923,7 +1906,8 @@ xfs_alloc_fix_freelist( | |||
1923 | while (be32_to_cpu(agf->agf_flcount) > need) { | 1906 | while (be32_to_cpu(agf->agf_flcount) > need) { |
1924 | xfs_buf_t *bp; | 1907 | xfs_buf_t *bp; |
1925 | 1908 | ||
1926 | if ((error = xfs_alloc_get_freelist(tp, agbp, &bno))) | 1909 | error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); |
1910 | if (error) | ||
1927 | return error; | 1911 | return error; |
1928 | if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) | 1912 | if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) |
1929 | return error; | 1913 | return error; |
@@ -1973,8 +1957,9 @@ xfs_alloc_fix_freelist( | |||
1973 | * Put each allocated block on the list. | 1957 | * Put each allocated block on the list. |
1974 | */ | 1958 | */ |
1975 | for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { | 1959 | for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { |
1976 | if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp, | 1960 | error = xfs_alloc_put_freelist(tp, agbp, |
1977 | bno))) | 1961 | agflbp, bno, 0); |
1962 | if (error) | ||
1978 | return error; | 1963 | return error; |
1979 | } | 1964 | } |
1980 | } | 1965 | } |
@@ -1991,16 +1976,15 @@ int /* error */ | |||
1991 | xfs_alloc_get_freelist( | 1976 | xfs_alloc_get_freelist( |
1992 | xfs_trans_t *tp, /* transaction pointer */ | 1977 | xfs_trans_t *tp, /* transaction pointer */ |
1993 | xfs_buf_t *agbp, /* buffer containing the agf structure */ | 1978 | xfs_buf_t *agbp, /* buffer containing the agf structure */ |
1994 | xfs_agblock_t *bnop) /* block address retrieved from freelist */ | 1979 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ |
1980 | int btreeblk) /* destination is a AGF btree */ | ||
1995 | { | 1981 | { |
1996 | xfs_agf_t *agf; /* a.g. freespace structure */ | 1982 | xfs_agf_t *agf; /* a.g. freespace structure */ |
1997 | xfs_agfl_t *agfl; /* a.g. freelist structure */ | 1983 | xfs_agfl_t *agfl; /* a.g. freelist structure */ |
1998 | xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ | 1984 | xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ |
1999 | xfs_agblock_t bno; /* block number returned */ | 1985 | xfs_agblock_t bno; /* block number returned */ |
2000 | int error; | 1986 | int error; |
2001 | #ifdef XFS_ALLOC_TRACE | 1987 | int logflags; |
2002 | static char fname[] = "xfs_alloc_get_freelist"; | ||
2003 | #endif | ||
2004 | xfs_mount_t *mp; /* mount structure */ | 1988 | xfs_mount_t *mp; /* mount structure */ |
2005 | xfs_perag_t *pag; /* per allocation group data */ | 1989 | xfs_perag_t *pag; /* per allocation group data */ |
2006 | 1990 | ||
@@ -2032,8 +2016,16 @@ xfs_alloc_get_freelist( | |||
2032 | be32_add(&agf->agf_flcount, -1); | 2016 | be32_add(&agf->agf_flcount, -1); |
2033 | xfs_trans_agflist_delta(tp, -1); | 2017 | xfs_trans_agflist_delta(tp, -1); |
2034 | pag->pagf_flcount--; | 2018 | pag->pagf_flcount--; |
2035 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT); | 2019 | |
2036 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT); | 2020 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; |
2021 | if (btreeblk) { | ||
2022 | be32_add(&agf->agf_btreeblks, 1); | ||
2023 | pag->pagf_btreeblks++; | ||
2024 | logflags |= XFS_AGF_BTREEBLKS; | ||
2025 | } | ||
2026 | |||
2027 | TRACE_MODAGF(NULL, agf, logflags); | ||
2028 | xfs_alloc_log_agf(tp, agbp, logflags); | ||
2037 | *bnop = bno; | 2029 | *bnop = bno; |
2038 | 2030 | ||
2039 | /* | 2031 | /* |
@@ -2071,6 +2063,7 @@ xfs_alloc_log_agf( | |||
2071 | offsetof(xfs_agf_t, agf_flcount), | 2063 | offsetof(xfs_agf_t, agf_flcount), |
2072 | offsetof(xfs_agf_t, agf_freeblks), | 2064 | offsetof(xfs_agf_t, agf_freeblks), |
2073 | offsetof(xfs_agf_t, agf_longest), | 2065 | offsetof(xfs_agf_t, agf_longest), |
2066 | offsetof(xfs_agf_t, agf_btreeblks), | ||
2074 | sizeof(xfs_agf_t) | 2067 | sizeof(xfs_agf_t) |
2075 | }; | 2068 | }; |
2076 | 2069 | ||
@@ -2106,15 +2099,14 @@ xfs_alloc_put_freelist( | |||
2106 | xfs_trans_t *tp, /* transaction pointer */ | 2099 | xfs_trans_t *tp, /* transaction pointer */ |
2107 | xfs_buf_t *agbp, /* buffer for a.g. freelist header */ | 2100 | xfs_buf_t *agbp, /* buffer for a.g. freelist header */ |
2108 | xfs_buf_t *agflbp,/* buffer for a.g. free block array */ | 2101 | xfs_buf_t *agflbp,/* buffer for a.g. free block array */ |
2109 | xfs_agblock_t bno) /* block being freed */ | 2102 | xfs_agblock_t bno, /* block being freed */ |
2103 | int btreeblk) /* block came from a AGF btree */ | ||
2110 | { | 2104 | { |
2111 | xfs_agf_t *agf; /* a.g. freespace structure */ | 2105 | xfs_agf_t *agf; /* a.g. freespace structure */ |
2112 | xfs_agfl_t *agfl; /* a.g. free block array */ | 2106 | xfs_agfl_t *agfl; /* a.g. free block array */ |
2113 | __be32 *blockp;/* pointer to array entry */ | 2107 | __be32 *blockp;/* pointer to array entry */ |
2114 | int error; | 2108 | int error; |
2115 | #ifdef XFS_ALLOC_TRACE | 2109 | int logflags; |
2116 | static char fname[] = "xfs_alloc_put_freelist"; | ||
2117 | #endif | ||
2118 | xfs_mount_t *mp; /* mount structure */ | 2110 | xfs_mount_t *mp; /* mount structure */ |
2119 | xfs_perag_t *pag; /* per allocation group data */ | 2111 | xfs_perag_t *pag; /* per allocation group data */ |
2120 | 2112 | ||
@@ -2132,11 +2124,22 @@ xfs_alloc_put_freelist( | |||
2132 | be32_add(&agf->agf_flcount, 1); | 2124 | be32_add(&agf->agf_flcount, 1); |
2133 | xfs_trans_agflist_delta(tp, 1); | 2125 | xfs_trans_agflist_delta(tp, 1); |
2134 | pag->pagf_flcount++; | 2126 | pag->pagf_flcount++; |
2127 | |||
2128 | logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; | ||
2129 | if (btreeblk) { | ||
2130 | be32_add(&agf->agf_btreeblks, -1); | ||
2131 | pag->pagf_btreeblks--; | ||
2132 | logflags |= XFS_AGF_BTREEBLKS; | ||
2133 | } | ||
2134 | |||
2135 | TRACE_MODAGF(NULL, agf, logflags); | ||
2136 | xfs_alloc_log_agf(tp, agbp, logflags); | ||
2137 | |||
2135 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); | 2138 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); |
2136 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; | 2139 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; |
2137 | *blockp = cpu_to_be32(bno); | 2140 | *blockp = cpu_to_be32(bno); |
2138 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2141 | TRACE_MODAGF(NULL, agf, logflags); |
2139 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2142 | xfs_alloc_log_agf(tp, agbp, logflags); |
2140 | xfs_trans_log_buf(tp, agflbp, | 2143 | xfs_trans_log_buf(tp, agflbp, |
2141 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), | 2144 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), |
2142 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + | 2145 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + |
@@ -2196,6 +2199,7 @@ xfs_alloc_read_agf( | |||
2196 | pag = &mp->m_perag[agno]; | 2199 | pag = &mp->m_perag[agno]; |
2197 | if (!pag->pagf_init) { | 2200 | if (!pag->pagf_init) { |
2198 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); | 2201 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); |
2202 | pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); | ||
2199 | pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); | 2203 | pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); |
2200 | pag->pagf_longest = be32_to_cpu(agf->agf_longest); | 2204 | pag->pagf_longest = be32_to_cpu(agf->agf_longest); |
2201 | pag->pagf_levels[XFS_BTNUM_BNOi] = | 2205 | pag->pagf_levels[XFS_BTNUM_BNOi] = |
@@ -2235,9 +2239,6 @@ xfs_alloc_vextent( | |||
2235 | xfs_agblock_t agsize; /* allocation group size */ | 2239 | xfs_agblock_t agsize; /* allocation group size */ |
2236 | int error; | 2240 | int error; |
2237 | int flags; /* XFS_ALLOC_FLAG_... locking flags */ | 2241 | int flags; /* XFS_ALLOC_FLAG_... locking flags */ |
2238 | #ifdef XFS_ALLOC_TRACE | ||
2239 | static char fname[] = "xfs_alloc_vextent"; | ||
2240 | #endif | ||
2241 | xfs_extlen_t minleft;/* minimum left value, temp copy */ | 2242 | xfs_extlen_t minleft;/* minimum left value, temp copy */ |
2242 | xfs_mount_t *mp; /* mount structure pointer */ | 2243 | xfs_mount_t *mp; /* mount structure pointer */ |
2243 | xfs_agnumber_t sagno; /* starting allocation group number */ | 2244 | xfs_agnumber_t sagno; /* starting allocation group number */ |
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index 5a4256120cc..5aec15d0651 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
@@ -136,7 +136,8 @@ int /* error */ | |||
136 | xfs_alloc_get_freelist( | 136 | xfs_alloc_get_freelist( |
137 | struct xfs_trans *tp, /* transaction pointer */ | 137 | struct xfs_trans *tp, /* transaction pointer */ |
138 | struct xfs_buf *agbp, /* buffer containing the agf structure */ | 138 | struct xfs_buf *agbp, /* buffer containing the agf structure */ |
139 | xfs_agblock_t *bnop); /* block address retrieved from freelist */ | 139 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ |
140 | int btreeblk); /* destination is a AGF btree */ | ||
140 | 141 | ||
141 | /* | 142 | /* |
142 | * Log the given fields from the agf structure. | 143 | * Log the given fields from the agf structure. |
@@ -165,7 +166,8 @@ xfs_alloc_put_freelist( | |||
165 | struct xfs_trans *tp, /* transaction pointer */ | 166 | struct xfs_trans *tp, /* transaction pointer */ |
166 | struct xfs_buf *agbp, /* buffer for a.g. freelist header */ | 167 | struct xfs_buf *agbp, /* buffer for a.g. freelist header */ |
167 | struct xfs_buf *agflbp,/* buffer for a.g. free block array */ | 168 | struct xfs_buf *agflbp,/* buffer for a.g. free block array */ |
168 | xfs_agblock_t bno); /* block being freed */ | 169 | xfs_agblock_t bno, /* block being freed */ |
170 | int btreeblk); /* owner was a AGF btree */ | ||
169 | 171 | ||
170 | /* | 172 | /* |
171 | * Read in the allocation group header (free/alloc section). | 173 | * Read in the allocation group header (free/alloc section). |
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 74cadf95d4e..1603ce59585 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c | |||
@@ -226,8 +226,9 @@ xfs_alloc_delrec( | |||
226 | /* | 226 | /* |
227 | * Put this buffer/block on the ag's freelist. | 227 | * Put this buffer/block on the ag's freelist. |
228 | */ | 228 | */ |
229 | if ((error = xfs_alloc_put_freelist(cur->bc_tp, | 229 | error = xfs_alloc_put_freelist(cur->bc_tp, |
230 | cur->bc_private.a.agbp, NULL, bno))) | 230 | cur->bc_private.a.agbp, NULL, bno, 1); |
231 | if (error) | ||
231 | return error; | 232 | return error; |
232 | /* | 233 | /* |
233 | * Since blocks move to the free list without the | 234 | * Since blocks move to the free list without the |
@@ -549,8 +550,9 @@ xfs_alloc_delrec( | |||
549 | /* | 550 | /* |
550 | * Free the deleting block by putting it on the freelist. | 551 | * Free the deleting block by putting it on the freelist. |
551 | */ | 552 | */ |
552 | if ((error = xfs_alloc_put_freelist(cur->bc_tp, cur->bc_private.a.agbp, | 553 | error = xfs_alloc_put_freelist(cur->bc_tp, |
553 | NULL, rbno))) | 554 | cur->bc_private.a.agbp, NULL, rbno, 1); |
555 | if (error) | ||
554 | return error; | 556 | return error; |
555 | /* | 557 | /* |
556 | * Since blocks move to the free list without the coordination | 558 | * Since blocks move to the free list without the coordination |
@@ -1320,8 +1322,9 @@ xfs_alloc_newroot( | |||
1320 | /* | 1322 | /* |
1321 | * Get a buffer from the freelist blocks, for the new root. | 1323 | * Get a buffer from the freelist blocks, for the new root. |
1322 | */ | 1324 | */ |
1323 | if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, | 1325 | error = xfs_alloc_get_freelist(cur->bc_tp, |
1324 | &nbno))) | 1326 | cur->bc_private.a.agbp, &nbno, 1); |
1327 | if (error) | ||
1325 | return error; | 1328 | return error; |
1326 | /* | 1329 | /* |
1327 | * None available, we fail. | 1330 | * None available, we fail. |
@@ -1604,8 +1607,9 @@ xfs_alloc_split( | |||
1604 | * Allocate the new block from the freelist. | 1607 | * Allocate the new block from the freelist. |
1605 | * If we can't do it, we're toast. Give up. | 1608 | * If we can't do it, we're toast. Give up. |
1606 | */ | 1609 | */ |
1607 | if ((error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, | 1610 | error = xfs_alloc_get_freelist(cur->bc_tp, |
1608 | &rbno))) | 1611 | cur->bc_private.a.agbp, &rbno, 1); |
1612 | if (error) | ||
1609 | return error; | 1613 | return error; |
1610 | if (rbno == NULLAGBLOCK) { | 1614 | if (rbno == NULLAGBLOCK) { |
1611 | *stat = 0; | 1615 | *stat = 0; |
diff --git a/fs/xfs/xfs_bit.c b/fs/xfs/xfs_bit.c index 1afe07f67e3..fab0b6d5a41 100644 --- a/fs/xfs/xfs_bit.c +++ b/fs/xfs/xfs_bit.c | |||
@@ -66,44 +66,6 @@ static const char xfs_highbit[256] = { | |||
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * Count of bits set in byte, 0..8. | ||
70 | */ | ||
71 | static const char xfs_countbit[256] = { | ||
72 | 0, 1, 1, 2, 1, 2, 2, 3, /* 00 .. 07 */ | ||
73 | 1, 2, 2, 3, 2, 3, 3, 4, /* 08 .. 0f */ | ||
74 | 1, 2, 2, 3, 2, 3, 3, 4, /* 10 .. 17 */ | ||
75 | 2, 3, 3, 4, 3, 4, 4, 5, /* 18 .. 1f */ | ||
76 | 1, 2, 2, 3, 2, 3, 3, 4, /* 20 .. 27 */ | ||
77 | 2, 3, 3, 4, 3, 4, 4, 5, /* 28 .. 2f */ | ||
78 | 2, 3, 3, 4, 3, 4, 4, 5, /* 30 .. 37 */ | ||
79 | 3, 4, 4, 5, 4, 5, 5, 6, /* 38 .. 3f */ | ||
80 | 1, 2, 2, 3, 2, 3, 3, 4, /* 40 .. 47 */ | ||
81 | 2, 3, 3, 4, 3, 4, 4, 5, /* 48 .. 4f */ | ||
82 | 2, 3, 3, 4, 3, 4, 4, 5, /* 50 .. 57 */ | ||
83 | 3, 4, 4, 5, 4, 5, 5, 6, /* 58 .. 5f */ | ||
84 | 2, 3, 3, 4, 3, 4, 4, 5, /* 60 .. 67 */ | ||
85 | 3, 4, 4, 5, 4, 5, 5, 6, /* 68 .. 6f */ | ||
86 | 3, 4, 4, 5, 4, 5, 5, 6, /* 70 .. 77 */ | ||
87 | 4, 5, 5, 6, 5, 6, 6, 7, /* 78 .. 7f */ | ||
88 | 1, 2, 2, 3, 2, 3, 3, 4, /* 80 .. 87 */ | ||
89 | 2, 3, 3, 4, 3, 4, 4, 5, /* 88 .. 8f */ | ||
90 | 2, 3, 3, 4, 3, 4, 4, 5, /* 90 .. 97 */ | ||
91 | 3, 4, 4, 5, 4, 5, 5, 6, /* 98 .. 9f */ | ||
92 | 2, 3, 3, 4, 3, 4, 4, 5, /* a0 .. a7 */ | ||
93 | 3, 4, 4, 5, 4, 5, 5, 6, /* a8 .. af */ | ||
94 | 3, 4, 4, 5, 4, 5, 5, 6, /* b0 .. b7 */ | ||
95 | 4, 5, 5, 6, 5, 6, 6, 7, /* b8 .. bf */ | ||
96 | 2, 3, 3, 4, 3, 4, 4, 5, /* c0 .. c7 */ | ||
97 | 3, 4, 4, 5, 4, 5, 5, 6, /* c8 .. cf */ | ||
98 | 3, 4, 4, 5, 4, 5, 5, 6, /* d0 .. d7 */ | ||
99 | 4, 5, 5, 6, 5, 6, 6, 7, /* d8 .. df */ | ||
100 | 3, 4, 4, 5, 4, 5, 5, 6, /* e0 .. e7 */ | ||
101 | 4, 5, 5, 6, 5, 6, 6, 7, /* e8 .. ef */ | ||
102 | 4, 5, 5, 6, 5, 6, 6, 7, /* f0 .. f7 */ | ||
103 | 5, 6, 6, 7, 6, 7, 7, 8, /* f8 .. ff */ | ||
104 | }; | ||
105 | |||
106 | /* | ||
107 | * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. | 69 | * xfs_highbit32: get high bit set out of 32-bit argument, -1 if none set. |
108 | */ | 70 | */ |
109 | inline int | 71 | inline int |
@@ -167,56 +129,21 @@ xfs_highbit64( | |||
167 | 129 | ||
168 | 130 | ||
169 | /* | 131 | /* |
170 | * Count the number of bits set in the bitmap starting with bit | 132 | * Return whether bitmap is empty. |
171 | * start_bit. Size is the size of the bitmap in words. | 133 | * Size is number of words in the bitmap, which is padded to word boundary |
172 | * | 134 | * Returns 1 for empty, 0 for non-empty. |
173 | * Do the counting by mapping a byte value to the number of set | ||
174 | * bits for that value using the xfs_countbit array, i.e. | ||
175 | * xfs_countbit[0] == 0, xfs_countbit[1] == 1, xfs_countbit[2] == 1, | ||
176 | * xfs_countbit[3] == 2, etc. | ||
177 | */ | 135 | */ |
178 | int | 136 | int |
179 | xfs_count_bits(uint *map, uint size, uint start_bit) | 137 | xfs_bitmap_empty(uint *map, uint size) |
180 | { | 138 | { |
181 | register int bits; | 139 | uint i; |
182 | register unsigned char *bytep; | 140 | uint ret = 0; |
183 | register unsigned char *end_map; | ||
184 | int byte_bit; | ||
185 | |||
186 | bits = 0; | ||
187 | end_map = (char*)(map + size); | ||
188 | bytep = (char*)(map + (start_bit & ~0x7)); | ||
189 | byte_bit = start_bit & 0x7; | ||
190 | |||
191 | /* | ||
192 | * If the caller fell off the end of the map, return 0. | ||
193 | */ | ||
194 | if (bytep >= end_map) { | ||
195 | return (0); | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * If start_bit is not byte aligned, then process the | ||
200 | * first byte separately. | ||
201 | */ | ||
202 | if (byte_bit != 0) { | ||
203 | /* | ||
204 | * Shift off the bits we don't want to look at, | ||
205 | * before indexing into xfs_countbit. | ||
206 | */ | ||
207 | bits += xfs_countbit[(*bytep >> byte_bit)]; | ||
208 | bytep++; | ||
209 | } | ||
210 | 141 | ||
211 | /* | 142 | for (i = 0; i < size; i++) { |
212 | * Count the bits in each byte until the end of the bitmap. | 143 | ret |= map[i]; |
213 | */ | ||
214 | while (bytep < end_map) { | ||
215 | bits += xfs_countbit[*bytep]; | ||
216 | bytep++; | ||
217 | } | 144 | } |
218 | 145 | ||
219 | return (bits); | 146 | return (ret == 0); |
220 | } | 147 | } |
221 | 148 | ||
222 | /* | 149 | /* |
diff --git a/fs/xfs/xfs_bit.h b/fs/xfs/xfs_bit.h index 0bbe5681754..082641a9782 100644 --- a/fs/xfs/xfs_bit.h +++ b/fs/xfs/xfs_bit.h | |||
@@ -55,8 +55,8 @@ extern int xfs_lowbit64(__uint64_t v); | |||
55 | /* Get high bit set out of 64-bit argument, -1 if none set */ | 55 | /* Get high bit set out of 64-bit argument, -1 if none set */ |
56 | extern int xfs_highbit64(__uint64_t); | 56 | extern int xfs_highbit64(__uint64_t); |
57 | 57 | ||
58 | /* Count set bits in map starting with start_bit */ | 58 | /* Return whether bitmap is empty (1 == empty) */ |
59 | extern int xfs_count_bits(uint *map, uint size, uint start_bit); | 59 | extern int xfs_bitmap_empty(uint *map, uint size); |
60 | 60 | ||
61 | /* Count continuous one bits in map starting with start_bit */ | 61 | /* Count continuous one bits in map starting with start_bit */ |
62 | extern int xfs_contig_bits(uint *map, uint size, uint start_bit); | 62 | extern int xfs_contig_bits(uint *map, uint size, uint start_bit); |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index b1ea26e40aa..94b5c5fe268 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "xfs_quota.h" | 52 | #include "xfs_quota.h" |
53 | #include "xfs_trans_space.h" | 53 | #include "xfs_trans_space.h" |
54 | #include "xfs_buf_item.h" | 54 | #include "xfs_buf_item.h" |
55 | #include "xfs_filestream.h" | ||
55 | 56 | ||
56 | 57 | ||
57 | #ifdef DEBUG | 58 | #ifdef DEBUG |
@@ -277,7 +278,7 @@ xfs_bmap_isaeof( | |||
277 | STATIC void | 278 | STATIC void |
278 | xfs_bmap_trace_addentry( | 279 | xfs_bmap_trace_addentry( |
279 | int opcode, /* operation */ | 280 | int opcode, /* operation */ |
280 | char *fname, /* function name */ | 281 | const char *fname, /* function name */ |
281 | char *desc, /* operation description */ | 282 | char *desc, /* operation description */ |
282 | xfs_inode_t *ip, /* incore inode pointer */ | 283 | xfs_inode_t *ip, /* incore inode pointer */ |
283 | xfs_extnum_t idx, /* index of entry(ies) */ | 284 | xfs_extnum_t idx, /* index of entry(ies) */ |
@@ -291,7 +292,7 @@ xfs_bmap_trace_addentry( | |||
291 | */ | 292 | */ |
292 | STATIC void | 293 | STATIC void |
293 | xfs_bmap_trace_delete( | 294 | xfs_bmap_trace_delete( |
294 | char *fname, /* function name */ | 295 | const char *fname, /* function name */ |
295 | char *desc, /* operation description */ | 296 | char *desc, /* operation description */ |
296 | xfs_inode_t *ip, /* incore inode pointer */ | 297 | xfs_inode_t *ip, /* incore inode pointer */ |
297 | xfs_extnum_t idx, /* index of entry(entries) deleted */ | 298 | xfs_extnum_t idx, /* index of entry(entries) deleted */ |
@@ -304,7 +305,7 @@ xfs_bmap_trace_delete( | |||
304 | */ | 305 | */ |
305 | STATIC void | 306 | STATIC void |
306 | xfs_bmap_trace_insert( | 307 | xfs_bmap_trace_insert( |
307 | char *fname, /* function name */ | 308 | const char *fname, /* function name */ |
308 | char *desc, /* operation description */ | 309 | char *desc, /* operation description */ |
309 | xfs_inode_t *ip, /* incore inode pointer */ | 310 | xfs_inode_t *ip, /* incore inode pointer */ |
310 | xfs_extnum_t idx, /* index of entry(entries) inserted */ | 311 | xfs_extnum_t idx, /* index of entry(entries) inserted */ |
@@ -318,7 +319,7 @@ xfs_bmap_trace_insert( | |||
318 | */ | 319 | */ |
319 | STATIC void | 320 | STATIC void |
320 | xfs_bmap_trace_post_update( | 321 | xfs_bmap_trace_post_update( |
321 | char *fname, /* function name */ | 322 | const char *fname, /* function name */ |
322 | char *desc, /* operation description */ | 323 | char *desc, /* operation description */ |
323 | xfs_inode_t *ip, /* incore inode pointer */ | 324 | xfs_inode_t *ip, /* incore inode pointer */ |
324 | xfs_extnum_t idx, /* index of entry updated */ | 325 | xfs_extnum_t idx, /* index of entry updated */ |
@@ -329,17 +330,25 @@ xfs_bmap_trace_post_update( | |||
329 | */ | 330 | */ |
330 | STATIC void | 331 | STATIC void |
331 | xfs_bmap_trace_pre_update( | 332 | xfs_bmap_trace_pre_update( |
332 | char *fname, /* function name */ | 333 | const char *fname, /* function name */ |
333 | char *desc, /* operation description */ | 334 | char *desc, /* operation description */ |
334 | xfs_inode_t *ip, /* incore inode pointer */ | 335 | xfs_inode_t *ip, /* incore inode pointer */ |
335 | xfs_extnum_t idx, /* index of entry to be updated */ | 336 | xfs_extnum_t idx, /* index of entry to be updated */ |
336 | int whichfork); /* data or attr fork */ | 337 | int whichfork); /* data or attr fork */ |
337 | 338 | ||
339 | #define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) \ | ||
340 | xfs_bmap_trace_delete(__FUNCTION__,d,ip,i,c,w) | ||
341 | #define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) \ | ||
342 | xfs_bmap_trace_insert(__FUNCTION__,d,ip,i,c,r1,r2,w) | ||
343 | #define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) \ | ||
344 | xfs_bmap_trace_post_update(__FUNCTION__,d,ip,i,w) | ||
345 | #define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) \ | ||
346 | xfs_bmap_trace_pre_update(__FUNCTION__,d,ip,i,w) | ||
338 | #else | 347 | #else |
339 | #define xfs_bmap_trace_delete(f,d,ip,i,c,w) | 348 | #define XFS_BMAP_TRACE_DELETE(d,ip,i,c,w) |
340 | #define xfs_bmap_trace_insert(f,d,ip,i,c,r1,r2,w) | 349 | #define XFS_BMAP_TRACE_INSERT(d,ip,i,c,r1,r2,w) |
341 | #define xfs_bmap_trace_post_update(f,d,ip,i,w) | 350 | #define XFS_BMAP_TRACE_POST_UPDATE(d,ip,i,w) |
342 | #define xfs_bmap_trace_pre_update(f,d,ip,i,w) | 351 | #define XFS_BMAP_TRACE_PRE_UPDATE(d,ip,i,w) |
343 | #endif /* XFS_BMAP_TRACE */ | 352 | #endif /* XFS_BMAP_TRACE */ |
344 | 353 | ||
345 | /* | 354 | /* |
@@ -531,9 +540,6 @@ xfs_bmap_add_extent( | |||
531 | xfs_filblks_t da_new; /* new count del alloc blocks used */ | 540 | xfs_filblks_t da_new; /* new count del alloc blocks used */ |
532 | xfs_filblks_t da_old; /* old count del alloc blocks used */ | 541 | xfs_filblks_t da_old; /* old count del alloc blocks used */ |
533 | int error; /* error return value */ | 542 | int error; /* error return value */ |
534 | #ifdef XFS_BMAP_TRACE | ||
535 | static char fname[] = "xfs_bmap_add_extent"; | ||
536 | #endif | ||
537 | xfs_ifork_t *ifp; /* inode fork ptr */ | 543 | xfs_ifork_t *ifp; /* inode fork ptr */ |
538 | int logflags; /* returned value */ | 544 | int logflags; /* returned value */ |
539 | xfs_extnum_t nextents; /* number of extents in file now */ | 545 | xfs_extnum_t nextents; /* number of extents in file now */ |
@@ -551,8 +557,8 @@ xfs_bmap_add_extent( | |||
551 | * already extents in the list. | 557 | * already extents in the list. |
552 | */ | 558 | */ |
553 | if (nextents == 0) { | 559 | if (nextents == 0) { |
554 | xfs_bmap_trace_insert(fname, "insert empty", ip, 0, 1, new, | 560 | XFS_BMAP_TRACE_INSERT("insert empty", ip, 0, 1, new, NULL, |
555 | NULL, whichfork); | 561 | whichfork); |
556 | xfs_iext_insert(ifp, 0, 1, new); | 562 | xfs_iext_insert(ifp, 0, 1, new); |
557 | ASSERT(cur == NULL); | 563 | ASSERT(cur == NULL); |
558 | ifp->if_lastex = 0; | 564 | ifp->if_lastex = 0; |
@@ -710,9 +716,6 @@ xfs_bmap_add_extent_delay_real( | |||
710 | int diff; /* temp value */ | 716 | int diff; /* temp value */ |
711 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ | 717 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ |
712 | int error; /* error return value */ | 718 | int error; /* error return value */ |
713 | #ifdef XFS_BMAP_TRACE | ||
714 | static char fname[] = "xfs_bmap_add_extent_delay_real"; | ||
715 | #endif | ||
716 | int i; /* temp state */ | 719 | int i; /* temp state */ |
717 | xfs_ifork_t *ifp; /* inode fork pointer */ | 720 | xfs_ifork_t *ifp; /* inode fork pointer */ |
718 | xfs_fileoff_t new_endoff; /* end offset of new entry */ | 721 | xfs_fileoff_t new_endoff; /* end offset of new entry */ |
@@ -808,15 +811,14 @@ xfs_bmap_add_extent_delay_real( | |||
808 | * Filling in all of a previously delayed allocation extent. | 811 | * Filling in all of a previously delayed allocation extent. |
809 | * The left and right neighbors are both contiguous with new. | 812 | * The left and right neighbors are both contiguous with new. |
810 | */ | 813 | */ |
811 | xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, | 814 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, |
812 | XFS_DATA_FORK); | 815 | XFS_DATA_FORK); |
813 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 816 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
814 | LEFT.br_blockcount + PREV.br_blockcount + | 817 | LEFT.br_blockcount + PREV.br_blockcount + |
815 | RIGHT.br_blockcount); | 818 | RIGHT.br_blockcount); |
816 | xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, | 819 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, |
817 | XFS_DATA_FORK); | ||
818 | xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, | ||
819 | XFS_DATA_FORK); | 820 | XFS_DATA_FORK); |
821 | XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); | ||
820 | xfs_iext_remove(ifp, idx, 2); | 822 | xfs_iext_remove(ifp, idx, 2); |
821 | ip->i_df.if_lastex = idx - 1; | 823 | ip->i_df.if_lastex = idx - 1; |
822 | ip->i_d.di_nextents--; | 824 | ip->i_d.di_nextents--; |
@@ -855,15 +857,14 @@ xfs_bmap_add_extent_delay_real( | |||
855 | * Filling in all of a previously delayed allocation extent. | 857 | * Filling in all of a previously delayed allocation extent. |
856 | * The left neighbor is contiguous, the right is not. | 858 | * The left neighbor is contiguous, the right is not. |
857 | */ | 859 | */ |
858 | xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, | 860 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, |
859 | XFS_DATA_FORK); | 861 | XFS_DATA_FORK); |
860 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 862 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
861 | LEFT.br_blockcount + PREV.br_blockcount); | 863 | LEFT.br_blockcount + PREV.br_blockcount); |
862 | xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, | 864 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, |
863 | XFS_DATA_FORK); | 865 | XFS_DATA_FORK); |
864 | ip->i_df.if_lastex = idx - 1; | 866 | ip->i_df.if_lastex = idx - 1; |
865 | xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, | 867 | XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); |
866 | XFS_DATA_FORK); | ||
867 | xfs_iext_remove(ifp, idx, 1); | 868 | xfs_iext_remove(ifp, idx, 1); |
868 | if (cur == NULL) | 869 | if (cur == NULL) |
869 | rval = XFS_ILOG_DEXT; | 870 | rval = XFS_ILOG_DEXT; |
@@ -892,16 +893,13 @@ xfs_bmap_add_extent_delay_real( | |||
892 | * Filling in all of a previously delayed allocation extent. | 893 | * Filling in all of a previously delayed allocation extent. |
893 | * The right neighbor is contiguous, the left is not. | 894 | * The right neighbor is contiguous, the left is not. |
894 | */ | 895 | */ |
895 | xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, | 896 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); |
896 | XFS_DATA_FORK); | ||
897 | xfs_bmbt_set_startblock(ep, new->br_startblock); | 897 | xfs_bmbt_set_startblock(ep, new->br_startblock); |
898 | xfs_bmbt_set_blockcount(ep, | 898 | xfs_bmbt_set_blockcount(ep, |
899 | PREV.br_blockcount + RIGHT.br_blockcount); | 899 | PREV.br_blockcount + RIGHT.br_blockcount); |
900 | xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, | 900 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, XFS_DATA_FORK); |
901 | XFS_DATA_FORK); | ||
902 | ip->i_df.if_lastex = idx; | 901 | ip->i_df.if_lastex = idx; |
903 | xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, | 902 | XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); |
904 | XFS_DATA_FORK); | ||
905 | xfs_iext_remove(ifp, idx + 1, 1); | 903 | xfs_iext_remove(ifp, idx + 1, 1); |
906 | if (cur == NULL) | 904 | if (cur == NULL) |
907 | rval = XFS_ILOG_DEXT; | 905 | rval = XFS_ILOG_DEXT; |
@@ -931,11 +929,9 @@ xfs_bmap_add_extent_delay_real( | |||
931 | * Neither the left nor right neighbors are contiguous with | 929 | * Neither the left nor right neighbors are contiguous with |
932 | * the new one. | 930 | * the new one. |
933 | */ | 931 | */ |
934 | xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, | 932 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); |
935 | XFS_DATA_FORK); | ||
936 | xfs_bmbt_set_startblock(ep, new->br_startblock); | 933 | xfs_bmbt_set_startblock(ep, new->br_startblock); |
937 | xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, | 934 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, XFS_DATA_FORK); |
938 | XFS_DATA_FORK); | ||
939 | ip->i_df.if_lastex = idx; | 935 | ip->i_df.if_lastex = idx; |
940 | ip->i_d.di_nextents++; | 936 | ip->i_d.di_nextents++; |
941 | if (cur == NULL) | 937 | if (cur == NULL) |
@@ -963,17 +959,14 @@ xfs_bmap_add_extent_delay_real( | |||
963 | * Filling in the first part of a previous delayed allocation. | 959 | * Filling in the first part of a previous delayed allocation. |
964 | * The left neighbor is contiguous. | 960 | * The left neighbor is contiguous. |
965 | */ | 961 | */ |
966 | xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, | 962 | XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); |
967 | XFS_DATA_FORK); | ||
968 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 963 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
969 | LEFT.br_blockcount + new->br_blockcount); | 964 | LEFT.br_blockcount + new->br_blockcount); |
970 | xfs_bmbt_set_startoff(ep, | 965 | xfs_bmbt_set_startoff(ep, |
971 | PREV.br_startoff + new->br_blockcount); | 966 | PREV.br_startoff + new->br_blockcount); |
972 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, | 967 | XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, XFS_DATA_FORK); |
973 | XFS_DATA_FORK); | ||
974 | temp = PREV.br_blockcount - new->br_blockcount; | 968 | temp = PREV.br_blockcount - new->br_blockcount; |
975 | xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, | 969 | XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); |
976 | XFS_DATA_FORK); | ||
977 | xfs_bmbt_set_blockcount(ep, temp); | 970 | xfs_bmbt_set_blockcount(ep, temp); |
978 | ip->i_df.if_lastex = idx - 1; | 971 | ip->i_df.if_lastex = idx - 1; |
979 | if (cur == NULL) | 972 | if (cur == NULL) |
@@ -995,8 +988,7 @@ xfs_bmap_add_extent_delay_real( | |||
995 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 988 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
996 | STARTBLOCKVAL(PREV.br_startblock)); | 989 | STARTBLOCKVAL(PREV.br_startblock)); |
997 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 990 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
998 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, | 991 | XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, XFS_DATA_FORK); |
999 | XFS_DATA_FORK); | ||
1000 | *dnew = temp; | 992 | *dnew = temp; |
1001 | /* DELTA: The boundary between two in-core extents moved. */ | 993 | /* DELTA: The boundary between two in-core extents moved. */ |
1002 | temp = LEFT.br_startoff; | 994 | temp = LEFT.br_startoff; |
@@ -1009,11 +1001,11 @@ xfs_bmap_add_extent_delay_real( | |||
1009 | * Filling in the first part of a previous delayed allocation. | 1001 | * Filling in the first part of a previous delayed allocation. |
1010 | * The left neighbor is not contiguous. | 1002 | * The left neighbor is not contiguous. |
1011 | */ | 1003 | */ |
1012 | xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); | 1004 | XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); |
1013 | xfs_bmbt_set_startoff(ep, new_endoff); | 1005 | xfs_bmbt_set_startoff(ep, new_endoff); |
1014 | temp = PREV.br_blockcount - new->br_blockcount; | 1006 | temp = PREV.br_blockcount - new->br_blockcount; |
1015 | xfs_bmbt_set_blockcount(ep, temp); | 1007 | xfs_bmbt_set_blockcount(ep, temp); |
1016 | xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, | 1008 | XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, |
1017 | XFS_DATA_FORK); | 1009 | XFS_DATA_FORK); |
1018 | xfs_iext_insert(ifp, idx, 1, new); | 1010 | xfs_iext_insert(ifp, idx, 1, new); |
1019 | ip->i_df.if_lastex = idx; | 1011 | ip->i_df.if_lastex = idx; |
@@ -1046,8 +1038,7 @@ xfs_bmap_add_extent_delay_real( | |||
1046 | (cur ? cur->bc_private.b.allocated : 0)); | 1038 | (cur ? cur->bc_private.b.allocated : 0)); |
1047 | ep = xfs_iext_get_ext(ifp, idx + 1); | 1039 | ep = xfs_iext_get_ext(ifp, idx + 1); |
1048 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 1040 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
1049 | xfs_bmap_trace_post_update(fname, "LF", ip, idx + 1, | 1041 | XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx + 1, XFS_DATA_FORK); |
1050 | XFS_DATA_FORK); | ||
1051 | *dnew = temp; | 1042 | *dnew = temp; |
1052 | /* DELTA: One in-core extent is split in two. */ | 1043 | /* DELTA: One in-core extent is split in two. */ |
1053 | temp = PREV.br_startoff; | 1044 | temp = PREV.br_startoff; |
@@ -1060,17 +1051,14 @@ xfs_bmap_add_extent_delay_real( | |||
1060 | * The right neighbor is contiguous with the new allocation. | 1051 | * The right neighbor is contiguous with the new allocation. |
1061 | */ | 1052 | */ |
1062 | temp = PREV.br_blockcount - new->br_blockcount; | 1053 | temp = PREV.br_blockcount - new->br_blockcount; |
1063 | xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, | 1054 | XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); |
1064 | XFS_DATA_FORK); | 1055 | XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); |
1065 | xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, | ||
1066 | XFS_DATA_FORK); | ||
1067 | xfs_bmbt_set_blockcount(ep, temp); | 1056 | xfs_bmbt_set_blockcount(ep, temp); |
1068 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), | 1057 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), |
1069 | new->br_startoff, new->br_startblock, | 1058 | new->br_startoff, new->br_startblock, |
1070 | new->br_blockcount + RIGHT.br_blockcount, | 1059 | new->br_blockcount + RIGHT.br_blockcount, |
1071 | RIGHT.br_state); | 1060 | RIGHT.br_state); |
1072 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, | 1061 | XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, XFS_DATA_FORK); |
1073 | XFS_DATA_FORK); | ||
1074 | ip->i_df.if_lastex = idx + 1; | 1062 | ip->i_df.if_lastex = idx + 1; |
1075 | if (cur == NULL) | 1063 | if (cur == NULL) |
1076 | rval = XFS_ILOG_DEXT; | 1064 | rval = XFS_ILOG_DEXT; |
@@ -1091,8 +1079,7 @@ xfs_bmap_add_extent_delay_real( | |||
1091 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 1079 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
1092 | STARTBLOCKVAL(PREV.br_startblock)); | 1080 | STARTBLOCKVAL(PREV.br_startblock)); |
1093 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 1081 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
1094 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, | 1082 | XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, XFS_DATA_FORK); |
1095 | XFS_DATA_FORK); | ||
1096 | *dnew = temp; | 1083 | *dnew = temp; |
1097 | /* DELTA: The boundary between two in-core extents moved. */ | 1084 | /* DELTA: The boundary between two in-core extents moved. */ |
1098 | temp = PREV.br_startoff; | 1085 | temp = PREV.br_startoff; |
@@ -1106,10 +1093,10 @@ xfs_bmap_add_extent_delay_real( | |||
1106 | * The right neighbor is not contiguous. | 1093 | * The right neighbor is not contiguous. |
1107 | */ | 1094 | */ |
1108 | temp = PREV.br_blockcount - new->br_blockcount; | 1095 | temp = PREV.br_blockcount - new->br_blockcount; |
1109 | xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); | 1096 | XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); |
1110 | xfs_bmbt_set_blockcount(ep, temp); | 1097 | xfs_bmbt_set_blockcount(ep, temp); |
1111 | xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, | 1098 | XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, |
1112 | new, NULL, XFS_DATA_FORK); | 1099 | XFS_DATA_FORK); |
1113 | xfs_iext_insert(ifp, idx + 1, 1, new); | 1100 | xfs_iext_insert(ifp, idx + 1, 1, new); |
1114 | ip->i_df.if_lastex = idx + 1; | 1101 | ip->i_df.if_lastex = idx + 1; |
1115 | ip->i_d.di_nextents++; | 1102 | ip->i_d.di_nextents++; |
@@ -1141,7 +1128,7 @@ xfs_bmap_add_extent_delay_real( | |||
1141 | (cur ? cur->bc_private.b.allocated : 0)); | 1128 | (cur ? cur->bc_private.b.allocated : 0)); |
1142 | ep = xfs_iext_get_ext(ifp, idx); | 1129 | ep = xfs_iext_get_ext(ifp, idx); |
1143 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 1130 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
1144 | xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); | 1131 | XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); |
1145 | *dnew = temp; | 1132 | *dnew = temp; |
1146 | /* DELTA: One in-core extent is split in two. */ | 1133 | /* DELTA: One in-core extent is split in two. */ |
1147 | temp = PREV.br_startoff; | 1134 | temp = PREV.br_startoff; |
@@ -1155,7 +1142,7 @@ xfs_bmap_add_extent_delay_real( | |||
1155 | * This case is avoided almost all the time. | 1142 | * This case is avoided almost all the time. |
1156 | */ | 1143 | */ |
1157 | temp = new->br_startoff - PREV.br_startoff; | 1144 | temp = new->br_startoff - PREV.br_startoff; |
1158 | xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); | 1145 | XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); |
1159 | xfs_bmbt_set_blockcount(ep, temp); | 1146 | xfs_bmbt_set_blockcount(ep, temp); |
1160 | r[0] = *new; | 1147 | r[0] = *new; |
1161 | r[1].br_state = PREV.br_state; | 1148 | r[1].br_state = PREV.br_state; |
@@ -1163,7 +1150,7 @@ xfs_bmap_add_extent_delay_real( | |||
1163 | r[1].br_startoff = new_endoff; | 1150 | r[1].br_startoff = new_endoff; |
1164 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; | 1151 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; |
1165 | r[1].br_blockcount = temp2; | 1152 | r[1].br_blockcount = temp2; |
1166 | xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], | 1153 | XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], |
1167 | XFS_DATA_FORK); | 1154 | XFS_DATA_FORK); |
1168 | xfs_iext_insert(ifp, idx + 1, 2, &r[0]); | 1155 | xfs_iext_insert(ifp, idx + 1, 2, &r[0]); |
1169 | ip->i_df.if_lastex = idx + 1; | 1156 | ip->i_df.if_lastex = idx + 1; |
@@ -1222,13 +1209,11 @@ xfs_bmap_add_extent_delay_real( | |||
1222 | } | 1209 | } |
1223 | ep = xfs_iext_get_ext(ifp, idx); | 1210 | ep = xfs_iext_get_ext(ifp, idx); |
1224 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 1211 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
1225 | xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); | 1212 | XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); |
1226 | xfs_bmap_trace_pre_update(fname, "0", ip, idx + 2, | 1213 | XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); |
1227 | XFS_DATA_FORK); | ||
1228 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), | 1214 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx + 2), |
1229 | NULLSTARTBLOCK((int)temp2)); | 1215 | NULLSTARTBLOCK((int)temp2)); |
1230 | xfs_bmap_trace_post_update(fname, "0", ip, idx + 2, | 1216 | XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx + 2, XFS_DATA_FORK); |
1231 | XFS_DATA_FORK); | ||
1232 | *dnew = temp + temp2; | 1217 | *dnew = temp + temp2; |
1233 | /* DELTA: One in-core extent is split in three. */ | 1218 | /* DELTA: One in-core extent is split in three. */ |
1234 | temp = PREV.br_startoff; | 1219 | temp = PREV.br_startoff; |
@@ -1287,9 +1272,6 @@ xfs_bmap_add_extent_unwritten_real( | |||
1287 | xfs_btree_cur_t *cur; /* btree cursor */ | 1272 | xfs_btree_cur_t *cur; /* btree cursor */ |
1288 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ | 1273 | xfs_bmbt_rec_t *ep; /* extent entry for idx */ |
1289 | int error; /* error return value */ | 1274 | int error; /* error return value */ |
1290 | #ifdef XFS_BMAP_TRACE | ||
1291 | static char fname[] = "xfs_bmap_add_extent_unwritten_real"; | ||
1292 | #endif | ||
1293 | int i; /* temp state */ | 1275 | int i; /* temp state */ |
1294 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1276 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1295 | xfs_fileoff_t new_endoff; /* end offset of new entry */ | 1277 | xfs_fileoff_t new_endoff; /* end offset of new entry */ |
@@ -1390,15 +1372,14 @@ xfs_bmap_add_extent_unwritten_real( | |||
1390 | * Setting all of a previous oldext extent to newext. | 1372 | * Setting all of a previous oldext extent to newext. |
1391 | * The left and right neighbors are both contiguous with new. | 1373 | * The left and right neighbors are both contiguous with new. |
1392 | */ | 1374 | */ |
1393 | xfs_bmap_trace_pre_update(fname, "LF|RF|LC|RC", ip, idx - 1, | 1375 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC|RC", ip, idx - 1, |
1394 | XFS_DATA_FORK); | 1376 | XFS_DATA_FORK); |
1395 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1377 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
1396 | LEFT.br_blockcount + PREV.br_blockcount + | 1378 | LEFT.br_blockcount + PREV.br_blockcount + |
1397 | RIGHT.br_blockcount); | 1379 | RIGHT.br_blockcount); |
1398 | xfs_bmap_trace_post_update(fname, "LF|RF|LC|RC", ip, idx - 1, | 1380 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC|RC", ip, idx - 1, |
1399 | XFS_DATA_FORK); | ||
1400 | xfs_bmap_trace_delete(fname, "LF|RF|LC|RC", ip, idx, 2, | ||
1401 | XFS_DATA_FORK); | 1381 | XFS_DATA_FORK); |
1382 | XFS_BMAP_TRACE_DELETE("LF|RF|LC|RC", ip, idx, 2, XFS_DATA_FORK); | ||
1402 | xfs_iext_remove(ifp, idx, 2); | 1383 | xfs_iext_remove(ifp, idx, 2); |
1403 | ip->i_df.if_lastex = idx - 1; | 1384 | ip->i_df.if_lastex = idx - 1; |
1404 | ip->i_d.di_nextents -= 2; | 1385 | ip->i_d.di_nextents -= 2; |
@@ -1441,15 +1422,14 @@ xfs_bmap_add_extent_unwritten_real( | |||
1441 | * Setting all of a previous oldext extent to newext. | 1422 | * Setting all of a previous oldext extent to newext. |
1442 | * The left neighbor is contiguous, the right is not. | 1423 | * The left neighbor is contiguous, the right is not. |
1443 | */ | 1424 | */ |
1444 | xfs_bmap_trace_pre_update(fname, "LF|RF|LC", ip, idx - 1, | 1425 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|LC", ip, idx - 1, |
1445 | XFS_DATA_FORK); | 1426 | XFS_DATA_FORK); |
1446 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1427 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
1447 | LEFT.br_blockcount + PREV.br_blockcount); | 1428 | LEFT.br_blockcount + PREV.br_blockcount); |
1448 | xfs_bmap_trace_post_update(fname, "LF|RF|LC", ip, idx - 1, | 1429 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|LC", ip, idx - 1, |
1449 | XFS_DATA_FORK); | 1430 | XFS_DATA_FORK); |
1450 | ip->i_df.if_lastex = idx - 1; | 1431 | ip->i_df.if_lastex = idx - 1; |
1451 | xfs_bmap_trace_delete(fname, "LF|RF|LC", ip, idx, 1, | 1432 | XFS_BMAP_TRACE_DELETE("LF|RF|LC", ip, idx, 1, XFS_DATA_FORK); |
1452 | XFS_DATA_FORK); | ||
1453 | xfs_iext_remove(ifp, idx, 1); | 1433 | xfs_iext_remove(ifp, idx, 1); |
1454 | ip->i_d.di_nextents--; | 1434 | ip->i_d.di_nextents--; |
1455 | if (cur == NULL) | 1435 | if (cur == NULL) |
@@ -1484,16 +1464,15 @@ xfs_bmap_add_extent_unwritten_real( | |||
1484 | * Setting all of a previous oldext extent to newext. | 1464 | * Setting all of a previous oldext extent to newext. |
1485 | * The right neighbor is contiguous, the left is not. | 1465 | * The right neighbor is contiguous, the left is not. |
1486 | */ | 1466 | */ |
1487 | xfs_bmap_trace_pre_update(fname, "LF|RF|RC", ip, idx, | 1467 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF|RC", ip, idx, |
1488 | XFS_DATA_FORK); | 1468 | XFS_DATA_FORK); |
1489 | xfs_bmbt_set_blockcount(ep, | 1469 | xfs_bmbt_set_blockcount(ep, |
1490 | PREV.br_blockcount + RIGHT.br_blockcount); | 1470 | PREV.br_blockcount + RIGHT.br_blockcount); |
1491 | xfs_bmbt_set_state(ep, newext); | 1471 | xfs_bmbt_set_state(ep, newext); |
1492 | xfs_bmap_trace_post_update(fname, "LF|RF|RC", ip, idx, | 1472 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF|RC", ip, idx, |
1493 | XFS_DATA_FORK); | 1473 | XFS_DATA_FORK); |
1494 | ip->i_df.if_lastex = idx; | 1474 | ip->i_df.if_lastex = idx; |
1495 | xfs_bmap_trace_delete(fname, "LF|RF|RC", ip, idx + 1, 1, | 1475 | XFS_BMAP_TRACE_DELETE("LF|RF|RC", ip, idx + 1, 1, XFS_DATA_FORK); |
1496 | XFS_DATA_FORK); | ||
1497 | xfs_iext_remove(ifp, idx + 1, 1); | 1476 | xfs_iext_remove(ifp, idx + 1, 1); |
1498 | ip->i_d.di_nextents--; | 1477 | ip->i_d.di_nextents--; |
1499 | if (cur == NULL) | 1478 | if (cur == NULL) |
@@ -1529,10 +1508,10 @@ xfs_bmap_add_extent_unwritten_real( | |||
1529 | * Neither the left nor right neighbors are contiguous with | 1508 | * Neither the left nor right neighbors are contiguous with |
1530 | * the new one. | 1509 | * the new one. |
1531 | */ | 1510 | */ |
1532 | xfs_bmap_trace_pre_update(fname, "LF|RF", ip, idx, | 1511 | XFS_BMAP_TRACE_PRE_UPDATE("LF|RF", ip, idx, |
1533 | XFS_DATA_FORK); | 1512 | XFS_DATA_FORK); |
1534 | xfs_bmbt_set_state(ep, newext); | 1513 | xfs_bmbt_set_state(ep, newext); |
1535 | xfs_bmap_trace_post_update(fname, "LF|RF", ip, idx, | 1514 | XFS_BMAP_TRACE_POST_UPDATE("LF|RF", ip, idx, |
1536 | XFS_DATA_FORK); | 1515 | XFS_DATA_FORK); |
1537 | ip->i_df.if_lastex = idx; | 1516 | ip->i_df.if_lastex = idx; |
1538 | if (cur == NULL) | 1517 | if (cur == NULL) |
@@ -1559,21 +1538,21 @@ xfs_bmap_add_extent_unwritten_real( | |||
1559 | * Setting the first part of a previous oldext extent to newext. | 1538 | * Setting the first part of a previous oldext extent to newext. |
1560 | * The left neighbor is contiguous. | 1539 | * The left neighbor is contiguous. |
1561 | */ | 1540 | */ |
1562 | xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx - 1, | 1541 | XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx - 1, |
1563 | XFS_DATA_FORK); | 1542 | XFS_DATA_FORK); |
1564 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 1543 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
1565 | LEFT.br_blockcount + new->br_blockcount); | 1544 | LEFT.br_blockcount + new->br_blockcount); |
1566 | xfs_bmbt_set_startoff(ep, | 1545 | xfs_bmbt_set_startoff(ep, |
1567 | PREV.br_startoff + new->br_blockcount); | 1546 | PREV.br_startoff + new->br_blockcount); |
1568 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx - 1, | 1547 | XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx - 1, |
1569 | XFS_DATA_FORK); | 1548 | XFS_DATA_FORK); |
1570 | xfs_bmap_trace_pre_update(fname, "LF|LC", ip, idx, | 1549 | XFS_BMAP_TRACE_PRE_UPDATE("LF|LC", ip, idx, |
1571 | XFS_DATA_FORK); | 1550 | XFS_DATA_FORK); |
1572 | xfs_bmbt_set_startblock(ep, | 1551 | xfs_bmbt_set_startblock(ep, |
1573 | new->br_startblock + new->br_blockcount); | 1552 | new->br_startblock + new->br_blockcount); |
1574 | xfs_bmbt_set_blockcount(ep, | 1553 | xfs_bmbt_set_blockcount(ep, |
1575 | PREV.br_blockcount - new->br_blockcount); | 1554 | PREV.br_blockcount - new->br_blockcount); |
1576 | xfs_bmap_trace_post_update(fname, "LF|LC", ip, idx, | 1555 | XFS_BMAP_TRACE_POST_UPDATE("LF|LC", ip, idx, |
1577 | XFS_DATA_FORK); | 1556 | XFS_DATA_FORK); |
1578 | ip->i_df.if_lastex = idx - 1; | 1557 | ip->i_df.if_lastex = idx - 1; |
1579 | if (cur == NULL) | 1558 | if (cur == NULL) |
@@ -1610,15 +1589,15 @@ xfs_bmap_add_extent_unwritten_real( | |||
1610 | * Setting the first part of a previous oldext extent to newext. | 1589 | * Setting the first part of a previous oldext extent to newext. |
1611 | * The left neighbor is not contiguous. | 1590 | * The left neighbor is not contiguous. |
1612 | */ | 1591 | */ |
1613 | xfs_bmap_trace_pre_update(fname, "LF", ip, idx, XFS_DATA_FORK); | 1592 | XFS_BMAP_TRACE_PRE_UPDATE("LF", ip, idx, XFS_DATA_FORK); |
1614 | ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); | 1593 | ASSERT(ep && xfs_bmbt_get_state(ep) == oldext); |
1615 | xfs_bmbt_set_startoff(ep, new_endoff); | 1594 | xfs_bmbt_set_startoff(ep, new_endoff); |
1616 | xfs_bmbt_set_blockcount(ep, | 1595 | xfs_bmbt_set_blockcount(ep, |
1617 | PREV.br_blockcount - new->br_blockcount); | 1596 | PREV.br_blockcount - new->br_blockcount); |
1618 | xfs_bmbt_set_startblock(ep, | 1597 | xfs_bmbt_set_startblock(ep, |
1619 | new->br_startblock + new->br_blockcount); | 1598 | new->br_startblock + new->br_blockcount); |
1620 | xfs_bmap_trace_post_update(fname, "LF", ip, idx, XFS_DATA_FORK); | 1599 | XFS_BMAP_TRACE_POST_UPDATE("LF", ip, idx, XFS_DATA_FORK); |
1621 | xfs_bmap_trace_insert(fname, "LF", ip, idx, 1, new, NULL, | 1600 | XFS_BMAP_TRACE_INSERT("LF", ip, idx, 1, new, NULL, |
1622 | XFS_DATA_FORK); | 1601 | XFS_DATA_FORK); |
1623 | xfs_iext_insert(ifp, idx, 1, new); | 1602 | xfs_iext_insert(ifp, idx, 1, new); |
1624 | ip->i_df.if_lastex = idx; | 1603 | ip->i_df.if_lastex = idx; |
@@ -1653,18 +1632,18 @@ xfs_bmap_add_extent_unwritten_real( | |||
1653 | * Setting the last part of a previous oldext extent to newext. | 1632 | * Setting the last part of a previous oldext extent to newext. |
1654 | * The right neighbor is contiguous with the new allocation. | 1633 | * The right neighbor is contiguous with the new allocation. |
1655 | */ | 1634 | */ |
1656 | xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx, | 1635 | XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx, |
1657 | XFS_DATA_FORK); | 1636 | XFS_DATA_FORK); |
1658 | xfs_bmap_trace_pre_update(fname, "RF|RC", ip, idx + 1, | 1637 | XFS_BMAP_TRACE_PRE_UPDATE("RF|RC", ip, idx + 1, |
1659 | XFS_DATA_FORK); | 1638 | XFS_DATA_FORK); |
1660 | xfs_bmbt_set_blockcount(ep, | 1639 | xfs_bmbt_set_blockcount(ep, |
1661 | PREV.br_blockcount - new->br_blockcount); | 1640 | PREV.br_blockcount - new->br_blockcount); |
1662 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx, | 1641 | XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx, |
1663 | XFS_DATA_FORK); | 1642 | XFS_DATA_FORK); |
1664 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), | 1643 | xfs_bmbt_set_allf(xfs_iext_get_ext(ifp, idx + 1), |
1665 | new->br_startoff, new->br_startblock, | 1644 | new->br_startoff, new->br_startblock, |
1666 | new->br_blockcount + RIGHT.br_blockcount, newext); | 1645 | new->br_blockcount + RIGHT.br_blockcount, newext); |
1667 | xfs_bmap_trace_post_update(fname, "RF|RC", ip, idx + 1, | 1646 | XFS_BMAP_TRACE_POST_UPDATE("RF|RC", ip, idx + 1, |
1668 | XFS_DATA_FORK); | 1647 | XFS_DATA_FORK); |
1669 | ip->i_df.if_lastex = idx + 1; | 1648 | ip->i_df.if_lastex = idx + 1; |
1670 | if (cur == NULL) | 1649 | if (cur == NULL) |
@@ -1700,12 +1679,12 @@ xfs_bmap_add_extent_unwritten_real( | |||
1700 | * Setting the last part of a previous oldext extent to newext. | 1679 | * Setting the last part of a previous oldext extent to newext. |
1701 | * The right neighbor is not contiguous. | 1680 | * The right neighbor is not contiguous. |
1702 | */ | 1681 | */ |
1703 | xfs_bmap_trace_pre_update(fname, "RF", ip, idx, XFS_DATA_FORK); | 1682 | XFS_BMAP_TRACE_PRE_UPDATE("RF", ip, idx, XFS_DATA_FORK); |
1704 | xfs_bmbt_set_blockcount(ep, | 1683 | xfs_bmbt_set_blockcount(ep, |
1705 | PREV.br_blockcount - new->br_blockcount); | 1684 | PREV.br_blockcount - new->br_blockcount); |
1706 | xfs_bmap_trace_post_update(fname, "RF", ip, idx, XFS_DATA_FORK); | 1685 | XFS_BMAP_TRACE_POST_UPDATE("RF", ip, idx, XFS_DATA_FORK); |
1707 | xfs_bmap_trace_insert(fname, "RF", ip, idx + 1, 1, | 1686 | XFS_BMAP_TRACE_INSERT("RF", ip, idx + 1, 1, new, NULL, |
1708 | new, NULL, XFS_DATA_FORK); | 1687 | XFS_DATA_FORK); |
1709 | xfs_iext_insert(ifp, idx + 1, 1, new); | 1688 | xfs_iext_insert(ifp, idx + 1, 1, new); |
1710 | ip->i_df.if_lastex = idx + 1; | 1689 | ip->i_df.if_lastex = idx + 1; |
1711 | ip->i_d.di_nextents++; | 1690 | ip->i_d.di_nextents++; |
@@ -1744,17 +1723,17 @@ xfs_bmap_add_extent_unwritten_real( | |||
1744 | * newext. Contiguity is impossible here. | 1723 | * newext. Contiguity is impossible here. |
1745 | * One extent becomes three extents. | 1724 | * One extent becomes three extents. |
1746 | */ | 1725 | */ |
1747 | xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); | 1726 | XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, XFS_DATA_FORK); |
1748 | xfs_bmbt_set_blockcount(ep, | 1727 | xfs_bmbt_set_blockcount(ep, |
1749 | new->br_startoff - PREV.br_startoff); | 1728 | new->br_startoff - PREV.br_startoff); |
1750 | xfs_bmap_trace_post_update(fname, "0", ip, idx, XFS_DATA_FORK); | 1729 | XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, XFS_DATA_FORK); |
1751 | r[0] = *new; | 1730 | r[0] = *new; |
1752 | r[1].br_startoff = new_endoff; | 1731 | r[1].br_startoff = new_endoff; |
1753 | r[1].br_blockcount = | 1732 | r[1].br_blockcount = |
1754 | PREV.br_startoff + PREV.br_blockcount - new_endoff; | 1733 | PREV.br_startoff + PREV.br_blockcount - new_endoff; |
1755 | r[1].br_startblock = new->br_startblock + new->br_blockcount; | 1734 | r[1].br_startblock = new->br_startblock + new->br_blockcount; |
1756 | r[1].br_state = oldext; | 1735 | r[1].br_state = oldext; |
1757 | xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 2, &r[0], &r[1], | 1736 | XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 2, &r[0], &r[1], |
1758 | XFS_DATA_FORK); | 1737 | XFS_DATA_FORK); |
1759 | xfs_iext_insert(ifp, idx + 1, 2, &r[0]); | 1738 | xfs_iext_insert(ifp, idx + 1, 2, &r[0]); |
1760 | ip->i_df.if_lastex = idx + 1; | 1739 | ip->i_df.if_lastex = idx + 1; |
@@ -1845,9 +1824,6 @@ xfs_bmap_add_extent_hole_delay( | |||
1845 | int rsvd) /* OK to allocate reserved blocks */ | 1824 | int rsvd) /* OK to allocate reserved blocks */ |
1846 | { | 1825 | { |
1847 | xfs_bmbt_rec_t *ep; /* extent record for idx */ | 1826 | xfs_bmbt_rec_t *ep; /* extent record for idx */ |
1848 | #ifdef XFS_BMAP_TRACE | ||
1849 | static char fname[] = "xfs_bmap_add_extent_hole_delay"; | ||
1850 | #endif | ||
1851 | xfs_ifork_t *ifp; /* inode fork pointer */ | 1827 | xfs_ifork_t *ifp; /* inode fork pointer */ |
1852 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ | 1828 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ |
1853 | xfs_filblks_t newlen=0; /* new indirect size */ | 1829 | xfs_filblks_t newlen=0; /* new indirect size */ |
@@ -1919,7 +1895,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1919 | */ | 1895 | */ |
1920 | temp = left.br_blockcount + new->br_blockcount + | 1896 | temp = left.br_blockcount + new->br_blockcount + |
1921 | right.br_blockcount; | 1897 | right.br_blockcount; |
1922 | xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, | 1898 | XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, |
1923 | XFS_DATA_FORK); | 1899 | XFS_DATA_FORK); |
1924 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); | 1900 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); |
1925 | oldlen = STARTBLOCKVAL(left.br_startblock) + | 1901 | oldlen = STARTBLOCKVAL(left.br_startblock) + |
@@ -1928,10 +1904,9 @@ xfs_bmap_add_extent_hole_delay( | |||
1928 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1904 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1929 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), | 1905 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), |
1930 | NULLSTARTBLOCK((int)newlen)); | 1906 | NULLSTARTBLOCK((int)newlen)); |
1931 | xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, | 1907 | XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, |
1932 | XFS_DATA_FORK); | ||
1933 | xfs_bmap_trace_delete(fname, "LC|RC", ip, idx, 1, | ||
1934 | XFS_DATA_FORK); | 1908 | XFS_DATA_FORK); |
1909 | XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, XFS_DATA_FORK); | ||
1935 | xfs_iext_remove(ifp, idx, 1); | 1910 | xfs_iext_remove(ifp, idx, 1); |
1936 | ip->i_df.if_lastex = idx - 1; | 1911 | ip->i_df.if_lastex = idx - 1; |
1937 | /* DELTA: Two in-core extents were replaced by one. */ | 1912 | /* DELTA: Two in-core extents were replaced by one. */ |
@@ -1946,7 +1921,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1946 | * Merge the new allocation with the left neighbor. | 1921 | * Merge the new allocation with the left neighbor. |
1947 | */ | 1922 | */ |
1948 | temp = left.br_blockcount + new->br_blockcount; | 1923 | temp = left.br_blockcount + new->br_blockcount; |
1949 | xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, | 1924 | XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, |
1950 | XFS_DATA_FORK); | 1925 | XFS_DATA_FORK); |
1951 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); | 1926 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), temp); |
1952 | oldlen = STARTBLOCKVAL(left.br_startblock) + | 1927 | oldlen = STARTBLOCKVAL(left.br_startblock) + |
@@ -1954,7 +1929,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1954 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1929 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1955 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), | 1930 | xfs_bmbt_set_startblock(xfs_iext_get_ext(ifp, idx - 1), |
1956 | NULLSTARTBLOCK((int)newlen)); | 1931 | NULLSTARTBLOCK((int)newlen)); |
1957 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, | 1932 | XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, |
1958 | XFS_DATA_FORK); | 1933 | XFS_DATA_FORK); |
1959 | ip->i_df.if_lastex = idx - 1; | 1934 | ip->i_df.if_lastex = idx - 1; |
1960 | /* DELTA: One in-core extent grew into a hole. */ | 1935 | /* DELTA: One in-core extent grew into a hole. */ |
@@ -1968,14 +1943,14 @@ xfs_bmap_add_extent_hole_delay( | |||
1968 | * on the right. | 1943 | * on the right. |
1969 | * Merge the new allocation with the right neighbor. | 1944 | * Merge the new allocation with the right neighbor. |
1970 | */ | 1945 | */ |
1971 | xfs_bmap_trace_pre_update(fname, "RC", ip, idx, XFS_DATA_FORK); | 1946 | XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, XFS_DATA_FORK); |
1972 | temp = new->br_blockcount + right.br_blockcount; | 1947 | temp = new->br_blockcount + right.br_blockcount; |
1973 | oldlen = STARTBLOCKVAL(new->br_startblock) + | 1948 | oldlen = STARTBLOCKVAL(new->br_startblock) + |
1974 | STARTBLOCKVAL(right.br_startblock); | 1949 | STARTBLOCKVAL(right.br_startblock); |
1975 | newlen = xfs_bmap_worst_indlen(ip, temp); | 1950 | newlen = xfs_bmap_worst_indlen(ip, temp); |
1976 | xfs_bmbt_set_allf(ep, new->br_startoff, | 1951 | xfs_bmbt_set_allf(ep, new->br_startoff, |
1977 | NULLSTARTBLOCK((int)newlen), temp, right.br_state); | 1952 | NULLSTARTBLOCK((int)newlen), temp, right.br_state); |
1978 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, XFS_DATA_FORK); | 1953 | XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, XFS_DATA_FORK); |
1979 | ip->i_df.if_lastex = idx; | 1954 | ip->i_df.if_lastex = idx; |
1980 | /* DELTA: One in-core extent grew into a hole. */ | 1955 | /* DELTA: One in-core extent grew into a hole. */ |
1981 | temp2 = temp; | 1956 | temp2 = temp; |
@@ -1989,7 +1964,7 @@ xfs_bmap_add_extent_hole_delay( | |||
1989 | * Insert a new entry. | 1964 | * Insert a new entry. |
1990 | */ | 1965 | */ |
1991 | oldlen = newlen = 0; | 1966 | oldlen = newlen = 0; |
1992 | xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, | 1967 | XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, |
1993 | XFS_DATA_FORK); | 1968 | XFS_DATA_FORK); |
1994 | xfs_iext_insert(ifp, idx, 1, new); | 1969 | xfs_iext_insert(ifp, idx, 1, new); |
1995 | ip->i_df.if_lastex = idx; | 1970 | ip->i_df.if_lastex = idx; |
@@ -2039,9 +2014,6 @@ xfs_bmap_add_extent_hole_real( | |||
2039 | { | 2014 | { |
2040 | xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ | 2015 | xfs_bmbt_rec_t *ep; /* pointer to extent entry ins. point */ |
2041 | int error; /* error return value */ | 2016 | int error; /* error return value */ |
2042 | #ifdef XFS_BMAP_TRACE | ||
2043 | static char fname[] = "xfs_bmap_add_extent_hole_real"; | ||
2044 | #endif | ||
2045 | int i; /* temp state */ | 2017 | int i; /* temp state */ |
2046 | xfs_ifork_t *ifp; /* inode fork pointer */ | 2018 | xfs_ifork_t *ifp; /* inode fork pointer */ |
2047 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ | 2019 | xfs_bmbt_irec_t left; /* left neighbor extent entry */ |
@@ -2118,15 +2090,14 @@ xfs_bmap_add_extent_hole_real( | |||
2118 | * left and on the right. | 2090 | * left and on the right. |
2119 | * Merge all three into a single extent record. | 2091 | * Merge all three into a single extent record. |
2120 | */ | 2092 | */ |
2121 | xfs_bmap_trace_pre_update(fname, "LC|RC", ip, idx - 1, | 2093 | XFS_BMAP_TRACE_PRE_UPDATE("LC|RC", ip, idx - 1, |
2122 | whichfork); | 2094 | whichfork); |
2123 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 2095 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
2124 | left.br_blockcount + new->br_blockcount + | 2096 | left.br_blockcount + new->br_blockcount + |
2125 | right.br_blockcount); | 2097 | right.br_blockcount); |
2126 | xfs_bmap_trace_post_update(fname, "LC|RC", ip, idx - 1, | 2098 | XFS_BMAP_TRACE_POST_UPDATE("LC|RC", ip, idx - 1, |
2127 | whichfork); | 2099 | whichfork); |
2128 | xfs_bmap_trace_delete(fname, "LC|RC", ip, | 2100 | XFS_BMAP_TRACE_DELETE("LC|RC", ip, idx, 1, whichfork); |
2129 | idx, 1, whichfork); | ||
2130 | xfs_iext_remove(ifp, idx, 1); | 2101 | xfs_iext_remove(ifp, idx, 1); |
2131 | ifp->if_lastex = idx - 1; | 2102 | ifp->if_lastex = idx - 1; |
2132 | XFS_IFORK_NEXT_SET(ip, whichfork, | 2103 | XFS_IFORK_NEXT_SET(ip, whichfork, |
@@ -2168,10 +2139,10 @@ xfs_bmap_add_extent_hole_real( | |||
2168 | * on the left. | 2139 | * on the left. |
2169 | * Merge the new allocation with the left neighbor. | 2140 | * Merge the new allocation with the left neighbor. |
2170 | */ | 2141 | */ |
2171 | xfs_bmap_trace_pre_update(fname, "LC", ip, idx - 1, whichfork); | 2142 | XFS_BMAP_TRACE_PRE_UPDATE("LC", ip, idx - 1, whichfork); |
2172 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), | 2143 | xfs_bmbt_set_blockcount(xfs_iext_get_ext(ifp, idx - 1), |
2173 | left.br_blockcount + new->br_blockcount); | 2144 | left.br_blockcount + new->br_blockcount); |
2174 | xfs_bmap_trace_post_update(fname, "LC", ip, idx - 1, whichfork); | 2145 | XFS_BMAP_TRACE_POST_UPDATE("LC", ip, idx - 1, whichfork); |
2175 | ifp->if_lastex = idx - 1; | 2146 | ifp->if_lastex = idx - 1; |
2176 | if (cur == NULL) { | 2147 | if (cur == NULL) { |
2177 | rval = XFS_ILOG_FEXT(whichfork); | 2148 | rval = XFS_ILOG_FEXT(whichfork); |
@@ -2202,11 +2173,11 @@ xfs_bmap_add_extent_hole_real( | |||
2202 | * on the right. | 2173 | * on the right. |
2203 | * Merge the new allocation with the right neighbor. | 2174 | * Merge the new allocation with the right neighbor. |
2204 | */ | 2175 | */ |
2205 | xfs_bmap_trace_pre_update(fname, "RC", ip, idx, whichfork); | 2176 | XFS_BMAP_TRACE_PRE_UPDATE("RC", ip, idx, whichfork); |
2206 | xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, | 2177 | xfs_bmbt_set_allf(ep, new->br_startoff, new->br_startblock, |
2207 | new->br_blockcount + right.br_blockcount, | 2178 | new->br_blockcount + right.br_blockcount, |
2208 | right.br_state); | 2179 | right.br_state); |
2209 | xfs_bmap_trace_post_update(fname, "RC", ip, idx, whichfork); | 2180 | XFS_BMAP_TRACE_POST_UPDATE("RC", ip, idx, whichfork); |
2210 | ifp->if_lastex = idx; | 2181 | ifp->if_lastex = idx; |
2211 | if (cur == NULL) { | 2182 | if (cur == NULL) { |
2212 | rval = XFS_ILOG_FEXT(whichfork); | 2183 | rval = XFS_ILOG_FEXT(whichfork); |
@@ -2237,8 +2208,7 @@ xfs_bmap_add_extent_hole_real( | |||
2237 | * real allocation. | 2208 | * real allocation. |
2238 | * Insert a new entry. | 2209 | * Insert a new entry. |
2239 | */ | 2210 | */ |
2240 | xfs_bmap_trace_insert(fname, "0", ip, idx, 1, new, NULL, | 2211 | XFS_BMAP_TRACE_INSERT("0", ip, idx, 1, new, NULL, whichfork); |
2241 | whichfork); | ||
2242 | xfs_iext_insert(ifp, idx, 1, new); | 2212 | xfs_iext_insert(ifp, idx, 1, new); |
2243 | ifp->if_lastex = idx; | 2213 | ifp->if_lastex = idx; |
2244 | XFS_IFORK_NEXT_SET(ip, whichfork, | 2214 | XFS_IFORK_NEXT_SET(ip, whichfork, |
@@ -2605,12 +2575,10 @@ xfs_bmap_rtalloc( | |||
2605 | xfs_extlen_t prod = 0; /* product factor for allocators */ | 2575 | xfs_extlen_t prod = 0; /* product factor for allocators */ |
2606 | xfs_extlen_t ralen = 0; /* realtime allocation length */ | 2576 | xfs_extlen_t ralen = 0; /* realtime allocation length */ |
2607 | xfs_extlen_t align; /* minimum allocation alignment */ | 2577 | xfs_extlen_t align; /* minimum allocation alignment */ |
2608 | xfs_rtblock_t rtx; /* realtime extent number */ | ||
2609 | xfs_rtblock_t rtb; | 2578 | xfs_rtblock_t rtb; |
2610 | 2579 | ||
2611 | mp = ap->ip->i_mount; | 2580 | mp = ap->ip->i_mount; |
2612 | align = ap->ip->i_d.di_extsize ? | 2581 | align = xfs_get_extsz_hint(ap->ip); |
2613 | ap->ip->i_d.di_extsize : mp->m_sb.sb_rextsize; | ||
2614 | prod = align / mp->m_sb.sb_rextsize; | 2582 | prod = align / mp->m_sb.sb_rextsize; |
2615 | error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, | 2583 | error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, |
2616 | align, 1, ap->eof, 0, | 2584 | align, 1, ap->eof, 0, |
@@ -2644,6 +2612,8 @@ xfs_bmap_rtalloc( | |||
2644 | * pick an extent that will space things out in the rt area. | 2612 | * pick an extent that will space things out in the rt area. |
2645 | */ | 2613 | */ |
2646 | if (ap->eof && ap->off == 0) { | 2614 | if (ap->eof && ap->off == 0) { |
2615 | xfs_rtblock_t uninitialized_var(rtx); /* realtime extent no */ | ||
2616 | |||
2647 | error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); | 2617 | error = xfs_rtpick_extent(mp, ap->tp, ralen, &rtx); |
2648 | if (error) | 2618 | if (error) |
2649 | return error; | 2619 | return error; |
@@ -2715,9 +2685,7 @@ xfs_bmap_btalloc( | |||
2715 | int error; | 2685 | int error; |
2716 | 2686 | ||
2717 | mp = ap->ip->i_mount; | 2687 | mp = ap->ip->i_mount; |
2718 | align = (ap->userdata && ap->ip->i_d.di_extsize && | 2688 | align = ap->userdata ? xfs_get_extsz_hint(ap->ip) : 0; |
2719 | (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)) ? | ||
2720 | ap->ip->i_d.di_extsize : 0; | ||
2721 | if (unlikely(align)) { | 2689 | if (unlikely(align)) { |
2722 | error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, | 2690 | error = xfs_bmap_extsize_align(mp, ap->gotp, ap->prevp, |
2723 | align, 0, ap->eof, 0, ap->conv, | 2691 | align, 0, ap->eof, 0, ap->conv, |
@@ -2727,9 +2695,15 @@ xfs_bmap_btalloc( | |||
2727 | } | 2695 | } |
2728 | nullfb = ap->firstblock == NULLFSBLOCK; | 2696 | nullfb = ap->firstblock == NULLFSBLOCK; |
2729 | fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); | 2697 | fb_agno = nullfb ? NULLAGNUMBER : XFS_FSB_TO_AGNO(mp, ap->firstblock); |
2730 | if (nullfb) | 2698 | if (nullfb) { |
2731 | ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); | 2699 | if (ap->userdata && xfs_inode_is_filestream(ap->ip)) { |
2732 | else | 2700 | ag = xfs_filestream_lookup_ag(ap->ip); |
2701 | ag = (ag != NULLAGNUMBER) ? ag : 0; | ||
2702 | ap->rval = XFS_AGB_TO_FSB(mp, ag, 0); | ||
2703 | } else { | ||
2704 | ap->rval = XFS_INO_TO_FSB(mp, ap->ip->i_ino); | ||
2705 | } | ||
2706 | } else | ||
2733 | ap->rval = ap->firstblock; | 2707 | ap->rval = ap->firstblock; |
2734 | 2708 | ||
2735 | xfs_bmap_adjacent(ap); | 2709 | xfs_bmap_adjacent(ap); |
@@ -2753,13 +2727,22 @@ xfs_bmap_btalloc( | |||
2753 | args.firstblock = ap->firstblock; | 2727 | args.firstblock = ap->firstblock; |
2754 | blen = 0; | 2728 | blen = 0; |
2755 | if (nullfb) { | 2729 | if (nullfb) { |
2756 | args.type = XFS_ALLOCTYPE_START_BNO; | 2730 | if (ap->userdata && xfs_inode_is_filestream(ap->ip)) |
2731 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | ||
2732 | else | ||
2733 | args.type = XFS_ALLOCTYPE_START_BNO; | ||
2757 | args.total = ap->total; | 2734 | args.total = ap->total; |
2735 | |||
2758 | /* | 2736 | /* |
2759 | * Find the longest available space. | 2737 | * Search for an allocation group with a single extent |
2760 | * We're going to try for the whole allocation at once. | 2738 | * large enough for the request. |
2739 | * | ||
2740 | * If one isn't found, then adjust the minimum allocation | ||
2741 | * size to the largest space found. | ||
2761 | */ | 2742 | */ |
2762 | startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); | 2743 | startag = ag = XFS_FSB_TO_AGNO(mp, args.fsbno); |
2744 | if (startag == NULLAGNUMBER) | ||
2745 | startag = ag = 0; | ||
2763 | notinit = 0; | 2746 | notinit = 0; |
2764 | down_read(&mp->m_peraglock); | 2747 | down_read(&mp->m_peraglock); |
2765 | while (blen < ap->alen) { | 2748 | while (blen < ap->alen) { |
@@ -2785,6 +2768,35 @@ xfs_bmap_btalloc( | |||
2785 | blen = longest; | 2768 | blen = longest; |
2786 | } else | 2769 | } else |
2787 | notinit = 1; | 2770 | notinit = 1; |
2771 | |||
2772 | if (xfs_inode_is_filestream(ap->ip)) { | ||
2773 | if (blen >= ap->alen) | ||
2774 | break; | ||
2775 | |||
2776 | if (ap->userdata) { | ||
2777 | /* | ||
2778 | * If startag is an invalid AG, we've | ||
2779 | * come here once before and | ||
2780 | * xfs_filestream_new_ag picked the | ||
2781 | * best currently available. | ||
2782 | * | ||
2783 | * Don't continue looping, since we | ||
2784 | * could loop forever. | ||
2785 | */ | ||
2786 | if (startag == NULLAGNUMBER) | ||
2787 | break; | ||
2788 | |||
2789 | error = xfs_filestream_new_ag(ap, &ag); | ||
2790 | if (error) { | ||
2791 | up_read(&mp->m_peraglock); | ||
2792 | return error; | ||
2793 | } | ||
2794 | |||
2795 | /* loop again to set 'blen'*/ | ||
2796 | startag = NULLAGNUMBER; | ||
2797 | continue; | ||
2798 | } | ||
2799 | } | ||
2788 | if (++ag == mp->m_sb.sb_agcount) | 2800 | if (++ag == mp->m_sb.sb_agcount) |
2789 | ag = 0; | 2801 | ag = 0; |
2790 | if (ag == startag) | 2802 | if (ag == startag) |
@@ -2809,17 +2821,27 @@ xfs_bmap_btalloc( | |||
2809 | */ | 2821 | */ |
2810 | else | 2822 | else |
2811 | args.minlen = ap->alen; | 2823 | args.minlen = ap->alen; |
2824 | |||
2825 | /* | ||
2826 | * set the failure fallback case to look in the selected | ||
2827 | * AG as the stream may have moved. | ||
2828 | */ | ||
2829 | if (xfs_inode_is_filestream(ap->ip)) | ||
2830 | ap->rval = args.fsbno = XFS_AGB_TO_FSB(mp, ag, 0); | ||
2812 | } else if (ap->low) { | 2831 | } else if (ap->low) { |
2813 | args.type = XFS_ALLOCTYPE_START_BNO; | 2832 | if (xfs_inode_is_filestream(ap->ip)) |
2833 | args.type = XFS_ALLOCTYPE_FIRST_AG; | ||
2834 | else | ||
2835 | args.type = XFS_ALLOCTYPE_START_BNO; | ||
2814 | args.total = args.minlen = ap->minlen; | 2836 | args.total = args.minlen = ap->minlen; |
2815 | } else { | 2837 | } else { |
2816 | args.type = XFS_ALLOCTYPE_NEAR_BNO; | 2838 | args.type = XFS_ALLOCTYPE_NEAR_BNO; |
2817 | args.total = ap->total; | 2839 | args.total = ap->total; |
2818 | args.minlen = ap->minlen; | 2840 | args.minlen = ap->minlen; |
2819 | } | 2841 | } |
2820 | if (unlikely(ap->userdata && ap->ip->i_d.di_extsize && | 2842 | /* apply extent size hints if obtained earlier */ |
2821 | (ap->ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE))) { | 2843 | if (unlikely(align)) { |
2822 | args.prod = ap->ip->i_d.di_extsize; | 2844 | args.prod = align; |
2823 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) | 2845 | if ((args.mod = (xfs_extlen_t)do_mod(ap->off, args.prod))) |
2824 | args.mod = (xfs_extlen_t)(args.prod - args.mod); | 2846 | args.mod = (xfs_extlen_t)(args.prod - args.mod); |
2825 | } else if (mp->m_sb.sb_blocksize >= NBPP) { | 2847 | } else if (mp->m_sb.sb_blocksize >= NBPP) { |
@@ -3051,9 +3073,6 @@ xfs_bmap_del_extent( | |||
3051 | xfs_bmbt_rec_t *ep; /* current extent entry pointer */ | 3073 | xfs_bmbt_rec_t *ep; /* current extent entry pointer */ |
3052 | int error; /* error return value */ | 3074 | int error; /* error return value */ |
3053 | int flags; /* inode logging flags */ | 3075 | int flags; /* inode logging flags */ |
3054 | #ifdef XFS_BMAP_TRACE | ||
3055 | static char fname[] = "xfs_bmap_del_extent"; | ||
3056 | #endif | ||
3057 | xfs_bmbt_irec_t got; /* current extent entry */ | 3076 | xfs_bmbt_irec_t got; /* current extent entry */ |
3058 | xfs_fileoff_t got_endoff; /* first offset past got */ | 3077 | xfs_fileoff_t got_endoff; /* first offset past got */ |
3059 | int i; /* temp state */ | 3078 | int i; /* temp state */ |
@@ -3147,7 +3166,7 @@ xfs_bmap_del_extent( | |||
3147 | /* | 3166 | /* |
3148 | * Matches the whole extent. Delete the entry. | 3167 | * Matches the whole extent. Delete the entry. |
3149 | */ | 3168 | */ |
3150 | xfs_bmap_trace_delete(fname, "3", ip, idx, 1, whichfork); | 3169 | XFS_BMAP_TRACE_DELETE("3", ip, idx, 1, whichfork); |
3151 | xfs_iext_remove(ifp, idx, 1); | 3170 | xfs_iext_remove(ifp, idx, 1); |
3152 | ifp->if_lastex = idx; | 3171 | ifp->if_lastex = idx; |
3153 | if (delay) | 3172 | if (delay) |
@@ -3168,7 +3187,7 @@ xfs_bmap_del_extent( | |||
3168 | /* | 3187 | /* |
3169 | * Deleting the first part of the extent. | 3188 | * Deleting the first part of the extent. |
3170 | */ | 3189 | */ |
3171 | xfs_bmap_trace_pre_update(fname, "2", ip, idx, whichfork); | 3190 | XFS_BMAP_TRACE_PRE_UPDATE("2", ip, idx, whichfork); |
3172 | xfs_bmbt_set_startoff(ep, del_endoff); | 3191 | xfs_bmbt_set_startoff(ep, del_endoff); |
3173 | temp = got.br_blockcount - del->br_blockcount; | 3192 | temp = got.br_blockcount - del->br_blockcount; |
3174 | xfs_bmbt_set_blockcount(ep, temp); | 3193 | xfs_bmbt_set_blockcount(ep, temp); |
@@ -3177,13 +3196,13 @@ xfs_bmap_del_extent( | |||
3177 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 3196 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
3178 | da_old); | 3197 | da_old); |
3179 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 3198 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
3180 | xfs_bmap_trace_post_update(fname, "2", ip, idx, | 3199 | XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, |
3181 | whichfork); | 3200 | whichfork); |
3182 | da_new = temp; | 3201 | da_new = temp; |
3183 | break; | 3202 | break; |
3184 | } | 3203 | } |
3185 | xfs_bmbt_set_startblock(ep, del_endblock); | 3204 | xfs_bmbt_set_startblock(ep, del_endblock); |
3186 | xfs_bmap_trace_post_update(fname, "2", ip, idx, whichfork); | 3205 | XFS_BMAP_TRACE_POST_UPDATE("2", ip, idx, whichfork); |
3187 | if (!cur) { | 3206 | if (!cur) { |
3188 | flags |= XFS_ILOG_FEXT(whichfork); | 3207 | flags |= XFS_ILOG_FEXT(whichfork); |
3189 | break; | 3208 | break; |
@@ -3199,19 +3218,19 @@ xfs_bmap_del_extent( | |||
3199 | * Deleting the last part of the extent. | 3218 | * Deleting the last part of the extent. |
3200 | */ | 3219 | */ |
3201 | temp = got.br_blockcount - del->br_blockcount; | 3220 | temp = got.br_blockcount - del->br_blockcount; |
3202 | xfs_bmap_trace_pre_update(fname, "1", ip, idx, whichfork); | 3221 | XFS_BMAP_TRACE_PRE_UPDATE("1", ip, idx, whichfork); |
3203 | xfs_bmbt_set_blockcount(ep, temp); | 3222 | xfs_bmbt_set_blockcount(ep, temp); |
3204 | ifp->if_lastex = idx; | 3223 | ifp->if_lastex = idx; |
3205 | if (delay) { | 3224 | if (delay) { |
3206 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), | 3225 | temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp), |
3207 | da_old); | 3226 | da_old); |
3208 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); | 3227 | xfs_bmbt_set_startblock(ep, NULLSTARTBLOCK((int)temp)); |
3209 | xfs_bmap_trace_post_update(fname, "1", ip, idx, | 3228 | XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, |
3210 | whichfork); | 3229 | whichfork); |
3211 | da_new = temp; | 3230 | da_new = temp; |
3212 | break; | 3231 | break; |
3213 | } | 3232 | } |
3214 | xfs_bmap_trace_post_update(fname, "1", ip, idx, whichfork); | 3233 | XFS_BMAP_TRACE_POST_UPDATE("1", ip, idx, whichfork); |
3215 | if (!cur) { | 3234 | if (!cur) { |
3216 | flags |= XFS_ILOG_FEXT(whichfork); | 3235 | flags |= XFS_ILOG_FEXT(whichfork); |
3217 | break; | 3236 | break; |
@@ -3228,7 +3247,7 @@ xfs_bmap_del_extent( | |||
3228 | * Deleting the middle of the extent. | 3247 | * Deleting the middle of the extent. |
3229 | */ | 3248 | */ |
3230 | temp = del->br_startoff - got.br_startoff; | 3249 | temp = del->br_startoff - got.br_startoff; |
3231 | xfs_bmap_trace_pre_update(fname, "0", ip, idx, whichfork); | 3250 | XFS_BMAP_TRACE_PRE_UPDATE("0", ip, idx, whichfork); |
3232 | xfs_bmbt_set_blockcount(ep, temp); | 3251 | xfs_bmbt_set_blockcount(ep, temp); |
3233 | new.br_startoff = del_endoff; | 3252 | new.br_startoff = del_endoff; |
3234 | temp2 = got_endoff - del_endoff; | 3253 | temp2 = got_endoff - del_endoff; |
@@ -3315,8 +3334,8 @@ xfs_bmap_del_extent( | |||
3315 | } | 3334 | } |
3316 | } | 3335 | } |
3317 | } | 3336 | } |
3318 | xfs_bmap_trace_post_update(fname, "0", ip, idx, whichfork); | 3337 | XFS_BMAP_TRACE_POST_UPDATE("0", ip, idx, whichfork); |
3319 | xfs_bmap_trace_insert(fname, "0", ip, idx + 1, 1, &new, NULL, | 3338 | XFS_BMAP_TRACE_INSERT("0", ip, idx + 1, 1, &new, NULL, |
3320 | whichfork); | 3339 | whichfork); |
3321 | xfs_iext_insert(ifp, idx + 1, 1, &new); | 3340 | xfs_iext_insert(ifp, idx + 1, 1, &new); |
3322 | ifp->if_lastex = idx + 1; | 3341 | ifp->if_lastex = idx + 1; |
@@ -3556,9 +3575,6 @@ xfs_bmap_local_to_extents( | |||
3556 | { | 3575 | { |
3557 | int error; /* error return value */ | 3576 | int error; /* error return value */ |
3558 | int flags; /* logging flags returned */ | 3577 | int flags; /* logging flags returned */ |
3559 | #ifdef XFS_BMAP_TRACE | ||
3560 | static char fname[] = "xfs_bmap_local_to_extents"; | ||
3561 | #endif | ||
3562 | xfs_ifork_t *ifp; /* inode fork pointer */ | 3578 | xfs_ifork_t *ifp; /* inode fork pointer */ |
3563 | 3579 | ||
3564 | /* | 3580 | /* |
@@ -3613,7 +3629,7 @@ xfs_bmap_local_to_extents( | |||
3613 | xfs_iext_add(ifp, 0, 1); | 3629 | xfs_iext_add(ifp, 0, 1); |
3614 | ep = xfs_iext_get_ext(ifp, 0); | 3630 | ep = xfs_iext_get_ext(ifp, 0); |
3615 | xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); | 3631 | xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM); |
3616 | xfs_bmap_trace_post_update(fname, "new", ip, 0, whichfork); | 3632 | XFS_BMAP_TRACE_POST_UPDATE("new", ip, 0, whichfork); |
3617 | XFS_IFORK_NEXT_SET(ip, whichfork, 1); | 3633 | XFS_IFORK_NEXT_SET(ip, whichfork, 1); |
3618 | ip->i_d.di_nblocks = 1; | 3634 | ip->i_d.di_nblocks = 1; |
3619 | XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, | 3635 | XFS_TRANS_MOD_DQUOT_BYINO(args.mp, tp, ip, |
@@ -3736,7 +3752,7 @@ ktrace_t *xfs_bmap_trace_buf; | |||
3736 | STATIC void | 3752 | STATIC void |
3737 | xfs_bmap_trace_addentry( | 3753 | xfs_bmap_trace_addentry( |
3738 | int opcode, /* operation */ | 3754 | int opcode, /* operation */ |
3739 | char *fname, /* function name */ | 3755 | const char *fname, /* function name */ |
3740 | char *desc, /* operation description */ | 3756 | char *desc, /* operation description */ |
3741 | xfs_inode_t *ip, /* incore inode pointer */ | 3757 | xfs_inode_t *ip, /* incore inode pointer */ |
3742 | xfs_extnum_t idx, /* index of entry(ies) */ | 3758 | xfs_extnum_t idx, /* index of entry(ies) */ |
@@ -3795,7 +3811,7 @@ xfs_bmap_trace_addentry( | |||
3795 | */ | 3811 | */ |
3796 | STATIC void | 3812 | STATIC void |
3797 | xfs_bmap_trace_delete( | 3813 | xfs_bmap_trace_delete( |
3798 | char *fname, /* function name */ | 3814 | const char *fname, /* function name */ |
3799 | char *desc, /* operation description */ | 3815 | char *desc, /* operation description */ |
3800 | xfs_inode_t *ip, /* incore inode pointer */ | 3816 | xfs_inode_t *ip, /* incore inode pointer */ |
3801 | xfs_extnum_t idx, /* index of entry(entries) deleted */ | 3817 | xfs_extnum_t idx, /* index of entry(entries) deleted */ |
@@ -3817,7 +3833,7 @@ xfs_bmap_trace_delete( | |||
3817 | */ | 3833 | */ |
3818 | STATIC void | 3834 | STATIC void |
3819 | xfs_bmap_trace_insert( | 3835 | xfs_bmap_trace_insert( |
3820 | char *fname, /* function name */ | 3836 | const char *fname, /* function name */ |
3821 | char *desc, /* operation description */ | 3837 | char *desc, /* operation description */ |
3822 | xfs_inode_t *ip, /* incore inode pointer */ | 3838 | xfs_inode_t *ip, /* incore inode pointer */ |
3823 | xfs_extnum_t idx, /* index of entry(entries) inserted */ | 3839 | xfs_extnum_t idx, /* index of entry(entries) inserted */ |
@@ -3846,7 +3862,7 @@ xfs_bmap_trace_insert( | |||
3846 | */ | 3862 | */ |
3847 | STATIC void | 3863 | STATIC void |
3848 | xfs_bmap_trace_post_update( | 3864 | xfs_bmap_trace_post_update( |
3849 | char *fname, /* function name */ | 3865 | const char *fname, /* function name */ |
3850 | char *desc, /* operation description */ | 3866 | char *desc, /* operation description */ |
3851 | xfs_inode_t *ip, /* incore inode pointer */ | 3867 | xfs_inode_t *ip, /* incore inode pointer */ |
3852 | xfs_extnum_t idx, /* index of entry updated */ | 3868 | xfs_extnum_t idx, /* index of entry updated */ |
@@ -3864,7 +3880,7 @@ xfs_bmap_trace_post_update( | |||
3864 | */ | 3880 | */ |
3865 | STATIC void | 3881 | STATIC void |
3866 | xfs_bmap_trace_pre_update( | 3882 | xfs_bmap_trace_pre_update( |
3867 | char *fname, /* function name */ | 3883 | const char *fname, /* function name */ |
3868 | char *desc, /* operation description */ | 3884 | char *desc, /* operation description */ |
3869 | xfs_inode_t *ip, /* incore inode pointer */ | 3885 | xfs_inode_t *ip, /* incore inode pointer */ |
3870 | xfs_extnum_t idx, /* index of entry to be updated */ | 3886 | xfs_extnum_t idx, /* index of entry to be updated */ |
@@ -4481,9 +4497,6 @@ xfs_bmap_read_extents( | |||
4481 | xfs_buf_t *bp; /* buffer for "block" */ | 4497 | xfs_buf_t *bp; /* buffer for "block" */ |
4482 | int error; /* error return value */ | 4498 | int error; /* error return value */ |
4483 | xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ | 4499 | xfs_exntfmt_t exntf; /* XFS_EXTFMT_NOSTATE, if checking */ |
4484 | #ifdef XFS_BMAP_TRACE | ||
4485 | static char fname[] = "xfs_bmap_read_extents"; | ||
4486 | #endif | ||
4487 | xfs_extnum_t i, j; /* index into the extents list */ | 4500 | xfs_extnum_t i, j; /* index into the extents list */ |
4488 | xfs_ifork_t *ifp; /* fork structure */ | 4501 | xfs_ifork_t *ifp; /* fork structure */ |
4489 | int level; /* btree level, for checking */ | 4502 | int level; /* btree level, for checking */ |
@@ -4600,7 +4613,7 @@ xfs_bmap_read_extents( | |||
4600 | } | 4613 | } |
4601 | ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); | 4614 | ASSERT(i == (ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); |
4602 | ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); | 4615 | ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork)); |
4603 | xfs_bmap_trace_exlist(fname, ip, i, whichfork); | 4616 | XFS_BMAP_TRACE_EXLIST(ip, i, whichfork); |
4604 | return 0; | 4617 | return 0; |
4605 | error0: | 4618 | error0: |
4606 | xfs_trans_brelse(tp, bp); | 4619 | xfs_trans_brelse(tp, bp); |
@@ -4613,7 +4626,7 @@ error0: | |||
4613 | */ | 4626 | */ |
4614 | void | 4627 | void |
4615 | xfs_bmap_trace_exlist( | 4628 | xfs_bmap_trace_exlist( |
4616 | char *fname, /* function name */ | 4629 | const char *fname, /* function name */ |
4617 | xfs_inode_t *ip, /* incore inode pointer */ | 4630 | xfs_inode_t *ip, /* incore inode pointer */ |
4618 | xfs_extnum_t cnt, /* count of entries in the list */ | 4631 | xfs_extnum_t cnt, /* count of entries in the list */ |
4619 | int whichfork) /* data or attr fork */ | 4632 | int whichfork) /* data or attr fork */ |
@@ -4628,7 +4641,7 @@ xfs_bmap_trace_exlist( | |||
4628 | for (idx = 0; idx < cnt; idx++) { | 4641 | for (idx = 0; idx < cnt; idx++) { |
4629 | ep = xfs_iext_get_ext(ifp, idx); | 4642 | ep = xfs_iext_get_ext(ifp, idx); |
4630 | xfs_bmbt_get_all(ep, &s); | 4643 | xfs_bmbt_get_all(ep, &s); |
4631 | xfs_bmap_trace_insert(fname, "exlist", ip, idx, 1, &s, NULL, | 4644 | XFS_BMAP_TRACE_INSERT("exlist", ip, idx, 1, &s, NULL, |
4632 | whichfork); | 4645 | whichfork); |
4633 | } | 4646 | } |
4634 | } | 4647 | } |
@@ -4868,12 +4881,7 @@ xfs_bmapi( | |||
4868 | xfs_extlen_t extsz; | 4881 | xfs_extlen_t extsz; |
4869 | 4882 | ||
4870 | /* Figure out the extent size, adjust alen */ | 4883 | /* Figure out the extent size, adjust alen */ |
4871 | if (rt) { | 4884 | extsz = xfs_get_extsz_hint(ip); |
4872 | if (!(extsz = ip->i_d.di_extsize)) | ||
4873 | extsz = mp->m_sb.sb_rextsize; | ||
4874 | } else { | ||
4875 | extsz = ip->i_d.di_extsize; | ||
4876 | } | ||
4877 | if (extsz) { | 4885 | if (extsz) { |
4878 | error = xfs_bmap_extsize_align(mp, | 4886 | error = xfs_bmap_extsize_align(mp, |
4879 | &got, &prev, extsz, | 4887 | &got, &prev, extsz, |
@@ -5219,10 +5227,10 @@ xfs_bmapi( | |||
5219 | * Else go on to the next record. | 5227 | * Else go on to the next record. |
5220 | */ | 5228 | */ |
5221 | ep = xfs_iext_get_ext(ifp, ++lastx); | 5229 | ep = xfs_iext_get_ext(ifp, ++lastx); |
5222 | if (lastx >= nextents) { | 5230 | prev = got; |
5231 | if (lastx >= nextents) | ||
5223 | eof = 1; | 5232 | eof = 1; |
5224 | prev = got; | 5233 | else |
5225 | } else | ||
5226 | xfs_bmbt_get_all(ep, &got); | 5234 | xfs_bmbt_get_all(ep, &got); |
5227 | } | 5235 | } |
5228 | ifp->if_lastex = lastx; | 5236 | ifp->if_lastex = lastx; |
@@ -5813,8 +5821,7 @@ xfs_getbmap( | |||
5813 | ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) | 5821 | ip->i_d.di_format != XFS_DINODE_FMT_LOCAL) |
5814 | return XFS_ERROR(EINVAL); | 5822 | return XFS_ERROR(EINVAL); |
5815 | if (whichfork == XFS_DATA_FORK) { | 5823 | if (whichfork == XFS_DATA_FORK) { |
5816 | if ((ip->i_d.di_extsize && (ip->i_d.di_flags & | 5824 | if (xfs_get_extsz_hint(ip) || |
5817 | (XFS_DIFLAG_REALTIME|XFS_DIFLAG_EXTSIZE))) || | ||
5818 | ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){ | 5825 | ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC|XFS_DIFLAG_APPEND)){ |
5819 | prealloced = 1; | 5826 | prealloced = 1; |
5820 | fixlen = XFS_MAXIOFFSET(mp); | 5827 | fixlen = XFS_MAXIOFFSET(mp); |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 4f24c7e39b3..524b1c9d524 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -144,12 +144,14 @@ extern ktrace_t *xfs_bmap_trace_buf; | |||
144 | */ | 144 | */ |
145 | void | 145 | void |
146 | xfs_bmap_trace_exlist( | 146 | xfs_bmap_trace_exlist( |
147 | char *fname, /* function name */ | 147 | const char *fname, /* function name */ |
148 | struct xfs_inode *ip, /* incore inode pointer */ | 148 | struct xfs_inode *ip, /* incore inode pointer */ |
149 | xfs_extnum_t cnt, /* count of entries in list */ | 149 | xfs_extnum_t cnt, /* count of entries in list */ |
150 | int whichfork); /* data or attr fork */ | 150 | int whichfork); /* data or attr fork */ |
151 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) \ | ||
152 | xfs_bmap_trace_exlist(__FUNCTION__,ip,c,w) | ||
151 | #else | 153 | #else |
152 | #define xfs_bmap_trace_exlist(f,ip,c,w) | 154 | #define XFS_BMAP_TRACE_EXLIST(ip,c,w) |
153 | #endif | 155 | #endif |
154 | 156 | ||
155 | /* | 157 | /* |
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index 0bf192fea3e..89b891f51cf 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c | |||
@@ -76,7 +76,7 @@ static char EXIT[] = "exit"; | |||
76 | */ | 76 | */ |
77 | STATIC void | 77 | STATIC void |
78 | xfs_bmbt_trace_enter( | 78 | xfs_bmbt_trace_enter( |
79 | char *func, | 79 | const char *func, |
80 | xfs_btree_cur_t *cur, | 80 | xfs_btree_cur_t *cur, |
81 | char *s, | 81 | char *s, |
82 | int type, | 82 | int type, |
@@ -117,7 +117,7 @@ xfs_bmbt_trace_enter( | |||
117 | */ | 117 | */ |
118 | STATIC void | 118 | STATIC void |
119 | xfs_bmbt_trace_argbi( | 119 | xfs_bmbt_trace_argbi( |
120 | char *func, | 120 | const char *func, |
121 | xfs_btree_cur_t *cur, | 121 | xfs_btree_cur_t *cur, |
122 | xfs_buf_t *b, | 122 | xfs_buf_t *b, |
123 | int i, | 123 | int i, |
@@ -134,7 +134,7 @@ xfs_bmbt_trace_argbi( | |||
134 | */ | 134 | */ |
135 | STATIC void | 135 | STATIC void |
136 | xfs_bmbt_trace_argbii( | 136 | xfs_bmbt_trace_argbii( |
137 | char *func, | 137 | const char *func, |
138 | xfs_btree_cur_t *cur, | 138 | xfs_btree_cur_t *cur, |
139 | xfs_buf_t *b, | 139 | xfs_buf_t *b, |
140 | int i0, | 140 | int i0, |
@@ -153,7 +153,7 @@ xfs_bmbt_trace_argbii( | |||
153 | */ | 153 | */ |
154 | STATIC void | 154 | STATIC void |
155 | xfs_bmbt_trace_argfffi( | 155 | xfs_bmbt_trace_argfffi( |
156 | char *func, | 156 | const char *func, |
157 | xfs_btree_cur_t *cur, | 157 | xfs_btree_cur_t *cur, |
158 | xfs_dfiloff_t o, | 158 | xfs_dfiloff_t o, |
159 | xfs_dfsbno_t b, | 159 | xfs_dfsbno_t b, |
@@ -172,7 +172,7 @@ xfs_bmbt_trace_argfffi( | |||
172 | */ | 172 | */ |
173 | STATIC void | 173 | STATIC void |
174 | xfs_bmbt_trace_argi( | 174 | xfs_bmbt_trace_argi( |
175 | char *func, | 175 | const char *func, |
176 | xfs_btree_cur_t *cur, | 176 | xfs_btree_cur_t *cur, |
177 | int i, | 177 | int i, |
178 | int line) | 178 | int line) |
@@ -188,7 +188,7 @@ xfs_bmbt_trace_argi( | |||
188 | */ | 188 | */ |
189 | STATIC void | 189 | STATIC void |
190 | xfs_bmbt_trace_argifk( | 190 | xfs_bmbt_trace_argifk( |
191 | char *func, | 191 | const char *func, |
192 | xfs_btree_cur_t *cur, | 192 | xfs_btree_cur_t *cur, |
193 | int i, | 193 | int i, |
194 | xfs_fsblock_t f, | 194 | xfs_fsblock_t f, |
@@ -206,7 +206,7 @@ xfs_bmbt_trace_argifk( | |||
206 | */ | 206 | */ |
207 | STATIC void | 207 | STATIC void |
208 | xfs_bmbt_trace_argifr( | 208 | xfs_bmbt_trace_argifr( |
209 | char *func, | 209 | const char *func, |
210 | xfs_btree_cur_t *cur, | 210 | xfs_btree_cur_t *cur, |
211 | int i, | 211 | int i, |
212 | xfs_fsblock_t f, | 212 | xfs_fsblock_t f, |
@@ -235,7 +235,7 @@ xfs_bmbt_trace_argifr( | |||
235 | */ | 235 | */ |
236 | STATIC void | 236 | STATIC void |
237 | xfs_bmbt_trace_argik( | 237 | xfs_bmbt_trace_argik( |
238 | char *func, | 238 | const char *func, |
239 | xfs_btree_cur_t *cur, | 239 | xfs_btree_cur_t *cur, |
240 | int i, | 240 | int i, |
241 | xfs_bmbt_key_t *k, | 241 | xfs_bmbt_key_t *k, |
@@ -255,7 +255,7 @@ xfs_bmbt_trace_argik( | |||
255 | */ | 255 | */ |
256 | STATIC void | 256 | STATIC void |
257 | xfs_bmbt_trace_cursor( | 257 | xfs_bmbt_trace_cursor( |
258 | char *func, | 258 | const char *func, |
259 | xfs_btree_cur_t *cur, | 259 | xfs_btree_cur_t *cur, |
260 | char *s, | 260 | char *s, |
261 | int line) | 261 | int line) |
@@ -274,21 +274,21 @@ xfs_bmbt_trace_cursor( | |||
274 | } | 274 | } |
275 | 275 | ||
276 | #define XFS_BMBT_TRACE_ARGBI(c,b,i) \ | 276 | #define XFS_BMBT_TRACE_ARGBI(c,b,i) \ |
277 | xfs_bmbt_trace_argbi(fname, c, b, i, __LINE__) | 277 | xfs_bmbt_trace_argbi(__FUNCTION__, c, b, i, __LINE__) |
278 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \ | 278 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) \ |
279 | xfs_bmbt_trace_argbii(fname, c, b, i, j, __LINE__) | 279 | xfs_bmbt_trace_argbii(__FUNCTION__, c, b, i, j, __LINE__) |
280 | #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \ | 280 | #define XFS_BMBT_TRACE_ARGFFFI(c,o,b,i,j) \ |
281 | xfs_bmbt_trace_argfffi(fname, c, o, b, i, j, __LINE__) | 281 | xfs_bmbt_trace_argfffi(__FUNCTION__, c, o, b, i, j, __LINE__) |
282 | #define XFS_BMBT_TRACE_ARGI(c,i) \ | 282 | #define XFS_BMBT_TRACE_ARGI(c,i) \ |
283 | xfs_bmbt_trace_argi(fname, c, i, __LINE__) | 283 | xfs_bmbt_trace_argi(__FUNCTION__, c, i, __LINE__) |
284 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \ | 284 | #define XFS_BMBT_TRACE_ARGIFK(c,i,f,s) \ |
285 | xfs_bmbt_trace_argifk(fname, c, i, f, s, __LINE__) | 285 | xfs_bmbt_trace_argifk(__FUNCTION__, c, i, f, s, __LINE__) |
286 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ | 286 | #define XFS_BMBT_TRACE_ARGIFR(c,i,f,r) \ |
287 | xfs_bmbt_trace_argifr(fname, c, i, f, r, __LINE__) | 287 | xfs_bmbt_trace_argifr(__FUNCTION__, c, i, f, r, __LINE__) |
288 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ | 288 | #define XFS_BMBT_TRACE_ARGIK(c,i,k) \ |
289 | xfs_bmbt_trace_argik(fname, c, i, k, __LINE__) | 289 | xfs_bmbt_trace_argik(__FUNCTION__, c, i, k, __LINE__) |
290 | #define XFS_BMBT_TRACE_CURSOR(c,s) \ | 290 | #define XFS_BMBT_TRACE_CURSOR(c,s) \ |
291 | xfs_bmbt_trace_cursor(fname, c, s, __LINE__) | 291 | xfs_bmbt_trace_cursor(__FUNCTION__, c, s, __LINE__) |
292 | #else | 292 | #else |
293 | #define XFS_BMBT_TRACE_ARGBI(c,b,i) | 293 | #define XFS_BMBT_TRACE_ARGBI(c,b,i) |
294 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) | 294 | #define XFS_BMBT_TRACE_ARGBII(c,b,i,j) |
@@ -318,9 +318,6 @@ xfs_bmbt_delrec( | |||
318 | xfs_fsblock_t bno; /* fs-relative block number */ | 318 | xfs_fsblock_t bno; /* fs-relative block number */ |
319 | xfs_buf_t *bp; /* buffer for block */ | 319 | xfs_buf_t *bp; /* buffer for block */ |
320 | int error; /* error return value */ | 320 | int error; /* error return value */ |
321 | #ifdef XFS_BMBT_TRACE | ||
322 | static char fname[] = "xfs_bmbt_delrec"; | ||
323 | #endif | ||
324 | int i; /* loop counter */ | 321 | int i; /* loop counter */ |
325 | int j; /* temp state */ | 322 | int j; /* temp state */ |
326 | xfs_bmbt_key_t key; /* bmap btree key */ | 323 | xfs_bmbt_key_t key; /* bmap btree key */ |
@@ -694,9 +691,6 @@ xfs_bmbt_insrec( | |||
694 | xfs_bmbt_block_t *block; /* bmap btree block */ | 691 | xfs_bmbt_block_t *block; /* bmap btree block */ |
695 | xfs_buf_t *bp; /* buffer for block */ | 692 | xfs_buf_t *bp; /* buffer for block */ |
696 | int error; /* error return value */ | 693 | int error; /* error return value */ |
697 | #ifdef XFS_BMBT_TRACE | ||
698 | static char fname[] = "xfs_bmbt_insrec"; | ||
699 | #endif | ||
700 | int i; /* loop index */ | 694 | int i; /* loop index */ |
701 | xfs_bmbt_key_t key; /* bmap btree key */ | 695 | xfs_bmbt_key_t key; /* bmap btree key */ |
702 | xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */ | 696 | xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */ |
@@ -881,9 +875,6 @@ xfs_bmbt_killroot( | |||
881 | #ifdef DEBUG | 875 | #ifdef DEBUG |
882 | int error; | 876 | int error; |
883 | #endif | 877 | #endif |
884 | #ifdef XFS_BMBT_TRACE | ||
885 | static char fname[] = "xfs_bmbt_killroot"; | ||
886 | #endif | ||
887 | int i; | 878 | int i; |
888 | xfs_bmbt_key_t *kp; | 879 | xfs_bmbt_key_t *kp; |
889 | xfs_inode_t *ip; | 880 | xfs_inode_t *ip; |
@@ -973,9 +964,6 @@ xfs_bmbt_log_keys( | |||
973 | int kfirst, | 964 | int kfirst, |
974 | int klast) | 965 | int klast) |
975 | { | 966 | { |
976 | #ifdef XFS_BMBT_TRACE | ||
977 | static char fname[] = "xfs_bmbt_log_keys"; | ||
978 | #endif | ||
979 | xfs_trans_t *tp; | 967 | xfs_trans_t *tp; |
980 | 968 | ||
981 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | 969 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); |
@@ -1012,9 +1000,6 @@ xfs_bmbt_log_ptrs( | |||
1012 | int pfirst, | 1000 | int pfirst, |
1013 | int plast) | 1001 | int plast) |
1014 | { | 1002 | { |
1015 | #ifdef XFS_BMBT_TRACE | ||
1016 | static char fname[] = "xfs_bmbt_log_ptrs"; | ||
1017 | #endif | ||
1018 | xfs_trans_t *tp; | 1003 | xfs_trans_t *tp; |
1019 | 1004 | ||
1020 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); | 1005 | XFS_BMBT_TRACE_CURSOR(cur, ENTRY); |
@@ -1055,9 +1040,6 @@ xfs_bmbt_lookup( | |||
1055 | xfs_daddr_t d; | 1040 | xfs_daddr_t d; |
1056 | xfs_sfiloff_t diff; | 1041 | xfs_sfiloff_t diff; |
1057 | int error; /* error return value */ | 1042 | int error; /* error return value */ |
1058 | #ifdef XFS_BMBT_TRACE | ||
1059 | static char fname[] = "xfs_bmbt_lookup"; | ||
1060 | #endif | ||
1061 | xfs_fsblock_t fsbno=0; | 1043 | xfs_fsblock_t fsbno=0; |
1062 | int high; | 1044 | int high; |
1063 | int i; | 1045 | int i; |
@@ -1195,9 +1177,6 @@ xfs_bmbt_lshift( | |||
1195 | int *stat) /* success/failure */ | 1177 | int *stat) /* success/failure */ |
1196 | { | 1178 | { |
1197 | int error; /* error return value */ | 1179 | int error; /* error return value */ |
1198 | #ifdef XFS_BMBT_TRACE | ||
1199 | static char fname[] = "xfs_bmbt_lshift"; | ||
1200 | #endif | ||
1201 | #ifdef DEBUG | 1180 | #ifdef DEBUG |
1202 | int i; /* loop counter */ | 1181 | int i; /* loop counter */ |
1203 | #endif | 1182 | #endif |
@@ -1331,9 +1310,6 @@ xfs_bmbt_rshift( | |||
1331 | int *stat) /* success/failure */ | 1310 | int *stat) /* success/failure */ |
1332 | { | 1311 | { |
1333 | int error; /* error return value */ | 1312 | int error; /* error return value */ |
1334 | #ifdef XFS_BMBT_TRACE | ||
1335 | static char fname[] = "xfs_bmbt_rshift"; | ||
1336 | #endif | ||
1337 | int i; /* loop counter */ | 1313 | int i; /* loop counter */ |
1338 | xfs_bmbt_key_t key; /* bmap btree key */ | 1314 | xfs_bmbt_key_t key; /* bmap btree key */ |
1339 | xfs_buf_t *lbp; /* left buffer pointer */ | 1315 | xfs_buf_t *lbp; /* left buffer pointer */ |
@@ -1492,9 +1468,6 @@ xfs_bmbt_split( | |||
1492 | { | 1468 | { |
1493 | xfs_alloc_arg_t args; /* block allocation args */ | 1469 | xfs_alloc_arg_t args; /* block allocation args */ |
1494 | int error; /* error return value */ | 1470 | int error; /* error return value */ |
1495 | #ifdef XFS_BMBT_TRACE | ||
1496 | static char fname[] = "xfs_bmbt_split"; | ||
1497 | #endif | ||
1498 | int i; /* loop counter */ | 1471 | int i; /* loop counter */ |
1499 | xfs_fsblock_t lbno; /* left sibling block number */ | 1472 | xfs_fsblock_t lbno; /* left sibling block number */ |
1500 | xfs_buf_t *lbp; /* left buffer pointer */ | 1473 | xfs_buf_t *lbp; /* left buffer pointer */ |
@@ -1641,9 +1614,6 @@ xfs_bmbt_updkey( | |||
1641 | #ifdef DEBUG | 1614 | #ifdef DEBUG |
1642 | int error; | 1615 | int error; |
1643 | #endif | 1616 | #endif |
1644 | #ifdef XFS_BMBT_TRACE | ||
1645 | static char fname[] = "xfs_bmbt_updkey"; | ||
1646 | #endif | ||
1647 | xfs_bmbt_key_t *kp; | 1617 | xfs_bmbt_key_t *kp; |
1648 | int ptr; | 1618 | int ptr; |
1649 | 1619 | ||
@@ -1712,9 +1682,6 @@ xfs_bmbt_decrement( | |||
1712 | xfs_bmbt_block_t *block; | 1682 | xfs_bmbt_block_t *block; |
1713 | xfs_buf_t *bp; | 1683 | xfs_buf_t *bp; |
1714 | int error; /* error return value */ | 1684 | int error; /* error return value */ |
1715 | #ifdef XFS_BMBT_TRACE | ||
1716 | static char fname[] = "xfs_bmbt_decrement"; | ||
1717 | #endif | ||
1718 | xfs_fsblock_t fsbno; | 1685 | xfs_fsblock_t fsbno; |
1719 | int lev; | 1686 | int lev; |
1720 | xfs_mount_t *mp; | 1687 | xfs_mount_t *mp; |
@@ -1785,9 +1752,6 @@ xfs_bmbt_delete( | |||
1785 | int *stat) /* success/failure */ | 1752 | int *stat) /* success/failure */ |
1786 | { | 1753 | { |
1787 | int error; /* error return value */ | 1754 | int error; /* error return value */ |
1788 | #ifdef XFS_BMBT_TRACE | ||
1789 | static char fname[] = "xfs_bmbt_delete"; | ||
1790 | #endif | ||
1791 | int i; | 1755 | int i; |
1792 | int level; | 1756 | int level; |
1793 | 1757 | ||
@@ -2000,9 +1964,6 @@ xfs_bmbt_increment( | |||
2000 | xfs_bmbt_block_t *block; | 1964 | xfs_bmbt_block_t *block; |
2001 | xfs_buf_t *bp; | 1965 | xfs_buf_t *bp; |
2002 | int error; /* error return value */ | 1966 | int error; /* error return value */ |
2003 | #ifdef XFS_BMBT_TRACE | ||
2004 | static char fname[] = "xfs_bmbt_increment"; | ||
2005 | #endif | ||
2006 | xfs_fsblock_t fsbno; | 1967 | xfs_fsblock_t fsbno; |
2007 | int lev; | 1968 | int lev; |
2008 | xfs_mount_t *mp; | 1969 | xfs_mount_t *mp; |
@@ -2080,9 +2041,6 @@ xfs_bmbt_insert( | |||
2080 | int *stat) /* success/failure */ | 2041 | int *stat) /* success/failure */ |
2081 | { | 2042 | { |
2082 | int error; /* error return value */ | 2043 | int error; /* error return value */ |
2083 | #ifdef XFS_BMBT_TRACE | ||
2084 | static char fname[] = "xfs_bmbt_insert"; | ||
2085 | #endif | ||
2086 | int i; | 2044 | int i; |
2087 | int level; | 2045 | int level; |
2088 | xfs_fsblock_t nbno; | 2046 | xfs_fsblock_t nbno; |
@@ -2142,9 +2100,6 @@ xfs_bmbt_log_block( | |||
2142 | int fields) | 2100 | int fields) |
2143 | { | 2101 | { |
2144 | int first; | 2102 | int first; |
2145 | #ifdef XFS_BMBT_TRACE | ||
2146 | static char fname[] = "xfs_bmbt_log_block"; | ||
2147 | #endif | ||
2148 | int last; | 2103 | int last; |
2149 | xfs_trans_t *tp; | 2104 | xfs_trans_t *tp; |
2150 | static const short offsets[] = { | 2105 | static const short offsets[] = { |
@@ -2181,9 +2136,6 @@ xfs_bmbt_log_recs( | |||
2181 | { | 2136 | { |
2182 | xfs_bmbt_block_t *block; | 2137 | xfs_bmbt_block_t *block; |
2183 | int first; | 2138 | int first; |
2184 | #ifdef XFS_BMBT_TRACE | ||
2185 | static char fname[] = "xfs_bmbt_log_recs"; | ||
2186 | #endif | ||
2187 | int last; | 2139 | int last; |
2188 | xfs_bmbt_rec_t *rp; | 2140 | xfs_bmbt_rec_t *rp; |
2189 | xfs_trans_t *tp; | 2141 | xfs_trans_t *tp; |
@@ -2245,9 +2197,6 @@ xfs_bmbt_newroot( | |||
2245 | xfs_bmbt_key_t *ckp; /* child key pointer */ | 2197 | xfs_bmbt_key_t *ckp; /* child key pointer */ |
2246 | xfs_bmbt_ptr_t *cpp; /* child ptr pointer */ | 2198 | xfs_bmbt_ptr_t *cpp; /* child ptr pointer */ |
2247 | int error; /* error return code */ | 2199 | int error; /* error return code */ |
2248 | #ifdef XFS_BMBT_TRACE | ||
2249 | static char fname[] = "xfs_bmbt_newroot"; | ||
2250 | #endif | ||
2251 | #ifdef DEBUG | 2200 | #ifdef DEBUG |
2252 | int i; /* loop counter */ | 2201 | int i; /* loop counter */ |
2253 | #endif | 2202 | #endif |
@@ -2630,9 +2579,6 @@ xfs_bmbt_update( | |||
2630 | xfs_bmbt_block_t *block; | 2579 | xfs_bmbt_block_t *block; |
2631 | xfs_buf_t *bp; | 2580 | xfs_buf_t *bp; |
2632 | int error; | 2581 | int error; |
2633 | #ifdef XFS_BMBT_TRACE | ||
2634 | static char fname[] = "xfs_bmbt_update"; | ||
2635 | #endif | ||
2636 | xfs_bmbt_key_t key; | 2582 | xfs_bmbt_key_t key; |
2637 | int ptr; | 2583 | int ptr; |
2638 | xfs_bmbt_rec_t *rp; | 2584 | xfs_bmbt_rec_t *rp; |
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 4e27d55a1e7..6e40a0a198f 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h | |||
@@ -444,30 +444,14 @@ xfs_btree_setbuf( | |||
444 | /* | 444 | /* |
445 | * Min and max functions for extlen, agblock, fileoff, and filblks types. | 445 | * Min and max functions for extlen, agblock, fileoff, and filblks types. |
446 | */ | 446 | */ |
447 | #define XFS_EXTLEN_MIN(a,b) \ | 447 | #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) |
448 | ((xfs_extlen_t)(a) < (xfs_extlen_t)(b) ? \ | 448 | #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) |
449 | (xfs_extlen_t)(a) : (xfs_extlen_t)(b)) | 449 | #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) |
450 | #define XFS_EXTLEN_MAX(a,b) \ | 450 | #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) |
451 | ((xfs_extlen_t)(a) > (xfs_extlen_t)(b) ? \ | 451 | #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) |
452 | (xfs_extlen_t)(a) : (xfs_extlen_t)(b)) | 452 | #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) |
453 | #define XFS_AGBLOCK_MIN(a,b) \ | 453 | #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) |
454 | ((xfs_agblock_t)(a) < (xfs_agblock_t)(b) ? \ | 454 | #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) |
455 | (xfs_agblock_t)(a) : (xfs_agblock_t)(b)) | ||
456 | #define XFS_AGBLOCK_MAX(a,b) \ | ||
457 | ((xfs_agblock_t)(a) > (xfs_agblock_t)(b) ? \ | ||
458 | (xfs_agblock_t)(a) : (xfs_agblock_t)(b)) | ||
459 | #define XFS_FILEOFF_MIN(a,b) \ | ||
460 | ((xfs_fileoff_t)(a) < (xfs_fileoff_t)(b) ? \ | ||
461 | (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b)) | ||
462 | #define XFS_FILEOFF_MAX(a,b) \ | ||
463 | ((xfs_fileoff_t)(a) > (xfs_fileoff_t)(b) ? \ | ||
464 | (xfs_fileoff_t)(a) : (xfs_fileoff_t)(b)) | ||
465 | #define XFS_FILBLKS_MIN(a,b) \ | ||
466 | ((xfs_filblks_t)(a) < (xfs_filblks_t)(b) ? \ | ||
467 | (xfs_filblks_t)(a) : (xfs_filblks_t)(b)) | ||
468 | #define XFS_FILBLKS_MAX(a,b) \ | ||
469 | ((xfs_filblks_t)(a) > (xfs_filblks_t)(b) ? \ | ||
470 | (xfs_filblks_t)(a) : (xfs_filblks_t)(b)) | ||
471 | 455 | ||
472 | #define XFS_FSB_SANITY_CHECK(mp,fsb) \ | 456 | #define XFS_FSB_SANITY_CHECK(mp,fsb) \ |
473 | (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ | 457 | (XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \ |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 6c1bddc04e3..b0667cb27d6 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -580,8 +580,8 @@ xfs_buf_item_unlock( | |||
580 | * If the buf item isn't tracking any data, free it. | 580 | * If the buf item isn't tracking any data, free it. |
581 | * Otherwise, if XFS_BLI_HOLD is set clear it. | 581 | * Otherwise, if XFS_BLI_HOLD is set clear it. |
582 | */ | 582 | */ |
583 | if (xfs_count_bits(bip->bli_format.blf_data_map, | 583 | if (xfs_bitmap_empty(bip->bli_format.blf_data_map, |
584 | bip->bli_format.blf_map_size, 0) == 0) { | 584 | bip->bli_format.blf_map_size)) { |
585 | xfs_buf_item_relse(bp); | 585 | xfs_buf_item_relse(bp); |
586 | } else if (hold) { | 586 | } else if (hold) { |
587 | bip->bli_flags &= ~XFS_BLI_HOLD; | 587 | bip->bli_flags &= ~XFS_BLI_HOLD; |
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h index 5b7eb81453b..f89196cb08d 100644 --- a/fs/xfs/xfs_clnt.h +++ b/fs/xfs/xfs_clnt.h | |||
@@ -99,5 +99,7 @@ struct xfs_mount_args { | |||
99 | */ | 99 | */ |
100 | #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred | 100 | #define XFSMNT2_COMPAT_IOSIZE 0x00000001 /* don't report large preferred |
101 | * I/O size in stat(2) */ | 101 | * I/O size in stat(2) */ |
102 | #define XFSMNT2_FILESTREAMS 0x00000002 /* enable the filestreams | ||
103 | * allocator */ | ||
102 | 104 | ||
103 | #endif /* __XFS_CLNT_H__ */ | 105 | #endif /* __XFS_CLNT_H__ */ |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index b33826961c4..fefd0116bac 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -257,6 +257,7 @@ typedef enum xfs_dinode_fmt | |||
257 | #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ | 257 | #define XFS_DIFLAG_EXTSIZE_BIT 11 /* inode extent size allocator hint */ |
258 | #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ | 258 | #define XFS_DIFLAG_EXTSZINHERIT_BIT 12 /* inherit inode extent size */ |
259 | #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ | 259 | #define XFS_DIFLAG_NODEFRAG_BIT 13 /* do not reorganize/defragment */ |
260 | #define XFS_DIFLAG_FILESTREAM_BIT 14 /* use filestream allocator */ | ||
260 | #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) | 261 | #define XFS_DIFLAG_REALTIME (1 << XFS_DIFLAG_REALTIME_BIT) |
261 | #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) | 262 | #define XFS_DIFLAG_PREALLOC (1 << XFS_DIFLAG_PREALLOC_BIT) |
262 | #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) | 263 | #define XFS_DIFLAG_NEWRTBM (1 << XFS_DIFLAG_NEWRTBM_BIT) |
@@ -271,12 +272,13 @@ typedef enum xfs_dinode_fmt | |||
271 | #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) | 272 | #define XFS_DIFLAG_EXTSIZE (1 << XFS_DIFLAG_EXTSIZE_BIT) |
272 | #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) | 273 | #define XFS_DIFLAG_EXTSZINHERIT (1 << XFS_DIFLAG_EXTSZINHERIT_BIT) |
273 | #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) | 274 | #define XFS_DIFLAG_NODEFRAG (1 << XFS_DIFLAG_NODEFRAG_BIT) |
275 | #define XFS_DIFLAG_FILESTREAM (1 << XFS_DIFLAG_FILESTREAM_BIT) | ||
274 | 276 | ||
275 | #define XFS_DIFLAG_ANY \ | 277 | #define XFS_DIFLAG_ANY \ |
276 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ | 278 | (XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \ |
277 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ | 279 | XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \ |
278 | XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ | 280 | XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP | XFS_DIFLAG_RTINHERIT | \ |
279 | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ | 281 | XFS_DIFLAG_PROJINHERIT | XFS_DIFLAG_NOSYMLINKS | XFS_DIFLAG_EXTSIZE | \ |
280 | XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG) | 282 | XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) |
281 | 283 | ||
282 | #endif /* __XFS_DINODE_H__ */ | 284 | #endif /* __XFS_DINODE_H__ */ |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 8e8e5279334..29e091914df 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -55,9 +55,9 @@ xfs_dir_mount( | |||
55 | XFS_MAX_BLOCKSIZE); | 55 | XFS_MAX_BLOCKSIZE); |
56 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); | 56 | mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog); |
57 | mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog; | 57 | mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog; |
58 | mp->m_dirdatablk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_DATA_FIRSTDB(mp)); | 58 | mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp)); |
59 | mp->m_dirleafblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); | 59 | mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp)); |
60 | mp->m_dirfreeblk = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_FREE_FIRSTDB(mp)); | 60 | mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp)); |
61 | mp->m_attr_node_ents = | 61 | mp->m_attr_node_ents = |
62 | (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) / | 62 | (mp->m_sb.sb_blocksize - (uint)sizeof(xfs_da_node_hdr_t)) / |
63 | (uint)sizeof(xfs_da_node_entry_t); | 63 | (uint)sizeof(xfs_da_node_entry_t); |
@@ -554,7 +554,7 @@ xfs_dir2_grow_inode( | |||
554 | */ | 554 | */ |
555 | if (mapp != &map) | 555 | if (mapp != &map) |
556 | kmem_free(mapp, sizeof(*mapp) * count); | 556 | kmem_free(mapp, sizeof(*mapp) * count); |
557 | *dbp = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)bno); | 557 | *dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); |
558 | /* | 558 | /* |
559 | * Update file's size if this is the data space and it grew. | 559 | * Update file's size if this is the data space and it grew. |
560 | */ | 560 | */ |
@@ -706,7 +706,7 @@ xfs_dir2_shrink_inode( | |||
706 | dp = args->dp; | 706 | dp = args->dp; |
707 | mp = dp->i_mount; | 707 | mp = dp->i_mount; |
708 | tp = args->trans; | 708 | tp = args->trans; |
709 | da = XFS_DIR2_DB_TO_DA(mp, db); | 709 | da = xfs_dir2_db_to_da(mp, db); |
710 | /* | 710 | /* |
711 | * Unmap the fsblock(s). | 711 | * Unmap the fsblock(s). |
712 | */ | 712 | */ |
@@ -742,7 +742,7 @@ xfs_dir2_shrink_inode( | |||
742 | /* | 742 | /* |
743 | * If the block isn't the last one in the directory, we're done. | 743 | * If the block isn't the last one in the directory, we're done. |
744 | */ | 744 | */ |
745 | if (dp->i_d.di_size > XFS_DIR2_DB_OFF_TO_BYTE(mp, db + 1, 0)) | 745 | if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(mp, db + 1, 0)) |
746 | return 0; | 746 | return 0; |
747 | bno = da; | 747 | bno = da; |
748 | if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { | 748 | if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { |
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c index 3accc1dcd6c..e4df1aaae2a 100644 --- a/fs/xfs/xfs_dir2_block.c +++ b/fs/xfs/xfs_dir2_block.c | |||
@@ -115,13 +115,13 @@ xfs_dir2_block_addname( | |||
115 | xfs_da_brelse(tp, bp); | 115 | xfs_da_brelse(tp, bp); |
116 | return XFS_ERROR(EFSCORRUPTED); | 116 | return XFS_ERROR(EFSCORRUPTED); |
117 | } | 117 | } |
118 | len = XFS_DIR2_DATA_ENTSIZE(args->namelen); | 118 | len = xfs_dir2_data_entsize(args->namelen); |
119 | /* | 119 | /* |
120 | * Set up pointers to parts of the block. | 120 | * Set up pointers to parts of the block. |
121 | */ | 121 | */ |
122 | bf = block->hdr.bestfree; | 122 | bf = block->hdr.bestfree; |
123 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 123 | btp = xfs_dir2_block_tail_p(mp, block); |
124 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 124 | blp = xfs_dir2_block_leaf_p(btp); |
125 | /* | 125 | /* |
126 | * No stale entries? Need space for entry and new leaf. | 126 | * No stale entries? Need space for entry and new leaf. |
127 | */ | 127 | */ |
@@ -396,7 +396,7 @@ xfs_dir2_block_addname( | |||
396 | * Fill in the leaf entry. | 396 | * Fill in the leaf entry. |
397 | */ | 397 | */ |
398 | blp[mid].hashval = cpu_to_be32(args->hashval); | 398 | blp[mid].hashval = cpu_to_be32(args->hashval); |
399 | blp[mid].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp, | 399 | blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
400 | (char *)dep - (char *)block)); | 400 | (char *)dep - (char *)block)); |
401 | xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); | 401 | xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); |
402 | /* | 402 | /* |
@@ -411,7 +411,7 @@ xfs_dir2_block_addname( | |||
411 | dep->inumber = cpu_to_be64(args->inumber); | 411 | dep->inumber = cpu_to_be64(args->inumber); |
412 | dep->namelen = args->namelen; | 412 | dep->namelen = args->namelen; |
413 | memcpy(dep->name, args->name, args->namelen); | 413 | memcpy(dep->name, args->name, args->namelen); |
414 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 414 | tagp = xfs_dir2_data_entry_tag_p(dep); |
415 | *tagp = cpu_to_be16((char *)dep - (char *)block); | 415 | *tagp = cpu_to_be16((char *)dep - (char *)block); |
416 | /* | 416 | /* |
417 | * Clean up the bestfree array and log the header, tail, and entry. | 417 | * Clean up the bestfree array and log the header, tail, and entry. |
@@ -455,7 +455,7 @@ xfs_dir2_block_getdents( | |||
455 | /* | 455 | /* |
456 | * If the block number in the offset is out of range, we're done. | 456 | * If the block number in the offset is out of range, we're done. |
457 | */ | 457 | */ |
458 | if (XFS_DIR2_DATAPTR_TO_DB(mp, uio->uio_offset) > mp->m_dirdatablk) { | 458 | if (xfs_dir2_dataptr_to_db(mp, uio->uio_offset) > mp->m_dirdatablk) { |
459 | *eofp = 1; | 459 | *eofp = 1; |
460 | return 0; | 460 | return 0; |
461 | } | 461 | } |
@@ -471,15 +471,15 @@ xfs_dir2_block_getdents( | |||
471 | * Extract the byte offset we start at from the seek pointer. | 471 | * Extract the byte offset we start at from the seek pointer. |
472 | * We'll skip entries before this. | 472 | * We'll skip entries before this. |
473 | */ | 473 | */ |
474 | wantoff = XFS_DIR2_DATAPTR_TO_OFF(mp, uio->uio_offset); | 474 | wantoff = xfs_dir2_dataptr_to_off(mp, uio->uio_offset); |
475 | block = bp->data; | 475 | block = bp->data; |
476 | xfs_dir2_data_check(dp, bp); | 476 | xfs_dir2_data_check(dp, bp); |
477 | /* | 477 | /* |
478 | * Set up values for the loop. | 478 | * Set up values for the loop. |
479 | */ | 479 | */ |
480 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 480 | btp = xfs_dir2_block_tail_p(mp, block); |
481 | ptr = (char *)block->u; | 481 | ptr = (char *)block->u; |
482 | endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); | 482 | endptr = (char *)xfs_dir2_block_leaf_p(btp); |
483 | p.dbp = dbp; | 483 | p.dbp = dbp; |
484 | p.put = put; | 484 | p.put = put; |
485 | p.uio = uio; | 485 | p.uio = uio; |
@@ -502,7 +502,7 @@ xfs_dir2_block_getdents( | |||
502 | /* | 502 | /* |
503 | * Bump pointer for the next iteration. | 503 | * Bump pointer for the next iteration. |
504 | */ | 504 | */ |
505 | ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); | 505 | ptr += xfs_dir2_data_entsize(dep->namelen); |
506 | /* | 506 | /* |
507 | * The entry is before the desired starting point, skip it. | 507 | * The entry is before the desired starting point, skip it. |
508 | */ | 508 | */ |
@@ -513,7 +513,7 @@ xfs_dir2_block_getdents( | |||
513 | */ | 513 | */ |
514 | p.namelen = dep->namelen; | 514 | p.namelen = dep->namelen; |
515 | 515 | ||
516 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 516 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
517 | ptr - (char *)block); | 517 | ptr - (char *)block); |
518 | p.ino = be64_to_cpu(dep->inumber); | 518 | p.ino = be64_to_cpu(dep->inumber); |
519 | #if XFS_BIG_INUMS | 519 | #if XFS_BIG_INUMS |
@@ -531,7 +531,7 @@ xfs_dir2_block_getdents( | |||
531 | */ | 531 | */ |
532 | if (!p.done) { | 532 | if (!p.done) { |
533 | uio->uio_offset = | 533 | uio->uio_offset = |
534 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 534 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
535 | (char *)dep - (char *)block); | 535 | (char *)dep - (char *)block); |
536 | xfs_da_brelse(tp, bp); | 536 | xfs_da_brelse(tp, bp); |
537 | return error; | 537 | return error; |
@@ -545,7 +545,7 @@ xfs_dir2_block_getdents( | |||
545 | *eofp = 1; | 545 | *eofp = 1; |
546 | 546 | ||
547 | uio->uio_offset = | 547 | uio->uio_offset = |
548 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0); | 548 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); |
549 | 549 | ||
550 | xfs_da_brelse(tp, bp); | 550 | xfs_da_brelse(tp, bp); |
551 | 551 | ||
@@ -569,8 +569,8 @@ xfs_dir2_block_log_leaf( | |||
569 | 569 | ||
570 | mp = tp->t_mountp; | 570 | mp = tp->t_mountp; |
571 | block = bp->data; | 571 | block = bp->data; |
572 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 572 | btp = xfs_dir2_block_tail_p(mp, block); |
573 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 573 | blp = xfs_dir2_block_leaf_p(btp); |
574 | xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), | 574 | xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), |
575 | (uint)((char *)&blp[last + 1] - (char *)block - 1)); | 575 | (uint)((char *)&blp[last + 1] - (char *)block - 1)); |
576 | } | 576 | } |
@@ -589,7 +589,7 @@ xfs_dir2_block_log_tail( | |||
589 | 589 | ||
590 | mp = tp->t_mountp; | 590 | mp = tp->t_mountp; |
591 | block = bp->data; | 591 | block = bp->data; |
592 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 592 | btp = xfs_dir2_block_tail_p(mp, block); |
593 | xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), | 593 | xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), |
594 | (uint)((char *)(btp + 1) - (char *)block - 1)); | 594 | (uint)((char *)(btp + 1) - (char *)block - 1)); |
595 | } | 595 | } |
@@ -623,13 +623,13 @@ xfs_dir2_block_lookup( | |||
623 | mp = dp->i_mount; | 623 | mp = dp->i_mount; |
624 | block = bp->data; | 624 | block = bp->data; |
625 | xfs_dir2_data_check(dp, bp); | 625 | xfs_dir2_data_check(dp, bp); |
626 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 626 | btp = xfs_dir2_block_tail_p(mp, block); |
627 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 627 | blp = xfs_dir2_block_leaf_p(btp); |
628 | /* | 628 | /* |
629 | * Get the offset from the leaf entry, to point to the data. | 629 | * Get the offset from the leaf entry, to point to the data. |
630 | */ | 630 | */ |
631 | dep = (xfs_dir2_data_entry_t *) | 631 | dep = (xfs_dir2_data_entry_t *) |
632 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); | 632 | ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); |
633 | /* | 633 | /* |
634 | * Fill in inode number, release the block. | 634 | * Fill in inode number, release the block. |
635 | */ | 635 | */ |
@@ -675,8 +675,8 @@ xfs_dir2_block_lookup_int( | |||
675 | ASSERT(bp != NULL); | 675 | ASSERT(bp != NULL); |
676 | block = bp->data; | 676 | block = bp->data; |
677 | xfs_dir2_data_check(dp, bp); | 677 | xfs_dir2_data_check(dp, bp); |
678 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 678 | btp = xfs_dir2_block_tail_p(mp, block); |
679 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 679 | blp = xfs_dir2_block_leaf_p(btp); |
680 | /* | 680 | /* |
681 | * Loop doing a binary search for our hash value. | 681 | * Loop doing a binary search for our hash value. |
682 | * Find our entry, ENOENT if it's not there. | 682 | * Find our entry, ENOENT if it's not there. |
@@ -713,7 +713,7 @@ xfs_dir2_block_lookup_int( | |||
713 | * Get pointer to the entry from the leaf. | 713 | * Get pointer to the entry from the leaf. |
714 | */ | 714 | */ |
715 | dep = (xfs_dir2_data_entry_t *) | 715 | dep = (xfs_dir2_data_entry_t *) |
716 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr)); | 716 | ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); |
717 | /* | 717 | /* |
718 | * Compare, if it's right give back buffer & entry number. | 718 | * Compare, if it's right give back buffer & entry number. |
719 | */ | 719 | */ |
@@ -768,20 +768,20 @@ xfs_dir2_block_removename( | |||
768 | tp = args->trans; | 768 | tp = args->trans; |
769 | mp = dp->i_mount; | 769 | mp = dp->i_mount; |
770 | block = bp->data; | 770 | block = bp->data; |
771 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 771 | btp = xfs_dir2_block_tail_p(mp, block); |
772 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 772 | blp = xfs_dir2_block_leaf_p(btp); |
773 | /* | 773 | /* |
774 | * Point to the data entry using the leaf entry. | 774 | * Point to the data entry using the leaf entry. |
775 | */ | 775 | */ |
776 | dep = (xfs_dir2_data_entry_t *) | 776 | dep = (xfs_dir2_data_entry_t *) |
777 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); | 777 | ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); |
778 | /* | 778 | /* |
779 | * Mark the data entry's space free. | 779 | * Mark the data entry's space free. |
780 | */ | 780 | */ |
781 | needlog = needscan = 0; | 781 | needlog = needscan = 0; |
782 | xfs_dir2_data_make_free(tp, bp, | 782 | xfs_dir2_data_make_free(tp, bp, |
783 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), | 783 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), |
784 | XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); | 784 | xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); |
785 | /* | 785 | /* |
786 | * Fix up the block tail. | 786 | * Fix up the block tail. |
787 | */ | 787 | */ |
@@ -843,13 +843,13 @@ xfs_dir2_block_replace( | |||
843 | dp = args->dp; | 843 | dp = args->dp; |
844 | mp = dp->i_mount; | 844 | mp = dp->i_mount; |
845 | block = bp->data; | 845 | block = bp->data; |
846 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 846 | btp = xfs_dir2_block_tail_p(mp, block); |
847 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 847 | blp = xfs_dir2_block_leaf_p(btp); |
848 | /* | 848 | /* |
849 | * Point to the data entry we need to change. | 849 | * Point to the data entry we need to change. |
850 | */ | 850 | */ |
851 | dep = (xfs_dir2_data_entry_t *) | 851 | dep = (xfs_dir2_data_entry_t *) |
852 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(blp[ent].address))); | 852 | ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); |
853 | ASSERT(be64_to_cpu(dep->inumber) != args->inumber); | 853 | ASSERT(be64_to_cpu(dep->inumber) != args->inumber); |
854 | /* | 854 | /* |
855 | * Change the inode number to the new value. | 855 | * Change the inode number to the new value. |
@@ -912,7 +912,7 @@ xfs_dir2_leaf_to_block( | |||
912 | mp = dp->i_mount; | 912 | mp = dp->i_mount; |
913 | leaf = lbp->data; | 913 | leaf = lbp->data; |
914 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); | 914 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); |
915 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 915 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
916 | /* | 916 | /* |
917 | * If there are data blocks other than the first one, take this | 917 | * If there are data blocks other than the first one, take this |
918 | * opportunity to remove trailing empty data blocks that may have | 918 | * opportunity to remove trailing empty data blocks that may have |
@@ -920,7 +920,7 @@ xfs_dir2_leaf_to_block( | |||
920 | * These will show up in the leaf bests table. | 920 | * These will show up in the leaf bests table. |
921 | */ | 921 | */ |
922 | while (dp->i_d.di_size > mp->m_dirblksize) { | 922 | while (dp->i_d.di_size > mp->m_dirblksize) { |
923 | bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); | 923 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
924 | if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == | 924 | if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == |
925 | mp->m_dirblksize - (uint)sizeof(block->hdr)) { | 925 | mp->m_dirblksize - (uint)sizeof(block->hdr)) { |
926 | if ((error = | 926 | if ((error = |
@@ -974,14 +974,14 @@ xfs_dir2_leaf_to_block( | |||
974 | /* | 974 | /* |
975 | * Initialize the block tail. | 975 | * Initialize the block tail. |
976 | */ | 976 | */ |
977 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 977 | btp = xfs_dir2_block_tail_p(mp, block); |
978 | btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); | 978 | btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); |
979 | btp->stale = 0; | 979 | btp->stale = 0; |
980 | xfs_dir2_block_log_tail(tp, dbp); | 980 | xfs_dir2_block_log_tail(tp, dbp); |
981 | /* | 981 | /* |
982 | * Initialize the block leaf area. We compact out stale entries. | 982 | * Initialize the block leaf area. We compact out stale entries. |
983 | */ | 983 | */ |
984 | lep = XFS_DIR2_BLOCK_LEAF_P(btp); | 984 | lep = xfs_dir2_block_leaf_p(btp); |
985 | for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { | 985 | for (from = to = 0; from < be16_to_cpu(leaf->hdr.count); from++) { |
986 | if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) | 986 | if (be32_to_cpu(leaf->ents[from].address) == XFS_DIR2_NULL_DATAPTR) |
987 | continue; | 987 | continue; |
@@ -1067,7 +1067,7 @@ xfs_dir2_sf_to_block( | |||
1067 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 1067 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
1068 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 1068 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
1069 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 1069 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
1070 | ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 1070 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
1071 | /* | 1071 | /* |
1072 | * Copy the directory into the stack buffer. | 1072 | * Copy the directory into the stack buffer. |
1073 | * Then pitch the incore inode data so we can make extents. | 1073 | * Then pitch the incore inode data so we can make extents. |
@@ -1119,10 +1119,10 @@ xfs_dir2_sf_to_block( | |||
1119 | /* | 1119 | /* |
1120 | * Fill in the tail. | 1120 | * Fill in the tail. |
1121 | */ | 1121 | */ |
1122 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 1122 | btp = xfs_dir2_block_tail_p(mp, block); |
1123 | btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ | 1123 | btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ |
1124 | btp->stale = 0; | 1124 | btp->stale = 0; |
1125 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 1125 | blp = xfs_dir2_block_leaf_p(btp); |
1126 | endoffset = (uint)((char *)blp - (char *)block); | 1126 | endoffset = (uint)((char *)blp - (char *)block); |
1127 | /* | 1127 | /* |
1128 | * Remove the freespace, we'll manage it. | 1128 | * Remove the freespace, we'll manage it. |
@@ -1138,25 +1138,25 @@ xfs_dir2_sf_to_block( | |||
1138 | dep->inumber = cpu_to_be64(dp->i_ino); | 1138 | dep->inumber = cpu_to_be64(dp->i_ino); |
1139 | dep->namelen = 1; | 1139 | dep->namelen = 1; |
1140 | dep->name[0] = '.'; | 1140 | dep->name[0] = '.'; |
1141 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1141 | tagp = xfs_dir2_data_entry_tag_p(dep); |
1142 | *tagp = cpu_to_be16((char *)dep - (char *)block); | 1142 | *tagp = cpu_to_be16((char *)dep - (char *)block); |
1143 | xfs_dir2_data_log_entry(tp, bp, dep); | 1143 | xfs_dir2_data_log_entry(tp, bp, dep); |
1144 | blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); | 1144 | blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); |
1145 | blp[0].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp, | 1145 | blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
1146 | (char *)dep - (char *)block)); | 1146 | (char *)dep - (char *)block)); |
1147 | /* | 1147 | /* |
1148 | * Create entry for .. | 1148 | * Create entry for .. |
1149 | */ | 1149 | */ |
1150 | dep = (xfs_dir2_data_entry_t *) | 1150 | dep = (xfs_dir2_data_entry_t *) |
1151 | ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); | 1151 | ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); |
1152 | dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); | 1152 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); |
1153 | dep->namelen = 2; | 1153 | dep->namelen = 2; |
1154 | dep->name[0] = dep->name[1] = '.'; | 1154 | dep->name[0] = dep->name[1] = '.'; |
1155 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1155 | tagp = xfs_dir2_data_entry_tag_p(dep); |
1156 | *tagp = cpu_to_be16((char *)dep - (char *)block); | 1156 | *tagp = cpu_to_be16((char *)dep - (char *)block); |
1157 | xfs_dir2_data_log_entry(tp, bp, dep); | 1157 | xfs_dir2_data_log_entry(tp, bp, dep); |
1158 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); | 1158 | blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); |
1159 | blp[1].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp, | 1159 | blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
1160 | (char *)dep - (char *)block)); | 1160 | (char *)dep - (char *)block)); |
1161 | offset = XFS_DIR2_DATA_FIRST_OFFSET; | 1161 | offset = XFS_DIR2_DATA_FIRST_OFFSET; |
1162 | /* | 1162 | /* |
@@ -1165,7 +1165,7 @@ xfs_dir2_sf_to_block( | |||
1165 | if ((i = 0) == sfp->hdr.count) | 1165 | if ((i = 0) == sfp->hdr.count) |
1166 | sfep = NULL; | 1166 | sfep = NULL; |
1167 | else | 1167 | else |
1168 | sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 1168 | sfep = xfs_dir2_sf_firstentry(sfp); |
1169 | /* | 1169 | /* |
1170 | * Need to preserve the existing offset values in the sf directory. | 1170 | * Need to preserve the existing offset values in the sf directory. |
1171 | * Insert holes (unused entries) where necessary. | 1171 | * Insert holes (unused entries) where necessary. |
@@ -1177,7 +1177,7 @@ xfs_dir2_sf_to_block( | |||
1177 | if (sfep == NULL) | 1177 | if (sfep == NULL) |
1178 | newoffset = endoffset; | 1178 | newoffset = endoffset; |
1179 | else | 1179 | else |
1180 | newoffset = XFS_DIR2_SF_GET_OFFSET(sfep); | 1180 | newoffset = xfs_dir2_sf_get_offset(sfep); |
1181 | /* | 1181 | /* |
1182 | * There should be a hole here, make one. | 1182 | * There should be a hole here, make one. |
1183 | */ | 1183 | */ |
@@ -1186,7 +1186,7 @@ xfs_dir2_sf_to_block( | |||
1186 | ((char *)block + offset); | 1186 | ((char *)block + offset); |
1187 | dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 1187 | dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
1188 | dup->length = cpu_to_be16(newoffset - offset); | 1188 | dup->length = cpu_to_be16(newoffset - offset); |
1189 | *XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16( | 1189 | *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( |
1190 | ((char *)dup - (char *)block)); | 1190 | ((char *)dup - (char *)block)); |
1191 | xfs_dir2_data_log_unused(tp, bp, dup); | 1191 | xfs_dir2_data_log_unused(tp, bp, dup); |
1192 | (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, | 1192 | (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, |
@@ -1198,22 +1198,22 @@ xfs_dir2_sf_to_block( | |||
1198 | * Copy a real entry. | 1198 | * Copy a real entry. |
1199 | */ | 1199 | */ |
1200 | dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); | 1200 | dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); |
1201 | dep->inumber = cpu_to_be64(XFS_DIR2_SF_GET_INUMBER(sfp, | 1201 | dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, |
1202 | XFS_DIR2_SF_INUMBERP(sfep))); | 1202 | xfs_dir2_sf_inumberp(sfep))); |
1203 | dep->namelen = sfep->namelen; | 1203 | dep->namelen = sfep->namelen; |
1204 | memcpy(dep->name, sfep->name, dep->namelen); | 1204 | memcpy(dep->name, sfep->name, dep->namelen); |
1205 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1205 | tagp = xfs_dir2_data_entry_tag_p(dep); |
1206 | *tagp = cpu_to_be16((char *)dep - (char *)block); | 1206 | *tagp = cpu_to_be16((char *)dep - (char *)block); |
1207 | xfs_dir2_data_log_entry(tp, bp, dep); | 1207 | xfs_dir2_data_log_entry(tp, bp, dep); |
1208 | blp[2 + i].hashval = cpu_to_be32(xfs_da_hashname( | 1208 | blp[2 + i].hashval = cpu_to_be32(xfs_da_hashname( |
1209 | (char *)sfep->name, sfep->namelen)); | 1209 | (char *)sfep->name, sfep->namelen)); |
1210 | blp[2 + i].address = cpu_to_be32(XFS_DIR2_BYTE_TO_DATAPTR(mp, | 1210 | blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, |
1211 | (char *)dep - (char *)block)); | 1211 | (char *)dep - (char *)block)); |
1212 | offset = (int)((char *)(tagp + 1) - (char *)block); | 1212 | offset = (int)((char *)(tagp + 1) - (char *)block); |
1213 | if (++i == sfp->hdr.count) | 1213 | if (++i == sfp->hdr.count) |
1214 | sfep = NULL; | 1214 | sfep = NULL; |
1215 | else | 1215 | else |
1216 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); | 1216 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); |
1217 | } | 1217 | } |
1218 | /* Done with the temporary buffer */ | 1218 | /* Done with the temporary buffer */ |
1219 | kmem_free(buf, buf_len); | 1219 | kmem_free(buf, buf_len); |
diff --git a/fs/xfs/xfs_dir2_block.h b/fs/xfs/xfs_dir2_block.h index 6722effd0b2..e7c2606161e 100644 --- a/fs/xfs/xfs_dir2_block.h +++ b/fs/xfs/xfs_dir2_block.h | |||
@@ -60,7 +60,6 @@ typedef struct xfs_dir2_block { | |||
60 | /* | 60 | /* |
61 | * Pointer to the leaf header embedded in a data block (1-block format) | 61 | * Pointer to the leaf header embedded in a data block (1-block format) |
62 | */ | 62 | */ |
63 | #define XFS_DIR2_BLOCK_TAIL_P(mp,block) xfs_dir2_block_tail_p(mp,block) | ||
64 | static inline xfs_dir2_block_tail_t * | 63 | static inline xfs_dir2_block_tail_t * |
65 | xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) | 64 | xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) |
66 | { | 65 | { |
@@ -71,7 +70,6 @@ xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) | |||
71 | /* | 70 | /* |
72 | * Pointer to the leaf entries embedded in a data block (1-block format) | 71 | * Pointer to the leaf entries embedded in a data block (1-block format) |
73 | */ | 72 | */ |
74 | #define XFS_DIR2_BLOCK_LEAF_P(btp) xfs_dir2_block_leaf_p(btp) | ||
75 | static inline struct xfs_dir2_leaf_entry * | 73 | static inline struct xfs_dir2_leaf_entry * |
76 | xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) | 74 | xfs_dir2_block_leaf_p(xfs_dir2_block_tail_t *btp) |
77 | { | 75 | { |
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index c211c37ef67..7ebe295bd6d 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -72,8 +72,8 @@ xfs_dir2_data_check( | |||
72 | bf = d->hdr.bestfree; | 72 | bf = d->hdr.bestfree; |
73 | p = (char *)d->u; | 73 | p = (char *)d->u; |
74 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { | 74 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { |
75 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); | 75 | btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); |
76 | lep = XFS_DIR2_BLOCK_LEAF_P(btp); | 76 | lep = xfs_dir2_block_leaf_p(btp); |
77 | endp = (char *)lep; | 77 | endp = (char *)lep; |
78 | } else | 78 | } else |
79 | endp = (char *)d + mp->m_dirblksize; | 79 | endp = (char *)d + mp->m_dirblksize; |
@@ -107,7 +107,7 @@ xfs_dir2_data_check( | |||
107 | */ | 107 | */ |
108 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { | 108 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { |
109 | ASSERT(lastfree == 0); | 109 | ASSERT(lastfree == 0); |
110 | ASSERT(be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup)) == | 110 | ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == |
111 | (char *)dup - (char *)d); | 111 | (char *)dup - (char *)d); |
112 | dfp = xfs_dir2_data_freefind(d, dup); | 112 | dfp = xfs_dir2_data_freefind(d, dup); |
113 | if (dfp) { | 113 | if (dfp) { |
@@ -131,12 +131,12 @@ xfs_dir2_data_check( | |||
131 | dep = (xfs_dir2_data_entry_t *)p; | 131 | dep = (xfs_dir2_data_entry_t *)p; |
132 | ASSERT(dep->namelen != 0); | 132 | ASSERT(dep->namelen != 0); |
133 | ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); | 133 | ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); |
134 | ASSERT(be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep)) == | 134 | ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == |
135 | (char *)dep - (char *)d); | 135 | (char *)dep - (char *)d); |
136 | count++; | 136 | count++; |
137 | lastfree = 0; | 137 | lastfree = 0; |
138 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { | 138 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { |
139 | addr = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 139 | addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
140 | (xfs_dir2_data_aoff_t) | 140 | (xfs_dir2_data_aoff_t) |
141 | ((char *)dep - (char *)d)); | 141 | ((char *)dep - (char *)d)); |
142 | hash = xfs_da_hashname((char *)dep->name, dep->namelen); | 142 | hash = xfs_da_hashname((char *)dep->name, dep->namelen); |
@@ -147,7 +147,7 @@ xfs_dir2_data_check( | |||
147 | } | 147 | } |
148 | ASSERT(i < be32_to_cpu(btp->count)); | 148 | ASSERT(i < be32_to_cpu(btp->count)); |
149 | } | 149 | } |
150 | p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); | 150 | p += xfs_dir2_data_entsize(dep->namelen); |
151 | } | 151 | } |
152 | /* | 152 | /* |
153 | * Need to have seen all the entries and all the bestfree slots. | 153 | * Need to have seen all the entries and all the bestfree slots. |
@@ -346,8 +346,8 @@ xfs_dir2_data_freescan( | |||
346 | */ | 346 | */ |
347 | p = (char *)d->u; | 347 | p = (char *)d->u; |
348 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { | 348 | if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { |
349 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); | 349 | btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); |
350 | endp = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); | 350 | endp = (char *)xfs_dir2_block_leaf_p(btp); |
351 | } else | 351 | } else |
352 | endp = (char *)d + mp->m_dirblksize; | 352 | endp = (char *)d + mp->m_dirblksize; |
353 | /* | 353 | /* |
@@ -360,7 +360,7 @@ xfs_dir2_data_freescan( | |||
360 | */ | 360 | */ |
361 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { | 361 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { |
362 | ASSERT((char *)dup - (char *)d == | 362 | ASSERT((char *)dup - (char *)d == |
363 | be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup))); | 363 | be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); |
364 | xfs_dir2_data_freeinsert(d, dup, loghead); | 364 | xfs_dir2_data_freeinsert(d, dup, loghead); |
365 | p += be16_to_cpu(dup->length); | 365 | p += be16_to_cpu(dup->length); |
366 | } | 366 | } |
@@ -370,8 +370,8 @@ xfs_dir2_data_freescan( | |||
370 | else { | 370 | else { |
371 | dep = (xfs_dir2_data_entry_t *)p; | 371 | dep = (xfs_dir2_data_entry_t *)p; |
372 | ASSERT((char *)dep - (char *)d == | 372 | ASSERT((char *)dep - (char *)d == |
373 | be16_to_cpu(*XFS_DIR2_DATA_ENTRY_TAG_P(dep))); | 373 | be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); |
374 | p += XFS_DIR2_DATA_ENTSIZE(dep->namelen); | 374 | p += xfs_dir2_data_entsize(dep->namelen); |
375 | } | 375 | } |
376 | } | 376 | } |
377 | } | 377 | } |
@@ -402,7 +402,7 @@ xfs_dir2_data_init( | |||
402 | /* | 402 | /* |
403 | * Get the buffer set up for the block. | 403 | * Get the buffer set up for the block. |
404 | */ | 404 | */ |
405 | error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, blkno), -1, &bp, | 405 | error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, |
406 | XFS_DATA_FORK); | 406 | XFS_DATA_FORK); |
407 | if (error) { | 407 | if (error) { |
408 | return error; | 408 | return error; |
@@ -427,7 +427,7 @@ xfs_dir2_data_init( | |||
427 | t=mp->m_dirblksize - (uint)sizeof(d->hdr); | 427 | t=mp->m_dirblksize - (uint)sizeof(d->hdr); |
428 | d->hdr.bestfree[0].length = cpu_to_be16(t); | 428 | d->hdr.bestfree[0].length = cpu_to_be16(t); |
429 | dup->length = cpu_to_be16(t); | 429 | dup->length = cpu_to_be16(t); |
430 | *XFS_DIR2_DATA_UNUSED_TAG_P(dup) = cpu_to_be16((char *)dup - (char *)d); | 430 | *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); |
431 | /* | 431 | /* |
432 | * Log it and return it. | 432 | * Log it and return it. |
433 | */ | 433 | */ |
@@ -452,7 +452,7 @@ xfs_dir2_data_log_entry( | |||
452 | ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || | 452 | ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || |
453 | be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); | 453 | be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); |
454 | xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), | 454 | xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), |
455 | (uint)((char *)(XFS_DIR2_DATA_ENTRY_TAG_P(dep) + 1) - | 455 | (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - |
456 | (char *)d - 1)); | 456 | (char *)d - 1)); |
457 | } | 457 | } |
458 | 458 | ||
@@ -497,8 +497,8 @@ xfs_dir2_data_log_unused( | |||
497 | * Log the end (tag) of the unused entry. | 497 | * Log the end (tag) of the unused entry. |
498 | */ | 498 | */ |
499 | xfs_da_log_buf(tp, bp, | 499 | xfs_da_log_buf(tp, bp, |
500 | (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d), | 500 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), |
501 | (uint)((char *)XFS_DIR2_DATA_UNUSED_TAG_P(dup) - (char *)d + | 501 | (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + |
502 | sizeof(xfs_dir2_data_off_t) - 1)); | 502 | sizeof(xfs_dir2_data_off_t) - 1)); |
503 | } | 503 | } |
504 | 504 | ||
@@ -535,8 +535,8 @@ xfs_dir2_data_make_free( | |||
535 | xfs_dir2_block_tail_t *btp; /* block tail */ | 535 | xfs_dir2_block_tail_t *btp; /* block tail */ |
536 | 536 | ||
537 | ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); | 537 | ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); |
538 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, (xfs_dir2_block_t *)d); | 538 | btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); |
539 | endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); | 539 | endptr = (char *)xfs_dir2_block_leaf_p(btp); |
540 | } | 540 | } |
541 | /* | 541 | /* |
542 | * If this isn't the start of the block, then back up to | 542 | * If this isn't the start of the block, then back up to |
@@ -587,7 +587,7 @@ xfs_dir2_data_make_free( | |||
587 | * Fix up the new big freespace. | 587 | * Fix up the new big freespace. |
588 | */ | 588 | */ |
589 | be16_add(&prevdup->length, len + be16_to_cpu(postdup->length)); | 589 | be16_add(&prevdup->length, len + be16_to_cpu(postdup->length)); |
590 | *XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) = | 590 | *xfs_dir2_data_unused_tag_p(prevdup) = |
591 | cpu_to_be16((char *)prevdup - (char *)d); | 591 | cpu_to_be16((char *)prevdup - (char *)d); |
592 | xfs_dir2_data_log_unused(tp, bp, prevdup); | 592 | xfs_dir2_data_log_unused(tp, bp, prevdup); |
593 | if (!needscan) { | 593 | if (!needscan) { |
@@ -621,7 +621,7 @@ xfs_dir2_data_make_free( | |||
621 | else if (prevdup) { | 621 | else if (prevdup) { |
622 | dfp = xfs_dir2_data_freefind(d, prevdup); | 622 | dfp = xfs_dir2_data_freefind(d, prevdup); |
623 | be16_add(&prevdup->length, len); | 623 | be16_add(&prevdup->length, len); |
624 | *XFS_DIR2_DATA_UNUSED_TAG_P(prevdup) = | 624 | *xfs_dir2_data_unused_tag_p(prevdup) = |
625 | cpu_to_be16((char *)prevdup - (char *)d); | 625 | cpu_to_be16((char *)prevdup - (char *)d); |
626 | xfs_dir2_data_log_unused(tp, bp, prevdup); | 626 | xfs_dir2_data_log_unused(tp, bp, prevdup); |
627 | /* | 627 | /* |
@@ -649,7 +649,7 @@ xfs_dir2_data_make_free( | |||
649 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); | 649 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); |
650 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 650 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
651 | newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); | 651 | newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); |
652 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) = | 652 | *xfs_dir2_data_unused_tag_p(newdup) = |
653 | cpu_to_be16((char *)newdup - (char *)d); | 653 | cpu_to_be16((char *)newdup - (char *)d); |
654 | xfs_dir2_data_log_unused(tp, bp, newdup); | 654 | xfs_dir2_data_log_unused(tp, bp, newdup); |
655 | /* | 655 | /* |
@@ -676,7 +676,7 @@ xfs_dir2_data_make_free( | |||
676 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); | 676 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); |
677 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 677 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
678 | newdup->length = cpu_to_be16(len); | 678 | newdup->length = cpu_to_be16(len); |
679 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) = | 679 | *xfs_dir2_data_unused_tag_p(newdup) = |
680 | cpu_to_be16((char *)newdup - (char *)d); | 680 | cpu_to_be16((char *)newdup - (char *)d); |
681 | xfs_dir2_data_log_unused(tp, bp, newdup); | 681 | xfs_dir2_data_log_unused(tp, bp, newdup); |
682 | (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); | 682 | (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); |
@@ -712,7 +712,7 @@ xfs_dir2_data_use_free( | |||
712 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); | 712 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); |
713 | ASSERT(offset >= (char *)dup - (char *)d); | 713 | ASSERT(offset >= (char *)dup - (char *)d); |
714 | ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); | 714 | ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); |
715 | ASSERT((char *)dup - (char *)d == be16_to_cpu(*XFS_DIR2_DATA_UNUSED_TAG_P(dup))); | 715 | ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); |
716 | /* | 716 | /* |
717 | * Look up the entry in the bestfree table. | 717 | * Look up the entry in the bestfree table. |
718 | */ | 718 | */ |
@@ -745,7 +745,7 @@ xfs_dir2_data_use_free( | |||
745 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); | 745 | newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); |
746 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 746 | newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
747 | newdup->length = cpu_to_be16(oldlen - len); | 747 | newdup->length = cpu_to_be16(oldlen - len); |
748 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) = | 748 | *xfs_dir2_data_unused_tag_p(newdup) = |
749 | cpu_to_be16((char *)newdup - (char *)d); | 749 | cpu_to_be16((char *)newdup - (char *)d); |
750 | xfs_dir2_data_log_unused(tp, bp, newdup); | 750 | xfs_dir2_data_log_unused(tp, bp, newdup); |
751 | /* | 751 | /* |
@@ -772,7 +772,7 @@ xfs_dir2_data_use_free( | |||
772 | else if (matchback) { | 772 | else if (matchback) { |
773 | newdup = dup; | 773 | newdup = dup; |
774 | newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); | 774 | newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); |
775 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) = | 775 | *xfs_dir2_data_unused_tag_p(newdup) = |
776 | cpu_to_be16((char *)newdup - (char *)d); | 776 | cpu_to_be16((char *)newdup - (char *)d); |
777 | xfs_dir2_data_log_unused(tp, bp, newdup); | 777 | xfs_dir2_data_log_unused(tp, bp, newdup); |
778 | /* | 778 | /* |
@@ -799,13 +799,13 @@ xfs_dir2_data_use_free( | |||
799 | else { | 799 | else { |
800 | newdup = dup; | 800 | newdup = dup; |
801 | newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); | 801 | newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); |
802 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup) = | 802 | *xfs_dir2_data_unused_tag_p(newdup) = |
803 | cpu_to_be16((char *)newdup - (char *)d); | 803 | cpu_to_be16((char *)newdup - (char *)d); |
804 | xfs_dir2_data_log_unused(tp, bp, newdup); | 804 | xfs_dir2_data_log_unused(tp, bp, newdup); |
805 | newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); | 805 | newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); |
806 | newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 806 | newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
807 | newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); | 807 | newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); |
808 | *XFS_DIR2_DATA_UNUSED_TAG_P(newdup2) = | 808 | *xfs_dir2_data_unused_tag_p(newdup2) = |
809 | cpu_to_be16((char *)newdup2 - (char *)d); | 809 | cpu_to_be16((char *)newdup2 - (char *)d); |
810 | xfs_dir2_data_log_unused(tp, bp, newdup2); | 810 | xfs_dir2_data_log_unused(tp, bp, newdup2); |
811 | /* | 811 | /* |
diff --git a/fs/xfs/xfs_dir2_data.h b/fs/xfs/xfs_dir2_data.h index c94c9099cfb..b816e025273 100644 --- a/fs/xfs/xfs_dir2_data.h +++ b/fs/xfs/xfs_dir2_data.h | |||
@@ -44,7 +44,7 @@ struct xfs_trans; | |||
44 | #define XFS_DIR2_DATA_SPACE 0 | 44 | #define XFS_DIR2_DATA_SPACE 0 |
45 | #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) | 45 | #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) |
46 | #define XFS_DIR2_DATA_FIRSTDB(mp) \ | 46 | #define XFS_DIR2_DATA_FIRSTDB(mp) \ |
47 | XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATA_OFFSET) | 47 | xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET) |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Offsets of . and .. in data space (always block 0) | 50 | * Offsets of . and .. in data space (always block 0) |
@@ -52,9 +52,9 @@ struct xfs_trans; | |||
52 | #define XFS_DIR2_DATA_DOT_OFFSET \ | 52 | #define XFS_DIR2_DATA_DOT_OFFSET \ |
53 | ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) | 53 | ((xfs_dir2_data_aoff_t)sizeof(xfs_dir2_data_hdr_t)) |
54 | #define XFS_DIR2_DATA_DOTDOT_OFFSET \ | 54 | #define XFS_DIR2_DATA_DOTDOT_OFFSET \ |
55 | (XFS_DIR2_DATA_DOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(1)) | 55 | (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1)) |
56 | #define XFS_DIR2_DATA_FIRST_OFFSET \ | 56 | #define XFS_DIR2_DATA_FIRST_OFFSET \ |
57 | (XFS_DIR2_DATA_DOTDOT_OFFSET + XFS_DIR2_DATA_ENTSIZE(2)) | 57 | (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2)) |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Structures. | 60 | * Structures. |
@@ -123,7 +123,6 @@ typedef struct xfs_dir2_data { | |||
123 | /* | 123 | /* |
124 | * Size of a data entry. | 124 | * Size of a data entry. |
125 | */ | 125 | */ |
126 | #define XFS_DIR2_DATA_ENTSIZE(n) xfs_dir2_data_entsize(n) | ||
127 | static inline int xfs_dir2_data_entsize(int n) | 126 | static inline int xfs_dir2_data_entsize(int n) |
128 | { | 127 | { |
129 | return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ | 128 | return (int)roundup(offsetof(xfs_dir2_data_entry_t, name[0]) + (n) + \ |
@@ -133,19 +132,16 @@ static inline int xfs_dir2_data_entsize(int n) | |||
133 | /* | 132 | /* |
134 | * Pointer to an entry's tag word. | 133 | * Pointer to an entry's tag word. |
135 | */ | 134 | */ |
136 | #define XFS_DIR2_DATA_ENTRY_TAG_P(dep) xfs_dir2_data_entry_tag_p(dep) | ||
137 | static inline __be16 * | 135 | static inline __be16 * |
138 | xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) | 136 | xfs_dir2_data_entry_tag_p(xfs_dir2_data_entry_t *dep) |
139 | { | 137 | { |
140 | return (__be16 *)((char *)dep + | 138 | return (__be16 *)((char *)dep + |
141 | XFS_DIR2_DATA_ENTSIZE(dep->namelen) - sizeof(__be16)); | 139 | xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16)); |
142 | } | 140 | } |
143 | 141 | ||
144 | /* | 142 | /* |
145 | * Pointer to a freespace's tag word. | 143 | * Pointer to a freespace's tag word. |
146 | */ | 144 | */ |
147 | #define XFS_DIR2_DATA_UNUSED_TAG_P(dup) \ | ||
148 | xfs_dir2_data_unused_tag_p(dup) | ||
149 | static inline __be16 * | 145 | static inline __be16 * |
150 | xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) | 146 | xfs_dir2_data_unused_tag_p(xfs_dir2_data_unused_t *dup) |
151 | { | 147 | { |
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index db14ea71459..1b73c9ad646 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -92,7 +92,7 @@ xfs_dir2_block_to_leaf( | |||
92 | if ((error = xfs_da_grow_inode(args, &blkno))) { | 92 | if ((error = xfs_da_grow_inode(args, &blkno))) { |
93 | return error; | 93 | return error; |
94 | } | 94 | } |
95 | ldb = XFS_DIR2_DA_TO_DB(mp, blkno); | 95 | ldb = xfs_dir2_da_to_db(mp, blkno); |
96 | ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); | 96 | ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); |
97 | /* | 97 | /* |
98 | * Initialize the leaf block, get a buffer for it. | 98 | * Initialize the leaf block, get a buffer for it. |
@@ -104,8 +104,8 @@ xfs_dir2_block_to_leaf( | |||
104 | leaf = lbp->data; | 104 | leaf = lbp->data; |
105 | block = dbp->data; | 105 | block = dbp->data; |
106 | xfs_dir2_data_check(dp, dbp); | 106 | xfs_dir2_data_check(dp, dbp); |
107 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 107 | btp = xfs_dir2_block_tail_p(mp, block); |
108 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 108 | blp = xfs_dir2_block_leaf_p(btp); |
109 | /* | 109 | /* |
110 | * Set the counts in the leaf header. | 110 | * Set the counts in the leaf header. |
111 | */ | 111 | */ |
@@ -137,9 +137,9 @@ xfs_dir2_block_to_leaf( | |||
137 | /* | 137 | /* |
138 | * Set up leaf tail and bests table. | 138 | * Set up leaf tail and bests table. |
139 | */ | 139 | */ |
140 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 140 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
141 | ltp->bestcount = cpu_to_be32(1); | 141 | ltp->bestcount = cpu_to_be32(1); |
142 | bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); | 142 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
143 | bestsp[0] = block->hdr.bestfree[0].length; | 143 | bestsp[0] = block->hdr.bestfree[0].length; |
144 | /* | 144 | /* |
145 | * Log the data header and leaf bests table. | 145 | * Log the data header and leaf bests table. |
@@ -209,9 +209,9 @@ xfs_dir2_leaf_addname( | |||
209 | */ | 209 | */ |
210 | index = xfs_dir2_leaf_search_hash(args, lbp); | 210 | index = xfs_dir2_leaf_search_hash(args, lbp); |
211 | leaf = lbp->data; | 211 | leaf = lbp->data; |
212 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 212 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
213 | bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); | 213 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
214 | length = XFS_DIR2_DATA_ENTSIZE(args->namelen); | 214 | length = xfs_dir2_data_entsize(args->namelen); |
215 | /* | 215 | /* |
216 | * See if there are any entries with the same hash value | 216 | * See if there are any entries with the same hash value |
217 | * and space in their block for the new entry. | 217 | * and space in their block for the new entry. |
@@ -223,7 +223,7 @@ xfs_dir2_leaf_addname( | |||
223 | index++, lep++) { | 223 | index++, lep++) { |
224 | if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) | 224 | if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) |
225 | continue; | 225 | continue; |
226 | i = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); | 226 | i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); |
227 | ASSERT(i < be32_to_cpu(ltp->bestcount)); | 227 | ASSERT(i < be32_to_cpu(ltp->bestcount)); |
228 | ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); | 228 | ASSERT(be16_to_cpu(bestsp[i]) != NULLDATAOFF); |
229 | if (be16_to_cpu(bestsp[i]) >= length) { | 229 | if (be16_to_cpu(bestsp[i]) >= length) { |
@@ -378,7 +378,7 @@ xfs_dir2_leaf_addname( | |||
378 | */ | 378 | */ |
379 | else { | 379 | else { |
380 | if ((error = | 380 | if ((error = |
381 | xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, use_block), | 381 | xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), |
382 | -1, &dbp, XFS_DATA_FORK))) { | 382 | -1, &dbp, XFS_DATA_FORK))) { |
383 | xfs_da_brelse(tp, lbp); | 383 | xfs_da_brelse(tp, lbp); |
384 | return error; | 384 | return error; |
@@ -407,7 +407,7 @@ xfs_dir2_leaf_addname( | |||
407 | dep->inumber = cpu_to_be64(args->inumber); | 407 | dep->inumber = cpu_to_be64(args->inumber); |
408 | dep->namelen = args->namelen; | 408 | dep->namelen = args->namelen; |
409 | memcpy(dep->name, args->name, dep->namelen); | 409 | memcpy(dep->name, args->name, dep->namelen); |
410 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 410 | tagp = xfs_dir2_data_entry_tag_p(dep); |
411 | *tagp = cpu_to_be16((char *)dep - (char *)data); | 411 | *tagp = cpu_to_be16((char *)dep - (char *)data); |
412 | /* | 412 | /* |
413 | * Need to scan fix up the bestfree table. | 413 | * Need to scan fix up the bestfree table. |
@@ -529,7 +529,7 @@ xfs_dir2_leaf_addname( | |||
529 | * Fill in the new leaf entry. | 529 | * Fill in the new leaf entry. |
530 | */ | 530 | */ |
531 | lep->hashval = cpu_to_be32(args->hashval); | 531 | lep->hashval = cpu_to_be32(args->hashval); |
532 | lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp, use_block, | 532 | lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block, |
533 | be16_to_cpu(*tagp))); | 533 | be16_to_cpu(*tagp))); |
534 | /* | 534 | /* |
535 | * Log the leaf fields and give up the buffers. | 535 | * Log the leaf fields and give up the buffers. |
@@ -567,13 +567,13 @@ xfs_dir2_leaf_check( | |||
567 | * Should factor in the size of the bests table as well. | 567 | * Should factor in the size of the bests table as well. |
568 | * We can deduce a value for that from di_size. | 568 | * We can deduce a value for that from di_size. |
569 | */ | 569 | */ |
570 | ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); | 570 | ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); |
571 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 571 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
572 | /* | 572 | /* |
573 | * Leaves and bests don't overlap. | 573 | * Leaves and bests don't overlap. |
574 | */ | 574 | */ |
575 | ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= | 575 | ASSERT((char *)&leaf->ents[be16_to_cpu(leaf->hdr.count)] <= |
576 | (char *)XFS_DIR2_LEAF_BESTS_P(ltp)); | 576 | (char *)xfs_dir2_leaf_bests_p(ltp)); |
577 | /* | 577 | /* |
578 | * Check hash value order, count stale entries. | 578 | * Check hash value order, count stale entries. |
579 | */ | 579 | */ |
@@ -815,12 +815,12 @@ xfs_dir2_leaf_getdents( | |||
815 | * Inside the loop we keep the main offset value as a byte offset | 815 | * Inside the loop we keep the main offset value as a byte offset |
816 | * in the directory file. | 816 | * in the directory file. |
817 | */ | 817 | */ |
818 | curoff = XFS_DIR2_DATAPTR_TO_BYTE(mp, uio->uio_offset); | 818 | curoff = xfs_dir2_dataptr_to_byte(mp, uio->uio_offset); |
819 | /* | 819 | /* |
820 | * Force this conversion through db so we truncate the offset | 820 | * Force this conversion through db so we truncate the offset |
821 | * down to get the start of the data block. | 821 | * down to get the start of the data block. |
822 | */ | 822 | */ |
823 | map_off = XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, curoff)); | 823 | map_off = xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, curoff)); |
824 | /* | 824 | /* |
825 | * Loop over directory entries until we reach the end offset. | 825 | * Loop over directory entries until we reach the end offset. |
826 | * Get more blocks and readahead as necessary. | 826 | * Get more blocks and readahead as necessary. |
@@ -870,7 +870,7 @@ xfs_dir2_leaf_getdents( | |||
870 | */ | 870 | */ |
871 | if (1 + ra_want > map_blocks && | 871 | if (1 + ra_want > map_blocks && |
872 | map_off < | 872 | map_off < |
873 | XFS_DIR2_BYTE_TO_DA(mp, XFS_DIR2_LEAF_OFFSET)) { | 873 | xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { |
874 | /* | 874 | /* |
875 | * Get more bmaps, fill in after the ones | 875 | * Get more bmaps, fill in after the ones |
876 | * we already have in the table. | 876 | * we already have in the table. |
@@ -878,7 +878,7 @@ xfs_dir2_leaf_getdents( | |||
878 | nmap = map_size - map_valid; | 878 | nmap = map_size - map_valid; |
879 | error = xfs_bmapi(tp, dp, | 879 | error = xfs_bmapi(tp, dp, |
880 | map_off, | 880 | map_off, |
881 | XFS_DIR2_BYTE_TO_DA(mp, | 881 | xfs_dir2_byte_to_da(mp, |
882 | XFS_DIR2_LEAF_OFFSET) - map_off, | 882 | XFS_DIR2_LEAF_OFFSET) - map_off, |
883 | XFS_BMAPI_METADATA, NULL, 0, | 883 | XFS_BMAPI_METADATA, NULL, 0, |
884 | &map[map_valid], &nmap, NULL, NULL); | 884 | &map[map_valid], &nmap, NULL, NULL); |
@@ -903,7 +903,7 @@ xfs_dir2_leaf_getdents( | |||
903 | map[map_valid + nmap - 1].br_blockcount; | 903 | map[map_valid + nmap - 1].br_blockcount; |
904 | else | 904 | else |
905 | map_off = | 905 | map_off = |
906 | XFS_DIR2_BYTE_TO_DA(mp, | 906 | xfs_dir2_byte_to_da(mp, |
907 | XFS_DIR2_LEAF_OFFSET); | 907 | XFS_DIR2_LEAF_OFFSET); |
908 | /* | 908 | /* |
909 | * Look for holes in the mapping, and | 909 | * Look for holes in the mapping, and |
@@ -931,14 +931,14 @@ xfs_dir2_leaf_getdents( | |||
931 | * No valid mappings, so no more data blocks. | 931 | * No valid mappings, so no more data blocks. |
932 | */ | 932 | */ |
933 | if (!map_valid) { | 933 | if (!map_valid) { |
934 | curoff = XFS_DIR2_DA_TO_BYTE(mp, map_off); | 934 | curoff = xfs_dir2_da_to_byte(mp, map_off); |
935 | break; | 935 | break; |
936 | } | 936 | } |
937 | /* | 937 | /* |
938 | * Read the directory block starting at the first | 938 | * Read the directory block starting at the first |
939 | * mapping. | 939 | * mapping. |
940 | */ | 940 | */ |
941 | curdb = XFS_DIR2_DA_TO_DB(mp, map->br_startoff); | 941 | curdb = xfs_dir2_da_to_db(mp, map->br_startoff); |
942 | error = xfs_da_read_buf(tp, dp, map->br_startoff, | 942 | error = xfs_da_read_buf(tp, dp, map->br_startoff, |
943 | map->br_blockcount >= mp->m_dirblkfsbs ? | 943 | map->br_blockcount >= mp->m_dirblkfsbs ? |
944 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : | 944 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : |
@@ -1014,7 +1014,7 @@ xfs_dir2_leaf_getdents( | |||
1014 | /* | 1014 | /* |
1015 | * Having done a read, we need to set a new offset. | 1015 | * Having done a read, we need to set a new offset. |
1016 | */ | 1016 | */ |
1017 | newoff = XFS_DIR2_DB_OFF_TO_BYTE(mp, curdb, 0); | 1017 | newoff = xfs_dir2_db_off_to_byte(mp, curdb, 0); |
1018 | /* | 1018 | /* |
1019 | * Start of the current block. | 1019 | * Start of the current block. |
1020 | */ | 1020 | */ |
@@ -1024,7 +1024,7 @@ xfs_dir2_leaf_getdents( | |||
1024 | * Make sure we're in the right block. | 1024 | * Make sure we're in the right block. |
1025 | */ | 1025 | */ |
1026 | else if (curoff > newoff) | 1026 | else if (curoff > newoff) |
1027 | ASSERT(XFS_DIR2_BYTE_TO_DB(mp, curoff) == | 1027 | ASSERT(xfs_dir2_byte_to_db(mp, curoff) == |
1028 | curdb); | 1028 | curdb); |
1029 | data = bp->data; | 1029 | data = bp->data; |
1030 | xfs_dir2_data_check(dp, bp); | 1030 | xfs_dir2_data_check(dp, bp); |
@@ -1032,7 +1032,7 @@ xfs_dir2_leaf_getdents( | |||
1032 | * Find our position in the block. | 1032 | * Find our position in the block. |
1033 | */ | 1033 | */ |
1034 | ptr = (char *)&data->u; | 1034 | ptr = (char *)&data->u; |
1035 | byteoff = XFS_DIR2_BYTE_TO_OFF(mp, curoff); | 1035 | byteoff = xfs_dir2_byte_to_off(mp, curoff); |
1036 | /* | 1036 | /* |
1037 | * Skip past the header. | 1037 | * Skip past the header. |
1038 | */ | 1038 | */ |
@@ -1054,15 +1054,15 @@ xfs_dir2_leaf_getdents( | |||
1054 | } | 1054 | } |
1055 | dep = (xfs_dir2_data_entry_t *)ptr; | 1055 | dep = (xfs_dir2_data_entry_t *)ptr; |
1056 | length = | 1056 | length = |
1057 | XFS_DIR2_DATA_ENTSIZE(dep->namelen); | 1057 | xfs_dir2_data_entsize(dep->namelen); |
1058 | ptr += length; | 1058 | ptr += length; |
1059 | } | 1059 | } |
1060 | /* | 1060 | /* |
1061 | * Now set our real offset. | 1061 | * Now set our real offset. |
1062 | */ | 1062 | */ |
1063 | curoff = | 1063 | curoff = |
1064 | XFS_DIR2_DB_OFF_TO_BYTE(mp, | 1064 | xfs_dir2_db_off_to_byte(mp, |
1065 | XFS_DIR2_BYTE_TO_DB(mp, curoff), | 1065 | xfs_dir2_byte_to_db(mp, curoff), |
1066 | (char *)ptr - (char *)data); | 1066 | (char *)ptr - (char *)data); |
1067 | if (ptr >= (char *)data + mp->m_dirblksize) { | 1067 | if (ptr >= (char *)data + mp->m_dirblksize) { |
1068 | continue; | 1068 | continue; |
@@ -1091,9 +1091,9 @@ xfs_dir2_leaf_getdents( | |||
1091 | 1091 | ||
1092 | p->namelen = dep->namelen; | 1092 | p->namelen = dep->namelen; |
1093 | 1093 | ||
1094 | length = XFS_DIR2_DATA_ENTSIZE(p->namelen); | 1094 | length = xfs_dir2_data_entsize(p->namelen); |
1095 | 1095 | ||
1096 | p->cook = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff + length); | 1096 | p->cook = xfs_dir2_byte_to_dataptr(mp, curoff + length); |
1097 | 1097 | ||
1098 | p->ino = be64_to_cpu(dep->inumber); | 1098 | p->ino = be64_to_cpu(dep->inumber); |
1099 | #if XFS_BIG_INUMS | 1099 | #if XFS_BIG_INUMS |
@@ -1121,10 +1121,10 @@ xfs_dir2_leaf_getdents( | |||
1121 | * All done. Set output offset value to current offset. | 1121 | * All done. Set output offset value to current offset. |
1122 | */ | 1122 | */ |
1123 | *eofp = eof; | 1123 | *eofp = eof; |
1124 | if (curoff > XFS_DIR2_DATAPTR_TO_BYTE(mp, XFS_DIR2_MAX_DATAPTR)) | 1124 | if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) |
1125 | uio->uio_offset = XFS_DIR2_MAX_DATAPTR; | 1125 | uio->uio_offset = XFS_DIR2_MAX_DATAPTR; |
1126 | else | 1126 | else |
1127 | uio->uio_offset = XFS_DIR2_BYTE_TO_DATAPTR(mp, curoff); | 1127 | uio->uio_offset = xfs_dir2_byte_to_dataptr(mp, curoff); |
1128 | kmem_free(map, map_size * sizeof(*map)); | 1128 | kmem_free(map, map_size * sizeof(*map)); |
1129 | kmem_free(p, sizeof(*p)); | 1129 | kmem_free(p, sizeof(*p)); |
1130 | if (bp) | 1130 | if (bp) |
@@ -1159,7 +1159,7 @@ xfs_dir2_leaf_init( | |||
1159 | /* | 1159 | /* |
1160 | * Get the buffer for the block. | 1160 | * Get the buffer for the block. |
1161 | */ | 1161 | */ |
1162 | error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, bno), -1, &bp, | 1162 | error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, |
1163 | XFS_DATA_FORK); | 1163 | XFS_DATA_FORK); |
1164 | if (error) { | 1164 | if (error) { |
1165 | return error; | 1165 | return error; |
@@ -1181,7 +1181,7 @@ xfs_dir2_leaf_init( | |||
1181 | * the block. | 1181 | * the block. |
1182 | */ | 1182 | */ |
1183 | if (magic == XFS_DIR2_LEAF1_MAGIC) { | 1183 | if (magic == XFS_DIR2_LEAF1_MAGIC) { |
1184 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 1184 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1185 | ltp->bestcount = 0; | 1185 | ltp->bestcount = 0; |
1186 | xfs_dir2_leaf_log_tail(tp, bp); | 1186 | xfs_dir2_leaf_log_tail(tp, bp); |
1187 | } | 1187 | } |
@@ -1206,9 +1206,9 @@ xfs_dir2_leaf_log_bests( | |||
1206 | 1206 | ||
1207 | leaf = bp->data; | 1207 | leaf = bp->data; |
1208 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); | 1208 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); |
1209 | ltp = XFS_DIR2_LEAF_TAIL_P(tp->t_mountp, leaf); | 1209 | ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); |
1210 | firstb = XFS_DIR2_LEAF_BESTS_P(ltp) + first; | 1210 | firstb = xfs_dir2_leaf_bests_p(ltp) + first; |
1211 | lastb = XFS_DIR2_LEAF_BESTS_P(ltp) + last; | 1211 | lastb = xfs_dir2_leaf_bests_p(ltp) + last; |
1212 | xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), | 1212 | xfs_da_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), |
1213 | (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); | 1213 | (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); |
1214 | } | 1214 | } |
@@ -1268,7 +1268,7 @@ xfs_dir2_leaf_log_tail( | |||
1268 | mp = tp->t_mountp; | 1268 | mp = tp->t_mountp; |
1269 | leaf = bp->data; | 1269 | leaf = bp->data; |
1270 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); | 1270 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAF1_MAGIC); |
1271 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 1271 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1272 | xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), | 1272 | xfs_da_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), |
1273 | (uint)(mp->m_dirblksize - 1)); | 1273 | (uint)(mp->m_dirblksize - 1)); |
1274 | } | 1274 | } |
@@ -1312,7 +1312,7 @@ xfs_dir2_leaf_lookup( | |||
1312 | */ | 1312 | */ |
1313 | dep = (xfs_dir2_data_entry_t *) | 1313 | dep = (xfs_dir2_data_entry_t *) |
1314 | ((char *)dbp->data + | 1314 | ((char *)dbp->data + |
1315 | XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); | 1315 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); |
1316 | /* | 1316 | /* |
1317 | * Return the found inode number. | 1317 | * Return the found inode number. |
1318 | */ | 1318 | */ |
@@ -1381,7 +1381,7 @@ xfs_dir2_leaf_lookup_int( | |||
1381 | /* | 1381 | /* |
1382 | * Get the new data block number. | 1382 | * Get the new data block number. |
1383 | */ | 1383 | */ |
1384 | newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); | 1384 | newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); |
1385 | /* | 1385 | /* |
1386 | * If it's not the same as the old data block number, | 1386 | * If it's not the same as the old data block number, |
1387 | * need to pitch the old one and read the new one. | 1387 | * need to pitch the old one and read the new one. |
@@ -1391,7 +1391,7 @@ xfs_dir2_leaf_lookup_int( | |||
1391 | xfs_da_brelse(tp, dbp); | 1391 | xfs_da_brelse(tp, dbp); |
1392 | if ((error = | 1392 | if ((error = |
1393 | xfs_da_read_buf(tp, dp, | 1393 | xfs_da_read_buf(tp, dp, |
1394 | XFS_DIR2_DB_TO_DA(mp, newdb), -1, &dbp, | 1394 | xfs_dir2_db_to_da(mp, newdb), -1, &dbp, |
1395 | XFS_DATA_FORK))) { | 1395 | XFS_DATA_FORK))) { |
1396 | xfs_da_brelse(tp, lbp); | 1396 | xfs_da_brelse(tp, lbp); |
1397 | return error; | 1397 | return error; |
@@ -1404,7 +1404,7 @@ xfs_dir2_leaf_lookup_int( | |||
1404 | */ | 1404 | */ |
1405 | dep = (xfs_dir2_data_entry_t *) | 1405 | dep = (xfs_dir2_data_entry_t *) |
1406 | ((char *)dbp->data + | 1406 | ((char *)dbp->data + |
1407 | XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address))); | 1407 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
1408 | /* | 1408 | /* |
1409 | * If it matches then return it. | 1409 | * If it matches then return it. |
1410 | */ | 1410 | */ |
@@ -1469,20 +1469,20 @@ xfs_dir2_leaf_removename( | |||
1469 | * Point to the leaf entry, use that to point to the data entry. | 1469 | * Point to the leaf entry, use that to point to the data entry. |
1470 | */ | 1470 | */ |
1471 | lep = &leaf->ents[index]; | 1471 | lep = &leaf->ents[index]; |
1472 | db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); | 1472 | db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); |
1473 | dep = (xfs_dir2_data_entry_t *) | 1473 | dep = (xfs_dir2_data_entry_t *) |
1474 | ((char *)data + XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address))); | 1474 | ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
1475 | needscan = needlog = 0; | 1475 | needscan = needlog = 0; |
1476 | oldbest = be16_to_cpu(data->hdr.bestfree[0].length); | 1476 | oldbest = be16_to_cpu(data->hdr.bestfree[0].length); |
1477 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 1477 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1478 | bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); | 1478 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
1479 | ASSERT(be16_to_cpu(bestsp[db]) == oldbest); | 1479 | ASSERT(be16_to_cpu(bestsp[db]) == oldbest); |
1480 | /* | 1480 | /* |
1481 | * Mark the former data entry unused. | 1481 | * Mark the former data entry unused. |
1482 | */ | 1482 | */ |
1483 | xfs_dir2_data_make_free(tp, dbp, | 1483 | xfs_dir2_data_make_free(tp, dbp, |
1484 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), | 1484 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), |
1485 | XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); | 1485 | xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); |
1486 | /* | 1486 | /* |
1487 | * We just mark the leaf entry stale by putting a null in it. | 1487 | * We just mark the leaf entry stale by putting a null in it. |
1488 | */ | 1488 | */ |
@@ -1602,7 +1602,7 @@ xfs_dir2_leaf_replace( | |||
1602 | */ | 1602 | */ |
1603 | dep = (xfs_dir2_data_entry_t *) | 1603 | dep = (xfs_dir2_data_entry_t *) |
1604 | ((char *)dbp->data + | 1604 | ((char *)dbp->data + |
1605 | XFS_DIR2_DATAPTR_TO_OFF(dp->i_mount, be32_to_cpu(lep->address))); | 1605 | xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); |
1606 | ASSERT(args->inumber != be64_to_cpu(dep->inumber)); | 1606 | ASSERT(args->inumber != be64_to_cpu(dep->inumber)); |
1607 | /* | 1607 | /* |
1608 | * Put the new inode number in, log it. | 1608 | * Put the new inode number in, log it. |
@@ -1698,7 +1698,7 @@ xfs_dir2_leaf_trim_data( | |||
1698 | /* | 1698 | /* |
1699 | * Read the offending data block. We need its buffer. | 1699 | * Read the offending data block. We need its buffer. |
1700 | */ | 1700 | */ |
1701 | if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, db), -1, &dbp, | 1701 | if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, |
1702 | XFS_DATA_FORK))) { | 1702 | XFS_DATA_FORK))) { |
1703 | return error; | 1703 | return error; |
1704 | } | 1704 | } |
@@ -1712,7 +1712,7 @@ xfs_dir2_leaf_trim_data( | |||
1712 | */ | 1712 | */ |
1713 | 1713 | ||
1714 | leaf = lbp->data; | 1714 | leaf = lbp->data; |
1715 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 1715 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1716 | ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == | 1716 | ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == |
1717 | mp->m_dirblksize - (uint)sizeof(data->hdr)); | 1717 | mp->m_dirblksize - (uint)sizeof(data->hdr)); |
1718 | ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); | 1718 | ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); |
@@ -1727,7 +1727,7 @@ xfs_dir2_leaf_trim_data( | |||
1727 | /* | 1727 | /* |
1728 | * Eliminate the last bests entry from the table. | 1728 | * Eliminate the last bests entry from the table. |
1729 | */ | 1729 | */ |
1730 | bestsp = XFS_DIR2_LEAF_BESTS_P(ltp); | 1730 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
1731 | be32_add(<p->bestcount, -1); | 1731 | be32_add(<p->bestcount, -1); |
1732 | memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); | 1732 | memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); |
1733 | xfs_dir2_leaf_log_tail(tp, lbp); | 1733 | xfs_dir2_leaf_log_tail(tp, lbp); |
@@ -1838,12 +1838,12 @@ xfs_dir2_node_to_leaf( | |||
1838 | /* | 1838 | /* |
1839 | * Set up the leaf tail from the freespace block. | 1839 | * Set up the leaf tail from the freespace block. |
1840 | */ | 1840 | */ |
1841 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 1841 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1842 | ltp->bestcount = free->hdr.nvalid; | 1842 | ltp->bestcount = free->hdr.nvalid; |
1843 | /* | 1843 | /* |
1844 | * Set up the leaf bests table. | 1844 | * Set up the leaf bests table. |
1845 | */ | 1845 | */ |
1846 | memcpy(XFS_DIR2_LEAF_BESTS_P(ltp), free->bests, | 1846 | memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, |
1847 | be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); | 1847 | be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); |
1848 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); | 1848 | xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
1849 | xfs_dir2_leaf_log_tail(tp, lbp); | 1849 | xfs_dir2_leaf_log_tail(tp, lbp); |
diff --git a/fs/xfs/xfs_dir2_leaf.h b/fs/xfs/xfs_dir2_leaf.h index f57ca116241..70c97f3f815 100644 --- a/fs/xfs/xfs_dir2_leaf.h +++ b/fs/xfs/xfs_dir2_leaf.h | |||
@@ -32,7 +32,7 @@ struct xfs_trans; | |||
32 | #define XFS_DIR2_LEAF_SPACE 1 | 32 | #define XFS_DIR2_LEAF_SPACE 1 |
33 | #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) | 33 | #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) |
34 | #define XFS_DIR2_LEAF_FIRSTDB(mp) \ | 34 | #define XFS_DIR2_LEAF_FIRSTDB(mp) \ |
35 | XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_LEAF_OFFSET) | 35 | xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET) |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Offset in data space of a data entry. | 38 | * Offset in data space of a data entry. |
@@ -82,7 +82,6 @@ typedef struct xfs_dir2_leaf { | |||
82 | * DB blocks here are logical directory block numbers, not filesystem blocks. | 82 | * DB blocks here are logical directory block numbers, not filesystem blocks. |
83 | */ | 83 | */ |
84 | 84 | ||
85 | #define XFS_DIR2_MAX_LEAF_ENTS(mp) xfs_dir2_max_leaf_ents(mp) | ||
86 | static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) | 85 | static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) |
87 | { | 86 | { |
88 | return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / | 87 | return (int)(((mp)->m_dirblksize - (uint)sizeof(xfs_dir2_leaf_hdr_t)) / |
@@ -92,7 +91,6 @@ static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp) | |||
92 | /* | 91 | /* |
93 | * Get address of the bestcount field in the single-leaf block. | 92 | * Get address of the bestcount field in the single-leaf block. |
94 | */ | 93 | */ |
95 | #define XFS_DIR2_LEAF_TAIL_P(mp,lp) xfs_dir2_leaf_tail_p(mp, lp) | ||
96 | static inline xfs_dir2_leaf_tail_t * | 94 | static inline xfs_dir2_leaf_tail_t * |
97 | xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) | 95 | xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) |
98 | { | 96 | { |
@@ -104,7 +102,6 @@ xfs_dir2_leaf_tail_p(struct xfs_mount *mp, xfs_dir2_leaf_t *lp) | |||
104 | /* | 102 | /* |
105 | * Get address of the bests array in the single-leaf block. | 103 | * Get address of the bests array in the single-leaf block. |
106 | */ | 104 | */ |
107 | #define XFS_DIR2_LEAF_BESTS_P(ltp) xfs_dir2_leaf_bests_p(ltp) | ||
108 | static inline __be16 * | 105 | static inline __be16 * |
109 | xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) | 106 | xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) |
110 | { | 107 | { |
@@ -114,7 +111,6 @@ xfs_dir2_leaf_bests_p(xfs_dir2_leaf_tail_t *ltp) | |||
114 | /* | 111 | /* |
115 | * Convert dataptr to byte in file space | 112 | * Convert dataptr to byte in file space |
116 | */ | 113 | */ |
117 | #define XFS_DIR2_DATAPTR_TO_BYTE(mp,dp) xfs_dir2_dataptr_to_byte(mp, dp) | ||
118 | static inline xfs_dir2_off_t | 114 | static inline xfs_dir2_off_t |
119 | xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) | 115 | xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) |
120 | { | 116 | { |
@@ -124,7 +120,6 @@ xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) | |||
124 | /* | 120 | /* |
125 | * Convert byte in file space to dataptr. It had better be aligned. | 121 | * Convert byte in file space to dataptr. It had better be aligned. |
126 | */ | 122 | */ |
127 | #define XFS_DIR2_BYTE_TO_DATAPTR(mp,by) xfs_dir2_byte_to_dataptr(mp,by) | ||
128 | static inline xfs_dir2_dataptr_t | 123 | static inline xfs_dir2_dataptr_t |
129 | xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) | 124 | xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) |
130 | { | 125 | { |
@@ -134,7 +129,6 @@ xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by) | |||
134 | /* | 129 | /* |
135 | * Convert byte in space to (DB) block | 130 | * Convert byte in space to (DB) block |
136 | */ | 131 | */ |
137 | #define XFS_DIR2_BYTE_TO_DB(mp,by) xfs_dir2_byte_to_db(mp, by) | ||
138 | static inline xfs_dir2_db_t | 132 | static inline xfs_dir2_db_t |
139 | xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) | 133 | xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) |
140 | { | 134 | { |
@@ -145,17 +139,15 @@ xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by) | |||
145 | /* | 139 | /* |
146 | * Convert dataptr to a block number | 140 | * Convert dataptr to a block number |
147 | */ | 141 | */ |
148 | #define XFS_DIR2_DATAPTR_TO_DB(mp,dp) xfs_dir2_dataptr_to_db(mp, dp) | ||
149 | static inline xfs_dir2_db_t | 142 | static inline xfs_dir2_db_t |
150 | xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) | 143 | xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) |
151 | { | 144 | { |
152 | return XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp)); | 145 | return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp)); |
153 | } | 146 | } |
154 | 147 | ||
155 | /* | 148 | /* |
156 | * Convert byte in space to offset in a block | 149 | * Convert byte in space to offset in a block |
157 | */ | 150 | */ |
158 | #define XFS_DIR2_BYTE_TO_OFF(mp,by) xfs_dir2_byte_to_off(mp, by) | ||
159 | static inline xfs_dir2_data_aoff_t | 151 | static inline xfs_dir2_data_aoff_t |
160 | xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) | 152 | xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) |
161 | { | 153 | { |
@@ -166,18 +158,15 @@ xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by) | |||
166 | /* | 158 | /* |
167 | * Convert dataptr to a byte offset in a block | 159 | * Convert dataptr to a byte offset in a block |
168 | */ | 160 | */ |
169 | #define XFS_DIR2_DATAPTR_TO_OFF(mp,dp) xfs_dir2_dataptr_to_off(mp, dp) | ||
170 | static inline xfs_dir2_data_aoff_t | 161 | static inline xfs_dir2_data_aoff_t |
171 | xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) | 162 | xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp) |
172 | { | 163 | { |
173 | return XFS_DIR2_BYTE_TO_OFF(mp, XFS_DIR2_DATAPTR_TO_BYTE(mp, dp)); | 164 | return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp)); |
174 | } | 165 | } |
175 | 166 | ||
176 | /* | 167 | /* |
177 | * Convert block and offset to byte in space | 168 | * Convert block and offset to byte in space |
178 | */ | 169 | */ |
179 | #define XFS_DIR2_DB_OFF_TO_BYTE(mp,db,o) \ | ||
180 | xfs_dir2_db_off_to_byte(mp, db, o) | ||
181 | static inline xfs_dir2_off_t | 170 | static inline xfs_dir2_off_t |
182 | xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, | 171 | xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, |
183 | xfs_dir2_data_aoff_t o) | 172 | xfs_dir2_data_aoff_t o) |
@@ -189,7 +178,6 @@ xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db, | |||
189 | /* | 178 | /* |
190 | * Convert block (DB) to block (dablk) | 179 | * Convert block (DB) to block (dablk) |
191 | */ | 180 | */ |
192 | #define XFS_DIR2_DB_TO_DA(mp,db) xfs_dir2_db_to_da(mp, db) | ||
193 | static inline xfs_dablk_t | 181 | static inline xfs_dablk_t |
194 | xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) | 182 | xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) |
195 | { | 183 | { |
@@ -199,29 +187,25 @@ xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db) | |||
199 | /* | 187 | /* |
200 | * Convert byte in space to (DA) block | 188 | * Convert byte in space to (DA) block |
201 | */ | 189 | */ |
202 | #define XFS_DIR2_BYTE_TO_DA(mp,by) xfs_dir2_byte_to_da(mp, by) | ||
203 | static inline xfs_dablk_t | 190 | static inline xfs_dablk_t |
204 | xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) | 191 | xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by) |
205 | { | 192 | { |
206 | return XFS_DIR2_DB_TO_DA(mp, XFS_DIR2_BYTE_TO_DB(mp, by)); | 193 | return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by)); |
207 | } | 194 | } |
208 | 195 | ||
209 | /* | 196 | /* |
210 | * Convert block and offset to dataptr | 197 | * Convert block and offset to dataptr |
211 | */ | 198 | */ |
212 | #define XFS_DIR2_DB_OFF_TO_DATAPTR(mp,db,o) \ | ||
213 | xfs_dir2_db_off_to_dataptr(mp, db, o) | ||
214 | static inline xfs_dir2_dataptr_t | 199 | static inline xfs_dir2_dataptr_t |
215 | xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, | 200 | xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db, |
216 | xfs_dir2_data_aoff_t o) | 201 | xfs_dir2_data_aoff_t o) |
217 | { | 202 | { |
218 | return XFS_DIR2_BYTE_TO_DATAPTR(mp, XFS_DIR2_DB_OFF_TO_BYTE(mp, db, o)); | 203 | return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o)); |
219 | } | 204 | } |
220 | 205 | ||
221 | /* | 206 | /* |
222 | * Convert block (dablk) to block (DB) | 207 | * Convert block (dablk) to block (DB) |
223 | */ | 208 | */ |
224 | #define XFS_DIR2_DA_TO_DB(mp,da) xfs_dir2_da_to_db(mp, da) | ||
225 | static inline xfs_dir2_db_t | 209 | static inline xfs_dir2_db_t |
226 | xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) | 210 | xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) |
227 | { | 211 | { |
@@ -231,11 +215,10 @@ xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da) | |||
231 | /* | 215 | /* |
232 | * Convert block (dablk) to byte offset in space | 216 | * Convert block (dablk) to byte offset in space |
233 | */ | 217 | */ |
234 | #define XFS_DIR2_DA_TO_BYTE(mp,da) xfs_dir2_da_to_byte(mp, da) | ||
235 | static inline xfs_dir2_off_t | 218 | static inline xfs_dir2_off_t |
236 | xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) | 219 | xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) |
237 | { | 220 | { |
238 | return XFS_DIR2_DB_OFF_TO_BYTE(mp, XFS_DIR2_DA_TO_DB(mp, da), 0); | 221 | return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0); |
239 | } | 222 | } |
240 | 223 | ||
241 | /* | 224 | /* |
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c index d083c381993..91c61d9632c 100644 --- a/fs/xfs/xfs_dir2_node.c +++ b/fs/xfs/xfs_dir2_node.c | |||
@@ -136,14 +136,14 @@ xfs_dir2_leaf_to_node( | |||
136 | /* | 136 | /* |
137 | * Get the buffer for the new freespace block. | 137 | * Get the buffer for the new freespace block. |
138 | */ | 138 | */ |
139 | if ((error = xfs_da_get_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), -1, &fbp, | 139 | if ((error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), -1, &fbp, |
140 | XFS_DATA_FORK))) { | 140 | XFS_DATA_FORK))) { |
141 | return error; | 141 | return error; |
142 | } | 142 | } |
143 | ASSERT(fbp != NULL); | 143 | ASSERT(fbp != NULL); |
144 | free = fbp->data; | 144 | free = fbp->data; |
145 | leaf = lbp->data; | 145 | leaf = lbp->data; |
146 | ltp = XFS_DIR2_LEAF_TAIL_P(mp, leaf); | 146 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
147 | /* | 147 | /* |
148 | * Initialize the freespace block header. | 148 | * Initialize the freespace block header. |
149 | */ | 149 | */ |
@@ -155,7 +155,7 @@ xfs_dir2_leaf_to_node( | |||
155 | * Copy freespace entries from the leaf block to the new block. | 155 | * Copy freespace entries from the leaf block to the new block. |
156 | * Count active entries. | 156 | * Count active entries. |
157 | */ | 157 | */ |
158 | for (i = n = 0, from = XFS_DIR2_LEAF_BESTS_P(ltp), to = free->bests; | 158 | for (i = n = 0, from = xfs_dir2_leaf_bests_p(ltp), to = free->bests; |
159 | i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { | 159 | i < be32_to_cpu(ltp->bestcount); i++, from++, to++) { |
160 | if ((off = be16_to_cpu(*from)) != NULLDATAOFF) | 160 | if ((off = be16_to_cpu(*from)) != NULLDATAOFF) |
161 | n++; | 161 | n++; |
@@ -215,7 +215,7 @@ xfs_dir2_leafn_add( | |||
215 | * a compact. | 215 | * a compact. |
216 | */ | 216 | */ |
217 | 217 | ||
218 | if (be16_to_cpu(leaf->hdr.count) == XFS_DIR2_MAX_LEAF_ENTS(mp)) { | 218 | if (be16_to_cpu(leaf->hdr.count) == xfs_dir2_max_leaf_ents(mp)) { |
219 | if (!leaf->hdr.stale) | 219 | if (!leaf->hdr.stale) |
220 | return XFS_ERROR(ENOSPC); | 220 | return XFS_ERROR(ENOSPC); |
221 | compact = be16_to_cpu(leaf->hdr.stale) > 1; | 221 | compact = be16_to_cpu(leaf->hdr.stale) > 1; |
@@ -327,7 +327,7 @@ xfs_dir2_leafn_add( | |||
327 | * Insert the new entry, log everything. | 327 | * Insert the new entry, log everything. |
328 | */ | 328 | */ |
329 | lep->hashval = cpu_to_be32(args->hashval); | 329 | lep->hashval = cpu_to_be32(args->hashval); |
330 | lep->address = cpu_to_be32(XFS_DIR2_DB_OFF_TO_DATAPTR(mp, | 330 | lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, |
331 | args->blkno, args->index)); | 331 | args->blkno, args->index)); |
332 | xfs_dir2_leaf_log_header(tp, bp); | 332 | xfs_dir2_leaf_log_header(tp, bp); |
333 | xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); | 333 | xfs_dir2_leaf_log_ents(tp, bp, lfloglow, lfloghigh); |
@@ -352,7 +352,7 @@ xfs_dir2_leafn_check( | |||
352 | leaf = bp->data; | 352 | leaf = bp->data; |
353 | mp = dp->i_mount; | 353 | mp = dp->i_mount; |
354 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); | 354 | ASSERT(be16_to_cpu(leaf->hdr.info.magic) == XFS_DIR2_LEAFN_MAGIC); |
355 | ASSERT(be16_to_cpu(leaf->hdr.count) <= XFS_DIR2_MAX_LEAF_ENTS(mp)); | 355 | ASSERT(be16_to_cpu(leaf->hdr.count) <= xfs_dir2_max_leaf_ents(mp)); |
356 | for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { | 356 | for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { |
357 | if (i + 1 < be16_to_cpu(leaf->hdr.count)) { | 357 | if (i + 1 < be16_to_cpu(leaf->hdr.count)) { |
358 | ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= | 358 | ASSERT(be32_to_cpu(leaf->ents[i].hashval) <= |
@@ -440,7 +440,7 @@ xfs_dir2_leafn_lookup_int( | |||
440 | if (args->addname) { | 440 | if (args->addname) { |
441 | curfdb = curbp ? state->extrablk.blkno : -1; | 441 | curfdb = curbp ? state->extrablk.blkno : -1; |
442 | curdb = -1; | 442 | curdb = -1; |
443 | length = XFS_DIR2_DATA_ENTSIZE(args->namelen); | 443 | length = xfs_dir2_data_entsize(args->namelen); |
444 | if ((free = (curbp ? curbp->data : NULL))) | 444 | if ((free = (curbp ? curbp->data : NULL))) |
445 | ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); | 445 | ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); |
446 | } | 446 | } |
@@ -465,7 +465,7 @@ xfs_dir2_leafn_lookup_int( | |||
465 | /* | 465 | /* |
466 | * Pull the data block number from the entry. | 466 | * Pull the data block number from the entry. |
467 | */ | 467 | */ |
468 | newdb = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); | 468 | newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); |
469 | /* | 469 | /* |
470 | * For addname, we're looking for a place to put the new entry. | 470 | * For addname, we're looking for a place to put the new entry. |
471 | * We want to use a data block with an entry of equal | 471 | * We want to use a data block with an entry of equal |
@@ -482,7 +482,7 @@ xfs_dir2_leafn_lookup_int( | |||
482 | * Convert the data block to the free block | 482 | * Convert the data block to the free block |
483 | * holding its freespace information. | 483 | * holding its freespace information. |
484 | */ | 484 | */ |
485 | newfdb = XFS_DIR2_DB_TO_FDB(mp, newdb); | 485 | newfdb = xfs_dir2_db_to_fdb(mp, newdb); |
486 | /* | 486 | /* |
487 | * If it's not the one we have in hand, | 487 | * If it's not the one we have in hand, |
488 | * read it in. | 488 | * read it in. |
@@ -497,7 +497,7 @@ xfs_dir2_leafn_lookup_int( | |||
497 | * Read the free block. | 497 | * Read the free block. |
498 | */ | 498 | */ |
499 | if ((error = xfs_da_read_buf(tp, dp, | 499 | if ((error = xfs_da_read_buf(tp, dp, |
500 | XFS_DIR2_DB_TO_DA(mp, | 500 | xfs_dir2_db_to_da(mp, |
501 | newfdb), | 501 | newfdb), |
502 | -1, &curbp, | 502 | -1, &curbp, |
503 | XFS_DATA_FORK))) { | 503 | XFS_DATA_FORK))) { |
@@ -517,7 +517,7 @@ xfs_dir2_leafn_lookup_int( | |||
517 | /* | 517 | /* |
518 | * Get the index for our entry. | 518 | * Get the index for our entry. |
519 | */ | 519 | */ |
520 | fi = XFS_DIR2_DB_TO_FDINDEX(mp, curdb); | 520 | fi = xfs_dir2_db_to_fdindex(mp, curdb); |
521 | /* | 521 | /* |
522 | * If it has room, return it. | 522 | * If it has room, return it. |
523 | */ | 523 | */ |
@@ -561,7 +561,7 @@ xfs_dir2_leafn_lookup_int( | |||
561 | */ | 561 | */ |
562 | if ((error = | 562 | if ((error = |
563 | xfs_da_read_buf(tp, dp, | 563 | xfs_da_read_buf(tp, dp, |
564 | XFS_DIR2_DB_TO_DA(mp, newdb), -1, | 564 | xfs_dir2_db_to_da(mp, newdb), -1, |
565 | &curbp, XFS_DATA_FORK))) { | 565 | &curbp, XFS_DATA_FORK))) { |
566 | return error; | 566 | return error; |
567 | } | 567 | } |
@@ -573,7 +573,7 @@ xfs_dir2_leafn_lookup_int( | |||
573 | */ | 573 | */ |
574 | dep = (xfs_dir2_data_entry_t *) | 574 | dep = (xfs_dir2_data_entry_t *) |
575 | ((char *)curbp->data + | 575 | ((char *)curbp->data + |
576 | XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address))); | 576 | xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
577 | /* | 577 | /* |
578 | * Compare the entry, return it if it matches. | 578 | * Compare the entry, return it if it matches. |
579 | */ | 579 | */ |
@@ -876,9 +876,9 @@ xfs_dir2_leafn_remove( | |||
876 | /* | 876 | /* |
877 | * Extract the data block and offset from the entry. | 877 | * Extract the data block and offset from the entry. |
878 | */ | 878 | */ |
879 | db = XFS_DIR2_DATAPTR_TO_DB(mp, be32_to_cpu(lep->address)); | 879 | db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); |
880 | ASSERT(dblk->blkno == db); | 880 | ASSERT(dblk->blkno == db); |
881 | off = XFS_DIR2_DATAPTR_TO_OFF(mp, be32_to_cpu(lep->address)); | 881 | off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); |
882 | ASSERT(dblk->index == off); | 882 | ASSERT(dblk->index == off); |
883 | /* | 883 | /* |
884 | * Kill the leaf entry by marking it stale. | 884 | * Kill the leaf entry by marking it stale. |
@@ -898,7 +898,7 @@ xfs_dir2_leafn_remove( | |||
898 | longest = be16_to_cpu(data->hdr.bestfree[0].length); | 898 | longest = be16_to_cpu(data->hdr.bestfree[0].length); |
899 | needlog = needscan = 0; | 899 | needlog = needscan = 0; |
900 | xfs_dir2_data_make_free(tp, dbp, off, | 900 | xfs_dir2_data_make_free(tp, dbp, off, |
901 | XFS_DIR2_DATA_ENTSIZE(dep->namelen), &needlog, &needscan); | 901 | xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); |
902 | /* | 902 | /* |
903 | * Rescan the data block freespaces for bestfree. | 903 | * Rescan the data block freespaces for bestfree. |
904 | * Log the data block header if needed. | 904 | * Log the data block header if needed. |
@@ -924,8 +924,8 @@ xfs_dir2_leafn_remove( | |||
924 | * Convert the data block number to a free block, | 924 | * Convert the data block number to a free block, |
925 | * read in the free block. | 925 | * read in the free block. |
926 | */ | 926 | */ |
927 | fdb = XFS_DIR2_DB_TO_FDB(mp, db); | 927 | fdb = xfs_dir2_db_to_fdb(mp, db); |
928 | if ((error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, fdb), | 928 | if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, fdb), |
929 | -1, &fbp, XFS_DATA_FORK))) { | 929 | -1, &fbp, XFS_DATA_FORK))) { |
930 | return error; | 930 | return error; |
931 | } | 931 | } |
@@ -937,7 +937,7 @@ xfs_dir2_leafn_remove( | |||
937 | /* | 937 | /* |
938 | * Calculate which entry we need to fix. | 938 | * Calculate which entry we need to fix. |
939 | */ | 939 | */ |
940 | findex = XFS_DIR2_DB_TO_FDINDEX(mp, db); | 940 | findex = xfs_dir2_db_to_fdindex(mp, db); |
941 | longest = be16_to_cpu(data->hdr.bestfree[0].length); | 941 | longest = be16_to_cpu(data->hdr.bestfree[0].length); |
942 | /* | 942 | /* |
943 | * If the data block is now empty we can get rid of it | 943 | * If the data block is now empty we can get rid of it |
@@ -1073,7 +1073,7 @@ xfs_dir2_leafn_split( | |||
1073 | /* | 1073 | /* |
1074 | * Initialize the new leaf block. | 1074 | * Initialize the new leaf block. |
1075 | */ | 1075 | */ |
1076 | error = xfs_dir2_leaf_init(args, XFS_DIR2_DA_TO_DB(mp, blkno), | 1076 | error = xfs_dir2_leaf_init(args, xfs_dir2_da_to_db(mp, blkno), |
1077 | &newblk->bp, XFS_DIR2_LEAFN_MAGIC); | 1077 | &newblk->bp, XFS_DIR2_LEAFN_MAGIC); |
1078 | if (error) { | 1078 | if (error) { |
1079 | return error; | 1079 | return error; |
@@ -1385,7 +1385,7 @@ xfs_dir2_node_addname_int( | |||
1385 | dp = args->dp; | 1385 | dp = args->dp; |
1386 | mp = dp->i_mount; | 1386 | mp = dp->i_mount; |
1387 | tp = args->trans; | 1387 | tp = args->trans; |
1388 | length = XFS_DIR2_DATA_ENTSIZE(args->namelen); | 1388 | length = xfs_dir2_data_entsize(args->namelen); |
1389 | /* | 1389 | /* |
1390 | * If we came in with a freespace block that means that lookup | 1390 | * If we came in with a freespace block that means that lookup |
1391 | * found an entry with our hash value. This is the freespace | 1391 | * found an entry with our hash value. This is the freespace |
@@ -1438,7 +1438,7 @@ xfs_dir2_node_addname_int( | |||
1438 | 1438 | ||
1439 | if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) | 1439 | if ((error = xfs_bmap_last_offset(tp, dp, &fo, XFS_DATA_FORK))) |
1440 | return error; | 1440 | return error; |
1441 | lastfbno = XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo); | 1441 | lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); |
1442 | fbno = ifbno; | 1442 | fbno = ifbno; |
1443 | } | 1443 | } |
1444 | /* | 1444 | /* |
@@ -1474,7 +1474,7 @@ xfs_dir2_node_addname_int( | |||
1474 | * to avoid it. | 1474 | * to avoid it. |
1475 | */ | 1475 | */ |
1476 | if ((error = xfs_da_read_buf(tp, dp, | 1476 | if ((error = xfs_da_read_buf(tp, dp, |
1477 | XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, | 1477 | xfs_dir2_db_to_da(mp, fbno), -2, &fbp, |
1478 | XFS_DATA_FORK))) { | 1478 | XFS_DATA_FORK))) { |
1479 | return error; | 1479 | return error; |
1480 | } | 1480 | } |
@@ -1550,9 +1550,9 @@ xfs_dir2_node_addname_int( | |||
1550 | * Get the freespace block corresponding to the data block | 1550 | * Get the freespace block corresponding to the data block |
1551 | * that was just allocated. | 1551 | * that was just allocated. |
1552 | */ | 1552 | */ |
1553 | fbno = XFS_DIR2_DB_TO_FDB(mp, dbno); | 1553 | fbno = xfs_dir2_db_to_fdb(mp, dbno); |
1554 | if (unlikely(error = xfs_da_read_buf(tp, dp, | 1554 | if (unlikely(error = xfs_da_read_buf(tp, dp, |
1555 | XFS_DIR2_DB_TO_DA(mp, fbno), -2, &fbp, | 1555 | xfs_dir2_db_to_da(mp, fbno), -2, &fbp, |
1556 | XFS_DATA_FORK))) { | 1556 | XFS_DATA_FORK))) { |
1557 | xfs_da_buf_done(dbp); | 1557 | xfs_da_buf_done(dbp); |
1558 | return error; | 1558 | return error; |
@@ -1567,14 +1567,14 @@ xfs_dir2_node_addname_int( | |||
1567 | return error; | 1567 | return error; |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | if (unlikely(XFS_DIR2_DB_TO_FDB(mp, dbno) != fbno)) { | 1570 | if (unlikely(xfs_dir2_db_to_fdb(mp, dbno) != fbno)) { |
1571 | cmn_err(CE_ALERT, | 1571 | cmn_err(CE_ALERT, |
1572 | "xfs_dir2_node_addname_int: dir ino " | 1572 | "xfs_dir2_node_addname_int: dir ino " |
1573 | "%llu needed freesp block %lld for\n" | 1573 | "%llu needed freesp block %lld for\n" |
1574 | " data block %lld, got %lld\n" | 1574 | " data block %lld, got %lld\n" |
1575 | " ifbno %llu lastfbno %d\n", | 1575 | " ifbno %llu lastfbno %d\n", |
1576 | (unsigned long long)dp->i_ino, | 1576 | (unsigned long long)dp->i_ino, |
1577 | (long long)XFS_DIR2_DB_TO_FDB(mp, dbno), | 1577 | (long long)xfs_dir2_db_to_fdb(mp, dbno), |
1578 | (long long)dbno, (long long)fbno, | 1578 | (long long)dbno, (long long)fbno, |
1579 | (unsigned long long)ifbno, lastfbno); | 1579 | (unsigned long long)ifbno, lastfbno); |
1580 | if (fblk) { | 1580 | if (fblk) { |
@@ -1598,7 +1598,7 @@ xfs_dir2_node_addname_int( | |||
1598 | * Get a buffer for the new block. | 1598 | * Get a buffer for the new block. |
1599 | */ | 1599 | */ |
1600 | if ((error = xfs_da_get_buf(tp, dp, | 1600 | if ((error = xfs_da_get_buf(tp, dp, |
1601 | XFS_DIR2_DB_TO_DA(mp, fbno), | 1601 | xfs_dir2_db_to_da(mp, fbno), |
1602 | -1, &fbp, XFS_DATA_FORK))) { | 1602 | -1, &fbp, XFS_DATA_FORK))) { |
1603 | return error; | 1603 | return error; |
1604 | } | 1604 | } |
@@ -1623,7 +1623,7 @@ xfs_dir2_node_addname_int( | |||
1623 | /* | 1623 | /* |
1624 | * Set the freespace block index from the data block number. | 1624 | * Set the freespace block index from the data block number. |
1625 | */ | 1625 | */ |
1626 | findex = XFS_DIR2_DB_TO_FDINDEX(mp, dbno); | 1626 | findex = xfs_dir2_db_to_fdindex(mp, dbno); |
1627 | /* | 1627 | /* |
1628 | * If it's after the end of the current entries in the | 1628 | * If it's after the end of the current entries in the |
1629 | * freespace block, extend that table. | 1629 | * freespace block, extend that table. |
@@ -1669,7 +1669,7 @@ xfs_dir2_node_addname_int( | |||
1669 | * Read the data block in. | 1669 | * Read the data block in. |
1670 | */ | 1670 | */ |
1671 | if (unlikely( | 1671 | if (unlikely( |
1672 | error = xfs_da_read_buf(tp, dp, XFS_DIR2_DB_TO_DA(mp, dbno), | 1672 | error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno), |
1673 | -1, &dbp, XFS_DATA_FORK))) { | 1673 | -1, &dbp, XFS_DATA_FORK))) { |
1674 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) | 1674 | if ((fblk == NULL || fblk->bp == NULL) && fbp != NULL) |
1675 | xfs_da_buf_done(fbp); | 1675 | xfs_da_buf_done(fbp); |
@@ -1698,7 +1698,7 @@ xfs_dir2_node_addname_int( | |||
1698 | dep->inumber = cpu_to_be64(args->inumber); | 1698 | dep->inumber = cpu_to_be64(args->inumber); |
1699 | dep->namelen = args->namelen; | 1699 | dep->namelen = args->namelen; |
1700 | memcpy(dep->name, args->name, dep->namelen); | 1700 | memcpy(dep->name, args->name, dep->namelen); |
1701 | tagp = XFS_DIR2_DATA_ENTRY_TAG_P(dep); | 1701 | tagp = xfs_dir2_data_entry_tag_p(dep); |
1702 | *tagp = cpu_to_be16((char *)dep - (char *)data); | 1702 | *tagp = cpu_to_be16((char *)dep - (char *)data); |
1703 | xfs_dir2_data_log_entry(tp, dbp, dep); | 1703 | xfs_dir2_data_log_entry(tp, dbp, dep); |
1704 | /* | 1704 | /* |
@@ -1904,7 +1904,7 @@ xfs_dir2_node_replace( | |||
1904 | ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); | 1904 | ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); |
1905 | dep = (xfs_dir2_data_entry_t *) | 1905 | dep = (xfs_dir2_data_entry_t *) |
1906 | ((char *)data + | 1906 | ((char *)data + |
1907 | XFS_DIR2_DATAPTR_TO_OFF(state->mp, be32_to_cpu(lep->address))); | 1907 | xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); |
1908 | ASSERT(inum != be64_to_cpu(dep->inumber)); | 1908 | ASSERT(inum != be64_to_cpu(dep->inumber)); |
1909 | /* | 1909 | /* |
1910 | * Fill in the new inode number and log the entry. | 1910 | * Fill in the new inode number and log the entry. |
@@ -1980,7 +1980,7 @@ xfs_dir2_node_trim_free( | |||
1980 | * Blow the block away. | 1980 | * Blow the block away. |
1981 | */ | 1981 | */ |
1982 | if ((error = | 1982 | if ((error = |
1983 | xfs_dir2_shrink_inode(args, XFS_DIR2_DA_TO_DB(mp, (xfs_dablk_t)fo), | 1983 | xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), |
1984 | bp))) { | 1984 | bp))) { |
1985 | /* | 1985 | /* |
1986 | * Can't fail with ENOSPC since that only happens with no | 1986 | * Can't fail with ENOSPC since that only happens with no |
diff --git a/fs/xfs/xfs_dir2_node.h b/fs/xfs/xfs_dir2_node.h index c7c870ee785..dde72db3d69 100644 --- a/fs/xfs/xfs_dir2_node.h +++ b/fs/xfs/xfs_dir2_node.h | |||
@@ -36,7 +36,7 @@ struct xfs_trans; | |||
36 | #define XFS_DIR2_FREE_SPACE 2 | 36 | #define XFS_DIR2_FREE_SPACE 2 |
37 | #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) | 37 | #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) |
38 | #define XFS_DIR2_FREE_FIRSTDB(mp) \ | 38 | #define XFS_DIR2_FREE_FIRSTDB(mp) \ |
39 | XFS_DIR2_BYTE_TO_DB(mp, XFS_DIR2_FREE_OFFSET) | 39 | xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET) |
40 | 40 | ||
41 | #define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */ | 41 | #define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F */ |
42 | 42 | ||
@@ -60,7 +60,6 @@ typedef struct xfs_dir2_free { | |||
60 | /* | 60 | /* |
61 | * Convert data space db to the corresponding free db. | 61 | * Convert data space db to the corresponding free db. |
62 | */ | 62 | */ |
63 | #define XFS_DIR2_DB_TO_FDB(mp,db) xfs_dir2_db_to_fdb(mp, db) | ||
64 | static inline xfs_dir2_db_t | 63 | static inline xfs_dir2_db_t |
65 | xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) | 64 | xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) |
66 | { | 65 | { |
@@ -70,7 +69,6 @@ xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) | |||
70 | /* | 69 | /* |
71 | * Convert data space db to the corresponding index in a free db. | 70 | * Convert data space db to the corresponding index in a free db. |
72 | */ | 71 | */ |
73 | #define XFS_DIR2_DB_TO_FDINDEX(mp,db) xfs_dir2_db_to_fdindex(mp, db) | ||
74 | static inline int | 72 | static inline int |
75 | xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) | 73 | xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) |
76 | { | 74 | { |
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c index 0cd77b17bf9..38fc4f22b76 100644 --- a/fs/xfs/xfs_dir2_sf.c +++ b/fs/xfs/xfs_dir2_sf.c | |||
@@ -89,8 +89,8 @@ xfs_dir2_block_sfsize( | |||
89 | mp = dp->i_mount; | 89 | mp = dp->i_mount; |
90 | 90 | ||
91 | count = i8count = namelen = 0; | 91 | count = i8count = namelen = 0; |
92 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 92 | btp = xfs_dir2_block_tail_p(mp, block); |
93 | blp = XFS_DIR2_BLOCK_LEAF_P(btp); | 93 | blp = xfs_dir2_block_leaf_p(btp); |
94 | 94 | ||
95 | /* | 95 | /* |
96 | * Iterate over the block's data entries by using the leaf pointers. | 96 | * Iterate over the block's data entries by using the leaf pointers. |
@@ -102,7 +102,7 @@ xfs_dir2_block_sfsize( | |||
102 | * Calculate the pointer to the entry at hand. | 102 | * Calculate the pointer to the entry at hand. |
103 | */ | 103 | */ |
104 | dep = (xfs_dir2_data_entry_t *) | 104 | dep = (xfs_dir2_data_entry_t *) |
105 | ((char *)block + XFS_DIR2_DATAPTR_TO_OFF(mp, addr)); | 105 | ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); |
106 | /* | 106 | /* |
107 | * Detect . and .., so we can special-case them. | 107 | * Detect . and .., so we can special-case them. |
108 | * . is not included in sf directories. | 108 | * . is not included in sf directories. |
@@ -124,7 +124,7 @@ xfs_dir2_block_sfsize( | |||
124 | /* | 124 | /* |
125 | * Calculate the new size, see if we should give up yet. | 125 | * Calculate the new size, see if we should give up yet. |
126 | */ | 126 | */ |
127 | size = XFS_DIR2_SF_HDR_SIZE(i8count) + /* header */ | 127 | size = xfs_dir2_sf_hdr_size(i8count) + /* header */ |
128 | count + /* namelen */ | 128 | count + /* namelen */ |
129 | count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */ | 129 | count * (uint)sizeof(xfs_dir2_sf_off_t) + /* offset */ |
130 | namelen + /* name */ | 130 | namelen + /* name */ |
@@ -139,7 +139,7 @@ xfs_dir2_block_sfsize( | |||
139 | */ | 139 | */ |
140 | sfhp->count = count; | 140 | sfhp->count = count; |
141 | sfhp->i8count = i8count; | 141 | sfhp->i8count = i8count; |
142 | XFS_DIR2_SF_PUT_INUMBER((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); | 142 | xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); |
143 | return size; | 143 | return size; |
144 | } | 144 | } |
145 | 145 | ||
@@ -199,15 +199,15 @@ xfs_dir2_block_to_sf( | |||
199 | * Copy the header into the newly allocate local space. | 199 | * Copy the header into the newly allocate local space. |
200 | */ | 200 | */ |
201 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 201 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
202 | memcpy(sfp, sfhp, XFS_DIR2_SF_HDR_SIZE(sfhp->i8count)); | 202 | memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); |
203 | dp->i_d.di_size = size; | 203 | dp->i_d.di_size = size; |
204 | /* | 204 | /* |
205 | * Set up to loop over the block's entries. | 205 | * Set up to loop over the block's entries. |
206 | */ | 206 | */ |
207 | btp = XFS_DIR2_BLOCK_TAIL_P(mp, block); | 207 | btp = xfs_dir2_block_tail_p(mp, block); |
208 | ptr = (char *)block->u; | 208 | ptr = (char *)block->u; |
209 | endptr = (char *)XFS_DIR2_BLOCK_LEAF_P(btp); | 209 | endptr = (char *)xfs_dir2_block_leaf_p(btp); |
210 | sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 210 | sfep = xfs_dir2_sf_firstentry(sfp); |
211 | /* | 211 | /* |
212 | * Loop over the active and unused entries. | 212 | * Loop over the active and unused entries. |
213 | * Stop when we reach the leaf/tail portion of the block. | 213 | * Stop when we reach the leaf/tail portion of the block. |
@@ -233,22 +233,22 @@ xfs_dir2_block_to_sf( | |||
233 | else if (dep->namelen == 2 && | 233 | else if (dep->namelen == 2 && |
234 | dep->name[0] == '.' && dep->name[1] == '.') | 234 | dep->name[0] == '.' && dep->name[1] == '.') |
235 | ASSERT(be64_to_cpu(dep->inumber) == | 235 | ASSERT(be64_to_cpu(dep->inumber) == |
236 | XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent)); | 236 | xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); |
237 | /* | 237 | /* |
238 | * Normal entry, copy it into shortform. | 238 | * Normal entry, copy it into shortform. |
239 | */ | 239 | */ |
240 | else { | 240 | else { |
241 | sfep->namelen = dep->namelen; | 241 | sfep->namelen = dep->namelen; |
242 | XFS_DIR2_SF_PUT_OFFSET(sfep, | 242 | xfs_dir2_sf_put_offset(sfep, |
243 | (xfs_dir2_data_aoff_t) | 243 | (xfs_dir2_data_aoff_t) |
244 | ((char *)dep - (char *)block)); | 244 | ((char *)dep - (char *)block)); |
245 | memcpy(sfep->name, dep->name, dep->namelen); | 245 | memcpy(sfep->name, dep->name, dep->namelen); |
246 | temp = be64_to_cpu(dep->inumber); | 246 | temp = be64_to_cpu(dep->inumber); |
247 | XFS_DIR2_SF_PUT_INUMBER(sfp, &temp, | 247 | xfs_dir2_sf_put_inumber(sfp, &temp, |
248 | XFS_DIR2_SF_INUMBERP(sfep)); | 248 | xfs_dir2_sf_inumberp(sfep)); |
249 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); | 249 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); |
250 | } | 250 | } |
251 | ptr += XFS_DIR2_DATA_ENTSIZE(dep->namelen); | 251 | ptr += xfs_dir2_data_entsize(dep->namelen); |
252 | } | 252 | } |
253 | ASSERT((char *)sfep - (char *)sfp == size); | 253 | ASSERT((char *)sfep - (char *)sfp == size); |
254 | xfs_dir2_sf_check(args); | 254 | xfs_dir2_sf_check(args); |
@@ -294,11 +294,11 @@ xfs_dir2_sf_addname( | |||
294 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 294 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
295 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 295 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
296 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 296 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
297 | ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 297 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
298 | /* | 298 | /* |
299 | * Compute entry (and change in) size. | 299 | * Compute entry (and change in) size. |
300 | */ | 300 | */ |
301 | add_entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen); | 301 | add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); |
302 | incr_isize = add_entsize; | 302 | incr_isize = add_entsize; |
303 | objchange = 0; | 303 | objchange = 0; |
304 | #if XFS_BIG_INUMS | 304 | #if XFS_BIG_INUMS |
@@ -392,7 +392,7 @@ xfs_dir2_sf_addname_easy( | |||
392 | /* | 392 | /* |
393 | * Grow the in-inode space. | 393 | * Grow the in-inode space. |
394 | */ | 394 | */ |
395 | xfs_idata_realloc(dp, XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen), | 395 | xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), |
396 | XFS_DATA_FORK); | 396 | XFS_DATA_FORK); |
397 | /* | 397 | /* |
398 | * Need to set up again due to realloc of the inode data. | 398 | * Need to set up again due to realloc of the inode data. |
@@ -403,10 +403,10 @@ xfs_dir2_sf_addname_easy( | |||
403 | * Fill in the new entry. | 403 | * Fill in the new entry. |
404 | */ | 404 | */ |
405 | sfep->namelen = args->namelen; | 405 | sfep->namelen = args->namelen; |
406 | XFS_DIR2_SF_PUT_OFFSET(sfep, offset); | 406 | xfs_dir2_sf_put_offset(sfep, offset); |
407 | memcpy(sfep->name, args->name, sfep->namelen); | 407 | memcpy(sfep->name, args->name, sfep->namelen); |
408 | XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, | 408 | xfs_dir2_sf_put_inumber(sfp, &args->inumber, |
409 | XFS_DIR2_SF_INUMBERP(sfep)); | 409 | xfs_dir2_sf_inumberp(sfep)); |
410 | /* | 410 | /* |
411 | * Update the header and inode. | 411 | * Update the header and inode. |
412 | */ | 412 | */ |
@@ -463,14 +463,14 @@ xfs_dir2_sf_addname_hard( | |||
463 | * If it's going to end up at the end then oldsfep will point there. | 463 | * If it's going to end up at the end then oldsfep will point there. |
464 | */ | 464 | */ |
465 | for (offset = XFS_DIR2_DATA_FIRST_OFFSET, | 465 | for (offset = XFS_DIR2_DATA_FIRST_OFFSET, |
466 | oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp), | 466 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), |
467 | add_datasize = XFS_DIR2_DATA_ENTSIZE(args->namelen), | 467 | add_datasize = xfs_dir2_data_entsize(args->namelen), |
468 | eof = (char *)oldsfep == &buf[old_isize]; | 468 | eof = (char *)oldsfep == &buf[old_isize]; |
469 | !eof; | 469 | !eof; |
470 | offset = new_offset + XFS_DIR2_DATA_ENTSIZE(oldsfep->namelen), | 470 | offset = new_offset + xfs_dir2_data_entsize(oldsfep->namelen), |
471 | oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep), | 471 | oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep), |
472 | eof = (char *)oldsfep == &buf[old_isize]) { | 472 | eof = (char *)oldsfep == &buf[old_isize]) { |
473 | new_offset = XFS_DIR2_SF_GET_OFFSET(oldsfep); | 473 | new_offset = xfs_dir2_sf_get_offset(oldsfep); |
474 | if (offset + add_datasize <= new_offset) | 474 | if (offset + add_datasize <= new_offset) |
475 | break; | 475 | break; |
476 | } | 476 | } |
@@ -495,10 +495,10 @@ xfs_dir2_sf_addname_hard( | |||
495 | * Fill in the new entry, and update the header counts. | 495 | * Fill in the new entry, and update the header counts. |
496 | */ | 496 | */ |
497 | sfep->namelen = args->namelen; | 497 | sfep->namelen = args->namelen; |
498 | XFS_DIR2_SF_PUT_OFFSET(sfep, offset); | 498 | xfs_dir2_sf_put_offset(sfep, offset); |
499 | memcpy(sfep->name, args->name, sfep->namelen); | 499 | memcpy(sfep->name, args->name, sfep->namelen); |
500 | XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, | 500 | xfs_dir2_sf_put_inumber(sfp, &args->inumber, |
501 | XFS_DIR2_SF_INUMBERP(sfep)); | 501 | xfs_dir2_sf_inumberp(sfep)); |
502 | sfp->hdr.count++; | 502 | sfp->hdr.count++; |
503 | #if XFS_BIG_INUMS | 503 | #if XFS_BIG_INUMS |
504 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) | 504 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) |
@@ -508,7 +508,7 @@ xfs_dir2_sf_addname_hard( | |||
508 | * If there's more left to copy, do that. | 508 | * If there's more left to copy, do that. |
509 | */ | 509 | */ |
510 | if (!eof) { | 510 | if (!eof) { |
511 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); | 511 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); |
512 | memcpy(sfep, oldsfep, old_isize - nbytes); | 512 | memcpy(sfep, oldsfep, old_isize - nbytes); |
513 | } | 513 | } |
514 | kmem_free(buf, old_isize); | 514 | kmem_free(buf, old_isize); |
@@ -544,9 +544,9 @@ xfs_dir2_sf_addname_pick( | |||
544 | mp = dp->i_mount; | 544 | mp = dp->i_mount; |
545 | 545 | ||
546 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 546 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
547 | size = XFS_DIR2_DATA_ENTSIZE(args->namelen); | 547 | size = xfs_dir2_data_entsize(args->namelen); |
548 | offset = XFS_DIR2_DATA_FIRST_OFFSET; | 548 | offset = XFS_DIR2_DATA_FIRST_OFFSET; |
549 | sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 549 | sfep = xfs_dir2_sf_firstentry(sfp); |
550 | holefit = 0; | 550 | holefit = 0; |
551 | /* | 551 | /* |
552 | * Loop over sf entries. | 552 | * Loop over sf entries. |
@@ -555,10 +555,10 @@ xfs_dir2_sf_addname_pick( | |||
555 | */ | 555 | */ |
556 | for (i = 0; i < sfp->hdr.count; i++) { | 556 | for (i = 0; i < sfp->hdr.count; i++) { |
557 | if (!holefit) | 557 | if (!holefit) |
558 | holefit = offset + size <= XFS_DIR2_SF_GET_OFFSET(sfep); | 558 | holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); |
559 | offset = XFS_DIR2_SF_GET_OFFSET(sfep) + | 559 | offset = xfs_dir2_sf_get_offset(sfep) + |
560 | XFS_DIR2_DATA_ENTSIZE(sfep->namelen); | 560 | xfs_dir2_data_entsize(sfep->namelen); |
561 | sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep); | 561 | sfep = xfs_dir2_sf_nextentry(sfp, sfep); |
562 | } | 562 | } |
563 | /* | 563 | /* |
564 | * Calculate data bytes used excluding the new entry, if this | 564 | * Calculate data bytes used excluding the new entry, if this |
@@ -617,18 +617,18 @@ xfs_dir2_sf_check( | |||
617 | 617 | ||
618 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 618 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
619 | offset = XFS_DIR2_DATA_FIRST_OFFSET; | 619 | offset = XFS_DIR2_DATA_FIRST_OFFSET; |
620 | ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); | 620 | ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); |
621 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; | 621 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; |
622 | 622 | ||
623 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 623 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
624 | i < sfp->hdr.count; | 624 | i < sfp->hdr.count; |
625 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { | 625 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { |
626 | ASSERT(XFS_DIR2_SF_GET_OFFSET(sfep) >= offset); | 626 | ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); |
627 | ino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep)); | 627 | ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); |
628 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; | 628 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; |
629 | offset = | 629 | offset = |
630 | XFS_DIR2_SF_GET_OFFSET(sfep) + | 630 | xfs_dir2_sf_get_offset(sfep) + |
631 | XFS_DIR2_DATA_ENTSIZE(sfep->namelen); | 631 | xfs_dir2_data_entsize(sfep->namelen); |
632 | } | 632 | } |
633 | ASSERT(i8count == sfp->hdr.i8count); | 633 | ASSERT(i8count == sfp->hdr.i8count); |
634 | ASSERT(XFS_BIG_INUMS || i8count == 0); | 634 | ASSERT(XFS_BIG_INUMS || i8count == 0); |
@@ -671,7 +671,7 @@ xfs_dir2_sf_create( | |||
671 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); | 671 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
672 | ASSERT(dp->i_df.if_bytes == 0); | 672 | ASSERT(dp->i_df.if_bytes == 0); |
673 | i8count = pino > XFS_DIR2_MAX_SHORT_INUM; | 673 | i8count = pino > XFS_DIR2_MAX_SHORT_INUM; |
674 | size = XFS_DIR2_SF_HDR_SIZE(i8count); | 674 | size = xfs_dir2_sf_hdr_size(i8count); |
675 | /* | 675 | /* |
676 | * Make a buffer for the data. | 676 | * Make a buffer for the data. |
677 | */ | 677 | */ |
@@ -684,7 +684,7 @@ xfs_dir2_sf_create( | |||
684 | /* | 684 | /* |
685 | * Now can put in the inode number, since i8count is set. | 685 | * Now can put in the inode number, since i8count is set. |
686 | */ | 686 | */ |
687 | XFS_DIR2_SF_PUT_INUMBER(sfp, &pino, &sfp->hdr.parent); | 687 | xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); |
688 | sfp->hdr.count = 0; | 688 | sfp->hdr.count = 0; |
689 | dp->i_d.di_size = size; | 689 | dp->i_d.di_size = size; |
690 | xfs_dir2_sf_check(args); | 690 | xfs_dir2_sf_check(args); |
@@ -727,12 +727,12 @@ xfs_dir2_sf_getdents( | |||
727 | 727 | ||
728 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 728 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
729 | 729 | ||
730 | ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 730 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
731 | 731 | ||
732 | /* | 732 | /* |
733 | * If the block number in the offset is out of range, we're done. | 733 | * If the block number in the offset is out of range, we're done. |
734 | */ | 734 | */ |
735 | if (XFS_DIR2_DATAPTR_TO_DB(mp, dir_offset) > mp->m_dirdatablk) { | 735 | if (xfs_dir2_dataptr_to_db(mp, dir_offset) > mp->m_dirdatablk) { |
736 | *eofp = 1; | 736 | *eofp = 1; |
737 | return 0; | 737 | return 0; |
738 | } | 738 | } |
@@ -747,9 +747,9 @@ xfs_dir2_sf_getdents( | |||
747 | * Put . entry unless we're starting past it. | 747 | * Put . entry unless we're starting past it. |
748 | */ | 748 | */ |
749 | if (dir_offset <= | 749 | if (dir_offset <= |
750 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 750 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
751 | XFS_DIR2_DATA_DOT_OFFSET)) { | 751 | XFS_DIR2_DATA_DOT_OFFSET)) { |
752 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, 0, | 752 | p.cook = xfs_dir2_db_off_to_dataptr(mp, 0, |
753 | XFS_DIR2_DATA_DOTDOT_OFFSET); | 753 | XFS_DIR2_DATA_DOTDOT_OFFSET); |
754 | p.ino = dp->i_ino; | 754 | p.ino = dp->i_ino; |
755 | #if XFS_BIG_INUMS | 755 | #if XFS_BIG_INUMS |
@@ -762,7 +762,7 @@ xfs_dir2_sf_getdents( | |||
762 | 762 | ||
763 | if (!p.done) { | 763 | if (!p.done) { |
764 | uio->uio_offset = | 764 | uio->uio_offset = |
765 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 765 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
766 | XFS_DIR2_DATA_DOT_OFFSET); | 766 | XFS_DIR2_DATA_DOT_OFFSET); |
767 | return error; | 767 | return error; |
768 | } | 768 | } |
@@ -772,11 +772,11 @@ xfs_dir2_sf_getdents( | |||
772 | * Put .. entry unless we're starting past it. | 772 | * Put .. entry unless we're starting past it. |
773 | */ | 773 | */ |
774 | if (dir_offset <= | 774 | if (dir_offset <= |
775 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 775 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
776 | XFS_DIR2_DATA_DOTDOT_OFFSET)) { | 776 | XFS_DIR2_DATA_DOTDOT_OFFSET)) { |
777 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 777 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
778 | XFS_DIR2_DATA_FIRST_OFFSET); | 778 | XFS_DIR2_DATA_FIRST_OFFSET); |
779 | p.ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); | 779 | p.ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); |
780 | #if XFS_BIG_INUMS | 780 | #if XFS_BIG_INUMS |
781 | p.ino += mp->m_inoadd; | 781 | p.ino += mp->m_inoadd; |
782 | #endif | 782 | #endif |
@@ -787,7 +787,7 @@ xfs_dir2_sf_getdents( | |||
787 | 787 | ||
788 | if (!p.done) { | 788 | if (!p.done) { |
789 | uio->uio_offset = | 789 | uio->uio_offset = |
790 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 790 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
791 | XFS_DIR2_DATA_DOTDOT_OFFSET); | 791 | XFS_DIR2_DATA_DOTDOT_OFFSET); |
792 | return error; | 792 | return error; |
793 | } | 793 | } |
@@ -796,23 +796,23 @@ xfs_dir2_sf_getdents( | |||
796 | /* | 796 | /* |
797 | * Loop while there are more entries and put'ing works. | 797 | * Loop while there are more entries and put'ing works. |
798 | */ | 798 | */ |
799 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 799 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
800 | i < sfp->hdr.count; | 800 | i < sfp->hdr.count; |
801 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { | 801 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { |
802 | 802 | ||
803 | off = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 803 | off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
804 | XFS_DIR2_SF_GET_OFFSET(sfep)); | 804 | xfs_dir2_sf_get_offset(sfep)); |
805 | 805 | ||
806 | if (dir_offset > off) | 806 | if (dir_offset > off) |
807 | continue; | 807 | continue; |
808 | 808 | ||
809 | p.namelen = sfep->namelen; | 809 | p.namelen = sfep->namelen; |
810 | 810 | ||
811 | p.cook = XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk, | 811 | p.cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
812 | XFS_DIR2_SF_GET_OFFSET(sfep) + | 812 | xfs_dir2_sf_get_offset(sfep) + |
813 | XFS_DIR2_DATA_ENTSIZE(p.namelen)); | 813 | xfs_dir2_data_entsize(p.namelen)); |
814 | 814 | ||
815 | p.ino = XFS_DIR2_SF_GET_INUMBER(sfp, XFS_DIR2_SF_INUMBERP(sfep)); | 815 | p.ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); |
816 | #if XFS_BIG_INUMS | 816 | #if XFS_BIG_INUMS |
817 | p.ino += mp->m_inoadd; | 817 | p.ino += mp->m_inoadd; |
818 | #endif | 818 | #endif |
@@ -832,7 +832,7 @@ xfs_dir2_sf_getdents( | |||
832 | *eofp = 1; | 832 | *eofp = 1; |
833 | 833 | ||
834 | uio->uio_offset = | 834 | uio->uio_offset = |
835 | XFS_DIR2_DB_OFF_TO_DATAPTR(mp, mp->m_dirdatablk + 1, 0); | 835 | xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); |
836 | 836 | ||
837 | return 0; | 837 | return 0; |
838 | } | 838 | } |
@@ -865,7 +865,7 @@ xfs_dir2_sf_lookup( | |||
865 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 865 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
866 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 866 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
867 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 867 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
868 | ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 868 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
869 | /* | 869 | /* |
870 | * Special case for . | 870 | * Special case for . |
871 | */ | 871 | */ |
@@ -878,21 +878,21 @@ xfs_dir2_sf_lookup( | |||
878 | */ | 878 | */ |
879 | if (args->namelen == 2 && | 879 | if (args->namelen == 2 && |
880 | args->name[0] == '.' && args->name[1] == '.') { | 880 | args->name[0] == '.' && args->name[1] == '.') { |
881 | args->inumber = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); | 881 | args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); |
882 | return XFS_ERROR(EEXIST); | 882 | return XFS_ERROR(EEXIST); |
883 | } | 883 | } |
884 | /* | 884 | /* |
885 | * Loop over all the entries trying to match ours. | 885 | * Loop over all the entries trying to match ours. |
886 | */ | 886 | */ |
887 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 887 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
888 | i < sfp->hdr.count; | 888 | i < sfp->hdr.count; |
889 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { | 889 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { |
890 | if (sfep->namelen == args->namelen && | 890 | if (sfep->namelen == args->namelen && |
891 | sfep->name[0] == args->name[0] && | 891 | sfep->name[0] == args->name[0] && |
892 | memcmp(args->name, sfep->name, args->namelen) == 0) { | 892 | memcmp(args->name, sfep->name, args->namelen) == 0) { |
893 | args->inumber = | 893 | args->inumber = |
894 | XFS_DIR2_SF_GET_INUMBER(sfp, | 894 | xfs_dir2_sf_get_inumber(sfp, |
895 | XFS_DIR2_SF_INUMBERP(sfep)); | 895 | xfs_dir2_sf_inumberp(sfep)); |
896 | return XFS_ERROR(EEXIST); | 896 | return XFS_ERROR(EEXIST); |
897 | } | 897 | } |
898 | } | 898 | } |
@@ -934,19 +934,19 @@ xfs_dir2_sf_removename( | |||
934 | ASSERT(dp->i_df.if_bytes == oldsize); | 934 | ASSERT(dp->i_df.if_bytes == oldsize); |
935 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 935 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
936 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 936 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
937 | ASSERT(oldsize >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 937 | ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
938 | /* | 938 | /* |
939 | * Loop over the old directory entries. | 939 | * Loop over the old directory entries. |
940 | * Find the one we're deleting. | 940 | * Find the one we're deleting. |
941 | */ | 941 | */ |
942 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 942 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
943 | i < sfp->hdr.count; | 943 | i < sfp->hdr.count; |
944 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { | 944 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { |
945 | if (sfep->namelen == args->namelen && | 945 | if (sfep->namelen == args->namelen && |
946 | sfep->name[0] == args->name[0] && | 946 | sfep->name[0] == args->name[0] && |
947 | memcmp(sfep->name, args->name, args->namelen) == 0) { | 947 | memcmp(sfep->name, args->name, args->namelen) == 0) { |
948 | ASSERT(XFS_DIR2_SF_GET_INUMBER(sfp, | 948 | ASSERT(xfs_dir2_sf_get_inumber(sfp, |
949 | XFS_DIR2_SF_INUMBERP(sfep)) == | 949 | xfs_dir2_sf_inumberp(sfep)) == |
950 | args->inumber); | 950 | args->inumber); |
951 | break; | 951 | break; |
952 | } | 952 | } |
@@ -961,7 +961,7 @@ xfs_dir2_sf_removename( | |||
961 | * Calculate sizes. | 961 | * Calculate sizes. |
962 | */ | 962 | */ |
963 | byteoff = (int)((char *)sfep - (char *)sfp); | 963 | byteoff = (int)((char *)sfep - (char *)sfp); |
964 | entsize = XFS_DIR2_SF_ENTSIZE_BYNAME(sfp, args->namelen); | 964 | entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); |
965 | newsize = oldsize - entsize; | 965 | newsize = oldsize - entsize; |
966 | /* | 966 | /* |
967 | * Copy the part if any after the removed entry, sliding it down. | 967 | * Copy the part if any after the removed entry, sliding it down. |
@@ -1027,7 +1027,7 @@ xfs_dir2_sf_replace( | |||
1027 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); | 1027 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
1028 | ASSERT(dp->i_df.if_u1.if_data != NULL); | 1028 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
1029 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; | 1029 | sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; |
1030 | ASSERT(dp->i_d.di_size >= XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count)); | 1030 | ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); |
1031 | #if XFS_BIG_INUMS | 1031 | #if XFS_BIG_INUMS |
1032 | /* | 1032 | /* |
1033 | * New inode number is large, and need to convert to 8-byte inodes. | 1033 | * New inode number is large, and need to convert to 8-byte inodes. |
@@ -1067,28 +1067,28 @@ xfs_dir2_sf_replace( | |||
1067 | if (args->namelen == 2 && | 1067 | if (args->namelen == 2 && |
1068 | args->name[0] == '.' && args->name[1] == '.') { | 1068 | args->name[0] == '.' && args->name[1] == '.') { |
1069 | #if XFS_BIG_INUMS || defined(DEBUG) | 1069 | #if XFS_BIG_INUMS || defined(DEBUG) |
1070 | ino = XFS_DIR2_SF_GET_INUMBER(sfp, &sfp->hdr.parent); | 1070 | ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); |
1071 | ASSERT(args->inumber != ino); | 1071 | ASSERT(args->inumber != ino); |
1072 | #endif | 1072 | #endif |
1073 | XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, &sfp->hdr.parent); | 1073 | xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); |
1074 | } | 1074 | } |
1075 | /* | 1075 | /* |
1076 | * Normal entry, look for the name. | 1076 | * Normal entry, look for the name. |
1077 | */ | 1077 | */ |
1078 | else { | 1078 | else { |
1079 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp); | 1079 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
1080 | i < sfp->hdr.count; | 1080 | i < sfp->hdr.count; |
1081 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep)) { | 1081 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { |
1082 | if (sfep->namelen == args->namelen && | 1082 | if (sfep->namelen == args->namelen && |
1083 | sfep->name[0] == args->name[0] && | 1083 | sfep->name[0] == args->name[0] && |
1084 | memcmp(args->name, sfep->name, args->namelen) == 0) { | 1084 | memcmp(args->name, sfep->name, args->namelen) == 0) { |
1085 | #if XFS_BIG_INUMS || defined(DEBUG) | 1085 | #if XFS_BIG_INUMS || defined(DEBUG) |
1086 | ino = XFS_DIR2_SF_GET_INUMBER(sfp, | 1086 | ino = xfs_dir2_sf_get_inumber(sfp, |
1087 | XFS_DIR2_SF_INUMBERP(sfep)); | 1087 | xfs_dir2_sf_inumberp(sfep)); |
1088 | ASSERT(args->inumber != ino); | 1088 | ASSERT(args->inumber != ino); |
1089 | #endif | 1089 | #endif |
1090 | XFS_DIR2_SF_PUT_INUMBER(sfp, &args->inumber, | 1090 | xfs_dir2_sf_put_inumber(sfp, &args->inumber, |
1091 | XFS_DIR2_SF_INUMBERP(sfep)); | 1091 | xfs_dir2_sf_inumberp(sfep)); |
1092 | break; | 1092 | break; |
1093 | } | 1093 | } |
1094 | } | 1094 | } |
@@ -1189,22 +1189,22 @@ xfs_dir2_sf_toino4( | |||
1189 | */ | 1189 | */ |
1190 | sfp->hdr.count = oldsfp->hdr.count; | 1190 | sfp->hdr.count = oldsfp->hdr.count; |
1191 | sfp->hdr.i8count = 0; | 1191 | sfp->hdr.i8count = 0; |
1192 | ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent); | 1192 | ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); |
1193 | XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent); | 1193 | xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); |
1194 | /* | 1194 | /* |
1195 | * Copy the entries field by field. | 1195 | * Copy the entries field by field. |
1196 | */ | 1196 | */ |
1197 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp), | 1197 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
1198 | oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp); | 1198 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
1199 | i < sfp->hdr.count; | 1199 | i < sfp->hdr.count; |
1200 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep), | 1200 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), |
1201 | oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) { | 1201 | oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { |
1202 | sfep->namelen = oldsfep->namelen; | 1202 | sfep->namelen = oldsfep->namelen; |
1203 | sfep->offset = oldsfep->offset; | 1203 | sfep->offset = oldsfep->offset; |
1204 | memcpy(sfep->name, oldsfep->name, sfep->namelen); | 1204 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
1205 | ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, | 1205 | ino = xfs_dir2_sf_get_inumber(oldsfp, |
1206 | XFS_DIR2_SF_INUMBERP(oldsfep)); | 1206 | xfs_dir2_sf_inumberp(oldsfep)); |
1207 | XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep)); | 1207 | xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); |
1208 | } | 1208 | } |
1209 | /* | 1209 | /* |
1210 | * Clean up the inode. | 1210 | * Clean up the inode. |
@@ -1266,22 +1266,22 @@ xfs_dir2_sf_toino8( | |||
1266 | */ | 1266 | */ |
1267 | sfp->hdr.count = oldsfp->hdr.count; | 1267 | sfp->hdr.count = oldsfp->hdr.count; |
1268 | sfp->hdr.i8count = 1; | 1268 | sfp->hdr.i8count = 1; |
1269 | ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, &oldsfp->hdr.parent); | 1269 | ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); |
1270 | XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, &sfp->hdr.parent); | 1270 | xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); |
1271 | /* | 1271 | /* |
1272 | * Copy the entries field by field. | 1272 | * Copy the entries field by field. |
1273 | */ | 1273 | */ |
1274 | for (i = 0, sfep = XFS_DIR2_SF_FIRSTENTRY(sfp), | 1274 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
1275 | oldsfep = XFS_DIR2_SF_FIRSTENTRY(oldsfp); | 1275 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
1276 | i < sfp->hdr.count; | 1276 | i < sfp->hdr.count; |
1277 | i++, sfep = XFS_DIR2_SF_NEXTENTRY(sfp, sfep), | 1277 | i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), |
1278 | oldsfep = XFS_DIR2_SF_NEXTENTRY(oldsfp, oldsfep)) { | 1278 | oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { |
1279 | sfep->namelen = oldsfep->namelen; | 1279 | sfep->namelen = oldsfep->namelen; |
1280 | sfep->offset = oldsfep->offset; | 1280 | sfep->offset = oldsfep->offset; |
1281 | memcpy(sfep->name, oldsfep->name, sfep->namelen); | 1281 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
1282 | ino = XFS_DIR2_SF_GET_INUMBER(oldsfp, | 1282 | ino = xfs_dir2_sf_get_inumber(oldsfp, |
1283 | XFS_DIR2_SF_INUMBERP(oldsfep)); | 1283 | xfs_dir2_sf_inumberp(oldsfep)); |
1284 | XFS_DIR2_SF_PUT_INUMBER(sfp, &ino, XFS_DIR2_SF_INUMBERP(sfep)); | 1284 | xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); |
1285 | } | 1285 | } |
1286 | /* | 1286 | /* |
1287 | * Clean up the inode. | 1287 | * Clean up the inode. |
diff --git a/fs/xfs/xfs_dir2_sf.h b/fs/xfs/xfs_dir2_sf.h index 42f015b7001..11e503209af 100644 --- a/fs/xfs/xfs_dir2_sf.h +++ b/fs/xfs/xfs_dir2_sf.h | |||
@@ -90,7 +90,6 @@ typedef struct xfs_dir2_sf { | |||
90 | xfs_dir2_sf_entry_t list[1]; /* shortform entries */ | 90 | xfs_dir2_sf_entry_t list[1]; /* shortform entries */ |
91 | } xfs_dir2_sf_t; | 91 | } xfs_dir2_sf_t; |
92 | 92 | ||
93 | #define XFS_DIR2_SF_HDR_SIZE(i8count) xfs_dir2_sf_hdr_size(i8count) | ||
94 | static inline int xfs_dir2_sf_hdr_size(int i8count) | 93 | static inline int xfs_dir2_sf_hdr_size(int i8count) |
95 | { | 94 | { |
96 | return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ | 95 | return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ |
@@ -98,14 +97,11 @@ static inline int xfs_dir2_sf_hdr_size(int i8count) | |||
98 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | 97 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); |
99 | } | 98 | } |
100 | 99 | ||
101 | #define XFS_DIR2_SF_INUMBERP(sfep) xfs_dir2_sf_inumberp(sfep) | ||
102 | static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) | 100 | static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) |
103 | { | 101 | { |
104 | return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; | 102 | return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; |
105 | } | 103 | } |
106 | 104 | ||
107 | #define XFS_DIR2_SF_GET_INUMBER(sfp, from) \ | ||
108 | xfs_dir2_sf_get_inumber(sfp, from) | ||
109 | static inline xfs_intino_t | 105 | static inline xfs_intino_t |
110 | xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) | 106 | xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) |
111 | { | 107 | { |
@@ -114,8 +110,6 @@ xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) | |||
114 | (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); | 110 | (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); |
115 | } | 111 | } |
116 | 112 | ||
117 | #define XFS_DIR2_SF_PUT_INUMBER(sfp,from,to) \ | ||
118 | xfs_dir2_sf_put_inumber(sfp,from,to) | ||
119 | static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, | 113 | static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, |
120 | xfs_dir2_inou_t *to) | 114 | xfs_dir2_inou_t *to) |
121 | { | 115 | { |
@@ -125,24 +119,18 @@ static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, | |||
125 | XFS_PUT_DIR_INO8(*(from), (to)->i8); | 119 | XFS_PUT_DIR_INO8(*(from), (to)->i8); |
126 | } | 120 | } |
127 | 121 | ||
128 | #define XFS_DIR2_SF_GET_OFFSET(sfep) \ | ||
129 | xfs_dir2_sf_get_offset(sfep) | ||
130 | static inline xfs_dir2_data_aoff_t | 122 | static inline xfs_dir2_data_aoff_t |
131 | xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) | 123 | xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) |
132 | { | 124 | { |
133 | return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); | 125 | return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); |
134 | } | 126 | } |
135 | 127 | ||
136 | #define XFS_DIR2_SF_PUT_OFFSET(sfep,off) \ | ||
137 | xfs_dir2_sf_put_offset(sfep,off) | ||
138 | static inline void | 128 | static inline void |
139 | xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) | 129 | xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) |
140 | { | 130 | { |
141 | INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); | 131 | INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); |
142 | } | 132 | } |
143 | 133 | ||
144 | #define XFS_DIR2_SF_ENTSIZE_BYNAME(sfp,len) \ | ||
145 | xfs_dir2_sf_entsize_byname(sfp,len) | ||
146 | static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) | 134 | static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) |
147 | { | 135 | { |
148 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ | 136 | return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ |
@@ -150,8 +138,6 @@ static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) | |||
150 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | 138 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); |
151 | } | 139 | } |
152 | 140 | ||
153 | #define XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep) \ | ||
154 | xfs_dir2_sf_entsize_byentry(sfp,sfep) | ||
155 | static inline int | 141 | static inline int |
156 | xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | 142 | xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) |
157 | { | 143 | { |
@@ -160,19 +146,17 @@ xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | |||
160 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); | 146 | ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); |
161 | } | 147 | } |
162 | 148 | ||
163 | #define XFS_DIR2_SF_FIRSTENTRY(sfp) xfs_dir2_sf_firstentry(sfp) | ||
164 | static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) | 149 | static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) |
165 | { | 150 | { |
166 | return ((xfs_dir2_sf_entry_t *) \ | 151 | return ((xfs_dir2_sf_entry_t *) \ |
167 | ((char *)(sfp) + XFS_DIR2_SF_HDR_SIZE(sfp->hdr.i8count))); | 152 | ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); |
168 | } | 153 | } |
169 | 154 | ||
170 | #define XFS_DIR2_SF_NEXTENTRY(sfp,sfep) xfs_dir2_sf_nextentry(sfp,sfep) | ||
171 | static inline xfs_dir2_sf_entry_t * | 155 | static inline xfs_dir2_sf_entry_t * |
172 | xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) | 156 | xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) |
173 | { | 157 | { |
174 | return ((xfs_dir2_sf_entry_t *) \ | 158 | return ((xfs_dir2_sf_entry_t *) \ |
175 | ((char *)(sfep) + XFS_DIR2_SF_ENTSIZE_BYENTRY(sfp,sfep))); | 159 | ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); |
176 | } | 160 | } |
177 | 161 | ||
178 | /* | 162 | /* |
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c new file mode 100644 index 00000000000..ce2278611bb --- /dev/null +++ b/fs/xfs/xfs_filestream.c | |||
@@ -0,0 +1,771 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006-2007 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_bmap_btree.h" | ||
20 | #include "xfs_inum.h" | ||
21 | #include "xfs_dir2.h" | ||
22 | #include "xfs_dir2_sf.h" | ||
23 | #include "xfs_attr_sf.h" | ||
24 | #include "xfs_dinode.h" | ||
25 | #include "xfs_inode.h" | ||
26 | #include "xfs_ag.h" | ||
27 | #include "xfs_dmapi.h" | ||
28 | #include "xfs_log.h" | ||
29 | #include "xfs_trans.h" | ||
30 | #include "xfs_sb.h" | ||
31 | #include "xfs_mount.h" | ||
32 | #include "xfs_bmap.h" | ||
33 | #include "xfs_alloc.h" | ||
34 | #include "xfs_utils.h" | ||
35 | #include "xfs_mru_cache.h" | ||
36 | #include "xfs_filestream.h" | ||
37 | |||
38 | #ifdef XFS_FILESTREAMS_TRACE | ||
39 | |||
40 | ktrace_t *xfs_filestreams_trace_buf; | ||
41 | |||
42 | STATIC void | ||
43 | xfs_filestreams_trace( | ||
44 | xfs_mount_t *mp, /* mount point */ | ||
45 | int type, /* type of trace */ | ||
46 | const char *func, /* source function */ | ||
47 | int line, /* source line number */ | ||
48 | __psunsigned_t arg0, | ||
49 | __psunsigned_t arg1, | ||
50 | __psunsigned_t arg2, | ||
51 | __psunsigned_t arg3, | ||
52 | __psunsigned_t arg4, | ||
53 | __psunsigned_t arg5) | ||
54 | { | ||
55 | ktrace_enter(xfs_filestreams_trace_buf, | ||
56 | (void *)(__psint_t)(type | (line << 16)), | ||
57 | (void *)func, | ||
58 | (void *)(__psunsigned_t)current_pid(), | ||
59 | (void *)mp, | ||
60 | (void *)(__psunsigned_t)arg0, | ||
61 | (void *)(__psunsigned_t)arg1, | ||
62 | (void *)(__psunsigned_t)arg2, | ||
63 | (void *)(__psunsigned_t)arg3, | ||
64 | (void *)(__psunsigned_t)arg4, | ||
65 | (void *)(__psunsigned_t)arg5, | ||
66 | NULL, NULL, NULL, NULL, NULL, NULL); | ||
67 | } | ||
68 | |||
69 | #define TRACE0(mp,t) TRACE6(mp,t,0,0,0,0,0,0) | ||
70 | #define TRACE1(mp,t,a0) TRACE6(mp,t,a0,0,0,0,0,0) | ||
71 | #define TRACE2(mp,t,a0,a1) TRACE6(mp,t,a0,a1,0,0,0,0) | ||
72 | #define TRACE3(mp,t,a0,a1,a2) TRACE6(mp,t,a0,a1,a2,0,0,0) | ||
73 | #define TRACE4(mp,t,a0,a1,a2,a3) TRACE6(mp,t,a0,a1,a2,a3,0,0) | ||
74 | #define TRACE5(mp,t,a0,a1,a2,a3,a4) TRACE6(mp,t,a0,a1,a2,a3,a4,0) | ||
75 | #define TRACE6(mp,t,a0,a1,a2,a3,a4,a5) \ | ||
76 | xfs_filestreams_trace(mp, t, __FUNCTION__, __LINE__, \ | ||
77 | (__psunsigned_t)a0, (__psunsigned_t)a1, \ | ||
78 | (__psunsigned_t)a2, (__psunsigned_t)a3, \ | ||
79 | (__psunsigned_t)a4, (__psunsigned_t)a5) | ||
80 | |||
81 | #define TRACE_AG_SCAN(mp, ag, ag2) \ | ||
82 | TRACE2(mp, XFS_FSTRM_KTRACE_AGSCAN, ag, ag2); | ||
83 | #define TRACE_AG_PICK1(mp, max_ag, maxfree) \ | ||
84 | TRACE2(mp, XFS_FSTRM_KTRACE_AGPICK1, max_ag, maxfree); | ||
85 | #define TRACE_AG_PICK2(mp, ag, ag2, cnt, free, scan, flag) \ | ||
86 | TRACE6(mp, XFS_FSTRM_KTRACE_AGPICK2, ag, ag2, \ | ||
87 | cnt, free, scan, flag) | ||
88 | #define TRACE_UPDATE(mp, ip, ag, cnt, ag2, cnt2) \ | ||
89 | TRACE5(mp, XFS_FSTRM_KTRACE_UPDATE, ip, ag, cnt, ag2, cnt2) | ||
90 | #define TRACE_FREE(mp, ip, pip, ag, cnt) \ | ||
91 | TRACE4(mp, XFS_FSTRM_KTRACE_FREE, ip, pip, ag, cnt) | ||
92 | #define TRACE_LOOKUP(mp, ip, pip, ag, cnt) \ | ||
93 | TRACE4(mp, XFS_FSTRM_KTRACE_ITEM_LOOKUP, ip, pip, ag, cnt) | ||
94 | #define TRACE_ASSOCIATE(mp, ip, pip, ag, cnt) \ | ||
95 | TRACE4(mp, XFS_FSTRM_KTRACE_ASSOCIATE, ip, pip, ag, cnt) | ||
96 | #define TRACE_MOVEAG(mp, ip, pip, oag, ocnt, nag, ncnt) \ | ||
97 | TRACE6(mp, XFS_FSTRM_KTRACE_MOVEAG, ip, pip, oag, ocnt, nag, ncnt) | ||
98 | #define TRACE_ORPHAN(mp, ip, ag) \ | ||
99 | TRACE2(mp, XFS_FSTRM_KTRACE_ORPHAN, ip, ag); | ||
100 | |||
101 | |||
102 | #else | ||
103 | #define TRACE_AG_SCAN(mp, ag, ag2) | ||
104 | #define TRACE_AG_PICK1(mp, max_ag, maxfree) | ||
105 | #define TRACE_AG_PICK2(mp, ag, ag2, cnt, free, scan, flag) | ||
106 | #define TRACE_UPDATE(mp, ip, ag, cnt, ag2, cnt2) | ||
107 | #define TRACE_FREE(mp, ip, pip, ag, cnt) | ||
108 | #define TRACE_LOOKUP(mp, ip, pip, ag, cnt) | ||
109 | #define TRACE_ASSOCIATE(mp, ip, pip, ag, cnt) | ||
110 | #define TRACE_MOVEAG(mp, ip, pip, oag, ocnt, nag, ncnt) | ||
111 | #define TRACE_ORPHAN(mp, ip, ag) | ||
112 | #endif | ||
113 | |||
114 | static kmem_zone_t *item_zone; | ||
115 | |||
116 | /* | ||
117 | * Structure for associating a file or a directory with an allocation group. | ||
118 | * The parent directory pointer is only needed for files, but since there will | ||
119 | * generally be vastly more files than directories in the cache, using the same | ||
120 | * data structure simplifies the code with very little memory overhead. | ||
121 | */ | ||
122 | typedef struct fstrm_item | ||
123 | { | ||
124 | xfs_agnumber_t ag; /* AG currently in use for the file/directory. */ | ||
125 | xfs_inode_t *ip; /* inode self-pointer. */ | ||
126 | xfs_inode_t *pip; /* Parent directory inode pointer. */ | ||
127 | } fstrm_item_t; | ||
128 | |||
129 | |||
130 | /* | ||
131 | * Scan the AGs starting at startag looking for an AG that isn't in use and has | ||
132 | * at least minlen blocks free. | ||
133 | */ | ||
134 | static int | ||
135 | _xfs_filestream_pick_ag( | ||
136 | xfs_mount_t *mp, | ||
137 | xfs_agnumber_t startag, | ||
138 | xfs_agnumber_t *agp, | ||
139 | int flags, | ||
140 | xfs_extlen_t minlen) | ||
141 | { | ||
142 | int err, trylock, nscan; | ||
143 | xfs_extlen_t delta, longest, need, free, minfree, maxfree = 0; | ||
144 | xfs_agnumber_t ag, max_ag = NULLAGNUMBER; | ||
145 | struct xfs_perag *pag; | ||
146 | |||
147 | /* 2% of an AG's blocks must be free for it to be chosen. */ | ||
148 | minfree = mp->m_sb.sb_agblocks / 50; | ||
149 | |||
150 | ag = startag; | ||
151 | *agp = NULLAGNUMBER; | ||
152 | |||
153 | /* For the first pass, don't sleep trying to init the per-AG. */ | ||
154 | trylock = XFS_ALLOC_FLAG_TRYLOCK; | ||
155 | |||
156 | for (nscan = 0; 1; nscan++) { | ||
157 | |||
158 | TRACE_AG_SCAN(mp, ag, xfs_filestream_peek_ag(mp, ag)); | ||
159 | |||
160 | pag = mp->m_perag + ag; | ||
161 | |||
162 | if (!pag->pagf_init) { | ||
163 | err = xfs_alloc_pagf_init(mp, NULL, ag, trylock); | ||
164 | if (err && !trylock) | ||
165 | return err; | ||
166 | } | ||
167 | |||
168 | /* Might fail sometimes during the 1st pass with trylock set. */ | ||
169 | if (!pag->pagf_init) | ||
170 | goto next_ag; | ||
171 | |||
172 | /* Keep track of the AG with the most free blocks. */ | ||
173 | if (pag->pagf_freeblks > maxfree) { | ||
174 | maxfree = pag->pagf_freeblks; | ||
175 | max_ag = ag; | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * The AG reference count does two things: it enforces mutual | ||
180 | * exclusion when examining the suitability of an AG in this | ||
181 | * loop, and it guards against two filestreams being established | ||
182 | * in the same AG as each other. | ||
183 | */ | ||
184 | if (xfs_filestream_get_ag(mp, ag) > 1) { | ||
185 | xfs_filestream_put_ag(mp, ag); | ||
186 | goto next_ag; | ||
187 | } | ||
188 | |||
189 | need = XFS_MIN_FREELIST_PAG(pag, mp); | ||
190 | delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; | ||
191 | longest = (pag->pagf_longest > delta) ? | ||
192 | (pag->pagf_longest - delta) : | ||
193 | (pag->pagf_flcount > 0 || pag->pagf_longest > 0); | ||
194 | |||
195 | if (((minlen && longest >= minlen) || | ||
196 | (!minlen && pag->pagf_freeblks >= minfree)) && | ||
197 | (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) || | ||
198 | (flags & XFS_PICK_LOWSPACE))) { | ||
199 | |||
200 | /* Break out, retaining the reference on the AG. */ | ||
201 | free = pag->pagf_freeblks; | ||
202 | *agp = ag; | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | /* Drop the reference on this AG, it's not usable. */ | ||
207 | xfs_filestream_put_ag(mp, ag); | ||
208 | next_ag: | ||
209 | /* Move to the next AG, wrapping to AG 0 if necessary. */ | ||
210 | if (++ag >= mp->m_sb.sb_agcount) | ||
211 | ag = 0; | ||
212 | |||
213 | /* If a full pass of the AGs hasn't been done yet, continue. */ | ||
214 | if (ag != startag) | ||
215 | continue; | ||
216 | |||
217 | /* Allow sleeping in xfs_alloc_pagf_init() on the 2nd pass. */ | ||
218 | if (trylock != 0) { | ||
219 | trylock = 0; | ||
220 | continue; | ||
221 | } | ||
222 | |||
223 | /* Finally, if lowspace wasn't set, set it for the 3rd pass. */ | ||
224 | if (!(flags & XFS_PICK_LOWSPACE)) { | ||
225 | flags |= XFS_PICK_LOWSPACE; | ||
226 | continue; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Take the AG with the most free space, regardless of whether | ||
231 | * it's already in use by another filestream. | ||
232 | */ | ||
233 | if (max_ag != NULLAGNUMBER) { | ||
234 | xfs_filestream_get_ag(mp, max_ag); | ||
235 | TRACE_AG_PICK1(mp, max_ag, maxfree); | ||
236 | free = maxfree; | ||
237 | *agp = max_ag; | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | /* take AG 0 if none matched */ | ||
242 | TRACE_AG_PICK1(mp, max_ag, maxfree); | ||
243 | *agp = 0; | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | TRACE_AG_PICK2(mp, startag, *agp, xfs_filestream_peek_ag(mp, *agp), | ||
248 | free, nscan, flags); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * Set the allocation group number for a file or a directory, updating inode | ||
255 | * references and per-AG references as appropriate. Must be called with the | ||
256 | * m_peraglock held in read mode. | ||
257 | */ | ||
258 | static int | ||
259 | _xfs_filestream_update_ag( | ||
260 | xfs_inode_t *ip, | ||
261 | xfs_inode_t *pip, | ||
262 | xfs_agnumber_t ag) | ||
263 | { | ||
264 | int err = 0; | ||
265 | xfs_mount_t *mp; | ||
266 | xfs_mru_cache_t *cache; | ||
267 | fstrm_item_t *item; | ||
268 | xfs_agnumber_t old_ag; | ||
269 | xfs_inode_t *old_pip; | ||
270 | |||
271 | /* | ||
272 | * Either ip is a regular file and pip is a directory, or ip is a | ||
273 | * directory and pip is NULL. | ||
274 | */ | ||
275 | ASSERT(ip && (((ip->i_d.di_mode & S_IFREG) && pip && | ||
276 | (pip->i_d.di_mode & S_IFDIR)) || | ||
277 | ((ip->i_d.di_mode & S_IFDIR) && !pip))); | ||
278 | |||
279 | mp = ip->i_mount; | ||
280 | cache = mp->m_filestream; | ||
281 | |||
282 | item = xfs_mru_cache_lookup(cache, ip->i_ino); | ||
283 | if (item) { | ||
284 | ASSERT(item->ip == ip); | ||
285 | old_ag = item->ag; | ||
286 | item->ag = ag; | ||
287 | old_pip = item->pip; | ||
288 | item->pip = pip; | ||
289 | xfs_mru_cache_done(cache); | ||
290 | |||
291 | /* | ||
292 | * If the AG has changed, drop the old ref and take a new one, | ||
293 | * effectively transferring the reference from old to new AG. | ||
294 | */ | ||
295 | if (ag != old_ag) { | ||
296 | xfs_filestream_put_ag(mp, old_ag); | ||
297 | xfs_filestream_get_ag(mp, ag); | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * If ip is a file and its pip has changed, drop the old ref and | ||
302 | * take a new one. | ||
303 | */ | ||
304 | if (pip && pip != old_pip) { | ||
305 | IRELE(old_pip); | ||
306 | IHOLD(pip); | ||
307 | } | ||
308 | |||
309 | TRACE_UPDATE(mp, ip, old_ag, xfs_filestream_peek_ag(mp, old_ag), | ||
310 | ag, xfs_filestream_peek_ag(mp, ag)); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | item = kmem_zone_zalloc(item_zone, KM_MAYFAIL); | ||
315 | if (!item) | ||
316 | return ENOMEM; | ||
317 | |||
318 | item->ag = ag; | ||
319 | item->ip = ip; | ||
320 | item->pip = pip; | ||
321 | |||
322 | err = xfs_mru_cache_insert(cache, ip->i_ino, item); | ||
323 | if (err) { | ||
324 | kmem_zone_free(item_zone, item); | ||
325 | return err; | ||
326 | } | ||
327 | |||
328 | /* Take a reference on the AG. */ | ||
329 | xfs_filestream_get_ag(mp, ag); | ||
330 | |||
331 | /* | ||
332 | * Take a reference on the inode itself regardless of whether it's a | ||
333 | * regular file or a directory. | ||
334 | */ | ||
335 | IHOLD(ip); | ||
336 | |||
337 | /* | ||
338 | * In the case of a regular file, take a reference on the parent inode | ||
339 | * as well to ensure it remains in-core. | ||
340 | */ | ||
341 | if (pip) | ||
342 | IHOLD(pip); | ||
343 | |||
344 | TRACE_UPDATE(mp, ip, ag, xfs_filestream_peek_ag(mp, ag), | ||
345 | ag, xfs_filestream_peek_ag(mp, ag)); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | /* xfs_fstrm_free_func(): callback for freeing cached stream items. */ | ||
351 | void | ||
352 | xfs_fstrm_free_func( | ||
353 | xfs_ino_t ino, | ||
354 | fstrm_item_t *item) | ||
355 | { | ||
356 | xfs_inode_t *ip = item->ip; | ||
357 | int ref; | ||
358 | |||
359 | ASSERT(ip->i_ino == ino); | ||
360 | |||
361 | xfs_iflags_clear(ip, XFS_IFILESTREAM); | ||
362 | |||
363 | /* Drop the reference taken on the AG when the item was added. */ | ||
364 | ref = xfs_filestream_put_ag(ip->i_mount, item->ag); | ||
365 | |||
366 | ASSERT(ref >= 0); | ||
367 | TRACE_FREE(ip->i_mount, ip, item->pip, item->ag, | ||
368 | xfs_filestream_peek_ag(ip->i_mount, item->ag)); | ||
369 | |||
370 | /* | ||
371 | * _xfs_filestream_update_ag() always takes a reference on the inode | ||
372 | * itself, whether it's a file or a directory. Release it here. | ||
373 | * This can result in the inode being freed and so we must | ||
374 | * not hold any inode locks when freeing filesstreams objects | ||
375 | * otherwise we can deadlock here. | ||
376 | */ | ||
377 | IRELE(ip); | ||
378 | |||
379 | /* | ||
380 | * In the case of a regular file, _xfs_filestream_update_ag() also | ||
381 | * takes a ref on the parent inode to keep it in-core. Release that | ||
382 | * too. | ||
383 | */ | ||
384 | if (item->pip) | ||
385 | IRELE(item->pip); | ||
386 | |||
387 | /* Finally, free the memory allocated for the item. */ | ||
388 | kmem_zone_free(item_zone, item); | ||
389 | } | ||
390 | |||
391 | /* | ||
392 | * xfs_filestream_init() is called at xfs initialisation time to set up the | ||
393 | * memory zone that will be used for filestream data structure allocation. | ||
394 | */ | ||
395 | int | ||
396 | xfs_filestream_init(void) | ||
397 | { | ||
398 | item_zone = kmem_zone_init(sizeof(fstrm_item_t), "fstrm_item"); | ||
399 | #ifdef XFS_FILESTREAMS_TRACE | ||
400 | xfs_filestreams_trace_buf = ktrace_alloc(XFS_FSTRM_KTRACE_SIZE, KM_SLEEP); | ||
401 | #endif | ||
402 | return item_zone ? 0 : -ENOMEM; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * xfs_filestream_uninit() is called at xfs termination time to destroy the | ||
407 | * memory zone that was used for filestream data structure allocation. | ||
408 | */ | ||
409 | void | ||
410 | xfs_filestream_uninit(void) | ||
411 | { | ||
412 | #ifdef XFS_FILESTREAMS_TRACE | ||
413 | ktrace_free(xfs_filestreams_trace_buf); | ||
414 | #endif | ||
415 | kmem_zone_destroy(item_zone); | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * xfs_filestream_mount() is called when a file system is mounted with the | ||
420 | * filestream option. It is responsible for allocating the data structures | ||
421 | * needed to track the new file system's file streams. | ||
422 | */ | ||
423 | int | ||
424 | xfs_filestream_mount( | ||
425 | xfs_mount_t *mp) | ||
426 | { | ||
427 | int err; | ||
428 | unsigned int lifetime, grp_count; | ||
429 | |||
430 | /* | ||
431 | * The filestream timer tunable is currently fixed within the range of | ||
432 | * one second to four minutes, with five seconds being the default. The | ||
433 | * group count is somewhat arbitrary, but it'd be nice to adhere to the | ||
434 | * timer tunable to within about 10 percent. This requires at least 10 | ||
435 | * groups. | ||
436 | */ | ||
437 | lifetime = xfs_fstrm_centisecs * 10; | ||
438 | grp_count = 10; | ||
439 | |||
440 | err = xfs_mru_cache_create(&mp->m_filestream, lifetime, grp_count, | ||
441 | (xfs_mru_cache_free_func_t)xfs_fstrm_free_func); | ||
442 | |||
443 | return err; | ||
444 | } | ||
445 | |||
446 | /* | ||
447 | * xfs_filestream_unmount() is called when a file system that was mounted with | ||
448 | * the filestream option is unmounted. It drains the data structures created | ||
449 | * to track the file system's file streams and frees all the memory that was | ||
450 | * allocated. | ||
451 | */ | ||
452 | void | ||
453 | xfs_filestream_unmount( | ||
454 | xfs_mount_t *mp) | ||
455 | { | ||
456 | xfs_mru_cache_destroy(mp->m_filestream); | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * If the mount point's m_perag array is going to be reallocated, all | ||
461 | * outstanding cache entries must be flushed to avoid accessing reference count | ||
462 | * addresses that have been freed. The call to xfs_filestream_flush() must be | ||
463 | * made inside the block that holds the m_peraglock in write mode to do the | ||
464 | * reallocation. | ||
465 | */ | ||
466 | void | ||
467 | xfs_filestream_flush( | ||
468 | xfs_mount_t *mp) | ||
469 | { | ||
470 | /* point in time flush, so keep the reaper running */ | ||
471 | xfs_mru_cache_flush(mp->m_filestream, 1); | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * Return the AG of the filestream the file or directory belongs to, or | ||
476 | * NULLAGNUMBER otherwise. | ||
477 | */ | ||
478 | xfs_agnumber_t | ||
479 | xfs_filestream_lookup_ag( | ||
480 | xfs_inode_t *ip) | ||
481 | { | ||
482 | xfs_mru_cache_t *cache; | ||
483 | fstrm_item_t *item; | ||
484 | xfs_agnumber_t ag; | ||
485 | int ref; | ||
486 | |||
487 | if (!(ip->i_d.di_mode & (S_IFREG | S_IFDIR))) { | ||
488 | ASSERT(0); | ||
489 | return NULLAGNUMBER; | ||
490 | } | ||
491 | |||
492 | cache = ip->i_mount->m_filestream; | ||
493 | item = xfs_mru_cache_lookup(cache, ip->i_ino); | ||
494 | if (!item) { | ||
495 | TRACE_LOOKUP(ip->i_mount, ip, NULL, NULLAGNUMBER, 0); | ||
496 | return NULLAGNUMBER; | ||
497 | } | ||
498 | |||
499 | ASSERT(ip == item->ip); | ||
500 | ag = item->ag; | ||
501 | ref = xfs_filestream_peek_ag(ip->i_mount, ag); | ||
502 | xfs_mru_cache_done(cache); | ||
503 | |||
504 | TRACE_LOOKUP(ip->i_mount, ip, item->pip, ag, ref); | ||
505 | return ag; | ||
506 | } | ||
507 | |||
508 | /* | ||
509 | * xfs_filestream_associate() should only be called to associate a regular file | ||
510 | * with its parent directory. Calling it with a child directory isn't | ||
511 | * appropriate because filestreams don't apply to entire directory hierarchies. | ||
512 | * Creating a file in a child directory of an existing filestream directory | ||
513 | * starts a new filestream with its own allocation group association. | ||
514 | * | ||
515 | * Returns < 0 on error, 0 if successful association occurred, > 0 if | ||
516 | * we failed to get an association because of locking issues. | ||
517 | */ | ||
518 | int | ||
519 | xfs_filestream_associate( | ||
520 | xfs_inode_t *pip, | ||
521 | xfs_inode_t *ip) | ||
522 | { | ||
523 | xfs_mount_t *mp; | ||
524 | xfs_mru_cache_t *cache; | ||
525 | fstrm_item_t *item; | ||
526 | xfs_agnumber_t ag, rotorstep, startag; | ||
527 | int err = 0; | ||
528 | |||
529 | ASSERT(pip->i_d.di_mode & S_IFDIR); | ||
530 | ASSERT(ip->i_d.di_mode & S_IFREG); | ||
531 | if (!(pip->i_d.di_mode & S_IFDIR) || !(ip->i_d.di_mode & S_IFREG)) | ||
532 | return -EINVAL; | ||
533 | |||
534 | mp = pip->i_mount; | ||
535 | cache = mp->m_filestream; | ||
536 | down_read(&mp->m_peraglock); | ||
537 | |||
538 | /* | ||
539 | * We have a problem, Houston. | ||
540 | * | ||
541 | * Taking the iolock here violates inode locking order - we already | ||
542 | * hold the ilock. Hence if we block getting this lock we may never | ||
543 | * wake. Unfortunately, that means if we can't get the lock, we're | ||
544 | * screwed in terms of getting a stream association - we can't spin | ||
545 | * waiting for the lock because someone else is waiting on the lock we | ||
546 | * hold and we cannot drop that as we are in a transaction here. | ||
547 | * | ||
548 | * Lucky for us, this inversion is rarely a problem because it's a | ||
549 | * directory inode that we are trying to lock here and that means the | ||
550 | * only place that matters is xfs_sync_inodes() and SYNC_DELWRI is | ||
551 | * used. i.e. freeze, remount-ro, quotasync or unmount. | ||
552 | * | ||
553 | * So, if we can't get the iolock without sleeping then just give up | ||
554 | */ | ||
555 | if (!xfs_ilock_nowait(pip, XFS_IOLOCK_EXCL)) { | ||
556 | up_read(&mp->m_peraglock); | ||
557 | return 1; | ||
558 | } | ||
559 | |||
560 | /* If the parent directory is already in the cache, use its AG. */ | ||
561 | item = xfs_mru_cache_lookup(cache, pip->i_ino); | ||
562 | if (item) { | ||
563 | ASSERT(item->ip == pip); | ||
564 | ag = item->ag; | ||
565 | xfs_mru_cache_done(cache); | ||
566 | |||
567 | TRACE_LOOKUP(mp, pip, pip, ag, xfs_filestream_peek_ag(mp, ag)); | ||
568 | err = _xfs_filestream_update_ag(ip, pip, ag); | ||
569 | |||
570 | goto exit; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * Set the starting AG using the rotor for inode32, otherwise | ||
575 | * use the directory inode's AG. | ||
576 | */ | ||
577 | if (mp->m_flags & XFS_MOUNT_32BITINODES) { | ||
578 | rotorstep = xfs_rotorstep; | ||
579 | startag = (mp->m_agfrotor / rotorstep) % mp->m_sb.sb_agcount; | ||
580 | mp->m_agfrotor = (mp->m_agfrotor + 1) % | ||
581 | (mp->m_sb.sb_agcount * rotorstep); | ||
582 | } else | ||
583 | startag = XFS_INO_TO_AGNO(mp, pip->i_ino); | ||
584 | |||
585 | /* Pick a new AG for the parent inode starting at startag. */ | ||
586 | err = _xfs_filestream_pick_ag(mp, startag, &ag, 0, 0); | ||
587 | if (err || ag == NULLAGNUMBER) | ||
588 | goto exit_did_pick; | ||
589 | |||
590 | /* Associate the parent inode with the AG. */ | ||
591 | err = _xfs_filestream_update_ag(pip, NULL, ag); | ||
592 | if (err) | ||
593 | goto exit_did_pick; | ||
594 | |||
595 | /* Associate the file inode with the AG. */ | ||
596 | err = _xfs_filestream_update_ag(ip, pip, ag); | ||
597 | if (err) | ||
598 | goto exit_did_pick; | ||
599 | |||
600 | TRACE_ASSOCIATE(mp, ip, pip, ag, xfs_filestream_peek_ag(mp, ag)); | ||
601 | |||
602 | exit_did_pick: | ||
603 | /* | ||
604 | * If _xfs_filestream_pick_ag() returned a valid AG, remove the | ||
605 | * reference it took on it, since the file and directory will have taken | ||
606 | * their own now if they were successfully cached. | ||
607 | */ | ||
608 | if (ag != NULLAGNUMBER) | ||
609 | xfs_filestream_put_ag(mp, ag); | ||
610 | |||
611 | exit: | ||
612 | xfs_iunlock(pip, XFS_IOLOCK_EXCL); | ||
613 | up_read(&mp->m_peraglock); | ||
614 | return -err; | ||
615 | } | ||
616 | |||
617 | /* | ||
618 | * Pick a new allocation group for the current file and its file stream. This | ||
619 | * function is called by xfs_bmap_filestreams() with the mount point's per-ag | ||
620 | * lock held. | ||
621 | */ | ||
622 | int | ||
623 | xfs_filestream_new_ag( | ||
624 | xfs_bmalloca_t *ap, | ||
625 | xfs_agnumber_t *agp) | ||
626 | { | ||
627 | int flags, err; | ||
628 | xfs_inode_t *ip, *pip = NULL; | ||
629 | xfs_mount_t *mp; | ||
630 | xfs_mru_cache_t *cache; | ||
631 | xfs_extlen_t minlen; | ||
632 | fstrm_item_t *dir, *file; | ||
633 | xfs_agnumber_t ag = NULLAGNUMBER; | ||
634 | |||
635 | ip = ap->ip; | ||
636 | mp = ip->i_mount; | ||
637 | cache = mp->m_filestream; | ||
638 | minlen = ap->alen; | ||
639 | *agp = NULLAGNUMBER; | ||
640 | |||
641 | /* | ||
642 | * Look for the file in the cache, removing it if it's found. Doing | ||
643 | * this allows it to be held across the dir lookup that follows. | ||
644 | */ | ||
645 | file = xfs_mru_cache_remove(cache, ip->i_ino); | ||
646 | if (file) { | ||
647 | ASSERT(ip == file->ip); | ||
648 | |||
649 | /* Save the file's parent inode and old AG number for later. */ | ||
650 | pip = file->pip; | ||
651 | ag = file->ag; | ||
652 | |||
653 | /* Look for the file's directory in the cache. */ | ||
654 | dir = xfs_mru_cache_lookup(cache, pip->i_ino); | ||
655 | if (dir) { | ||
656 | ASSERT(pip == dir->ip); | ||
657 | |||
658 | /* | ||
659 | * If the directory has already moved on to a new AG, | ||
660 | * use that AG as the new AG for the file. Don't | ||
661 | * forget to twiddle the AG refcounts to match the | ||
662 | * movement. | ||
663 | */ | ||
664 | if (dir->ag != file->ag) { | ||
665 | xfs_filestream_put_ag(mp, file->ag); | ||
666 | xfs_filestream_get_ag(mp, dir->ag); | ||
667 | *agp = file->ag = dir->ag; | ||
668 | } | ||
669 | |||
670 | xfs_mru_cache_done(cache); | ||
671 | } | ||
672 | |||
673 | /* | ||
674 | * Put the file back in the cache. If this fails, the free | ||
675 | * function needs to be called to tidy up in the same way as if | ||
676 | * the item had simply expired from the cache. | ||
677 | */ | ||
678 | err = xfs_mru_cache_insert(cache, ip->i_ino, file); | ||
679 | if (err) { | ||
680 | xfs_fstrm_free_func(ip->i_ino, file); | ||
681 | return err; | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * If the file's AG was moved to the directory's new AG, there's | ||
686 | * nothing more to be done. | ||
687 | */ | ||
688 | if (*agp != NULLAGNUMBER) { | ||
689 | TRACE_MOVEAG(mp, ip, pip, | ||
690 | ag, xfs_filestream_peek_ag(mp, ag), | ||
691 | *agp, xfs_filestream_peek_ag(mp, *agp)); | ||
692 | return 0; | ||
693 | } | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * If the file's parent directory is known, take its iolock in exclusive | ||
698 | * mode to prevent two sibling files from racing each other to migrate | ||
699 | * themselves and their parent to different AGs. | ||
700 | */ | ||
701 | if (pip) | ||
702 | xfs_ilock(pip, XFS_IOLOCK_EXCL); | ||
703 | |||
704 | /* | ||
705 | * A new AG needs to be found for the file. If the file's parent | ||
706 | * directory is also known, it will be moved to the new AG as well to | ||
707 | * ensure that files created inside it in future use the new AG. | ||
708 | */ | ||
709 | ag = (ag == NULLAGNUMBER) ? 0 : (ag + 1) % mp->m_sb.sb_agcount; | ||
710 | flags = (ap->userdata ? XFS_PICK_USERDATA : 0) | | ||
711 | (ap->low ? XFS_PICK_LOWSPACE : 0); | ||
712 | |||
713 | err = _xfs_filestream_pick_ag(mp, ag, agp, flags, minlen); | ||
714 | if (err || *agp == NULLAGNUMBER) | ||
715 | goto exit; | ||
716 | |||
717 | /* | ||
718 | * If the file wasn't found in the file cache, then its parent directory | ||
719 | * inode isn't known. For this to have happened, the file must either | ||
720 | * be pre-existing, or it was created long enough ago that its cache | ||
721 | * entry has expired. This isn't the sort of usage that the filestreams | ||
722 | * allocator is trying to optimise, so there's no point trying to track | ||
723 | * its new AG somehow in the filestream data structures. | ||
724 | */ | ||
725 | if (!pip) { | ||
726 | TRACE_ORPHAN(mp, ip, *agp); | ||
727 | goto exit; | ||
728 | } | ||
729 | |||
730 | /* Associate the parent inode with the AG. */ | ||
731 | err = _xfs_filestream_update_ag(pip, NULL, *agp); | ||
732 | if (err) | ||
733 | goto exit; | ||
734 | |||
735 | /* Associate the file inode with the AG. */ | ||
736 | err = _xfs_filestream_update_ag(ip, pip, *agp); | ||
737 | if (err) | ||
738 | goto exit; | ||
739 | |||
740 | TRACE_MOVEAG(mp, ip, pip, NULLAGNUMBER, 0, | ||
741 | *agp, xfs_filestream_peek_ag(mp, *agp)); | ||
742 | |||
743 | exit: | ||
744 | /* | ||
745 | * If _xfs_filestream_pick_ag() returned a valid AG, remove the | ||
746 | * reference it took on it, since the file and directory will have taken | ||
747 | * their own now if they were successfully cached. | ||
748 | */ | ||
749 | if (*agp != NULLAGNUMBER) | ||
750 | xfs_filestream_put_ag(mp, *agp); | ||
751 | else | ||
752 | *agp = 0; | ||
753 | |||
754 | if (pip) | ||
755 | xfs_iunlock(pip, XFS_IOLOCK_EXCL); | ||
756 | |||
757 | return err; | ||
758 | } | ||
759 | |||
760 | /* | ||
761 | * Remove an association between an inode and a filestream object. | ||
762 | * Typically this is done on last close of an unlinked file. | ||
763 | */ | ||
764 | void | ||
765 | xfs_filestream_deassociate( | ||
766 | xfs_inode_t *ip) | ||
767 | { | ||
768 | xfs_mru_cache_t *cache = ip->i_mount->m_filestream; | ||
769 | |||
770 | xfs_mru_cache_delete(cache, ip->i_ino); | ||
771 | } | ||
diff --git a/fs/xfs/xfs_filestream.h b/fs/xfs/xfs_filestream.h new file mode 100644 index 00000000000..f655f7dc334 --- /dev/null +++ b/fs/xfs/xfs_filestream.h | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006-2007 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_FILESTREAM_H__ | ||
19 | #define __XFS_FILESTREAM_H__ | ||
20 | |||
21 | #ifdef __KERNEL__ | ||
22 | |||
23 | struct xfs_mount; | ||
24 | struct xfs_inode; | ||
25 | struct xfs_perag; | ||
26 | struct xfs_bmalloca; | ||
27 | |||
28 | #ifdef XFS_FILESTREAMS_TRACE | ||
29 | #define XFS_FSTRM_KTRACE_INFO 1 | ||
30 | #define XFS_FSTRM_KTRACE_AGSCAN 2 | ||
31 | #define XFS_FSTRM_KTRACE_AGPICK1 3 | ||
32 | #define XFS_FSTRM_KTRACE_AGPICK2 4 | ||
33 | #define XFS_FSTRM_KTRACE_UPDATE 5 | ||
34 | #define XFS_FSTRM_KTRACE_FREE 6 | ||
35 | #define XFS_FSTRM_KTRACE_ITEM_LOOKUP 7 | ||
36 | #define XFS_FSTRM_KTRACE_ASSOCIATE 8 | ||
37 | #define XFS_FSTRM_KTRACE_MOVEAG 9 | ||
38 | #define XFS_FSTRM_KTRACE_ORPHAN 10 | ||
39 | |||
40 | #define XFS_FSTRM_KTRACE_SIZE 16384 | ||
41 | extern ktrace_t *xfs_filestreams_trace_buf; | ||
42 | |||
43 | #endif | ||
44 | |||
45 | /* | ||
46 | * Allocation group filestream associations are tracked with per-ag atomic | ||
47 | * counters. These counters allow _xfs_filestream_pick_ag() to tell whether a | ||
48 | * particular AG already has active filestreams associated with it. The mount | ||
49 | * point's m_peraglock is used to protect these counters from per-ag array | ||
50 | * re-allocation during a growfs operation. When xfs_growfs_data_private() is | ||
51 | * about to reallocate the array, it calls xfs_filestream_flush() with the | ||
52 | * m_peraglock held in write mode. | ||
53 | * | ||
54 | * Since xfs_mru_cache_flush() guarantees that all the free functions for all | ||
55 | * the cache elements have finished executing before it returns, it's safe for | ||
56 | * the free functions to use the atomic counters without m_peraglock protection. | ||
57 | * This allows the implementation of xfs_fstrm_free_func() to be agnostic about | ||
58 | * whether it was called with the m_peraglock held in read mode, write mode or | ||
59 | * not held at all. The race condition this addresses is the following: | ||
60 | * | ||
61 | * - The work queue scheduler fires and pulls a filestream directory cache | ||
62 | * element off the LRU end of the cache for deletion, then gets pre-empted. | ||
63 | * - A growfs operation grabs the m_peraglock in write mode, flushes all the | ||
64 | * remaining items from the cache and reallocates the mount point's per-ag | ||
65 | * array, resetting all the counters to zero. | ||
66 | * - The work queue thread resumes and calls the free function for the element | ||
67 | * it started cleaning up earlier. In the process it decrements the | ||
68 | * filestreams counter for an AG that now has no references. | ||
69 | * | ||
70 | * With a shrinkfs feature, the above scenario could panic the system. | ||
71 | * | ||
72 | * All other uses of the following macros should be protected by either the | ||
73 | * m_peraglock held in read mode, or the cache's internal locking exposed by the | ||
74 | * interval between a call to xfs_mru_cache_lookup() and a call to | ||
75 | * xfs_mru_cache_done(). In addition, the m_peraglock must be held in read mode | ||
76 | * when new elements are added to the cache. | ||
77 | * | ||
78 | * Combined, these locking rules ensure that no associations will ever exist in | ||
79 | * the cache that reference per-ag array elements that have since been | ||
80 | * reallocated. | ||
81 | */ | ||
82 | STATIC_INLINE int | ||
83 | xfs_filestream_peek_ag( | ||
84 | xfs_mount_t *mp, | ||
85 | xfs_agnumber_t agno) | ||
86 | { | ||
87 | return atomic_read(&mp->m_perag[agno].pagf_fstrms); | ||
88 | } | ||
89 | |||
90 | STATIC_INLINE int | ||
91 | xfs_filestream_get_ag( | ||
92 | xfs_mount_t *mp, | ||
93 | xfs_agnumber_t agno) | ||
94 | { | ||
95 | return atomic_inc_return(&mp->m_perag[agno].pagf_fstrms); | ||
96 | } | ||
97 | |||
98 | STATIC_INLINE int | ||
99 | xfs_filestream_put_ag( | ||
100 | xfs_mount_t *mp, | ||
101 | xfs_agnumber_t agno) | ||
102 | { | ||
103 | return atomic_dec_return(&mp->m_perag[agno].pagf_fstrms); | ||
104 | } | ||
105 | |||
106 | /* allocation selection flags */ | ||
107 | typedef enum xfs_fstrm_alloc { | ||
108 | XFS_PICK_USERDATA = 1, | ||
109 | XFS_PICK_LOWSPACE = 2, | ||
110 | } xfs_fstrm_alloc_t; | ||
111 | |||
112 | /* prototypes for filestream.c */ | ||
113 | int xfs_filestream_init(void); | ||
114 | void xfs_filestream_uninit(void); | ||
115 | int xfs_filestream_mount(struct xfs_mount *mp); | ||
116 | void xfs_filestream_unmount(struct xfs_mount *mp); | ||
117 | void xfs_filestream_flush(struct xfs_mount *mp); | ||
118 | xfs_agnumber_t xfs_filestream_lookup_ag(struct xfs_inode *ip); | ||
119 | int xfs_filestream_associate(struct xfs_inode *dip, struct xfs_inode *ip); | ||
120 | void xfs_filestream_deassociate(struct xfs_inode *ip); | ||
121 | int xfs_filestream_new_ag(struct xfs_bmalloca *ap, xfs_agnumber_t *agp); | ||
122 | |||
123 | |||
124 | /* filestreams for the inode? */ | ||
125 | STATIC_INLINE int | ||
126 | xfs_inode_is_filestream( | ||
127 | struct xfs_inode *ip) | ||
128 | { | ||
129 | return (ip->i_mount->m_flags & XFS_MOUNT_FILESTREAMS) || | ||
130 | xfs_iflags_test(ip, XFS_IFILESTREAM) || | ||
131 | (ip->i_d.di_flags & XFS_DIFLAG_FILESTREAM); | ||
132 | } | ||
133 | |||
134 | #endif /* __KERNEL__ */ | ||
135 | |||
136 | #endif /* __XFS_FILESTREAM_H__ */ | ||
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 1335449841c..ec3c9c27e0d 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -66,6 +66,7 @@ struct fsxattr { | |||
66 | #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ | 66 | #define XFS_XFLAG_EXTSIZE 0x00000800 /* extent size allocator hint */ |
67 | #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ | 67 | #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ |
68 | #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ | 68 | #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ |
69 | #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ | ||
69 | #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ | 70 | #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ |
70 | 71 | ||
71 | /* | 72 | /* |
@@ -238,6 +239,7 @@ typedef struct xfs_fsop_resblks { | |||
238 | #define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ | 239 | #define XFS_FSOP_GEOM_FLAGS_LOGV2 0x0100 /* log format version 2 */ |
239 | #define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ | 240 | #define XFS_FSOP_GEOM_FLAGS_SECTOR 0x0200 /* sector sizes >1BB */ |
240 | #define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */ | 241 | #define XFS_FSOP_GEOM_FLAGS_ATTR2 0x0400 /* inline attributes rework */ |
242 | #define XFS_FSOP_GEOM_FLAGS_LAZYSB 0x4000 /* lazy superblock counters */ | ||
241 | 243 | ||
242 | 244 | ||
243 | /* | 245 | /* |
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index b599e6be9ec..432e82347ed 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "xfs_trans_space.h" | 44 | #include "xfs_trans_space.h" |
45 | #include "xfs_rtalloc.h" | 45 | #include "xfs_rtalloc.h" |
46 | #include "xfs_rw.h" | 46 | #include "xfs_rw.h" |
47 | #include "xfs_filestream.h" | ||
47 | 48 | ||
48 | /* | 49 | /* |
49 | * File system operations | 50 | * File system operations |
@@ -94,6 +95,8 @@ xfs_fs_geometry( | |||
94 | XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) | | 95 | XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) | |
95 | (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? | 96 | (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? |
96 | XFS_FSOP_GEOM_FLAGS_SECTOR : 0) | | 97 | XFS_FSOP_GEOM_FLAGS_SECTOR : 0) | |
98 | (xfs_sb_version_haslazysbcount(&mp->m_sb) ? | ||
99 | XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) | | ||
97 | (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ? | 100 | (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ? |
98 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); | 101 | XFS_FSOP_GEOM_FLAGS_ATTR2 : 0); |
99 | geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? | 102 | geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ? |
@@ -140,6 +143,8 @@ xfs_growfs_data_private( | |||
140 | pct = in->imaxpct; | 143 | pct = in->imaxpct; |
141 | if (nb < mp->m_sb.sb_dblocks || pct < 0 || pct > 100) | 144 | if (nb < mp->m_sb.sb_dblocks || pct < 0 || pct > 100) |
142 | return XFS_ERROR(EINVAL); | 145 | return XFS_ERROR(EINVAL); |
146 | if ((error = xfs_sb_validate_fsb_count(&mp->m_sb, nb))) | ||
147 | return error; | ||
143 | dpct = pct - mp->m_sb.sb_imax_pct; | 148 | dpct = pct - mp->m_sb.sb_imax_pct; |
144 | error = xfs_read_buf(mp, mp->m_ddev_targp, | 149 | error = xfs_read_buf(mp, mp->m_ddev_targp, |
145 | XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), | 150 | XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), |
@@ -161,6 +166,7 @@ xfs_growfs_data_private( | |||
161 | new = nb - mp->m_sb.sb_dblocks; | 166 | new = nb - mp->m_sb.sb_dblocks; |
162 | oagcount = mp->m_sb.sb_agcount; | 167 | oagcount = mp->m_sb.sb_agcount; |
163 | if (nagcount > oagcount) { | 168 | if (nagcount > oagcount) { |
169 | xfs_filestream_flush(mp); | ||
164 | down_write(&mp->m_peraglock); | 170 | down_write(&mp->m_peraglock); |
165 | mp->m_perag = kmem_realloc(mp->m_perag, | 171 | mp->m_perag = kmem_realloc(mp->m_perag, |
166 | sizeof(xfs_perag_t) * nagcount, | 172 | sizeof(xfs_perag_t) * nagcount, |
@@ -173,6 +179,7 @@ xfs_growfs_data_private( | |||
173 | up_write(&mp->m_peraglock); | 179 | up_write(&mp->m_peraglock); |
174 | } | 180 | } |
175 | tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); | 181 | tp = xfs_trans_alloc(mp, XFS_TRANS_GROWFS); |
182 | tp->t_flags |= XFS_TRANS_RESERVE; | ||
176 | if ((error = xfs_trans_reserve(tp, XFS_GROWFS_SPACE_RES(mp), | 183 | if ((error = xfs_trans_reserve(tp, XFS_GROWFS_SPACE_RES(mp), |
177 | XFS_GROWDATA_LOG_RES(mp), 0, 0, 0))) { | 184 | XFS_GROWDATA_LOG_RES(mp), 0, 0, 0))) { |
178 | xfs_trans_cancel(tp, 0); | 185 | xfs_trans_cancel(tp, 0); |
@@ -328,6 +335,7 @@ xfs_growfs_data_private( | |||
328 | be32_add(&agf->agf_length, new); | 335 | be32_add(&agf->agf_length, new); |
329 | ASSERT(be32_to_cpu(agf->agf_length) == | 336 | ASSERT(be32_to_cpu(agf->agf_length) == |
330 | be32_to_cpu(agi->agi_length)); | 337 | be32_to_cpu(agi->agi_length)); |
338 | xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH); | ||
331 | /* | 339 | /* |
332 | * Free the new space. | 340 | * Free the new space. |
333 | */ | 341 | */ |
@@ -494,8 +502,9 @@ xfs_reserve_blocks( | |||
494 | unsigned long s; | 502 | unsigned long s; |
495 | 503 | ||
496 | /* If inval is null, report current values and return */ | 504 | /* If inval is null, report current values and return */ |
497 | |||
498 | if (inval == (__uint64_t *)NULL) { | 505 | if (inval == (__uint64_t *)NULL) { |
506 | if (!outval) | ||
507 | return EINVAL; | ||
499 | outval->resblks = mp->m_resblks; | 508 | outval->resblks = mp->m_resblks; |
500 | outval->resblks_avail = mp->m_resblks_avail; | 509 | outval->resblks_avail = mp->m_resblks_avail; |
501 | return 0; | 510 | return 0; |
@@ -558,8 +567,10 @@ retry: | |||
558 | } | 567 | } |
559 | } | 568 | } |
560 | out: | 569 | out: |
561 | outval->resblks = mp->m_resblks; | 570 | if (outval) { |
562 | outval->resblks_avail = mp->m_resblks_avail; | 571 | outval->resblks = mp->m_resblks; |
572 | outval->resblks_avail = mp->m_resblks_avail; | ||
573 | } | ||
563 | XFS_SB_UNLOCK(mp, s); | 574 | XFS_SB_UNLOCK(mp, s); |
564 | 575 | ||
565 | if (fdblks_delta) { | 576 | if (fdblks_delta) { |
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index b5feb3e7711..f943368c9b9 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
@@ -123,6 +123,7 @@ xfs_ialloc_ag_alloc( | |||
123 | int blks_per_cluster; /* fs blocks per inode cluster */ | 123 | int blks_per_cluster; /* fs blocks per inode cluster */ |
124 | xfs_btree_cur_t *cur; /* inode btree cursor */ | 124 | xfs_btree_cur_t *cur; /* inode btree cursor */ |
125 | xfs_daddr_t d; /* disk addr of buffer */ | 125 | xfs_daddr_t d; /* disk addr of buffer */ |
126 | xfs_agnumber_t agno; | ||
126 | int error; | 127 | int error; |
127 | xfs_buf_t *fbuf; /* new free inodes' buffer */ | 128 | xfs_buf_t *fbuf; /* new free inodes' buffer */ |
128 | xfs_dinode_t *free; /* new free inode structure */ | 129 | xfs_dinode_t *free; /* new free inode structure */ |
@@ -302,15 +303,15 @@ xfs_ialloc_ag_alloc( | |||
302 | } | 303 | } |
303 | be32_add(&agi->agi_count, newlen); | 304 | be32_add(&agi->agi_count, newlen); |
304 | be32_add(&agi->agi_freecount, newlen); | 305 | be32_add(&agi->agi_freecount, newlen); |
306 | agno = be32_to_cpu(agi->agi_seqno); | ||
305 | down_read(&args.mp->m_peraglock); | 307 | down_read(&args.mp->m_peraglock); |
306 | args.mp->m_perag[be32_to_cpu(agi->agi_seqno)].pagi_freecount += newlen; | 308 | args.mp->m_perag[agno].pagi_freecount += newlen; |
307 | up_read(&args.mp->m_peraglock); | 309 | up_read(&args.mp->m_peraglock); |
308 | agi->agi_newino = cpu_to_be32(newino); | 310 | agi->agi_newino = cpu_to_be32(newino); |
309 | /* | 311 | /* |
310 | * Insert records describing the new inode chunk into the btree. | 312 | * Insert records describing the new inode chunk into the btree. |
311 | */ | 313 | */ |
312 | cur = xfs_btree_init_cursor(args.mp, tp, agbp, | 314 | cur = xfs_btree_init_cursor(args.mp, tp, agbp, agno, |
313 | be32_to_cpu(agi->agi_seqno), | ||
314 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); | 315 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); |
315 | for (thisino = newino; | 316 | for (thisino = newino; |
316 | thisino < newino + newlen; | 317 | thisino < newino + newlen; |
@@ -1387,6 +1388,7 @@ xfs_ialloc_read_agi( | |||
1387 | pag = &mp->m_perag[agno]; | 1388 | pag = &mp->m_perag[agno]; |
1388 | if (!pag->pagi_init) { | 1389 | if (!pag->pagi_init) { |
1389 | pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); | 1390 | pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); |
1391 | pag->pagi_count = be32_to_cpu(agi->agi_count); | ||
1390 | pag->pagi_init = 1; | 1392 | pag->pagi_init = 1; |
1391 | } else { | 1393 | } else { |
1392 | /* | 1394 | /* |
@@ -1410,3 +1412,23 @@ xfs_ialloc_read_agi( | |||
1410 | *bpp = bp; | 1412 | *bpp = bp; |
1411 | return 0; | 1413 | return 0; |
1412 | } | 1414 | } |
1415 | |||
1416 | /* | ||
1417 | * Read in the agi to initialise the per-ag data in the mount structure | ||
1418 | */ | ||
1419 | int | ||
1420 | xfs_ialloc_pagi_init( | ||
1421 | xfs_mount_t *mp, /* file system mount structure */ | ||
1422 | xfs_trans_t *tp, /* transaction pointer */ | ||
1423 | xfs_agnumber_t agno) /* allocation group number */ | ||
1424 | { | ||
1425 | xfs_buf_t *bp = NULL; | ||
1426 | int error; | ||
1427 | |||
1428 | error = xfs_ialloc_read_agi(mp, tp, agno, &bp); | ||
1429 | if (error) | ||
1430 | return error; | ||
1431 | if (bp) | ||
1432 | xfs_trans_brelse(tp, bp); | ||
1433 | return 0; | ||
1434 | } | ||
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h index 7f5debe1acb..97f4040931c 100644 --- a/fs/xfs/xfs_ialloc.h +++ b/fs/xfs/xfs_ialloc.h | |||
@@ -149,6 +149,16 @@ xfs_ialloc_read_agi( | |||
149 | xfs_agnumber_t agno, /* allocation group number */ | 149 | xfs_agnumber_t agno, /* allocation group number */ |
150 | struct xfs_buf **bpp); /* allocation group hdr buf */ | 150 | struct xfs_buf **bpp); /* allocation group hdr buf */ |
151 | 151 | ||
152 | /* | ||
153 | * Read in the allocation group header to initialise the per-ag data | ||
154 | * in the mount structure | ||
155 | */ | ||
156 | int | ||
157 | xfs_ialloc_pagi_init( | ||
158 | struct xfs_mount *mp, /* file system mount structure */ | ||
159 | struct xfs_trans *tp, /* transaction pointer */ | ||
160 | xfs_agnumber_t agno); /* allocation group number */ | ||
161 | |||
152 | #endif /* __KERNEL__ */ | 162 | #endif /* __KERNEL__ */ |
153 | 163 | ||
154 | #endif /* __XFS_IALLOC_H__ */ | 164 | #endif /* __XFS_IALLOC_H__ */ |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 3ca5d43b834..cdc4c28926d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -48,7 +48,9 @@ | |||
48 | #include "xfs_dir2_trace.h" | 48 | #include "xfs_dir2_trace.h" |
49 | #include "xfs_quota.h" | 49 | #include "xfs_quota.h" |
50 | #include "xfs_acl.h" | 50 | #include "xfs_acl.h" |
51 | #include "xfs_filestream.h" | ||
51 | 52 | ||
53 | #include <linux/log2.h> | ||
52 | 54 | ||
53 | kmem_zone_t *xfs_ifork_zone; | 55 | kmem_zone_t *xfs_ifork_zone; |
54 | kmem_zone_t *xfs_inode_zone; | 56 | kmem_zone_t *xfs_inode_zone; |
@@ -643,8 +645,7 @@ xfs_iformat_extents( | |||
643 | ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), | 645 | ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), |
644 | ARCH_CONVERT); | 646 | ARCH_CONVERT); |
645 | } | 647 | } |
646 | xfs_bmap_trace_exlist("xfs_iformat_extents", ip, nex, | 648 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); |
647 | whichfork); | ||
648 | if (whichfork != XFS_DATA_FORK || | 649 | if (whichfork != XFS_DATA_FORK || |
649 | XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) | 650 | XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE) |
650 | if (unlikely(xfs_check_nostate_extents( | 651 | if (unlikely(xfs_check_nostate_extents( |
@@ -817,6 +818,8 @@ _xfs_dic2xflags( | |||
817 | flags |= XFS_XFLAG_EXTSZINHERIT; | 818 | flags |= XFS_XFLAG_EXTSZINHERIT; |
818 | if (di_flags & XFS_DIFLAG_NODEFRAG) | 819 | if (di_flags & XFS_DIFLAG_NODEFRAG) |
819 | flags |= XFS_XFLAG_NODEFRAG; | 820 | flags |= XFS_XFLAG_NODEFRAG; |
821 | if (di_flags & XFS_DIFLAG_FILESTREAM) | ||
822 | flags |= XFS_XFLAG_FILESTREAM; | ||
820 | } | 823 | } |
821 | 824 | ||
822 | return flags; | 825 | return flags; |
@@ -1074,6 +1077,11 @@ xfs_iread_extents( | |||
1074 | * also returns the [locked] bp pointing to the head of the freelist | 1077 | * also returns the [locked] bp pointing to the head of the freelist |
1075 | * as ialloc_context. The caller should hold this buffer across | 1078 | * as ialloc_context. The caller should hold this buffer across |
1076 | * the commit and pass it back into this routine on the second call. | 1079 | * the commit and pass it back into this routine on the second call. |
1080 | * | ||
1081 | * If we are allocating quota inodes, we do not have a parent inode | ||
1082 | * to attach to or associate with (i.e. pip == NULL) because they | ||
1083 | * are not linked into the directory structure - they are attached | ||
1084 | * directly to the superblock - and so have no parent. | ||
1077 | */ | 1085 | */ |
1078 | int | 1086 | int |
1079 | xfs_ialloc( | 1087 | xfs_ialloc( |
@@ -1099,7 +1107,7 @@ xfs_ialloc( | |||
1099 | * Call the space management code to pick | 1107 | * Call the space management code to pick |
1100 | * the on-disk inode to be allocated. | 1108 | * the on-disk inode to be allocated. |
1101 | */ | 1109 | */ |
1102 | error = xfs_dialloc(tp, pip->i_ino, mode, okalloc, | 1110 | error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, |
1103 | ialloc_context, call_again, &ino); | 1111 | ialloc_context, call_again, &ino); |
1104 | if (error != 0) { | 1112 | if (error != 0) { |
1105 | return error; | 1113 | return error; |
@@ -1150,10 +1158,10 @@ xfs_ialloc( | |||
1150 | /* | 1158 | /* |
1151 | * Project ids won't be stored on disk if we are using a version 1 inode. | 1159 | * Project ids won't be stored on disk if we are using a version 1 inode. |
1152 | */ | 1160 | */ |
1153 | if ( (prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) | 1161 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) |
1154 | xfs_bump_ino_vers2(tp, ip); | 1162 | xfs_bump_ino_vers2(tp, ip); |
1155 | 1163 | ||
1156 | if (XFS_INHERIT_GID(pip, vp->v_vfsp)) { | 1164 | if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { |
1157 | ip->i_d.di_gid = pip->i_d.di_gid; | 1165 | ip->i_d.di_gid = pip->i_d.di_gid; |
1158 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { | 1166 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { |
1159 | ip->i_d.di_mode |= S_ISGID; | 1167 | ip->i_d.di_mode |= S_ISGID; |
@@ -1195,8 +1203,16 @@ xfs_ialloc( | |||
1195 | flags |= XFS_ILOG_DEV; | 1203 | flags |= XFS_ILOG_DEV; |
1196 | break; | 1204 | break; |
1197 | case S_IFREG: | 1205 | case S_IFREG: |
1206 | if (pip && xfs_inode_is_filestream(pip)) { | ||
1207 | error = xfs_filestream_associate(pip, ip); | ||
1208 | if (error < 0) | ||
1209 | return -error; | ||
1210 | if (!error) | ||
1211 | xfs_iflags_set(ip, XFS_IFILESTREAM); | ||
1212 | } | ||
1213 | /* fall through */ | ||
1198 | case S_IFDIR: | 1214 | case S_IFDIR: |
1199 | if (unlikely(pip->i_d.di_flags & XFS_DIFLAG_ANY)) { | 1215 | if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { |
1200 | uint di_flags = 0; | 1216 | uint di_flags = 0; |
1201 | 1217 | ||
1202 | if ((mode & S_IFMT) == S_IFDIR) { | 1218 | if ((mode & S_IFMT) == S_IFDIR) { |
@@ -1233,6 +1249,8 @@ xfs_ialloc( | |||
1233 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) && | 1249 | if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) && |
1234 | xfs_inherit_nodefrag) | 1250 | xfs_inherit_nodefrag) |
1235 | di_flags |= XFS_DIFLAG_NODEFRAG; | 1251 | di_flags |= XFS_DIFLAG_NODEFRAG; |
1252 | if (pip->i_d.di_flags & XFS_DIFLAG_FILESTREAM) | ||
1253 | di_flags |= XFS_DIFLAG_FILESTREAM; | ||
1236 | ip->i_d.di_flags |= di_flags; | 1254 | ip->i_d.di_flags |= di_flags; |
1237 | } | 1255 | } |
1238 | /* FALLTHROUGH */ | 1256 | /* FALLTHROUGH */ |
@@ -2875,9 +2893,6 @@ xfs_iextents_copy( | |||
2875 | int copied; | 2893 | int copied; |
2876 | xfs_bmbt_rec_t *dest_ep; | 2894 | xfs_bmbt_rec_t *dest_ep; |
2877 | xfs_bmbt_rec_t *ep; | 2895 | xfs_bmbt_rec_t *ep; |
2878 | #ifdef XFS_BMAP_TRACE | ||
2879 | static char fname[] = "xfs_iextents_copy"; | ||
2880 | #endif | ||
2881 | int i; | 2896 | int i; |
2882 | xfs_ifork_t *ifp; | 2897 | xfs_ifork_t *ifp; |
2883 | int nrecs; | 2898 | int nrecs; |
@@ -2888,7 +2903,7 @@ xfs_iextents_copy( | |||
2888 | ASSERT(ifp->if_bytes > 0); | 2903 | ASSERT(ifp->if_bytes > 0); |
2889 | 2904 | ||
2890 | nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 2905 | nrecs = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
2891 | xfs_bmap_trace_exlist(fname, ip, nrecs, whichfork); | 2906 | XFS_BMAP_TRACE_EXLIST(ip, nrecs, whichfork); |
2892 | ASSERT(nrecs > 0); | 2907 | ASSERT(nrecs > 0); |
2893 | 2908 | ||
2894 | /* | 2909 | /* |
@@ -4184,7 +4199,7 @@ xfs_iext_realloc_direct( | |||
4184 | ifp->if_bytes = new_size; | 4199 | ifp->if_bytes = new_size; |
4185 | return; | 4200 | return; |
4186 | } | 4201 | } |
4187 | if ((new_size & (new_size - 1)) != 0) { | 4202 | if (!is_power_of_2(new_size)){ |
4188 | rnew_size = xfs_iroundup(new_size); | 4203 | rnew_size = xfs_iroundup(new_size); |
4189 | } | 4204 | } |
4190 | if (rnew_size != ifp->if_real_bytes) { | 4205 | if (rnew_size != ifp->if_real_bytes) { |
@@ -4207,7 +4222,7 @@ xfs_iext_realloc_direct( | |||
4207 | */ | 4222 | */ |
4208 | else { | 4223 | else { |
4209 | new_size += ifp->if_bytes; | 4224 | new_size += ifp->if_bytes; |
4210 | if ((new_size & (new_size - 1)) != 0) { | 4225 | if (!is_power_of_2(new_size)) { |
4211 | rnew_size = xfs_iroundup(new_size); | 4226 | rnew_size = xfs_iroundup(new_size); |
4212 | } | 4227 | } |
4213 | xfs_iext_inline_to_direct(ifp, rnew_size); | 4228 | xfs_iext_inline_to_direct(ifp, rnew_size); |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index f75afecef8e..012dfd4a958 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -379,6 +379,7 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
379 | #define XFS_ISTALE 0x0010 /* inode has been staled */ | 379 | #define XFS_ISTALE 0x0010 /* inode has been staled */ |
380 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ | 380 | #define XFS_IRECLAIMABLE 0x0020 /* inode can be reclaimed */ |
381 | #define XFS_INEW 0x0040 | 381 | #define XFS_INEW 0x0040 |
382 | #define XFS_IFILESTREAM 0x0080 /* inode is in a filestream directory */ | ||
382 | 383 | ||
383 | /* | 384 | /* |
384 | * Flags for inode locking. | 385 | * Flags for inode locking. |
@@ -414,19 +415,22 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | |||
414 | * gets a lockdep subclass of 1 and the second lock will have a lockdep | 415 | * gets a lockdep subclass of 1 and the second lock will have a lockdep |
415 | * subclass of 0. | 416 | * subclass of 0. |
416 | * | 417 | * |
417 | * XFS_I[O]LOCK_INUMORDER - for locking several inodes at the some time | 418 | * XFS_LOCK_INUMORDER - for locking several inodes at the some time |
418 | * with xfs_lock_inodes(). This flag is used as the starting subclass | 419 | * with xfs_lock_inodes(). This flag is used as the starting subclass |
419 | * and each subsequent lock acquired will increment the subclass by one. | 420 | * and each subsequent lock acquired will increment the subclass by one. |
420 | * So the first lock acquired will have a lockdep subclass of 2, the | 421 | * So the first lock acquired will have a lockdep subclass of 2, the |
421 | * second lock will have a lockdep subclass of 3, and so on. | 422 | * second lock will have a lockdep subclass of 3, and so on. It is |
423 | * the responsibility of the class builder to shift this to the correct | ||
424 | * portion of the lock_mode lockdep mask. | ||
422 | */ | 425 | */ |
426 | #define XFS_LOCK_PARENT 1 | ||
427 | #define XFS_LOCK_INUMORDER 2 | ||
428 | |||
423 | #define XFS_IOLOCK_SHIFT 16 | 429 | #define XFS_IOLOCK_SHIFT 16 |
424 | #define XFS_IOLOCK_PARENT (1 << XFS_IOLOCK_SHIFT) | 430 | #define XFS_IOLOCK_PARENT (XFS_LOCK_PARENT << XFS_IOLOCK_SHIFT) |
425 | #define XFS_IOLOCK_INUMORDER (2 << XFS_IOLOCK_SHIFT) | ||
426 | 431 | ||
427 | #define XFS_ILOCK_SHIFT 24 | 432 | #define XFS_ILOCK_SHIFT 24 |
428 | #define XFS_ILOCK_PARENT (1 << XFS_ILOCK_SHIFT) | 433 | #define XFS_ILOCK_PARENT (XFS_LOCK_PARENT << XFS_ILOCK_SHIFT) |
429 | #define XFS_ILOCK_INUMORDER (2 << XFS_ILOCK_SHIFT) | ||
430 | 434 | ||
431 | #define XFS_IOLOCK_DEP_MASK 0x00ff0000 | 435 | #define XFS_IOLOCK_DEP_MASK 0x00ff0000 |
432 | #define XFS_ILOCK_DEP_MASK 0xff000000 | 436 | #define XFS_ILOCK_DEP_MASK 0xff000000 |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3f2b9f2a7b9..bf57b75acb9 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -451,19 +451,14 @@ xfs_iomap_write_direct( | |||
451 | return XFS_ERROR(error); | 451 | return XFS_ERROR(error); |
452 | 452 | ||
453 | rt = XFS_IS_REALTIME_INODE(ip); | 453 | rt = XFS_IS_REALTIME_INODE(ip); |
454 | if (unlikely(rt)) { | 454 | extsz = xfs_get_extsz_hint(ip); |
455 | if (!(extsz = ip->i_d.di_extsize)) | ||
456 | extsz = mp->m_sb.sb_rextsize; | ||
457 | } else { | ||
458 | extsz = ip->i_d.di_extsize; | ||
459 | } | ||
460 | 455 | ||
461 | isize = ip->i_size; | 456 | isize = ip->i_size; |
462 | if (io->io_new_size > isize) | 457 | if (io->io_new_size > isize) |
463 | isize = io->io_new_size; | 458 | isize = io->io_new_size; |
464 | 459 | ||
465 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 460 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
466 | last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); | 461 | last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); |
467 | if ((offset + count) > isize) { | 462 | if ((offset + count) > isize) { |
468 | error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz, | 463 | error = xfs_iomap_eof_align_last_fsb(mp, io, isize, extsz, |
469 | &last_fsb); | 464 | &last_fsb); |
@@ -489,13 +484,13 @@ xfs_iomap_write_direct( | |||
489 | if (unlikely(rt)) { | 484 | if (unlikely(rt)) { |
490 | resrtextents = qblocks = resaligned; | 485 | resrtextents = qblocks = resaligned; |
491 | resrtextents /= mp->m_sb.sb_rextsize; | 486 | resrtextents /= mp->m_sb.sb_rextsize; |
492 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); | 487 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); |
493 | quota_flag = XFS_QMOPT_RES_RTBLKS; | 488 | quota_flag = XFS_QMOPT_RES_RTBLKS; |
494 | } else { | 489 | } else { |
495 | resrtextents = 0; | 490 | resrtextents = 0; |
496 | resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned); | 491 | resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned); |
497 | quota_flag = XFS_QMOPT_RES_REGBLKS; | 492 | quota_flag = XFS_QMOPT_RES_REGBLKS; |
498 | } | 493 | } |
499 | 494 | ||
500 | /* | 495 | /* |
501 | * Allocate and setup the transaction | 496 | * Allocate and setup the transaction |
@@ -666,13 +661,7 @@ xfs_iomap_write_delay( | |||
666 | if (error) | 661 | if (error) |
667 | return XFS_ERROR(error); | 662 | return XFS_ERROR(error); |
668 | 663 | ||
669 | if (XFS_IS_REALTIME_INODE(ip)) { | 664 | extsz = xfs_get_extsz_hint(ip); |
670 | if (!(extsz = ip->i_d.di_extsize)) | ||
671 | extsz = mp->m_sb.sb_rextsize; | ||
672 | } else { | ||
673 | extsz = ip->i_d.di_extsize; | ||
674 | } | ||
675 | |||
676 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 665 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
677 | 666 | ||
678 | retry: | 667 | retry: |
@@ -788,18 +777,12 @@ xfs_iomap_write_allocate( | |||
788 | nimaps = 0; | 777 | nimaps = 0; |
789 | while (nimaps == 0) { | 778 | while (nimaps == 0) { |
790 | tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); | 779 | tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); |
780 | tp->t_flags |= XFS_TRANS_RESERVE; | ||
791 | nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); | 781 | nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); |
792 | error = xfs_trans_reserve(tp, nres, | 782 | error = xfs_trans_reserve(tp, nres, |
793 | XFS_WRITE_LOG_RES(mp), | 783 | XFS_WRITE_LOG_RES(mp), |
794 | 0, XFS_TRANS_PERM_LOG_RES, | 784 | 0, XFS_TRANS_PERM_LOG_RES, |
795 | XFS_WRITE_LOG_COUNT); | 785 | XFS_WRITE_LOG_COUNT); |
796 | if (error == ENOSPC) { | ||
797 | error = xfs_trans_reserve(tp, 0, | ||
798 | XFS_WRITE_LOG_RES(mp), | ||
799 | 0, | ||
800 | XFS_TRANS_PERM_LOG_RES, | ||
801 | XFS_WRITE_LOG_COUNT); | ||
802 | } | ||
803 | if (error) { | 786 | if (error) { |
804 | xfs_trans_cancel(tp, 0); | 787 | xfs_trans_cancel(tp, 0); |
805 | return XFS_ERROR(error); | 788 | return XFS_ERROR(error); |
@@ -917,8 +900,8 @@ xfs_iomap_write_unwritten( | |||
917 | * from unwritten to real. Do allocations in a loop until | 900 | * from unwritten to real. Do allocations in a loop until |
918 | * we have covered the range passed in. | 901 | * we have covered the range passed in. |
919 | */ | 902 | */ |
920 | |||
921 | tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); | 903 | tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); |
904 | tp->t_flags |= XFS_TRANS_RESERVE; | ||
922 | error = xfs_trans_reserve(tp, resblks, | 905 | error = xfs_trans_reserve(tp, resblks, |
923 | XFS_WRITE_LOG_RES(mp), 0, | 906 | XFS_WRITE_LOG_RES(mp), 0, |
924 | XFS_TRANS_PERM_LOG_RES, | 907 | XFS_TRANS_PERM_LOG_RES, |
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index e725ddd3de5..4c2454bcc71 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -202,6 +202,16 @@ xfs_bulkstat_one_dinode( | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | STATIC int | ||
206 | xfs_bulkstat_one_fmt( | ||
207 | void __user *ubuffer, | ||
208 | const xfs_bstat_t *buffer) | ||
209 | { | ||
210 | if (copy_to_user(ubuffer, buffer, sizeof(*buffer))) | ||
211 | return -EFAULT; | ||
212 | return sizeof(*buffer); | ||
213 | } | ||
214 | |||
205 | /* | 215 | /* |
206 | * Return stat information for one inode. | 216 | * Return stat information for one inode. |
207 | * Return 0 if ok, else errno. | 217 | * Return 0 if ok, else errno. |
@@ -221,6 +231,7 @@ xfs_bulkstat_one( | |||
221 | xfs_bstat_t *buf; /* return buffer */ | 231 | xfs_bstat_t *buf; /* return buffer */ |
222 | int error = 0; /* error value */ | 232 | int error = 0; /* error value */ |
223 | xfs_dinode_t *dip; /* dinode inode pointer */ | 233 | xfs_dinode_t *dip; /* dinode inode pointer */ |
234 | bulkstat_one_fmt_pf formatter = private_data ? : xfs_bulkstat_one_fmt; | ||
224 | 235 | ||
225 | dip = (xfs_dinode_t *)dibuff; | 236 | dip = (xfs_dinode_t *)dibuff; |
226 | *stat = BULKSTAT_RV_NOTHING; | 237 | *stat = BULKSTAT_RV_NOTHING; |
@@ -243,14 +254,15 @@ xfs_bulkstat_one( | |||
243 | xfs_bulkstat_one_dinode(mp, ino, dip, buf); | 254 | xfs_bulkstat_one_dinode(mp, ino, dip, buf); |
244 | } | 255 | } |
245 | 256 | ||
246 | if (copy_to_user(buffer, buf, sizeof(*buf))) { | 257 | error = formatter(buffer, buf); |
258 | if (error < 0) { | ||
247 | error = EFAULT; | 259 | error = EFAULT; |
248 | goto out_free; | 260 | goto out_free; |
249 | } | 261 | } |
250 | 262 | ||
251 | *stat = BULKSTAT_RV_DIDONE; | 263 | *stat = BULKSTAT_RV_DIDONE; |
252 | if (ubused) | 264 | if (ubused) |
253 | *ubused = sizeof(*buf); | 265 | *ubused = error; |
254 | 266 | ||
255 | out_free: | 267 | out_free: |
256 | kmem_free(buf, sizeof(*buf)); | 268 | kmem_free(buf, sizeof(*buf)); |
@@ -748,6 +760,19 @@ xfs_bulkstat_single( | |||
748 | return 0; | 760 | return 0; |
749 | } | 761 | } |
750 | 762 | ||
763 | int | ||
764 | xfs_inumbers_fmt( | ||
765 | void __user *ubuffer, /* buffer to write to */ | ||
766 | const xfs_inogrp_t *buffer, /* buffer to read from */ | ||
767 | long count, /* # of elements to read */ | ||
768 | long *written) /* # of bytes written */ | ||
769 | { | ||
770 | if (copy_to_user(ubuffer, buffer, count * sizeof(*buffer))) | ||
771 | return -EFAULT; | ||
772 | *written = count * sizeof(*buffer); | ||
773 | return 0; | ||
774 | } | ||
775 | |||
751 | /* | 776 | /* |
752 | * Return inode number table for the filesystem. | 777 | * Return inode number table for the filesystem. |
753 | */ | 778 | */ |
@@ -756,7 +781,8 @@ xfs_inumbers( | |||
756 | xfs_mount_t *mp, /* mount point for filesystem */ | 781 | xfs_mount_t *mp, /* mount point for filesystem */ |
757 | xfs_ino_t *lastino, /* last inode returned */ | 782 | xfs_ino_t *lastino, /* last inode returned */ |
758 | int *count, /* size of buffer/count returned */ | 783 | int *count, /* size of buffer/count returned */ |
759 | xfs_inogrp_t __user *ubuffer)/* buffer with inode descriptions */ | 784 | void __user *ubuffer,/* buffer with inode descriptions */ |
785 | inumbers_fmt_pf formatter) | ||
760 | { | 786 | { |
761 | xfs_buf_t *agbp; | 787 | xfs_buf_t *agbp; |
762 | xfs_agino_t agino; | 788 | xfs_agino_t agino; |
@@ -835,12 +861,12 @@ xfs_inumbers( | |||
835 | bufidx++; | 861 | bufidx++; |
836 | left--; | 862 | left--; |
837 | if (bufidx == bcount) { | 863 | if (bufidx == bcount) { |
838 | if (copy_to_user(ubuffer, buffer, | 864 | long written; |
839 | bufidx * sizeof(*buffer))) { | 865 | if (formatter(ubuffer, buffer, bufidx, &written)) { |
840 | error = XFS_ERROR(EFAULT); | 866 | error = XFS_ERROR(EFAULT); |
841 | break; | 867 | break; |
842 | } | 868 | } |
843 | ubuffer += bufidx; | 869 | ubuffer += written; |
844 | *count += bufidx; | 870 | *count += bufidx; |
845 | bufidx = 0; | 871 | bufidx = 0; |
846 | } | 872 | } |
@@ -862,8 +888,8 @@ xfs_inumbers( | |||
862 | } | 888 | } |
863 | if (!error) { | 889 | if (!error) { |
864 | if (bufidx) { | 890 | if (bufidx) { |
865 | if (copy_to_user(ubuffer, buffer, | 891 | long written; |
866 | bufidx * sizeof(*buffer))) | 892 | if (formatter(ubuffer, buffer, bufidx, &written)) |
867 | error = XFS_ERROR(EFAULT); | 893 | error = XFS_ERROR(EFAULT); |
868 | else | 894 | else |
869 | *count += bufidx; | 895 | *count += bufidx; |
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index f25a28862a1..a1f18fce9b7 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h | |||
@@ -69,6 +69,10 @@ xfs_bulkstat_single( | |||
69 | char __user *buffer, | 69 | char __user *buffer, |
70 | int *done); | 70 | int *done); |
71 | 71 | ||
72 | typedef int (*bulkstat_one_fmt_pf)( /* used size in bytes or negative error */ | ||
73 | void __user *ubuffer, /* buffer to write to */ | ||
74 | const xfs_bstat_t *buffer); /* buffer to read from */ | ||
75 | |||
72 | int | 76 | int |
73 | xfs_bulkstat_one( | 77 | xfs_bulkstat_one( |
74 | xfs_mount_t *mp, | 78 | xfs_mount_t *mp, |
@@ -86,11 +90,25 @@ xfs_internal_inum( | |||
86 | xfs_mount_t *mp, | 90 | xfs_mount_t *mp, |
87 | xfs_ino_t ino); | 91 | xfs_ino_t ino); |
88 | 92 | ||
93 | typedef int (*inumbers_fmt_pf)( | ||
94 | void __user *ubuffer, /* buffer to write to */ | ||
95 | const xfs_inogrp_t *buffer, /* buffer to read from */ | ||
96 | long count, /* # of elements to read */ | ||
97 | long *written); /* # of bytes written */ | ||
98 | |||
99 | int | ||
100 | xfs_inumbers_fmt( | ||
101 | void __user *ubuffer, /* buffer to write to */ | ||
102 | const xfs_inogrp_t *buffer, /* buffer to read from */ | ||
103 | long count, /* # of elements to read */ | ||
104 | long *written); /* # of bytes written */ | ||
105 | |||
89 | int /* error status */ | 106 | int /* error status */ |
90 | xfs_inumbers( | 107 | xfs_inumbers( |
91 | xfs_mount_t *mp, /* mount point for filesystem */ | 108 | xfs_mount_t *mp, /* mount point for filesystem */ |
92 | xfs_ino_t *last, /* last inode returned */ | 109 | xfs_ino_t *last, /* last inode returned */ |
93 | int *count, /* size of buffer/count returned */ | 110 | int *count, /* size of buffer/count returned */ |
94 | xfs_inogrp_t __user *buffer);/* buffer with inode info */ | 111 | void __user *buffer, /* buffer with inode info */ |
112 | inumbers_fmt_pf formatter); | ||
95 | 113 | ||
96 | #endif /* __XFS_ITABLE_H__ */ | 114 | #endif /* __XFS_ITABLE_H__ */ |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index c48bf61f17b..9d4c4fbeb3e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -817,10 +817,8 @@ xfs_log_need_covered(xfs_mount_t *mp) | |||
817 | SPLDECL(s); | 817 | SPLDECL(s); |
818 | int needed = 0, gen; | 818 | int needed = 0, gen; |
819 | xlog_t *log = mp->m_log; | 819 | xlog_t *log = mp->m_log; |
820 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | ||
821 | 820 | ||
822 | if (vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) || | 821 | if (!xfs_fs_writable(mp)) |
823 | (vfsp->vfs_flag & VFS_RDONLY)) | ||
824 | return 0; | 822 | return 0; |
825 | 823 | ||
826 | s = LOG_LOCK(log); | 824 | s = LOG_LOCK(log); |
@@ -967,14 +965,16 @@ xlog_iodone(xfs_buf_t *bp) | |||
967 | } else if (iclog->ic_state & XLOG_STATE_IOERROR) { | 965 | } else if (iclog->ic_state & XLOG_STATE_IOERROR) { |
968 | aborted = XFS_LI_ABORTED; | 966 | aborted = XFS_LI_ABORTED; |
969 | } | 967 | } |
968 | |||
969 | /* log I/O is always issued ASYNC */ | ||
970 | ASSERT(XFS_BUF_ISASYNC(bp)); | ||
970 | xlog_state_done_syncing(iclog, aborted); | 971 | xlog_state_done_syncing(iclog, aborted); |
971 | if (!(XFS_BUF_ISASYNC(bp))) { | 972 | /* |
972 | /* | 973 | * do not reference the buffer (bp) here as we could race |
973 | * Corresponding psema() will be done in bwrite(). If we don't | 974 | * with it being freed after writing the unmount record to the |
974 | * vsema() here, panic. | 975 | * log. |
975 | */ | 976 | */ |
976 | XFS_BUF_V_IODONESEMA(bp); | 977 | |
977 | } | ||
978 | } /* xlog_iodone */ | 978 | } /* xlog_iodone */ |
979 | 979 | ||
980 | /* | 980 | /* |
@@ -1199,11 +1199,18 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1199 | *iclogp = (xlog_in_core_t *) | 1199 | *iclogp = (xlog_in_core_t *) |
1200 | kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); | 1200 | kmem_zalloc(sizeof(xlog_in_core_t), KM_SLEEP); |
1201 | iclog = *iclogp; | 1201 | iclog = *iclogp; |
1202 | iclog->hic_data = (xlog_in_core_2_t *) | ||
1203 | kmem_zalloc(iclogsize, KM_SLEEP | KM_LARGE); | ||
1204 | |||
1205 | iclog->ic_prev = prev_iclog; | 1202 | iclog->ic_prev = prev_iclog; |
1206 | prev_iclog = iclog; | 1203 | prev_iclog = iclog; |
1204 | |||
1205 | bp = xfs_buf_get_noaddr(log->l_iclog_size, mp->m_logdev_targp); | ||
1206 | if (!XFS_BUF_CPSEMA(bp)) | ||
1207 | ASSERT(0); | ||
1208 | XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); | ||
1209 | XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb); | ||
1210 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); | ||
1211 | iclog->ic_bp = bp; | ||
1212 | iclog->hic_data = bp->b_addr; | ||
1213 | |||
1207 | log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header); | 1214 | log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header); |
1208 | 1215 | ||
1209 | head = &iclog->ic_header; | 1216 | head = &iclog->ic_header; |
@@ -1216,11 +1223,6 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1216 | INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT); | 1223 | INT_SET(head->h_fmt, ARCH_CONVERT, XLOG_FMT); |
1217 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); | 1224 | memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t)); |
1218 | 1225 | ||
1219 | bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp); | ||
1220 | XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); | ||
1221 | XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb); | ||
1222 | XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); | ||
1223 | iclog->ic_bp = bp; | ||
1224 | 1226 | ||
1225 | iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize; | 1227 | iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize; |
1226 | iclog->ic_state = XLOG_STATE_ACTIVE; | 1228 | iclog->ic_state = XLOG_STATE_ACTIVE; |
@@ -1432,7 +1434,7 @@ xlog_sync(xlog_t *log, | |||
1432 | } else { | 1434 | } else { |
1433 | iclog->ic_bwritecnt = 1; | 1435 | iclog->ic_bwritecnt = 1; |
1434 | } | 1436 | } |
1435 | XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count); | 1437 | XFS_BUF_SET_COUNT(bp, count); |
1436 | XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */ | 1438 | XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */ |
1437 | XFS_BUF_ZEROFLAGS(bp); | 1439 | XFS_BUF_ZEROFLAGS(bp); |
1438 | XFS_BUF_BUSY(bp); | 1440 | XFS_BUF_BUSY(bp); |
@@ -1528,7 +1530,6 @@ xlog_dealloc_log(xlog_t *log) | |||
1528 | } | 1530 | } |
1529 | #endif | 1531 | #endif |
1530 | next_iclog = iclog->ic_next; | 1532 | next_iclog = iclog->ic_next; |
1531 | kmem_free(iclog->hic_data, log->l_iclog_size); | ||
1532 | kmem_free(iclog, sizeof(xlog_in_core_t)); | 1533 | kmem_free(iclog, sizeof(xlog_in_core_t)); |
1533 | iclog = next_iclog; | 1534 | iclog = next_iclog; |
1534 | } | 1535 | } |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 080fabf61c9..fddbb091a86 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -927,6 +927,14 @@ xlog_find_tail( | |||
927 | ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle, | 927 | ASSIGN_ANY_LSN_HOST(log->l_last_sync_lsn, log->l_curr_cycle, |
928 | after_umount_blk); | 928 | after_umount_blk); |
929 | *tail_blk = after_umount_blk; | 929 | *tail_blk = after_umount_blk; |
930 | |||
931 | /* | ||
932 | * Note that the unmount was clean. If the unmount | ||
933 | * was not clean, we need to know this to rebuild the | ||
934 | * superblock counters from the perag headers if we | ||
935 | * have a filesystem using non-persistent counters. | ||
936 | */ | ||
937 | log->l_mp->m_flags |= XFS_MOUNT_WAS_CLEAN; | ||
930 | } | 938 | } |
931 | } | 939 | } |
932 | 940 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index a96bde6df96..a66b3980517 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -202,6 +202,27 @@ xfs_mount_free( | |||
202 | kmem_free(mp, sizeof(xfs_mount_t)); | 202 | kmem_free(mp, sizeof(xfs_mount_t)); |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Check size of device based on the (data/realtime) block count. | ||
207 | * Note: this check is used by the growfs code as well as mount. | ||
208 | */ | ||
209 | int | ||
210 | xfs_sb_validate_fsb_count( | ||
211 | xfs_sb_t *sbp, | ||
212 | __uint64_t nblocks) | ||
213 | { | ||
214 | ASSERT(PAGE_SHIFT >= sbp->sb_blocklog); | ||
215 | ASSERT(sbp->sb_blocklog >= BBSHIFT); | ||
216 | |||
217 | #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ | ||
218 | if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX) | ||
219 | return E2BIG; | ||
220 | #else /* Limited by UINT_MAX of sectors */ | ||
221 | if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX) | ||
222 | return E2BIG; | ||
223 | #endif | ||
224 | return 0; | ||
225 | } | ||
205 | 226 | ||
206 | /* | 227 | /* |
207 | * Check the validity of the SB found. | 228 | * Check the validity of the SB found. |
@@ -284,18 +305,8 @@ xfs_mount_validate_sb( | |||
284 | return XFS_ERROR(EFSCORRUPTED); | 305 | return XFS_ERROR(EFSCORRUPTED); |
285 | } | 306 | } |
286 | 307 | ||
287 | ASSERT(PAGE_SHIFT >= sbp->sb_blocklog); | 308 | if (xfs_sb_validate_fsb_count(sbp, sbp->sb_dblocks) || |
288 | ASSERT(sbp->sb_blocklog >= BBSHIFT); | 309 | xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) { |
289 | |||
290 | #if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */ | ||
291 | if (unlikely( | ||
292 | (sbp->sb_dblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX || | ||
293 | (sbp->sb_rblocks >> (PAGE_SHIFT - sbp->sb_blocklog)) > ULONG_MAX)) { | ||
294 | #else /* Limited by UINT_MAX of sectors */ | ||
295 | if (unlikely( | ||
296 | (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX || | ||
297 | (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) { | ||
298 | #endif | ||
299 | xfs_fs_mount_cmn_err(flags, | 310 | xfs_fs_mount_cmn_err(flags, |
300 | "file system too large to be mounted on this system."); | 311 | "file system too large to be mounted on this system."); |
301 | return XFS_ERROR(E2BIG); | 312 | return XFS_ERROR(E2BIG); |
@@ -632,6 +643,64 @@ xfs_mount_common(xfs_mount_t *mp, xfs_sb_t *sbp) | |||
632 | sbp->sb_inopblock); | 643 | sbp->sb_inopblock); |
633 | mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; | 644 | mp->m_ialloc_blks = mp->m_ialloc_inos >> sbp->sb_inopblog; |
634 | } | 645 | } |
646 | |||
647 | /* | ||
648 | * xfs_initialize_perag_data | ||
649 | * | ||
650 | * Read in each per-ag structure so we can count up the number of | ||
651 | * allocated inodes, free inodes and used filesystem blocks as this | ||
652 | * information is no longer persistent in the superblock. Once we have | ||
653 | * this information, write it into the in-core superblock structure. | ||
654 | */ | ||
655 | STATIC int | ||
656 | xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount) | ||
657 | { | ||
658 | xfs_agnumber_t index; | ||
659 | xfs_perag_t *pag; | ||
660 | xfs_sb_t *sbp = &mp->m_sb; | ||
661 | uint64_t ifree = 0; | ||
662 | uint64_t ialloc = 0; | ||
663 | uint64_t bfree = 0; | ||
664 | uint64_t bfreelst = 0; | ||
665 | uint64_t btree = 0; | ||
666 | int error; | ||
667 | int s; | ||
668 | |||
669 | for (index = 0; index < agcount; index++) { | ||
670 | /* | ||
671 | * read the agf, then the agi. This gets us | ||
672 | * all the inforamtion we need and populates the | ||
673 | * per-ag structures for us. | ||
674 | */ | ||
675 | error = xfs_alloc_pagf_init(mp, NULL, index, 0); | ||
676 | if (error) | ||
677 | return error; | ||
678 | |||
679 | error = xfs_ialloc_pagi_init(mp, NULL, index); | ||
680 | if (error) | ||
681 | return error; | ||
682 | pag = &mp->m_perag[index]; | ||
683 | ifree += pag->pagi_freecount; | ||
684 | ialloc += pag->pagi_count; | ||
685 | bfree += pag->pagf_freeblks; | ||
686 | bfreelst += pag->pagf_flcount; | ||
687 | btree += pag->pagf_btreeblks; | ||
688 | } | ||
689 | /* | ||
690 | * Overwrite incore superblock counters with just-read data | ||
691 | */ | ||
692 | s = XFS_SB_LOCK(mp); | ||
693 | sbp->sb_ifree = ifree; | ||
694 | sbp->sb_icount = ialloc; | ||
695 | sbp->sb_fdblocks = bfree + bfreelst + btree; | ||
696 | XFS_SB_UNLOCK(mp, s); | ||
697 | |||
698 | /* Fixup the per-cpu counters as well. */ | ||
699 | xfs_icsb_reinit_counters(mp); | ||
700 | |||
701 | return 0; | ||
702 | } | ||
703 | |||
635 | /* | 704 | /* |
636 | * xfs_mountfs | 705 | * xfs_mountfs |
637 | * | 706 | * |
@@ -656,7 +725,7 @@ xfs_mountfs( | |||
656 | bhv_vnode_t *rvp = NULL; | 725 | bhv_vnode_t *rvp = NULL; |
657 | int readio_log, writeio_log; | 726 | int readio_log, writeio_log; |
658 | xfs_daddr_t d; | 727 | xfs_daddr_t d; |
659 | __uint64_t ret64; | 728 | __uint64_t resblks; |
660 | __int64_t update_flags; | 729 | __int64_t update_flags; |
661 | uint quotamount, quotaflags; | 730 | uint quotamount, quotaflags; |
662 | int agno; | 731 | int agno; |
@@ -773,6 +842,7 @@ xfs_mountfs( | |||
773 | */ | 842 | */ |
774 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && | 843 | if ((mfsi_flags & XFS_MFSI_SECOND) == 0 && |
775 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { | 844 | (mp->m_flags & XFS_MOUNT_NOUUID) == 0) { |
845 | __uint64_t ret64; | ||
776 | if (xfs_uuid_mount(mp)) { | 846 | if (xfs_uuid_mount(mp)) { |
777 | error = XFS_ERROR(EINVAL); | 847 | error = XFS_ERROR(EINVAL); |
778 | goto error1; | 848 | goto error1; |
@@ -976,6 +1046,34 @@ xfs_mountfs( | |||
976 | } | 1046 | } |
977 | 1047 | ||
978 | /* | 1048 | /* |
1049 | * Now the log is mounted, we know if it was an unclean shutdown or | ||
1050 | * not. If it was, with the first phase of recovery has completed, we | ||
1051 | * have consistent AG blocks on disk. We have not recovered EFIs yet, | ||
1052 | * but they are recovered transactionally in the second recovery phase | ||
1053 | * later. | ||
1054 | * | ||
1055 | * Hence we can safely re-initialise incore superblock counters from | ||
1056 | * the per-ag data. These may not be correct if the filesystem was not | ||
1057 | * cleanly unmounted, so we need to wait for recovery to finish before | ||
1058 | * doing this. | ||
1059 | * | ||
1060 | * If the filesystem was cleanly unmounted, then we can trust the | ||
1061 | * values in the superblock to be correct and we don't need to do | ||
1062 | * anything here. | ||
1063 | * | ||
1064 | * If we are currently making the filesystem, the initialisation will | ||
1065 | * fail as the perag data is in an undefined state. | ||
1066 | */ | ||
1067 | |||
1068 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) && | ||
1069 | !XFS_LAST_UNMOUNT_WAS_CLEAN(mp) && | ||
1070 | !mp->m_sb.sb_inprogress) { | ||
1071 | error = xfs_initialize_perag_data(mp, sbp->sb_agcount); | ||
1072 | if (error) { | ||
1073 | goto error2; | ||
1074 | } | ||
1075 | } | ||
1076 | /* | ||
979 | * Get and sanity-check the root inode. | 1077 | * Get and sanity-check the root inode. |
980 | * Save the pointer to it in the mount structure. | 1078 | * Save the pointer to it in the mount structure. |
981 | */ | 1079 | */ |
@@ -1044,6 +1142,23 @@ xfs_mountfs( | |||
1044 | if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags))) | 1142 | if ((error = XFS_QM_MOUNT(mp, quotamount, quotaflags, mfsi_flags))) |
1045 | goto error4; | 1143 | goto error4; |
1046 | 1144 | ||
1145 | /* | ||
1146 | * Now we are mounted, reserve a small amount of unused space for | ||
1147 | * privileged transactions. This is needed so that transaction | ||
1148 | * space required for critical operations can dip into this pool | ||
1149 | * when at ENOSPC. This is needed for operations like create with | ||
1150 | * attr, unwritten extent conversion at ENOSPC, etc. Data allocations | ||
1151 | * are not allowed to use this reserved space. | ||
1152 | * | ||
1153 | * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. | ||
1154 | * This may drive us straight to ENOSPC on mount, but that implies | ||
1155 | * we were already there on the last unmount. | ||
1156 | */ | ||
1157 | resblks = mp->m_sb.sb_dblocks; | ||
1158 | do_div(resblks, 20); | ||
1159 | resblks = min_t(__uint64_t, resblks, 1024); | ||
1160 | xfs_reserve_blocks(mp, &resblks, NULL); | ||
1161 | |||
1047 | return 0; | 1162 | return 0; |
1048 | 1163 | ||
1049 | error4: | 1164 | error4: |
@@ -1083,7 +1198,19 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1083 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) | 1198 | #if defined(DEBUG) || defined(INDUCE_IO_ERROR) |
1084 | int64_t fsid; | 1199 | int64_t fsid; |
1085 | #endif | 1200 | #endif |
1201 | __uint64_t resblks; | ||
1086 | 1202 | ||
1203 | /* | ||
1204 | * We can potentially deadlock here if we have an inode cluster | ||
1205 | * that has been freed has it's buffer still pinned in memory because | ||
1206 | * the transaction is still sitting in a iclog. The stale inodes | ||
1207 | * on that buffer will have their flush locks held until the | ||
1208 | * transaction hits the disk and the callbacks run. the inode | ||
1209 | * flush takes the flush lock unconditionally and with nothing to | ||
1210 | * push out the iclog we will never get that unlocked. hence we | ||
1211 | * need to force the log first. | ||
1212 | */ | ||
1213 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
1087 | xfs_iflush_all(mp); | 1214 | xfs_iflush_all(mp); |
1088 | 1215 | ||
1089 | XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING); | 1216 | XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING); |
@@ -1100,10 +1227,26 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1100 | xfs_binval(mp->m_rtdev_targp); | 1227 | xfs_binval(mp->m_rtdev_targp); |
1101 | } | 1228 | } |
1102 | 1229 | ||
1103 | xfs_unmountfs_writesb(mp); | 1230 | /* |
1231 | * Unreserve any blocks we have so that when we unmount we don't account | ||
1232 | * the reserved free space as used. This is really only necessary for | ||
1233 | * lazy superblock counting because it trusts the incore superblock | ||
1234 | * counters to be aboslutely correct on clean unmount. | ||
1235 | * | ||
1236 | * We don't bother correcting this elsewhere for lazy superblock | ||
1237 | * counting because on mount of an unclean filesystem we reconstruct the | ||
1238 | * correct counter value and this is irrelevant. | ||
1239 | * | ||
1240 | * For non-lazy counter filesystems, this doesn't matter at all because | ||
1241 | * we only every apply deltas to the superblock and hence the incore | ||
1242 | * value does not matter.... | ||
1243 | */ | ||
1244 | resblks = 0; | ||
1245 | xfs_reserve_blocks(mp, &resblks, NULL); | ||
1104 | 1246 | ||
1247 | xfs_log_sbcount(mp, 1); | ||
1248 | xfs_unmountfs_writesb(mp); | ||
1105 | xfs_unmountfs_wait(mp); /* wait for async bufs */ | 1249 | xfs_unmountfs_wait(mp); /* wait for async bufs */ |
1106 | |||
1107 | xfs_log_unmount(mp); /* Done! No more fs ops. */ | 1250 | xfs_log_unmount(mp); /* Done! No more fs ops. */ |
1108 | 1251 | ||
1109 | xfs_freesb(mp); | 1252 | xfs_freesb(mp); |
@@ -1150,6 +1293,62 @@ xfs_unmountfs_wait(xfs_mount_t *mp) | |||
1150 | } | 1293 | } |
1151 | 1294 | ||
1152 | int | 1295 | int |
1296 | xfs_fs_writable(xfs_mount_t *mp) | ||
1297 | { | ||
1298 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | ||
1299 | |||
1300 | return !(vfs_test_for_freeze(vfsp) || XFS_FORCED_SHUTDOWN(mp) || | ||
1301 | (vfsp->vfs_flag & VFS_RDONLY)); | ||
1302 | } | ||
1303 | |||
1304 | /* | ||
1305 | * xfs_log_sbcount | ||
1306 | * | ||
1307 | * Called either periodically to keep the on disk superblock values | ||
1308 | * roughly up to date or from unmount to make sure the values are | ||
1309 | * correct on a clean unmount. | ||
1310 | * | ||
1311 | * Note this code can be called during the process of freezing, so | ||
1312 | * we may need to use the transaction allocator which does not not | ||
1313 | * block when the transaction subsystem is in its frozen state. | ||
1314 | */ | ||
1315 | int | ||
1316 | xfs_log_sbcount( | ||
1317 | xfs_mount_t *mp, | ||
1318 | uint sync) | ||
1319 | { | ||
1320 | xfs_trans_t *tp; | ||
1321 | int error; | ||
1322 | |||
1323 | if (!xfs_fs_writable(mp)) | ||
1324 | return 0; | ||
1325 | |||
1326 | xfs_icsb_sync_counters(mp); | ||
1327 | |||
1328 | /* | ||
1329 | * we don't need to do this if we are updating the superblock | ||
1330 | * counters on every modification. | ||
1331 | */ | ||
1332 | if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
1333 | return 0; | ||
1334 | |||
1335 | tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT); | ||
1336 | error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, | ||
1337 | XFS_DEFAULT_LOG_COUNT); | ||
1338 | if (error) { | ||
1339 | xfs_trans_cancel(tp, 0); | ||
1340 | return error; | ||
1341 | } | ||
1342 | |||
1343 | xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); | ||
1344 | if (sync) | ||
1345 | xfs_trans_set_sync(tp); | ||
1346 | xfs_trans_commit(tp, 0); | ||
1347 | |||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | int | ||
1153 | xfs_unmountfs_writesb(xfs_mount_t *mp) | 1352 | xfs_unmountfs_writesb(xfs_mount_t *mp) |
1154 | { | 1353 | { |
1155 | xfs_buf_t *sbp; | 1354 | xfs_buf_t *sbp; |
@@ -1160,16 +1359,15 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) | |||
1160 | * skip superblock write if fs is read-only, or | 1359 | * skip superblock write if fs is read-only, or |
1161 | * if we are doing a forced umount. | 1360 | * if we are doing a forced umount. |
1162 | */ | 1361 | */ |
1163 | sbp = xfs_getsb(mp, 0); | ||
1164 | if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY || | 1362 | if (!(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY || |
1165 | XFS_FORCED_SHUTDOWN(mp))) { | 1363 | XFS_FORCED_SHUTDOWN(mp))) { |
1166 | 1364 | ||
1167 | xfs_icsb_sync_counters(mp); | 1365 | sbp = xfs_getsb(mp, 0); |
1366 | sb = XFS_BUF_TO_SBP(sbp); | ||
1168 | 1367 | ||
1169 | /* | 1368 | /* |
1170 | * mark shared-readonly if desired | 1369 | * mark shared-readonly if desired |
1171 | */ | 1370 | */ |
1172 | sb = XFS_BUF_TO_SBP(sbp); | ||
1173 | if (mp->m_mk_sharedro) { | 1371 | if (mp->m_mk_sharedro) { |
1174 | if (!(sb->sb_flags & XFS_SBF_READONLY)) | 1372 | if (!(sb->sb_flags & XFS_SBF_READONLY)) |
1175 | sb->sb_flags |= XFS_SBF_READONLY; | 1373 | sb->sb_flags |= XFS_SBF_READONLY; |
@@ -1178,6 +1376,7 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) | |||
1178 | xfs_fs_cmn_err(CE_NOTE, mp, | 1376 | xfs_fs_cmn_err(CE_NOTE, mp, |
1179 | "Unmounting, marking shared read-only"); | 1377 | "Unmounting, marking shared read-only"); |
1180 | } | 1378 | } |
1379 | |||
1181 | XFS_BUF_UNDONE(sbp); | 1380 | XFS_BUF_UNDONE(sbp); |
1182 | XFS_BUF_UNREAD(sbp); | 1381 | XFS_BUF_UNREAD(sbp); |
1183 | XFS_BUF_UNDELAYWRITE(sbp); | 1382 | XFS_BUF_UNDELAYWRITE(sbp); |
@@ -1192,8 +1391,8 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) | |||
1192 | mp, sbp, XFS_BUF_ADDR(sbp)); | 1391 | mp, sbp, XFS_BUF_ADDR(sbp)); |
1193 | if (error && mp->m_mk_sharedro) | 1392 | if (error && mp->m_mk_sharedro) |
1194 | xfs_fs_cmn_err(CE_ALERT, mp, "Superblock write error detected while unmounting. Filesystem may not be marked shared readonly"); | 1393 | xfs_fs_cmn_err(CE_ALERT, mp, "Superblock write error detected while unmounting. Filesystem may not be marked shared readonly"); |
1394 | xfs_buf_relse(sbp); | ||
1195 | } | 1395 | } |
1196 | xfs_buf_relse(sbp); | ||
1197 | return error; | 1396 | return error; |
1198 | } | 1397 | } |
1199 | 1398 | ||
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 82304b94646..76ad7475869 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -66,6 +66,7 @@ struct xfs_bmbt_irec; | |||
66 | struct xfs_bmap_free; | 66 | struct xfs_bmap_free; |
67 | struct xfs_extdelta; | 67 | struct xfs_extdelta; |
68 | struct xfs_swapext; | 68 | struct xfs_swapext; |
69 | struct xfs_mru_cache; | ||
69 | 70 | ||
70 | extern struct bhv_vfsops xfs_vfsops; | 71 | extern struct bhv_vfsops xfs_vfsops; |
71 | extern struct bhv_vnodeops xfs_vnodeops; | 72 | extern struct bhv_vnodeops xfs_vnodeops; |
@@ -424,17 +425,18 @@ typedef struct xfs_mount { | |||
424 | struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ | 425 | struct notifier_block m_icsb_notifier; /* hotplug cpu notifier */ |
425 | struct mutex m_icsb_mutex; /* balancer sync lock */ | 426 | struct mutex m_icsb_mutex; /* balancer sync lock */ |
426 | #endif | 427 | #endif |
428 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ | ||
427 | } xfs_mount_t; | 429 | } xfs_mount_t; |
428 | 430 | ||
429 | /* | 431 | /* |
430 | * Flags for m_flags. | 432 | * Flags for m_flags. |
431 | */ | 433 | */ |
432 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops | 434 | #define XFS_MOUNT_WSYNC (1ULL << 0) /* for nfs - all metadata ops |
433 | must be synchronous except | 435 | must be synchronous except |
434 | for space allocations */ | 436 | for space allocations */ |
435 | #define XFS_MOUNT_INO64 (1ULL << 1) | 437 | #define XFS_MOUNT_INO64 (1ULL << 1) |
436 | /* (1ULL << 2) -- currently unused */ | 438 | /* (1ULL << 2) -- currently unused */ |
437 | /* (1ULL << 3) -- currently unused */ | 439 | #define XFS_MOUNT_WAS_CLEAN (1ULL << 3) |
438 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem | 440 | #define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem |
439 | operations, typically for | 441 | operations, typically for |
440 | disk errors in metadata */ | 442 | disk errors in metadata */ |
@@ -463,6 +465,8 @@ typedef struct xfs_mount { | |||
463 | * I/O size in stat() */ | 465 | * I/O size in stat() */ |
464 | #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock | 466 | #define XFS_MOUNT_NO_PERCPU_SB (1ULL << 23) /* don't use per-cpu superblock |
465 | counters */ | 467 | counters */ |
468 | #define XFS_MOUNT_FILESTREAMS (1ULL << 24) /* enable the filestreams | ||
469 | allocator */ | ||
466 | 470 | ||
467 | 471 | ||
468 | /* | 472 | /* |
@@ -511,6 +515,8 @@ xfs_preferred_iosize(xfs_mount_t *mp) | |||
511 | 515 | ||
512 | #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) | 516 | #define XFS_MAXIOFFSET(mp) ((mp)->m_maxioffset) |
513 | 517 | ||
518 | #define XFS_LAST_UNMOUNT_WAS_CLEAN(mp) \ | ||
519 | ((mp)->m_flags & XFS_MOUNT_WAS_CLEAN) | ||
514 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) | 520 | #define XFS_FORCED_SHUTDOWN(mp) ((mp)->m_flags & XFS_MOUNT_FS_SHUTDOWN) |
515 | #define xfs_force_shutdown(m,f) \ | 521 | #define xfs_force_shutdown(m,f) \ |
516 | bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__) | 522 | bhv_vfs_force_shutdown((XFS_MTOVFS(m)), f, __FILE__, __LINE__) |
@@ -602,6 +608,7 @@ typedef struct xfs_mod_sb { | |||
602 | 608 | ||
603 | extern xfs_mount_t *xfs_mount_init(void); | 609 | extern xfs_mount_t *xfs_mount_init(void); |
604 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); | 610 | extern void xfs_mod_sb(xfs_trans_t *, __int64_t); |
611 | extern int xfs_log_sbcount(xfs_mount_t *, uint); | ||
605 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); | 612 | extern void xfs_mount_free(xfs_mount_t *mp, int remove_bhv); |
606 | extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); | 613 | extern int xfs_mountfs(struct bhv_vfs *, xfs_mount_t *mp, int); |
607 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); | 614 | extern void xfs_mountfs_check_barriers(xfs_mount_t *mp); |
@@ -618,12 +625,14 @@ extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, | |||
618 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); | 625 | extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); |
619 | extern int xfs_readsb(xfs_mount_t *, int); | 626 | extern int xfs_readsb(xfs_mount_t *, int); |
620 | extern void xfs_freesb(xfs_mount_t *); | 627 | extern void xfs_freesb(xfs_mount_t *); |
628 | extern int xfs_fs_writable(xfs_mount_t *); | ||
621 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); | 629 | extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); |
622 | extern int xfs_syncsub(xfs_mount_t *, int, int *); | 630 | extern int xfs_syncsub(xfs_mount_t *, int, int *); |
623 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); | 631 | extern int xfs_sync_inodes(xfs_mount_t *, int, int *); |
624 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, | 632 | extern xfs_agnumber_t xfs_initialize_perag(struct bhv_vfs *, xfs_mount_t *, |
625 | xfs_agnumber_t); | 633 | xfs_agnumber_t); |
626 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); | 634 | extern void xfs_xlatesb(void *, struct xfs_sb *, int, __int64_t); |
635 | extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); | ||
627 | 636 | ||
628 | extern struct xfs_dmops xfs_dmcore_stub; | 637 | extern struct xfs_dmops xfs_dmcore_stub; |
629 | extern struct xfs_qmops xfs_qmcore_stub; | 638 | extern struct xfs_qmops xfs_qmcore_stub; |
diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c new file mode 100644 index 00000000000..7deb9e3cbbd --- /dev/null +++ b/fs/xfs/xfs_mru_cache.c | |||
@@ -0,0 +1,608 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006-2007 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_mru_cache.h" | ||
20 | |||
21 | /* | ||
22 | * The MRU Cache data structure consists of a data store, an array of lists and | ||
23 | * a lock to protect its internal state. At initialisation time, the client | ||
24 | * supplies an element lifetime in milliseconds and a group count, as well as a | ||
25 | * function pointer to call when deleting elements. A data structure for | ||
26 | * queueing up work in the form of timed callbacks is also included. | ||
27 | * | ||
28 | * The group count controls how many lists are created, and thereby how finely | ||
29 | * the elements are grouped in time. When reaping occurs, all the elements in | ||
30 | * all the lists whose time has expired are deleted. | ||
31 | * | ||
32 | * To give an example of how this works in practice, consider a client that | ||
33 | * initialises an MRU Cache with a lifetime of ten seconds and a group count of | ||
34 | * five. Five internal lists will be created, each representing a two second | ||
35 | * period in time. When the first element is added, time zero for the data | ||
36 | * structure is initialised to the current time. | ||
37 | * | ||
38 | * All the elements added in the first two seconds are appended to the first | ||
39 | * list. Elements added in the third second go into the second list, and so on. | ||
40 | * If an element is accessed at any point, it is removed from its list and | ||
41 | * inserted at the head of the current most-recently-used list. | ||
42 | * | ||
43 | * The reaper function will have nothing to do until at least twelve seconds | ||
44 | * have elapsed since the first element was added. The reason for this is that | ||
45 | * if it were called at t=11s, there could be elements in the first list that | ||
46 | * have only been inactive for nine seconds, so it still does nothing. If it is | ||
47 | * called anywhere between t=12 and t=14 seconds, it will delete all the | ||
48 | * elements that remain in the first list. It's therefore possible for elements | ||
49 | * to remain in the data store even after they've been inactive for up to | ||
50 | * (t + t/g) seconds, where t is the inactive element lifetime and g is the | ||
51 | * number of groups. | ||
52 | * | ||
53 | * The above example assumes that the reaper function gets called at least once | ||
54 | * every (t/g) seconds. If it is called less frequently, unused elements will | ||
55 | * accumulate in the reap list until the reaper function is eventually called. | ||
56 | * The current implementation uses work queue callbacks to carefully time the | ||
57 | * reaper function calls, so this should happen rarely, if at all. | ||
58 | * | ||
59 | * From a design perspective, the primary reason for the choice of a list array | ||
60 | * representing discrete time intervals is that it's only practical to reap | ||
61 | * expired elements in groups of some appreciable size. This automatically | ||
62 | * introduces a granularity to element lifetimes, so there's no point storing an | ||
63 | * individual timeout with each element that specifies a more precise reap time. | ||
64 | * The bonus is a saving of sizeof(long) bytes of memory per element stored. | ||
65 | * | ||
66 | * The elements could have been stored in just one list, but an array of | ||
67 | * counters or pointers would need to be maintained to allow them to be divided | ||
68 | * up into discrete time groups. More critically, the process of touching or | ||
69 | * removing an element would involve walking large portions of the entire list, | ||
70 | * which would have a detrimental effect on performance. The additional memory | ||
71 | * requirement for the array of list heads is minimal. | ||
72 | * | ||
73 | * When an element is touched or deleted, it needs to be removed from its | ||
74 | * current list. Doubly linked lists are used to make the list maintenance | ||
75 | * portion of these operations O(1). Since reaper timing can be imprecise, | ||
76 | * inserts and lookups can occur when there are no free lists available. When | ||
77 | * this happens, all the elements on the LRU list need to be migrated to the end | ||
78 | * of the reap list. To keep the list maintenance portion of these operations | ||
79 | * O(1) also, list tails need to be accessible without walking the entire list. | ||
80 | * This is the reason why doubly linked list heads are used. | ||
81 | */ | ||
82 | |||
83 | /* | ||
84 | * An MRU Cache is a dynamic data structure that stores its elements in a way | ||
85 | * that allows efficient lookups, but also groups them into discrete time | ||
86 | * intervals based on insertion time. This allows elements to be efficiently | ||
87 | * and automatically reaped after a fixed period of inactivity. | ||
88 | * | ||
89 | * When a client data pointer is stored in the MRU Cache it needs to be added to | ||
90 | * both the data store and to one of the lists. It must also be possible to | ||
91 | * access each of these entries via the other, i.e. to: | ||
92 | * | ||
93 | * a) Walk a list, removing the corresponding data store entry for each item. | ||
94 | * b) Look up a data store entry, then access its list entry directly. | ||
95 | * | ||
96 | * To achieve both of these goals, each entry must contain both a list entry and | ||
97 | * a key, in addition to the user's data pointer. Note that it's not a good | ||
98 | * idea to have the client embed one of these structures at the top of their own | ||
99 | * data structure, because inserting the same item more than once would most | ||
100 | * likely result in a loop in one of the lists. That's a sure-fire recipe for | ||
101 | * an infinite loop in the code. | ||
102 | */ | ||
103 | typedef struct xfs_mru_cache_elem | ||
104 | { | ||
105 | struct list_head list_node; | ||
106 | unsigned long key; | ||
107 | void *value; | ||
108 | } xfs_mru_cache_elem_t; | ||
109 | |||
110 | static kmem_zone_t *xfs_mru_elem_zone; | ||
111 | static struct workqueue_struct *xfs_mru_reap_wq; | ||
112 | |||
113 | /* | ||
114 | * When inserting, destroying or reaping, it's first necessary to update the | ||
115 | * lists relative to a particular time. In the case of destroying, that time | ||
116 | * will be well in the future to ensure that all items are moved to the reap | ||
117 | * list. In all other cases though, the time will be the current time. | ||
118 | * | ||
119 | * This function enters a loop, moving the contents of the LRU list to the reap | ||
120 | * list again and again until either a) the lists are all empty, or b) time zero | ||
121 | * has been advanced sufficiently to be within the immediate element lifetime. | ||
122 | * | ||
123 | * Case a) above is detected by counting how many groups are migrated and | ||
124 | * stopping when they've all been moved. Case b) is detected by monitoring the | ||
125 | * time_zero field, which is updated as each group is migrated. | ||
126 | * | ||
127 | * The return value is the earliest time that more migration could be needed, or | ||
128 | * zero if there's no need to schedule more work because the lists are empty. | ||
129 | */ | ||
130 | STATIC unsigned long | ||
131 | _xfs_mru_cache_migrate( | ||
132 | xfs_mru_cache_t *mru, | ||
133 | unsigned long now) | ||
134 | { | ||
135 | unsigned int grp; | ||
136 | unsigned int migrated = 0; | ||
137 | struct list_head *lru_list; | ||
138 | |||
139 | /* Nothing to do if the data store is empty. */ | ||
140 | if (!mru->time_zero) | ||
141 | return 0; | ||
142 | |||
143 | /* While time zero is older than the time spanned by all the lists. */ | ||
144 | while (mru->time_zero <= now - mru->grp_count * mru->grp_time) { | ||
145 | |||
146 | /* | ||
147 | * If the LRU list isn't empty, migrate its elements to the tail | ||
148 | * of the reap list. | ||
149 | */ | ||
150 | lru_list = mru->lists + mru->lru_grp; | ||
151 | if (!list_empty(lru_list)) | ||
152 | list_splice_init(lru_list, mru->reap_list.prev); | ||
153 | |||
154 | /* | ||
155 | * Advance the LRU group number, freeing the old LRU list to | ||
156 | * become the new MRU list; advance time zero accordingly. | ||
157 | */ | ||
158 | mru->lru_grp = (mru->lru_grp + 1) % mru->grp_count; | ||
159 | mru->time_zero += mru->grp_time; | ||
160 | |||
161 | /* | ||
162 | * If reaping is so far behind that all the elements on all the | ||
163 | * lists have been migrated to the reap list, it's now empty. | ||
164 | */ | ||
165 | if (++migrated == mru->grp_count) { | ||
166 | mru->lru_grp = 0; | ||
167 | mru->time_zero = 0; | ||
168 | return 0; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | /* Find the first non-empty list from the LRU end. */ | ||
173 | for (grp = 0; grp < mru->grp_count; grp++) { | ||
174 | |||
175 | /* Check the grp'th list from the LRU end. */ | ||
176 | lru_list = mru->lists + ((mru->lru_grp + grp) % mru->grp_count); | ||
177 | if (!list_empty(lru_list)) | ||
178 | return mru->time_zero + | ||
179 | (mru->grp_count + grp) * mru->grp_time; | ||
180 | } | ||
181 | |||
182 | /* All the lists must be empty. */ | ||
183 | mru->lru_grp = 0; | ||
184 | mru->time_zero = 0; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * When inserting or doing a lookup, an element needs to be inserted into the | ||
190 | * MRU list. The lists must be migrated first to ensure that they're | ||
191 | * up-to-date, otherwise the new element could be given a shorter lifetime in | ||
192 | * the cache than it should. | ||
193 | */ | ||
194 | STATIC void | ||
195 | _xfs_mru_cache_list_insert( | ||
196 | xfs_mru_cache_t *mru, | ||
197 | xfs_mru_cache_elem_t *elem) | ||
198 | { | ||
199 | unsigned int grp = 0; | ||
200 | unsigned long now = jiffies; | ||
201 | |||
202 | /* | ||
203 | * If the data store is empty, initialise time zero, leave grp set to | ||
204 | * zero and start the work queue timer if necessary. Otherwise, set grp | ||
205 | * to the number of group times that have elapsed since time zero. | ||
206 | */ | ||
207 | if (!_xfs_mru_cache_migrate(mru, now)) { | ||
208 | mru->time_zero = now; | ||
209 | if (!mru->next_reap) | ||
210 | mru->next_reap = mru->grp_count * mru->grp_time; | ||
211 | } else { | ||
212 | grp = (now - mru->time_zero) / mru->grp_time; | ||
213 | grp = (mru->lru_grp + grp) % mru->grp_count; | ||
214 | } | ||
215 | |||
216 | /* Insert the element at the tail of the corresponding list. */ | ||
217 | list_add_tail(&elem->list_node, mru->lists + grp); | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * When destroying or reaping, all the elements that were migrated to the reap | ||
222 | * list need to be deleted. For each element this involves removing it from the | ||
223 | * data store, removing it from the reap list, calling the client's free | ||
224 | * function and deleting the element from the element zone. | ||
225 | */ | ||
226 | STATIC void | ||
227 | _xfs_mru_cache_clear_reap_list( | ||
228 | xfs_mru_cache_t *mru) | ||
229 | { | ||
230 | xfs_mru_cache_elem_t *elem, *next; | ||
231 | struct list_head tmp; | ||
232 | |||
233 | INIT_LIST_HEAD(&tmp); | ||
234 | list_for_each_entry_safe(elem, next, &mru->reap_list, list_node) { | ||
235 | |||
236 | /* Remove the element from the data store. */ | ||
237 | radix_tree_delete(&mru->store, elem->key); | ||
238 | |||
239 | /* | ||
240 | * remove to temp list so it can be freed without | ||
241 | * needing to hold the lock | ||
242 | */ | ||
243 | list_move(&elem->list_node, &tmp); | ||
244 | } | ||
245 | mutex_spinunlock(&mru->lock, 0); | ||
246 | |||
247 | list_for_each_entry_safe(elem, next, &tmp, list_node) { | ||
248 | |||
249 | /* Remove the element from the reap list. */ | ||
250 | list_del_init(&elem->list_node); | ||
251 | |||
252 | /* Call the client's free function with the key and value pointer. */ | ||
253 | mru->free_func(elem->key, elem->value); | ||
254 | |||
255 | /* Free the element structure. */ | ||
256 | kmem_zone_free(xfs_mru_elem_zone, elem); | ||
257 | } | ||
258 | |||
259 | mutex_spinlock(&mru->lock); | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * We fire the reap timer every group expiry interval so | ||
264 | * we always have a reaper ready to run. This makes shutdown | ||
265 | * and flushing of the reaper easy to do. Hence we need to | ||
266 | * keep when the next reap must occur so we can determine | ||
267 | * at each interval whether there is anything we need to do. | ||
268 | */ | ||
269 | STATIC void | ||
270 | _xfs_mru_cache_reap( | ||
271 | struct work_struct *work) | ||
272 | { | ||
273 | xfs_mru_cache_t *mru = container_of(work, xfs_mru_cache_t, work.work); | ||
274 | unsigned long now; | ||
275 | |||
276 | ASSERT(mru && mru->lists); | ||
277 | if (!mru || !mru->lists) | ||
278 | return; | ||
279 | |||
280 | mutex_spinlock(&mru->lock); | ||
281 | now = jiffies; | ||
282 | if (mru->reap_all || | ||
283 | (mru->next_reap && time_after(now, mru->next_reap))) { | ||
284 | if (mru->reap_all) | ||
285 | now += mru->grp_count * mru->grp_time * 2; | ||
286 | mru->next_reap = _xfs_mru_cache_migrate(mru, now); | ||
287 | _xfs_mru_cache_clear_reap_list(mru); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * the process that triggered the reap_all is responsible | ||
292 | * for restating the periodic reap if it is required. | ||
293 | */ | ||
294 | if (!mru->reap_all) | ||
295 | queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); | ||
296 | mru->reap_all = 0; | ||
297 | mutex_spinunlock(&mru->lock, 0); | ||
298 | } | ||
299 | |||
300 | int | ||
301 | xfs_mru_cache_init(void) | ||
302 | { | ||
303 | xfs_mru_elem_zone = kmem_zone_init(sizeof(xfs_mru_cache_elem_t), | ||
304 | "xfs_mru_cache_elem"); | ||
305 | if (!xfs_mru_elem_zone) | ||
306 | return ENOMEM; | ||
307 | |||
308 | xfs_mru_reap_wq = create_singlethread_workqueue("xfs_mru_cache"); | ||
309 | if (!xfs_mru_reap_wq) { | ||
310 | kmem_zone_destroy(xfs_mru_elem_zone); | ||
311 | return ENOMEM; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | void | ||
318 | xfs_mru_cache_uninit(void) | ||
319 | { | ||
320 | destroy_workqueue(xfs_mru_reap_wq); | ||
321 | kmem_zone_destroy(xfs_mru_elem_zone); | ||
322 | } | ||
323 | |||
324 | /* | ||
325 | * To initialise a struct xfs_mru_cache pointer, call xfs_mru_cache_create() | ||
326 | * with the address of the pointer, a lifetime value in milliseconds, a group | ||
327 | * count and a free function to use when deleting elements. This function | ||
328 | * returns 0 if the initialisation was successful. | ||
329 | */ | ||
330 | int | ||
331 | xfs_mru_cache_create( | ||
332 | xfs_mru_cache_t **mrup, | ||
333 | unsigned int lifetime_ms, | ||
334 | unsigned int grp_count, | ||
335 | xfs_mru_cache_free_func_t free_func) | ||
336 | { | ||
337 | xfs_mru_cache_t *mru = NULL; | ||
338 | int err = 0, grp; | ||
339 | unsigned int grp_time; | ||
340 | |||
341 | if (mrup) | ||
342 | *mrup = NULL; | ||
343 | |||
344 | if (!mrup || !grp_count || !lifetime_ms || !free_func) | ||
345 | return EINVAL; | ||
346 | |||
347 | if (!(grp_time = msecs_to_jiffies(lifetime_ms) / grp_count)) | ||
348 | return EINVAL; | ||
349 | |||
350 | if (!(mru = kmem_zalloc(sizeof(*mru), KM_SLEEP))) | ||
351 | return ENOMEM; | ||
352 | |||
353 | /* An extra list is needed to avoid reaping up to a grp_time early. */ | ||
354 | mru->grp_count = grp_count + 1; | ||
355 | mru->lists = kmem_alloc(mru->grp_count * sizeof(*mru->lists), KM_SLEEP); | ||
356 | |||
357 | if (!mru->lists) { | ||
358 | err = ENOMEM; | ||
359 | goto exit; | ||
360 | } | ||
361 | |||
362 | for (grp = 0; grp < mru->grp_count; grp++) | ||
363 | INIT_LIST_HEAD(mru->lists + grp); | ||
364 | |||
365 | /* | ||
366 | * We use GFP_KERNEL radix tree preload and do inserts under a | ||
367 | * spinlock so GFP_ATOMIC is appropriate for the radix tree itself. | ||
368 | */ | ||
369 | INIT_RADIX_TREE(&mru->store, GFP_ATOMIC); | ||
370 | INIT_LIST_HEAD(&mru->reap_list); | ||
371 | spinlock_init(&mru->lock, "xfs_mru_cache"); | ||
372 | INIT_DELAYED_WORK(&mru->work, _xfs_mru_cache_reap); | ||
373 | |||
374 | mru->grp_time = grp_time; | ||
375 | mru->free_func = free_func; | ||
376 | |||
377 | /* start up the reaper event */ | ||
378 | mru->next_reap = 0; | ||
379 | mru->reap_all = 0; | ||
380 | queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); | ||
381 | |||
382 | *mrup = mru; | ||
383 | |||
384 | exit: | ||
385 | if (err && mru && mru->lists) | ||
386 | kmem_free(mru->lists, mru->grp_count * sizeof(*mru->lists)); | ||
387 | if (err && mru) | ||
388 | kmem_free(mru, sizeof(*mru)); | ||
389 | |||
390 | return err; | ||
391 | } | ||
392 | |||
393 | /* | ||
394 | * Call xfs_mru_cache_flush() to flush out all cached entries, calling their | ||
395 | * free functions as they're deleted. When this function returns, the caller is | ||
396 | * guaranteed that all the free functions for all the elements have finished | ||
397 | * executing. | ||
398 | * | ||
399 | * While we are flushing, we stop the periodic reaper event from triggering. | ||
400 | * Normally, we want to restart this periodic event, but if we are shutting | ||
401 | * down the cache we do not want it restarted. hence the restart parameter | ||
402 | * where 0 = do not restart reaper and 1 = restart reaper. | ||
403 | */ | ||
404 | void | ||
405 | xfs_mru_cache_flush( | ||
406 | xfs_mru_cache_t *mru, | ||
407 | int restart) | ||
408 | { | ||
409 | if (!mru || !mru->lists) | ||
410 | return; | ||
411 | |||
412 | cancel_rearming_delayed_workqueue(xfs_mru_reap_wq, &mru->work); | ||
413 | |||
414 | mutex_spinlock(&mru->lock); | ||
415 | mru->reap_all = 1; | ||
416 | mutex_spinunlock(&mru->lock, 0); | ||
417 | |||
418 | queue_work(xfs_mru_reap_wq, &mru->work.work); | ||
419 | flush_workqueue(xfs_mru_reap_wq); | ||
420 | |||
421 | mutex_spinlock(&mru->lock); | ||
422 | WARN_ON_ONCE(mru->reap_all != 0); | ||
423 | mru->reap_all = 0; | ||
424 | if (restart) | ||
425 | queue_delayed_work(xfs_mru_reap_wq, &mru->work, mru->grp_time); | ||
426 | mutex_spinunlock(&mru->lock, 0); | ||
427 | } | ||
428 | |||
429 | void | ||
430 | xfs_mru_cache_destroy( | ||
431 | xfs_mru_cache_t *mru) | ||
432 | { | ||
433 | if (!mru || !mru->lists) | ||
434 | return; | ||
435 | |||
436 | /* we don't want the reaper to restart here */ | ||
437 | xfs_mru_cache_flush(mru, 0); | ||
438 | |||
439 | kmem_free(mru->lists, mru->grp_count * sizeof(*mru->lists)); | ||
440 | kmem_free(mru, sizeof(*mru)); | ||
441 | } | ||
442 | |||
443 | /* | ||
444 | * To insert an element, call xfs_mru_cache_insert() with the data store, the | ||
445 | * element's key and the client data pointer. This function returns 0 on | ||
446 | * success or ENOMEM if memory for the data element couldn't be allocated. | ||
447 | */ | ||
448 | int | ||
449 | xfs_mru_cache_insert( | ||
450 | xfs_mru_cache_t *mru, | ||
451 | unsigned long key, | ||
452 | void *value) | ||
453 | { | ||
454 | xfs_mru_cache_elem_t *elem; | ||
455 | |||
456 | ASSERT(mru && mru->lists); | ||
457 | if (!mru || !mru->lists) | ||
458 | return EINVAL; | ||
459 | |||
460 | elem = kmem_zone_zalloc(xfs_mru_elem_zone, KM_SLEEP); | ||
461 | if (!elem) | ||
462 | return ENOMEM; | ||
463 | |||
464 | if (radix_tree_preload(GFP_KERNEL)) { | ||
465 | kmem_zone_free(xfs_mru_elem_zone, elem); | ||
466 | return ENOMEM; | ||
467 | } | ||
468 | |||
469 | INIT_LIST_HEAD(&elem->list_node); | ||
470 | elem->key = key; | ||
471 | elem->value = value; | ||
472 | |||
473 | mutex_spinlock(&mru->lock); | ||
474 | |||
475 | radix_tree_insert(&mru->store, key, elem); | ||
476 | radix_tree_preload_end(); | ||
477 | _xfs_mru_cache_list_insert(mru, elem); | ||
478 | |||
479 | mutex_spinunlock(&mru->lock, 0); | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | /* | ||
485 | * To remove an element without calling the free function, call | ||
486 | * xfs_mru_cache_remove() with the data store and the element's key. On success | ||
487 | * the client data pointer for the removed element is returned, otherwise this | ||
488 | * function will return a NULL pointer. | ||
489 | */ | ||
490 | void * | ||
491 | xfs_mru_cache_remove( | ||
492 | xfs_mru_cache_t *mru, | ||
493 | unsigned long key) | ||
494 | { | ||
495 | xfs_mru_cache_elem_t *elem; | ||
496 | void *value = NULL; | ||
497 | |||
498 | ASSERT(mru && mru->lists); | ||
499 | if (!mru || !mru->lists) | ||
500 | return NULL; | ||
501 | |||
502 | mutex_spinlock(&mru->lock); | ||
503 | elem = radix_tree_delete(&mru->store, key); | ||
504 | if (elem) { | ||
505 | value = elem->value; | ||
506 | list_del(&elem->list_node); | ||
507 | } | ||
508 | |||
509 | mutex_spinunlock(&mru->lock, 0); | ||
510 | |||
511 | if (elem) | ||
512 | kmem_zone_free(xfs_mru_elem_zone, elem); | ||
513 | |||
514 | return value; | ||
515 | } | ||
516 | |||
517 | /* | ||
518 | * To remove and element and call the free function, call xfs_mru_cache_delete() | ||
519 | * with the data store and the element's key. | ||
520 | */ | ||
521 | void | ||
522 | xfs_mru_cache_delete( | ||
523 | xfs_mru_cache_t *mru, | ||
524 | unsigned long key) | ||
525 | { | ||
526 | void *value = xfs_mru_cache_remove(mru, key); | ||
527 | |||
528 | if (value) | ||
529 | mru->free_func(key, value); | ||
530 | } | ||
531 | |||
532 | /* | ||
533 | * To look up an element using its key, call xfs_mru_cache_lookup() with the | ||
534 | * data store and the element's key. If found, the element will be moved to the | ||
535 | * head of the MRU list to indicate that it's been touched. | ||
536 | * | ||
537 | * The internal data structures are protected by a spinlock that is STILL HELD | ||
538 | * when this function returns. Call xfs_mru_cache_done() to release it. Note | ||
539 | * that it is not safe to call any function that might sleep in the interim. | ||
540 | * | ||
541 | * The implementation could have used reference counting to avoid this | ||
542 | * restriction, but since most clients simply want to get, set or test a member | ||
543 | * of the returned data structure, the extra per-element memory isn't warranted. | ||
544 | * | ||
545 | * If the element isn't found, this function returns NULL and the spinlock is | ||
546 | * released. xfs_mru_cache_done() should NOT be called when this occurs. | ||
547 | */ | ||
548 | void * | ||
549 | xfs_mru_cache_lookup( | ||
550 | xfs_mru_cache_t *mru, | ||
551 | unsigned long key) | ||
552 | { | ||
553 | xfs_mru_cache_elem_t *elem; | ||
554 | |||
555 | ASSERT(mru && mru->lists); | ||
556 | if (!mru || !mru->lists) | ||
557 | return NULL; | ||
558 | |||
559 | mutex_spinlock(&mru->lock); | ||
560 | elem = radix_tree_lookup(&mru->store, key); | ||
561 | if (elem) { | ||
562 | list_del(&elem->list_node); | ||
563 | _xfs_mru_cache_list_insert(mru, elem); | ||
564 | } | ||
565 | else | ||
566 | mutex_spinunlock(&mru->lock, 0); | ||
567 | |||
568 | return elem ? elem->value : NULL; | ||
569 | } | ||
570 | |||
571 | /* | ||
572 | * To look up an element using its key, but leave its location in the internal | ||
573 | * lists alone, call xfs_mru_cache_peek(). If the element isn't found, this | ||
574 | * function returns NULL. | ||
575 | * | ||
576 | * See the comments above the declaration of the xfs_mru_cache_lookup() function | ||
577 | * for important locking information pertaining to this call. | ||
578 | */ | ||
579 | void * | ||
580 | xfs_mru_cache_peek( | ||
581 | xfs_mru_cache_t *mru, | ||
582 | unsigned long key) | ||
583 | { | ||
584 | xfs_mru_cache_elem_t *elem; | ||
585 | |||
586 | ASSERT(mru && mru->lists); | ||
587 | if (!mru || !mru->lists) | ||
588 | return NULL; | ||
589 | |||
590 | mutex_spinlock(&mru->lock); | ||
591 | elem = radix_tree_lookup(&mru->store, key); | ||
592 | if (!elem) | ||
593 | mutex_spinunlock(&mru->lock, 0); | ||
594 | |||
595 | return elem ? elem->value : NULL; | ||
596 | } | ||
597 | |||
598 | /* | ||
599 | * To release the internal data structure spinlock after having performed an | ||
600 | * xfs_mru_cache_lookup() or an xfs_mru_cache_peek(), call xfs_mru_cache_done() | ||
601 | * with the data store pointer. | ||
602 | */ | ||
603 | void | ||
604 | xfs_mru_cache_done( | ||
605 | xfs_mru_cache_t *mru) | ||
606 | { | ||
607 | mutex_spinunlock(&mru->lock, 0); | ||
608 | } | ||
diff --git a/fs/xfs/xfs_mru_cache.h b/fs/xfs/xfs_mru_cache.h new file mode 100644 index 00000000000..624fd10ee8e --- /dev/null +++ b/fs/xfs/xfs_mru_cache.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2006-2007 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_MRU_CACHE_H__ | ||
19 | #define __XFS_MRU_CACHE_H__ | ||
20 | |||
21 | |||
22 | /* Function pointer type for callback to free a client's data pointer. */ | ||
23 | typedef void (*xfs_mru_cache_free_func_t)(unsigned long, void*); | ||
24 | |||
25 | typedef struct xfs_mru_cache | ||
26 | { | ||
27 | struct radix_tree_root store; /* Core storage data structure. */ | ||
28 | struct list_head *lists; /* Array of lists, one per grp. */ | ||
29 | struct list_head reap_list; /* Elements overdue for reaping. */ | ||
30 | spinlock_t lock; /* Lock to protect this struct. */ | ||
31 | unsigned int grp_count; /* Number of discrete groups. */ | ||
32 | unsigned int grp_time; /* Time period spanned by grps. */ | ||
33 | unsigned int lru_grp; /* Group containing time zero. */ | ||
34 | unsigned long time_zero; /* Time first element was added. */ | ||
35 | unsigned long next_reap; /* Time that the reaper should | ||
36 | next do something. */ | ||
37 | unsigned int reap_all; /* if set, reap all lists */ | ||
38 | xfs_mru_cache_free_func_t free_func; /* Function pointer for freeing. */ | ||
39 | struct delayed_work work; /* Workqueue data for reaping. */ | ||
40 | } xfs_mru_cache_t; | ||
41 | |||
42 | int xfs_mru_cache_init(void); | ||
43 | void xfs_mru_cache_uninit(void); | ||
44 | int xfs_mru_cache_create(struct xfs_mru_cache **mrup, unsigned int lifetime_ms, | ||
45 | unsigned int grp_count, | ||
46 | xfs_mru_cache_free_func_t free_func); | ||
47 | void xfs_mru_cache_flush(xfs_mru_cache_t *mru, int restart); | ||
48 | void xfs_mru_cache_destroy(struct xfs_mru_cache *mru); | ||
49 | int xfs_mru_cache_insert(struct xfs_mru_cache *mru, unsigned long key, | ||
50 | void *value); | ||
51 | void * xfs_mru_cache_remove(struct xfs_mru_cache *mru, unsigned long key); | ||
52 | void xfs_mru_cache_delete(struct xfs_mru_cache *mru, unsigned long key); | ||
53 | void *xfs_mru_cache_lookup(struct xfs_mru_cache *mru, unsigned long key); | ||
54 | void *xfs_mru_cache_peek(struct xfs_mru_cache *mru, unsigned long key); | ||
55 | void xfs_mru_cache_done(struct xfs_mru_cache *mru); | ||
56 | |||
57 | #endif /* __XFS_MRU_CACHE_H__ */ | ||
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index b3a5f07bd07..47082c01872 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -1882,11 +1882,13 @@ xfs_growfs_rt( | |||
1882 | (nrblocks = in->newblocks) <= sbp->sb_rblocks || | 1882 | (nrblocks = in->newblocks) <= sbp->sb_rblocks || |
1883 | (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize))) | 1883 | (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize))) |
1884 | return XFS_ERROR(EINVAL); | 1884 | return XFS_ERROR(EINVAL); |
1885 | if ((error = xfs_sb_validate_fsb_count(sbp, nrblocks))) | ||
1886 | return error; | ||
1885 | /* | 1887 | /* |
1886 | * Read in the last block of the device, make sure it exists. | 1888 | * Read in the last block of the device, make sure it exists. |
1887 | */ | 1889 | */ |
1888 | error = xfs_read_buf(mp, mp->m_rtdev_targp, | 1890 | error = xfs_read_buf(mp, mp->m_rtdev_targp, |
1889 | XFS_FSB_TO_BB(mp, in->newblocks - 1), | 1891 | XFS_FSB_TO_BB(mp, nrblocks - 1), |
1890 | XFS_FSB_TO_BB(mp, 1), 0, &bp); | 1892 | XFS_FSB_TO_BB(mp, 1), 0, &bp); |
1891 | if (error) | 1893 | if (error) |
1892 | return error; | 1894 | return error; |
diff --git a/fs/xfs/xfs_rw.h b/fs/xfs/xfs_rw.h index 188b296ff50..fcf28dbded7 100644 --- a/fs/xfs/xfs_rw.h +++ b/fs/xfs/xfs_rw.h | |||
@@ -72,6 +72,34 @@ xfs_fsb_to_db_io(struct xfs_iocore *io, xfs_fsblock_t fsb) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * Flags for xfs_free_eofblocks | ||
76 | */ | ||
77 | #define XFS_FREE_EOF_LOCK (1<<0) | ||
78 | #define XFS_FREE_EOF_NOLOCK (1<<1) | ||
79 | |||
80 | |||
81 | /* | ||
82 | * helper function to extract extent size hint from inode | ||
83 | */ | ||
84 | STATIC_INLINE xfs_extlen_t | ||
85 | xfs_get_extsz_hint( | ||
86 | xfs_inode_t *ip) | ||
87 | { | ||
88 | xfs_extlen_t extsz; | ||
89 | |||
90 | if (unlikely(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) { | ||
91 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
92 | ? ip->i_d.di_extsize | ||
93 | : ip->i_mount->m_sb.sb_rextsize; | ||
94 | ASSERT(extsz); | ||
95 | } else { | ||
96 | extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE) | ||
97 | ? ip->i_d.di_extsize : 0; | ||
98 | } | ||
99 | return extsz; | ||
100 | } | ||
101 | |||
102 | /* | ||
75 | * Prototypes for functions in xfs_rw.c. | 103 | * Prototypes for functions in xfs_rw.c. |
76 | */ | 104 | */ |
77 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); | 105 | extern int xfs_write_clear_setuid(struct xfs_inode *ip); |
@@ -91,10 +119,12 @@ extern void xfs_ioerror_alert(char *func, struct xfs_mount *mp, | |||
91 | extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); | 119 | extern int xfs_rwlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
92 | extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); | 120 | extern void xfs_rwunlock(bhv_desc_t *bdp, bhv_vrwlock_t write_lock); |
93 | extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags, | 121 | extern int xfs_setattr(bhv_desc_t *, bhv_vattr_t *vap, int flags, |
94 | cred_t *credp); | 122 | cred_t *credp); |
95 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, | 123 | extern int xfs_change_file_space(bhv_desc_t *bdp, int cmd, xfs_flock64_t *bf, |
96 | xfs_off_t offset, cred_t *credp, int flags); | 124 | xfs_off_t offset, cred_t *credp, int flags); |
97 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, | 125 | extern int xfs_set_dmattrs(bhv_desc_t *bdp, u_int evmask, u_int16_t state, |
98 | cred_t *credp); | 126 | cred_t *credp); |
127 | extern int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, | ||
128 | int flags); | ||
99 | 129 | ||
100 | #endif /* __XFS_RW_H__ */ | 130 | #endif /* __XFS_RW_H__ */ |
diff --git a/fs/xfs/xfs_sb.h b/fs/xfs/xfs_sb.h index 467854b45c8..ef42537a607 100644 --- a/fs/xfs/xfs_sb.h +++ b/fs/xfs/xfs_sb.h | |||
@@ -74,12 +74,13 @@ struct xfs_mount; | |||
74 | */ | 74 | */ |
75 | #define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */ | 75 | #define XFS_SB_VERSION2_REALFBITS 0x00ffffff /* Mask: features */ |
76 | #define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 | 76 | #define XFS_SB_VERSION2_RESERVED1BIT 0x00000001 |
77 | #define XFS_SB_VERSION2_RESERVED2BIT 0x00000002 | 77 | #define XFS_SB_VERSION2_LAZYSBCOUNTBIT 0x00000002 /* Superblk counters */ |
78 | #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 | 78 | #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 |
79 | #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ | 79 | #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ |
80 | 80 | ||
81 | #define XFS_SB_VERSION2_OKREALFBITS \ | 81 | #define XFS_SB_VERSION2_OKREALFBITS \ |
82 | (XFS_SB_VERSION2_ATTR2BIT) | 82 | (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ |
83 | XFS_SB_VERSION2_ATTR2BIT) | ||
83 | #define XFS_SB_VERSION2_OKSASHFBITS \ | 84 | #define XFS_SB_VERSION2_OKSASHFBITS \ |
84 | (0) | 85 | (0) |
85 | #define XFS_SB_VERSION2_OKREALBITS \ | 86 | #define XFS_SB_VERSION2_OKREALBITS \ |
@@ -181,6 +182,9 @@ typedef enum { | |||
181 | #define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) | 182 | #define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) |
182 | #define XFS_SB_UNIT XFS_SB_MVAL(UNIT) | 183 | #define XFS_SB_UNIT XFS_SB_MVAL(UNIT) |
183 | #define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) | 184 | #define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) |
185 | #define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) | ||
186 | #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) | ||
187 | #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) | ||
184 | #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) | 188 | #define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) |
185 | #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) | 189 | #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) |
186 | #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) | 190 | #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) |
@@ -188,7 +192,7 @@ typedef enum { | |||
188 | (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ | 192 | (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ |
189 | XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ | 193 | XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ |
190 | XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ | 194 | XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ |
191 | XFS_SB_FEATURES2) | 195 | XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2) |
192 | 196 | ||
193 | 197 | ||
194 | /* | 198 | /* |
@@ -414,6 +418,12 @@ static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp) | |||
414 | * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) | 418 | * ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT) |
415 | */ | 419 | */ |
416 | 420 | ||
421 | static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp) | ||
422 | { | ||
423 | return (XFS_SB_VERSION_HASMOREBITS(sbp) && \ | ||
424 | ((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT)); | ||
425 | } | ||
426 | |||
417 | #define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp) | 427 | #define XFS_SB_VERSION_HASATTR2(sbp) xfs_sb_version_hasattr2(sbp) |
418 | static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) | 428 | static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp) |
419 | { | 429 | { |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index cc2d60951e2..356d6627f58 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -427,6 +427,14 @@ undo_blocks: | |||
427 | * | 427 | * |
428 | * Mark the transaction structure to indicate that the superblock | 428 | * Mark the transaction structure to indicate that the superblock |
429 | * needs to be updated before committing. | 429 | * needs to be updated before committing. |
430 | * | ||
431 | * Because we may not be keeping track of allocated/free inodes and | ||
432 | * used filesystem blocks in the superblock, we do not mark the | ||
433 | * superblock dirty in this transaction if we modify these fields. | ||
434 | * We still need to update the transaction deltas so that they get | ||
435 | * applied to the incore superblock, but we don't want them to | ||
436 | * cause the superblock to get locked and logged if these are the | ||
437 | * only fields in the superblock that the transaction modifies. | ||
430 | */ | 438 | */ |
431 | void | 439 | void |
432 | xfs_trans_mod_sb( | 440 | xfs_trans_mod_sb( |
@@ -434,13 +442,19 @@ xfs_trans_mod_sb( | |||
434 | uint field, | 442 | uint field, |
435 | int64_t delta) | 443 | int64_t delta) |
436 | { | 444 | { |
445 | uint32_t flags = (XFS_TRANS_DIRTY|XFS_TRANS_SB_DIRTY); | ||
446 | xfs_mount_t *mp = tp->t_mountp; | ||
437 | 447 | ||
438 | switch (field) { | 448 | switch (field) { |
439 | case XFS_TRANS_SB_ICOUNT: | 449 | case XFS_TRANS_SB_ICOUNT: |
440 | tp->t_icount_delta += delta; | 450 | tp->t_icount_delta += delta; |
451 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
452 | flags &= ~XFS_TRANS_SB_DIRTY; | ||
441 | break; | 453 | break; |
442 | case XFS_TRANS_SB_IFREE: | 454 | case XFS_TRANS_SB_IFREE: |
443 | tp->t_ifree_delta += delta; | 455 | tp->t_ifree_delta += delta; |
456 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
457 | flags &= ~XFS_TRANS_SB_DIRTY; | ||
444 | break; | 458 | break; |
445 | case XFS_TRANS_SB_FDBLOCKS: | 459 | case XFS_TRANS_SB_FDBLOCKS: |
446 | /* | 460 | /* |
@@ -453,6 +467,8 @@ xfs_trans_mod_sb( | |||
453 | ASSERT(tp->t_blk_res_used <= tp->t_blk_res); | 467 | ASSERT(tp->t_blk_res_used <= tp->t_blk_res); |
454 | } | 468 | } |
455 | tp->t_fdblocks_delta += delta; | 469 | tp->t_fdblocks_delta += delta; |
470 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
471 | flags &= ~XFS_TRANS_SB_DIRTY; | ||
456 | break; | 472 | break; |
457 | case XFS_TRANS_SB_RES_FDBLOCKS: | 473 | case XFS_TRANS_SB_RES_FDBLOCKS: |
458 | /* | 474 | /* |
@@ -462,6 +478,8 @@ xfs_trans_mod_sb( | |||
462 | */ | 478 | */ |
463 | ASSERT(delta < 0); | 479 | ASSERT(delta < 0); |
464 | tp->t_res_fdblocks_delta += delta; | 480 | tp->t_res_fdblocks_delta += delta; |
481 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
482 | flags &= ~XFS_TRANS_SB_DIRTY; | ||
465 | break; | 483 | break; |
466 | case XFS_TRANS_SB_FREXTENTS: | 484 | case XFS_TRANS_SB_FREXTENTS: |
467 | /* | 485 | /* |
@@ -515,7 +533,7 @@ xfs_trans_mod_sb( | |||
515 | return; | 533 | return; |
516 | } | 534 | } |
517 | 535 | ||
518 | tp->t_flags |= (XFS_TRANS_SB_DIRTY | XFS_TRANS_DIRTY); | 536 | tp->t_flags |= flags; |
519 | } | 537 | } |
520 | 538 | ||
521 | /* | 539 | /* |
@@ -544,18 +562,23 @@ xfs_trans_apply_sb_deltas( | |||
544 | (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta + | 562 | (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta + |
545 | tp->t_ag_btree_delta)); | 563 | tp->t_ag_btree_delta)); |
546 | 564 | ||
547 | if (tp->t_icount_delta != 0) { | 565 | /* |
548 | INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); | 566 | * Only update the superblock counters if we are logging them |
549 | } | 567 | */ |
550 | if (tp->t_ifree_delta != 0) { | 568 | if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { |
551 | INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); | 569 | if (tp->t_icount_delta != 0) { |
552 | } | 570 | INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); |
571 | } | ||
572 | if (tp->t_ifree_delta != 0) { | ||
573 | INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); | ||
574 | } | ||
553 | 575 | ||
554 | if (tp->t_fdblocks_delta != 0) { | 576 | if (tp->t_fdblocks_delta != 0) { |
555 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta); | 577 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta); |
556 | } | 578 | } |
557 | if (tp->t_res_fdblocks_delta != 0) { | 579 | if (tp->t_res_fdblocks_delta != 0) { |
558 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta); | 580 | INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta); |
581 | } | ||
559 | } | 582 | } |
560 | 583 | ||
561 | if (tp->t_frextents_delta != 0) { | 584 | if (tp->t_frextents_delta != 0) { |
@@ -615,11 +638,23 @@ xfs_trans_apply_sb_deltas( | |||
615 | } | 638 | } |
616 | 639 | ||
617 | /* | 640 | /* |
618 | * xfs_trans_unreserve_and_mod_sb() is called to release unused | 641 | * xfs_trans_unreserve_and_mod_sb() is called to release unused reservations |
619 | * reservations and apply superblock counter changes to the in-core | 642 | * and apply superblock counter changes to the in-core superblock. The |
620 | * superblock. | 643 | * t_res_fdblocks_delta and t_res_frextents_delta fields are explicitly NOT |
644 | * applied to the in-core superblock. The idea is that that has already been | ||
645 | * done. | ||
621 | * | 646 | * |
622 | * This is done efficiently with a single call to xfs_mod_incore_sb_batch(). | 647 | * This is done efficiently with a single call to xfs_mod_incore_sb_batch(). |
648 | * However, we have to ensure that we only modify each superblock field only | ||
649 | * once because the application of the delta values may not be atomic. That can | ||
650 | * lead to ENOSPC races occurring if we have two separate modifcations of the | ||
651 | * free space counter to put back the entire reservation and then take away | ||
652 | * what we used. | ||
653 | * | ||
654 | * If we are not logging superblock counters, then the inode allocated/free and | ||
655 | * used block counts are not updated in the on disk superblock. In this case, | ||
656 | * XFS_TRANS_SB_DIRTY will not be set when the transaction is updated but we | ||
657 | * still need to update the incore superblock with the changes. | ||
623 | */ | 658 | */ |
624 | STATIC void | 659 | STATIC void |
625 | xfs_trans_unreserve_and_mod_sb( | 660 | xfs_trans_unreserve_and_mod_sb( |
@@ -627,40 +662,49 @@ xfs_trans_unreserve_and_mod_sb( | |||
627 | { | 662 | { |
628 | xfs_mod_sb_t msb[14]; /* If you add cases, add entries */ | 663 | xfs_mod_sb_t msb[14]; /* If you add cases, add entries */ |
629 | xfs_mod_sb_t *msbp; | 664 | xfs_mod_sb_t *msbp; |
665 | xfs_mount_t *mp = tp->t_mountp; | ||
630 | /* REFERENCED */ | 666 | /* REFERENCED */ |
631 | int error; | 667 | int error; |
632 | int rsvd; | 668 | int rsvd; |
669 | int64_t blkdelta = 0; | ||
670 | int64_t rtxdelta = 0; | ||
633 | 671 | ||
634 | msbp = msb; | 672 | msbp = msb; |
635 | rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; | 673 | rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; |
636 | 674 | ||
637 | /* | 675 | /* calculate free blocks delta */ |
638 | * Release any reserved blocks. Any that were allocated | 676 | if (tp->t_blk_res > 0) |
639 | * will be taken back again by fdblocks_delta below. | 677 | blkdelta = tp->t_blk_res; |
640 | */ | 678 | |
641 | if (tp->t_blk_res > 0) { | 679 | if ((tp->t_fdblocks_delta != 0) && |
680 | (xfs_sb_version_haslazysbcount(&mp->m_sb) || | ||
681 | (tp->t_flags & XFS_TRANS_SB_DIRTY))) | ||
682 | blkdelta += tp->t_fdblocks_delta; | ||
683 | |||
684 | if (blkdelta != 0) { | ||
642 | msbp->msb_field = XFS_SBS_FDBLOCKS; | 685 | msbp->msb_field = XFS_SBS_FDBLOCKS; |
643 | msbp->msb_delta = tp->t_blk_res; | 686 | msbp->msb_delta = blkdelta; |
644 | msbp++; | 687 | msbp++; |
645 | } | 688 | } |
646 | 689 | ||
647 | /* | 690 | /* calculate free realtime extents delta */ |
648 | * Release any reserved real time extents . Any that were | 691 | if (tp->t_rtx_res > 0) |
649 | * allocated will be taken back again by frextents_delta below. | 692 | rtxdelta = tp->t_rtx_res; |
650 | */ | 693 | |
651 | if (tp->t_rtx_res > 0) { | 694 | if ((tp->t_frextents_delta != 0) && |
695 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) | ||
696 | rtxdelta += tp->t_frextents_delta; | ||
697 | |||
698 | if (rtxdelta != 0) { | ||
652 | msbp->msb_field = XFS_SBS_FREXTENTS; | 699 | msbp->msb_field = XFS_SBS_FREXTENTS; |
653 | msbp->msb_delta = tp->t_rtx_res; | 700 | msbp->msb_delta = rtxdelta; |
654 | msbp++; | 701 | msbp++; |
655 | } | 702 | } |
656 | 703 | ||
657 | /* | 704 | /* apply remaining deltas */ |
658 | * Apply any superblock modifications to the in-core version. | 705 | |
659 | * The t_res_fdblocks_delta and t_res_frextents_delta fields are | 706 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) || |
660 | * explicitly NOT applied to the in-core superblock. | 707 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) { |
661 | * The idea is that that has already been done. | ||
662 | */ | ||
663 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) { | ||
664 | if (tp->t_icount_delta != 0) { | 708 | if (tp->t_icount_delta != 0) { |
665 | msbp->msb_field = XFS_SBS_ICOUNT; | 709 | msbp->msb_field = XFS_SBS_ICOUNT; |
666 | msbp->msb_delta = tp->t_icount_delta; | 710 | msbp->msb_delta = tp->t_icount_delta; |
@@ -671,16 +715,9 @@ xfs_trans_unreserve_and_mod_sb( | |||
671 | msbp->msb_delta = tp->t_ifree_delta; | 715 | msbp->msb_delta = tp->t_ifree_delta; |
672 | msbp++; | 716 | msbp++; |
673 | } | 717 | } |
674 | if (tp->t_fdblocks_delta != 0) { | 718 | } |
675 | msbp->msb_field = XFS_SBS_FDBLOCKS; | 719 | |
676 | msbp->msb_delta = tp->t_fdblocks_delta; | 720 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) { |
677 | msbp++; | ||
678 | } | ||
679 | if (tp->t_frextents_delta != 0) { | ||
680 | msbp->msb_field = XFS_SBS_FREXTENTS; | ||
681 | msbp->msb_delta = tp->t_frextents_delta; | ||
682 | msbp++; | ||
683 | } | ||
684 | if (tp->t_dblocks_delta != 0) { | 721 | if (tp->t_dblocks_delta != 0) { |
685 | msbp->msb_field = XFS_SBS_DBLOCKS; | 722 | msbp->msb_field = XFS_SBS_DBLOCKS; |
686 | msbp->msb_delta = tp->t_dblocks_delta; | 723 | msbp->msb_delta = tp->t_dblocks_delta; |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 7dfcc450366..0e26e729023 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -94,7 +94,8 @@ typedef struct xfs_trans_header { | |||
94 | #define XFS_TRANS_GROWFSRT_ZERO 38 | 94 | #define XFS_TRANS_GROWFSRT_ZERO 38 |
95 | #define XFS_TRANS_GROWFSRT_FREE 39 | 95 | #define XFS_TRANS_GROWFSRT_FREE 39 |
96 | #define XFS_TRANS_SWAPEXT 40 | 96 | #define XFS_TRANS_SWAPEXT 40 |
97 | #define XFS_TRANS_TYPE_MAX 40 | 97 | #define XFS_TRANS_SB_COUNT 41 |
98 | #define XFS_TRANS_TYPE_MAX 41 | ||
98 | /* new transaction types need to be reflected in xfs_logprint(8) */ | 99 | /* new transaction types need to be reflected in xfs_logprint(8) */ |
99 | 100 | ||
100 | 101 | ||
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 65c561201cb..11f5ea29a03 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #include "xfs_acl.h" | 51 | #include "xfs_acl.h" |
52 | #include "xfs_attr.h" | 52 | #include "xfs_attr.h" |
53 | #include "xfs_clnt.h" | 53 | #include "xfs_clnt.h" |
54 | #include "xfs_mru_cache.h" | ||
55 | #include "xfs_filestream.h" | ||
54 | #include "xfs_fsops.h" | 56 | #include "xfs_fsops.h" |
55 | 57 | ||
56 | STATIC int xfs_sync(bhv_desc_t *, int, cred_t *); | 58 | STATIC int xfs_sync(bhv_desc_t *, int, cred_t *); |
@@ -81,6 +83,8 @@ xfs_init(void) | |||
81 | xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); | 83 | xfs_dabuf_zone = kmem_zone_init(sizeof(xfs_dabuf_t), "xfs_dabuf"); |
82 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); | 84 | xfs_ifork_zone = kmem_zone_init(sizeof(xfs_ifork_t), "xfs_ifork"); |
83 | xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); | 85 | xfs_acl_zone_init(xfs_acl_zone, "xfs_acl"); |
86 | xfs_mru_cache_init(); | ||
87 | xfs_filestream_init(); | ||
84 | 88 | ||
85 | /* | 89 | /* |
86 | * The size of the zone allocated buf log item is the maximum | 90 | * The size of the zone allocated buf log item is the maximum |
@@ -164,6 +168,8 @@ xfs_cleanup(void) | |||
164 | xfs_cleanup_procfs(); | 168 | xfs_cleanup_procfs(); |
165 | xfs_sysctl_unregister(); | 169 | xfs_sysctl_unregister(); |
166 | xfs_refcache_destroy(); | 170 | xfs_refcache_destroy(); |
171 | xfs_filestream_uninit(); | ||
172 | xfs_mru_cache_uninit(); | ||
167 | xfs_acl_zone_destroy(xfs_acl_zone); | 173 | xfs_acl_zone_destroy(xfs_acl_zone); |
168 | 174 | ||
169 | #ifdef XFS_DIR2_TRACE | 175 | #ifdef XFS_DIR2_TRACE |
@@ -320,6 +326,9 @@ xfs_start_flags( | |||
320 | else | 326 | else |
321 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 327 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
322 | 328 | ||
329 | if (ap->flags2 & XFSMNT2_FILESTREAMS) | ||
330 | mp->m_flags |= XFS_MOUNT_FILESTREAMS; | ||
331 | |||
323 | return 0; | 332 | return 0; |
324 | } | 333 | } |
325 | 334 | ||
@@ -518,6 +527,9 @@ xfs_mount( | |||
518 | if (mp->m_flags & XFS_MOUNT_BARRIER) | 527 | if (mp->m_flags & XFS_MOUNT_BARRIER) |
519 | xfs_mountfs_check_barriers(mp); | 528 | xfs_mountfs_check_barriers(mp); |
520 | 529 | ||
530 | if ((error = xfs_filestream_mount(mp))) | ||
531 | goto error2; | ||
532 | |||
521 | error = XFS_IOINIT(vfsp, args, flags); | 533 | error = XFS_IOINIT(vfsp, args, flags); |
522 | if (error) | 534 | if (error) |
523 | goto error2; | 535 | goto error2; |
@@ -575,6 +587,13 @@ xfs_unmount( | |||
575 | */ | 587 | */ |
576 | xfs_refcache_purge_mp(mp); | 588 | xfs_refcache_purge_mp(mp); |
577 | 589 | ||
590 | /* | ||
591 | * Blow away any referenced inode in the filestreams cache. | ||
592 | * This can and will cause log traffic as inodes go inactive | ||
593 | * here. | ||
594 | */ | ||
595 | xfs_filestream_unmount(mp); | ||
596 | |||
578 | XFS_bflush(mp->m_ddev_targp); | 597 | XFS_bflush(mp->m_ddev_targp); |
579 | error = xfs_unmount_flush(mp, 0); | 598 | error = xfs_unmount_flush(mp, 0); |
580 | if (error) | 599 | if (error) |
@@ -640,7 +659,7 @@ xfs_quiesce_fs( | |||
640 | * we can write the unmount record. | 659 | * we can write the unmount record. |
641 | */ | 660 | */ |
642 | do { | 661 | do { |
643 | xfs_syncsub(mp, SYNC_REMOUNT|SYNC_ATTR|SYNC_WAIT, NULL); | 662 | xfs_syncsub(mp, SYNC_INODE_QUIESCE, NULL); |
644 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); | 663 | pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1); |
645 | if (!pincount) { | 664 | if (!pincount) { |
646 | delay(50); | 665 | delay(50); |
@@ -651,6 +670,30 @@ xfs_quiesce_fs( | |||
651 | return 0; | 670 | return 0; |
652 | } | 671 | } |
653 | 672 | ||
673 | /* | ||
674 | * Second stage of a quiesce. The data is already synced, now we have to take | ||
675 | * care of the metadata. New transactions are already blocked, so we need to | ||
676 | * wait for any remaining transactions to drain out before proceding. | ||
677 | */ | ||
678 | STATIC void | ||
679 | xfs_attr_quiesce( | ||
680 | xfs_mount_t *mp) | ||
681 | { | ||
682 | /* wait for all modifications to complete */ | ||
683 | while (atomic_read(&mp->m_active_trans) > 0) | ||
684 | delay(100); | ||
685 | |||
686 | /* flush inodes and push all remaining buffers out to disk */ | ||
687 | xfs_quiesce_fs(mp); | ||
688 | |||
689 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
690 | |||
691 | /* Push the superblock and write an unmount record */ | ||
692 | xfs_log_sbcount(mp, 1); | ||
693 | xfs_log_unmount_write(mp); | ||
694 | xfs_unmountfs_writesb(mp); | ||
695 | } | ||
696 | |||
654 | STATIC int | 697 | STATIC int |
655 | xfs_mntupdate( | 698 | xfs_mntupdate( |
656 | bhv_desc_t *bdp, | 699 | bhv_desc_t *bdp, |
@@ -670,10 +713,9 @@ xfs_mntupdate( | |||
670 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | 713 | mp->m_flags &= ~XFS_MOUNT_BARRIER; |
671 | } | 714 | } |
672 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ | 715 | } else if (!(vfsp->vfs_flag & VFS_RDONLY)) { /* rw -> ro */ |
673 | bhv_vfs_sync(vfsp, SYNC_FSDATA|SYNC_BDFLUSH|SYNC_ATTR, NULL); | 716 | xfs_filestream_flush(mp); |
674 | xfs_quiesce_fs(mp); | 717 | bhv_vfs_sync(vfsp, SYNC_DATA_QUIESCE, NULL); |
675 | xfs_log_unmount_write(mp); | 718 | xfs_attr_quiesce(mp); |
676 | xfs_unmountfs_writesb(mp); | ||
677 | vfsp->vfs_flag |= VFS_RDONLY; | 719 | vfsp->vfs_flag |= VFS_RDONLY; |
678 | } | 720 | } |
679 | return 0; | 721 | return 0; |
@@ -887,6 +929,9 @@ xfs_sync( | |||
887 | { | 929 | { |
888 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 930 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
889 | 931 | ||
932 | if (flags & SYNC_IOWAIT) | ||
933 | xfs_filestream_flush(mp); | ||
934 | |||
890 | return xfs_syncsub(mp, flags, NULL); | 935 | return xfs_syncsub(mp, flags, NULL); |
891 | } | 936 | } |
892 | 937 | ||
@@ -1128,58 +1173,41 @@ xfs_sync_inodes( | |||
1128 | * in the inode list. | 1173 | * in the inode list. |
1129 | */ | 1174 | */ |
1130 | 1175 | ||
1131 | if ((flags & SYNC_CLOSE) && (vp != NULL)) { | 1176 | /* |
1132 | /* | 1177 | * If we have to flush data or wait for I/O completion |
1133 | * This is the shutdown case. We just need to | 1178 | * we need to drop the ilock that we currently hold. |
1134 | * flush and invalidate all the pages associated | 1179 | * If we need to drop the lock, insert a marker if we |
1135 | * with the inode. Drop the inode lock since | 1180 | * have not already done so. |
1136 | * we can't hold it across calls to the buffer | 1181 | */ |
1137 | * cache. | 1182 | if ((flags & (SYNC_CLOSE|SYNC_IOWAIT)) || |
1138 | * | 1183 | ((flags & SYNC_DELWRI) && VN_DIRTY(vp))) { |
1139 | * We don't set the VREMAPPING bit in the vnode | 1184 | if (mount_locked) { |
1140 | * here, because we don't hold the vnode lock | 1185 | IPOINTER_INSERT(ip, mp); |
1141 | * exclusively. It doesn't really matter, though, | ||
1142 | * because we only come here when we're shutting | ||
1143 | * down anyway. | ||
1144 | */ | ||
1145 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1146 | |||
1147 | if (XFS_FORCED_SHUTDOWN(mp)) { | ||
1148 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); | ||
1149 | } else { | ||
1150 | error = bhv_vop_flushinval_pages(vp, 0, -1, FI_REMAPF); | ||
1151 | } | 1186 | } |
1187 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1152 | 1188 | ||
1153 | xfs_ilock(ip, XFS_ILOCK_SHARED); | 1189 | if (flags & SYNC_CLOSE) { |
1154 | 1190 | /* Shutdown case. Flush and invalidate. */ | |
1155 | } else if ((flags & SYNC_DELWRI) && (vp != NULL)) { | 1191 | if (XFS_FORCED_SHUTDOWN(mp)) |
1156 | if (VN_DIRTY(vp)) { | 1192 | bhv_vop_toss_pages(vp, 0, -1, FI_REMAPF); |
1157 | /* We need to have dropped the lock here, | 1193 | else |
1158 | * so insert a marker if we have not already | 1194 | error = bhv_vop_flushinval_pages(vp, 0, |
1159 | * done so. | 1195 | -1, FI_REMAPF); |
1160 | */ | 1196 | } else if ((flags & SYNC_DELWRI) && VN_DIRTY(vp)) { |
1161 | if (mount_locked) { | ||
1162 | IPOINTER_INSERT(ip, mp); | ||
1163 | } | ||
1164 | |||
1165 | /* | ||
1166 | * Drop the inode lock since we can't hold it | ||
1167 | * across calls to the buffer cache. | ||
1168 | */ | ||
1169 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
1170 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, | 1197 | error = bhv_vop_flush_pages(vp, (xfs_off_t)0, |
1171 | -1, fflag, FI_NONE); | 1198 | -1, fflag, FI_NONE); |
1172 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
1173 | } | 1199 | } |
1174 | 1200 | ||
1201 | /* | ||
1202 | * When freezing, we need to wait ensure all I/O (including direct | ||
1203 | * I/O) is complete to ensure no further data modification can take | ||
1204 | * place after this point | ||
1205 | */ | ||
1206 | if (flags & SYNC_IOWAIT) | ||
1207 | vn_iowait(vp); | ||
1208 | |||
1209 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
1175 | } | 1210 | } |
1176 | /* | ||
1177 | * When freezing, we need to wait ensure all I/O (including direct | ||
1178 | * I/O) is complete to ensure no further data modification can take | ||
1179 | * place after this point | ||
1180 | */ | ||
1181 | if (flags & SYNC_IOWAIT) | ||
1182 | vn_iowait(vp); | ||
1183 | 1211 | ||
1184 | if (flags & SYNC_BDFLUSH) { | 1212 | if (flags & SYNC_BDFLUSH) { |
1185 | if ((flags & SYNC_ATTR) && | 1213 | if ((flags & SYNC_ATTR) && |
@@ -1514,6 +1542,15 @@ xfs_syncsub( | |||
1514 | } | 1542 | } |
1515 | 1543 | ||
1516 | /* | 1544 | /* |
1545 | * If asked, update the disk superblock with incore counter values if we | ||
1546 | * are using non-persistent counters so that they don't get too far out | ||
1547 | * of sync if we crash or get a forced shutdown. We don't want to force | ||
1548 | * this to disk, just get a transaction into the iclogs.... | ||
1549 | */ | ||
1550 | if (flags & SYNC_SUPER) | ||
1551 | xfs_log_sbcount(mp, 0); | ||
1552 | |||
1553 | /* | ||
1517 | * Now check to see if the log needs a "dummy" transaction. | 1554 | * Now check to see if the log needs a "dummy" transaction. |
1518 | */ | 1555 | */ |
1519 | 1556 | ||
@@ -1645,6 +1682,7 @@ xfs_vget( | |||
1645 | * in stat(). */ | 1682 | * in stat(). */ |
1646 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ | 1683 | #define MNTOPT_ATTR2 "attr2" /* do use attr2 attribute format */ |
1647 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ | 1684 | #define MNTOPT_NOATTR2 "noattr2" /* do not use attr2 attribute format */ |
1685 | #define MNTOPT_FILESTREAM "filestreams" /* use filestreams allocator */ | ||
1648 | 1686 | ||
1649 | STATIC unsigned long | 1687 | STATIC unsigned long |
1650 | suffix_strtoul(char *s, char **endp, unsigned int base) | 1688 | suffix_strtoul(char *s, char **endp, unsigned int base) |
@@ -1831,6 +1869,8 @@ xfs_parseargs( | |||
1831 | args->flags |= XFSMNT_ATTR2; | 1869 | args->flags |= XFSMNT_ATTR2; |
1832 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { | 1870 | } else if (!strcmp(this_char, MNTOPT_NOATTR2)) { |
1833 | args->flags &= ~XFSMNT_ATTR2; | 1871 | args->flags &= ~XFSMNT_ATTR2; |
1872 | } else if (!strcmp(this_char, MNTOPT_FILESTREAM)) { | ||
1873 | args->flags2 |= XFSMNT2_FILESTREAMS; | ||
1834 | } else if (!strcmp(this_char, "osyncisdsync")) { | 1874 | } else if (!strcmp(this_char, "osyncisdsync")) { |
1835 | /* no-op, this is now the default */ | 1875 | /* no-op, this is now the default */ |
1836 | cmn_err(CE_WARN, | 1876 | cmn_err(CE_WARN, |
@@ -1959,9 +1999,9 @@ xfs_showargs( | |||
1959 | } | 1999 | } |
1960 | 2000 | ||
1961 | /* | 2001 | /* |
1962 | * Second stage of a freeze. The data is already frozen, now we have to take | 2002 | * Second stage of a freeze. The data is already frozen so we only |
1963 | * care of the metadata. New transactions are already blocked, so we need to | 2003 | * need to take care of themetadata. Once that's done write a dummy |
1964 | * wait for any remaining transactions to drain out before proceding. | 2004 | * record to dirty the log in case of a crash while frozen. |
1965 | */ | 2005 | */ |
1966 | STATIC void | 2006 | STATIC void |
1967 | xfs_freeze( | 2007 | xfs_freeze( |
@@ -1969,18 +2009,7 @@ xfs_freeze( | |||
1969 | { | 2009 | { |
1970 | xfs_mount_t *mp = XFS_BHVTOM(bdp); | 2010 | xfs_mount_t *mp = XFS_BHVTOM(bdp); |
1971 | 2011 | ||
1972 | /* wait for all modifications to complete */ | 2012 | xfs_attr_quiesce(mp); |
1973 | while (atomic_read(&mp->m_active_trans) > 0) | ||
1974 | delay(100); | ||
1975 | |||
1976 | /* flush inodes and push all remaining buffers out to disk */ | ||
1977 | xfs_quiesce_fs(mp); | ||
1978 | |||
1979 | ASSERT_ALWAYS(atomic_read(&mp->m_active_trans) == 0); | ||
1980 | |||
1981 | /* Push the superblock and write an unmount record */ | ||
1982 | xfs_log_unmount_write(mp); | ||
1983 | xfs_unmountfs_writesb(mp); | ||
1984 | xfs_fs_log_dummy(mp); | 2013 | xfs_fs_log_dummy(mp); |
1985 | } | 2014 | } |
1986 | 2015 | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 70bc82f6531..79b522779aa 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "xfs_refcache.h" | 51 | #include "xfs_refcache.h" |
52 | #include "xfs_trans_space.h" | 52 | #include "xfs_trans_space.h" |
53 | #include "xfs_log_priv.h" | 53 | #include "xfs_log_priv.h" |
54 | #include "xfs_filestream.h" | ||
54 | 55 | ||
55 | STATIC int | 56 | STATIC int |
56 | xfs_open( | 57 | xfs_open( |
@@ -77,36 +78,6 @@ xfs_open( | |||
77 | return 0; | 78 | return 0; |
78 | } | 79 | } |
79 | 80 | ||
80 | STATIC int | ||
81 | xfs_close( | ||
82 | bhv_desc_t *bdp, | ||
83 | int flags, | ||
84 | lastclose_t lastclose, | ||
85 | cred_t *credp) | ||
86 | { | ||
87 | bhv_vnode_t *vp = BHV_TO_VNODE(bdp); | ||
88 | xfs_inode_t *ip = XFS_BHVTOI(bdp); | ||
89 | |||
90 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | ||
91 | return XFS_ERROR(EIO); | ||
92 | |||
93 | if (lastclose != L_TRUE || !VN_ISREG(vp)) | ||
94 | return 0; | ||
95 | |||
96 | /* | ||
97 | * If we previously truncated this file and removed old data in | ||
98 | * the process, we want to initiate "early" writeout on the last | ||
99 | * close. This is an attempt to combat the notorious NULL files | ||
100 | * problem which is particularly noticable from a truncate down, | ||
101 | * buffered (re-)write (delalloc), followed by a crash. What we | ||
102 | * are effectively doing here is significantly reducing the time | ||
103 | * window where we'd otherwise be exposed to that problem. | ||
104 | */ | ||
105 | if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) | ||
106 | return bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | 81 | /* |
111 | * xfs_getattr | 82 | * xfs_getattr |
112 | */ | 83 | */ |
@@ -183,9 +154,8 @@ xfs_getattr( | |||
183 | * realtime extent size or the realtime volume's | 154 | * realtime extent size or the realtime volume's |
184 | * extent size. | 155 | * extent size. |
185 | */ | 156 | */ |
186 | vap->va_blocksize = ip->i_d.di_extsize ? | 157 | vap->va_blocksize = |
187 | (ip->i_d.di_extsize << mp->m_sb.sb_blocklog) : | 158 | xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog; |
188 | (mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog); | ||
189 | } | 159 | } |
190 | break; | 160 | break; |
191 | } | 161 | } |
@@ -814,6 +784,8 @@ xfs_setattr( | |||
814 | di_flags |= XFS_DIFLAG_PROJINHERIT; | 784 | di_flags |= XFS_DIFLAG_PROJINHERIT; |
815 | if (vap->va_xflags & XFS_XFLAG_NODEFRAG) | 785 | if (vap->va_xflags & XFS_XFLAG_NODEFRAG) |
816 | di_flags |= XFS_DIFLAG_NODEFRAG; | 786 | di_flags |= XFS_DIFLAG_NODEFRAG; |
787 | if (vap->va_xflags & XFS_XFLAG_FILESTREAM) | ||
788 | di_flags |= XFS_DIFLAG_FILESTREAM; | ||
817 | if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { | 789 | if ((ip->i_d.di_mode & S_IFMT) == S_IFDIR) { |
818 | if (vap->va_xflags & XFS_XFLAG_RTINHERIT) | 790 | if (vap->va_xflags & XFS_XFLAG_RTINHERIT) |
819 | di_flags |= XFS_DIFLAG_RTINHERIT; | 791 | di_flags |= XFS_DIFLAG_RTINHERIT; |
@@ -1201,13 +1173,15 @@ xfs_fsync( | |||
1201 | } | 1173 | } |
1202 | 1174 | ||
1203 | /* | 1175 | /* |
1204 | * This is called by xfs_inactive to free any blocks beyond eof, | 1176 | * This is called by xfs_inactive to free any blocks beyond eof |
1205 | * when the link count isn't zero. | 1177 | * when the link count isn't zero and by xfs_dm_punch_hole() when |
1178 | * punching a hole to EOF. | ||
1206 | */ | 1179 | */ |
1207 | STATIC int | 1180 | int |
1208 | xfs_inactive_free_eofblocks( | 1181 | xfs_free_eofblocks( |
1209 | xfs_mount_t *mp, | 1182 | xfs_mount_t *mp, |
1210 | xfs_inode_t *ip) | 1183 | xfs_inode_t *ip, |
1184 | int flags) | ||
1211 | { | 1185 | { |
1212 | xfs_trans_t *tp; | 1186 | xfs_trans_t *tp; |
1213 | int error; | 1187 | int error; |
@@ -1216,6 +1190,7 @@ xfs_inactive_free_eofblocks( | |||
1216 | xfs_filblks_t map_len; | 1190 | xfs_filblks_t map_len; |
1217 | int nimaps; | 1191 | int nimaps; |
1218 | xfs_bmbt_irec_t imap; | 1192 | xfs_bmbt_irec_t imap; |
1193 | int use_iolock = (flags & XFS_FREE_EOF_LOCK); | ||
1219 | 1194 | ||
1220 | /* | 1195 | /* |
1221 | * Figure out if there are any blocks beyond the end | 1196 | * Figure out if there are any blocks beyond the end |
@@ -1256,11 +1231,14 @@ xfs_inactive_free_eofblocks( | |||
1256 | * cache and we can't | 1231 | * cache and we can't |
1257 | * do that within a transaction. | 1232 | * do that within a transaction. |
1258 | */ | 1233 | */ |
1259 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 1234 | if (use_iolock) |
1235 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
1260 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, | 1236 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, |
1261 | ip->i_size); | 1237 | ip->i_size); |
1262 | if (error) { | 1238 | if (error) { |
1263 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 1239 | xfs_trans_cancel(tp, 0); |
1240 | if (use_iolock) | ||
1241 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1264 | return error; | 1242 | return error; |
1265 | } | 1243 | } |
1266 | 1244 | ||
@@ -1297,7 +1275,8 @@ xfs_inactive_free_eofblocks( | |||
1297 | error = xfs_trans_commit(tp, | 1275 | error = xfs_trans_commit(tp, |
1298 | XFS_TRANS_RELEASE_LOG_RES); | 1276 | XFS_TRANS_RELEASE_LOG_RES); |
1299 | } | 1277 | } |
1300 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 1278 | xfs_iunlock(ip, (use_iolock ? (XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL) |
1279 | : XFS_ILOCK_EXCL)); | ||
1301 | } | 1280 | } |
1302 | return error; | 1281 | return error; |
1303 | } | 1282 | } |
@@ -1560,6 +1539,31 @@ xfs_release( | |||
1560 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) | 1539 | if (vp->v_vfsp->vfs_flag & VFS_RDONLY) |
1561 | return 0; | 1540 | return 0; |
1562 | 1541 | ||
1542 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
1543 | /* | ||
1544 | * If we are using filestreams, and we have an unlinked | ||
1545 | * file that we are processing the last close on, then nothing | ||
1546 | * will be able to reopen and write to this file. Purge this | ||
1547 | * inode from the filestreams cache so that it doesn't delay | ||
1548 | * teardown of the inode. | ||
1549 | */ | ||
1550 | if ((ip->i_d.di_nlink == 0) && xfs_inode_is_filestream(ip)) | ||
1551 | xfs_filestream_deassociate(ip); | ||
1552 | |||
1553 | /* | ||
1554 | * If we previously truncated this file and removed old data | ||
1555 | * in the process, we want to initiate "early" writeout on | ||
1556 | * the last close. This is an attempt to combat the notorious | ||
1557 | * NULL files problem which is particularly noticable from a | ||
1558 | * truncate down, buffered (re-)write (delalloc), followed by | ||
1559 | * a crash. What we are effectively doing here is | ||
1560 | * significantly reducing the time window where we'd otherwise | ||
1561 | * be exposed to that problem. | ||
1562 | */ | ||
1563 | if (VUNTRUNCATE(vp) && VN_DIRTY(vp) && ip->i_delayed_blks > 0) | ||
1564 | bhv_vop_flush_pages(vp, 0, -1, XFS_B_ASYNC, FI_NONE); | ||
1565 | } | ||
1566 | |||
1563 | #ifdef HAVE_REFCACHE | 1567 | #ifdef HAVE_REFCACHE |
1564 | /* If we are in the NFS reference cache then don't do this now */ | 1568 | /* If we are in the NFS reference cache then don't do this now */ |
1565 | if (ip->i_refcache) | 1569 | if (ip->i_refcache) |
@@ -1573,7 +1577,8 @@ xfs_release( | |||
1573 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && | 1577 | (ip->i_df.if_flags & XFS_IFEXTENTS)) && |
1574 | (!(ip->i_d.di_flags & | 1578 | (!(ip->i_d.di_flags & |
1575 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { | 1579 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { |
1576 | if ((error = xfs_inactive_free_eofblocks(mp, ip))) | 1580 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); |
1581 | if (error) | ||
1577 | return error; | 1582 | return error; |
1578 | /* Update linux inode block count after free above */ | 1583 | /* Update linux inode block count after free above */ |
1579 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, | 1584 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, |
@@ -1654,7 +1659,8 @@ xfs_inactive( | |||
1654 | (!(ip->i_d.di_flags & | 1659 | (!(ip->i_d.di_flags & |
1655 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 1660 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
1656 | (ip->i_delayed_blks != 0)))) { | 1661 | (ip->i_delayed_blks != 0)))) { |
1657 | if ((error = xfs_inactive_free_eofblocks(mp, ip))) | 1662 | error = xfs_free_eofblocks(mp, ip, XFS_FREE_EOF_LOCK); |
1663 | if (error) | ||
1658 | return VN_INACTIVE_CACHE; | 1664 | return VN_INACTIVE_CACHE; |
1659 | /* Update linux inode block count after free above */ | 1665 | /* Update linux inode block count after free above */ |
1660 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, | 1666 | vn_to_inode(vp)->i_blocks = XFS_FSB_TO_BB(mp, |
@@ -1680,6 +1686,7 @@ xfs_inactive( | |||
1680 | 1686 | ||
1681 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); | 1687 | error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); |
1682 | if (error) { | 1688 | if (error) { |
1689 | xfs_trans_cancel(tp, 0); | ||
1683 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 1690 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
1684 | return VN_INACTIVE_CACHE; | 1691 | return VN_INACTIVE_CACHE; |
1685 | } | 1692 | } |
@@ -2217,9 +2224,9 @@ static inline int | |||
2217 | xfs_lock_inumorder(int lock_mode, int subclass) | 2224 | xfs_lock_inumorder(int lock_mode, int subclass) |
2218 | { | 2225 | { |
2219 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | 2226 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) |
2220 | lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT; | 2227 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_IOLOCK_SHIFT; |
2221 | if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) | 2228 | if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) |
2222 | lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT; | 2229 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_ILOCK_SHIFT; |
2223 | 2230 | ||
2224 | return lock_mode; | 2231 | return lock_mode; |
2225 | } | 2232 | } |
@@ -2546,6 +2553,15 @@ xfs_remove( | |||
2546 | */ | 2553 | */ |
2547 | xfs_refcache_purge_ip(ip); | 2554 | xfs_refcache_purge_ip(ip); |
2548 | 2555 | ||
2556 | /* | ||
2557 | * If we are using filestreams, kill the stream association. | ||
2558 | * If the file is still open it may get a new one but that | ||
2559 | * will get killed on last close in xfs_close() so we don't | ||
2560 | * have to worry about that. | ||
2561 | */ | ||
2562 | if (link_zero && xfs_inode_is_filestream(ip)) | ||
2563 | xfs_filestream_deassociate(ip); | ||
2564 | |||
2549 | vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 2565 | vn_trace_exit(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
2550 | 2566 | ||
2551 | /* | 2567 | /* |
@@ -4047,22 +4063,16 @@ xfs_alloc_file_space( | |||
4047 | if (XFS_FORCED_SHUTDOWN(mp)) | 4063 | if (XFS_FORCED_SHUTDOWN(mp)) |
4048 | return XFS_ERROR(EIO); | 4064 | return XFS_ERROR(EIO); |
4049 | 4065 | ||
4050 | rt = XFS_IS_REALTIME_INODE(ip); | ||
4051 | if (unlikely(rt)) { | ||
4052 | if (!(extsz = ip->i_d.di_extsize)) | ||
4053 | extsz = mp->m_sb.sb_rextsize; | ||
4054 | } else { | ||
4055 | extsz = ip->i_d.di_extsize; | ||
4056 | } | ||
4057 | |||
4058 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 4066 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) |
4059 | return error; | 4067 | return error; |
4060 | 4068 | ||
4061 | if (len <= 0) | 4069 | if (len <= 0) |
4062 | return XFS_ERROR(EINVAL); | 4070 | return XFS_ERROR(EINVAL); |
4063 | 4071 | ||
4072 | rt = XFS_IS_REALTIME_INODE(ip); | ||
4073 | extsz = xfs_get_extsz_hint(ip); | ||
4074 | |||
4064 | count = len; | 4075 | count = len; |
4065 | error = 0; | ||
4066 | imapp = &imaps[0]; | 4076 | imapp = &imaps[0]; |
4067 | nimaps = 1; | 4077 | nimaps = 1; |
4068 | bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0); | 4078 | bmapi_flag = XFS_BMAPI_WRITE | (alloc_type ? XFS_BMAPI_PREALLOC : 0); |
@@ -4678,7 +4688,6 @@ xfs_change_file_space( | |||
4678 | bhv_vnodeops_t xfs_vnodeops = { | 4688 | bhv_vnodeops_t xfs_vnodeops = { |
4679 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), | 4689 | BHV_IDENTITY_INIT(VN_BHV_XFS,VNODE_POSITION_XFS), |
4680 | .vop_open = xfs_open, | 4690 | .vop_open = xfs_open, |
4681 | .vop_close = xfs_close, | ||
4682 | .vop_read = xfs_read, | 4691 | .vop_read = xfs_read, |
4683 | #ifdef HAVE_SPLICE | 4692 | #ifdef HAVE_SPLICE |
4684 | .vop_splice_read = xfs_splice_read, | 4693 | .vop_splice_read = xfs_splice_read, |
diff --git a/include/asm-frv/uaccess.h b/include/asm-frv/uaccess.h index 3d90e1018ee..53650c958f4 100644 --- a/include/asm-frv/uaccess.h +++ b/include/asm-frv/uaccess.h | |||
@@ -277,6 +277,8 @@ extern long __memcpy_user(void *dst, const void *src, unsigned long count); | |||
277 | 277 | ||
278 | #endif | 278 | #endif |
279 | 279 | ||
280 | #define __clear_user clear_user | ||
281 | |||
280 | static inline unsigned long __must_check | 282 | static inline unsigned long __must_check |
281 | __copy_to_user(void __user *to, const void *from, unsigned long n) | 283 | __copy_to_user(void __user *to, const void *from, unsigned long n) |
282 | { | 284 | { |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 9391e4a4c34..ce256438e61 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -1639,7 +1639,7 @@ static inline int skb_csum_unnecessary(const struct sk_buff *skb) | |||
1639 | * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the | 1639 | * if skb->ip_summed is CHECKSUM_UNNECESSARY which indicates that the |
1640 | * hardware has already verified the correctness of the checksum. | 1640 | * hardware has already verified the correctness of the checksum. |
1641 | */ | 1641 | */ |
1642 | static inline unsigned int skb_checksum_complete(struct sk_buff *skb) | 1642 | static inline __sum16 skb_checksum_complete(struct sk_buff *skb) |
1643 | { | 1643 | { |
1644 | return skb_csum_unnecessary(skb) ? | 1644 | return skb_csum_unnecessary(skb) ? |
1645 | 0 : __skb_checksum_complete(skb); | 1645 | 0 : __skb_checksum_complete(skb); |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h new file mode 100644 index 00000000000..88884d39f28 --- /dev/null +++ b/include/net/9p/9p.h | |||
@@ -0,0 +1,417 @@ | |||
1 | /* | ||
2 | * include/net/9p/9p.h | ||
3 | * | ||
4 | * 9P protocol definitions. | ||
5 | * | ||
6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #ifndef NET_9P_H | ||
28 | #define NET_9P_H | ||
29 | |||
30 | #ifdef CONFIG_NET_9P_DEBUG | ||
31 | |||
32 | #define P9_DEBUG_ERROR (1<<0) | ||
33 | #define P9_DEBUG_9P (1<<2) | ||
34 | #define P9_DEBUG_VFS (1<<3) | ||
35 | #define P9_DEBUG_CONV (1<<4) | ||
36 | #define P9_DEBUG_MUX (1<<5) | ||
37 | #define P9_DEBUG_TRANS (1<<6) | ||
38 | #define P9_DEBUG_SLABS (1<<7) | ||
39 | #define P9_DEBUG_FCALL (1<<8) | ||
40 | |||
41 | extern unsigned int p9_debug_level; | ||
42 | |||
43 | #define P9_DPRINTK(level, format, arg...) \ | ||
44 | do { \ | ||
45 | if ((p9_debug_level & level) == level) \ | ||
46 | printk(KERN_NOTICE "-- %s (%d): " \ | ||
47 | format , __FUNCTION__, current->pid , ## arg); \ | ||
48 | } while (0) | ||
49 | |||
50 | #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, \ | ||
51 | "%s: %.*s\n", s, fcall?fcall->params.rerror.error.len:0, \ | ||
52 | fcall?fcall->params.rerror.error.str:""); | ||
53 | |||
54 | #else | ||
55 | #define P9_DPRINTK(level, format, arg...) do { } while (0) | ||
56 | #define PRINT_FCALL_ERROR(s, fcall) do { } while (0) | ||
57 | #endif | ||
58 | |||
59 | #define P9_EPRINTK(level, format, arg...) \ | ||
60 | do { \ | ||
61 | printk(level "9p: %s (%d): " \ | ||
62 | format , __FUNCTION__, current->pid , ## arg); \ | ||
63 | } while (0) | ||
64 | |||
65 | |||
66 | /* Message Types */ | ||
67 | enum { | ||
68 | P9_TVERSION = 100, | ||
69 | P9_RVERSION, | ||
70 | P9_TAUTH = 102, | ||
71 | P9_RAUTH, | ||
72 | P9_TATTACH = 104, | ||
73 | P9_RATTACH, | ||
74 | P9_TERROR = 106, | ||
75 | P9_RERROR, | ||
76 | P9_TFLUSH = 108, | ||
77 | P9_RFLUSH, | ||
78 | P9_TWALK = 110, | ||
79 | P9_RWALK, | ||
80 | P9_TOPEN = 112, | ||
81 | P9_ROPEN, | ||
82 | P9_TCREATE = 114, | ||
83 | P9_RCREATE, | ||
84 | P9_TREAD = 116, | ||
85 | P9_RREAD, | ||
86 | P9_TWRITE = 118, | ||
87 | P9_RWRITE, | ||
88 | P9_TCLUNK = 120, | ||
89 | P9_RCLUNK, | ||
90 | P9_TREMOVE = 122, | ||
91 | P9_RREMOVE, | ||
92 | P9_TSTAT = 124, | ||
93 | P9_RSTAT, | ||
94 | P9_TWSTAT = 126, | ||
95 | P9_RWSTAT, | ||
96 | }; | ||
97 | |||
98 | /* open modes */ | ||
99 | enum { | ||
100 | P9_OREAD = 0x00, | ||
101 | P9_OWRITE = 0x01, | ||
102 | P9_ORDWR = 0x02, | ||
103 | P9_OEXEC = 0x03, | ||
104 | P9_OEXCL = 0x04, | ||
105 | P9_OTRUNC = 0x10, | ||
106 | P9_OREXEC = 0x20, | ||
107 | P9_ORCLOSE = 0x40, | ||
108 | P9_OAPPEND = 0x80, | ||
109 | }; | ||
110 | |||
111 | /* permissions */ | ||
112 | enum { | ||
113 | P9_DMDIR = 0x80000000, | ||
114 | P9_DMAPPEND = 0x40000000, | ||
115 | P9_DMEXCL = 0x20000000, | ||
116 | P9_DMMOUNT = 0x10000000, | ||
117 | P9_DMAUTH = 0x08000000, | ||
118 | P9_DMTMP = 0x04000000, | ||
119 | P9_DMSYMLINK = 0x02000000, | ||
120 | P9_DMLINK = 0x01000000, | ||
121 | /* 9P2000.u extensions */ | ||
122 | P9_DMDEVICE = 0x00800000, | ||
123 | P9_DMNAMEDPIPE = 0x00200000, | ||
124 | P9_DMSOCKET = 0x00100000, | ||
125 | P9_DMSETUID = 0x00080000, | ||
126 | P9_DMSETGID = 0x00040000, | ||
127 | }; | ||
128 | |||
129 | /* qid.types */ | ||
130 | enum { | ||
131 | P9_QTDIR = 0x80, | ||
132 | P9_QTAPPEND = 0x40, | ||
133 | P9_QTEXCL = 0x20, | ||
134 | P9_QTMOUNT = 0x10, | ||
135 | P9_QTAUTH = 0x08, | ||
136 | P9_QTTMP = 0x04, | ||
137 | P9_QTSYMLINK = 0x02, | ||
138 | P9_QTLINK = 0x01, | ||
139 | P9_QTFILE = 0x00, | ||
140 | }; | ||
141 | |||
142 | #define P9_NOTAG (u16)(~0) | ||
143 | #define P9_NOFID (u32)(~0) | ||
144 | #define P9_MAXWELEM 16 | ||
145 | |||
146 | /* ample room for Twrite/Rread header */ | ||
147 | #define P9_IOHDRSZ 24 | ||
148 | |||
149 | struct p9_str { | ||
150 | u16 len; | ||
151 | char *str; | ||
152 | }; | ||
153 | |||
154 | /* qids are the unique ID for a file (like an inode */ | ||
155 | struct p9_qid { | ||
156 | u8 type; | ||
157 | u32 version; | ||
158 | u64 path; | ||
159 | }; | ||
160 | |||
161 | /* Plan 9 file metadata (stat) structure */ | ||
162 | struct p9_stat { | ||
163 | u16 size; | ||
164 | u16 type; | ||
165 | u32 dev; | ||
166 | struct p9_qid qid; | ||
167 | u32 mode; | ||
168 | u32 atime; | ||
169 | u32 mtime; | ||
170 | u64 length; | ||
171 | struct p9_str name; | ||
172 | struct p9_str uid; | ||
173 | struct p9_str gid; | ||
174 | struct p9_str muid; | ||
175 | struct p9_str extension; /* 9p2000.u extensions */ | ||
176 | u32 n_uid; /* 9p2000.u extensions */ | ||
177 | u32 n_gid; /* 9p2000.u extensions */ | ||
178 | u32 n_muid; /* 9p2000.u extensions */ | ||
179 | }; | ||
180 | |||
181 | /* file metadata (stat) structure used to create Twstat message | ||
182 | The is similar to p9_stat, but the strings don't point to | ||
183 | the same memory block and should be freed separately | ||
184 | */ | ||
185 | struct p9_wstat { | ||
186 | u16 size; | ||
187 | u16 type; | ||
188 | u32 dev; | ||
189 | struct p9_qid qid; | ||
190 | u32 mode; | ||
191 | u32 atime; | ||
192 | u32 mtime; | ||
193 | u64 length; | ||
194 | char *name; | ||
195 | char *uid; | ||
196 | char *gid; | ||
197 | char *muid; | ||
198 | char *extension; /* 9p2000.u extensions */ | ||
199 | u32 n_uid; /* 9p2000.u extensions */ | ||
200 | u32 n_gid; /* 9p2000.u extensions */ | ||
201 | u32 n_muid; /* 9p2000.u extensions */ | ||
202 | }; | ||
203 | |||
204 | /* Structures for Protocol Operations */ | ||
205 | struct p9_tversion { | ||
206 | u32 msize; | ||
207 | struct p9_str version; | ||
208 | }; | ||
209 | |||
210 | struct p9_rversion { | ||
211 | u32 msize; | ||
212 | struct p9_str version; | ||
213 | }; | ||
214 | |||
215 | struct p9_tauth { | ||
216 | u32 afid; | ||
217 | struct p9_str uname; | ||
218 | struct p9_str aname; | ||
219 | }; | ||
220 | |||
221 | struct p9_rauth { | ||
222 | struct p9_qid qid; | ||
223 | }; | ||
224 | |||
225 | struct p9_rerror { | ||
226 | struct p9_str error; | ||
227 | u32 errno; /* 9p2000.u extension */ | ||
228 | }; | ||
229 | |||
230 | struct p9_tflush { | ||
231 | u16 oldtag; | ||
232 | }; | ||
233 | |||
234 | struct p9_rflush { | ||
235 | }; | ||
236 | |||
237 | struct p9_tattach { | ||
238 | u32 fid; | ||
239 | u32 afid; | ||
240 | struct p9_str uname; | ||
241 | struct p9_str aname; | ||
242 | }; | ||
243 | |||
244 | struct p9_rattach { | ||
245 | struct p9_qid qid; | ||
246 | }; | ||
247 | |||
248 | struct p9_twalk { | ||
249 | u32 fid; | ||
250 | u32 newfid; | ||
251 | u16 nwname; | ||
252 | struct p9_str wnames[16]; | ||
253 | }; | ||
254 | |||
255 | struct p9_rwalk { | ||
256 | u16 nwqid; | ||
257 | struct p9_qid wqids[16]; | ||
258 | }; | ||
259 | |||
260 | struct p9_topen { | ||
261 | u32 fid; | ||
262 | u8 mode; | ||
263 | }; | ||
264 | |||
265 | struct p9_ropen { | ||
266 | struct p9_qid qid; | ||
267 | u32 iounit; | ||
268 | }; | ||
269 | |||
270 | struct p9_tcreate { | ||
271 | u32 fid; | ||
272 | struct p9_str name; | ||
273 | u32 perm; | ||
274 | u8 mode; | ||
275 | struct p9_str extension; | ||
276 | }; | ||
277 | |||
278 | struct p9_rcreate { | ||
279 | struct p9_qid qid; | ||
280 | u32 iounit; | ||
281 | }; | ||
282 | |||
283 | struct p9_tread { | ||
284 | u32 fid; | ||
285 | u64 offset; | ||
286 | u32 count; | ||
287 | }; | ||
288 | |||
289 | struct p9_rread { | ||
290 | u32 count; | ||
291 | u8 *data; | ||
292 | }; | ||
293 | |||
294 | struct p9_twrite { | ||
295 | u32 fid; | ||
296 | u64 offset; | ||
297 | u32 count; | ||
298 | u8 *data; | ||
299 | }; | ||
300 | |||
301 | struct p9_rwrite { | ||
302 | u32 count; | ||
303 | }; | ||
304 | |||
305 | struct p9_tclunk { | ||
306 | u32 fid; | ||
307 | }; | ||
308 | |||
309 | struct p9_rclunk { | ||
310 | }; | ||
311 | |||
312 | struct p9_tremove { | ||
313 | u32 fid; | ||
314 | }; | ||
315 | |||
316 | struct p9_rremove { | ||
317 | }; | ||
318 | |||
319 | struct p9_tstat { | ||
320 | u32 fid; | ||
321 | }; | ||
322 | |||
323 | struct p9_rstat { | ||
324 | struct p9_stat stat; | ||
325 | }; | ||
326 | |||
327 | struct p9_twstat { | ||
328 | u32 fid; | ||
329 | struct p9_stat stat; | ||
330 | }; | ||
331 | |||
332 | struct p9_rwstat { | ||
333 | }; | ||
334 | |||
335 | /* | ||
336 | * fcall is the primary packet structure | ||
337 | * | ||
338 | */ | ||
339 | |||
340 | struct p9_fcall { | ||
341 | u32 size; | ||
342 | u8 id; | ||
343 | u16 tag; | ||
344 | void *sdata; | ||
345 | |||
346 | union { | ||
347 | struct p9_tversion tversion; | ||
348 | struct p9_rversion rversion; | ||
349 | struct p9_tauth tauth; | ||
350 | struct p9_rauth rauth; | ||
351 | struct p9_rerror rerror; | ||
352 | struct p9_tflush tflush; | ||
353 | struct p9_rflush rflush; | ||
354 | struct p9_tattach tattach; | ||
355 | struct p9_rattach rattach; | ||
356 | struct p9_twalk twalk; | ||
357 | struct p9_rwalk rwalk; | ||
358 | struct p9_topen topen; | ||
359 | struct p9_ropen ropen; | ||
360 | struct p9_tcreate tcreate; | ||
361 | struct p9_rcreate rcreate; | ||
362 | struct p9_tread tread; | ||
363 | struct p9_rread rread; | ||
364 | struct p9_twrite twrite; | ||
365 | struct p9_rwrite rwrite; | ||
366 | struct p9_tclunk tclunk; | ||
367 | struct p9_rclunk rclunk; | ||
368 | struct p9_tremove tremove; | ||
369 | struct p9_rremove rremove; | ||
370 | struct p9_tstat tstat; | ||
371 | struct p9_rstat rstat; | ||
372 | struct p9_twstat twstat; | ||
373 | struct p9_rwstat rwstat; | ||
374 | } params; | ||
375 | }; | ||
376 | |||
377 | struct p9_idpool; | ||
378 | |||
379 | int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, | ||
380 | int dotu); | ||
381 | int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu); | ||
382 | void p9_set_tag(struct p9_fcall *fc, u16 tag); | ||
383 | struct p9_fcall *p9_create_tversion(u32 msize, char *version); | ||
384 | struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname, | ||
385 | char *aname); | ||
386 | struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname); | ||
387 | struct p9_fcall *p9_create_tflush(u16 oldtag); | ||
388 | struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, | ||
389 | char **wnames); | ||
390 | struct p9_fcall *p9_create_topen(u32 fid, u8 mode); | ||
391 | struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | ||
392 | char *extension, int dotu); | ||
393 | struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count); | ||
394 | struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, | ||
395 | const char *data); | ||
396 | struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, | ||
397 | const char __user *data); | ||
398 | struct p9_fcall *p9_create_tclunk(u32 fid); | ||
399 | struct p9_fcall *p9_create_tremove(u32 fid); | ||
400 | struct p9_fcall *p9_create_tstat(u32 fid); | ||
401 | struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, | ||
402 | int dotu); | ||
403 | |||
404 | int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int dotu); | ||
405 | int p9_errstr2errno(char *errstr, int len); | ||
406 | |||
407 | struct p9_idpool *p9_idpool_create(void); | ||
408 | void p9_idpool_destroy(struct p9_idpool *); | ||
409 | int p9_idpool_get(struct p9_idpool *p); | ||
410 | void p9_idpool_put(int id, struct p9_idpool *p); | ||
411 | int p9_idpool_check(int id, struct p9_idpool *p); | ||
412 | |||
413 | int p9_error_init(void); | ||
414 | int p9_errstr2errno(char *, int); | ||
415 | int __init p9_sysctl_register(void); | ||
416 | void __exit p9_sysctl_unregister(void); | ||
417 | #endif /* NET_9P_H */ | ||
diff --git a/include/net/9p/client.h b/include/net/9p/client.h new file mode 100644 index 00000000000..d65ed7c6906 --- /dev/null +++ b/include/net/9p/client.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * include/net/9p/client.h | ||
3 | * | ||
4 | * 9P Client Definitions | ||
5 | * | ||
6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to: | ||
19 | * Free Software Foundation | ||
20 | * 51 Franklin Street, Fifth Floor | ||
21 | * Boston, MA 02111-1301 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #ifndef NET_9P_CLIENT_H | ||
26 | #define NET_9P_CLIENT_H | ||
27 | |||
28 | struct p9_client { | ||
29 | spinlock_t lock; /* protect client structure */ | ||
30 | int msize; | ||
31 | unsigned char dotu; | ||
32 | struct p9_transport *trans; | ||
33 | struct p9_conn *conn; | ||
34 | |||
35 | struct p9_idpool *fidpool; | ||
36 | struct list_head fidlist; | ||
37 | }; | ||
38 | |||
39 | struct p9_fid { | ||
40 | struct p9_client *clnt; | ||
41 | u32 fid; | ||
42 | int mode; | ||
43 | struct p9_qid qid; | ||
44 | u32 iounit; | ||
45 | uid_t uid; | ||
46 | void *aux; | ||
47 | |||
48 | int rdir_fpos; | ||
49 | int rdir_pos; | ||
50 | struct p9_fcall *rdir_fcall; | ||
51 | struct list_head flist; | ||
52 | struct list_head dlist; /* list of all fids attached to a dentry */ | ||
53 | }; | ||
54 | |||
55 | struct p9_client *p9_client_create(struct p9_transport *trans, int msize, | ||
56 | int dotu); | ||
57 | void p9_client_destroy(struct p9_client *clnt); | ||
58 | void p9_client_disconnect(struct p9_client *clnt); | ||
59 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
60 | char *uname, char *aname); | ||
61 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname); | ||
62 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | ||
63 | int clone); | ||
64 | int p9_client_open(struct p9_fid *fid, int mode); | ||
65 | int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | ||
66 | char *extension); | ||
67 | int p9_client_clunk(struct p9_fid *fid); | ||
68 | int p9_client_remove(struct p9_fid *fid); | ||
69 | int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
70 | int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
71 | int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count); | ||
72 | int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, | ||
73 | u32 count); | ||
74 | int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, | ||
75 | u32 count); | ||
76 | struct p9_stat *p9_client_stat(struct p9_fid *fid); | ||
77 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst); | ||
78 | struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset); | ||
79 | |||
80 | #endif /* NET_9P_CLIENT_H */ | ||
diff --git a/fs/9p/mux.h b/include/net/9p/conn.h index fb10c50186a..583b6a2cb3d 100644 --- a/fs/9p/mux.h +++ b/include/net/9p/conn.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/mux.h | 2 | * include/net/9p/conn.h |
3 | * | 3 | * |
4 | * Multiplexer Definitions | 4 | * Connection Definitions |
5 | * | 5 | * |
6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> | 6 | * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> |
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | 7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
@@ -23,33 +23,35 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | struct v9fs_mux_data; | 26 | #ifndef NET_9P_CONN_H |
27 | struct v9fs_req; | 27 | #define NET_9P_CONN_H |
28 | |||
29 | #undef P9_NONBLOCK | ||
30 | |||
31 | struct p9_conn; | ||
32 | struct p9_req; | ||
28 | 33 | ||
29 | /** | 34 | /** |
30 | * v9fs_mux_req_callback - callback function that is called when the | 35 | * p9_mux_req_callback - callback function that is called when the |
31 | * response of a request is received. The callback is called from | 36 | * response of a request is received. The callback is called from |
32 | * a workqueue and shouldn't block. | 37 | * a workqueue and shouldn't block. |
33 | * | 38 | * |
39 | * @req - request | ||
34 | * @a - the pointer that was specified when the request was send to be | 40 | * @a - the pointer that was specified when the request was send to be |
35 | * passed to the callback | 41 | * passed to the callback |
36 | * @tc - request call | ||
37 | * @rc - response call | ||
38 | * @err - error code (non-zero if error occured) | ||
39 | */ | 42 | */ |
40 | typedef void (*v9fs_mux_req_callback)(struct v9fs_req *req, void *a); | 43 | typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a); |
41 | 44 | ||
42 | int v9fs_mux_global_init(void); | 45 | struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, |
43 | void v9fs_mux_global_exit(void); | 46 | unsigned char *dotu); |
47 | void p9_conn_destroy(struct p9_conn *); | ||
48 | int p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, struct p9_fcall **rc); | ||
44 | 49 | ||
45 | struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | 50 | #ifdef P9_NONBLOCK |
46 | unsigned char *extended); | 51 | int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, |
47 | void v9fs_mux_destroy(struct v9fs_mux_data *); | 52 | p9_conn_req_callback cb, void *a); |
53 | #endif /* P9_NONBLOCK */ | ||
48 | 54 | ||
49 | int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc); | 55 | void p9_conn_cancel(struct p9_conn *m, int err); |
50 | struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m); | ||
51 | int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc); | ||
52 | 56 | ||
53 | void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush); | 57 | #endif /* NET_9P_CONN_H */ |
54 | void v9fs_mux_cancel(struct v9fs_mux_data *m, int err); | ||
55 | int v9fs_errstr2errno(char *errstr, int len); | ||
diff --git a/fs/9p/transport.h b/include/net/9p/transport.h index b38a4b8a41c..462d42279fb 100644 --- a/fs/9p/transport.h +++ b/include/net/9p/transport.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/transport.h | 2 | * include/net/9p/transport.h |
3 | * | 3 | * |
4 | * Transport Definition | 4 | * Transport Definition |
5 | * | 5 | * |
@@ -23,23 +23,27 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | enum v9fs_transport_status { | 26 | #ifndef NET_9P_TRANSPORT_H |
27 | #define NET_9P_TRANSPORT_H | ||
28 | |||
29 | enum p9_transport_status { | ||
27 | Connected, | 30 | Connected, |
28 | Disconnected, | 31 | Disconnected, |
29 | Hung, | 32 | Hung, |
30 | }; | 33 | }; |
31 | 34 | ||
32 | struct v9fs_transport { | 35 | struct p9_transport { |
33 | enum v9fs_transport_status status; | 36 | enum p9_transport_status status; |
34 | void *priv; | 37 | void *priv; |
35 | 38 | ||
36 | int (*init) (struct v9fs_session_info *, const char *, char *); | 39 | int (*write) (struct p9_transport *, void *, int); |
37 | int (*write) (struct v9fs_transport *, void *, int); | 40 | int (*read) (struct p9_transport *, void *, int); |
38 | int (*read) (struct v9fs_transport *, void *, int); | 41 | void (*close) (struct p9_transport *); |
39 | void (*close) (struct v9fs_transport *); | 42 | unsigned int (*poll)(struct p9_transport *, struct poll_table_struct *); |
40 | unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *); | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | extern struct v9fs_transport v9fs_trans_tcp; | 45 | struct p9_transport *p9_trans_create_tcp(const char *addr, int port); |
44 | extern struct v9fs_transport v9fs_trans_unix; | 46 | struct p9_transport *p9_trans_create_unix(const char *addr); |
45 | extern struct v9fs_transport v9fs_trans_fd; | 47 | struct p9_transport *p9_trans_create_fd(int rfd, int wfd); |
48 | |||
49 | #endif /* NET_9P_TRANSPORT_H */ | ||
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 402eb4eb6b2..9927cca14cb 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -151,6 +151,7 @@ int radix_tree_preload(gfp_t gfp_mask) | |||
151 | out: | 151 | out: |
152 | return ret; | 152 | return ret; |
153 | } | 153 | } |
154 | EXPORT_SYMBOL(radix_tree_preload); | ||
154 | 155 | ||
155 | static inline void tag_set(struct radix_tree_node *node, unsigned int tag, | 156 | static inline void tag_set(struct radix_tree_node *node, unsigned int tag, |
156 | int offset) | 157 | int offset) |
diff --git a/net/9p/Kconfig b/net/9p/Kconfig new file mode 100644 index 00000000000..66821cd64a7 --- /dev/null +++ b/net/9p/Kconfig | |||
@@ -0,0 +1,21 @@ | |||
1 | # | ||
2 | # 9P protocol configuration | ||
3 | # | ||
4 | |||
5 | menuconfig NET_9P | ||
6 | depends on NET && EXPERIMENTAL | ||
7 | tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)" | ||
8 | help | ||
9 | If you say Y here, you will get experimental support for | ||
10 | Plan 9 resource sharing via the 9P2000 protocol. | ||
11 | |||
12 | See <http://v9fs.sf.net> for more information. | ||
13 | |||
14 | If unsure, say N. | ||
15 | |||
16 | config NET_9P_DEBUG | ||
17 | bool "Debug information" | ||
18 | depends on NET_9P | ||
19 | help | ||
20 | Say Y if you want the 9P subsistem to log debug information. | ||
21 | |||
diff --git a/net/9p/Makefile b/net/9p/Makefile new file mode 100644 index 00000000000..85b3a7838ac --- /dev/null +++ b/net/9p/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | obj-$(CONFIG_NET_9P) := 9pnet.o | ||
2 | |||
3 | 9pnet-objs := \ | ||
4 | mod.o \ | ||
5 | trans_fd.o \ | ||
6 | mux.o \ | ||
7 | client.o \ | ||
8 | conv.o \ | ||
9 | error.o \ | ||
10 | fcprint.o \ | ||
11 | util.o \ | ||
12 | |||
13 | 9pnet-$(CONFIG_SYSCTL) += sysctl.o | ||
diff --git a/net/9p/client.c b/net/9p/client.c new file mode 100644 index 00000000000..cb170750337 --- /dev/null +++ b/net/9p/client.c | |||
@@ -0,0 +1,965 @@ | |||
1 | /* | ||
2 | * net/9p/clnt.c | ||
3 | * | ||
4 | * 9P Client | ||
5 | * | ||
6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to: | ||
19 | * Free Software Foundation | ||
20 | * 51 Franklin Street, Fifth Floor | ||
21 | * Boston, MA 02111-1301 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/idr.h> | ||
29 | #include <linux/mutex.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/uaccess.h> | ||
32 | #include <net/9p/9p.h> | ||
33 | #include <net/9p/transport.h> | ||
34 | #include <net/9p/conn.h> | ||
35 | #include <net/9p/client.h> | ||
36 | |||
37 | static struct p9_fid *p9_fid_create(struct p9_client *clnt); | ||
38 | static void p9_fid_destroy(struct p9_fid *fid); | ||
39 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu); | ||
40 | |||
41 | struct p9_client *p9_client_create(struct p9_transport *trans, int msize, | ||
42 | int dotu) | ||
43 | { | ||
44 | int err, n; | ||
45 | struct p9_client *clnt; | ||
46 | struct p9_fcall *tc, *rc; | ||
47 | struct p9_str *version; | ||
48 | |||
49 | err = 0; | ||
50 | tc = NULL; | ||
51 | rc = NULL; | ||
52 | clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL); | ||
53 | if (!clnt) | ||
54 | return ERR_PTR(-ENOMEM); | ||
55 | |||
56 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n", | ||
57 | clnt, trans, msize, dotu); | ||
58 | spin_lock_init(&clnt->lock); | ||
59 | clnt->trans = trans; | ||
60 | clnt->msize = msize; | ||
61 | clnt->dotu = dotu; | ||
62 | INIT_LIST_HEAD(&clnt->fidlist); | ||
63 | clnt->fidpool = p9_idpool_create(); | ||
64 | if (!clnt->fidpool) { | ||
65 | err = PTR_ERR(clnt->fidpool); | ||
66 | clnt->fidpool = NULL; | ||
67 | goto error; | ||
68 | } | ||
69 | |||
70 | clnt->conn = p9_conn_create(clnt->trans, clnt->msize, &clnt->dotu); | ||
71 | if (IS_ERR(clnt->conn)) { | ||
72 | err = PTR_ERR(clnt->conn); | ||
73 | clnt->conn = NULL; | ||
74 | goto error; | ||
75 | } | ||
76 | |||
77 | tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000"); | ||
78 | if (IS_ERR(tc)) { | ||
79 | err = PTR_ERR(tc); | ||
80 | tc = NULL; | ||
81 | goto error; | ||
82 | } | ||
83 | |||
84 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
85 | if (err) | ||
86 | goto error; | ||
87 | |||
88 | version = &rc->params.rversion.version; | ||
89 | if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8)) | ||
90 | clnt->dotu = 1; | ||
91 | else if (version->len == 6 && !memcmp(version->str, "9P2000", 6)) | ||
92 | clnt->dotu = 0; | ||
93 | else { | ||
94 | err = -EREMOTEIO; | ||
95 | goto error; | ||
96 | } | ||
97 | |||
98 | n = rc->params.rversion.msize; | ||
99 | if (n < clnt->msize) | ||
100 | clnt->msize = n; | ||
101 | |||
102 | kfree(tc); | ||
103 | kfree(rc); | ||
104 | return clnt; | ||
105 | |||
106 | error: | ||
107 | kfree(tc); | ||
108 | kfree(rc); | ||
109 | p9_client_destroy(clnt); | ||
110 | return ERR_PTR(err); | ||
111 | } | ||
112 | EXPORT_SYMBOL(p9_client_create); | ||
113 | |||
114 | void p9_client_destroy(struct p9_client *clnt) | ||
115 | { | ||
116 | struct p9_fid *fid, *fidptr; | ||
117 | |||
118 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
119 | if (clnt->conn) { | ||
120 | p9_conn_destroy(clnt->conn); | ||
121 | clnt->conn = NULL; | ||
122 | } | ||
123 | |||
124 | if (clnt->trans) { | ||
125 | clnt->trans->close(clnt->trans); | ||
126 | kfree(clnt->trans); | ||
127 | clnt->trans = NULL; | ||
128 | } | ||
129 | |||
130 | list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) | ||
131 | p9_fid_destroy(fid); | ||
132 | |||
133 | if (clnt->fidpool) | ||
134 | p9_idpool_destroy(clnt->fidpool); | ||
135 | |||
136 | kfree(clnt); | ||
137 | } | ||
138 | EXPORT_SYMBOL(p9_client_destroy); | ||
139 | |||
140 | void p9_client_disconnect(struct p9_client *clnt) | ||
141 | { | ||
142 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
143 | clnt->trans->status = Disconnected; | ||
144 | p9_conn_cancel(clnt->conn, -EIO); | ||
145 | } | ||
146 | EXPORT_SYMBOL(p9_client_disconnect); | ||
147 | |||
148 | struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | ||
149 | char *uname, char *aname) | ||
150 | { | ||
151 | int err; | ||
152 | struct p9_fcall *tc, *rc; | ||
153 | struct p9_fid *fid; | ||
154 | |||
155 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p afid %d uname %s aname %s\n", | ||
156 | clnt, afid?afid->fid:-1, uname, aname); | ||
157 | err = 0; | ||
158 | tc = NULL; | ||
159 | rc = NULL; | ||
160 | |||
161 | fid = p9_fid_create(clnt); | ||
162 | if (IS_ERR(fid)) { | ||
163 | err = PTR_ERR(fid); | ||
164 | fid = NULL; | ||
165 | goto error; | ||
166 | } | ||
167 | |||
168 | tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname); | ||
169 | if (IS_ERR(tc)) { | ||
170 | err = PTR_ERR(tc); | ||
171 | tc = NULL; | ||
172 | goto error; | ||
173 | } | ||
174 | |||
175 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
176 | if (err) | ||
177 | goto error; | ||
178 | |||
179 | memmove(&fid->qid, &rc->params.rattach.qid, sizeof(struct p9_qid)); | ||
180 | kfree(tc); | ||
181 | kfree(rc); | ||
182 | return fid; | ||
183 | |||
184 | error: | ||
185 | kfree(tc); | ||
186 | kfree(rc); | ||
187 | if (fid) | ||
188 | p9_fid_destroy(fid); | ||
189 | return ERR_PTR(err); | ||
190 | } | ||
191 | EXPORT_SYMBOL(p9_client_attach); | ||
192 | |||
193 | struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, char *aname) | ||
194 | { | ||
195 | int err; | ||
196 | struct p9_fcall *tc, *rc; | ||
197 | struct p9_fid *fid; | ||
198 | |||
199 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p uname %s aname %s\n", clnt, uname, | ||
200 | aname); | ||
201 | err = 0; | ||
202 | tc = NULL; | ||
203 | rc = NULL; | ||
204 | |||
205 | fid = p9_fid_create(clnt); | ||
206 | if (IS_ERR(fid)) { | ||
207 | err = PTR_ERR(fid); | ||
208 | fid = NULL; | ||
209 | goto error; | ||
210 | } | ||
211 | |||
212 | tc = p9_create_tauth(fid->fid, uname, aname); | ||
213 | if (IS_ERR(tc)) { | ||
214 | err = PTR_ERR(tc); | ||
215 | tc = NULL; | ||
216 | goto error; | ||
217 | } | ||
218 | |||
219 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
220 | if (err) | ||
221 | goto error; | ||
222 | |||
223 | memmove(&fid->qid, &rc->params.rauth.qid, sizeof(struct p9_qid)); | ||
224 | kfree(tc); | ||
225 | kfree(rc); | ||
226 | return fid; | ||
227 | |||
228 | error: | ||
229 | kfree(tc); | ||
230 | kfree(rc); | ||
231 | if (fid) | ||
232 | p9_fid_destroy(fid); | ||
233 | return ERR_PTR(err); | ||
234 | } | ||
235 | EXPORT_SYMBOL(p9_client_auth); | ||
236 | |||
237 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | ||
238 | int clone) | ||
239 | { | ||
240 | int err; | ||
241 | struct p9_fcall *tc, *rc; | ||
242 | struct p9_client *clnt; | ||
243 | struct p9_fid *fid; | ||
244 | |||
245 | P9_DPRINTK(P9_DEBUG_9P, "fid %d nwname %d wname[0] %s\n", | ||
246 | oldfid->fid, nwname, wnames?wnames[0]:NULL); | ||
247 | err = 0; | ||
248 | tc = NULL; | ||
249 | rc = NULL; | ||
250 | clnt = oldfid->clnt; | ||
251 | if (clone) { | ||
252 | fid = p9_fid_create(clnt); | ||
253 | if (IS_ERR(fid)) { | ||
254 | err = PTR_ERR(fid); | ||
255 | fid = NULL; | ||
256 | goto error; | ||
257 | } | ||
258 | |||
259 | fid->uid = oldfid->uid; | ||
260 | } else | ||
261 | fid = oldfid; | ||
262 | |||
263 | tc = p9_create_twalk(oldfid->fid, fid->fid, nwname, wnames); | ||
264 | if (IS_ERR(tc)) { | ||
265 | err = PTR_ERR(tc); | ||
266 | tc = NULL; | ||
267 | goto error; | ||
268 | } | ||
269 | |||
270 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
271 | if (err) { | ||
272 | if (rc && rc->id == P9_RWALK) | ||
273 | goto clunk_fid; | ||
274 | else | ||
275 | goto error; | ||
276 | } | ||
277 | |||
278 | if (rc->params.rwalk.nwqid != nwname) { | ||
279 | err = -ENOENT; | ||
280 | goto clunk_fid; | ||
281 | } | ||
282 | |||
283 | if (nwname) | ||
284 | memmove(&fid->qid, | ||
285 | &rc->params.rwalk.wqids[rc->params.rwalk.nwqid - 1], | ||
286 | sizeof(struct p9_qid)); | ||
287 | else | ||
288 | fid->qid = oldfid->qid; | ||
289 | |||
290 | kfree(tc); | ||
291 | kfree(rc); | ||
292 | return fid; | ||
293 | |||
294 | clunk_fid: | ||
295 | kfree(tc); | ||
296 | kfree(rc); | ||
297 | rc = NULL; | ||
298 | tc = p9_create_tclunk(fid->fid); | ||
299 | if (IS_ERR(tc)) { | ||
300 | err = PTR_ERR(tc); | ||
301 | tc = NULL; | ||
302 | goto error; | ||
303 | } | ||
304 | |||
305 | p9_conn_rpc(clnt->conn, tc, &rc); | ||
306 | |||
307 | error: | ||
308 | kfree(tc); | ||
309 | kfree(rc); | ||
310 | if (fid && (fid != oldfid)) | ||
311 | p9_fid_destroy(fid); | ||
312 | |||
313 | return ERR_PTR(err); | ||
314 | } | ||
315 | EXPORT_SYMBOL(p9_client_walk); | ||
316 | |||
317 | int p9_client_open(struct p9_fid *fid, int mode) | ||
318 | { | ||
319 | int err; | ||
320 | struct p9_fcall *tc, *rc; | ||
321 | struct p9_client *clnt; | ||
322 | |||
323 | P9_DPRINTK(P9_DEBUG_9P, "fid %d mode %d\n", fid->fid, mode); | ||
324 | err = 0; | ||
325 | tc = NULL; | ||
326 | rc = NULL; | ||
327 | clnt = fid->clnt; | ||
328 | |||
329 | if (fid->mode != -1) | ||
330 | return -EINVAL; | ||
331 | |||
332 | tc = p9_create_topen(fid->fid, mode); | ||
333 | if (IS_ERR(tc)) { | ||
334 | err = PTR_ERR(tc); | ||
335 | tc = NULL; | ||
336 | goto done; | ||
337 | } | ||
338 | |||
339 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
340 | if (err) | ||
341 | goto done; | ||
342 | |||
343 | fid->mode = mode; | ||
344 | fid->iounit = rc->params.ropen.iounit; | ||
345 | |||
346 | done: | ||
347 | kfree(tc); | ||
348 | kfree(rc); | ||
349 | return err; | ||
350 | } | ||
351 | EXPORT_SYMBOL(p9_client_open); | ||
352 | |||
353 | int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | ||
354 | char *extension) | ||
355 | { | ||
356 | int err; | ||
357 | struct p9_fcall *tc, *rc; | ||
358 | struct p9_client *clnt; | ||
359 | |||
360 | P9_DPRINTK(P9_DEBUG_9P, "fid %d name %s perm %d mode %d\n", fid->fid, | ||
361 | name, perm, mode); | ||
362 | err = 0; | ||
363 | tc = NULL; | ||
364 | rc = NULL; | ||
365 | clnt = fid->clnt; | ||
366 | |||
367 | if (fid->mode != -1) | ||
368 | return -EINVAL; | ||
369 | |||
370 | tc = p9_create_tcreate(fid->fid, name, perm, mode, extension, | ||
371 | clnt->dotu); | ||
372 | if (IS_ERR(tc)) { | ||
373 | err = PTR_ERR(tc); | ||
374 | tc = NULL; | ||
375 | goto done; | ||
376 | } | ||
377 | |||
378 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
379 | if (err) | ||
380 | goto done; | ||
381 | |||
382 | fid->mode = mode; | ||
383 | fid->iounit = rc->params.ropen.iounit; | ||
384 | |||
385 | done: | ||
386 | kfree(tc); | ||
387 | kfree(rc); | ||
388 | return err; | ||
389 | } | ||
390 | EXPORT_SYMBOL(p9_client_fcreate); | ||
391 | |||
392 | int p9_client_clunk(struct p9_fid *fid) | ||
393 | { | ||
394 | int err; | ||
395 | struct p9_fcall *tc, *rc; | ||
396 | struct p9_client *clnt; | ||
397 | |||
398 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
399 | err = 0; | ||
400 | tc = NULL; | ||
401 | rc = NULL; | ||
402 | clnt = fid->clnt; | ||
403 | |||
404 | tc = p9_create_tclunk(fid->fid); | ||
405 | if (IS_ERR(tc)) { | ||
406 | err = PTR_ERR(tc); | ||
407 | tc = NULL; | ||
408 | goto done; | ||
409 | } | ||
410 | |||
411 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
412 | if (err) | ||
413 | goto done; | ||
414 | |||
415 | p9_fid_destroy(fid); | ||
416 | |||
417 | done: | ||
418 | kfree(tc); | ||
419 | kfree(rc); | ||
420 | return err; | ||
421 | } | ||
422 | EXPORT_SYMBOL(p9_client_clunk); | ||
423 | |||
424 | int p9_client_remove(struct p9_fid *fid) | ||
425 | { | ||
426 | int err; | ||
427 | struct p9_fcall *tc, *rc; | ||
428 | struct p9_client *clnt; | ||
429 | |||
430 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
431 | err = 0; | ||
432 | tc = NULL; | ||
433 | rc = NULL; | ||
434 | clnt = fid->clnt; | ||
435 | |||
436 | tc = p9_create_tremove(fid->fid); | ||
437 | if (IS_ERR(tc)) { | ||
438 | err = PTR_ERR(tc); | ||
439 | tc = NULL; | ||
440 | goto done; | ||
441 | } | ||
442 | |||
443 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
444 | if (err) | ||
445 | goto done; | ||
446 | |||
447 | p9_fid_destroy(fid); | ||
448 | |||
449 | done: | ||
450 | kfree(tc); | ||
451 | kfree(rc); | ||
452 | return err; | ||
453 | } | ||
454 | EXPORT_SYMBOL(p9_client_remove); | ||
455 | |||
456 | int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
457 | { | ||
458 | int err, n, rsize, total; | ||
459 | struct p9_fcall *tc, *rc; | ||
460 | struct p9_client *clnt; | ||
461 | |||
462 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu %d\n", fid->fid, | ||
463 | (long long unsigned) offset, count); | ||
464 | err = 0; | ||
465 | tc = NULL; | ||
466 | rc = NULL; | ||
467 | clnt = fid->clnt; | ||
468 | total = 0; | ||
469 | |||
470 | rsize = fid->iounit; | ||
471 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
472 | rsize = clnt->msize - P9_IOHDRSZ; | ||
473 | |||
474 | do { | ||
475 | if (count < rsize) | ||
476 | rsize = count; | ||
477 | |||
478 | tc = p9_create_tread(fid->fid, offset, rsize); | ||
479 | if (IS_ERR(tc)) { | ||
480 | err = PTR_ERR(tc); | ||
481 | tc = NULL; | ||
482 | goto error; | ||
483 | } | ||
484 | |||
485 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
486 | if (err) | ||
487 | goto error; | ||
488 | |||
489 | n = rc->params.rread.count; | ||
490 | if (n > count) | ||
491 | n = count; | ||
492 | |||
493 | memmove(data, rc->params.rread.data, n); | ||
494 | count -= n; | ||
495 | data += n; | ||
496 | offset += n; | ||
497 | total += n; | ||
498 | kfree(tc); | ||
499 | tc = NULL; | ||
500 | kfree(rc); | ||
501 | rc = NULL; | ||
502 | } while (count > 0 && n == rsize); | ||
503 | |||
504 | return total; | ||
505 | |||
506 | error: | ||
507 | kfree(tc); | ||
508 | kfree(rc); | ||
509 | return err; | ||
510 | } | ||
511 | EXPORT_SYMBOL(p9_client_read); | ||
512 | |||
513 | int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
514 | { | ||
515 | int err, n, rsize, total; | ||
516 | struct p9_fcall *tc, *rc; | ||
517 | struct p9_client *clnt; | ||
518 | |||
519 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
520 | (long long unsigned) offset, count); | ||
521 | err = 0; | ||
522 | tc = NULL; | ||
523 | rc = NULL; | ||
524 | clnt = fid->clnt; | ||
525 | total = 0; | ||
526 | |||
527 | rsize = fid->iounit; | ||
528 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
529 | rsize = clnt->msize - P9_IOHDRSZ; | ||
530 | |||
531 | do { | ||
532 | if (count < rsize) | ||
533 | rsize = count; | ||
534 | |||
535 | tc = p9_create_twrite(fid->fid, offset, rsize, data); | ||
536 | if (IS_ERR(tc)) { | ||
537 | err = PTR_ERR(tc); | ||
538 | tc = NULL; | ||
539 | goto error; | ||
540 | } | ||
541 | |||
542 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
543 | if (err) | ||
544 | goto error; | ||
545 | |||
546 | n = rc->params.rread.count; | ||
547 | count -= n; | ||
548 | data += n; | ||
549 | offset += n; | ||
550 | total += n; | ||
551 | kfree(tc); | ||
552 | tc = NULL; | ||
553 | kfree(rc); | ||
554 | rc = NULL; | ||
555 | } while (count > 0); | ||
556 | |||
557 | return total; | ||
558 | |||
559 | error: | ||
560 | kfree(tc); | ||
561 | kfree(rc); | ||
562 | return err; | ||
563 | } | ||
564 | EXPORT_SYMBOL(p9_client_write); | ||
565 | |||
566 | int | ||
567 | p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count) | ||
568 | { | ||
569 | int err, n, rsize, total; | ||
570 | struct p9_fcall *tc, *rc; | ||
571 | struct p9_client *clnt; | ||
572 | |||
573 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
574 | (long long unsigned) offset, count); | ||
575 | err = 0; | ||
576 | tc = NULL; | ||
577 | rc = NULL; | ||
578 | clnt = fid->clnt; | ||
579 | total = 0; | ||
580 | |||
581 | rsize = fid->iounit; | ||
582 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
583 | rsize = clnt->msize - P9_IOHDRSZ; | ||
584 | |||
585 | do { | ||
586 | if (count < rsize) | ||
587 | rsize = count; | ||
588 | |||
589 | tc = p9_create_tread(fid->fid, offset, rsize); | ||
590 | if (IS_ERR(tc)) { | ||
591 | err = PTR_ERR(tc); | ||
592 | tc = NULL; | ||
593 | goto error; | ||
594 | } | ||
595 | |||
596 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
597 | if (err) | ||
598 | goto error; | ||
599 | |||
600 | n = rc->params.rread.count; | ||
601 | if (n > count) | ||
602 | n = count; | ||
603 | |||
604 | err = copy_to_user(data, rc->params.rread.data, n); | ||
605 | if (err) { | ||
606 | err = -EFAULT; | ||
607 | goto error; | ||
608 | } | ||
609 | |||
610 | count -= n; | ||
611 | data += n; | ||
612 | offset += n; | ||
613 | total += n; | ||
614 | kfree(tc); | ||
615 | tc = NULL; | ||
616 | kfree(rc); | ||
617 | rc = NULL; | ||
618 | } while (count > 0 && n == rsize); | ||
619 | |||
620 | return total; | ||
621 | |||
622 | error: | ||
623 | kfree(tc); | ||
624 | kfree(rc); | ||
625 | return err; | ||
626 | } | ||
627 | EXPORT_SYMBOL(p9_client_uread); | ||
628 | |||
629 | int | ||
630 | p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset, | ||
631 | u32 count) | ||
632 | { | ||
633 | int err, n, rsize, total; | ||
634 | struct p9_fcall *tc, *rc; | ||
635 | struct p9_client *clnt; | ||
636 | |||
637 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
638 | (long long unsigned) offset, count); | ||
639 | err = 0; | ||
640 | tc = NULL; | ||
641 | rc = NULL; | ||
642 | clnt = fid->clnt; | ||
643 | total = 0; | ||
644 | |||
645 | rsize = fid->iounit; | ||
646 | if (!rsize || rsize > clnt->msize-P9_IOHDRSZ) | ||
647 | rsize = clnt->msize - P9_IOHDRSZ; | ||
648 | |||
649 | do { | ||
650 | if (count < rsize) | ||
651 | rsize = count; | ||
652 | |||
653 | tc = p9_create_twrite_u(fid->fid, offset, rsize, data); | ||
654 | if (IS_ERR(tc)) { | ||
655 | err = PTR_ERR(tc); | ||
656 | tc = NULL; | ||
657 | goto error; | ||
658 | } | ||
659 | |||
660 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
661 | if (err) | ||
662 | goto error; | ||
663 | |||
664 | n = rc->params.rread.count; | ||
665 | count -= n; | ||
666 | data += n; | ||
667 | offset += n; | ||
668 | total += n; | ||
669 | kfree(tc); | ||
670 | tc = NULL; | ||
671 | kfree(rc); | ||
672 | rc = NULL; | ||
673 | } while (count > 0); | ||
674 | |||
675 | return total; | ||
676 | |||
677 | error: | ||
678 | kfree(tc); | ||
679 | kfree(rc); | ||
680 | return err; | ||
681 | } | ||
682 | EXPORT_SYMBOL(p9_client_uwrite); | ||
683 | |||
684 | int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count) | ||
685 | { | ||
686 | int n, total; | ||
687 | |||
688 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid, | ||
689 | (long long unsigned) offset, count); | ||
690 | n = 0; | ||
691 | total = 0; | ||
692 | while (count) { | ||
693 | n = p9_client_read(fid, data, offset, count); | ||
694 | if (n <= 0) | ||
695 | break; | ||
696 | |||
697 | data += n; | ||
698 | offset += n; | ||
699 | count -= n; | ||
700 | total += n; | ||
701 | } | ||
702 | |||
703 | if (n < 0) | ||
704 | total = n; | ||
705 | |||
706 | return total; | ||
707 | } | ||
708 | EXPORT_SYMBOL(p9_client_readn); | ||
709 | |||
710 | struct p9_stat *p9_client_stat(struct p9_fid *fid) | ||
711 | { | ||
712 | int err; | ||
713 | struct p9_fcall *tc, *rc; | ||
714 | struct p9_client *clnt; | ||
715 | struct p9_stat *ret; | ||
716 | |||
717 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
718 | err = 0; | ||
719 | tc = NULL; | ||
720 | rc = NULL; | ||
721 | ret = NULL; | ||
722 | clnt = fid->clnt; | ||
723 | |||
724 | tc = p9_create_tstat(fid->fid); | ||
725 | if (IS_ERR(tc)) { | ||
726 | err = PTR_ERR(tc); | ||
727 | tc = NULL; | ||
728 | goto error; | ||
729 | } | ||
730 | |||
731 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
732 | if (err) | ||
733 | goto error; | ||
734 | |||
735 | ret = p9_clone_stat(&rc->params.rstat.stat, clnt->dotu); | ||
736 | if (IS_ERR(ret)) { | ||
737 | err = PTR_ERR(ret); | ||
738 | ret = NULL; | ||
739 | goto error; | ||
740 | } | ||
741 | |||
742 | kfree(tc); | ||
743 | kfree(rc); | ||
744 | return ret; | ||
745 | |||
746 | error: | ||
747 | kfree(tc); | ||
748 | kfree(rc); | ||
749 | kfree(ret); | ||
750 | return ERR_PTR(err); | ||
751 | } | ||
752 | EXPORT_SYMBOL(p9_client_stat); | ||
753 | |||
754 | int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | ||
755 | { | ||
756 | int err; | ||
757 | struct p9_fcall *tc, *rc; | ||
758 | struct p9_client *clnt; | ||
759 | |||
760 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
761 | err = 0; | ||
762 | tc = NULL; | ||
763 | rc = NULL; | ||
764 | clnt = fid->clnt; | ||
765 | |||
766 | tc = p9_create_twstat(fid->fid, wst, clnt->dotu); | ||
767 | if (IS_ERR(tc)) { | ||
768 | err = PTR_ERR(tc); | ||
769 | tc = NULL; | ||
770 | goto done; | ||
771 | } | ||
772 | |||
773 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
774 | |||
775 | done: | ||
776 | kfree(tc); | ||
777 | kfree(rc); | ||
778 | return err; | ||
779 | } | ||
780 | EXPORT_SYMBOL(p9_client_wstat); | ||
781 | |||
782 | struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset) | ||
783 | { | ||
784 | int err, n, m; | ||
785 | struct p9_fcall *tc, *rc; | ||
786 | struct p9_client *clnt; | ||
787 | struct p9_stat st, *ret; | ||
788 | |||
789 | P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid, | ||
790 | (long long unsigned) offset); | ||
791 | err = 0; | ||
792 | tc = NULL; | ||
793 | rc = NULL; | ||
794 | ret = NULL; | ||
795 | clnt = fid->clnt; | ||
796 | |||
797 | /* if the offset is below or above the current response, free it */ | ||
798 | if (offset < fid->rdir_fpos || (fid->rdir_fcall && | ||
799 | offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) { | ||
800 | fid->rdir_pos = 0; | ||
801 | if (fid->rdir_fcall) | ||
802 | fid->rdir_fpos += fid->rdir_fcall->params.rread.count; | ||
803 | |||
804 | kfree(fid->rdir_fcall); | ||
805 | fid->rdir_fcall = NULL; | ||
806 | if (offset < fid->rdir_fpos) | ||
807 | fid->rdir_fpos = 0; | ||
808 | } | ||
809 | |||
810 | if (!fid->rdir_fcall) { | ||
811 | n = fid->iounit; | ||
812 | if (!n || n > clnt->msize-P9_IOHDRSZ) | ||
813 | n = clnt->msize - P9_IOHDRSZ; | ||
814 | |||
815 | while (1) { | ||
816 | if (fid->rdir_fcall) { | ||
817 | fid->rdir_fpos += | ||
818 | fid->rdir_fcall->params.rread.count; | ||
819 | kfree(fid->rdir_fcall); | ||
820 | fid->rdir_fcall = NULL; | ||
821 | } | ||
822 | |||
823 | tc = p9_create_tread(fid->fid, fid->rdir_fpos, n); | ||
824 | if (IS_ERR(tc)) { | ||
825 | err = PTR_ERR(tc); | ||
826 | tc = NULL; | ||
827 | goto error; | ||
828 | } | ||
829 | |||
830 | err = p9_conn_rpc(clnt->conn, tc, &rc); | ||
831 | if (err) | ||
832 | goto error; | ||
833 | |||
834 | n = rc->params.rread.count; | ||
835 | if (n == 0) | ||
836 | goto done; | ||
837 | |||
838 | fid->rdir_fcall = rc; | ||
839 | rc = NULL; | ||
840 | if (offset >= fid->rdir_fpos && | ||
841 | offset < fid->rdir_fpos+n) | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | fid->rdir_pos = 0; | ||
846 | } | ||
847 | |||
848 | m = offset - fid->rdir_fpos; | ||
849 | if (m < 0) | ||
850 | goto done; | ||
851 | |||
852 | n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m, | ||
853 | fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu); | ||
854 | |||
855 | if (!n) { | ||
856 | err = -EIO; | ||
857 | goto error; | ||
858 | } | ||
859 | |||
860 | fid->rdir_pos += n; | ||
861 | st.size = n; | ||
862 | ret = p9_clone_stat(&st, clnt->dotu); | ||
863 | if (IS_ERR(ret)) { | ||
864 | err = PTR_ERR(ret); | ||
865 | ret = NULL; | ||
866 | goto error; | ||
867 | } | ||
868 | |||
869 | done: | ||
870 | kfree(tc); | ||
871 | kfree(rc); | ||
872 | return ret; | ||
873 | |||
874 | error: | ||
875 | kfree(tc); | ||
876 | kfree(rc); | ||
877 | kfree(ret); | ||
878 | return ERR_PTR(err); | ||
879 | } | ||
880 | EXPORT_SYMBOL(p9_client_dirread); | ||
881 | |||
882 | static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu) | ||
883 | { | ||
884 | int n; | ||
885 | char *p; | ||
886 | struct p9_stat *ret; | ||
887 | |||
888 | n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len + | ||
889 | st->muid.len; | ||
890 | |||
891 | if (dotu) | ||
892 | n += st->extension.len; | ||
893 | |||
894 | ret = kmalloc(n, GFP_KERNEL); | ||
895 | if (!ret) | ||
896 | return ERR_PTR(-ENOMEM); | ||
897 | |||
898 | memmove(ret, st, sizeof(struct p9_stat)); | ||
899 | p = ((char *) ret) + sizeof(struct p9_stat); | ||
900 | memmove(p, st->name.str, st->name.len); | ||
901 | p += st->name.len; | ||
902 | memmove(p, st->uid.str, st->uid.len); | ||
903 | p += st->uid.len; | ||
904 | memmove(p, st->gid.str, st->gid.len); | ||
905 | p += st->gid.len; | ||
906 | memmove(p, st->muid.str, st->muid.len); | ||
907 | p += st->muid.len; | ||
908 | |||
909 | if (dotu) { | ||
910 | memmove(p, st->extension.str, st->extension.len); | ||
911 | p += st->extension.len; | ||
912 | } | ||
913 | |||
914 | return ret; | ||
915 | } | ||
916 | |||
917 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | ||
918 | { | ||
919 | int err; | ||
920 | struct p9_fid *fid; | ||
921 | |||
922 | P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt); | ||
923 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); | ||
924 | if (!fid) | ||
925 | return ERR_PTR(-ENOMEM); | ||
926 | |||
927 | fid->fid = p9_idpool_get(clnt->fidpool); | ||
928 | if (fid->fid < 0) { | ||
929 | err = -ENOSPC; | ||
930 | goto error; | ||
931 | } | ||
932 | |||
933 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | ||
934 | fid->mode = -1; | ||
935 | fid->rdir_fpos = 0; | ||
936 | fid->rdir_pos = 0; | ||
937 | fid->rdir_fcall = NULL; | ||
938 | fid->uid = current->fsuid; | ||
939 | fid->clnt = clnt; | ||
940 | fid->aux = NULL; | ||
941 | |||
942 | spin_lock(&clnt->lock); | ||
943 | list_add(&fid->flist, &clnt->fidlist); | ||
944 | spin_unlock(&clnt->lock); | ||
945 | |||
946 | return fid; | ||
947 | |||
948 | error: | ||
949 | kfree(fid); | ||
950 | return ERR_PTR(err); | ||
951 | } | ||
952 | |||
953 | static void p9_fid_destroy(struct p9_fid *fid) | ||
954 | { | ||
955 | struct p9_client *clnt; | ||
956 | |||
957 | P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid); | ||
958 | clnt = fid->clnt; | ||
959 | p9_idpool_put(fid->fid, clnt->fidpool); | ||
960 | spin_lock(&clnt->lock); | ||
961 | list_del(&fid->flist); | ||
962 | spin_unlock(&clnt->lock); | ||
963 | kfree(fid->rdir_fcall); | ||
964 | kfree(fid); | ||
965 | } | ||
diff --git a/fs/9p/conv.c b/net/9p/conv.c index a3ed571eee3..37451178e76 100644 --- a/fs/9p/conv.c +++ b/net/9p/conv.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/conv.c | 2 | * net/9p/conv.c |
3 | * | 3 | * |
4 | * 9P protocol conversion functions | 4 | * 9P protocol conversion functions |
5 | * | 5 | * |
@@ -29,11 +29,8 @@ | |||
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
32 | #include <asm/uaccess.h> | 32 | #include <linux/uaccess.h> |
33 | #include "debug.h" | 33 | #include <net/9p/9p.h> |
34 | #include "v9fs.h" | ||
35 | #include "9p.h" | ||
36 | #include "conv.h" | ||
37 | 34 | ||
38 | /* | 35 | /* |
39 | * Buffer to help with string parsing | 36 | * Buffer to help with string parsing |
@@ -59,8 +56,9 @@ static int buf_check_size(struct cbuf *buf, int len) | |||
59 | { | 56 | { |
60 | if (buf->p + len > buf->ep) { | 57 | if (buf->p + len > buf->ep) { |
61 | if (buf->p < buf->ep) { | 58 | if (buf->p < buf->ep) { |
62 | eprintk(KERN_ERR, "buffer overflow: want %d has %d\n", | 59 | P9_EPRINTK(KERN_ERR, |
63 | len, (int)(buf->ep - buf->p)); | 60 | "buffer overflow: want %d has %d\n", len, |
61 | (int)(buf->ep - buf->p)); | ||
64 | dump_stack(); | 62 | dump_stack(); |
65 | buf->p = buf->ep + 1; | 63 | buf->p = buf->ep + 1; |
66 | } | 64 | } |
@@ -183,7 +181,7 @@ static u64 buf_get_int64(struct cbuf *buf) | |||
183 | return ret; | 181 | return ret; |
184 | } | 182 | } |
185 | 183 | ||
186 | static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr) | 184 | static void buf_get_str(struct cbuf *buf, struct p9_str *vstr) |
187 | { | 185 | { |
188 | vstr->len = buf_get_int16(buf); | 186 | vstr->len = buf_get_int16(buf); |
189 | if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { | 187 | if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) { |
@@ -195,7 +193,7 @@ static void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr) | |||
195 | } | 193 | } |
196 | } | 194 | } |
197 | 195 | ||
198 | static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid) | 196 | static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid) |
199 | { | 197 | { |
200 | qid->type = buf_get_int8(bufp); | 198 | qid->type = buf_get_int8(bufp); |
201 | qid->version = buf_get_int32(bufp); | 199 | qid->version = buf_get_int32(bufp); |
@@ -203,18 +201,18 @@ static void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid) | |||
203 | } | 201 | } |
204 | 202 | ||
205 | /** | 203 | /** |
206 | * v9fs_size_wstat - calculate the size of a variable length stat struct | 204 | * p9_size_wstat - calculate the size of a variable length stat struct |
207 | * @stat: metadata (stat) structure | 205 | * @stat: metadata (stat) structure |
208 | * @extended: non-zero if 9P2000.u | 206 | * @dotu: non-zero if 9P2000.u |
209 | * | 207 | * |
210 | */ | 208 | */ |
211 | 209 | ||
212 | static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | 210 | static int p9_size_wstat(struct p9_wstat *wstat, int dotu) |
213 | { | 211 | { |
214 | int size = 0; | 212 | int size = 0; |
215 | 213 | ||
216 | if (wstat == NULL) { | 214 | if (wstat == NULL) { |
217 | eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n"); | 215 | P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n"); |
218 | return 0; | 216 | return 0; |
219 | } | 217 | } |
220 | 218 | ||
@@ -239,7 +237,7 @@ static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | |||
239 | if (wstat->muid) | 237 | if (wstat->muid) |
240 | size += strlen(wstat->muid); | 238 | size += strlen(wstat->muid); |
241 | 239 | ||
242 | if (extended) { | 240 | if (dotu) { |
243 | size += 4 + /* n_uid[4] */ | 241 | size += 4 + /* n_uid[4] */ |
244 | 4 + /* n_gid[4] */ | 242 | 4 + /* n_gid[4] */ |
245 | 4 + /* n_muid[4] */ | 243 | 4 + /* n_muid[4] */ |
@@ -255,12 +253,12 @@ static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended) | |||
255 | * buf_get_stat - safely decode a recieved metadata (stat) structure | 253 | * buf_get_stat - safely decode a recieved metadata (stat) structure |
256 | * @bufp: buffer to deserialize | 254 | * @bufp: buffer to deserialize |
257 | * @stat: metadata (stat) structure | 255 | * @stat: metadata (stat) structure |
258 | * @extended: non-zero if 9P2000.u | 256 | * @dotu: non-zero if 9P2000.u |
259 | * | 257 | * |
260 | */ | 258 | */ |
261 | 259 | ||
262 | static void | 260 | static void |
263 | buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | 261 | buf_get_stat(struct cbuf *bufp, struct p9_stat *stat, int dotu) |
264 | { | 262 | { |
265 | stat->size = buf_get_int16(bufp); | 263 | stat->size = buf_get_int16(bufp); |
266 | stat->type = buf_get_int16(bufp); | 264 | stat->type = buf_get_int16(bufp); |
@@ -277,7 +275,7 @@ buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | |||
277 | buf_get_str(bufp, &stat->gid); | 275 | buf_get_str(bufp, &stat->gid); |
278 | buf_get_str(bufp, &stat->muid); | 276 | buf_get_str(bufp, &stat->muid); |
279 | 277 | ||
280 | if (extended) { | 278 | if (dotu) { |
281 | buf_get_str(bufp, &stat->extension); | 279 | buf_get_str(bufp, &stat->extension); |
282 | stat->n_uid = buf_get_int32(bufp); | 280 | stat->n_uid = buf_get_int32(bufp); |
283 | stat->n_gid = buf_get_int32(bufp); | 281 | stat->n_gid = buf_get_int32(bufp); |
@@ -286,18 +284,18 @@ buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended) | |||
286 | } | 284 | } |
287 | 285 | ||
288 | /** | 286 | /** |
289 | * v9fs_deserialize_stat - decode a received metadata structure | 287 | * p9_deserialize_stat - decode a received metadata structure |
290 | * @buf: buffer to deserialize | 288 | * @buf: buffer to deserialize |
291 | * @buflen: length of received buffer | 289 | * @buflen: length of received buffer |
292 | * @stat: metadata structure to decode into | 290 | * @stat: metadata structure to decode into |
293 | * @extended: non-zero if 9P2000.u | 291 | * @dotu: non-zero if 9P2000.u |
294 | * | 292 | * |
295 | * Note: stat will point to the buf region. | 293 | * Note: stat will point to the buf region. |
296 | */ | 294 | */ |
297 | 295 | ||
298 | int | 296 | int |
299 | v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | 297 | p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat, |
300 | int extended) | 298 | int dotu) |
301 | { | 299 | { |
302 | struct cbuf buffer; | 300 | struct cbuf buffer; |
303 | struct cbuf *bufp = &buffer; | 301 | struct cbuf *bufp = &buffer; |
@@ -305,13 +303,14 @@ v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | |||
305 | 303 | ||
306 | buf_init(bufp, buf, buflen); | 304 | buf_init(bufp, buf, buflen); |
307 | p = bufp->p; | 305 | p = bufp->p; |
308 | buf_get_stat(bufp, stat, extended); | 306 | buf_get_stat(bufp, stat, dotu); |
309 | 307 | ||
310 | if (buf_check_overflow(bufp)) | 308 | if (buf_check_overflow(bufp)) |
311 | return 0; | 309 | return 0; |
312 | else | 310 | else |
313 | return bufp->p - p; | 311 | return bufp->p - p; |
314 | } | 312 | } |
313 | EXPORT_SYMBOL(p9_deserialize_stat); | ||
315 | 314 | ||
316 | /** | 315 | /** |
317 | * deserialize_fcall - unmarshal a response | 316 | * deserialize_fcall - unmarshal a response |
@@ -319,13 +318,13 @@ v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat, | |||
319 | * @buflen: length of received buffer | 318 | * @buflen: length of received buffer |
320 | * @rcall: fcall structure to populate | 319 | * @rcall: fcall structure to populate |
321 | * @rcalllen: length of fcall structure to populate | 320 | * @rcalllen: length of fcall structure to populate |
322 | * @extended: non-zero if 9P2000.u | 321 | * @dotu: non-zero if 9P2000.u |
323 | * | 322 | * |
324 | */ | 323 | */ |
325 | 324 | ||
326 | int | 325 | int |
327 | v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | 326 | p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall, |
328 | int extended) | 327 | int dotu) |
329 | { | 328 | { |
330 | 329 | ||
331 | struct cbuf buffer; | 330 | struct cbuf buffer; |
@@ -338,102 +337,104 @@ v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall, | |||
338 | rcall->id = buf_get_int8(bufp); | 337 | rcall->id = buf_get_int8(bufp); |
339 | rcall->tag = buf_get_int16(bufp); | 338 | rcall->tag = buf_get_int16(bufp); |
340 | 339 | ||
341 | dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id, | 340 | P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, |
342 | rcall->tag); | 341 | rcall->id, rcall->tag); |
343 | 342 | ||
344 | switch (rcall->id) { | 343 | switch (rcall->id) { |
345 | default: | 344 | default: |
346 | eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id); | 345 | P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id); |
347 | return -EPROTO; | 346 | return -EPROTO; |
348 | case RVERSION: | 347 | case P9_RVERSION: |
349 | rcall->params.rversion.msize = buf_get_int32(bufp); | 348 | rcall->params.rversion.msize = buf_get_int32(bufp); |
350 | buf_get_str(bufp, &rcall->params.rversion.version); | 349 | buf_get_str(bufp, &rcall->params.rversion.version); |
351 | break; | 350 | break; |
352 | case RFLUSH: | 351 | case P9_RFLUSH: |
353 | break; | 352 | break; |
354 | case RATTACH: | 353 | case P9_RATTACH: |
355 | rcall->params.rattach.qid.type = buf_get_int8(bufp); | 354 | rcall->params.rattach.qid.type = buf_get_int8(bufp); |
356 | rcall->params.rattach.qid.version = buf_get_int32(bufp); | 355 | rcall->params.rattach.qid.version = buf_get_int32(bufp); |
357 | rcall->params.rattach.qid.path = buf_get_int64(bufp); | 356 | rcall->params.rattach.qid.path = buf_get_int64(bufp); |
358 | break; | 357 | break; |
359 | case RWALK: | 358 | case P9_RWALK: |
360 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); | 359 | rcall->params.rwalk.nwqid = buf_get_int16(bufp); |
361 | if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) { | 360 | if (rcall->params.rwalk.nwqid > P9_MAXWELEM) { |
362 | eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n", | 361 | P9_EPRINTK(KERN_ERR, |
363 | V9FS_MAXWELEM, rcall->params.rwalk.nwqid); | 362 | "Rwalk with more than %d qids: %d\n", |
363 | P9_MAXWELEM, rcall->params.rwalk.nwqid); | ||
364 | return -EPROTO; | 364 | return -EPROTO; |
365 | } | 365 | } |
366 | 366 | ||
367 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) | 367 | for (i = 0; i < rcall->params.rwalk.nwqid; i++) |
368 | buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); | 368 | buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]); |
369 | break; | 369 | break; |
370 | case ROPEN: | 370 | case P9_ROPEN: |
371 | buf_get_qid(bufp, &rcall->params.ropen.qid); | 371 | buf_get_qid(bufp, &rcall->params.ropen.qid); |
372 | rcall->params.ropen.iounit = buf_get_int32(bufp); | 372 | rcall->params.ropen.iounit = buf_get_int32(bufp); |
373 | break; | 373 | break; |
374 | case RCREATE: | 374 | case P9_RCREATE: |
375 | buf_get_qid(bufp, &rcall->params.rcreate.qid); | 375 | buf_get_qid(bufp, &rcall->params.rcreate.qid); |
376 | rcall->params.rcreate.iounit = buf_get_int32(bufp); | 376 | rcall->params.rcreate.iounit = buf_get_int32(bufp); |
377 | break; | 377 | break; |
378 | case RREAD: | 378 | case P9_RREAD: |
379 | rcall->params.rread.count = buf_get_int32(bufp); | 379 | rcall->params.rread.count = buf_get_int32(bufp); |
380 | rcall->params.rread.data = bufp->p; | 380 | rcall->params.rread.data = bufp->p; |
381 | buf_check_size(bufp, rcall->params.rread.count); | 381 | buf_check_size(bufp, rcall->params.rread.count); |
382 | break; | 382 | break; |
383 | case RWRITE: | 383 | case P9_RWRITE: |
384 | rcall->params.rwrite.count = buf_get_int32(bufp); | 384 | rcall->params.rwrite.count = buf_get_int32(bufp); |
385 | break; | 385 | break; |
386 | case RCLUNK: | 386 | case P9_RCLUNK: |
387 | break; | 387 | break; |
388 | case RREMOVE: | 388 | case P9_RREMOVE: |
389 | break; | 389 | break; |
390 | case RSTAT: | 390 | case P9_RSTAT: |
391 | buf_get_int16(bufp); | 391 | buf_get_int16(bufp); |
392 | buf_get_stat(bufp, &rcall->params.rstat.stat, extended); | 392 | buf_get_stat(bufp, &rcall->params.rstat.stat, dotu); |
393 | break; | 393 | break; |
394 | case RWSTAT: | 394 | case P9_RWSTAT: |
395 | break; | 395 | break; |
396 | case RERROR: | 396 | case P9_RERROR: |
397 | buf_get_str(bufp, &rcall->params.rerror.error); | 397 | buf_get_str(bufp, &rcall->params.rerror.error); |
398 | if (extended) | 398 | if (dotu) |
399 | rcall->params.rerror.errno = buf_get_int16(bufp); | 399 | rcall->params.rerror.errno = buf_get_int16(bufp); |
400 | break; | 400 | break; |
401 | } | 401 | } |
402 | 402 | ||
403 | if (buf_check_overflow(bufp)) { | 403 | if (buf_check_overflow(bufp)) { |
404 | dprintk(DEBUG_ERROR, "buffer overflow\n"); | 404 | P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n"); |
405 | return -EIO; | 405 | return -EIO; |
406 | } | 406 | } |
407 | 407 | ||
408 | return bufp->p - bufp->sp; | 408 | return bufp->p - bufp->sp; |
409 | } | 409 | } |
410 | EXPORT_SYMBOL(p9_deserialize_fcall); | ||
410 | 411 | ||
411 | static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p) | 412 | static inline void p9_put_int8(struct cbuf *bufp, u8 val, u8 * p) |
412 | { | 413 | { |
413 | *p = val; | 414 | *p = val; |
414 | buf_put_int8(bufp, val); | 415 | buf_put_int8(bufp, val); |
415 | } | 416 | } |
416 | 417 | ||
417 | static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p) | 418 | static inline void p9_put_int16(struct cbuf *bufp, u16 val, u16 * p) |
418 | { | 419 | { |
419 | *p = val; | 420 | *p = val; |
420 | buf_put_int16(bufp, val); | 421 | buf_put_int16(bufp, val); |
421 | } | 422 | } |
422 | 423 | ||
423 | static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p) | 424 | static inline void p9_put_int32(struct cbuf *bufp, u32 val, u32 * p) |
424 | { | 425 | { |
425 | *p = val; | 426 | *p = val; |
426 | buf_put_int32(bufp, val); | 427 | buf_put_int32(bufp, val); |
427 | } | 428 | } |
428 | 429 | ||
429 | static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p) | 430 | static inline void p9_put_int64(struct cbuf *bufp, u64 val, u64 * p) |
430 | { | 431 | { |
431 | *p = val; | 432 | *p = val; |
432 | buf_put_int64(bufp, val); | 433 | buf_put_int64(bufp, val); |
433 | } | 434 | } |
434 | 435 | ||
435 | static void | 436 | static void |
436 | v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) | 437 | p9_put_str(struct cbuf *bufp, char *data, struct p9_str *str) |
437 | { | 438 | { |
438 | int len; | 439 | int len; |
439 | char *s; | 440 | char *s; |
@@ -451,7 +452,16 @@ v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) | |||
451 | } | 452 | } |
452 | 453 | ||
453 | static int | 454 | static int |
454 | v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count, | 455 | p9_put_data(struct cbuf *bufp, const char *data, int count, |
456 | unsigned char **pdata) | ||
457 | { | ||
458 | *pdata = buf_alloc(bufp, count); | ||
459 | memmove(*pdata, data, count); | ||
460 | return count; | ||
461 | } | ||
462 | |||
463 | static int | ||
464 | p9_put_user_data(struct cbuf *bufp, const char __user *data, int count, | ||
455 | unsigned char **pdata) | 465 | unsigned char **pdata) |
456 | { | 466 | { |
457 | *pdata = buf_alloc(bufp, count); | 467 | *pdata = buf_alloc(bufp, count); |
@@ -459,162 +469,167 @@ v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count, | |||
459 | } | 469 | } |
460 | 470 | ||
461 | static void | 471 | static void |
462 | v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat, | 472 | p9_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat, |
463 | struct v9fs_stat *stat, int statsz, int extended) | 473 | struct p9_stat *stat, int statsz, int dotu) |
464 | { | 474 | { |
465 | v9fs_put_int16(bufp, statsz, &stat->size); | 475 | p9_put_int16(bufp, statsz, &stat->size); |
466 | v9fs_put_int16(bufp, wstat->type, &stat->type); | 476 | p9_put_int16(bufp, wstat->type, &stat->type); |
467 | v9fs_put_int32(bufp, wstat->dev, &stat->dev); | 477 | p9_put_int32(bufp, wstat->dev, &stat->dev); |
468 | v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type); | 478 | p9_put_int8(bufp, wstat->qid.type, &stat->qid.type); |
469 | v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version); | 479 | p9_put_int32(bufp, wstat->qid.version, &stat->qid.version); |
470 | v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path); | 480 | p9_put_int64(bufp, wstat->qid.path, &stat->qid.path); |
471 | v9fs_put_int32(bufp, wstat->mode, &stat->mode); | 481 | p9_put_int32(bufp, wstat->mode, &stat->mode); |
472 | v9fs_put_int32(bufp, wstat->atime, &stat->atime); | 482 | p9_put_int32(bufp, wstat->atime, &stat->atime); |
473 | v9fs_put_int32(bufp, wstat->mtime, &stat->mtime); | 483 | p9_put_int32(bufp, wstat->mtime, &stat->mtime); |
474 | v9fs_put_int64(bufp, wstat->length, &stat->length); | 484 | p9_put_int64(bufp, wstat->length, &stat->length); |
475 | 485 | ||
476 | v9fs_put_str(bufp, wstat->name, &stat->name); | 486 | p9_put_str(bufp, wstat->name, &stat->name); |
477 | v9fs_put_str(bufp, wstat->uid, &stat->uid); | 487 | p9_put_str(bufp, wstat->uid, &stat->uid); |
478 | v9fs_put_str(bufp, wstat->gid, &stat->gid); | 488 | p9_put_str(bufp, wstat->gid, &stat->gid); |
479 | v9fs_put_str(bufp, wstat->muid, &stat->muid); | 489 | p9_put_str(bufp, wstat->muid, &stat->muid); |
480 | 490 | ||
481 | if (extended) { | 491 | if (dotu) { |
482 | v9fs_put_str(bufp, wstat->extension, &stat->extension); | 492 | p9_put_str(bufp, wstat->extension, &stat->extension); |
483 | v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid); | 493 | p9_put_int32(bufp, wstat->n_uid, &stat->n_uid); |
484 | v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid); | 494 | p9_put_int32(bufp, wstat->n_gid, &stat->n_gid); |
485 | v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid); | 495 | p9_put_int32(bufp, wstat->n_muid, &stat->n_muid); |
486 | } | 496 | } |
487 | } | 497 | } |
488 | 498 | ||
489 | static struct v9fs_fcall * | 499 | static struct p9_fcall * |
490 | v9fs_create_common(struct cbuf *bufp, u32 size, u8 id) | 500 | p9_create_common(struct cbuf *bufp, u32 size, u8 id) |
491 | { | 501 | { |
492 | struct v9fs_fcall *fc; | 502 | struct p9_fcall *fc; |
493 | 503 | ||
494 | size += 4 + 1 + 2; /* size[4] id[1] tag[2] */ | 504 | size += 4 + 1 + 2; /* size[4] id[1] tag[2] */ |
495 | fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL); | 505 | fc = kmalloc(sizeof(struct p9_fcall) + size, GFP_KERNEL); |
496 | if (!fc) | 506 | if (!fc) |
497 | return ERR_PTR(-ENOMEM); | 507 | return ERR_PTR(-ENOMEM); |
498 | 508 | ||
499 | fc->sdata = (char *)fc + sizeof(*fc); | 509 | fc->sdata = (char *)fc + sizeof(*fc); |
500 | 510 | ||
501 | buf_init(bufp, (char *)fc->sdata, size); | 511 | buf_init(bufp, (char *)fc->sdata, size); |
502 | v9fs_put_int32(bufp, size, &fc->size); | 512 | p9_put_int32(bufp, size, &fc->size); |
503 | v9fs_put_int8(bufp, id, &fc->id); | 513 | p9_put_int8(bufp, id, &fc->id); |
504 | v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag); | 514 | p9_put_int16(bufp, P9_NOTAG, &fc->tag); |
505 | 515 | ||
506 | return fc; | 516 | return fc; |
507 | } | 517 | } |
508 | 518 | ||
509 | void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag) | 519 | void p9_set_tag(struct p9_fcall *fc, u16 tag) |
510 | { | 520 | { |
511 | fc->tag = tag; | 521 | fc->tag = tag; |
512 | *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag); | 522 | *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag); |
513 | } | 523 | } |
524 | EXPORT_SYMBOL(p9_set_tag); | ||
514 | 525 | ||
515 | struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version) | 526 | struct p9_fcall *p9_create_tversion(u32 msize, char *version) |
516 | { | 527 | { |
517 | int size; | 528 | int size; |
518 | struct v9fs_fcall *fc; | 529 | struct p9_fcall *fc; |
519 | struct cbuf buffer; | 530 | struct cbuf buffer; |
520 | struct cbuf *bufp = &buffer; | 531 | struct cbuf *bufp = &buffer; |
521 | 532 | ||
522 | size = 4 + 2 + strlen(version); /* msize[4] version[s] */ | 533 | size = 4 + 2 + strlen(version); /* msize[4] version[s] */ |
523 | fc = v9fs_create_common(bufp, size, TVERSION); | 534 | fc = p9_create_common(bufp, size, P9_TVERSION); |
524 | if (IS_ERR(fc)) | 535 | if (IS_ERR(fc)) |
525 | goto error; | 536 | goto error; |
526 | 537 | ||
527 | v9fs_put_int32(bufp, msize, &fc->params.tversion.msize); | 538 | p9_put_int32(bufp, msize, &fc->params.tversion.msize); |
528 | v9fs_put_str(bufp, version, &fc->params.tversion.version); | 539 | p9_put_str(bufp, version, &fc->params.tversion.version); |
529 | 540 | ||
530 | if (buf_check_overflow(bufp)) { | 541 | if (buf_check_overflow(bufp)) { |
531 | kfree(fc); | 542 | kfree(fc); |
532 | fc = ERR_PTR(-ENOMEM); | 543 | fc = ERR_PTR(-ENOMEM); |
533 | } | 544 | } |
534 | error: | 545 | error: |
535 | return fc; | 546 | return fc; |
536 | } | 547 | } |
548 | EXPORT_SYMBOL(p9_create_tversion); | ||
537 | 549 | ||
538 | #if 0 | 550 | struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname) |
539 | struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname) | ||
540 | { | 551 | { |
541 | int size; | 552 | int size; |
542 | struct v9fs_fcall *fc; | 553 | struct p9_fcall *fc; |
543 | struct cbuf buffer; | 554 | struct cbuf buffer; |
544 | struct cbuf *bufp = &buffer; | 555 | struct cbuf *bufp = &buffer; |
545 | 556 | ||
546 | size = 4 + 2 + strlen(uname) + 2 + strlen(aname); /* afid[4] uname[s] aname[s] */ | 557 | /* afid[4] uname[s] aname[s] */ |
547 | fc = v9fs_create_common(bufp, size, TAUTH); | 558 | size = 4 + 2 + strlen(uname) + 2 + strlen(aname); |
559 | fc = p9_create_common(bufp, size, P9_TAUTH); | ||
548 | if (IS_ERR(fc)) | 560 | if (IS_ERR(fc)) |
549 | goto error; | 561 | goto error; |
550 | 562 | ||
551 | v9fs_put_int32(bufp, afid, &fc->params.tauth.afid); | 563 | p9_put_int32(bufp, afid, &fc->params.tauth.afid); |
552 | v9fs_put_str(bufp, uname, &fc->params.tauth.uname); | 564 | p9_put_str(bufp, uname, &fc->params.tauth.uname); |
553 | v9fs_put_str(bufp, aname, &fc->params.tauth.aname); | 565 | p9_put_str(bufp, aname, &fc->params.tauth.aname); |
554 | 566 | ||
555 | if (buf_check_overflow(bufp)) { | 567 | if (buf_check_overflow(bufp)) { |
556 | kfree(fc); | 568 | kfree(fc); |
557 | fc = ERR_PTR(-ENOMEM); | 569 | fc = ERR_PTR(-ENOMEM); |
558 | } | 570 | } |
559 | error: | 571 | error: |
560 | return fc; | 572 | return fc; |
561 | } | 573 | } |
562 | #endif /* 0 */ | 574 | EXPORT_SYMBOL(p9_create_tauth); |
563 | 575 | ||
564 | struct v9fs_fcall * | 576 | struct p9_fcall * |
565 | v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname) | 577 | p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname) |
566 | { | 578 | { |
567 | int size; | 579 | int size; |
568 | struct v9fs_fcall *fc; | 580 | struct p9_fcall *fc; |
569 | struct cbuf buffer; | 581 | struct cbuf buffer; |
570 | struct cbuf *bufp = &buffer; | 582 | struct cbuf *bufp = &buffer; |
571 | 583 | ||
572 | size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); /* fid[4] afid[4] uname[s] aname[s] */ | 584 | /* fid[4] afid[4] uname[s] aname[s] */ |
573 | fc = v9fs_create_common(bufp, size, TATTACH); | 585 | size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname); |
586 | fc = p9_create_common(bufp, size, P9_TATTACH); | ||
574 | if (IS_ERR(fc)) | 587 | if (IS_ERR(fc)) |
575 | goto error; | 588 | goto error; |
576 | 589 | ||
577 | v9fs_put_int32(bufp, fid, &fc->params.tattach.fid); | 590 | p9_put_int32(bufp, fid, &fc->params.tattach.fid); |
578 | v9fs_put_int32(bufp, afid, &fc->params.tattach.afid); | 591 | p9_put_int32(bufp, afid, &fc->params.tattach.afid); |
579 | v9fs_put_str(bufp, uname, &fc->params.tattach.uname); | 592 | p9_put_str(bufp, uname, &fc->params.tattach.uname); |
580 | v9fs_put_str(bufp, aname, &fc->params.tattach.aname); | 593 | p9_put_str(bufp, aname, &fc->params.tattach.aname); |
581 | 594 | ||
582 | error: | 595 | error: |
583 | return fc; | 596 | return fc; |
584 | } | 597 | } |
598 | EXPORT_SYMBOL(p9_create_tattach); | ||
585 | 599 | ||
586 | struct v9fs_fcall *v9fs_create_tflush(u16 oldtag) | 600 | struct p9_fcall *p9_create_tflush(u16 oldtag) |
587 | { | 601 | { |
588 | int size; | 602 | int size; |
589 | struct v9fs_fcall *fc; | 603 | struct p9_fcall *fc; |
590 | struct cbuf buffer; | 604 | struct cbuf buffer; |
591 | struct cbuf *bufp = &buffer; | 605 | struct cbuf *bufp = &buffer; |
592 | 606 | ||
593 | size = 2; /* oldtag[2] */ | 607 | size = 2; /* oldtag[2] */ |
594 | fc = v9fs_create_common(bufp, size, TFLUSH); | 608 | fc = p9_create_common(bufp, size, P9_TFLUSH); |
595 | if (IS_ERR(fc)) | 609 | if (IS_ERR(fc)) |
596 | goto error; | 610 | goto error; |
597 | 611 | ||
598 | v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); | 612 | p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag); |
599 | 613 | ||
600 | if (buf_check_overflow(bufp)) { | 614 | if (buf_check_overflow(bufp)) { |
601 | kfree(fc); | 615 | kfree(fc); |
602 | fc = ERR_PTR(-ENOMEM); | 616 | fc = ERR_PTR(-ENOMEM); |
603 | } | 617 | } |
604 | error: | 618 | error: |
605 | return fc; | 619 | return fc; |
606 | } | 620 | } |
621 | EXPORT_SYMBOL(p9_create_tflush); | ||
607 | 622 | ||
608 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | 623 | struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname, |
609 | char **wnames) | 624 | char **wnames) |
610 | { | 625 | { |
611 | int i, size; | 626 | int i, size; |
612 | struct v9fs_fcall *fc; | 627 | struct p9_fcall *fc; |
613 | struct cbuf buffer; | 628 | struct cbuf buffer; |
614 | struct cbuf *bufp = &buffer; | 629 | struct cbuf *bufp = &buffer; |
615 | 630 | ||
616 | if (nwname > V9FS_MAXWELEM) { | 631 | if (nwname > P9_MAXWELEM) { |
617 | dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM); | 632 | P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM); |
618 | return NULL; | 633 | return NULL; |
619 | } | 634 | } |
620 | 635 | ||
@@ -623,122 +638,160 @@ struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | |||
623 | size += 2 + strlen(wnames[i]); /* wname[s] */ | 638 | size += 2 + strlen(wnames[i]); /* wname[s] */ |
624 | } | 639 | } |
625 | 640 | ||
626 | fc = v9fs_create_common(bufp, size, TWALK); | 641 | fc = p9_create_common(bufp, size, P9_TWALK); |
627 | if (IS_ERR(fc)) | 642 | if (IS_ERR(fc)) |
628 | goto error; | 643 | goto error; |
629 | 644 | ||
630 | v9fs_put_int32(bufp, fid, &fc->params.twalk.fid); | 645 | p9_put_int32(bufp, fid, &fc->params.twalk.fid); |
631 | v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid); | 646 | p9_put_int32(bufp, newfid, &fc->params.twalk.newfid); |
632 | v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname); | 647 | p9_put_int16(bufp, nwname, &fc->params.twalk.nwname); |
633 | for (i = 0; i < nwname; i++) { | 648 | for (i = 0; i < nwname; i++) { |
634 | v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); | 649 | p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]); |
635 | } | 650 | } |
636 | 651 | ||
637 | if (buf_check_overflow(bufp)) { | 652 | if (buf_check_overflow(bufp)) { |
638 | kfree(fc); | 653 | kfree(fc); |
639 | fc = ERR_PTR(-ENOMEM); | 654 | fc = ERR_PTR(-ENOMEM); |
640 | } | 655 | } |
641 | error: | 656 | error: |
642 | return fc; | 657 | return fc; |
643 | } | 658 | } |
659 | EXPORT_SYMBOL(p9_create_twalk); | ||
644 | 660 | ||
645 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode) | 661 | struct p9_fcall *p9_create_topen(u32 fid, u8 mode) |
646 | { | 662 | { |
647 | int size; | 663 | int size; |
648 | struct v9fs_fcall *fc; | 664 | struct p9_fcall *fc; |
649 | struct cbuf buffer; | 665 | struct cbuf buffer; |
650 | struct cbuf *bufp = &buffer; | 666 | struct cbuf *bufp = &buffer; |
651 | 667 | ||
652 | size = 4 + 1; /* fid[4] mode[1] */ | 668 | size = 4 + 1; /* fid[4] mode[1] */ |
653 | fc = v9fs_create_common(bufp, size, TOPEN); | 669 | fc = p9_create_common(bufp, size, P9_TOPEN); |
654 | if (IS_ERR(fc)) | 670 | if (IS_ERR(fc)) |
655 | goto error; | 671 | goto error; |
656 | 672 | ||
657 | v9fs_put_int32(bufp, fid, &fc->params.topen.fid); | 673 | p9_put_int32(bufp, fid, &fc->params.topen.fid); |
658 | v9fs_put_int8(bufp, mode, &fc->params.topen.mode); | 674 | p9_put_int8(bufp, mode, &fc->params.topen.mode); |
659 | 675 | ||
660 | if (buf_check_overflow(bufp)) { | 676 | if (buf_check_overflow(bufp)) { |
661 | kfree(fc); | 677 | kfree(fc); |
662 | fc = ERR_PTR(-ENOMEM); | 678 | fc = ERR_PTR(-ENOMEM); |
663 | } | 679 | } |
664 | error: | 680 | error: |
665 | return fc; | 681 | return fc; |
666 | } | 682 | } |
683 | EXPORT_SYMBOL(p9_create_topen); | ||
667 | 684 | ||
668 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, | 685 | struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, |
669 | char *extension, int extended) | 686 | char *extension, int dotu) |
670 | { | 687 | { |
671 | int size; | 688 | int size; |
672 | struct v9fs_fcall *fc; | 689 | struct p9_fcall *fc; |
673 | struct cbuf buffer; | 690 | struct cbuf buffer; |
674 | struct cbuf *bufp = &buffer; | 691 | struct cbuf *bufp = &buffer; |
675 | 692 | ||
676 | size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ | 693 | /* fid[4] name[s] perm[4] mode[1] */ |
677 | if (extended) { | 694 | size = 4 + 2 + strlen(name) + 4 + 1; |
695 | if (dotu) { | ||
678 | size += 2 + /* extension[s] */ | 696 | size += 2 + /* extension[s] */ |
679 | (extension == NULL ? 0 : strlen(extension)); | 697 | (extension == NULL ? 0 : strlen(extension)); |
680 | } | 698 | } |
681 | 699 | ||
682 | fc = v9fs_create_common(bufp, size, TCREATE); | 700 | fc = p9_create_common(bufp, size, P9_TCREATE); |
683 | if (IS_ERR(fc)) | 701 | if (IS_ERR(fc)) |
684 | goto error; | 702 | goto error; |
685 | 703 | ||
686 | v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid); | 704 | p9_put_int32(bufp, fid, &fc->params.tcreate.fid); |
687 | v9fs_put_str(bufp, name, &fc->params.tcreate.name); | 705 | p9_put_str(bufp, name, &fc->params.tcreate.name); |
688 | v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); | 706 | p9_put_int32(bufp, perm, &fc->params.tcreate.perm); |
689 | v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); | 707 | p9_put_int8(bufp, mode, &fc->params.tcreate.mode); |
690 | if (extended) | 708 | if (dotu) |
691 | v9fs_put_str(bufp, extension, &fc->params.tcreate.extension); | 709 | p9_put_str(bufp, extension, &fc->params.tcreate.extension); |
692 | 710 | ||
693 | if (buf_check_overflow(bufp)) { | 711 | if (buf_check_overflow(bufp)) { |
694 | kfree(fc); | 712 | kfree(fc); |
695 | fc = ERR_PTR(-ENOMEM); | 713 | fc = ERR_PTR(-ENOMEM); |
696 | } | 714 | } |
697 | error: | 715 | error: |
698 | return fc; | 716 | return fc; |
699 | } | 717 | } |
718 | EXPORT_SYMBOL(p9_create_tcreate); | ||
700 | 719 | ||
701 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count) | 720 | struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count) |
702 | { | 721 | { |
703 | int size; | 722 | int size; |
704 | struct v9fs_fcall *fc; | 723 | struct p9_fcall *fc; |
705 | struct cbuf buffer; | 724 | struct cbuf buffer; |
706 | struct cbuf *bufp = &buffer; | 725 | struct cbuf *bufp = &buffer; |
707 | 726 | ||
708 | size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ | 727 | size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */ |
709 | fc = v9fs_create_common(bufp, size, TREAD); | 728 | fc = p9_create_common(bufp, size, P9_TREAD); |
729 | if (IS_ERR(fc)) | ||
730 | goto error; | ||
731 | |||
732 | p9_put_int32(bufp, fid, &fc->params.tread.fid); | ||
733 | p9_put_int64(bufp, offset, &fc->params.tread.offset); | ||
734 | p9_put_int32(bufp, count, &fc->params.tread.count); | ||
735 | |||
736 | if (buf_check_overflow(bufp)) { | ||
737 | kfree(fc); | ||
738 | fc = ERR_PTR(-ENOMEM); | ||
739 | } | ||
740 | error: | ||
741 | return fc; | ||
742 | } | ||
743 | EXPORT_SYMBOL(p9_create_tread); | ||
744 | |||
745 | struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count, | ||
746 | const char *data) | ||
747 | { | ||
748 | int size, err; | ||
749 | struct p9_fcall *fc; | ||
750 | struct cbuf buffer; | ||
751 | struct cbuf *bufp = &buffer; | ||
752 | |||
753 | /* fid[4] offset[8] count[4] data[count] */ | ||
754 | size = 4 + 8 + 4 + count; | ||
755 | fc = p9_create_common(bufp, size, P9_TWRITE); | ||
710 | if (IS_ERR(fc)) | 756 | if (IS_ERR(fc)) |
711 | goto error; | 757 | goto error; |
712 | 758 | ||
713 | v9fs_put_int32(bufp, fid, &fc->params.tread.fid); | 759 | p9_put_int32(bufp, fid, &fc->params.twrite.fid); |
714 | v9fs_put_int64(bufp, offset, &fc->params.tread.offset); | 760 | p9_put_int64(bufp, offset, &fc->params.twrite.offset); |
715 | v9fs_put_int32(bufp, count, &fc->params.tread.count); | 761 | p9_put_int32(bufp, count, &fc->params.twrite.count); |
762 | err = p9_put_data(bufp, data, count, &fc->params.twrite.data); | ||
763 | if (err) { | ||
764 | kfree(fc); | ||
765 | fc = ERR_PTR(err); | ||
766 | } | ||
716 | 767 | ||
717 | if (buf_check_overflow(bufp)) { | 768 | if (buf_check_overflow(bufp)) { |
718 | kfree(fc); | 769 | kfree(fc); |
719 | fc = ERR_PTR(-ENOMEM); | 770 | fc = ERR_PTR(-ENOMEM); |
720 | } | 771 | } |
721 | error: | 772 | error: |
722 | return fc; | 773 | return fc; |
723 | } | 774 | } |
775 | EXPORT_SYMBOL(p9_create_twrite); | ||
724 | 776 | ||
725 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | 777 | struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count, |
726 | const char __user * data) | 778 | const char __user *data) |
727 | { | 779 | { |
728 | int size, err; | 780 | int size, err; |
729 | struct v9fs_fcall *fc; | 781 | struct p9_fcall *fc; |
730 | struct cbuf buffer; | 782 | struct cbuf buffer; |
731 | struct cbuf *bufp = &buffer; | 783 | struct cbuf *bufp = &buffer; |
732 | 784 | ||
733 | size = 4 + 8 + 4 + count; /* fid[4] offset[8] count[4] data[count] */ | 785 | /* fid[4] offset[8] count[4] data[count] */ |
734 | fc = v9fs_create_common(bufp, size, TWRITE); | 786 | size = 4 + 8 + 4 + count; |
787 | fc = p9_create_common(bufp, size, P9_TWRITE); | ||
735 | if (IS_ERR(fc)) | 788 | if (IS_ERR(fc)) |
736 | goto error; | 789 | goto error; |
737 | 790 | ||
738 | v9fs_put_int32(bufp, fid, &fc->params.twrite.fid); | 791 | p9_put_int32(bufp, fid, &fc->params.twrite.fid); |
739 | v9fs_put_int64(bufp, offset, &fc->params.twrite.offset); | 792 | p9_put_int64(bufp, offset, &fc->params.twrite.offset); |
740 | v9fs_put_int32(bufp, count, &fc->params.twrite.count); | 793 | p9_put_int32(bufp, count, &fc->params.twrite.count); |
741 | err = v9fs_put_user_data(bufp, data, count, &fc->params.twrite.data); | 794 | err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data); |
742 | if (err) { | 795 | if (err) { |
743 | kfree(fc); | 796 | kfree(fc); |
744 | fc = ERR_PTR(err); | 797 | fc = ERR_PTR(err); |
@@ -748,98 +801,103 @@ struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | |||
748 | kfree(fc); | 801 | kfree(fc); |
749 | fc = ERR_PTR(-ENOMEM); | 802 | fc = ERR_PTR(-ENOMEM); |
750 | } | 803 | } |
751 | error: | 804 | error: |
752 | return fc; | 805 | return fc; |
753 | } | 806 | } |
807 | EXPORT_SYMBOL(p9_create_twrite_u); | ||
754 | 808 | ||
755 | struct v9fs_fcall *v9fs_create_tclunk(u32 fid) | 809 | struct p9_fcall *p9_create_tclunk(u32 fid) |
756 | { | 810 | { |
757 | int size; | 811 | int size; |
758 | struct v9fs_fcall *fc; | 812 | struct p9_fcall *fc; |
759 | struct cbuf buffer; | 813 | struct cbuf buffer; |
760 | struct cbuf *bufp = &buffer; | 814 | struct cbuf *bufp = &buffer; |
761 | 815 | ||
762 | size = 4; /* fid[4] */ | 816 | size = 4; /* fid[4] */ |
763 | fc = v9fs_create_common(bufp, size, TCLUNK); | 817 | fc = p9_create_common(bufp, size, P9_TCLUNK); |
764 | if (IS_ERR(fc)) | 818 | if (IS_ERR(fc)) |
765 | goto error; | 819 | goto error; |
766 | 820 | ||
767 | v9fs_put_int32(bufp, fid, &fc->params.tclunk.fid); | 821 | p9_put_int32(bufp, fid, &fc->params.tclunk.fid); |
768 | 822 | ||
769 | if (buf_check_overflow(bufp)) { | 823 | if (buf_check_overflow(bufp)) { |
770 | kfree(fc); | 824 | kfree(fc); |
771 | fc = ERR_PTR(-ENOMEM); | 825 | fc = ERR_PTR(-ENOMEM); |
772 | } | 826 | } |
773 | error: | 827 | error: |
774 | return fc; | 828 | return fc; |
775 | } | 829 | } |
830 | EXPORT_SYMBOL(p9_create_tclunk); | ||
776 | 831 | ||
777 | struct v9fs_fcall *v9fs_create_tremove(u32 fid) | 832 | struct p9_fcall *p9_create_tremove(u32 fid) |
778 | { | 833 | { |
779 | int size; | 834 | int size; |
780 | struct v9fs_fcall *fc; | 835 | struct p9_fcall *fc; |
781 | struct cbuf buffer; | 836 | struct cbuf buffer; |
782 | struct cbuf *bufp = &buffer; | 837 | struct cbuf *bufp = &buffer; |
783 | 838 | ||
784 | size = 4; /* fid[4] */ | 839 | size = 4; /* fid[4] */ |
785 | fc = v9fs_create_common(bufp, size, TREMOVE); | 840 | fc = p9_create_common(bufp, size, P9_TREMOVE); |
786 | if (IS_ERR(fc)) | 841 | if (IS_ERR(fc)) |
787 | goto error; | 842 | goto error; |
788 | 843 | ||
789 | v9fs_put_int32(bufp, fid, &fc->params.tremove.fid); | 844 | p9_put_int32(bufp, fid, &fc->params.tremove.fid); |
790 | 845 | ||
791 | if (buf_check_overflow(bufp)) { | 846 | if (buf_check_overflow(bufp)) { |
792 | kfree(fc); | 847 | kfree(fc); |
793 | fc = ERR_PTR(-ENOMEM); | 848 | fc = ERR_PTR(-ENOMEM); |
794 | } | 849 | } |
795 | error: | 850 | error: |
796 | return fc; | 851 | return fc; |
797 | } | 852 | } |
853 | EXPORT_SYMBOL(p9_create_tremove); | ||
798 | 854 | ||
799 | struct v9fs_fcall *v9fs_create_tstat(u32 fid) | 855 | struct p9_fcall *p9_create_tstat(u32 fid) |
800 | { | 856 | { |
801 | int size; | 857 | int size; |
802 | struct v9fs_fcall *fc; | 858 | struct p9_fcall *fc; |
803 | struct cbuf buffer; | 859 | struct cbuf buffer; |
804 | struct cbuf *bufp = &buffer; | 860 | struct cbuf *bufp = &buffer; |
805 | 861 | ||
806 | size = 4; /* fid[4] */ | 862 | size = 4; /* fid[4] */ |
807 | fc = v9fs_create_common(bufp, size, TSTAT); | 863 | fc = p9_create_common(bufp, size, P9_TSTAT); |
808 | if (IS_ERR(fc)) | 864 | if (IS_ERR(fc)) |
809 | goto error; | 865 | goto error; |
810 | 866 | ||
811 | v9fs_put_int32(bufp, fid, &fc->params.tstat.fid); | 867 | p9_put_int32(bufp, fid, &fc->params.tstat.fid); |
812 | 868 | ||
813 | if (buf_check_overflow(bufp)) { | 869 | if (buf_check_overflow(bufp)) { |
814 | kfree(fc); | 870 | kfree(fc); |
815 | fc = ERR_PTR(-ENOMEM); | 871 | fc = ERR_PTR(-ENOMEM); |
816 | } | 872 | } |
817 | error: | 873 | error: |
818 | return fc; | 874 | return fc; |
819 | } | 875 | } |
876 | EXPORT_SYMBOL(p9_create_tstat); | ||
820 | 877 | ||
821 | struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat, | 878 | struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat, |
822 | int extended) | 879 | int dotu) |
823 | { | 880 | { |
824 | int size, statsz; | 881 | int size, statsz; |
825 | struct v9fs_fcall *fc; | 882 | struct p9_fcall *fc; |
826 | struct cbuf buffer; | 883 | struct cbuf buffer; |
827 | struct cbuf *bufp = &buffer; | 884 | struct cbuf *bufp = &buffer; |
828 | 885 | ||
829 | statsz = v9fs_size_wstat(wstat, extended); | 886 | statsz = p9_size_wstat(wstat, dotu); |
830 | size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ | 887 | size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */ |
831 | fc = v9fs_create_common(bufp, size, TWSTAT); | 888 | fc = p9_create_common(bufp, size, P9_TWSTAT); |
832 | if (IS_ERR(fc)) | 889 | if (IS_ERR(fc)) |
833 | goto error; | 890 | goto error; |
834 | 891 | ||
835 | v9fs_put_int32(bufp, fid, &fc->params.twstat.fid); | 892 | p9_put_int32(bufp, fid, &fc->params.twstat.fid); |
836 | buf_put_int16(bufp, statsz + 2); | 893 | buf_put_int16(bufp, statsz + 2); |
837 | v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended); | 894 | p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu); |
838 | 895 | ||
839 | if (buf_check_overflow(bufp)) { | 896 | if (buf_check_overflow(bufp)) { |
840 | kfree(fc); | 897 | kfree(fc); |
841 | fc = ERR_PTR(-ENOMEM); | 898 | fc = ERR_PTR(-ENOMEM); |
842 | } | 899 | } |
843 | error: | 900 | error: |
844 | return fc; | 901 | return fc; |
845 | } | 902 | } |
903 | EXPORT_SYMBOL(p9_create_twstat); | ||
diff --git a/fs/9p/error.h b/net/9p/error.c index 5f3ca522b31..ab2458b6c90 100644 --- a/fs/9p/error.h +++ b/net/9p/error.c | |||
@@ -1,12 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/error.h | 2 | * linux/fs/9p/error.c |
3 | * | 3 | * |
4 | * Huge Nasty Error Table | 4 | * Error string handling |
5 | * | 5 | * |
6 | * Plan 9 uses error strings, Unix uses error numbers. This table tries to | 6 | * Plan 9 uses error strings, Unix uses error numbers. These functions |
7 | * match UNIX strings and Plan 9 strings to unix error numbers. It is used | 7 | * try to help manage that and provide for dynamically adding error |
8 | * to preload the dynamic error table which can also track user-specific error | 8 | * mappings. |
9 | * strings. | ||
10 | * | 9 | * |
11 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | 10 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> |
12 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | 11 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> |
@@ -28,8 +27,11 @@ | |||
28 | * | 27 | * |
29 | */ | 28 | */ |
30 | 29 | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/list.h> | ||
32 | #include <linux/jhash.h> | ||
31 | #include <linux/errno.h> | 33 | #include <linux/errno.h> |
32 | #include <asm/errno.h> | 34 | #include <net/9p/9p.h> |
33 | 35 | ||
34 | struct errormap { | 36 | struct errormap { |
35 | char *name; | 37 | char *name; |
@@ -174,4 +176,65 @@ static struct errormap errmap[] = { | |||
174 | {NULL, -1} | 176 | {NULL, -1} |
175 | }; | 177 | }; |
176 | 178 | ||
177 | extern int v9fs_error_init(void); | 179 | /** |
180 | * p9_error_init - preload | ||
181 | * @errstr: error string | ||
182 | * | ||
183 | */ | ||
184 | |||
185 | int p9_error_init(void) | ||
186 | { | ||
187 | struct errormap *c; | ||
188 | int bucket; | ||
189 | |||
190 | /* initialize hash table */ | ||
191 | for (bucket = 0; bucket < ERRHASHSZ; bucket++) | ||
192 | INIT_HLIST_HEAD(&hash_errmap[bucket]); | ||
193 | |||
194 | /* load initial error map into hash table */ | ||
195 | for (c = errmap; c->name != NULL; c++) { | ||
196 | c->namelen = strlen(c->name); | ||
197 | bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ; | ||
198 | INIT_HLIST_NODE(&c->list); | ||
199 | hlist_add_head(&c->list, &hash_errmap[bucket]); | ||
200 | } | ||
201 | |||
202 | return 1; | ||
203 | } | ||
204 | EXPORT_SYMBOL(p9_error_init); | ||
205 | |||
206 | /** | ||
207 | * errstr2errno - convert error string to error number | ||
208 | * @errstr: error string | ||
209 | * | ||
210 | */ | ||
211 | |||
212 | int p9_errstr2errno(char *errstr, int len) | ||
213 | { | ||
214 | int errno; | ||
215 | struct hlist_node *p; | ||
216 | struct errormap *c; | ||
217 | int bucket; | ||
218 | |||
219 | errno = 0; | ||
220 | p = NULL; | ||
221 | c = NULL; | ||
222 | bucket = jhash(errstr, len, 0) % ERRHASHSZ; | ||
223 | hlist_for_each_entry(c, p, &hash_errmap[bucket], list) { | ||
224 | if (c->namelen == len && !memcmp(c->name, errstr, len)) { | ||
225 | errno = c->val; | ||
226 | break; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | if (errno == 0) { | ||
231 | /* TODO: if error isn't found, add it dynamically */ | ||
232 | errstr[len] = 0; | ||
233 | printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, | ||
234 | errstr); | ||
235 | errno = 1; | ||
236 | } | ||
237 | |||
238 | return -errno; | ||
239 | } | ||
240 | EXPORT_SYMBOL(p9_errstr2errno); | ||
diff --git a/fs/9p/fcprint.c b/net/9p/fcprint.c index 34b96114a28..b1ae8ec57d5 100644 --- a/fs/9p/fcprint.c +++ b/net/9p/fcprint.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/fcprint.c | 2 | * net/9p/fcprint.c |
3 | * | 3 | * |
4 | * Print 9P call. | 4 | * Print 9P call. |
5 | * | 5 | * |
@@ -25,61 +25,59 @@ | |||
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <net/9p/9p.h> | ||
28 | 29 | ||
29 | #include "debug.h" | 30 | #ifdef CONFIG_NET_9P_DEBUG |
30 | #include "v9fs.h" | ||
31 | #include "9p.h" | ||
32 | #include "mux.h" | ||
33 | 31 | ||
34 | static int | 32 | static int |
35 | v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q) | 33 | p9_printqid(char *buf, int buflen, struct p9_qid *q) |
36 | { | 34 | { |
37 | int n; | 35 | int n; |
38 | char b[10]; | 36 | char b[10]; |
39 | 37 | ||
40 | n = 0; | 38 | n = 0; |
41 | if (q->type & V9FS_QTDIR) | 39 | if (q->type & P9_QTDIR) |
42 | b[n++] = 'd'; | 40 | b[n++] = 'd'; |
43 | if (q->type & V9FS_QTAPPEND) | 41 | if (q->type & P9_QTAPPEND) |
44 | b[n++] = 'a'; | 42 | b[n++] = 'a'; |
45 | if (q->type & V9FS_QTAUTH) | 43 | if (q->type & P9_QTAUTH) |
46 | b[n++] = 'A'; | 44 | b[n++] = 'A'; |
47 | if (q->type & V9FS_QTEXCL) | 45 | if (q->type & P9_QTEXCL) |
48 | b[n++] = 'l'; | 46 | b[n++] = 'l'; |
49 | if (q->type & V9FS_QTTMP) | 47 | if (q->type & P9_QTTMP) |
50 | b[n++] = 't'; | 48 | b[n++] = 't'; |
51 | if (q->type & V9FS_QTSYMLINK) | 49 | if (q->type & P9_QTSYMLINK) |
52 | b[n++] = 'L'; | 50 | b[n++] = 'L'; |
53 | b[n] = '\0'; | 51 | b[n] = '\0'; |
54 | 52 | ||
55 | return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path, | 53 | return scnprintf(buf, buflen, "(%.16llx %x %s)", |
56 | q->version, b); | 54 | (long long int) q->path, q->version, b); |
57 | } | 55 | } |
58 | 56 | ||
59 | static int | 57 | static int |
60 | v9fs_printperm(char *buf, int buflen, int perm) | 58 | p9_printperm(char *buf, int buflen, int perm) |
61 | { | 59 | { |
62 | int n; | 60 | int n; |
63 | char b[15]; | 61 | char b[15]; |
64 | 62 | ||
65 | n = 0; | 63 | n = 0; |
66 | if (perm & V9FS_DMDIR) | 64 | if (perm & P9_DMDIR) |
67 | b[n++] = 'd'; | 65 | b[n++] = 'd'; |
68 | if (perm & V9FS_DMAPPEND) | 66 | if (perm & P9_DMAPPEND) |
69 | b[n++] = 'a'; | 67 | b[n++] = 'a'; |
70 | if (perm & V9FS_DMAUTH) | 68 | if (perm & P9_DMAUTH) |
71 | b[n++] = 'A'; | 69 | b[n++] = 'A'; |
72 | if (perm & V9FS_DMEXCL) | 70 | if (perm & P9_DMEXCL) |
73 | b[n++] = 'l'; | 71 | b[n++] = 'l'; |
74 | if (perm & V9FS_DMTMP) | 72 | if (perm & P9_DMTMP) |
75 | b[n++] = 't'; | 73 | b[n++] = 't'; |
76 | if (perm & V9FS_DMDEVICE) | 74 | if (perm & P9_DMDEVICE) |
77 | b[n++] = 'D'; | 75 | b[n++] = 'D'; |
78 | if (perm & V9FS_DMSOCKET) | 76 | if (perm & P9_DMSOCKET) |
79 | b[n++] = 'S'; | 77 | b[n++] = 'S'; |
80 | if (perm & V9FS_DMNAMEDPIPE) | 78 | if (perm & P9_DMNAMEDPIPE) |
81 | b[n++] = 'P'; | 79 | b[n++] = 'P'; |
82 | if (perm & V9FS_DMSYMLINK) | 80 | if (perm & P9_DMSYMLINK) |
83 | b[n++] = 'L'; | 81 | b[n++] = 'L'; |
84 | b[n] = '\0'; | 82 | b[n] = '\0'; |
85 | 83 | ||
@@ -87,7 +85,7 @@ v9fs_printperm(char *buf, int buflen, int perm) | |||
87 | } | 85 | } |
88 | 86 | ||
89 | static int | 87 | static int |
90 | v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | 88 | p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended) |
91 | { | 89 | { |
92 | int n; | 90 | int n; |
93 | 91 | ||
@@ -105,9 +103,9 @@ v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | |||
105 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); | 103 | n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid); |
106 | 104 | ||
107 | n += scnprintf(buf+n, buflen-n, " q "); | 105 | n += scnprintf(buf+n, buflen-n, " q "); |
108 | n += v9fs_printqid(buf+n, buflen-n, &st->qid); | 106 | n += p9_printqid(buf+n, buflen-n, &st->qid); |
109 | n += scnprintf(buf+n, buflen-n, " m "); | 107 | n += scnprintf(buf+n, buflen-n, " m "); |
110 | n += v9fs_printperm(buf+n, buflen-n, st->mode); | 108 | n += p9_printperm(buf+n, buflen-n, st->mode); |
111 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", | 109 | n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld", |
112 | st->atime, st->mtime, (long long int) st->length); | 110 | st->atime, st->mtime, (long long int) st->length); |
113 | 111 | ||
@@ -119,7 +117,7 @@ v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended) | |||
119 | } | 117 | } |
120 | 118 | ||
121 | static int | 119 | static int |
122 | v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) | 120 | p9_dumpdata(char *buf, int buflen, u8 *data, int datalen) |
123 | { | 121 | { |
124 | int i, n; | 122 | int i, n; |
125 | 123 | ||
@@ -139,13 +137,13 @@ v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen) | |||
139 | } | 137 | } |
140 | 138 | ||
141 | static int | 139 | static int |
142 | v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) | 140 | p9_printdata(char *buf, int buflen, u8 *data, int datalen) |
143 | { | 141 | { |
144 | return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); | 142 | return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16); |
145 | } | 143 | } |
146 | 144 | ||
147 | int | 145 | int |
148 | v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | 146 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) |
149 | { | 147 | { |
150 | int i, ret, type, tag; | 148 | int i, ret, type, tag; |
151 | 149 | ||
@@ -157,21 +155,23 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
157 | 155 | ||
158 | ret = 0; | 156 | ret = 0; |
159 | switch (type) { | 157 | switch (type) { |
160 | case TVERSION: | 158 | case P9_TVERSION: |
161 | ret += scnprintf(buf+ret, buflen-ret, | 159 | ret += scnprintf(buf+ret, buflen-ret, |
162 | "Tversion tag %u msize %u version '%.*s'", tag, | 160 | "Tversion tag %u msize %u version '%.*s'", tag, |
163 | fc->params.tversion.msize, fc->params.tversion.version.len, | 161 | fc->params.tversion.msize, |
164 | fc->params.tversion.version.str); | 162 | fc->params.tversion.version.len, |
163 | fc->params.tversion.version.str); | ||
165 | break; | 164 | break; |
166 | 165 | ||
167 | case RVERSION: | 166 | case P9_RVERSION: |
168 | ret += scnprintf(buf+ret, buflen-ret, | 167 | ret += scnprintf(buf+ret, buflen-ret, |
169 | "Rversion tag %u msize %u version '%.*s'", tag, | 168 | "Rversion tag %u msize %u version '%.*s'", tag, |
170 | fc->params.rversion.msize, fc->params.rversion.version.len, | 169 | fc->params.rversion.msize, |
171 | fc->params.rversion.version.str); | 170 | fc->params.rversion.version.len, |
171 | fc->params.rversion.version.str); | ||
172 | break; | 172 | break; |
173 | 173 | ||
174 | case TAUTH: | 174 | case P9_TAUTH: |
175 | ret += scnprintf(buf+ret, buflen-ret, | 175 | ret += scnprintf(buf+ret, buflen-ret, |
176 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, | 176 | "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag, |
177 | fc->params.tauth.afid, fc->params.tauth.uname.len, | 177 | fc->params.tauth.afid, fc->params.tauth.uname.len, |
@@ -179,93 +179,97 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
179 | fc->params.tauth.aname.str); | 179 | fc->params.tauth.aname.str); |
180 | break; | 180 | break; |
181 | 181 | ||
182 | case RAUTH: | 182 | case P9_RAUTH: |
183 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); | 183 | ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag); |
184 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); | 184 | p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid); |
185 | break; | 185 | break; |
186 | 186 | ||
187 | case TATTACH: | 187 | case P9_TATTACH: |
188 | ret += scnprintf(buf+ret, buflen-ret, | 188 | ret += scnprintf(buf+ret, buflen-ret, |
189 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", | 189 | "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag, |
190 | tag, fc->params.tattach.fid, fc->params.tattach.afid, | 190 | fc->params.tattach.fid, fc->params.tattach.afid, |
191 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, | 191 | fc->params.tattach.uname.len, fc->params.tattach.uname.str, |
192 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); | 192 | fc->params.tattach.aname.len, fc->params.tattach.aname.str); |
193 | break; | 193 | break; |
194 | 194 | ||
195 | case RATTACH: | 195 | case P9_RATTACH: |
196 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag); | 196 | ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", |
197 | v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | 197 | tag); |
198 | p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid); | ||
198 | break; | 199 | break; |
199 | 200 | ||
200 | case RERROR: | 201 | case P9_RERROR: |
201 | ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'", | 202 | ret += scnprintf(buf+ret, buflen-ret, |
202 | tag, fc->params.rerror.error.len, | 203 | "Rerror tag %u ename '%.*s'", tag, |
203 | fc->params.rerror.error.str); | 204 | fc->params.rerror.error.len, |
205 | fc->params.rerror.error.str); | ||
204 | if (extended) | 206 | if (extended) |
205 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", | 207 | ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n", |
206 | fc->params.rerror.errno); | 208 | fc->params.rerror.errno); |
207 | break; | 209 | break; |
208 | 210 | ||
209 | case TFLUSH: | 211 | case P9_TFLUSH: |
210 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", | 212 | ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u", |
211 | tag, fc->params.tflush.oldtag); | 213 | tag, fc->params.tflush.oldtag); |
212 | break; | 214 | break; |
213 | 215 | ||
214 | case RFLUSH: | 216 | case P9_RFLUSH: |
215 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); | 217 | ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag); |
216 | break; | 218 | break; |
217 | 219 | ||
218 | case TWALK: | 220 | case P9_TWALK: |
219 | ret += scnprintf(buf+ret, buflen-ret, | 221 | ret += scnprintf(buf+ret, buflen-ret, |
220 | "Twalk tag %u fid %d newfid %d nwname %d", tag, | 222 | "Twalk tag %u fid %d newfid %d nwname %d", tag, |
221 | fc->params.twalk.fid, fc->params.twalk.newfid, | 223 | fc->params.twalk.fid, fc->params.twalk.newfid, |
222 | fc->params.twalk.nwname); | 224 | fc->params.twalk.nwname); |
223 | for(i = 0; i < fc->params.twalk.nwname; i++) | 225 | for (i = 0; i < fc->params.twalk.nwname; i++) |
224 | ret += scnprintf(buf+ret, buflen-ret," '%.*s'", | 226 | ret += scnprintf(buf+ret, buflen-ret, " '%.*s'", |
225 | fc->params.twalk.wnames[i].len, | 227 | fc->params.twalk.wnames[i].len, |
226 | fc->params.twalk.wnames[i].str); | 228 | fc->params.twalk.wnames[i].str); |
227 | break; | 229 | break; |
228 | 230 | ||
229 | case RWALK: | 231 | case P9_RWALK: |
230 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", | 232 | ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d", |
231 | tag, fc->params.rwalk.nwqid); | 233 | tag, fc->params.rwalk.nwqid); |
232 | for(i = 0; i < fc->params.rwalk.nwqid; i++) | 234 | for (i = 0; i < fc->params.rwalk.nwqid; i++) |
233 | ret += v9fs_printqid(buf+ret, buflen-ret, | 235 | ret += p9_printqid(buf+ret, buflen-ret, |
234 | &fc->params.rwalk.wqids[i]); | 236 | &fc->params.rwalk.wqids[i]); |
235 | break; | 237 | break; |
236 | 238 | ||
237 | case TOPEN: | 239 | case P9_TOPEN: |
238 | ret += scnprintf(buf+ret, buflen-ret, | 240 | ret += scnprintf(buf+ret, buflen-ret, |
239 | "Topen tag %u fid %d mode %d", tag, | 241 | "Topen tag %u fid %d mode %d", tag, |
240 | fc->params.topen.fid, fc->params.topen.mode); | 242 | fc->params.topen.fid, fc->params.topen.mode); |
241 | break; | 243 | break; |
242 | 244 | ||
243 | case ROPEN: | 245 | case P9_ROPEN: |
244 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); | 246 | ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag); |
245 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); | 247 | ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid); |
246 | ret += scnprintf(buf+ret, buflen-ret," iounit %d", | 248 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
247 | fc->params.ropen.iounit); | 249 | fc->params.ropen.iounit); |
248 | break; | 250 | break; |
249 | 251 | ||
250 | case TCREATE: | 252 | case P9_TCREATE: |
251 | ret += scnprintf(buf+ret, buflen-ret, | 253 | ret += scnprintf(buf+ret, buflen-ret, |
252 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, | 254 | "Tcreate tag %u fid %d name '%.*s' perm ", tag, |
253 | fc->params.tcreate.fid, fc->params.tcreate.name.len, | 255 | fc->params.tcreate.fid, fc->params.tcreate.name.len, |
254 | fc->params.tcreate.name.str); | 256 | fc->params.tcreate.name.str); |
255 | 257 | ||
256 | ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm); | 258 | ret += p9_printperm(buf+ret, buflen-ret, |
259 | fc->params.tcreate.perm); | ||
257 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", | 260 | ret += scnprintf(buf+ret, buflen-ret, " mode %d", |
258 | fc->params.tcreate.mode); | 261 | fc->params.tcreate.mode); |
259 | break; | 262 | break; |
260 | 263 | ||
261 | case RCREATE: | 264 | case P9_RCREATE: |
262 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); | 265 | ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag); |
263 | ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid); | 266 | ret += p9_printqid(buf+ret, buflen-ret, |
267 | &fc->params.rcreate.qid); | ||
264 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", | 268 | ret += scnprintf(buf+ret, buflen-ret, " iounit %d", |
265 | fc->params.rcreate.iounit); | 269 | fc->params.rcreate.iounit); |
266 | break; | 270 | break; |
267 | 271 | ||
268 | case TREAD: | 272 | case P9_TREAD: |
269 | ret += scnprintf(buf+ret, buflen-ret, | 273 | ret += scnprintf(buf+ret, buflen-ret, |
270 | "Tread tag %u fid %d offset %lld count %u", tag, | 274 | "Tread tag %u fid %d offset %lld count %u", tag, |
271 | fc->params.tread.fid, | 275 | fc->params.tread.fid, |
@@ -273,66 +277,66 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
273 | fc->params.tread.count); | 277 | fc->params.tread.count); |
274 | break; | 278 | break; |
275 | 279 | ||
276 | case RREAD: | 280 | case P9_RREAD: |
277 | ret += scnprintf(buf+ret, buflen-ret, | 281 | ret += scnprintf(buf+ret, buflen-ret, |
278 | "Rread tag %u count %u data ", tag, | 282 | "Rread tag %u count %u data ", tag, |
279 | fc->params.rread.count); | 283 | fc->params.rread.count); |
280 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data, | 284 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data, |
281 | fc->params.rread.count); | 285 | fc->params.rread.count); |
282 | break; | 286 | break; |
283 | 287 | ||
284 | case TWRITE: | 288 | case P9_TWRITE: |
285 | ret += scnprintf(buf+ret, buflen-ret, | 289 | ret += scnprintf(buf+ret, buflen-ret, |
286 | "Twrite tag %u fid %d offset %lld count %u data ", | 290 | "Twrite tag %u fid %d offset %lld count %u data ", |
287 | tag, fc->params.twrite.fid, | 291 | tag, fc->params.twrite.fid, |
288 | (long long int) fc->params.twrite.offset, | 292 | (long long int) fc->params.twrite.offset, |
289 | fc->params.twrite.count); | 293 | fc->params.twrite.count); |
290 | ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data, | 294 | ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data, |
291 | fc->params.twrite.count); | 295 | fc->params.twrite.count); |
292 | break; | 296 | break; |
293 | 297 | ||
294 | case RWRITE: | 298 | case P9_RWRITE: |
295 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", | 299 | ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u", |
296 | tag, fc->params.rwrite.count); | 300 | tag, fc->params.rwrite.count); |
297 | break; | 301 | break; |
298 | 302 | ||
299 | case TCLUNK: | 303 | case P9_TCLUNK: |
300 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", | 304 | ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d", |
301 | tag, fc->params.tclunk.fid); | 305 | tag, fc->params.tclunk.fid); |
302 | break; | 306 | break; |
303 | 307 | ||
304 | case RCLUNK: | 308 | case P9_RCLUNK: |
305 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); | 309 | ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag); |
306 | break; | 310 | break; |
307 | 311 | ||
308 | case TREMOVE: | 312 | case P9_TREMOVE: |
309 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", | 313 | ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d", |
310 | tag, fc->params.tremove.fid); | 314 | tag, fc->params.tremove.fid); |
311 | break; | 315 | break; |
312 | 316 | ||
313 | case RREMOVE: | 317 | case P9_RREMOVE: |
314 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); | 318 | ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag); |
315 | break; | 319 | break; |
316 | 320 | ||
317 | case TSTAT: | 321 | case P9_TSTAT: |
318 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", | 322 | ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d", |
319 | tag, fc->params.tstat.fid); | 323 | tag, fc->params.tstat.fid); |
320 | break; | 324 | break; |
321 | 325 | ||
322 | case RSTAT: | 326 | case P9_RSTAT: |
323 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); | 327 | ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag); |
324 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, | 328 | ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat, |
325 | extended); | 329 | extended); |
326 | break; | 330 | break; |
327 | 331 | ||
328 | case TWSTAT: | 332 | case P9_TWSTAT: |
329 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", | 333 | ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ", |
330 | tag, fc->params.twstat.fid); | 334 | tag, fc->params.twstat.fid); |
331 | ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat, | 335 | ret += p9_printstat(buf+ret, buflen-ret, |
332 | extended); | 336 | &fc->params.twstat.stat, extended); |
333 | break; | 337 | break; |
334 | 338 | ||
335 | case RWSTAT: | 339 | case P9_RWSTAT: |
336 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); | 340 | ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag); |
337 | break; | 341 | break; |
338 | 342 | ||
@@ -343,3 +347,12 @@ v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended) | |||
343 | 347 | ||
344 | return ret; | 348 | return ret; |
345 | } | 349 | } |
350 | |||
351 | #else | ||
352 | int | ||
353 | p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended) | ||
354 | { | ||
355 | return 0; | ||
356 | } | ||
357 | EXPORT_SYMBOL(p9_printfcall); | ||
358 | #endif /* CONFIG_NET_9P_DEBUG */ | ||
diff --git a/net/9p/mod.c b/net/9p/mod.c new file mode 100644 index 00000000000..4f9e1d2ac25 --- /dev/null +++ b/net/9p/mod.c | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * net/9p/9p.c | ||
3 | * | ||
4 | * 9P entry point | ||
5 | * | ||
6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/moduleparam.h> | ||
29 | #include <net/9p/9p.h> | ||
30 | |||
31 | #ifdef CONFIG_NET_9P_DEBUG | ||
32 | unsigned int p9_debug_level = 0; /* feature-rific global debug level */ | ||
33 | EXPORT_SYMBOL(p9_debug_level); | ||
34 | module_param_named(debug, p9_debug_level, uint, 0); | ||
35 | MODULE_PARM_DESC(debug, "9P debugging level"); | ||
36 | #endif | ||
37 | |||
38 | extern int p9_mux_global_init(void); | ||
39 | extern void p9_mux_global_exit(void); | ||
40 | extern int p9_sysctl_register(void); | ||
41 | extern void p9_sysctl_unregister(void); | ||
42 | |||
43 | /** | ||
44 | * v9fs_init - Initialize module | ||
45 | * | ||
46 | */ | ||
47 | static int __init init_p9(void) | ||
48 | { | ||
49 | int ret; | ||
50 | |||
51 | p9_error_init(); | ||
52 | printk(KERN_INFO "Installing 9P2000 support\n"); | ||
53 | ret = p9_mux_global_init(); | ||
54 | if (ret) { | ||
55 | printk(KERN_WARNING "9p: starting mux failed\n"); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | ret = p9_sysctl_register(); | ||
60 | if (ret) { | ||
61 | printk(KERN_WARNING "9p: registering sysctl failed\n"); | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * v9fs_init - shutdown module | ||
70 | * | ||
71 | */ | ||
72 | |||
73 | static void __exit exit_p9(void) | ||
74 | { | ||
75 | p9_sysctl_unregister(); | ||
76 | p9_mux_global_exit(); | ||
77 | } | ||
78 | |||
79 | module_init(init_p9) | ||
80 | module_exit(exit_p9) | ||
81 | |||
82 | MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); | ||
83 | MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); | ||
84 | MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); | ||
85 | MODULE_LICENSE("GPL"); | ||
diff --git a/fs/9p/mux.c b/net/9p/mux.c index c783874a9ca..acb038810f3 100644 --- a/fs/9p/mux.c +++ b/net/9p/mux.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/9p/mux.c | 2 | * net/9p/mux.c |
3 | * | 3 | * |
4 | * Protocol Multiplexer | 4 | * Protocol Multiplexer |
5 | * | 5 | * |
@@ -30,13 +30,9 @@ | |||
30 | #include <linux/kthread.h> | 30 | #include <linux/kthread.h> |
31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
32 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
33 | 33 | #include <net/9p/9p.h> | |
34 | #include "debug.h" | 34 | #include <net/9p/transport.h> |
35 | #include "v9fs.h" | 35 | #include <net/9p/conn.h> |
36 | #include "9p.h" | ||
37 | #include "conv.h" | ||
38 | #include "transport.h" | ||
39 | #include "mux.h" | ||
40 | 36 | ||
41 | #define ERREQFLUSH 1 | 37 | #define ERREQFLUSH 1 |
42 | #define SCHED_TIMEOUT 10 | 38 | #define SCHED_TIMEOUT 10 |
@@ -55,33 +51,33 @@ enum { | |||
55 | Flushed, | 51 | Flushed, |
56 | }; | 52 | }; |
57 | 53 | ||
58 | struct v9fs_mux_poll_task; | 54 | struct p9_mux_poll_task; |
59 | 55 | ||
60 | struct v9fs_req { | 56 | struct p9_req { |
61 | spinlock_t lock; | 57 | spinlock_t lock; /* protect request structure */ |
62 | int tag; | 58 | int tag; |
63 | struct v9fs_fcall *tcall; | 59 | struct p9_fcall *tcall; |
64 | struct v9fs_fcall *rcall; | 60 | struct p9_fcall *rcall; |
65 | int err; | 61 | int err; |
66 | v9fs_mux_req_callback cb; | 62 | p9_conn_req_callback cb; |
67 | void *cba; | 63 | void *cba; |
68 | int flush; | 64 | int flush; |
69 | struct list_head req_list; | 65 | struct list_head req_list; |
70 | }; | 66 | }; |
71 | 67 | ||
72 | struct v9fs_mux_data { | 68 | struct p9_conn { |
73 | spinlock_t lock; | 69 | spinlock_t lock; /* protect lock structure */ |
74 | struct list_head mux_list; | 70 | struct list_head mux_list; |
75 | struct v9fs_mux_poll_task *poll_task; | 71 | struct p9_mux_poll_task *poll_task; |
76 | int msize; | 72 | int msize; |
77 | unsigned char *extended; | 73 | unsigned char *extended; |
78 | struct v9fs_transport *trans; | 74 | struct p9_transport *trans; |
79 | struct v9fs_idpool tagpool; | 75 | struct p9_idpool *tagpool; |
80 | int err; | 76 | int err; |
81 | wait_queue_head_t equeue; | 77 | wait_queue_head_t equeue; |
82 | struct list_head req_list; | 78 | struct list_head req_list; |
83 | struct list_head unsent_req_list; | 79 | struct list_head unsent_req_list; |
84 | struct v9fs_fcall *rcall; | 80 | struct p9_fcall *rcall; |
85 | int rpos; | 81 | int rpos; |
86 | char *rbuf; | 82 | char *rbuf; |
87 | int wpos; | 83 | int wpos; |
@@ -95,44 +91,44 @@ struct v9fs_mux_data { | |||
95 | unsigned long wsched; | 91 | unsigned long wsched; |
96 | }; | 92 | }; |
97 | 93 | ||
98 | struct v9fs_mux_poll_task { | 94 | struct p9_mux_poll_task { |
99 | struct task_struct *task; | 95 | struct task_struct *task; |
100 | struct list_head mux_list; | 96 | struct list_head mux_list; |
101 | int muxnum; | 97 | int muxnum; |
102 | }; | 98 | }; |
103 | 99 | ||
104 | struct v9fs_mux_rpc { | 100 | struct p9_mux_rpc { |
105 | struct v9fs_mux_data *m; | 101 | struct p9_conn *m; |
106 | int err; | 102 | int err; |
107 | struct v9fs_fcall *tcall; | 103 | struct p9_fcall *tcall; |
108 | struct v9fs_fcall *rcall; | 104 | struct p9_fcall *rcall; |
109 | wait_queue_head_t wqueue; | 105 | wait_queue_head_t wqueue; |
110 | }; | 106 | }; |
111 | 107 | ||
112 | static int v9fs_poll_proc(void *); | 108 | static int p9_poll_proc(void *); |
113 | static void v9fs_read_work(struct work_struct *work); | 109 | static void p9_read_work(struct work_struct *work); |
114 | static void v9fs_write_work(struct work_struct *work); | 110 | static void p9_write_work(struct work_struct *work); |
115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 111 | static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, |
116 | poll_table * p); | 112 | poll_table * p); |
117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); | 113 | static u16 p9_mux_get_tag(struct p9_conn *); |
118 | static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16); | 114 | static void p9_mux_put_tag(struct p9_conn *, u16); |
119 | 115 | ||
120 | static DEFINE_MUTEX(v9fs_mux_task_lock); | 116 | static DEFINE_MUTEX(p9_mux_task_lock); |
121 | static struct workqueue_struct *v9fs_mux_wq; | 117 | static struct workqueue_struct *p9_mux_wq; |
122 | 118 | ||
123 | static int v9fs_mux_num; | 119 | static int p9_mux_num; |
124 | static int v9fs_mux_poll_task_num; | 120 | static int p9_mux_poll_task_num; |
125 | static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100]; | 121 | static struct p9_mux_poll_task p9_mux_poll_tasks[100]; |
126 | 122 | ||
127 | int v9fs_mux_global_init(void) | 123 | int p9_mux_global_init(void) |
128 | { | 124 | { |
129 | int i; | 125 | int i; |
130 | 126 | ||
131 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) | 127 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) |
132 | v9fs_mux_poll_tasks[i].task = NULL; | 128 | p9_mux_poll_tasks[i].task = NULL; |
133 | 129 | ||
134 | v9fs_mux_wq = create_workqueue("v9fs"); | 130 | p9_mux_wq = create_workqueue("v9fs"); |
135 | if (!v9fs_mux_wq) { | 131 | if (!p9_mux_wq) { |
136 | printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); | 132 | printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n"); |
137 | return -ENOMEM; | 133 | return -ENOMEM; |
138 | } | 134 | } |
@@ -140,114 +136,117 @@ int v9fs_mux_global_init(void) | |||
140 | return 0; | 136 | return 0; |
141 | } | 137 | } |
142 | 138 | ||
143 | void v9fs_mux_global_exit(void) | 139 | void p9_mux_global_exit(void) |
144 | { | 140 | { |
145 | destroy_workqueue(v9fs_mux_wq); | 141 | destroy_workqueue(p9_mux_wq); |
146 | } | 142 | } |
147 | 143 | ||
148 | /** | 144 | /** |
149 | * v9fs_mux_calc_poll_procs - calculates the number of polling procs | 145 | * p9_mux_calc_poll_procs - calculates the number of polling procs |
150 | * based on the number of mounted v9fs filesystems. | 146 | * based on the number of mounted v9fs filesystems. |
151 | * | 147 | * |
152 | * The current implementation returns sqrt of the number of mounts. | 148 | * The current implementation returns sqrt of the number of mounts. |
153 | */ | 149 | */ |
154 | static int v9fs_mux_calc_poll_procs(int muxnum) | 150 | static int p9_mux_calc_poll_procs(int muxnum) |
155 | { | 151 | { |
156 | int n; | 152 | int n; |
157 | 153 | ||
158 | if (v9fs_mux_poll_task_num) | 154 | if (p9_mux_poll_task_num) |
159 | n = muxnum / v9fs_mux_poll_task_num + | 155 | n = muxnum / p9_mux_poll_task_num + |
160 | (muxnum % v9fs_mux_poll_task_num ? 1 : 0); | 156 | (muxnum % p9_mux_poll_task_num ? 1 : 0); |
161 | else | 157 | else |
162 | n = 1; | 158 | n = 1; |
163 | 159 | ||
164 | if (n > ARRAY_SIZE(v9fs_mux_poll_tasks)) | 160 | if (n > ARRAY_SIZE(p9_mux_poll_tasks)) |
165 | n = ARRAY_SIZE(v9fs_mux_poll_tasks); | 161 | n = ARRAY_SIZE(p9_mux_poll_tasks); |
166 | 162 | ||
167 | return n; | 163 | return n; |
168 | } | 164 | } |
169 | 165 | ||
170 | static int v9fs_mux_poll_start(struct v9fs_mux_data *m) | 166 | static int p9_mux_poll_start(struct p9_conn *m) |
171 | { | 167 | { |
172 | int i, n; | 168 | int i, n; |
173 | struct v9fs_mux_poll_task *vpt, *vptlast; | 169 | struct p9_mux_poll_task *vpt, *vptlast; |
174 | struct task_struct *pproc; | 170 | struct task_struct *pproc; |
175 | 171 | ||
176 | dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num, | 172 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, p9_mux_num, |
177 | v9fs_mux_poll_task_num); | 173 | p9_mux_poll_task_num); |
178 | mutex_lock(&v9fs_mux_task_lock); | 174 | mutex_lock(&p9_mux_task_lock); |
179 | 175 | ||
180 | n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1); | 176 | n = p9_mux_calc_poll_procs(p9_mux_num + 1); |
181 | if (n > v9fs_mux_poll_task_num) { | 177 | if (n > p9_mux_poll_task_num) { |
182 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { | 178 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { |
183 | if (v9fs_mux_poll_tasks[i].task == NULL) { | 179 | if (p9_mux_poll_tasks[i].task == NULL) { |
184 | vpt = &v9fs_mux_poll_tasks[i]; | 180 | vpt = &p9_mux_poll_tasks[i]; |
185 | dprintk(DEBUG_MUX, "create proc %p\n", vpt); | 181 | P9_DPRINTK(P9_DEBUG_MUX, "create proc %p\n", |
186 | pproc = kthread_create(v9fs_poll_proc, vpt, | 182 | vpt); |
187 | "v9fs-poll"); | 183 | pproc = kthread_create(p9_poll_proc, vpt, |
184 | "v9fs-poll"); | ||
188 | 185 | ||
189 | if (!IS_ERR(pproc)) { | 186 | if (!IS_ERR(pproc)) { |
190 | vpt->task = pproc; | 187 | vpt->task = pproc; |
191 | INIT_LIST_HEAD(&vpt->mux_list); | 188 | INIT_LIST_HEAD(&vpt->mux_list); |
192 | vpt->muxnum = 0; | 189 | vpt->muxnum = 0; |
193 | v9fs_mux_poll_task_num++; | 190 | p9_mux_poll_task_num++; |
194 | wake_up_process(vpt->task); | 191 | wake_up_process(vpt->task); |
195 | } | 192 | } |
196 | break; | 193 | break; |
197 | } | 194 | } |
198 | } | 195 | } |
199 | 196 | ||
200 | if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) | 197 | if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) |
201 | dprintk(DEBUG_ERROR, "warning: no free poll slots\n"); | 198 | P9_DPRINTK(P9_DEBUG_ERROR, |
199 | "warning: no free poll slots\n"); | ||
202 | } | 200 | } |
203 | 201 | ||
204 | n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num + | 202 | n = (p9_mux_num + 1) / p9_mux_poll_task_num + |
205 | ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0); | 203 | ((p9_mux_num + 1) % p9_mux_poll_task_num ? 1 : 0); |
206 | 204 | ||
207 | vptlast = NULL; | 205 | vptlast = NULL; |
208 | for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) { | 206 | for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) { |
209 | vpt = &v9fs_mux_poll_tasks[i]; | 207 | vpt = &p9_mux_poll_tasks[i]; |
210 | if (vpt->task != NULL) { | 208 | if (vpt->task != NULL) { |
211 | vptlast = vpt; | 209 | vptlast = vpt; |
212 | if (vpt->muxnum < n) { | 210 | if (vpt->muxnum < n) { |
213 | dprintk(DEBUG_MUX, "put in proc %d\n", i); | 211 | P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); |
214 | list_add(&m->mux_list, &vpt->mux_list); | 212 | list_add(&m->mux_list, &vpt->mux_list); |
215 | vpt->muxnum++; | 213 | vpt->muxnum++; |
216 | m->poll_task = vpt; | 214 | m->poll_task = vpt; |
217 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 215 | memset(&m->poll_waddr, 0, |
218 | init_poll_funcptr(&m->pt, v9fs_pollwait); | 216 | sizeof(m->poll_waddr)); |
217 | init_poll_funcptr(&m->pt, p9_pollwait); | ||
219 | break; | 218 | break; |
220 | } | 219 | } |
221 | } | 220 | } |
222 | } | 221 | } |
223 | 222 | ||
224 | if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) { | 223 | if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) { |
225 | if (vptlast == NULL) | 224 | if (vptlast == NULL) |
226 | return -ENOMEM; | 225 | return -ENOMEM; |
227 | 226 | ||
228 | dprintk(DEBUG_MUX, "put in proc %d\n", i); | 227 | P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i); |
229 | list_add(&m->mux_list, &vptlast->mux_list); | 228 | list_add(&m->mux_list, &vptlast->mux_list); |
230 | vptlast->muxnum++; | 229 | vptlast->muxnum++; |
231 | m->poll_task = vptlast; | 230 | m->poll_task = vptlast; |
232 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 231 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
233 | init_poll_funcptr(&m->pt, v9fs_pollwait); | 232 | init_poll_funcptr(&m->pt, p9_pollwait); |
234 | } | 233 | } |
235 | 234 | ||
236 | v9fs_mux_num++; | 235 | p9_mux_num++; |
237 | mutex_unlock(&v9fs_mux_task_lock); | 236 | mutex_unlock(&p9_mux_task_lock); |
238 | 237 | ||
239 | return 0; | 238 | return 0; |
240 | } | 239 | } |
241 | 240 | ||
242 | static void v9fs_mux_poll_stop(struct v9fs_mux_data *m) | 241 | static void p9_mux_poll_stop(struct p9_conn *m) |
243 | { | 242 | { |
244 | int i; | 243 | int i; |
245 | struct v9fs_mux_poll_task *vpt; | 244 | struct p9_mux_poll_task *vpt; |
246 | 245 | ||
247 | mutex_lock(&v9fs_mux_task_lock); | 246 | mutex_lock(&p9_mux_task_lock); |
248 | vpt = m->poll_task; | 247 | vpt = m->poll_task; |
249 | list_del(&m->mux_list); | 248 | list_del(&m->mux_list); |
250 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { | 249 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { |
251 | if (m->poll_waddr[i] != NULL) { | 250 | if (m->poll_waddr[i] != NULL) { |
252 | remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]); | 251 | remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]); |
253 | m->poll_waddr[i] = NULL; | 252 | m->poll_waddr[i] = NULL; |
@@ -255,31 +254,31 @@ static void v9fs_mux_poll_stop(struct v9fs_mux_data *m) | |||
255 | } | 254 | } |
256 | vpt->muxnum--; | 255 | vpt->muxnum--; |
257 | if (!vpt->muxnum) { | 256 | if (!vpt->muxnum) { |
258 | dprintk(DEBUG_MUX, "destroy proc %p\n", vpt); | 257 | P9_DPRINTK(P9_DEBUG_MUX, "destroy proc %p\n", vpt); |
259 | kthread_stop(vpt->task); | 258 | kthread_stop(vpt->task); |
260 | vpt->task = NULL; | 259 | vpt->task = NULL; |
261 | v9fs_mux_poll_task_num--; | 260 | p9_mux_poll_task_num--; |
262 | } | 261 | } |
263 | v9fs_mux_num--; | 262 | p9_mux_num--; |
264 | mutex_unlock(&v9fs_mux_task_lock); | 263 | mutex_unlock(&p9_mux_task_lock); |
265 | } | 264 | } |
266 | 265 | ||
267 | /** | 266 | /** |
268 | * v9fs_mux_init - allocate and initialize the per-session mux data | 267 | * p9_conn_create - allocate and initialize the per-session mux data |
269 | * Creates the polling task if this is the first session. | 268 | * Creates the polling task if this is the first session. |
270 | * | 269 | * |
271 | * @trans - transport structure | 270 | * @trans - transport structure |
272 | * @msize - maximum message size | 271 | * @msize - maximum message size |
273 | * @extended - pointer to the extended flag | 272 | * @extended - pointer to the extended flag |
274 | */ | 273 | */ |
275 | struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | 274 | struct p9_conn *p9_conn_create(struct p9_transport *trans, int msize, |
276 | unsigned char *extended) | 275 | unsigned char *extended) |
277 | { | 276 | { |
278 | int i, n; | 277 | int i, n; |
279 | struct v9fs_mux_data *m, *mtmp; | 278 | struct p9_conn *m, *mtmp; |
280 | 279 | ||
281 | dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize); | 280 | P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, msize); |
282 | m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL); | 281 | m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); |
283 | if (!m) | 282 | if (!m) |
284 | return ERR_PTR(-ENOMEM); | 283 | return ERR_PTR(-ENOMEM); |
285 | 284 | ||
@@ -288,8 +287,12 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
288 | m->msize = msize; | 287 | m->msize = msize; |
289 | m->extended = extended; | 288 | m->extended = extended; |
290 | m->trans = trans; | 289 | m->trans = trans; |
291 | idr_init(&m->tagpool.pool); | 290 | m->tagpool = p9_idpool_create(); |
292 | init_MUTEX(&m->tagpool.lock); | 291 | if (!m->tagpool) { |
292 | kfree(m); | ||
293 | return ERR_PTR(PTR_ERR(m->tagpool)); | ||
294 | } | ||
295 | |||
293 | m->err = 0; | 296 | m->err = 0; |
294 | init_waitqueue_head(&m->equeue); | 297 | init_waitqueue_head(&m->equeue); |
295 | INIT_LIST_HEAD(&m->req_list); | 298 | INIT_LIST_HEAD(&m->req_list); |
@@ -299,29 +302,29 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
299 | m->rbuf = NULL; | 302 | m->rbuf = NULL; |
300 | m->wpos = m->wsize = 0; | 303 | m->wpos = m->wsize = 0; |
301 | m->wbuf = NULL; | 304 | m->wbuf = NULL; |
302 | INIT_WORK(&m->rq, v9fs_read_work); | 305 | INIT_WORK(&m->rq, p9_read_work); |
303 | INIT_WORK(&m->wq, v9fs_write_work); | 306 | INIT_WORK(&m->wq, p9_write_work); |
304 | m->wsched = 0; | 307 | m->wsched = 0; |
305 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 308 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
306 | m->poll_task = NULL; | 309 | m->poll_task = NULL; |
307 | n = v9fs_mux_poll_start(m); | 310 | n = p9_mux_poll_start(m); |
308 | if (n) | 311 | if (n) |
309 | return ERR_PTR(n); | 312 | return ERR_PTR(n); |
310 | 313 | ||
311 | n = trans->poll(trans, &m->pt); | 314 | n = trans->poll(trans, &m->pt); |
312 | if (n & POLLIN) { | 315 | if (n & POLLIN) { |
313 | dprintk(DEBUG_MUX, "mux %p can read\n", m); | 316 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); |
314 | set_bit(Rpending, &m->wsched); | 317 | set_bit(Rpending, &m->wsched); |
315 | } | 318 | } |
316 | 319 | ||
317 | if (n & POLLOUT) { | 320 | if (n & POLLOUT) { |
318 | dprintk(DEBUG_MUX, "mux %p can write\n", m); | 321 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); |
319 | set_bit(Wpending, &m->wsched); | 322 | set_bit(Wpending, &m->wsched); |
320 | } | 323 | } |
321 | 324 | ||
322 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { | 325 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { |
323 | if (IS_ERR(m->poll_waddr[i])) { | 326 | if (IS_ERR(m->poll_waddr[i])) { |
324 | v9fs_mux_poll_stop(m); | 327 | p9_mux_poll_stop(m); |
325 | mtmp = (void *)m->poll_waddr; /* the error code */ | 328 | mtmp = (void *)m->poll_waddr; /* the error code */ |
326 | kfree(m); | 329 | kfree(m); |
327 | m = mtmp; | 330 | m = mtmp; |
@@ -331,56 +334,58 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
331 | 334 | ||
332 | return m; | 335 | return m; |
333 | } | 336 | } |
337 | EXPORT_SYMBOL(p9_conn_create); | ||
334 | 338 | ||
335 | /** | 339 | /** |
336 | * v9fs_mux_destroy - cancels all pending requests and frees mux resources | 340 | * p9_mux_destroy - cancels all pending requests and frees mux resources |
337 | */ | 341 | */ |
338 | void v9fs_mux_destroy(struct v9fs_mux_data *m) | 342 | void p9_conn_destroy(struct p9_conn *m) |
339 | { | 343 | { |
340 | dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m, | 344 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, |
341 | m->mux_list.prev, m->mux_list.next); | 345 | m->mux_list.prev, m->mux_list.next); |
342 | v9fs_mux_cancel(m, -ECONNRESET); | 346 | p9_conn_cancel(m, -ECONNRESET); |
343 | 347 | ||
344 | if (!list_empty(&m->req_list)) { | 348 | if (!list_empty(&m->req_list)) { |
345 | /* wait until all processes waiting on this session exit */ | 349 | /* wait until all processes waiting on this session exit */ |
346 | dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n", | 350 | P9_DPRINTK(P9_DEBUG_MUX, |
347 | m); | 351 | "mux %p waiting for empty request queue\n", m); |
348 | wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); | 352 | wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000); |
349 | dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m, | 353 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m, |
350 | list_empty(&m->req_list)); | 354 | list_empty(&m->req_list)); |
351 | } | 355 | } |
352 | 356 | ||
353 | v9fs_mux_poll_stop(m); | 357 | p9_mux_poll_stop(m); |
354 | m->trans = NULL; | 358 | m->trans = NULL; |
355 | 359 | p9_idpool_destroy(m->tagpool); | |
356 | kfree(m); | 360 | kfree(m); |
357 | } | 361 | } |
362 | EXPORT_SYMBOL(p9_conn_destroy); | ||
358 | 363 | ||
359 | /** | 364 | /** |
360 | * v9fs_pollwait - called by files poll operation to add v9fs-poll task | 365 | * p9_pollwait - called by files poll operation to add v9fs-poll task |
361 | * to files wait queue | 366 | * to files wait queue |
362 | */ | 367 | */ |
363 | static void | 368 | static void |
364 | v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 369 | p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, |
365 | poll_table * p) | 370 | poll_table * p) |
366 | { | 371 | { |
367 | int i; | 372 | int i; |
368 | struct v9fs_mux_data *m; | 373 | struct p9_conn *m; |
369 | 374 | ||
370 | m = container_of(p, struct v9fs_mux_data, pt); | 375 | m = container_of(p, struct p9_conn, pt); |
371 | for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) | 376 | for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) |
372 | if (m->poll_waddr[i] == NULL) | 377 | if (m->poll_waddr[i] == NULL) |
373 | break; | 378 | break; |
374 | 379 | ||
375 | if (i >= ARRAY_SIZE(m->poll_waddr)) { | 380 | if (i >= ARRAY_SIZE(m->poll_waddr)) { |
376 | dprintk(DEBUG_ERROR, "not enough wait_address slots\n"); | 381 | P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n"); |
377 | return; | 382 | return; |
378 | } | 383 | } |
379 | 384 | ||
380 | m->poll_waddr[i] = wait_address; | 385 | m->poll_waddr[i] = wait_address; |
381 | 386 | ||
382 | if (!wait_address) { | 387 | if (!wait_address) { |
383 | dprintk(DEBUG_ERROR, "no wait_address\n"); | 388 | P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n"); |
384 | m->poll_waddr[i] = ERR_PTR(-EIO); | 389 | m->poll_waddr[i] = ERR_PTR(-EIO); |
385 | return; | 390 | return; |
386 | } | 391 | } |
@@ -390,9 +395,9 @@ v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | |||
390 | } | 395 | } |
391 | 396 | ||
392 | /** | 397 | /** |
393 | * v9fs_poll_mux - polls a mux and schedules read or write works if necessary | 398 | * p9_poll_mux - polls a mux and schedules read or write works if necessary |
394 | */ | 399 | */ |
395 | static void v9fs_poll_mux(struct v9fs_mux_data *m) | 400 | static void p9_poll_mux(struct p9_conn *m) |
396 | { | 401 | { |
397 | int n; | 402 | int n; |
398 | 403 | ||
@@ -401,69 +406,69 @@ static void v9fs_poll_mux(struct v9fs_mux_data *m) | |||
401 | 406 | ||
402 | n = m->trans->poll(m->trans, NULL); | 407 | n = m->trans->poll(m->trans, NULL); |
403 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { | 408 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { |
404 | dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n); | 409 | P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n); |
405 | if (n >= 0) | 410 | if (n >= 0) |
406 | n = -ECONNRESET; | 411 | n = -ECONNRESET; |
407 | v9fs_mux_cancel(m, n); | 412 | p9_conn_cancel(m, n); |
408 | } | 413 | } |
409 | 414 | ||
410 | if (n & POLLIN) { | 415 | if (n & POLLIN) { |
411 | set_bit(Rpending, &m->wsched); | 416 | set_bit(Rpending, &m->wsched); |
412 | dprintk(DEBUG_MUX, "mux %p can read\n", m); | 417 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m); |
413 | if (!test_and_set_bit(Rworksched, &m->wsched)) { | 418 | if (!test_and_set_bit(Rworksched, &m->wsched)) { |
414 | dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); | 419 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); |
415 | queue_work(v9fs_mux_wq, &m->rq); | 420 | queue_work(p9_mux_wq, &m->rq); |
416 | } | 421 | } |
417 | } | 422 | } |
418 | 423 | ||
419 | if (n & POLLOUT) { | 424 | if (n & POLLOUT) { |
420 | set_bit(Wpending, &m->wsched); | 425 | set_bit(Wpending, &m->wsched); |
421 | dprintk(DEBUG_MUX, "mux %p can write\n", m); | 426 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m); |
422 | if ((m->wsize || !list_empty(&m->unsent_req_list)) | 427 | if ((m->wsize || !list_empty(&m->unsent_req_list)) |
423 | && !test_and_set_bit(Wworksched, &m->wsched)) { | 428 | && !test_and_set_bit(Wworksched, &m->wsched)) { |
424 | dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); | 429 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); |
425 | queue_work(v9fs_mux_wq, &m->wq); | 430 | queue_work(p9_mux_wq, &m->wq); |
426 | } | 431 | } |
427 | } | 432 | } |
428 | } | 433 | } |
429 | 434 | ||
430 | /** | 435 | /** |
431 | * v9fs_poll_proc - polls all v9fs transports for new events and queues | 436 | * p9_poll_proc - polls all v9fs transports for new events and queues |
432 | * the appropriate work to the work queue | 437 | * the appropriate work to the work queue |
433 | */ | 438 | */ |
434 | static int v9fs_poll_proc(void *a) | 439 | static int p9_poll_proc(void *a) |
435 | { | 440 | { |
436 | struct v9fs_mux_data *m, *mtmp; | 441 | struct p9_conn *m, *mtmp; |
437 | struct v9fs_mux_poll_task *vpt; | 442 | struct p9_mux_poll_task *vpt; |
438 | 443 | ||
439 | vpt = a; | 444 | vpt = a; |
440 | dprintk(DEBUG_MUX, "start %p %p\n", current, vpt); | 445 | P9_DPRINTK(P9_DEBUG_MUX, "start %p %p\n", current, vpt); |
441 | while (!kthread_should_stop()) { | 446 | while (!kthread_should_stop()) { |
442 | set_current_state(TASK_INTERRUPTIBLE); | 447 | set_current_state(TASK_INTERRUPTIBLE); |
443 | 448 | ||
444 | list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { | 449 | list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) { |
445 | v9fs_poll_mux(m); | 450 | p9_poll_mux(m); |
446 | } | 451 | } |
447 | 452 | ||
448 | dprintk(DEBUG_MUX, "sleeping...\n"); | 453 | P9_DPRINTK(P9_DEBUG_MUX, "sleeping...\n"); |
449 | schedule_timeout(SCHED_TIMEOUT * HZ); | 454 | schedule_timeout(SCHED_TIMEOUT * HZ); |
450 | } | 455 | } |
451 | 456 | ||
452 | __set_current_state(TASK_RUNNING); | 457 | __set_current_state(TASK_RUNNING); |
453 | dprintk(DEBUG_MUX, "finish\n"); | 458 | P9_DPRINTK(P9_DEBUG_MUX, "finish\n"); |
454 | return 0; | 459 | return 0; |
455 | } | 460 | } |
456 | 461 | ||
457 | /** | 462 | /** |
458 | * v9fs_write_work - called when a transport can send some data | 463 | * p9_write_work - called when a transport can send some data |
459 | */ | 464 | */ |
460 | static void v9fs_write_work(struct work_struct *work) | 465 | static void p9_write_work(struct work_struct *work) |
461 | { | 466 | { |
462 | int n, err; | 467 | int n, err; |
463 | struct v9fs_mux_data *m; | 468 | struct p9_conn *m; |
464 | struct v9fs_req *req; | 469 | struct p9_req *req; |
465 | 470 | ||
466 | m = container_of(work, struct v9fs_mux_data, wq); | 471 | m = container_of(work, struct p9_conn, wq); |
467 | 472 | ||
468 | if (m->err < 0) { | 473 | if (m->err < 0) { |
469 | clear_bit(Wworksched, &m->wsched); | 474 | clear_bit(Wworksched, &m->wsched); |
@@ -478,7 +483,7 @@ static void v9fs_write_work(struct work_struct *work) | |||
478 | 483 | ||
479 | spin_lock(&m->lock); | 484 | spin_lock(&m->lock); |
480 | again: | 485 | again: |
481 | req = list_entry(m->unsent_req_list.next, struct v9fs_req, | 486 | req = list_entry(m->unsent_req_list.next, struct p9_req, |
482 | req_list); | 487 | req_list); |
483 | list_move_tail(&req->req_list, &m->req_list); | 488 | list_move_tail(&req->req_list, &m->req_list); |
484 | if (req->err == ERREQFLUSH) | 489 | if (req->err == ERREQFLUSH) |
@@ -487,21 +492,25 @@ again: | |||
487 | m->wbuf = req->tcall->sdata; | 492 | m->wbuf = req->tcall->sdata; |
488 | m->wsize = req->tcall->size; | 493 | m->wsize = req->tcall->size; |
489 | m->wpos = 0; | 494 | m->wpos = 0; |
490 | dump_data(m->wbuf, m->wsize); | ||
491 | spin_unlock(&m->lock); | 495 | spin_unlock(&m->lock); |
492 | } | 496 | } |
493 | 497 | ||
494 | dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize); | 498 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, |
499 | m->wsize); | ||
495 | clear_bit(Wpending, &m->wsched); | 500 | clear_bit(Wpending, &m->wsched); |
496 | err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); | 501 | err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos); |
497 | dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err); | 502 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err); |
498 | if (err == -EAGAIN) { | 503 | if (err == -EAGAIN) { |
499 | clear_bit(Wworksched, &m->wsched); | 504 | clear_bit(Wworksched, &m->wsched); |
500 | return; | 505 | return; |
501 | } | 506 | } |
502 | 507 | ||
503 | if (err <= 0) | 508 | if (err < 0) |
509 | goto error; | ||
510 | else if (err == 0) { | ||
511 | err = -EREMOTEIO; | ||
504 | goto error; | 512 | goto error; |
513 | } | ||
505 | 514 | ||
506 | m->wpos += err; | 515 | m->wpos += err; |
507 | if (m->wpos == m->wsize) | 516 | if (m->wpos == m->wsize) |
@@ -514,8 +523,8 @@ again: | |||
514 | n = m->trans->poll(m->trans, NULL); | 523 | n = m->trans->poll(m->trans, NULL); |
515 | 524 | ||
516 | if (n & POLLOUT) { | 525 | if (n & POLLOUT) { |
517 | dprintk(DEBUG_MUX, "schedule write work mux %p\n", m); | 526 | P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m); |
518 | queue_work(v9fs_mux_wq, &m->wq); | 527 | queue_work(p9_mux_wq, &m->wq); |
519 | } else | 528 | } else |
520 | clear_bit(Wworksched, &m->wsched); | 529 | clear_bit(Wworksched, &m->wsched); |
521 | } else | 530 | } else |
@@ -523,27 +532,28 @@ again: | |||
523 | 532 | ||
524 | return; | 533 | return; |
525 | 534 | ||
526 | error: | 535 | error: |
527 | v9fs_mux_cancel(m, err); | 536 | p9_conn_cancel(m, err); |
528 | clear_bit(Wworksched, &m->wsched); | 537 | clear_bit(Wworksched, &m->wsched); |
529 | } | 538 | } |
530 | 539 | ||
531 | static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 540 | static void process_request(struct p9_conn *m, struct p9_req *req) |
532 | { | 541 | { |
533 | int ecode; | 542 | int ecode; |
534 | struct v9fs_str *ename; | 543 | struct p9_str *ename; |
535 | 544 | ||
536 | if (!req->err && req->rcall->id == RERROR) { | 545 | if (!req->err && req->rcall->id == P9_RERROR) { |
537 | ecode = req->rcall->params.rerror.errno; | 546 | ecode = req->rcall->params.rerror.errno; |
538 | ename = &req->rcall->params.rerror.error; | 547 | ename = &req->rcall->params.rerror.error; |
539 | 548 | ||
540 | dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str); | 549 | P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len, |
550 | ename->str); | ||
541 | 551 | ||
542 | if (*m->extended) | 552 | if (*m->extended) |
543 | req->err = -ecode; | 553 | req->err = -ecode; |
544 | 554 | ||
545 | if (!req->err) { | 555 | if (!req->err) { |
546 | req->err = v9fs_errstr2errno(ename->str, ename->len); | 556 | req->err = p9_errstr2errno(ename->str, ename->len); |
547 | 557 | ||
548 | if (!req->err) { /* string match failed */ | 558 | if (!req->err) { /* string match failed */ |
549 | PRINT_FCALL_ERROR("unknown error", req->rcall); | 559 | PRINT_FCALL_ERROR("unknown error", req->rcall); |
@@ -553,47 +563,48 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
553 | req->err = -ESERVERFAULT; | 563 | req->err = -ESERVERFAULT; |
554 | } | 564 | } |
555 | } else if (req->tcall && req->rcall->id != req->tcall->id + 1) { | 565 | } else if (req->tcall && req->rcall->id != req->tcall->id + 1) { |
556 | dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n", | 566 | P9_DPRINTK(P9_DEBUG_ERROR, |
557 | req->tcall->id + 1, req->rcall->id); | 567 | "fcall mismatch: expected %d, got %d\n", |
568 | req->tcall->id + 1, req->rcall->id); | ||
558 | if (!req->err) | 569 | if (!req->err) |
559 | req->err = -EIO; | 570 | req->err = -EIO; |
560 | } | 571 | } |
561 | } | 572 | } |
562 | 573 | ||
563 | /** | 574 | /** |
564 | * v9fs_read_work - called when there is some data to be read from a transport | 575 | * p9_read_work - called when there is some data to be read from a transport |
565 | */ | 576 | */ |
566 | static void v9fs_read_work(struct work_struct *work) | 577 | static void p9_read_work(struct work_struct *work) |
567 | { | 578 | { |
568 | int n, err; | 579 | int n, err; |
569 | struct v9fs_mux_data *m; | 580 | struct p9_conn *m; |
570 | struct v9fs_req *req, *rptr, *rreq; | 581 | struct p9_req *req, *rptr, *rreq; |
571 | struct v9fs_fcall *rcall; | 582 | struct p9_fcall *rcall; |
572 | char *rbuf; | 583 | char *rbuf; |
573 | 584 | ||
574 | m = container_of(work, struct v9fs_mux_data, rq); | 585 | m = container_of(work, struct p9_conn, rq); |
575 | 586 | ||
576 | if (m->err < 0) | 587 | if (m->err < 0) |
577 | return; | 588 | return; |
578 | 589 | ||
579 | rcall = NULL; | 590 | rcall = NULL; |
580 | dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); | 591 | P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos); |
581 | 592 | ||
582 | if (!m->rcall) { | 593 | if (!m->rcall) { |
583 | m->rcall = | 594 | m->rcall = |
584 | kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL); | 595 | kmalloc(sizeof(struct p9_fcall) + m->msize, GFP_KERNEL); |
585 | if (!m->rcall) { | 596 | if (!m->rcall) { |
586 | err = -ENOMEM; | 597 | err = -ENOMEM; |
587 | goto error; | 598 | goto error; |
588 | } | 599 | } |
589 | 600 | ||
590 | m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); | 601 | m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); |
591 | m->rpos = 0; | 602 | m->rpos = 0; |
592 | } | 603 | } |
593 | 604 | ||
594 | clear_bit(Rpending, &m->wsched); | 605 | clear_bit(Rpending, &m->wsched); |
595 | err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); | 606 | err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos); |
596 | dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err); | 607 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err); |
597 | if (err == -EAGAIN) { | 608 | if (err == -EAGAIN) { |
598 | clear_bit(Rworksched, &m->wsched); | 609 | clear_bit(Rworksched, &m->wsched); |
599 | return; | 610 | return; |
@@ -606,7 +617,7 @@ static void v9fs_read_work(struct work_struct *work) | |||
606 | while (m->rpos > 4) { | 617 | while (m->rpos > 4) { |
607 | n = le32_to_cpu(*(__le32 *) m->rbuf); | 618 | n = le32_to_cpu(*(__le32 *) m->rbuf); |
608 | if (n >= m->msize) { | 619 | if (n >= m->msize) { |
609 | dprintk(DEBUG_ERROR, | 620 | P9_DPRINTK(P9_DEBUG_ERROR, |
610 | "requested packet size too big: %d\n", n); | 621 | "requested packet size too big: %d\n", n); |
611 | err = -EIO; | 622 | err = -EIO; |
612 | goto error; | 623 | goto error; |
@@ -615,32 +626,33 @@ static void v9fs_read_work(struct work_struct *work) | |||
615 | if (m->rpos < n) | 626 | if (m->rpos < n) |
616 | break; | 627 | break; |
617 | 628 | ||
618 | dump_data(m->rbuf, n); | ||
619 | err = | 629 | err = |
620 | v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); | 630 | p9_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended); |
621 | if (err < 0) { | 631 | if (err < 0) { |
622 | goto error; | 632 | goto error; |
623 | } | 633 | } |
624 | 634 | ||
625 | if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { | 635 | #ifdef CONFIG_NET_9P_DEBUG |
636 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { | ||
626 | char buf[150]; | 637 | char buf[150]; |
627 | 638 | ||
628 | v9fs_printfcall(buf, sizeof(buf), m->rcall, | 639 | p9_printfcall(buf, sizeof(buf), m->rcall, |
629 | *m->extended); | 640 | *m->extended); |
630 | printk(KERN_NOTICE ">>> %p %s\n", m, buf); | 641 | printk(KERN_NOTICE ">>> %p %s\n", m, buf); |
631 | } | 642 | } |
643 | #endif | ||
632 | 644 | ||
633 | rcall = m->rcall; | 645 | rcall = m->rcall; |
634 | rbuf = m->rbuf; | 646 | rbuf = m->rbuf; |
635 | if (m->rpos > n) { | 647 | if (m->rpos > n) { |
636 | m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize, | 648 | m->rcall = kmalloc(sizeof(struct p9_fcall) + m->msize, |
637 | GFP_KERNEL); | 649 | GFP_KERNEL); |
638 | if (!m->rcall) { | 650 | if (!m->rcall) { |
639 | err = -ENOMEM; | 651 | err = -ENOMEM; |
640 | goto error; | 652 | goto error; |
641 | } | 653 | } |
642 | 654 | ||
643 | m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall); | 655 | m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall); |
644 | memmove(m->rbuf, rbuf + n, m->rpos - n); | 656 | memmove(m->rbuf, rbuf + n, m->rpos - n); |
645 | m->rpos -= n; | 657 | m->rpos -= n; |
646 | } else { | 658 | } else { |
@@ -649,8 +661,8 @@ static void v9fs_read_work(struct work_struct *work) | |||
649 | m->rpos = 0; | 661 | m->rpos = 0; |
650 | } | 662 | } |
651 | 663 | ||
652 | dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id, | 664 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, |
653 | rcall->tag); | 665 | rcall->id, rcall->tag); |
654 | 666 | ||
655 | req = NULL; | 667 | req = NULL; |
656 | spin_lock(&m->lock); | 668 | spin_lock(&m->lock); |
@@ -677,10 +689,10 @@ static void v9fs_read_work(struct work_struct *work) | |||
677 | wake_up(&m->equeue); | 689 | wake_up(&m->equeue); |
678 | } | 690 | } |
679 | } else { | 691 | } else { |
680 | if (err >= 0 && rcall->id != RFLUSH) | 692 | if (err >= 0 && rcall->id != P9_RFLUSH) |
681 | dprintk(DEBUG_ERROR, | 693 | P9_DPRINTK(P9_DEBUG_ERROR, |
682 | "unexpected response mux %p id %d tag %d\n", | 694 | "unexpected response mux %p id %d tag %d\n", |
683 | m, rcall->id, rcall->tag); | 695 | m, rcall->id, rcall->tag); |
684 | kfree(rcall); | 696 | kfree(rcall); |
685 | } | 697 | } |
686 | } | 698 | } |
@@ -692,8 +704,8 @@ static void v9fs_read_work(struct work_struct *work) | |||
692 | n = m->trans->poll(m->trans, NULL); | 704 | n = m->trans->poll(m->trans, NULL); |
693 | 705 | ||
694 | if (n & POLLIN) { | 706 | if (n & POLLIN) { |
695 | dprintk(DEBUG_MUX, "schedule read work mux %p\n", m); | 707 | P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m); |
696 | queue_work(v9fs_mux_wq, &m->rq); | 708 | queue_work(p9_mux_wq, &m->rq); |
697 | } else | 709 | } else |
698 | clear_bit(Rworksched, &m->wsched); | 710 | clear_bit(Rworksched, &m->wsched); |
699 | } else | 711 | } else |
@@ -701,13 +713,13 @@ static void v9fs_read_work(struct work_struct *work) | |||
701 | 713 | ||
702 | return; | 714 | return; |
703 | 715 | ||
704 | error: | 716 | error: |
705 | v9fs_mux_cancel(m, err); | 717 | p9_conn_cancel(m, err); |
706 | clear_bit(Rworksched, &m->wsched); | 718 | clear_bit(Rworksched, &m->wsched); |
707 | } | 719 | } |
708 | 720 | ||
709 | /** | 721 | /** |
710 | * v9fs_send_request - send 9P request | 722 | * p9_send_request - send 9P request |
711 | * The function can sleep until the request is scheduled for sending. | 723 | * The function can sleep until the request is scheduled for sending. |
712 | * The function can be interrupted. Return from the function is not | 724 | * The function can be interrupted. Return from the function is not |
713 | * a guarantee that the request is sent successfully. Can return errors | 725 | * a guarantee that the request is sent successfully. Can return errors |
@@ -718,37 +730,40 @@ static void v9fs_read_work(struct work_struct *work) | |||
718 | * @cb: callback function to call when response is received | 730 | * @cb: callback function to call when response is received |
719 | * @cba: parameter to pass to the callback function | 731 | * @cba: parameter to pass to the callback function |
720 | */ | 732 | */ |
721 | static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, | 733 | static struct p9_req *p9_send_request(struct p9_conn *m, |
722 | struct v9fs_fcall *tc, | 734 | struct p9_fcall *tc, |
723 | v9fs_mux_req_callback cb, void *cba) | 735 | p9_conn_req_callback cb, void *cba) |
724 | { | 736 | { |
725 | int n; | 737 | int n; |
726 | struct v9fs_req *req; | 738 | struct p9_req *req; |
727 | 739 | ||
728 | dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, | 740 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current, |
729 | tc, tc->id); | 741 | tc, tc->id); |
730 | if (m->err < 0) | 742 | if (m->err < 0) |
731 | return ERR_PTR(m->err); | 743 | return ERR_PTR(m->err); |
732 | 744 | ||
733 | req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL); | 745 | req = kmalloc(sizeof(struct p9_req), GFP_KERNEL); |
734 | if (!req) | 746 | if (!req) |
735 | return ERR_PTR(-ENOMEM); | 747 | return ERR_PTR(-ENOMEM); |
736 | 748 | ||
737 | if (tc->id == TVERSION) | 749 | if (tc->id == P9_TVERSION) |
738 | n = V9FS_NOTAG; | 750 | n = P9_NOTAG; |
739 | else | 751 | else |
740 | n = v9fs_mux_get_tag(m); | 752 | n = p9_mux_get_tag(m); |
741 | 753 | ||
742 | if (n < 0) | 754 | if (n < 0) |
743 | return ERR_PTR(-ENOMEM); | 755 | return ERR_PTR(-ENOMEM); |
744 | 756 | ||
745 | v9fs_set_tag(tc, n); | 757 | p9_set_tag(tc, n); |
746 | if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) { | 758 | |
759 | #ifdef CONFIG_NET_9P_DEBUG | ||
760 | if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) { | ||
747 | char buf[150]; | 761 | char buf[150]; |
748 | 762 | ||
749 | v9fs_printfcall(buf, sizeof(buf), tc, *m->extended); | 763 | p9_printfcall(buf, sizeof(buf), tc, *m->extended); |
750 | printk(KERN_NOTICE "<<< %p %s\n", m, buf); | 764 | printk(KERN_NOTICE "<<< %p %s\n", m, buf); |
751 | } | 765 | } |
766 | #endif | ||
752 | 767 | ||
753 | spin_lock_init(&req->lock); | 768 | spin_lock_init(&req->lock); |
754 | req->tag = n; | 769 | req->tag = n; |
@@ -769,26 +784,26 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m, | |||
769 | n = m->trans->poll(m->trans, NULL); | 784 | n = m->trans->poll(m->trans, NULL); |
770 | 785 | ||
771 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) | 786 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) |
772 | queue_work(v9fs_mux_wq, &m->wq); | 787 | queue_work(p9_mux_wq, &m->wq); |
773 | 788 | ||
774 | return req; | 789 | return req; |
775 | } | 790 | } |
776 | 791 | ||
777 | static void v9fs_mux_free_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 792 | static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req) |
778 | { | 793 | { |
779 | v9fs_mux_put_tag(m, req->tag); | 794 | p9_mux_put_tag(m, req->tag); |
780 | kfree(req); | 795 | kfree(req); |
781 | } | 796 | } |
782 | 797 | ||
783 | static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) | 798 | static void p9_mux_flush_cb(struct p9_req *freq, void *a) |
784 | { | 799 | { |
785 | v9fs_mux_req_callback cb; | 800 | p9_conn_req_callback cb; |
786 | int tag; | 801 | int tag; |
787 | struct v9fs_mux_data *m; | 802 | struct p9_conn *m; |
788 | struct v9fs_req *req, *rreq, *rptr; | 803 | struct p9_req *req, *rreq, *rptr; |
789 | 804 | ||
790 | m = a; | 805 | m = a; |
791 | dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, | 806 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, |
792 | freq->tcall, freq->rcall, freq->err, | 807 | freq->tcall, freq->rcall, freq->err, |
793 | freq->tcall->params.tflush.oldtag); | 808 | freq->tcall->params.tflush.oldtag); |
794 | 809 | ||
@@ -820,22 +835,23 @@ static void v9fs_mux_flush_cb(struct v9fs_req *freq, void *a) | |||
820 | 835 | ||
821 | kfree(freq->tcall); | 836 | kfree(freq->tcall); |
822 | kfree(freq->rcall); | 837 | kfree(freq->rcall); |
823 | v9fs_mux_free_request(m, freq); | 838 | p9_mux_free_request(m, freq); |
824 | } | 839 | } |
825 | 840 | ||
826 | static int | 841 | static int |
827 | v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | 842 | p9_mux_flush_request(struct p9_conn *m, struct p9_req *req) |
828 | { | 843 | { |
829 | struct v9fs_fcall *fc; | 844 | struct p9_fcall *fc; |
830 | struct v9fs_req *rreq, *rptr; | 845 | struct p9_req *rreq, *rptr; |
831 | 846 | ||
832 | dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); | 847 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag); |
833 | 848 | ||
834 | /* if a response was received for a request, do nothing */ | 849 | /* if a response was received for a request, do nothing */ |
835 | spin_lock(&req->lock); | 850 | spin_lock(&req->lock); |
836 | if (req->rcall || req->err) { | 851 | if (req->rcall || req->err) { |
837 | spin_unlock(&req->lock); | 852 | spin_unlock(&req->lock); |
838 | dprintk(DEBUG_MUX, "mux %p req %p response already received\n", m, req); | 853 | P9_DPRINTK(P9_DEBUG_MUX, |
854 | "mux %p req %p response already received\n", m, req); | ||
839 | return 0; | 855 | return 0; |
840 | } | 856 | } |
841 | 857 | ||
@@ -846,7 +862,8 @@ v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
846 | /* if the request is not sent yet, just remove it from the list */ | 862 | /* if the request is not sent yet, just remove it from the list */ |
847 | list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { | 863 | list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) { |
848 | if (rreq->tag == req->tag) { | 864 | if (rreq->tag == req->tag) { |
849 | dprintk(DEBUG_MUX, "mux %p req %p request is not sent yet\n", m, req); | 865 | P9_DPRINTK(P9_DEBUG_MUX, |
866 | "mux %p req %p request is not sent yet\n", m, req); | ||
850 | list_del(&rreq->req_list); | 867 | list_del(&rreq->req_list); |
851 | req->flush = Flushed; | 868 | req->flush = Flushed; |
852 | spin_unlock(&m->lock); | 869 | spin_unlock(&m->lock); |
@@ -858,42 +875,42 @@ v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
858 | spin_unlock(&m->lock); | 875 | spin_unlock(&m->lock); |
859 | 876 | ||
860 | clear_thread_flag(TIF_SIGPENDING); | 877 | clear_thread_flag(TIF_SIGPENDING); |
861 | fc = v9fs_create_tflush(req->tag); | 878 | fc = p9_create_tflush(req->tag); |
862 | v9fs_send_request(m, fc, v9fs_mux_flush_cb, m); | 879 | p9_send_request(m, fc, p9_mux_flush_cb, m); |
863 | return 1; | 880 | return 1; |
864 | } | 881 | } |
865 | 882 | ||
866 | static void | 883 | static void |
867 | v9fs_mux_rpc_cb(struct v9fs_req *req, void *a) | 884 | p9_conn_rpc_cb(struct p9_req *req, void *a) |
868 | { | 885 | { |
869 | struct v9fs_mux_rpc *r; | 886 | struct p9_mux_rpc *r; |
870 | 887 | ||
871 | dprintk(DEBUG_MUX, "req %p r %p\n", req, a); | 888 | P9_DPRINTK(P9_DEBUG_MUX, "req %p r %p\n", req, a); |
872 | r = a; | 889 | r = a; |
873 | r->rcall = req->rcall; | 890 | r->rcall = req->rcall; |
874 | r->err = req->err; | 891 | r->err = req->err; |
875 | 892 | ||
876 | if (req->flush!=None && !req->err) | 893 | if (req->flush != None && !req->err) |
877 | r->err = -ERESTARTSYS; | 894 | r->err = -ERESTARTSYS; |
878 | 895 | ||
879 | wake_up(&r->wqueue); | 896 | wake_up(&r->wqueue); |
880 | } | 897 | } |
881 | 898 | ||
882 | /** | 899 | /** |
883 | * v9fs_mux_rpc - sends 9P request and waits until a response is available. | 900 | * p9_mux_rpc - sends 9P request and waits until a response is available. |
884 | * The function can be interrupted. | 901 | * The function can be interrupted. |
885 | * @m: mux data | 902 | * @m: mux data |
886 | * @tc: request to be sent | 903 | * @tc: request to be sent |
887 | * @rc: pointer where a pointer to the response is stored | 904 | * @rc: pointer where a pointer to the response is stored |
888 | */ | 905 | */ |
889 | int | 906 | int |
890 | v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | 907 | p9_conn_rpc(struct p9_conn *m, struct p9_fcall *tc, |
891 | struct v9fs_fcall **rc) | 908 | struct p9_fcall **rc) |
892 | { | 909 | { |
893 | int err, sigpending; | 910 | int err, sigpending; |
894 | unsigned long flags; | 911 | unsigned long flags; |
895 | struct v9fs_req *req; | 912 | struct p9_req *req; |
896 | struct v9fs_mux_rpc r; | 913 | struct p9_mux_rpc r; |
897 | 914 | ||
898 | r.err = 0; | 915 | r.err = 0; |
899 | r.tcall = tc; | 916 | r.tcall = tc; |
@@ -910,10 +927,10 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
910 | clear_thread_flag(TIF_SIGPENDING); | 927 | clear_thread_flag(TIF_SIGPENDING); |
911 | } | 928 | } |
912 | 929 | ||
913 | req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r); | 930 | req = p9_send_request(m, tc, p9_conn_rpc_cb, &r); |
914 | if (IS_ERR(req)) { | 931 | if (IS_ERR(req)) { |
915 | err = PTR_ERR(req); | 932 | err = PTR_ERR(req); |
916 | dprintk(DEBUG_MUX, "error %d\n", err); | 933 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); |
917 | return err; | 934 | return err; |
918 | } | 935 | } |
919 | 936 | ||
@@ -921,15 +938,16 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
921 | if (r.err < 0) | 938 | if (r.err < 0) |
922 | err = r.err; | 939 | err = r.err; |
923 | 940 | ||
924 | if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) { | 941 | if (err == -ERESTARTSYS && m->trans->status == Connected |
925 | if (v9fs_mux_flush_request(m, req)) { | 942 | && m->err == 0) { |
943 | if (p9_mux_flush_request(m, req)) { | ||
926 | /* wait until we get response of the flush message */ | 944 | /* wait until we get response of the flush message */ |
927 | do { | 945 | do { |
928 | clear_thread_flag(TIF_SIGPENDING); | 946 | clear_thread_flag(TIF_SIGPENDING); |
929 | err = wait_event_interruptible(r.wqueue, | 947 | err = wait_event_interruptible(r.wqueue, |
930 | r.rcall || r.err); | 948 | r.rcall || r.err); |
931 | } while (!r.rcall && !r.err && err==-ERESTARTSYS && | 949 | } while (!r.rcall && !r.err && err == -ERESTARTSYS && |
932 | m->trans->status==Connected && !m->err); | 950 | m->trans->status == Connected && !m->err); |
933 | 951 | ||
934 | err = -ERESTARTSYS; | 952 | err = -ERESTARTSYS; |
935 | } | 953 | } |
@@ -947,50 +965,52 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | |||
947 | else | 965 | else |
948 | kfree(r.rcall); | 966 | kfree(r.rcall); |
949 | 967 | ||
950 | v9fs_mux_free_request(m, req); | 968 | p9_mux_free_request(m, req); |
951 | if (err > 0) | 969 | if (err > 0) |
952 | err = -EIO; | 970 | err = -EIO; |
953 | 971 | ||
954 | return err; | 972 | return err; |
955 | } | 973 | } |
974 | EXPORT_SYMBOL(p9_conn_rpc); | ||
956 | 975 | ||
957 | #if 0 | 976 | #ifdef P9_NONBLOCK |
958 | /** | 977 | /** |
959 | * v9fs_mux_rpcnb - sends 9P request without waiting for response. | 978 | * p9_conn_rpcnb - sends 9P request without waiting for response. |
960 | * @m: mux data | 979 | * @m: mux data |
961 | * @tc: request to be sent | 980 | * @tc: request to be sent |
962 | * @cb: callback function to be called when response arrives | 981 | * @cb: callback function to be called when response arrives |
963 | * @cba: value to pass to the callback function | 982 | * @cba: value to pass to the callback function |
964 | */ | 983 | */ |
965 | int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc, | 984 | int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc, |
966 | v9fs_mux_req_callback cb, void *a) | 985 | p9_conn_req_callback cb, void *a) |
967 | { | 986 | { |
968 | int err; | 987 | int err; |
969 | struct v9fs_req *req; | 988 | struct p9_req *req; |
970 | 989 | ||
971 | req = v9fs_send_request(m, tc, cb, a); | 990 | req = p9_send_request(m, tc, cb, a); |
972 | if (IS_ERR(req)) { | 991 | if (IS_ERR(req)) { |
973 | err = PTR_ERR(req); | 992 | err = PTR_ERR(req); |
974 | dprintk(DEBUG_MUX, "error %d\n", err); | 993 | P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err); |
975 | return PTR_ERR(req); | 994 | return PTR_ERR(req); |
976 | } | 995 | } |
977 | 996 | ||
978 | dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); | 997 | P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag); |
979 | return 0; | 998 | return 0; |
980 | } | 999 | } |
981 | #endif /* 0 */ | 1000 | EXPORT_SYMBOL(p9_conn_rpcnb); |
1001 | #endif /* P9_NONBLOCK */ | ||
982 | 1002 | ||
983 | /** | 1003 | /** |
984 | * v9fs_mux_cancel - cancel all pending requests with error | 1004 | * p9_conn_cancel - cancel all pending requests with error |
985 | * @m: mux data | 1005 | * @m: mux data |
986 | * @err: error code | 1006 | * @err: error code |
987 | */ | 1007 | */ |
988 | void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) | 1008 | void p9_conn_cancel(struct p9_conn *m, int err) |
989 | { | 1009 | { |
990 | struct v9fs_req *req, *rtmp; | 1010 | struct p9_req *req, *rtmp; |
991 | LIST_HEAD(cancel_list); | 1011 | LIST_HEAD(cancel_list); |
992 | 1012 | ||
993 | dprintk(DEBUG_ERROR, "mux %p err %d\n", m, err); | 1013 | P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err); |
994 | m->err = err; | 1014 | m->err = err; |
995 | spin_lock(&m->lock); | 1015 | spin_lock(&m->lock); |
996 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { | 1016 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { |
@@ -1014,20 +1034,21 @@ void v9fs_mux_cancel(struct v9fs_mux_data *m, int err) | |||
1014 | 1034 | ||
1015 | wake_up(&m->equeue); | 1035 | wake_up(&m->equeue); |
1016 | } | 1036 | } |
1037 | EXPORT_SYMBOL(p9_conn_cancel); | ||
1017 | 1038 | ||
1018 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m) | 1039 | static u16 p9_mux_get_tag(struct p9_conn *m) |
1019 | { | 1040 | { |
1020 | int tag; | 1041 | int tag; |
1021 | 1042 | ||
1022 | tag = v9fs_get_idpool(&m->tagpool); | 1043 | tag = p9_idpool_get(m->tagpool); |
1023 | if (tag < 0) | 1044 | if (tag < 0) |
1024 | return V9FS_NOTAG; | 1045 | return P9_NOTAG; |
1025 | else | 1046 | else |
1026 | return (u16) tag; | 1047 | return (u16) tag; |
1027 | } | 1048 | } |
1028 | 1049 | ||
1029 | static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) | 1050 | static void p9_mux_put_tag(struct p9_conn *m, u16 tag) |
1030 | { | 1051 | { |
1031 | if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool)) | 1052 | if (tag != P9_NOTAG && p9_idpool_check(tag, m->tagpool)) |
1032 | v9fs_put_idpool(tag, &m->tagpool); | 1053 | p9_idpool_put(tag, m->tagpool); |
1033 | } | 1054 | } |
diff --git a/net/9p/sysctl.c b/net/9p/sysctl.c new file mode 100644 index 00000000000..e7fe706ab95 --- /dev/null +++ b/net/9p/sysctl.c | |||
@@ -0,0 +1,86 @@ | |||
1 | /* | ||
2 | * net/9p/sysctl.c | ||
3 | * | ||
4 | * 9P sysctl interface | ||
5 | * | ||
6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 | ||
10 | * as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to: | ||
19 | * Free Software Foundation | ||
20 | * 51 Franklin Street, Fifth Floor | ||
21 | * Boston, MA 02111-1301 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/mm.h> | ||
27 | #include <linux/sysctl.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <net/9p/9p.h> | ||
30 | |||
31 | enum { | ||
32 | P9_SYSCTL_NET = 487, | ||
33 | P9_SYSCTL_DEBUG = 1, | ||
34 | }; | ||
35 | |||
36 | static ctl_table p9_table[] = { | ||
37 | #ifdef CONFIG_NET_9P_DEBUG | ||
38 | { | ||
39 | .ctl_name = P9_SYSCTL_DEBUG, | ||
40 | .procname = "debug", | ||
41 | .data = &p9_debug_level, | ||
42 | .maxlen = sizeof(int), | ||
43 | .mode = 0644, | ||
44 | .proc_handler = &proc_dointvec | ||
45 | }, | ||
46 | #endif | ||
47 | { .ctl_name = 0 }, | ||
48 | }; | ||
49 | |||
50 | static ctl_table p9_net_table[] = { | ||
51 | { | ||
52 | .ctl_name = P9_SYSCTL_NET, | ||
53 | .procname = "9p", | ||
54 | .maxlen = 0, | ||
55 | .mode = 0555, | ||
56 | .child = p9_table, | ||
57 | }, | ||
58 | { .ctl_name = 0 }, | ||
59 | }; | ||
60 | |||
61 | static ctl_table p9_ctl_table[] = { | ||
62 | { | ||
63 | .ctl_name = CTL_NET, | ||
64 | .procname = "net", | ||
65 | .maxlen = 0, | ||
66 | .mode = 0555, | ||
67 | .child = p9_net_table, | ||
68 | }, | ||
69 | { .ctl_name = 0 }, | ||
70 | }; | ||
71 | |||
72 | static struct ctl_table_header *p9_table_header; | ||
73 | |||
74 | int __init p9_sysctl_register(void) | ||
75 | { | ||
76 | p9_table_header = register_sysctl_table(p9_ctl_table); | ||
77 | if (!p9_table_header) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | void __exit p9_sysctl_unregister(void) | ||
84 | { | ||
85 | unregister_sysctl_table(p9_table_header); | ||
86 | } | ||
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c new file mode 100644 index 00000000000..fd636e94358 --- /dev/null +++ b/net/9p/trans_fd.c | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | * linux/fs/9p/trans_fd.c | ||
3 | * | ||
4 | * Fd transport layer. Includes deprecated socket layer. | ||
5 | * | ||
6 | * Copyright (C) 2006 by Russ Cox <rsc@swtch.com> | ||
7 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> | ||
8 | * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com> | ||
9 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 | ||
13 | * as published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to: | ||
22 | * Free Software Foundation | ||
23 | * 51 Franklin Street, Fifth Floor | ||
24 | * Boston, MA 02111-1301 USA | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/in.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/net.h> | ||
31 | #include <linux/ipv6.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/un.h> | ||
35 | #include <linux/uaccess.h> | ||
36 | #include <linux/inet.h> | ||
37 | #include <linux/idr.h> | ||
38 | #include <linux/file.h> | ||
39 | #include <net/9p/9p.h> | ||
40 | #include <net/9p/transport.h> | ||
41 | |||
42 | #define P9_PORT 564 | ||
43 | |||
44 | struct p9_trans_fd { | ||
45 | struct file *rd; | ||
46 | struct file *wr; | ||
47 | }; | ||
48 | |||
49 | static int p9_socket_open(struct p9_transport *trans, struct socket *csocket); | ||
50 | static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd); | ||
51 | static int p9_fd_read(struct p9_transport *trans, void *v, int len); | ||
52 | static int p9_fd_write(struct p9_transport *trans, void *v, int len); | ||
53 | static unsigned int p9_fd_poll(struct p9_transport *trans, | ||
54 | struct poll_table_struct *pt); | ||
55 | static void p9_fd_close(struct p9_transport *trans); | ||
56 | |||
57 | struct p9_transport *p9_trans_create_tcp(const char *addr, int port) | ||
58 | { | ||
59 | int err; | ||
60 | struct p9_transport *trans; | ||
61 | struct socket *csocket; | ||
62 | struct sockaddr_in sin_server; | ||
63 | |||
64 | csocket = NULL; | ||
65 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
66 | if (!trans) | ||
67 | return ERR_PTR(-ENOMEM); | ||
68 | |||
69 | trans->write = p9_fd_write; | ||
70 | trans->read = p9_fd_read; | ||
71 | trans->close = p9_fd_close; | ||
72 | trans->poll = p9_fd_poll; | ||
73 | |||
74 | sin_server.sin_family = AF_INET; | ||
75 | sin_server.sin_addr.s_addr = in_aton(addr); | ||
76 | sin_server.sin_port = htons(port); | ||
77 | sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket); | ||
78 | |||
79 | if (!csocket) { | ||
80 | P9_EPRINTK(KERN_ERR, "p9_trans_tcp: problem creating socket\n"); | ||
81 | err = -EIO; | ||
82 | goto error; | ||
83 | } | ||
84 | |||
85 | err = csocket->ops->connect(csocket, | ||
86 | (struct sockaddr *)&sin_server, | ||
87 | sizeof(struct sockaddr_in), 0); | ||
88 | if (err < 0) { | ||
89 | P9_EPRINTK(KERN_ERR, | ||
90 | "p9_trans_tcp: problem connecting socket to %s\n", | ||
91 | addr); | ||
92 | goto error; | ||
93 | } | ||
94 | |||
95 | err = p9_socket_open(trans, csocket); | ||
96 | if (err < 0) | ||
97 | goto error; | ||
98 | |||
99 | return trans; | ||
100 | |||
101 | error: | ||
102 | if (csocket) | ||
103 | sock_release(csocket); | ||
104 | |||
105 | kfree(trans); | ||
106 | return ERR_PTR(err); | ||
107 | } | ||
108 | EXPORT_SYMBOL(p9_trans_create_tcp); | ||
109 | |||
110 | struct p9_transport *p9_trans_create_unix(const char *addr) | ||
111 | { | ||
112 | int err; | ||
113 | struct socket *csocket; | ||
114 | struct sockaddr_un sun_server; | ||
115 | struct p9_transport *trans; | ||
116 | |||
117 | csocket = NULL; | ||
118 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
119 | if (!trans) | ||
120 | return ERR_PTR(-ENOMEM); | ||
121 | |||
122 | trans->write = p9_fd_write; | ||
123 | trans->read = p9_fd_read; | ||
124 | trans->close = p9_fd_close; | ||
125 | trans->poll = p9_fd_poll; | ||
126 | |||
127 | if (strlen(addr) > UNIX_PATH_MAX) { | ||
128 | P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n", | ||
129 | addr); | ||
130 | err = -ENAMETOOLONG; | ||
131 | goto error; | ||
132 | } | ||
133 | |||
134 | sun_server.sun_family = PF_UNIX; | ||
135 | strcpy(sun_server.sun_path, addr); | ||
136 | sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket); | ||
137 | err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server, | ||
138 | sizeof(struct sockaddr_un) - 1, 0); | ||
139 | if (err < 0) { | ||
140 | P9_EPRINTK(KERN_ERR, | ||
141 | "p9_trans_unix: problem connecting socket: %s: %d\n", | ||
142 | addr, err); | ||
143 | goto error; | ||
144 | } | ||
145 | |||
146 | err = p9_socket_open(trans, csocket); | ||
147 | if (err < 0) | ||
148 | goto error; | ||
149 | |||
150 | return trans; | ||
151 | |||
152 | error: | ||
153 | if (csocket) | ||
154 | sock_release(csocket); | ||
155 | |||
156 | kfree(trans); | ||
157 | return ERR_PTR(err); | ||
158 | } | ||
159 | EXPORT_SYMBOL(p9_trans_create_unix); | ||
160 | |||
161 | struct p9_transport *p9_trans_create_fd(int rfd, int wfd) | ||
162 | { | ||
163 | int err; | ||
164 | struct p9_transport *trans; | ||
165 | |||
166 | if (rfd == ~0 || wfd == ~0) { | ||
167 | printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); | ||
168 | return ERR_PTR(-ENOPROTOOPT); | ||
169 | } | ||
170 | |||
171 | trans = kmalloc(sizeof(struct p9_transport), GFP_KERNEL); | ||
172 | if (!trans) | ||
173 | return ERR_PTR(-ENOMEM); | ||
174 | |||
175 | trans->write = p9_fd_write; | ||
176 | trans->read = p9_fd_read; | ||
177 | trans->close = p9_fd_close; | ||
178 | trans->poll = p9_fd_poll; | ||
179 | |||
180 | err = p9_fd_open(trans, rfd, wfd); | ||
181 | if (err < 0) | ||
182 | goto error; | ||
183 | |||
184 | return trans; | ||
185 | |||
186 | error: | ||
187 | kfree(trans); | ||
188 | return ERR_PTR(err); | ||
189 | } | ||
190 | EXPORT_SYMBOL(p9_trans_create_fd); | ||
191 | |||
192 | static int p9_socket_open(struct p9_transport *trans, struct socket *csocket) | ||
193 | { | ||
194 | int fd, ret; | ||
195 | |||
196 | csocket->sk->sk_allocation = GFP_NOIO; | ||
197 | fd = sock_map_fd(csocket); | ||
198 | if (fd < 0) { | ||
199 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n"); | ||
200 | return fd; | ||
201 | } | ||
202 | |||
203 | ret = p9_fd_open(trans, fd, fd); | ||
204 | if (ret < 0) { | ||
205 | P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n"); | ||
206 | sockfd_put(csocket); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int p9_fd_open(struct p9_transport *trans, int rfd, int wfd) | ||
216 | { | ||
217 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), | ||
218 | GFP_KERNEL); | ||
219 | if (!ts) | ||
220 | return -ENOMEM; | ||
221 | |||
222 | ts->rd = fget(rfd); | ||
223 | ts->wr = fget(wfd); | ||
224 | if (!ts->rd || !ts->wr) { | ||
225 | if (ts->rd) | ||
226 | fput(ts->rd); | ||
227 | if (ts->wr) | ||
228 | fput(ts->wr); | ||
229 | kfree(ts); | ||
230 | return -EIO; | ||
231 | } | ||
232 | |||
233 | trans->priv = ts; | ||
234 | trans->status = Connected; | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * p9_fd_read- read from a fd | ||
241 | * @v9ses: session information | ||
242 | * @v: buffer to receive data into | ||
243 | * @len: size of receive buffer | ||
244 | * | ||
245 | */ | ||
246 | static int p9_fd_read(struct p9_transport *trans, void *v, int len) | ||
247 | { | ||
248 | int ret; | ||
249 | struct p9_trans_fd *ts = NULL; | ||
250 | |||
251 | if (trans && trans->status != Disconnected) | ||
252 | ts = trans->priv; | ||
253 | |||
254 | if (!ts) | ||
255 | return -EREMOTEIO; | ||
256 | |||
257 | if (!(ts->rd->f_flags & O_NONBLOCK)) | ||
258 | P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n"); | ||
259 | |||
260 | ret = kernel_read(ts->rd, ts->rd->f_pos, v, len); | ||
261 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
262 | trans->status = Disconnected; | ||
263 | return ret; | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * p9_fd_write - write to a socket | ||
268 | * @v9ses: session information | ||
269 | * @v: buffer to send data from | ||
270 | * @len: size of send buffer | ||
271 | * | ||
272 | */ | ||
273 | static int p9_fd_write(struct p9_transport *trans, void *v, int len) | ||
274 | { | ||
275 | int ret; | ||
276 | mm_segment_t oldfs; | ||
277 | struct p9_trans_fd *ts = NULL; | ||
278 | |||
279 | if (trans && trans->status != Disconnected) | ||
280 | ts = trans->priv; | ||
281 | |||
282 | if (!ts) | ||
283 | return -EREMOTEIO; | ||
284 | |||
285 | if (!(ts->wr->f_flags & O_NONBLOCK)) | ||
286 | P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n"); | ||
287 | |||
288 | oldfs = get_fs(); | ||
289 | set_fs(get_ds()); | ||
290 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
291 | ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos); | ||
292 | set_fs(oldfs); | ||
293 | |||
294 | if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN) | ||
295 | trans->status = Disconnected; | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | static unsigned int | ||
300 | p9_fd_poll(struct p9_transport *trans, struct poll_table_struct *pt) | ||
301 | { | ||
302 | int ret, n; | ||
303 | struct p9_trans_fd *ts = NULL; | ||
304 | mm_segment_t oldfs; | ||
305 | |||
306 | if (trans && trans->status == Connected) | ||
307 | ts = trans->priv; | ||
308 | |||
309 | if (!ts) | ||
310 | return -EREMOTEIO; | ||
311 | |||
312 | if (!ts->rd->f_op || !ts->rd->f_op->poll) | ||
313 | return -EIO; | ||
314 | |||
315 | if (!ts->wr->f_op || !ts->wr->f_op->poll) | ||
316 | return -EIO; | ||
317 | |||
318 | oldfs = get_fs(); | ||
319 | set_fs(get_ds()); | ||
320 | |||
321 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
322 | if (ret < 0) | ||
323 | goto end; | ||
324 | |||
325 | if (ts->rd != ts->wr) { | ||
326 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
327 | if (n < 0) { | ||
328 | ret = n; | ||
329 | goto end; | ||
330 | } | ||
331 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); | ||
332 | } | ||
333 | |||
334 | end: | ||
335 | set_fs(oldfs); | ||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * p9_sock_close - shutdown socket | ||
341 | * @trans: private socket structure | ||
342 | * | ||
343 | */ | ||
344 | static void p9_fd_close(struct p9_transport *trans) | ||
345 | { | ||
346 | struct p9_trans_fd *ts; | ||
347 | |||
348 | if (!trans) | ||
349 | return; | ||
350 | |||
351 | ts = xchg(&trans->priv, NULL); | ||
352 | |||
353 | if (!ts) | ||
354 | return; | ||
355 | |||
356 | trans->status = Disconnected; | ||
357 | if (ts->rd) | ||
358 | fput(ts->rd); | ||
359 | if (ts->wr) | ||
360 | fput(ts->wr); | ||
361 | kfree(ts); | ||
362 | } | ||
363 | |||
diff --git a/net/9p/util.c b/net/9p/util.c new file mode 100644 index 00000000000..22077b79395 --- /dev/null +++ b/net/9p/util.c | |||
@@ -0,0 +1,125 @@ | |||
1 | /* | ||
2 | * net/9p/util.c | ||
3 | * | ||
4 | * This file contains some helper functions | ||
5 | * | ||
6 | * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> | ||
7 | * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> | ||
8 | * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 | ||
12 | * as published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to: | ||
21 | * Free Software Foundation | ||
22 | * 51 Franklin Street, Fifth Floor | ||
23 | * Boston, MA 02111-1301 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/fs.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/parser.h> | ||
32 | #include <linux/idr.h> | ||
33 | #include <net/9p/9p.h> | ||
34 | |||
35 | struct p9_idpool { | ||
36 | struct semaphore lock; | ||
37 | struct idr pool; | ||
38 | }; | ||
39 | |||
40 | struct p9_idpool *p9_idpool_create(void) | ||
41 | { | ||
42 | struct p9_idpool *p; | ||
43 | |||
44 | p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL); | ||
45 | if (!p) | ||
46 | return ERR_PTR(-ENOMEM); | ||
47 | |||
48 | init_MUTEX(&p->lock); | ||
49 | idr_init(&p->pool); | ||
50 | |||
51 | return p; | ||
52 | } | ||
53 | EXPORT_SYMBOL(p9_idpool_create); | ||
54 | |||
55 | void p9_idpool_destroy(struct p9_idpool *p) | ||
56 | { | ||
57 | idr_destroy(&p->pool); | ||
58 | kfree(p); | ||
59 | } | ||
60 | EXPORT_SYMBOL(p9_idpool_destroy); | ||
61 | |||
62 | /** | ||
63 | * p9_idpool_get - allocate numeric id from pool | ||
64 | * @p - pool to allocate from | ||
65 | * | ||
66 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
67 | * the lock included in struct idr? | ||
68 | */ | ||
69 | |||
70 | int p9_idpool_get(struct p9_idpool *p) | ||
71 | { | ||
72 | int i = 0; | ||
73 | int error; | ||
74 | |||
75 | retry: | ||
76 | if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) | ||
77 | return 0; | ||
78 | |||
79 | if (down_interruptible(&p->lock) == -EINTR) { | ||
80 | P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); | ||
81 | return -1; | ||
82 | } | ||
83 | |||
84 | /* no need to store exactly p, we just need something non-null */ | ||
85 | error = idr_get_new(&p->pool, p, &i); | ||
86 | up(&p->lock); | ||
87 | |||
88 | if (error == -EAGAIN) | ||
89 | goto retry; | ||
90 | else if (error) | ||
91 | return -1; | ||
92 | |||
93 | return i; | ||
94 | } | ||
95 | EXPORT_SYMBOL(p9_idpool_get); | ||
96 | |||
97 | /** | ||
98 | * p9_idpool_put - release numeric id from pool | ||
99 | * @p - pool to allocate from | ||
100 | * | ||
101 | * XXX - This seems to be an awful generic function, should it be in idr.c with | ||
102 | * the lock included in struct idr? | ||
103 | */ | ||
104 | |||
105 | void p9_idpool_put(int id, struct p9_idpool *p) | ||
106 | { | ||
107 | if (down_interruptible(&p->lock) == -EINTR) { | ||
108 | P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); | ||
109 | return; | ||
110 | } | ||
111 | idr_remove(&p->pool, id); | ||
112 | up(&p->lock); | ||
113 | } | ||
114 | EXPORT_SYMBOL(p9_idpool_put); | ||
115 | |||
116 | /** | ||
117 | * p9_idpool_check - check if the specified id is available | ||
118 | * @id - id to check | ||
119 | * @p - pool | ||
120 | */ | ||
121 | int p9_idpool_check(int id, struct p9_idpool *p) | ||
122 | { | ||
123 | return idr_find(&p->pool, id) != NULL; | ||
124 | } | ||
125 | EXPORT_SYMBOL(p9_idpool_check); | ||
diff --git a/net/Kconfig b/net/Kconfig index f3de72978ab..cdba08ca2ef 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -227,6 +227,7 @@ source "net/ieee80211/Kconfig" | |||
227 | endmenu | 227 | endmenu |
228 | 228 | ||
229 | source "net/rfkill/Kconfig" | 229 | source "net/rfkill/Kconfig" |
230 | source "net/9p/Kconfig" | ||
230 | 231 | ||
231 | endif # if NET | 232 | endif # if NET |
232 | endmenu # Networking | 233 | endmenu # Networking |
diff --git a/net/Makefile b/net/Makefile index a87a8896343..bbe7d2a4148 100644 --- a/net/Makefile +++ b/net/Makefile | |||
@@ -51,6 +51,7 @@ obj-$(CONFIG_TIPC) += tipc/ | |||
51 | obj-$(CONFIG_NETLABEL) += netlabel/ | 51 | obj-$(CONFIG_NETLABEL) += netlabel/ |
52 | obj-$(CONFIG_IUCV) += iucv/ | 52 | obj-$(CONFIG_IUCV) += iucv/ |
53 | obj-$(CONFIG_RFKILL) += rfkill/ | 53 | obj-$(CONFIG_RFKILL) += rfkill/ |
54 | obj-$(CONFIG_NET_9P) += 9p/ | ||
54 | 55 | ||
55 | ifeq ($(CONFIG_NET),y) | 56 | ifeq ($(CONFIG_NET),y) |
56 | obj-$(CONFIG_SYSCTL) += sysctl_net.o | 57 | obj-$(CONFIG_SYSCTL) += sysctl_net.o |
diff --git a/net/atm/proc.c b/net/atm/proc.c index 88154da62cd..99fc1fe950e 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c | |||
@@ -110,7 +110,7 @@ static inline void *vcc_walk(struct vcc_state *state, loff_t l) | |||
110 | } | 110 | } |
111 | 111 | ||
112 | static int __vcc_seq_open(struct inode *inode, struct file *file, | 112 | static int __vcc_seq_open(struct inode *inode, struct file *file, |
113 | int family, struct seq_operations *ops) | 113 | int family, const struct seq_operations *ops) |
114 | { | 114 | { |
115 | struct vcc_state *state; | 115 | struct vcc_state *state; |
116 | struct seq_file *seq; | 116 | struct seq_file *seq; |