diff options
Diffstat (limited to 'fs')
150 files changed, 1655 insertions, 1762 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index a42f767dcdd5..8ea7b04c661f 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1734,6 +1734,18 @@ config SUNRPC | |||
1734 | config SUNRPC_GSS | 1734 | config SUNRPC_GSS |
1735 | tristate | 1735 | tristate |
1736 | 1736 | ||
1737 | config SUNRPC_BIND34 | ||
1738 | bool "Support for rpcbind versions 3 & 4 (EXPERIMENTAL)" | ||
1739 | depends on SUNRPC && EXPERIMENTAL | ||
1740 | help | ||
1741 | Provides kernel support for querying rpcbind servers via versions 3 | ||
1742 | and 4 of the rpcbind protocol. The kernel automatically falls back | ||
1743 | to version 2 if a remote rpcbind service does not support versions | ||
1744 | 3 or 4. | ||
1745 | |||
1746 | If unsure, say N to get traditional behavior (version 2 rpcbind | ||
1747 | requests only). | ||
1748 | |||
1737 | config RPCSEC_GSS_KRB5 | 1749 | config RPCSEC_GSS_KRB5 |
1738 | tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" | 1750 | tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)" |
1739 | depends on SUNRPC && EXPERIMENTAL | 1751 | depends on SUNRPC && EXPERIMENTAL |
@@ -2020,7 +2032,6 @@ config AFS_FS | |||
2020 | tristate "Andrew File System support (AFS) (EXPERIMENTAL)" | 2032 | tristate "Andrew File System support (AFS) (EXPERIMENTAL)" |
2021 | depends on INET && EXPERIMENTAL | 2033 | depends on INET && EXPERIMENTAL |
2022 | select AF_RXRPC | 2034 | select AF_RXRPC |
2023 | select KEYS | ||
2024 | help | 2035 | help |
2025 | If you say Y here, you will get an experimental Andrew File System | 2036 | If you say Y here, you will get an experimental Andrew File System |
2026 | driver. It currently only supports unsecured read-only AFS access. | 2037 | driver. It currently only supports unsecured read-only AFS access. |
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index f3d3d81eb7e9..74c64409ddbc 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -26,7 +26,7 @@ config BINFMT_ELF | |||
26 | config BINFMT_ELF_FDPIC | 26 | config BINFMT_ELF_FDPIC |
27 | bool "Kernel support for FDPIC ELF binaries" | 27 | bool "Kernel support for FDPIC ELF binaries" |
28 | default y | 28 | default y |
29 | depends on FRV | 29 | depends on (FRV || BLACKFIN) |
30 | help | 30 | help |
31 | ELF FDPIC binaries are based on ELF, but allow the individual load | 31 | ELF FDPIC binaries are based on ELF, but allow the individual load |
32 | segments of a binary to be located in memory independently of each | 32 | segments of a binary to be located in memory independently of each |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 2e5f2c8371ee..30c296508497 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -232,8 +232,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
232 | { | 232 | { |
233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; | 233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; |
234 | 234 | ||
235 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 235 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
236 | SLAB_CTOR_CONSTRUCTOR) | ||
237 | inode_init_once(&ei->vfs_inode); | 236 | inode_init_once(&ei->vfs_inode); |
238 | } | 237 | } |
239 | 238 | ||
diff --git a/fs/affs/super.c b/fs/affs/super.c index c3986a1911b0..beff7d21e6e2 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -87,8 +87,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
87 | { | 87 | { |
88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; | 88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; |
89 | 89 | ||
90 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 90 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
91 | SLAB_CTOR_CONSTRUCTOR) { | ||
92 | init_MUTEX(&ei->i_link_lock); | 91 | init_MUTEX(&ei->i_link_lock); |
93 | init_MUTEX(&ei->i_ext_lock); | 92 | init_MUTEX(&ei->i_ext_lock); |
94 | inode_init_once(&ei->vfs_inode); | 93 | inode_init_once(&ei->vfs_inode); |
diff --git a/fs/afs/Makefile b/fs/afs/Makefile index 01545eb1d872..cf83e5d63512 100644 --- a/fs/afs/Makefile +++ b/fs/afs/Makefile | |||
@@ -18,7 +18,7 @@ kafs-objs := \ | |||
18 | security.o \ | 18 | security.o \ |
19 | server.o \ | 19 | server.o \ |
20 | super.o \ | 20 | super.o \ |
21 | use-rtnetlink.o \ | 21 | netdevices.o \ |
22 | vlclient.o \ | 22 | vlclient.o \ |
23 | vlocation.o \ | 23 | vlocation.o \ |
24 | vnode.o \ | 24 | vnode.o \ |
diff --git a/fs/afs/callback.c b/fs/afs/callback.c index 639399f0ab6f..9bdbf36a9aa9 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c | |||
@@ -468,7 +468,7 @@ int __init afs_callback_update_init(void) | |||
468 | /* | 468 | /* |
469 | * shut down the callback update process | 469 | * shut down the callback update process |
470 | */ | 470 | */ |
471 | void __exit afs_callback_update_kill(void) | 471 | void afs_callback_update_kill(void) |
472 | { | 472 | { |
473 | destroy_workqueue(afs_callback_update_worker); | 473 | destroy_workqueue(afs_callback_update_worker); |
474 | } | 474 | } |
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 6685f4cbccb3..d5b2ad6575bc 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -443,6 +443,7 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work) | |||
443 | reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; | 443 | reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; |
444 | reply.ia.mtu[loop] = htonl(ifs[loop].mtu); | 444 | reply.ia.mtu[loop] = htonl(ifs[loop].mtu); |
445 | } | 445 | } |
446 | kfree(ifs); | ||
446 | } | 447 | } |
447 | 448 | ||
448 | reply.cap.capcount = htonl(1); | 449 | reply.cap.capcount = htonl(1); |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index dac5b990c0cd..0c1e902f17a3 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -194,10 +194,7 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index, | |||
194 | 194 | ||
195 | page = read_mapping_page(dir->i_mapping, index, &file); | 195 | page = read_mapping_page(dir->i_mapping, index, &file); |
196 | if (!IS_ERR(page)) { | 196 | if (!IS_ERR(page)) { |
197 | wait_on_page_locked(page); | ||
198 | kmap(page); | 197 | kmap(page); |
199 | if (!PageUptodate(page)) | ||
200 | goto fail; | ||
201 | if (!PageChecked(page)) | 198 | if (!PageChecked(page)) |
202 | afs_dir_check_page(dir, page); | 199 | afs_dir_check_page(dir, page); |
203 | if (PageError(page)) | 200 | if (PageError(page)) |
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 2393d2a08d79..e54e6c2ad343 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c | |||
@@ -266,7 +266,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call, | |||
266 | call->unmarshall++; | 266 | call->unmarshall++; |
267 | 267 | ||
268 | if (call->count < PAGE_SIZE) { | 268 | if (call->count < PAGE_SIZE) { |
269 | buffer = kmap_atomic(call->reply3, KM_USER0); | 269 | page = call->reply3; |
270 | buffer = kmap_atomic(page, KM_USER0); | ||
270 | memset(buffer + PAGE_SIZE - call->count, 0, | 271 | memset(buffer + PAGE_SIZE - call->count, 0, |
271 | call->count); | 272 | call->count); |
272 | kunmap_atomic(buffer, KM_USER0); | 273 | kunmap_atomic(buffer, KM_USER0); |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 34665f7d7a19..d90c158cd934 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -349,7 +349,6 @@ struct afs_permits { | |||
349 | * record of one of a system's set of network interfaces | 349 | * record of one of a system's set of network interfaces |
350 | */ | 350 | */ |
351 | struct afs_interface { | 351 | struct afs_interface { |
352 | unsigned index; /* interface index */ | ||
353 | struct in_addr address; /* IPv4 address bound to interface */ | 352 | struct in_addr address; /* IPv4 address bound to interface */ |
354 | struct in_addr netmask; /* netmask applied to address */ | 353 | struct in_addr netmask; /* netmask applied to address */ |
355 | unsigned mtu; /* MTU of interface */ | 354 | unsigned mtu; /* MTU of interface */ |
@@ -392,7 +391,7 @@ extern void afs_give_up_callback(struct afs_vnode *); | |||
392 | extern void afs_dispatch_give_up_callbacks(struct work_struct *); | 391 | extern void afs_dispatch_give_up_callbacks(struct work_struct *); |
393 | extern void afs_flush_callback_breaks(struct afs_server *); | 392 | extern void afs_flush_callback_breaks(struct afs_server *); |
394 | extern int __init afs_callback_update_init(void); | 393 | extern int __init afs_callback_update_init(void); |
395 | extern void __exit afs_callback_update_kill(void); | 394 | extern void afs_callback_update_kill(void); |
396 | 395 | ||
397 | /* | 396 | /* |
398 | * cell.c | 397 | * cell.c |
@@ -564,7 +563,7 @@ extern void afs_fs_exit(void); | |||
564 | * use-rtnetlink.c | 563 | * use-rtnetlink.c |
565 | */ | 564 | */ |
566 | extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); | 565 | extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); |
567 | extern int afs_get_MAC_address(u8 [6]); | 566 | extern int afs_get_MAC_address(u8 *, size_t); |
568 | 567 | ||
569 | /* | 568 | /* |
570 | * vlclient.c | 569 | * vlclient.c |
@@ -591,7 +590,7 @@ extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *, | |||
591 | struct key *, | 590 | struct key *, |
592 | const char *, size_t); | 591 | const char *, size_t); |
593 | extern void afs_put_vlocation(struct afs_vlocation *); | 592 | extern void afs_put_vlocation(struct afs_vlocation *); |
594 | extern void __exit afs_vlocation_purge(void); | 593 | extern void afs_vlocation_purge(void); |
595 | 594 | ||
596 | /* | 595 | /* |
597 | * vnode.c | 596 | * vnode.c |
diff --git a/fs/afs/main.c b/fs/afs/main.c index 40c2704e7557..80ec6fd19a73 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c | |||
@@ -54,7 +54,7 @@ static int __init afs_get_client_UUID(void) | |||
54 | 54 | ||
55 | /* read the MAC address of one of the external interfaces and construct | 55 | /* read the MAC address of one of the external interfaces and construct |
56 | * a UUID from it */ | 56 | * a UUID from it */ |
57 | ret = afs_get_MAC_address(afs_uuid.node); | 57 | ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node)); |
58 | if (ret < 0) | 58 | if (ret < 0) |
59 | return ret; | 59 | return ret; |
60 | 60 | ||
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index b905ae37f912..034fcfd4e330 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -68,13 +68,11 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | ret = -EIO; | 70 | ret = -EIO; |
71 | wait_on_page_locked(page); | ||
72 | buf = kmap(page); | ||
73 | if (!PageUptodate(page)) | ||
74 | goto out_free; | ||
75 | if (PageError(page)) | 71 | if (PageError(page)) |
76 | goto out_free; | 72 | goto out_free; |
77 | 73 | ||
74 | buf = kmap(page); | ||
75 | |||
78 | /* examine the symlink's contents */ | 76 | /* examine the symlink's contents */ |
79 | size = vnode->status.size; | 77 | size = vnode->status.size; |
80 | _debug("symlink to %*.*s", (int) size, (int) size, buf); | 78 | _debug("symlink to %*.*s", (int) size, (int) size, buf); |
@@ -91,8 +89,8 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key) | |||
91 | 89 | ||
92 | ret = 0; | 90 | ret = 0; |
93 | 91 | ||
94 | out_free: | ||
95 | kunmap(page); | 92 | kunmap(page); |
93 | out_free: | ||
96 | page_cache_release(page); | 94 | page_cache_release(page); |
97 | out: | 95 | out: |
98 | _leave(" = %d", ret); | 96 | _leave(" = %d", ret); |
@@ -171,8 +169,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) | |||
171 | } | 169 | } |
172 | 170 | ||
173 | ret = -EIO; | 171 | ret = -EIO; |
174 | wait_on_page_locked(page); | 172 | if (PageError(page)) |
175 | if (!PageUptodate(page) || PageError(page)) | ||
176 | goto error; | 173 | goto error; |
177 | 174 | ||
178 | buf = kmap(page); | 175 | buf = kmap(page); |
diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c new file mode 100644 index 000000000000..fc27d4b52e5f --- /dev/null +++ b/fs/afs/netdevices.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* AFS network device helpers | ||
2 | * | ||
3 | * Copyright (c) 2007 Patrick McHardy <kaber@trash.net> | ||
4 | */ | ||
5 | |||
6 | #include <linux/string.h> | ||
7 | #include <linux/rtnetlink.h> | ||
8 | #include <linux/inetdevice.h> | ||
9 | #include <linux/netdevice.h> | ||
10 | #include <linux/if_arp.h> | ||
11 | #include "internal.h" | ||
12 | |||
13 | /* | ||
14 | * get a MAC address from a random ethernet interface that has a real one | ||
15 | * - the buffer will normally be 6 bytes in size | ||
16 | */ | ||
17 | int afs_get_MAC_address(u8 *mac, size_t maclen) | ||
18 | { | ||
19 | struct net_device *dev; | ||
20 | int ret = -ENODEV; | ||
21 | |||
22 | if (maclen != ETH_ALEN) | ||
23 | BUG(); | ||
24 | |||
25 | rtnl_lock(); | ||
26 | dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); | ||
27 | if (dev) { | ||
28 | memcpy(mac, dev->dev_addr, maclen); | ||
29 | ret = 0; | ||
30 | } | ||
31 | rtnl_unlock(); | ||
32 | return ret; | ||
33 | } | ||
34 | |||
35 | /* | ||
36 | * get a list of this system's interface IPv4 addresses, netmasks and MTUs | ||
37 | * - maxbufs must be at least 1 | ||
38 | * - returns the number of interface records in the buffer | ||
39 | */ | ||
40 | int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, | ||
41 | bool wantloopback) | ||
42 | { | ||
43 | struct net_device *dev; | ||
44 | struct in_device *idev; | ||
45 | int n = 0; | ||
46 | |||
47 | ASSERT(maxbufs > 0); | ||
48 | |||
49 | rtnl_lock(); | ||
50 | for_each_netdev(dev) { | ||
51 | if (dev->type == ARPHRD_LOOPBACK && !wantloopback) | ||
52 | continue; | ||
53 | idev = __in_dev_get_rtnl(dev); | ||
54 | if (!idev) | ||
55 | continue; | ||
56 | for_primary_ifa(idev) { | ||
57 | bufs[n].address.s_addr = ifa->ifa_address; | ||
58 | bufs[n].netmask.s_addr = ifa->ifa_mask; | ||
59 | bufs[n].mtu = dev->mtu; | ||
60 | n++; | ||
61 | if (n >= maxbufs) | ||
62 | goto out; | ||
63 | } endfor_ifa(idev); | ||
64 | } | ||
65 | out: | ||
66 | rtnl_unlock(); | ||
67 | return n; | ||
68 | } | ||
diff --git a/fs/afs/super.c b/fs/afs/super.c index cebd03c91f57..7030d76155fc 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/parser.h> | ||
23 | #include "internal.h" | 24 | #include "internal.h" |
24 | 25 | ||
25 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ | 26 | #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ |
@@ -42,7 +43,7 @@ struct file_system_type afs_fs_type = { | |||
42 | .name = "afs", | 43 | .name = "afs", |
43 | .get_sb = afs_get_sb, | 44 | .get_sb = afs_get_sb, |
44 | .kill_sb = kill_anon_super, | 45 | .kill_sb = kill_anon_super, |
45 | .fs_flags = FS_BINARY_MOUNTDATA, | 46 | .fs_flags = 0, |
46 | }; | 47 | }; |
47 | 48 | ||
48 | static const struct super_operations afs_super_ops = { | 49 | static const struct super_operations afs_super_ops = { |
@@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = { | |||
58 | static struct kmem_cache *afs_inode_cachep; | 59 | static struct kmem_cache *afs_inode_cachep; |
59 | static atomic_t afs_count_active_inodes; | 60 | static atomic_t afs_count_active_inodes; |
60 | 61 | ||
62 | enum { | ||
63 | afs_no_opt, | ||
64 | afs_opt_cell, | ||
65 | afs_opt_rwpath, | ||
66 | afs_opt_vol, | ||
67 | }; | ||
68 | |||
69 | static const match_table_t afs_options_list = { | ||
70 | { afs_opt_cell, "cell=%s" }, | ||
71 | { afs_opt_rwpath, "rwpath" }, | ||
72 | { afs_opt_vol, "vol=%s" }, | ||
73 | { afs_no_opt, NULL }, | ||
74 | }; | ||
75 | |||
61 | /* | 76 | /* |
62 | * initialise the filesystem | 77 | * initialise the filesystem |
63 | */ | 78 | */ |
@@ -115,31 +130,6 @@ void __exit afs_fs_exit(void) | |||
115 | } | 130 | } |
116 | 131 | ||
117 | /* | 132 | /* |
118 | * check that an argument has a value | ||
119 | */ | ||
120 | static int want_arg(char **_value, const char *option) | ||
121 | { | ||
122 | if (!_value || !*_value || !**_value) { | ||
123 | printk(KERN_NOTICE "kAFS: %s: argument missing\n", option); | ||
124 | return 0; | ||
125 | } | ||
126 | return 1; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * check that there's no subsequent value | ||
131 | */ | ||
132 | static int want_no_value(char *const *_value, const char *option) | ||
133 | { | ||
134 | if (*_value && **_value) { | ||
135 | printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n", | ||
136 | option, *_value); | ||
137 | return 0; | ||
138 | } | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * parse the mount options | 133 | * parse the mount options |
144 | * - this function has been shamelessly adapted from the ext3 fs which | 134 | * - this function has been shamelessly adapted from the ext3 fs which |
145 | * shamelessly adapted it from the msdos fs | 135 | * shamelessly adapted it from the msdos fs |
@@ -148,48 +138,46 @@ static int afs_parse_options(struct afs_mount_params *params, | |||
148 | char *options, const char **devname) | 138 | char *options, const char **devname) |
149 | { | 139 | { |
150 | struct afs_cell *cell; | 140 | struct afs_cell *cell; |
151 | char *key, *value; | 141 | substring_t args[MAX_OPT_ARGS]; |
152 | int ret; | 142 | char *p; |
143 | int token; | ||
153 | 144 | ||
154 | _enter("%s", options); | 145 | _enter("%s", options); |
155 | 146 | ||
156 | options[PAGE_SIZE - 1] = 0; | 147 | options[PAGE_SIZE - 1] = 0; |
157 | 148 | ||
158 | ret = 0; | 149 | while ((p = strsep(&options, ","))) { |
159 | while ((key = strsep(&options, ","))) { | 150 | if (!*p) |
160 | value = strchr(key, '='); | 151 | continue; |
161 | if (value) | ||
162 | *value++ = 0; | ||
163 | |||
164 | _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-"); | ||
165 | 152 | ||
166 | if (strcmp(key, "rwpath") == 0) { | 153 | token = match_token(p, afs_options_list, args); |
167 | if (!want_no_value(&value, "rwpath")) | 154 | switch (token) { |
168 | return -EINVAL; | 155 | case afs_opt_cell: |
169 | params->rwpath = 1; | 156 | cell = afs_cell_lookup(args[0].from, |
170 | } else if (strcmp(key, "vol") == 0) { | 157 | args[0].to - args[0].from); |
171 | if (!want_arg(&value, "vol")) | ||
172 | return -EINVAL; | ||
173 | *devname = value; | ||
174 | } else if (strcmp(key, "cell") == 0) { | ||
175 | if (!want_arg(&value, "cell")) | ||
176 | return -EINVAL; | ||
177 | cell = afs_cell_lookup(value, strlen(value)); | ||
178 | if (IS_ERR(cell)) | 158 | if (IS_ERR(cell)) |
179 | return PTR_ERR(cell); | 159 | return PTR_ERR(cell); |
180 | afs_put_cell(params->cell); | 160 | afs_put_cell(params->cell); |
181 | params->cell = cell; | 161 | params->cell = cell; |
182 | } else { | 162 | break; |
183 | printk("kAFS: Unknown mount option: '%s'\n", key); | 163 | |
184 | ret = -EINVAL; | 164 | case afs_opt_rwpath: |
185 | goto error; | 165 | params->rwpath = 1; |
166 | break; | ||
167 | |||
168 | case afs_opt_vol: | ||
169 | *devname = args[0].from; | ||
170 | break; | ||
171 | |||
172 | default: | ||
173 | printk(KERN_ERR "kAFS:" | ||
174 | " Unknown or invalid mount option: '%s'\n", p); | ||
175 | return -EINVAL; | ||
186 | } | 176 | } |
187 | } | 177 | } |
188 | 178 | ||
189 | ret = 0; | 179 | _leave(" = 0"); |
190 | error: | 180 | return 0; |
191 | _leave(" = %d", ret); | ||
192 | return ret; | ||
193 | } | 181 | } |
194 | 182 | ||
195 | /* | 183 | /* |
@@ -361,7 +349,6 @@ error: | |||
361 | 349 | ||
362 | /* | 350 | /* |
363 | * get an AFS superblock | 351 | * get an AFS superblock |
364 | * - TODO: don't use get_sb_nodev(), but rather call sget() directly | ||
365 | */ | 352 | */ |
366 | static int afs_get_sb(struct file_system_type *fs_type, | 353 | static int afs_get_sb(struct file_system_type *fs_type, |
367 | int flags, | 354 | int flags, |
@@ -386,7 +373,6 @@ static int afs_get_sb(struct file_system_type *fs_type, | |||
386 | goto error; | 373 | goto error; |
387 | } | 374 | } |
388 | 375 | ||
389 | |||
390 | ret = afs_parse_device_name(¶ms, dev_name); | 376 | ret = afs_parse_device_name(¶ms, dev_name); |
391 | if (ret < 0) | 377 | if (ret < 0) |
392 | goto error; | 378 | goto error; |
@@ -467,8 +453,7 @@ static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, | |||
467 | { | 453 | { |
468 | struct afs_vnode *vnode = _vnode; | 454 | struct afs_vnode *vnode = _vnode; |
469 | 455 | ||
470 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 456 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
471 | SLAB_CTOR_CONSTRUCTOR) { | ||
472 | memset(vnode, 0, sizeof(*vnode)); | 457 | memset(vnode, 0, sizeof(*vnode)); |
473 | inode_init_once(&vnode->vfs_inode); | 458 | inode_init_once(&vnode->vfs_inode); |
474 | init_waitqueue_head(&vnode->update_waitq); | 459 | init_waitqueue_head(&vnode->update_waitq); |
diff --git a/fs/afs/use-rtnetlink.c b/fs/afs/use-rtnetlink.c deleted file mode 100644 index f8991c700e02..000000000000 --- a/fs/afs/use-rtnetlink.c +++ /dev/null | |||
@@ -1,473 +0,0 @@ | |||
1 | /* RTNETLINK client | ||
2 | * | ||
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/netlink.h> | ||
12 | #include <linux/rtnetlink.h> | ||
13 | #include <linux/if_addr.h> | ||
14 | #include <linux/if_arp.h> | ||
15 | #include <linux/inetdevice.h> | ||
16 | #include <net/netlink.h> | ||
17 | #include "internal.h" | ||
18 | |||
19 | struct afs_rtm_desc { | ||
20 | struct socket *nlsock; | ||
21 | struct afs_interface *bufs; | ||
22 | u8 *mac; | ||
23 | size_t nbufs; | ||
24 | size_t maxbufs; | ||
25 | void *data; | ||
26 | ssize_t datalen; | ||
27 | size_t datamax; | ||
28 | int msg_seq; | ||
29 | unsigned mac_index; | ||
30 | bool wantloopback; | ||
31 | int (*parse)(struct afs_rtm_desc *, struct nlmsghdr *); | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * parse an RTM_GETADDR response | ||
36 | */ | ||
37 | static int afs_rtm_getaddr_parse(struct afs_rtm_desc *desc, | ||
38 | struct nlmsghdr *nlhdr) | ||
39 | { | ||
40 | struct afs_interface *this; | ||
41 | struct ifaddrmsg *ifa; | ||
42 | struct rtattr *rtattr; | ||
43 | const char *name; | ||
44 | size_t len; | ||
45 | |||
46 | ifa = (struct ifaddrmsg *) NLMSG_DATA(nlhdr); | ||
47 | |||
48 | _enter("{ix=%d,af=%d}", ifa->ifa_index, ifa->ifa_family); | ||
49 | |||
50 | if (ifa->ifa_family != AF_INET) { | ||
51 | _leave(" = 0 [family %d]", ifa->ifa_family); | ||
52 | return 0; | ||
53 | } | ||
54 | if (desc->nbufs >= desc->maxbufs) { | ||
55 | _leave(" = 0 [max %zu/%zu]", desc->nbufs, desc->maxbufs); | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | this = &desc->bufs[desc->nbufs]; | ||
60 | |||
61 | this->index = ifa->ifa_index; | ||
62 | this->netmask.s_addr = inet_make_mask(ifa->ifa_prefixlen); | ||
63 | this->mtu = 0; | ||
64 | |||
65 | rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)); | ||
66 | len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifaddrmsg)); | ||
67 | |||
68 | name = "unknown"; | ||
69 | for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { | ||
70 | switch (rtattr->rta_type) { | ||
71 | case IFA_ADDRESS: | ||
72 | memcpy(&this->address, RTA_DATA(rtattr), 4); | ||
73 | break; | ||
74 | case IFA_LABEL: | ||
75 | name = RTA_DATA(rtattr); | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT, | ||
81 | name, NIPQUAD(this->address), NIPQUAD(this->netmask)); | ||
82 | |||
83 | desc->nbufs++; | ||
84 | _leave(" = 0"); | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* | ||
89 | * parse an RTM_GETLINK response for MTUs | ||
90 | */ | ||
91 | static int afs_rtm_getlink_if_parse(struct afs_rtm_desc *desc, | ||
92 | struct nlmsghdr *nlhdr) | ||
93 | { | ||
94 | struct afs_interface *this; | ||
95 | struct ifinfomsg *ifi; | ||
96 | struct rtattr *rtattr; | ||
97 | const char *name; | ||
98 | size_t len, loop; | ||
99 | |||
100 | ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); | ||
101 | |||
102 | _enter("{ix=%d}", ifi->ifi_index); | ||
103 | |||
104 | for (loop = 0; loop < desc->nbufs; loop++) { | ||
105 | this = &desc->bufs[loop]; | ||
106 | if (this->index == ifi->ifi_index) | ||
107 | goto found; | ||
108 | } | ||
109 | |||
110 | _leave(" = 0 [no match]"); | ||
111 | return 0; | ||
112 | |||
113 | found: | ||
114 | if (ifi->ifi_type == ARPHRD_LOOPBACK && !desc->wantloopback) { | ||
115 | _leave(" = 0 [loopback]"); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); | ||
120 | len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); | ||
121 | |||
122 | name = "unknown"; | ||
123 | for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { | ||
124 | switch (rtattr->rta_type) { | ||
125 | case IFLA_MTU: | ||
126 | memcpy(&this->mtu, RTA_DATA(rtattr), 4); | ||
127 | break; | ||
128 | case IFLA_IFNAME: | ||
129 | name = RTA_DATA(rtattr); | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", | ||
135 | name, NIPQUAD(this->address), NIPQUAD(this->netmask), | ||
136 | this->mtu); | ||
137 | |||
138 | _leave(" = 0"); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * parse an RTM_GETLINK response for the MAC address belonging to the lowest | ||
144 | * non-internal interface | ||
145 | */ | ||
146 | static int afs_rtm_getlink_mac_parse(struct afs_rtm_desc *desc, | ||
147 | struct nlmsghdr *nlhdr) | ||
148 | { | ||
149 | struct ifinfomsg *ifi; | ||
150 | struct rtattr *rtattr; | ||
151 | const char *name; | ||
152 | size_t remain, len; | ||
153 | bool set; | ||
154 | |||
155 | ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); | ||
156 | |||
157 | _enter("{ix=%d}", ifi->ifi_index); | ||
158 | |||
159 | if (ifi->ifi_index >= desc->mac_index) { | ||
160 | _leave(" = 0 [high]"); | ||
161 | return 0; | ||
162 | } | ||
163 | if (ifi->ifi_type == ARPHRD_LOOPBACK) { | ||
164 | _leave(" = 0 [loopback]"); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); | ||
169 | remain = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); | ||
170 | |||
171 | name = "unknown"; | ||
172 | set = false; | ||
173 | for (; RTA_OK(rtattr, remain); rtattr = RTA_NEXT(rtattr, remain)) { | ||
174 | switch (rtattr->rta_type) { | ||
175 | case IFLA_ADDRESS: | ||
176 | len = RTA_PAYLOAD(rtattr); | ||
177 | memcpy(desc->mac, RTA_DATA(rtattr), | ||
178 | min_t(size_t, len, 6)); | ||
179 | desc->mac_index = ifi->ifi_index; | ||
180 | set = true; | ||
181 | break; | ||
182 | case IFLA_IFNAME: | ||
183 | name = RTA_DATA(rtattr); | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | if (set) | ||
189 | _debug("%s: %02x:%02x:%02x:%02x:%02x:%02x", | ||
190 | name, | ||
191 | desc->mac[0], desc->mac[1], desc->mac[2], | ||
192 | desc->mac[3], desc->mac[4], desc->mac[5]); | ||
193 | |||
194 | _leave(" = 0"); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * read the rtnetlink response and pass to parsing routine | ||
200 | */ | ||
201 | static int afs_read_rtm(struct afs_rtm_desc *desc) | ||
202 | { | ||
203 | struct nlmsghdr *nlhdr, tmphdr; | ||
204 | struct msghdr msg; | ||
205 | struct kvec iov[1]; | ||
206 | void *data; | ||
207 | bool last = false; | ||
208 | int len, ret, remain; | ||
209 | |||
210 | _enter(""); | ||
211 | |||
212 | do { | ||
213 | /* first of all peek to see how big the packet is */ | ||
214 | memset(&msg, 0, sizeof(msg)); | ||
215 | iov[0].iov_base = &tmphdr; | ||
216 | iov[0].iov_len = sizeof(tmphdr); | ||
217 | len = kernel_recvmsg(desc->nlsock, &msg, iov, 1, | ||
218 | sizeof(tmphdr), MSG_PEEK | MSG_TRUNC); | ||
219 | if (len < 0) { | ||
220 | _leave(" = %d [peek]", len); | ||
221 | return len; | ||
222 | } | ||
223 | if (len == 0) | ||
224 | continue; | ||
225 | if (len < sizeof(tmphdr) || len < NLMSG_PAYLOAD(&tmphdr, 0)) { | ||
226 | _leave(" = -EMSGSIZE"); | ||
227 | return -EMSGSIZE; | ||
228 | } | ||
229 | |||
230 | if (desc->datamax < len) { | ||
231 | kfree(desc->data); | ||
232 | desc->data = NULL; | ||
233 | data = kmalloc(len, GFP_KERNEL); | ||
234 | if (!data) | ||
235 | return -ENOMEM; | ||
236 | desc->data = data; | ||
237 | } | ||
238 | desc->datamax = len; | ||
239 | |||
240 | /* read all the data from this packet */ | ||
241 | iov[0].iov_base = desc->data; | ||
242 | iov[0].iov_len = desc->datamax; | ||
243 | desc->datalen = kernel_recvmsg(desc->nlsock, &msg, iov, 1, | ||
244 | desc->datamax, 0); | ||
245 | if (desc->datalen < 0) { | ||
246 | _leave(" = %zd [recv]", desc->datalen); | ||
247 | return desc->datalen; | ||
248 | } | ||
249 | |||
250 | nlhdr = desc->data; | ||
251 | |||
252 | /* check if the header is valid */ | ||
253 | if (!NLMSG_OK(nlhdr, desc->datalen) || | ||
254 | nlhdr->nlmsg_type == NLMSG_ERROR) { | ||
255 | _leave(" = -EIO"); | ||
256 | return -EIO; | ||
257 | } | ||
258 | |||
259 | /* see if this is the last message */ | ||
260 | if (nlhdr->nlmsg_type == NLMSG_DONE || | ||
261 | !(nlhdr->nlmsg_flags & NLM_F_MULTI)) | ||
262 | last = true; | ||
263 | |||
264 | /* parse the bits we got this time */ | ||
265 | nlmsg_for_each_msg(nlhdr, desc->data, desc->datalen, remain) { | ||
266 | ret = desc->parse(desc, nlhdr); | ||
267 | if (ret < 0) { | ||
268 | _leave(" = %d [parse]", ret); | ||
269 | return ret; | ||
270 | } | ||
271 | } | ||
272 | |||
273 | } while (!last); | ||
274 | |||
275 | _leave(" = 0"); | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * list the interface bound addresses to get the address and netmask | ||
281 | */ | ||
282 | static int afs_rtm_getaddr(struct afs_rtm_desc *desc) | ||
283 | { | ||
284 | struct msghdr msg; | ||
285 | struct kvec iov[1]; | ||
286 | int ret; | ||
287 | |||
288 | struct { | ||
289 | struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); | ||
290 | struct ifaddrmsg addr_msg __attribute__((aligned(NLMSG_ALIGNTO))); | ||
291 | } request; | ||
292 | |||
293 | _enter(""); | ||
294 | |||
295 | memset(&request, 0, sizeof(request)); | ||
296 | |||
297 | request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); | ||
298 | request.nl_msg.nlmsg_type = RTM_GETADDR; | ||
299 | request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; | ||
300 | request.nl_msg.nlmsg_seq = desc->msg_seq++; | ||
301 | request.nl_msg.nlmsg_pid = 0; | ||
302 | |||
303 | memset(&msg, 0, sizeof(msg)); | ||
304 | iov[0].iov_base = &request; | ||
305 | iov[0].iov_len = sizeof(request); | ||
306 | |||
307 | ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); | ||
308 | _leave(" = %d", ret); | ||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * list the interface link statuses to get the MTUs | ||
314 | */ | ||
315 | static int afs_rtm_getlink(struct afs_rtm_desc *desc) | ||
316 | { | ||
317 | struct msghdr msg; | ||
318 | struct kvec iov[1]; | ||
319 | int ret; | ||
320 | |||
321 | struct { | ||
322 | struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); | ||
323 | struct ifinfomsg link_msg __attribute__((aligned(NLMSG_ALIGNTO))); | ||
324 | } request; | ||
325 | |||
326 | _enter(""); | ||
327 | |||
328 | memset(&request, 0, sizeof(request)); | ||
329 | |||
330 | request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); | ||
331 | request.nl_msg.nlmsg_type = RTM_GETLINK; | ||
332 | request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; | ||
333 | request.nl_msg.nlmsg_seq = desc->msg_seq++; | ||
334 | request.nl_msg.nlmsg_pid = 0; | ||
335 | |||
336 | memset(&msg, 0, sizeof(msg)); | ||
337 | iov[0].iov_base = &request; | ||
338 | iov[0].iov_len = sizeof(request); | ||
339 | |||
340 | ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); | ||
341 | _leave(" = %d", ret); | ||
342 | return ret; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * cull any interface records for which there isn't an MTU value | ||
347 | */ | ||
348 | static void afs_cull_interfaces(struct afs_rtm_desc *desc) | ||
349 | { | ||
350 | struct afs_interface *bufs = desc->bufs; | ||
351 | size_t nbufs = desc->nbufs; | ||
352 | int loop, point = 0; | ||
353 | |||
354 | _enter("{%zu}", nbufs); | ||
355 | |||
356 | for (loop = 0; loop < nbufs; loop++) { | ||
357 | if (desc->bufs[loop].mtu != 0) { | ||
358 | if (loop != point) { | ||
359 | ASSERTCMP(loop, >, point); | ||
360 | bufs[point] = bufs[loop]; | ||
361 | } | ||
362 | point++; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | desc->nbufs = point; | ||
367 | _leave(" [%zu/%zu]", desc->nbufs, nbufs); | ||
368 | } | ||
369 | |||
370 | /* | ||
371 | * get a list of this system's interface IPv4 addresses, netmasks and MTUs | ||
372 | * - returns the number of interface records in the buffer | ||
373 | */ | ||
374 | int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, | ||
375 | bool wantloopback) | ||
376 | { | ||
377 | struct afs_rtm_desc desc; | ||
378 | int ret, loop; | ||
379 | |||
380 | _enter(""); | ||
381 | |||
382 | memset(&desc, 0, sizeof(desc)); | ||
383 | desc.bufs = bufs; | ||
384 | desc.maxbufs = maxbufs; | ||
385 | desc.wantloopback = wantloopback; | ||
386 | |||
387 | ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, | ||
388 | &desc.nlsock); | ||
389 | if (ret < 0) { | ||
390 | _leave(" = %d [sock]", ret); | ||
391 | return ret; | ||
392 | } | ||
393 | |||
394 | /* issue RTM_GETADDR */ | ||
395 | desc.parse = afs_rtm_getaddr_parse; | ||
396 | ret = afs_rtm_getaddr(&desc); | ||
397 | if (ret < 0) | ||
398 | goto error; | ||
399 | ret = afs_read_rtm(&desc); | ||
400 | if (ret < 0) | ||
401 | goto error; | ||
402 | |||
403 | /* issue RTM_GETLINK */ | ||
404 | desc.parse = afs_rtm_getlink_if_parse; | ||
405 | ret = afs_rtm_getlink(&desc); | ||
406 | if (ret < 0) | ||
407 | goto error; | ||
408 | ret = afs_read_rtm(&desc); | ||
409 | if (ret < 0) | ||
410 | goto error; | ||
411 | |||
412 | afs_cull_interfaces(&desc); | ||
413 | ret = desc.nbufs; | ||
414 | |||
415 | for (loop = 0; loop < ret; loop++) | ||
416 | _debug("[%d] "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", | ||
417 | bufs[loop].index, | ||
418 | NIPQUAD(bufs[loop].address), | ||
419 | NIPQUAD(bufs[loop].netmask), | ||
420 | bufs[loop].mtu); | ||
421 | |||
422 | error: | ||
423 | kfree(desc.data); | ||
424 | sock_release(desc.nlsock); | ||
425 | _leave(" = %d", ret); | ||
426 | return ret; | ||
427 | } | ||
428 | |||
429 | /* | ||
430 | * get a MAC address from a random ethernet interface that has a real one | ||
431 | * - the buffer should be 6 bytes in size | ||
432 | */ | ||
433 | int afs_get_MAC_address(u8 mac[6]) | ||
434 | { | ||
435 | struct afs_rtm_desc desc; | ||
436 | int ret; | ||
437 | |||
438 | _enter(""); | ||
439 | |||
440 | memset(&desc, 0, sizeof(desc)); | ||
441 | desc.mac = mac; | ||
442 | desc.mac_index = UINT_MAX; | ||
443 | |||
444 | ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, | ||
445 | &desc.nlsock); | ||
446 | if (ret < 0) { | ||
447 | _leave(" = %d [sock]", ret); | ||
448 | return ret; | ||
449 | } | ||
450 | |||
451 | /* issue RTM_GETLINK */ | ||
452 | desc.parse = afs_rtm_getlink_mac_parse; | ||
453 | ret = afs_rtm_getlink(&desc); | ||
454 | if (ret < 0) | ||
455 | goto error; | ||
456 | ret = afs_read_rtm(&desc); | ||
457 | if (ret < 0) | ||
458 | goto error; | ||
459 | |||
460 | if (desc.mac_index < UINT_MAX) { | ||
461 | /* got a MAC address */ | ||
462 | _debug("[%d] %02x:%02x:%02x:%02x:%02x:%02x", | ||
463 | desc.mac_index, | ||
464 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||
465 | } else { | ||
466 | ret = -ENONET; | ||
467 | } | ||
468 | |||
469 | error: | ||
470 | sock_release(desc.nlsock); | ||
471 | _leave(" = %d", ret); | ||
472 | return ret; | ||
473 | } | ||
diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 6c8e95a7c2c9..3370cdb72566 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c | |||
@@ -602,7 +602,7 @@ int __init afs_vlocation_update_init(void) | |||
602 | /* | 602 | /* |
603 | * discard all the volume location records for rmmod | 603 | * discard all the volume location records for rmmod |
604 | */ | 604 | */ |
605 | void __exit afs_vlocation_purge(void) | 605 | void afs_vlocation_purge(void) |
606 | { | 606 | { |
607 | afs_vlocation_timeout = 0; | 607 | afs_vlocation_timeout = 0; |
608 | 608 | ||
@@ -68,10 +68,8 @@ static void aio_queue_work(struct kioctx *); | |||
68 | */ | 68 | */ |
69 | static int __init aio_setup(void) | 69 | static int __init aio_setup(void) |
70 | { | 70 | { |
71 | kiocb_cachep = kmem_cache_create("kiocb", sizeof(struct kiocb), | 71 | kiocb_cachep = KMEM_CACHE(kiocb, SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
72 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 72 | kioctx_cachep = KMEM_CACHE(kioctx,SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
73 | kioctx_cachep = kmem_cache_create("kioctx", sizeof(struct kioctx), | ||
74 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | ||
75 | 73 | ||
76 | aio_wq = create_workqueue("aio"); | 74 | aio_wq = create_workqueue("aio"); |
77 | 75 | ||
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index cc6cc8ed2e39..fe96108a788d 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -293,8 +293,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
293 | { | 293 | { |
294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; | 294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; |
295 | 295 | ||
296 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 296 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
297 | SLAB_CTOR_CONSTRUCTOR) { | ||
298 | inode_init_once(&bi->vfs_inode); | 297 | inode_init_once(&bi->vfs_inode); |
299 | } | 298 | } |
300 | } | 299 | } |
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 93d6219243ad..edc08d89aabc 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -248,8 +248,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
248 | { | 248 | { |
249 | struct bfs_inode_info *bi = foo; | 249 | struct bfs_inode_info *bi = foo; |
250 | 250 | ||
251 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 251 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
252 | SLAB_CTOR_CONSTRUCTOR) | ||
253 | inode_init_once(&bi->vfs_inode); | 252 | inode_init_once(&bi->vfs_inode); |
254 | } | 253 | } |
255 | 254 | ||
@@ -1193,8 +1193,7 @@ static void __init biovec_init_slabs(void) | |||
1193 | 1193 | ||
1194 | static int __init init_bio(void) | 1194 | static int __init init_bio(void) |
1195 | { | 1195 | { |
1196 | bio_slab = kmem_cache_create("bio", sizeof(struct bio), 0, | 1196 | bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); |
1197 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | ||
1198 | 1197 | ||
1199 | biovec_init_slabs(); | 1198 | biovec_init_slabs(); |
1200 | 1199 | ||
diff --git a/fs/block_dev.c b/fs/block_dev.c index 575076c018f4..f02b7bdd9864 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -55,10 +55,12 @@ static sector_t max_block(struct block_device *bdev) | |||
55 | return retval; | 55 | return retval; |
56 | } | 56 | } |
57 | 57 | ||
58 | /* Kill _all_ buffers, dirty or not.. */ | 58 | /* Kill _all_ buffers and pagecache , dirty or not.. */ |
59 | static void kill_bdev(struct block_device *bdev) | 59 | static void kill_bdev(struct block_device *bdev) |
60 | { | 60 | { |
61 | invalidate_bdev(bdev, 1); | 61 | if (bdev->bd_inode->i_mapping->nrpages == 0) |
62 | return; | ||
63 | invalidate_bh_lrus(); | ||
62 | truncate_inode_pages(bdev->bd_inode->i_mapping, 0); | 64 | truncate_inode_pages(bdev->bd_inode->i_mapping, 0); |
63 | } | 65 | } |
64 | 66 | ||
@@ -455,9 +457,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
455 | struct bdev_inode *ei = (struct bdev_inode *) foo; | 457 | struct bdev_inode *ei = (struct bdev_inode *) foo; |
456 | struct block_device *bdev = &ei->bdev; | 458 | struct block_device *bdev = &ei->bdev; |
457 | 459 | ||
458 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 460 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
459 | SLAB_CTOR_CONSTRUCTOR) | ||
460 | { | ||
461 | memset(bdev, 0, sizeof(*bdev)); | 461 | memset(bdev, 0, sizeof(*bdev)); |
462 | mutex_init(&bdev->bd_mutex); | 462 | mutex_init(&bdev->bd_mutex); |
463 | sema_init(&bdev->bd_mount_sem, 1); | 463 | sema_init(&bdev->bd_mount_sem, 1); |
@@ -1478,7 +1478,7 @@ int __invalidate_device(struct block_device *bdev) | |||
1478 | res = invalidate_inodes(sb); | 1478 | res = invalidate_inodes(sb); |
1479 | drop_super(sb); | 1479 | drop_super(sb); |
1480 | } | 1480 | } |
1481 | invalidate_bdev(bdev, 0); | 1481 | invalidate_bdev(bdev); |
1482 | return res; | 1482 | return res; |
1483 | } | 1483 | } |
1484 | EXPORT_SYMBOL(__invalidate_device); | 1484 | EXPORT_SYMBOL(__invalidate_device); |
diff --git a/fs/buffer.c b/fs/buffer.c index 1d0852fa728b..7db24b9e5449 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/bit_spinlock.h> | 44 | #include <linux/bit_spinlock.h> |
45 | 45 | ||
46 | static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); | 46 | static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); |
47 | static void invalidate_bh_lrus(void); | ||
48 | 47 | ||
49 | #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers) | 48 | #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers) |
50 | 49 | ||
@@ -333,7 +332,7 @@ out: | |||
333 | we think the disk contains more recent information than the buffercache. | 332 | we think the disk contains more recent information than the buffercache. |
334 | The update == 1 pass marks the buffers we need to update, the update == 2 | 333 | The update == 1 pass marks the buffers we need to update, the update == 2 |
335 | pass does the actual I/O. */ | 334 | pass does the actual I/O. */ |
336 | void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) | 335 | void invalidate_bdev(struct block_device *bdev) |
337 | { | 336 | { |
338 | struct address_space *mapping = bdev->bd_inode->i_mapping; | 337 | struct address_space *mapping = bdev->bd_inode->i_mapping; |
339 | 338 | ||
@@ -341,11 +340,6 @@ void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) | |||
341 | return; | 340 | return; |
342 | 341 | ||
343 | invalidate_bh_lrus(); | 342 | invalidate_bh_lrus(); |
344 | /* | ||
345 | * FIXME: what about destroy_dirty_buffers? | ||
346 | * We really want to use invalidate_inode_pages2() for | ||
347 | * that, but not until that's cleaned up. | ||
348 | */ | ||
349 | invalidate_mapping_pages(mapping, 0, -1); | 343 | invalidate_mapping_pages(mapping, 0, -1); |
350 | } | 344 | } |
351 | 345 | ||
@@ -1408,7 +1402,7 @@ static void invalidate_bh_lru(void *arg) | |||
1408 | put_cpu_var(bh_lrus); | 1402 | put_cpu_var(bh_lrus); |
1409 | } | 1403 | } |
1410 | 1404 | ||
1411 | static void invalidate_bh_lrus(void) | 1405 | void invalidate_bh_lrus(void) |
1412 | { | 1406 | { |
1413 | on_each_cpu(invalidate_bh_lru, NULL, 1, 1); | 1407 | on_each_cpu(invalidate_bh_lru, NULL, 1, 1); |
1414 | } | 1408 | } |
@@ -1700,17 +1694,8 @@ done: | |||
1700 | * clean. Someone wrote them back by hand with | 1694 | * clean. Someone wrote them back by hand with |
1701 | * ll_rw_block/submit_bh. A rare case. | 1695 | * ll_rw_block/submit_bh. A rare case. |
1702 | */ | 1696 | */ |
1703 | int uptodate = 1; | ||
1704 | do { | ||
1705 | if (!buffer_uptodate(bh)) { | ||
1706 | uptodate = 0; | ||
1707 | break; | ||
1708 | } | ||
1709 | bh = bh->b_this_page; | ||
1710 | } while (bh != head); | ||
1711 | if (uptodate) | ||
1712 | SetPageUptodate(page); | ||
1713 | end_page_writeback(page); | 1697 | end_page_writeback(page); |
1698 | |||
1714 | /* | 1699 | /* |
1715 | * The page and buffer_heads can be released at any time from | 1700 | * The page and buffer_heads can be released at any time from |
1716 | * here on. | 1701 | * here on. |
@@ -2968,8 +2953,7 @@ EXPORT_SYMBOL(free_buffer_head); | |||
2968 | static void | 2953 | static void |
2969 | init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) | 2954 | init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) |
2970 | { | 2955 | { |
2971 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 2956 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
2972 | SLAB_CTOR_CONSTRUCTOR) { | ||
2973 | struct buffer_head * bh = (struct buffer_head *)data; | 2957 | struct buffer_head * bh = (struct buffer_head *)data; |
2974 | 2958 | ||
2975 | memset(bh, 0, sizeof(*bh)); | 2959 | memset(bh, 0, sizeof(*bh)); |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 5d1f4873d701..a9b6bc5157b8 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,4 +1,16 @@ | |||
1 | Verison 1.48 | 1 | Version 1.49 |
2 | ------------ | ||
3 | IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6 | ||
4 | address after the "ip=" mount option, at least until mount.cifs is fixed to | ||
5 | handle DNS host to ipv6 name translation). Accept override of uid or gid | ||
6 | on mount even when Unix Extensions are negotiated (it used to be ignored | ||
7 | when Unix Extensions were ignored). This allows users to override the | ||
8 | default uid and gid for files when they are certain that the uids or | ||
9 | gids on the server do not match those of the client. Make "sec=none" | ||
10 | mount override username (so that null user connection is attempted) | ||
11 | to match what documentation said. | ||
12 | |||
13 | Version 1.48 | ||
2 | ------------ | 14 | ------------ |
3 | Fix mtime bouncing around from local idea of last write times to remote time. | 15 | Fix mtime bouncing around from local idea of last write times to remote time. |
4 | Fix hang (in i_size_read) when simultaneous size update of same remote file | 16 | Fix hang (in i_size_read) when simultaneous size update of same remote file |
@@ -9,7 +21,13 @@ from read-only back to read-write, reflect this change in default file mode | |||
9 | (we had been leaving a file's mode read-only until the inode were reloaded). | 21 | (we had been leaving a file's mode read-only until the inode were reloaded). |
10 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute | 22 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute |
11 | when archive dos attribute not set and we are changing mode back to writeable | 23 | when archive dos attribute not set and we are changing mode back to writeable |
12 | on server which does not support the Unix Extensions). | 24 | on server which does not support the Unix Extensions). Remove read only dos |
25 | attribute on chmod when adding any write permission (ie on any of | ||
26 | user/group/other (not all of user/group/other ie 0222) when | ||
27 | mounted to windows. Add support for POSIX MkDir (slight performance | ||
28 | enhancement and eliminates the network race between the mkdir and set | ||
29 | path info of the mode). | ||
30 | |||
13 | 31 | ||
14 | Version 1.47 | 32 | Version 1.47 |
15 | ------------ | 33 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index 080c5eba112b..4d01697722cc 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -257,13 +257,19 @@ A partial list of the supported mount options follows: | |||
257 | mount. | 257 | mount. |
258 | domain Set the SMB/CIFS workgroup name prepended to the | 258 | domain Set the SMB/CIFS workgroup name prepended to the |
259 | username during CIFS session establishment | 259 | username during CIFS session establishment |
260 | uid If CIFS Unix extensions are not supported by the server | 260 | uid Set the default uid for inodes. For mounts to servers |
261 | this overrides the default uid for inodes. For mounts to | 261 | which do support the CIFS Unix extensions, such as a |
262 | servers which do support the CIFS Unix extensions, such | 262 | properly configured Samba server, the server provides |
263 | as a properly configured Samba server, the server provides | 263 | the uid, gid and mode so this parameter should not be |
264 | the uid, gid and mode. For servers which do not support | 264 | specified unless the server and clients uid and gid |
265 | the Unix extensions, the default uid (and gid) returned on | 265 | numbering differ. If the server and client are in the |
266 | lookup of existing files is the uid (gid) of the person | 266 | same domain (e.g. running winbind or nss_ldap) and |
267 | the server supports the Unix Extensions then the uid | ||
268 | and gid can be retrieved from the server (and uid | ||
269 | and gid would not have to be specifed on the mount. | ||
270 | For servers which do not support the CIFS Unix | ||
271 | extensions, the default uid (and gid) returned on lookup | ||
272 | of existing files will be the uid (gid) of the person | ||
267 | who executed the mount (root, except when mount.cifs | 273 | who executed the mount (root, except when mount.cifs |
268 | is configured setuid for user mounts) unless the "uid=" | 274 | is configured setuid for user mounts) unless the "uid=" |
269 | (gid) mount option is specified. For the uid (gid) of newly | 275 | (gid) mount option is specified. For the uid (gid) of newly |
@@ -281,8 +287,7 @@ A partial list of the supported mount options follows: | |||
281 | the client. Note that the mount.cifs helper must be | 287 | the client. Note that the mount.cifs helper must be |
282 | at version 1.10 or higher to support specifying the uid | 288 | at version 1.10 or higher to support specifying the uid |
283 | (or gid) in non-numberic form. | 289 | (or gid) in non-numberic form. |
284 | gid If CIFS Unix extensions are not supported by the server | 290 | gid Set the default gid for inodes (similar to above). |
285 | this overrides the default gid for inodes. | ||
286 | file_mode If CIFS Unix extensions are not supported by the server | 291 | file_mode If CIFS Unix extensions are not supported by the server |
287 | this overrides the default mode for file inodes. | 292 | this overrides the default mode for file inodes. |
288 | dir_mode If CIFS Unix extensions are not supported by the server | 293 | dir_mode If CIFS Unix extensions are not supported by the server |
@@ -467,7 +472,7 @@ including: | |||
467 | -V print mount.cifs version | 472 | -V print mount.cifs version |
468 | -? display simple usage information | 473 | -? display simple usage information |
469 | 474 | ||
470 | With recent 2.6 kernel versions of modutils, the version of the cifs kernel | 475 | With most 2.6 kernel versions of modutils, the version of the cifs kernel |
471 | module can be displayed via modinfo. | 476 | module can be displayed via modinfo. |
472 | 477 | ||
473 | Misc /proc/fs/cifs Flags and Debug Info | 478 | Misc /proc/fs/cifs Flags and Debug Info |
@@ -516,8 +521,22 @@ SecurityFlags Flags which control security negotiation and | |||
516 | must use plaintext passwords 0x20020 | 521 | must use plaintext passwords 0x20020 |
517 | (reserved for future packet encryption) 0x00040 | 522 | (reserved for future packet encryption) 0x00040 |
518 | 523 | ||
519 | cifsFYI If set to one, additional debug information is | 524 | cifsFYI If set to non-zero value, additional debug information |
520 | logged to the system error log. (default 0) | 525 | will be logged to the system error log. This field |
526 | contains three flags controlling different classes of | ||
527 | debugging entries. The maximum value it can be set | ||
528 | to is 7 which enables all debugging points (default 0). | ||
529 | Some debugging statements are not compiled into the | ||
530 | cifs kernel unless CONFIG_CIFS_DEBUG2 is enabled in the | ||
531 | kernel configuration. cifsFYI may be set to one or | ||
532 | nore of the following flags (7 sets them all): | ||
533 | |||
534 | log cifs informational messages 0x01 | ||
535 | log return codes from cifs entry points 0x02 | ||
536 | log slow responses (ie which take longer than 1 second) | ||
537 | CONFIG_CIFS_STATS2 must be enabled in .config 0x04 | ||
538 | |||
539 | |||
521 | traceSMB If set to one, debug information is logged to the | 540 | traceSMB If set to one, debug information is logged to the |
522 | system error log with the start of smb requests | 541 | system error log with the start of smb requests |
523 | and responses (default 0) | 542 | and responses (default 0) |
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index d7b9c27c942d..78b620e332bd 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
@@ -1,4 +1,4 @@ | |||
1 | Version 1.39 November 30, 2005 | 1 | Version 1.49 April 26, 2007 |
2 | 2 | ||
3 | A Partial List of Missing Features | 3 | A Partial List of Missing Features |
4 | ================================== | 4 | ================================== |
@@ -18,7 +18,7 @@ better) | |||
18 | 18 | ||
19 | d) Kerberos/SPNEGO session setup support - (started) | 19 | d) Kerberos/SPNEGO session setup support - (started) |
20 | 20 | ||
21 | e) NTLMv2 authentication (mostly implemented - double check | 21 | e) More testing of NTLMv2 authentication (mostly implemented - double check |
22 | that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in | 22 | that NTLMv2 signing works, also need to cleanup now unneeded SessSetup code in |
23 | fs/cifs/connect.c) | 23 | fs/cifs/connect.c) |
24 | 24 | ||
@@ -27,55 +27,44 @@ used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM | |||
27 | and raw NTLMSSP already. This is important when enabling | 27 | and raw NTLMSSP already. This is important when enabling |
28 | extended security and mounting to Windows 2003 Servers | 28 | extended security and mounting to Windows 2003 Servers |
29 | 29 | ||
30 | f) Directory entry caching relies on a 1 second timer, rather than | 30 | g) Directory entry caching relies on a 1 second timer, rather than |
31 | using FindNotify or equivalent. - (started) | 31 | using FindNotify or equivalent. - (started) |
32 | 32 | ||
33 | g) A few byte range testcases fail due to POSIX vs. Windows/CIFS | 33 | h) quota support (needs minor kernel change since quota calls |
34 | style byte range lock differences. Save byte range locks so | ||
35 | reconnect can replay them. | ||
36 | |||
37 | h) Support unlock all (unlock 0,MAX_OFFSET) | ||
38 | by unlocking all known byte range locks that we locked on the file. | ||
39 | |||
40 | i) quota support (needs minor kernel change since quota calls | ||
41 | to make it to network filesystems or deviceless filesystems) | 34 | to make it to network filesystems or deviceless filesystems) |
42 | 35 | ||
43 | j) investigate sync behavior (including syncpage) and check | 36 | i) investigate sync behavior (including syncpage) and check |
44 | for proper behavior of intr/nointr | 37 | for proper behavior of intr/nointr |
45 | 38 | ||
46 | k) hook lower into the sockets api (as NFS/SunRPC does) to avoid the | 39 | j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the |
47 | extra copy in/out of the socket buffers in some cases. | 40 | extra copy in/out of the socket buffers in some cases. |
48 | 41 | ||
49 | l) finish support for IPv6. This is mostly complete but | 42 | k) Better optimize open (and pathbased setfilesize) to reduce the |
50 | needs a simple conversion of ipv6 to sin6_addr from the | ||
51 | address in string representation. | ||
52 | |||
53 | m) Better optimize open (and pathbased setfilesize) to reduce the | ||
54 | oplock breaks coming from windows srv. Piggyback identical file | 43 | oplock breaks coming from windows srv. Piggyback identical file |
55 | opens on top of each other by incrementing reference count rather | 44 | opens on top of each other by incrementing reference count rather |
56 | than resending (helps reduce server resource utilization and avoid | 45 | than resending (helps reduce server resource utilization and avoid |
57 | spurious oplock breaks). | 46 | spurious oplock breaks). |
58 | 47 | ||
59 | o) Improve performance of readpages by sending more than one read | 48 | l) Improve performance of readpages by sending more than one read |
60 | at a time when 8 pages or more are requested. In conjuntion | 49 | at a time when 8 pages or more are requested. In conjuntion |
61 | add support for async_cifs_readpages. | 50 | add support for async_cifs_readpages. |
62 | 51 | ||
63 | p) Add support for storing symlink info to Windows servers | 52 | m) Add support for storing symlink info to Windows servers |
64 | in the Extended Attribute format their SFU clients would recognize. | 53 | in the Extended Attribute format their SFU clients would recognize. |
65 | 54 | ||
66 | q) Finish fcntl D_NOTIFY support so kde and gnome file list windows | 55 | n) Finish fcntl D_NOTIFY support so kde and gnome file list windows |
67 | will autorefresh (partially complete by Asser). Needs minor kernel | 56 | will autorefresh (partially complete by Asser). Needs minor kernel |
68 | vfs change to support removing D_NOTIFY on a file. | 57 | vfs change to support removing D_NOTIFY on a file. |
69 | 58 | ||
70 | r) Add GUI tool to configure /proc/fs/cifs settings and for display of | 59 | o) Add GUI tool to configure /proc/fs/cifs settings and for display of |
71 | the CIFS statistics (started) | 60 | the CIFS statistics (started) |
72 | 61 | ||
73 | s) implement support for security and trusted categories of xattrs | 62 | p) implement support for security and trusted categories of xattrs |
74 | (requires minor protocol extension) to enable better support for SELINUX | 63 | (requires minor protocol extension) to enable better support for SELINUX |
75 | 64 | ||
76 | t) Implement O_DIRECT flag on open (already supported on mount) | 65 | q) Implement O_DIRECT flag on open (already supported on mount) |
77 | 66 | ||
78 | u) Create UID mapping facility so server UIDs can be mapped on a per | 67 | r) Create UID mapping facility so server UIDs can be mapped on a per |
79 | mount or a per server basis to client UIDs or nobody if no mapping | 68 | mount or a per server basis to client UIDs or nobody if no mapping |
80 | exists. This is helpful when Unix extensions are negotiated to | 69 | exists. This is helpful when Unix extensions are negotiated to |
81 | allow better permission checking when UIDs differ on the server | 70 | allow better permission checking when UIDs differ on the server |
@@ -83,19 +72,26 @@ and client. Add new protocol request to the CIFS protocol | |||
83 | standard for asking the server for the corresponding name of a | 72 | standard for asking the server for the corresponding name of a |
84 | particular uid. | 73 | particular uid. |
85 | 74 | ||
86 | v) Add support for CIFS Unix and also the newer POSIX extensions to the | 75 | s) Add support for CIFS Unix and also the newer POSIX extensions to the |
87 | server side for Samba 4. | 76 | server side for Samba 4. |
88 | 77 | ||
89 | w) Finish up the dos time conversion routines needed to return old server | 78 | t) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) |
90 | time to the client (default time, of now or time 0 is used now for these | ||
91 | very old servers) | ||
92 | |||
93 | x) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers) | ||
94 | need to add ability to set time to server (utimes command) | 79 | need to add ability to set time to server (utimes command) |
95 | 80 | ||
96 | y) Finish testing of Windows 9x/Windows ME server support (started). | 81 | u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) |
82 | |||
83 | v) mount check for unmatched uids | ||
84 | |||
85 | w) Add mount option for Linux extension disable per mount, and partial | ||
86 | disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?) | ||
97 | 87 | ||
98 | KNOWN BUGS (updated February 26, 2007) | 88 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of |
89 | processes can proceed better in parallel (on the server) | ||
90 | |||
91 | y) Fix Samba 3 to handle reads/writes over 127K (and remove the cifs mount | ||
92 | restriction of wsize max being 127K) | ||
93 | |||
94 | KNOWN BUGS (updated April 24, 2007) | ||
99 | ==================================== | 95 | ==================================== |
100 | See http://bugzilla.samba.org - search on product "CifsVFS" for | 96 | See http://bugzilla.samba.org - search on product "CifsVFS" for |
101 | current bug list. | 97 | current bug list. |
@@ -127,10 +123,3 @@ negotiated size) and send larger write sizes to modern servers. | |||
127 | 4) More exhaustively test against less common servers. More testing | 123 | 4) More exhaustively test against less common servers. More testing |
128 | against Windows 9x, Windows ME servers. | 124 | against Windows 9x, Windows ME servers. |
129 | 125 | ||
130 | DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too) | ||
131 | |||
132 | mount check for unmatched uids - and uid override | ||
133 | |||
134 | Add mount option for Linux extension disable per mount, and partial disable per mount (uid off, symlink/fifo/mknod on but what about posix acls?) | ||
135 | |||
136 | Free threads at umount --force that are stuck on the sesSem | ||
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index fd1e52ebcee6..4cc2012e9322 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -22,12 +22,14 @@ | |||
22 | #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ | 22 | #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ |
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ | 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ |
25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ | 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ |
26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ | 26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ |
27 | #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible. */ | 27 | #define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible*/ |
28 | #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ | 28 | #define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */ |
29 | #define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ | 29 | #define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */ |
30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ | 30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ |
31 | #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ | ||
32 | #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ | ||
31 | 33 | ||
32 | struct cifs_sb_info { | 34 | struct cifs_sb_info { |
33 | struct cifsTconInfo *tcon; /* primary mount */ | 35 | struct cifsTconInfo *tcon; /* primary mount */ |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index d2a8b2941fc2..793c4b95c164 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
@@ -74,8 +74,8 @@ cifs_strtoUCS(__le16 * to, const char *from, int len, | |||
74 | charlen = codepage->char2uni(from, len, &wchar_to[i]); | 74 | charlen = codepage->char2uni(from, len, &wchar_to[i]); |
75 | if (charlen < 1) { | 75 | if (charlen < 1) { |
76 | cERROR(1, | 76 | cERROR(1, |
77 | ("cifs_strtoUCS: char2uni returned %d", | 77 | ("strtoUCS: char2uni of %d returned %d", |
78 | charlen)); | 78 | (int)*from, charlen)); |
79 | /* A question mark */ | 79 | /* A question mark */ |
80 | to[i] = cpu_to_le16(0x003f); | 80 | to[i] = cpu_to_le16(0x003f); |
81 | charlen = 1; | 81 | charlen = 1; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index faba4d69fe91..8568e100953c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -100,7 +100,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
100 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | 100 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; |
101 | sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); | 101 | sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); |
102 | cifs_sb = CIFS_SB(sb); | 102 | cifs_sb = CIFS_SB(sb); |
103 | if(cifs_sb == NULL) | 103 | if (cifs_sb == NULL) |
104 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | 105 | ||
106 | rc = cifs_mount(sb, cifs_sb, data, devname); | 106 | rc = cifs_mount(sb, cifs_sb, data, devname); |
@@ -115,10 +115,10 @@ cifs_read_super(struct super_block *sb, void *data, | |||
115 | sb->s_magic = CIFS_MAGIC_NUMBER; | 115 | sb->s_magic = CIFS_MAGIC_NUMBER; |
116 | sb->s_op = &cifs_super_ops; | 116 | sb->s_op = &cifs_super_ops; |
117 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 117 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
118 | if(experimEnabled != 0) | 118 | if (experimEnabled != 0) |
119 | sb->s_export_op = &cifs_export_ops; | 119 | sb->s_export_op = &cifs_export_ops; |
120 | #endif /* EXPERIMENTAL */ | 120 | #endif /* EXPERIMENTAL */ |
121 | /* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) | 121 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) |
122 | sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ | 122 | sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ |
123 | #ifdef CONFIG_CIFS_QUOTA | 123 | #ifdef CONFIG_CIFS_QUOTA |
124 | sb->s_qcop = &cifs_quotactl_ops; | 124 | sb->s_qcop = &cifs_quotactl_ops; |
@@ -147,8 +147,8 @@ out_no_root: | |||
147 | iput(inode); | 147 | iput(inode); |
148 | 148 | ||
149 | out_mount_failed: | 149 | out_mount_failed: |
150 | if(cifs_sb) { | 150 | if (cifs_sb) { |
151 | if(cifs_sb->local_nls) | 151 | if (cifs_sb->local_nls) |
152 | unload_nls(cifs_sb->local_nls); | 152 | unload_nls(cifs_sb->local_nls); |
153 | kfree(cifs_sb); | 153 | kfree(cifs_sb); |
154 | } | 154 | } |
@@ -163,7 +163,7 @@ cifs_put_super(struct super_block *sb) | |||
163 | 163 | ||
164 | cFYI(1, ("In cifs_put_super")); | 164 | cFYI(1, ("In cifs_put_super")); |
165 | cifs_sb = CIFS_SB(sb); | 165 | cifs_sb = CIFS_SB(sb); |
166 | if(cifs_sb == NULL) { | 166 | if (cifs_sb == NULL) { |
167 | cFYI(1,("Empty cifs superblock info passed to unmount")); | 167 | cFYI(1,("Empty cifs superblock info passed to unmount")); |
168 | return; | 168 | return; |
169 | } | 169 | } |
@@ -208,14 +208,14 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
208 | 208 | ||
209 | /* Only need to call the old QFSInfo if failed | 209 | /* Only need to call the old QFSInfo if failed |
210 | on newer one */ | 210 | on newer one */ |
211 | if(rc) | 211 | if (rc) |
212 | if(pTcon->ses->capabilities & CAP_NT_SMBS) | 212 | if (pTcon->ses->capabilities & CAP_NT_SMBS) |
213 | rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ | 213 | rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */ |
214 | 214 | ||
215 | /* Some old Windows servers also do not support level 103, retry with | 215 | /* Some old Windows servers also do not support level 103, retry with |
216 | older level one if old server failed the previous call or we | 216 | older level one if old server failed the previous call or we |
217 | bypassed it because we detected that this was an older LANMAN sess */ | 217 | bypassed it because we detected that this was an older LANMAN sess */ |
218 | if(rc) | 218 | if (rc) |
219 | rc = SMBOldQFSInfo(xid, pTcon, buf); | 219 | rc = SMBOldQFSInfo(xid, pTcon, buf); |
220 | /* | 220 | /* |
221 | int f_type; | 221 | int f_type; |
@@ -301,11 +301,19 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
301 | if (cifs_sb->tcon->ses->userName) | 301 | if (cifs_sb->tcon->ses->userName) |
302 | seq_printf(s, ",username=%s", | 302 | seq_printf(s, ",username=%s", |
303 | cifs_sb->tcon->ses->userName); | 303 | cifs_sb->tcon->ses->userName); |
304 | if(cifs_sb->tcon->ses->domainName) | 304 | if (cifs_sb->tcon->ses->domainName) |
305 | seq_printf(s, ",domain=%s", | 305 | seq_printf(s, ",domain=%s", |
306 | cifs_sb->tcon->ses->domainName); | 306 | cifs_sb->tcon->ses->domainName); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | ||
310 | seq_printf(s, ",posixpaths"); | ||
311 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
312 | !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) | ||
313 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
314 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
315 | !(cifs_sb->tcon->ses->capabilities & CAP_UNIX)) | ||
316 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
309 | seq_printf(s, ",rsize=%d",cifs_sb->rsize); | 317 | seq_printf(s, ",rsize=%d",cifs_sb->rsize); |
310 | seq_printf(s, ",wsize=%d",cifs_sb->wsize); | 318 | seq_printf(s, ",wsize=%d",cifs_sb->wsize); |
311 | } | 319 | } |
@@ -321,14 +329,14 @@ int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid, | |||
321 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 329 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
322 | struct cifsTconInfo *pTcon; | 330 | struct cifsTconInfo *pTcon; |
323 | 331 | ||
324 | if(cifs_sb) | 332 | if (cifs_sb) |
325 | pTcon = cifs_sb->tcon; | 333 | pTcon = cifs_sb->tcon; |
326 | else | 334 | else |
327 | return -EIO; | 335 | return -EIO; |
328 | 336 | ||
329 | 337 | ||
330 | xid = GetXid(); | 338 | xid = GetXid(); |
331 | if(pTcon) { | 339 | if (pTcon) { |
332 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); | 340 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); |
333 | } else { | 341 | } else { |
334 | return -EIO; | 342 | return -EIO; |
@@ -346,13 +354,13 @@ int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid, | |||
346 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 354 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
347 | struct cifsTconInfo *pTcon; | 355 | struct cifsTconInfo *pTcon; |
348 | 356 | ||
349 | if(cifs_sb) | 357 | if (cifs_sb) |
350 | pTcon = cifs_sb->tcon; | 358 | pTcon = cifs_sb->tcon; |
351 | else | 359 | else |
352 | return -EIO; | 360 | return -EIO; |
353 | 361 | ||
354 | xid = GetXid(); | 362 | xid = GetXid(); |
355 | if(pTcon) { | 363 | if (pTcon) { |
356 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); | 364 | cFYI(1,("set type: 0x%x id: %d",quota_type,qid)); |
357 | } else { | 365 | } else { |
358 | rc = -EIO; | 366 | rc = -EIO; |
@@ -369,13 +377,13 @@ int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation) | |||
369 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 377 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
370 | struct cifsTconInfo *pTcon; | 378 | struct cifsTconInfo *pTcon; |
371 | 379 | ||
372 | if(cifs_sb) | 380 | if (cifs_sb) |
373 | pTcon = cifs_sb->tcon; | 381 | pTcon = cifs_sb->tcon; |
374 | else | 382 | else |
375 | return -EIO; | 383 | return -EIO; |
376 | 384 | ||
377 | xid = GetXid(); | 385 | xid = GetXid(); |
378 | if(pTcon) { | 386 | if (pTcon) { |
379 | cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); | 387 | cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation)); |
380 | } else { | 388 | } else { |
381 | rc = -EIO; | 389 | rc = -EIO; |
@@ -392,13 +400,13 @@ int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats) | |||
392 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 400 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
393 | struct cifsTconInfo *pTcon; | 401 | struct cifsTconInfo *pTcon; |
394 | 402 | ||
395 | if(cifs_sb) { | 403 | if (cifs_sb) { |
396 | pTcon = cifs_sb->tcon; | 404 | pTcon = cifs_sb->tcon; |
397 | } else { | 405 | } else { |
398 | return -EIO; | 406 | return -EIO; |
399 | } | 407 | } |
400 | xid = GetXid(); | 408 | xid = GetXid(); |
401 | if(pTcon) { | 409 | if (pTcon) { |
402 | cFYI(1,("pqstats %p",qstats)); | 410 | cFYI(1,("pqstats %p",qstats)); |
403 | } else { | 411 | } else { |
404 | rc = -EIO; | 412 | rc = -EIO; |
@@ -424,11 +432,11 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) | |||
424 | if (!(flags & MNT_FORCE)) | 432 | if (!(flags & MNT_FORCE)) |
425 | return; | 433 | return; |
426 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); | 434 | cifs_sb = CIFS_SB(vfsmnt->mnt_sb); |
427 | if(cifs_sb == NULL) | 435 | if (cifs_sb == NULL) |
428 | return; | 436 | return; |
429 | 437 | ||
430 | tcon = cifs_sb->tcon; | 438 | tcon = cifs_sb->tcon; |
431 | if(tcon == NULL) | 439 | if (tcon == NULL) |
432 | return; | 440 | return; |
433 | down(&tcon->tconSem); | 441 | down(&tcon->tconSem); |
434 | if (atomic_read(&tcon->useCount) == 1) | 442 | if (atomic_read(&tcon->useCount) == 1) |
@@ -437,7 +445,7 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags) | |||
437 | 445 | ||
438 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ | 446 | /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ |
439 | /* cancel_notify_requests(tcon); */ | 447 | /* cancel_notify_requests(tcon); */ |
440 | if(tcon->ses && tcon->ses->server) | 448 | if (tcon->ses && tcon->ses->server) |
441 | { | 449 | { |
442 | cFYI(1,("wake up tasks now - umount begin not complete")); | 450 | cFYI(1,("wake up tasks now - umount begin not complete")); |
443 | wake_up_all(&tcon->ses->server->request_q); | 451 | wake_up_all(&tcon->ses->server->request_q); |
@@ -529,8 +537,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) | |||
529 | /* some applications poll for the file length in this strange | 537 | /* some applications poll for the file length in this strange |
530 | way so we must seek to end on non-oplocked files by | 538 | way so we must seek to end on non-oplocked files by |
531 | setting the revalidate time to zero */ | 539 | setting the revalidate time to zero */ |
532 | if(file->f_path.dentry->d_inode) | 540 | CIFS_I(file->f_path.dentry->d_inode)->time = 0; |
533 | CIFS_I(file->f_path.dentry->d_inode)->time = 0; | ||
534 | 541 | ||
535 | retval = cifs_revalidate(file->f_path.dentry); | 542 | retval = cifs_revalidate(file->f_path.dentry); |
536 | if (retval < 0) | 543 | if (retval < 0) |
@@ -694,8 +701,7 @@ cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) | |||
694 | { | 701 | { |
695 | struct cifsInodeInfo *cifsi = inode; | 702 | struct cifsInodeInfo *cifsi = inode; |
696 | 703 | ||
697 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | 704 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
698 | SLAB_CTOR_CONSTRUCTOR) { | ||
699 | inode_init_once(&cifsi->vfs_inode); | 705 | inode_init_once(&cifsi->vfs_inode); |
700 | INIT_LIST_HEAD(&cifsi->lockList); | 706 | INIT_LIST_HEAD(&cifsi->lockList); |
701 | } | 707 | } |
@@ -724,7 +730,7 @@ cifs_destroy_inodecache(void) | |||
724 | static int | 730 | static int |
725 | cifs_init_request_bufs(void) | 731 | cifs_init_request_bufs(void) |
726 | { | 732 | { |
727 | if(CIFSMaxBufSize < 8192) { | 733 | if (CIFSMaxBufSize < 8192) { |
728 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum | 734 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum |
729 | Unicode path name has to fit in any SMB/CIFS path based frames */ | 735 | Unicode path name has to fit in any SMB/CIFS path based frames */ |
730 | CIFSMaxBufSize = 8192; | 736 | CIFSMaxBufSize = 8192; |
@@ -741,7 +747,7 @@ cifs_init_request_bufs(void) | |||
741 | if (cifs_req_cachep == NULL) | 747 | if (cifs_req_cachep == NULL) |
742 | return -ENOMEM; | 748 | return -ENOMEM; |
743 | 749 | ||
744 | if(cifs_min_rcv < 1) | 750 | if (cifs_min_rcv < 1) |
745 | cifs_min_rcv = 1; | 751 | cifs_min_rcv = 1; |
746 | else if (cifs_min_rcv > 64) { | 752 | else if (cifs_min_rcv > 64) { |
747 | cifs_min_rcv = 64; | 753 | cifs_min_rcv = 64; |
@@ -751,7 +757,7 @@ cifs_init_request_bufs(void) | |||
751 | cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, | 757 | cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv, |
752 | cifs_req_cachep); | 758 | cifs_req_cachep); |
753 | 759 | ||
754 | if(cifs_req_poolp == NULL) { | 760 | if (cifs_req_poolp == NULL) { |
755 | kmem_cache_destroy(cifs_req_cachep); | 761 | kmem_cache_destroy(cifs_req_cachep); |
756 | return -ENOMEM; | 762 | return -ENOMEM; |
757 | } | 763 | } |
@@ -772,7 +778,7 @@ cifs_init_request_bufs(void) | |||
772 | return -ENOMEM; | 778 | return -ENOMEM; |
773 | } | 779 | } |
774 | 780 | ||
775 | if(cifs_min_small < 2) | 781 | if (cifs_min_small < 2) |
776 | cifs_min_small = 2; | 782 | cifs_min_small = 2; |
777 | else if (cifs_min_small > 256) { | 783 | else if (cifs_min_small > 256) { |
778 | cifs_min_small = 256; | 784 | cifs_min_small = 256; |
@@ -782,7 +788,7 @@ cifs_init_request_bufs(void) | |||
782 | cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, | 788 | cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small, |
783 | cifs_sm_req_cachep); | 789 | cifs_sm_req_cachep); |
784 | 790 | ||
785 | if(cifs_sm_req_poolp == NULL) { | 791 | if (cifs_sm_req_poolp == NULL) { |
786 | mempool_destroy(cifs_req_poolp); | 792 | mempool_destroy(cifs_req_poolp); |
787 | kmem_cache_destroy(cifs_req_cachep); | 793 | kmem_cache_destroy(cifs_req_cachep); |
788 | kmem_cache_destroy(cifs_sm_req_cachep); | 794 | kmem_cache_destroy(cifs_sm_req_cachep); |
@@ -812,7 +818,7 @@ cifs_init_mids(void) | |||
812 | 818 | ||
813 | /* 3 is a reasonable minimum number of simultaneous operations */ | 819 | /* 3 is a reasonable minimum number of simultaneous operations */ |
814 | cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep); | 820 | cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep); |
815 | if(cifs_mid_poolp == NULL) { | 821 | if (cifs_mid_poolp == NULL) { |
816 | kmem_cache_destroy(cifs_mid_cachep); | 822 | kmem_cache_destroy(cifs_mid_cachep); |
817 | return -ENOMEM; | 823 | return -ENOMEM; |
818 | } | 824 | } |
@@ -850,14 +856,14 @@ static int cifs_oplock_thread(void * dummyarg) | |||
850 | continue; | 856 | continue; |
851 | 857 | ||
852 | spin_lock(&GlobalMid_Lock); | 858 | spin_lock(&GlobalMid_Lock); |
853 | if(list_empty(&GlobalOplock_Q)) { | 859 | if (list_empty(&GlobalOplock_Q)) { |
854 | spin_unlock(&GlobalMid_Lock); | 860 | spin_unlock(&GlobalMid_Lock); |
855 | set_current_state(TASK_INTERRUPTIBLE); | 861 | set_current_state(TASK_INTERRUPTIBLE); |
856 | schedule_timeout(39*HZ); | 862 | schedule_timeout(39*HZ); |
857 | } else { | 863 | } else { |
858 | oplock_item = list_entry(GlobalOplock_Q.next, | 864 | oplock_item = list_entry(GlobalOplock_Q.next, |
859 | struct oplock_q_entry, qhead); | 865 | struct oplock_q_entry, qhead); |
860 | if(oplock_item) { | 866 | if (oplock_item) { |
861 | cFYI(1,("found oplock item to write out")); | 867 | cFYI(1,("found oplock item to write out")); |
862 | pTcon = oplock_item->tcon; | 868 | pTcon = oplock_item->tcon; |
863 | inode = oplock_item->pinode; | 869 | inode = oplock_item->pinode; |
@@ -871,7 +877,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
871 | /* mutex_lock(&inode->i_mutex);*/ | 877 | /* mutex_lock(&inode->i_mutex);*/ |
872 | if (S_ISREG(inode->i_mode)) { | 878 | if (S_ISREG(inode->i_mode)) { |
873 | rc = filemap_fdatawrite(inode->i_mapping); | 879 | rc = filemap_fdatawrite(inode->i_mapping); |
874 | if(CIFS_I(inode)->clientCanCacheRead == 0) { | 880 | if (CIFS_I(inode)->clientCanCacheRead == 0) { |
875 | filemap_fdatawait(inode->i_mapping); | 881 | filemap_fdatawait(inode->i_mapping); |
876 | invalidate_remote_inode(inode); | 882 | invalidate_remote_inode(inode); |
877 | } | 883 | } |
@@ -888,7 +894,7 @@ static int cifs_oplock_thread(void * dummyarg) | |||
888 | not bother sending an oplock release if session | 894 | not bother sending an oplock release if session |
889 | to server still is disconnected since oplock | 895 | to server still is disconnected since oplock |
890 | already released by the server in that case */ | 896 | already released by the server in that case */ |
891 | if(pTcon->tidStatus != CifsNeedReconnect) { | 897 | if (pTcon->tidStatus != CifsNeedReconnect) { |
892 | rc = CIFSSMBLock(0, pTcon, netfid, | 898 | rc = CIFSSMBLock(0, pTcon, netfid, |
893 | 0 /* len */ , 0 /* offset */, 0, | 899 | 0 /* len */ , 0 /* offset */, 0, |
894 | 0, LOCKING_ANDX_OPLOCK_RELEASE, | 900 | 0, LOCKING_ANDX_OPLOCK_RELEASE, |
@@ -922,7 +928,7 @@ static int cifs_dnotify_thread(void * dummyarg) | |||
922 | list_for_each(tmp, &GlobalSMBSessionList) { | 928 | list_for_each(tmp, &GlobalSMBSessionList) { |
923 | ses = list_entry(tmp, struct cifsSesInfo, | 929 | ses = list_entry(tmp, struct cifsSesInfo, |
924 | cifsSessionList); | 930 | cifsSessionList); |
925 | if(ses && ses->server && | 931 | if (ses && ses->server && |
926 | atomic_read(&ses->server->inFlight)) | 932 | atomic_read(&ses->server->inFlight)) |
927 | wake_up_all(&ses->server->response_q); | 933 | wake_up_all(&ses->server->response_q); |
928 | } | 934 | } |
@@ -971,10 +977,10 @@ init_cifs(void) | |||
971 | rwlock_init(&GlobalSMBSeslock); | 977 | rwlock_init(&GlobalSMBSeslock); |
972 | spin_lock_init(&GlobalMid_Lock); | 978 | spin_lock_init(&GlobalMid_Lock); |
973 | 979 | ||
974 | if(cifs_max_pending < 2) { | 980 | if (cifs_max_pending < 2) { |
975 | cifs_max_pending = 2; | 981 | cifs_max_pending = 2; |
976 | cFYI(1,("cifs_max_pending set to min of 2")); | 982 | cFYI(1,("cifs_max_pending set to min of 2")); |
977 | } else if(cifs_max_pending > 256) { | 983 | } else if (cifs_max_pending > 256) { |
978 | cifs_max_pending = 256; | 984 | cifs_max_pending = 256; |
979 | cFYI(1,("cifs_max_pending set to max of 256")); | 985 | cFYI(1,("cifs_max_pending set to max of 256")); |
980 | } | 986 | } |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 2c2c384894d8..c235d32ad4a8 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | |||
100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 100 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
101 | extern int cifs_ioctl (struct inode * inode, struct file * filep, | 101 | extern int cifs_ioctl (struct inode * inode, struct file * filep, |
102 | unsigned int command, unsigned long arg); | 102 | unsigned int command, unsigned long arg); |
103 | #define CIFS_VERSION "1.48" | 103 | #define CIFS_VERSION "1.49" |
104 | #endif /* _CIFSFS_H */ | 104 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e4de8eba4780..23655de2f4a4 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -311,7 +311,7 @@ struct cifsFileInfo { | |||
311 | /* lock scope id (0 if none) */ | 311 | /* lock scope id (0 if none) */ |
312 | struct file * pfile; /* needed for writepage */ | 312 | struct file * pfile; /* needed for writepage */ |
313 | struct inode * pInode; /* needed for oplock break */ | 313 | struct inode * pInode; /* needed for oplock break */ |
314 | struct semaphore lock_sem; | 314 | struct mutex lock_mutex; |
315 | struct list_head llist; /* list of byte range locks we have. */ | 315 | struct list_head llist; /* list of byte range locks we have. */ |
316 | unsigned closePend:1; /* file is marked to close */ | 316 | unsigned closePend:1; /* file is marked to close */ |
317 | unsigned invalidHandle:1; /* file closed via session abend */ | 317 | unsigned invalidHandle:1; /* file closed via session abend */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 4d8948e8762c..d619ca7d1416 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -1388,7 +1388,7 @@ struct smb_t2_rsp { | |||
1388 | #define SMB_SET_POSIX_LOCK 0x208 | 1388 | #define SMB_SET_POSIX_LOCK 0x208 |
1389 | #define SMB_POSIX_OPEN 0x209 | 1389 | #define SMB_POSIX_OPEN 0x209 |
1390 | #define SMB_POSIX_UNLINK 0x20a | 1390 | #define SMB_POSIX_UNLINK 0x20a |
1391 | #define SMB_SET_FILE_UNIX_INFO2 | 1391 | #define SMB_SET_FILE_UNIX_INFO2 0x20b |
1392 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec | 1392 | #define SMB_SET_FILE_BASIC_INFO2 0x3ec |
1393 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo too */ | 1393 | #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo too */ |
1394 | #define SMB_FILE_ALL_INFO2 0x3fa | 1394 | #define SMB_FILE_ALL_INFO2 0x3fa |
@@ -2109,22 +2109,40 @@ struct cifs_posix_acl { /* access conrol list (ACL) */ | |||
2109 | 2109 | ||
2110 | /* end of POSIX ACL definitions */ | 2110 | /* end of POSIX ACL definitions */ |
2111 | 2111 | ||
2112 | /* POSIX Open Flags */ | ||
2113 | #define SMB_O_RDONLY 0x1 | ||
2114 | #define SMB_O_WRONLY 0x2 | ||
2115 | #define SMB_O_RDWR 0x4 | ||
2116 | #define SMB_O_CREAT 0x10 | ||
2117 | #define SMB_O_EXCL 0x20 | ||
2118 | #define SMB_O_TRUNC 0x40 | ||
2119 | #define SMB_O_APPEND 0x80 | ||
2120 | #define SMB_O_SYNC 0x100 | ||
2121 | #define SMB_O_DIRECTORY 0x200 | ||
2122 | #define SMB_O_NOFOLLOW 0x400 | ||
2123 | #define SMB_O_DIRECT 0x800 | ||
2124 | |||
2112 | typedef struct { | 2125 | typedef struct { |
2113 | __u32 OpenFlags; /* same as NT CreateX */ | 2126 | __le32 OpenFlags; /* same as NT CreateX */ |
2114 | __u32 PosixOpenFlags; | 2127 | __le32 PosixOpenFlags; |
2115 | __u32 Mode; | 2128 | __le64 Permissions; |
2116 | __u16 Level; /* reply level requested (see QPathInfo levels) */ | 2129 | __le16 Level; /* reply level requested (see QPathInfo levels) */ |
2117 | __u16 Pad; /* reserved - MBZ */ | ||
2118 | } __attribute__((packed)) OPEN_PSX_REQ; /* level 0x209 SetPathInfo data */ | 2130 | } __attribute__((packed)) OPEN_PSX_REQ; /* level 0x209 SetPathInfo data */ |
2119 | 2131 | ||
2120 | typedef struct { | 2132 | typedef struct { |
2121 | /* reply varies based on requested level */ | 2133 | __le16 OplockFlags; |
2134 | __u16 Fid; | ||
2135 | __le32 CreateAction; | ||
2136 | __le16 ReturnedLevel; | ||
2137 | __le16 Pad; | ||
2138 | /* struct following varies based on requested level */ | ||
2122 | } __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */ | 2139 | } __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */ |
2123 | 2140 | ||
2124 | 2141 | ||
2125 | struct file_internal_info { | 2142 | struct file_internal_info { |
2126 | __u64 UniqueId; /* inode number */ | 2143 | __u64 UniqueId; /* inode number */ |
2127 | } __attribute__((packed)); /* level 0x3ee */ | 2144 | } __attribute__((packed)); /* level 0x3ee */ |
2145 | |||
2128 | struct file_mode_info { | 2146 | struct file_mode_info { |
2129 | __le32 Mode; | 2147 | __le32 Mode; |
2130 | } __attribute__((packed)); /* level 0x3f8 */ | 2148 | } __attribute__((packed)); /* level 0x3f8 */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 32eb1acab630..5d163e2b6143 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsproto.h | 2 | * fs/cifs/cifsproto.h |
3 | * | 3 | * |
4 | * Copyright (c) International Business Machines Corp., 2002,2006 | 4 | * Copyright (c) International Business Machines Corp., 2002,2007 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -244,6 +244,11 @@ extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, | |||
244 | const int access_flags, const int omode, | 244 | const int access_flags, const int omode, |
245 | __u16 * netfid, int *pOplock, FILE_ALL_INFO *, | 245 | __u16 * netfid, int *pOplock, FILE_ALL_INFO *, |
246 | const struct nls_table *nls_codepage, int remap); | 246 | const struct nls_table *nls_codepage, int remap); |
247 | extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, | ||
248 | u32 posix_flags, __u64 mode, __u16 * netfid, | ||
249 | FILE_UNIX_BASIC_INFO *pRetData, | ||
250 | __u32 *pOplock, const char *name, | ||
251 | const struct nls_table *nls_codepage, int remap); | ||
247 | extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, | 252 | extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, |
248 | const int smb_file_id); | 253 | const int smb_file_id); |
249 | 254 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 48fc0c2ab0e5..14de58fa1437 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifssmb.c | 2 | * fs/cifs/cifssmb.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2006 | 4 | * Copyright (C) International Business Machines Corp., 2002,2007 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * Contains the routines for constructing the SMB PDUs themselves | 7 | * Contains the routines for constructing the SMB PDUs themselves |
@@ -24,8 +24,8 @@ | |||
24 | /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ | 24 | /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */ |
25 | /* These are mostly routines that operate on a pathname, or on a tree id */ | 25 | /* These are mostly routines that operate on a pathname, or on a tree id */ |
26 | /* (mounted volume), but there are eight handle based routines which must be */ | 26 | /* (mounted volume), but there are eight handle based routines which must be */ |
27 | /* treated slightly different for reconnection purposes since we never want */ | 27 | /* treated slightly differently for reconnection purposes since we never */ |
28 | /* to reuse a stale file handle and the caller knows the file handle */ | 28 | /* want to reuse a stale file handle and only the caller knows the file info */ |
29 | 29 | ||
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
@@ -913,6 +913,130 @@ MkDirRetry: | |||
913 | return rc; | 913 | return rc; |
914 | } | 914 | } |
915 | 915 | ||
916 | int | ||
917 | CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, | ||
918 | __u64 mode, __u16 * netfid, FILE_UNIX_BASIC_INFO *pRetData, | ||
919 | __u32 *pOplock, const char *name, | ||
920 | const struct nls_table *nls_codepage, int remap) | ||
921 | { | ||
922 | TRANSACTION2_SPI_REQ *pSMB = NULL; | ||
923 | TRANSACTION2_SPI_RSP *pSMBr = NULL; | ||
924 | int name_len; | ||
925 | int rc = 0; | ||
926 | int bytes_returned = 0; | ||
927 | char *data_offset; | ||
928 | __u16 params, param_offset, offset, byte_count, count; | ||
929 | OPEN_PSX_REQ * pdata; | ||
930 | OPEN_PSX_RSP * psx_rsp; | ||
931 | |||
932 | cFYI(1, ("In POSIX Create")); | ||
933 | PsxCreat: | ||
934 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
935 | (void **) &pSMBr); | ||
936 | if (rc) | ||
937 | return rc; | ||
938 | |||
939 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | ||
940 | name_len = | ||
941 | cifsConvertToUCS((__le16 *) pSMB->FileName, name, | ||
942 | PATH_MAX, nls_codepage, remap); | ||
943 | name_len++; /* trailing null */ | ||
944 | name_len *= 2; | ||
945 | } else { /* BB improve the check for buffer overruns BB */ | ||
946 | name_len = strnlen(name, PATH_MAX); | ||
947 | name_len++; /* trailing null */ | ||
948 | strncpy(pSMB->FileName, name, name_len); | ||
949 | } | ||
950 | |||
951 | params = 6 + name_len; | ||
952 | count = sizeof(OPEN_PSX_REQ); | ||
953 | pSMB->MaxParameterCount = cpu_to_le16(2); | ||
954 | pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */ | ||
955 | pSMB->MaxSetupCount = 0; | ||
956 | pSMB->Reserved = 0; | ||
957 | pSMB->Flags = 0; | ||
958 | pSMB->Timeout = 0; | ||
959 | pSMB->Reserved2 = 0; | ||
960 | param_offset = offsetof(struct smb_com_transaction2_spi_req, | ||
961 | InformationLevel) - 4; | ||
962 | offset = param_offset + params; | ||
963 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | ||
964 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); | ||
965 | pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; | ||
966 | pdata->Permissions = cpu_to_le64(mode); | ||
967 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); | ||
968 | pdata->OpenFlags = cpu_to_le32(*pOplock); | ||
969 | pSMB->ParameterOffset = cpu_to_le16(param_offset); | ||
970 | pSMB->DataOffset = cpu_to_le16(offset); | ||
971 | pSMB->SetupCount = 1; | ||
972 | pSMB->Reserved3 = 0; | ||
973 | pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); | ||
974 | byte_count = 3 /* pad */ + params + count; | ||
975 | |||
976 | pSMB->DataCount = cpu_to_le16(count); | ||
977 | pSMB->ParameterCount = cpu_to_le16(params); | ||
978 | pSMB->TotalDataCount = pSMB->DataCount; | ||
979 | pSMB->TotalParameterCount = pSMB->ParameterCount; | ||
980 | pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN); | ||
981 | pSMB->Reserved4 = 0; | ||
982 | pSMB->hdr.smb_buf_length += byte_count; | ||
983 | pSMB->ByteCount = cpu_to_le16(byte_count); | ||
984 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | ||
985 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | ||
986 | if (rc) { | ||
987 | cFYI(1, ("Posix create returned %d", rc)); | ||
988 | goto psx_create_err; | ||
989 | } | ||
990 | |||
991 | cFYI(1,("copying inode info")); | ||
992 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | ||
993 | |||
994 | if (rc || (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP))) { | ||
995 | rc = -EIO; /* bad smb */ | ||
996 | goto psx_create_err; | ||
997 | } | ||
998 | |||
999 | /* copy return information to pRetData */ | ||
1000 | psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol | ||
1001 | + le16_to_cpu(pSMBr->t2.DataOffset)); | ||
1002 | |||
1003 | *pOplock = le16_to_cpu(psx_rsp->OplockFlags); | ||
1004 | if(netfid) | ||
1005 | *netfid = psx_rsp->Fid; /* cifs fid stays in le */ | ||
1006 | /* Let caller know file was created so we can set the mode. */ | ||
1007 | /* Do we care about the CreateAction in any other cases? */ | ||
1008 | if(cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) | ||
1009 | *pOplock |= CIFS_CREATE_ACTION; | ||
1010 | /* check to make sure response data is there */ | ||
1011 | if(psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { | ||
1012 | pRetData->Type = -1; /* unknown */ | ||
1013 | #ifdef CONFIG_CIFS_DEBUG2 | ||
1014 | cFYI(1,("unknown type")); | ||
1015 | #endif | ||
1016 | } else { | ||
1017 | if(pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) | ||
1018 | + sizeof(FILE_UNIX_BASIC_INFO)) { | ||
1019 | cERROR(1,("Open response data too small")); | ||
1020 | pRetData->Type = -1; | ||
1021 | goto psx_create_err; | ||
1022 | } | ||
1023 | memcpy((char *) pRetData, | ||
1024 | (char *)psx_rsp + sizeof(OPEN_PSX_RSP), | ||
1025 | sizeof (FILE_UNIX_BASIC_INFO)); | ||
1026 | } | ||
1027 | |||
1028 | |||
1029 | psx_create_err: | ||
1030 | cifs_buf_release(pSMB); | ||
1031 | |||
1032 | cifs_stats_inc(&tcon->num_mkdirs); | ||
1033 | |||
1034 | if (rc == -EAGAIN) | ||
1035 | goto PsxCreat; | ||
1036 | |||
1037 | return rc; | ||
1038 | } | ||
1039 | |||
916 | static __u16 convert_disposition(int disposition) | 1040 | static __u16 convert_disposition(int disposition) |
917 | { | 1041 | { |
918 | __u16 ofun = 0; | 1042 | __u16 ofun = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 20ba7dcc9959..216fb625843f 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mempool.h> | 30 | #include <linux/mempool.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/completion.h> | 32 | #include <linux/completion.h> |
33 | #include <linux/kthread.h> | ||
33 | #include <linux/pagevec.h> | 34 | #include <linux/pagevec.h> |
34 | #include <linux/freezer.h> | 35 | #include <linux/freezer.h> |
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
@@ -74,6 +75,8 @@ struct smb_vol { | |||
74 | unsigned retry:1; | 75 | unsigned retry:1; |
75 | unsigned intr:1; | 76 | unsigned intr:1; |
76 | unsigned setuids:1; | 77 | unsigned setuids:1; |
78 | unsigned override_uid:1; | ||
79 | unsigned override_gid:1; | ||
77 | unsigned noperm:1; | 80 | unsigned noperm:1; |
78 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ | 81 | unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ |
79 | unsigned cifs_acl:1; | 82 | unsigned cifs_acl:1; |
@@ -120,7 +123,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
120 | struct mid_q_entry * mid_entry; | 123 | struct mid_q_entry * mid_entry; |
121 | 124 | ||
122 | spin_lock(&GlobalMid_Lock); | 125 | spin_lock(&GlobalMid_Lock); |
123 | if(server->tcpStatus == CifsExiting) { | 126 | if( kthread_should_stop() ) { |
124 | /* the demux thread will exit normally | 127 | /* the demux thread will exit normally |
125 | next time through the loop */ | 128 | next time through the loop */ |
126 | spin_unlock(&GlobalMid_Lock); | 129 | spin_unlock(&GlobalMid_Lock); |
@@ -182,7 +185,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
182 | spin_unlock(&GlobalMid_Lock); | 185 | spin_unlock(&GlobalMid_Lock); |
183 | up(&server->tcpSem); | 186 | up(&server->tcpSem); |
184 | 187 | ||
185 | while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) | 188 | while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) |
186 | { | 189 | { |
187 | try_to_freeze(); | 190 | try_to_freeze(); |
188 | if(server->protocolType == IPV6) { | 191 | if(server->protocolType == IPV6) { |
@@ -199,7 +202,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
199 | } else { | 202 | } else { |
200 | atomic_inc(&tcpSesReconnectCount); | 203 | atomic_inc(&tcpSesReconnectCount); |
201 | spin_lock(&GlobalMid_Lock); | 204 | spin_lock(&GlobalMid_Lock); |
202 | if(server->tcpStatus != CifsExiting) | 205 | if( !kthread_should_stop() ) |
203 | server->tcpStatus = CifsGood; | 206 | server->tcpStatus = CifsGood; |
204 | server->sequence_number = 0; | 207 | server->sequence_number = 0; |
205 | spin_unlock(&GlobalMid_Lock); | 208 | spin_unlock(&GlobalMid_Lock); |
@@ -345,7 +348,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
345 | int isMultiRsp; | 348 | int isMultiRsp; |
346 | int reconnect; | 349 | int reconnect; |
347 | 350 | ||
348 | daemonize("cifsd"); | ||
349 | allow_signal(SIGKILL); | 351 | allow_signal(SIGKILL); |
350 | current->flags |= PF_MEMALLOC; | 352 | current->flags |= PF_MEMALLOC; |
351 | server->tsk = current; /* save process info to wake at shutdown */ | 353 | server->tsk = current; /* save process info to wake at shutdown */ |
@@ -361,7 +363,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
361 | GFP_KERNEL); | 363 | GFP_KERNEL); |
362 | } | 364 | } |
363 | 365 | ||
364 | while (server->tcpStatus != CifsExiting) { | 366 | while (!kthread_should_stop()) { |
365 | if (try_to_freeze()) | 367 | if (try_to_freeze()) |
366 | continue; | 368 | continue; |
367 | if (bigbuf == NULL) { | 369 | if (bigbuf == NULL) { |
@@ -400,7 +402,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
400 | kernel_recvmsg(csocket, &smb_msg, | 402 | kernel_recvmsg(csocket, &smb_msg, |
401 | &iov, 1, 4, 0 /* BB see socket.h flags */); | 403 | &iov, 1, 4, 0 /* BB see socket.h flags */); |
402 | 404 | ||
403 | if (server->tcpStatus == CifsExiting) { | 405 | if ( kthread_should_stop() ) { |
404 | break; | 406 | break; |
405 | } else if (server->tcpStatus == CifsNeedReconnect) { | 407 | } else if (server->tcpStatus == CifsNeedReconnect) { |
406 | cFYI(1, ("Reconnect after server stopped responding")); | 408 | cFYI(1, ("Reconnect after server stopped responding")); |
@@ -524,7 +526,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
524 | total_read += length) { | 526 | total_read += length) { |
525 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | 527 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, |
526 | pdu_length - total_read, 0); | 528 | pdu_length - total_read, 0); |
527 | if((server->tcpStatus == CifsExiting) || | 529 | if( kthread_should_stop() || |
528 | (length == -EINTR)) { | 530 | (length == -EINTR)) { |
529 | /* then will exit */ | 531 | /* then will exit */ |
530 | reconnect = 2; | 532 | reconnect = 2; |
@@ -757,7 +759,6 @@ multi_t2_fnd: | |||
757 | GFP_KERNEL); | 759 | GFP_KERNEL); |
758 | } | 760 | } |
759 | 761 | ||
760 | complete_and_exit(&cifsd_complete, 0); | ||
761 | return 0; | 762 | return 0; |
762 | } | 763 | } |
763 | 764 | ||
@@ -973,7 +974,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
973 | } | 974 | } |
974 | if ((temp_len = strnlen(value, 300)) < 300) { | 975 | if ((temp_len = strnlen(value, 300)) < 300) { |
975 | vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); | 976 | vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); |
976 | if(vol->UNC == NULL) | 977 | if (vol->UNC == NULL) |
977 | return 1; | 978 | return 1; |
978 | strcpy(vol->UNC,value); | 979 | strcpy(vol->UNC,value); |
979 | if (strncmp(vol->UNC, "//", 2) == 0) { | 980 | if (strncmp(vol->UNC, "//", 2) == 0) { |
@@ -1010,12 +1011,12 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1010 | return 1; /* needs_arg; */ | 1011 | return 1; /* needs_arg; */ |
1011 | } | 1012 | } |
1012 | if ((temp_len = strnlen(value, 1024)) < 1024) { | 1013 | if ((temp_len = strnlen(value, 1024)) < 1024) { |
1013 | if(value[0] != '/') | 1014 | if (value[0] != '/') |
1014 | temp_len++; /* missing leading slash */ | 1015 | temp_len++; /* missing leading slash */ |
1015 | vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); | 1016 | vol->prepath = kmalloc(temp_len+1,GFP_KERNEL); |
1016 | if(vol->prepath == NULL) | 1017 | if (vol->prepath == NULL) |
1017 | return 1; | 1018 | return 1; |
1018 | if(value[0] != '/') { | 1019 | if (value[0] != '/') { |
1019 | vol->prepath[0] = '/'; | 1020 | vol->prepath[0] = '/'; |
1020 | strcpy(vol->prepath+1,value); | 1021 | strcpy(vol->prepath+1,value); |
1021 | } else | 1022 | } else |
@@ -1031,7 +1032,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1031 | return 1; /* needs_arg; */ | 1032 | return 1; /* needs_arg; */ |
1032 | } | 1033 | } |
1033 | if (strnlen(value, 65) < 65) { | 1034 | if (strnlen(value, 65) < 65) { |
1034 | if(strnicmp(value,"default",7)) | 1035 | if (strnicmp(value,"default",7)) |
1035 | vol->iocharset = value; | 1036 | vol->iocharset = value; |
1036 | /* if iocharset not set load_nls_default used by caller */ | 1037 | /* if iocharset not set load_nls_default used by caller */ |
1037 | cFYI(1, ("iocharset set to %s",value)); | 1038 | cFYI(1, ("iocharset set to %s",value)); |
@@ -1043,11 +1044,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1043 | if (value && *value) { | 1044 | if (value && *value) { |
1044 | vol->linux_uid = | 1045 | vol->linux_uid = |
1045 | simple_strtoul(value, &value, 0); | 1046 | simple_strtoul(value, &value, 0); |
1047 | vol->override_uid = 1; | ||
1046 | } | 1048 | } |
1047 | } else if (strnicmp(data, "gid", 3) == 0) { | 1049 | } else if (strnicmp(data, "gid", 3) == 0) { |
1048 | if (value && *value) { | 1050 | if (value && *value) { |
1049 | vol->linux_gid = | 1051 | vol->linux_gid = |
1050 | simple_strtoul(value, &value, 0); | 1052 | simple_strtoul(value, &value, 0); |
1053 | vol->override_gid = 1; | ||
1051 | } | 1054 | } |
1052 | } else if (strnicmp(data, "file_mode", 4) == 0) { | 1055 | } else if (strnicmp(data, "file_mode", 4) == 0) { |
1053 | if (value && *value) { | 1056 | if (value && *value) { |
@@ -1102,7 +1105,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1102 | } | 1105 | } |
1103 | /* The string has 16th byte zero still from | 1106 | /* The string has 16th byte zero still from |
1104 | set at top of the function */ | 1107 | set at top of the function */ |
1105 | if((i==15) && (value[i] != 0)) | 1108 | if ((i==15) && (value[i] != 0)) |
1106 | printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); | 1109 | printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n"); |
1107 | } | 1110 | } |
1108 | } else if (strnicmp(data, "servern", 7) == 0) { | 1111 | } else if (strnicmp(data, "servern", 7) == 0) { |
@@ -1126,7 +1129,7 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1126 | } | 1129 | } |
1127 | /* The string has 16th byte zero still from | 1130 | /* The string has 16th byte zero still from |
1128 | set at top of the function */ | 1131 | set at top of the function */ |
1129 | if((i==15) && (value[i] != 0)) | 1132 | if ((i==15) && (value[i] != 0)) |
1130 | printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); | 1133 | printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n"); |
1131 | } | 1134 | } |
1132 | } else if (strnicmp(data, "credentials", 4) == 0) { | 1135 | } else if (strnicmp(data, "credentials", 4) == 0) { |
@@ -1233,13 +1236,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol) | |||
1233 | printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); | 1236 | printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); |
1234 | } | 1237 | } |
1235 | if (vol->UNC == NULL) { | 1238 | if (vol->UNC == NULL) { |
1236 | if(devname == NULL) { | 1239 | if (devname == NULL) { |
1237 | printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); | 1240 | printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n"); |
1238 | return 1; | 1241 | return 1; |
1239 | } | 1242 | } |
1240 | if ((temp_len = strnlen(devname, 300)) < 300) { | 1243 | if ((temp_len = strnlen(devname, 300)) < 300) { |
1241 | vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); | 1244 | vol->UNC = kmalloc(temp_len+1,GFP_KERNEL); |
1242 | if(vol->UNC == NULL) | 1245 | if (vol->UNC == NULL) |
1243 | return 1; | 1246 | return 1; |
1244 | strcpy(vol->UNC,devname); | 1247 | strcpy(vol->UNC,devname); |
1245 | if (strncmp(vol->UNC, "//", 2) == 0) { | 1248 | if (strncmp(vol->UNC, "//", 2) == 0) { |
@@ -1663,7 +1666,13 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo * tcon, | |||
1663 | CIFS_SB(sb)->mnt_cifs_flags |= | 1666 | CIFS_SB(sb)->mnt_cifs_flags |= |
1664 | CIFS_MOUNT_POSIX_PATHS; | 1667 | CIFS_MOUNT_POSIX_PATHS; |
1665 | } | 1668 | } |
1666 | 1669 | ||
1670 | /* We might be setting the path sep back to a different | ||
1671 | form if we are reconnecting and the server switched its | ||
1672 | posix path capability for this share */ | ||
1673 | if(sb && (CIFS_SB(sb)->prepathlen > 0)) | ||
1674 | CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb)); | ||
1675 | |||
1667 | cFYI(1,("Negotiate caps 0x%x",(int)cap)); | 1676 | cFYI(1,("Negotiate caps 0x%x",(int)cap)); |
1668 | #ifdef CONFIG_CIFS_DEBUG2 | 1677 | #ifdef CONFIG_CIFS_DEBUG2 |
1669 | if(cap & CIFS_UNIX_FCNTL_CAP) | 1678 | if(cap & CIFS_UNIX_FCNTL_CAP) |
@@ -1712,12 +1721,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1712 | return -EINVAL; | 1721 | return -EINVAL; |
1713 | } | 1722 | } |
1714 | 1723 | ||
1715 | if (volume_info.username) { | 1724 | if (volume_info.nullauth) { |
1725 | cFYI(1,("null user")); | ||
1726 | volume_info.username = NULL; | ||
1727 | } else if (volume_info.username) { | ||
1716 | /* BB fixme parse for domain name here */ | 1728 | /* BB fixme parse for domain name here */ |
1717 | cFYI(1, ("Username: %s ", volume_info.username)); | 1729 | cFYI(1, ("Username: %s ", volume_info.username)); |
1718 | |||
1719 | } else if (volume_info.nullauth) { | ||
1720 | cFYI(1,("null user")); | ||
1721 | } else { | 1730 | } else { |
1722 | cifserror("No username specified"); | 1731 | cifserror("No username specified"); |
1723 | /* In userspace mount helper we can get user name from alternate | 1732 | /* In userspace mount helper we can get user name from alternate |
@@ -1791,11 +1800,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1791 | existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, | 1800 | existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr, |
1792 | NULL /* no ipv6 addr */, | 1801 | NULL /* no ipv6 addr */, |
1793 | volume_info.username, &srvTcp); | 1802 | volume_info.username, &srvTcp); |
1794 | else if(address_type == AF_INET6) | 1803 | else if(address_type == AF_INET6) { |
1804 | cFYI(1,("looking for ipv6 address")); | ||
1795 | existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, | 1805 | existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */, |
1796 | &sin_server6.sin6_addr, | 1806 | &sin_server6.sin6_addr, |
1797 | volume_info.username, &srvTcp); | 1807 | volume_info.username, &srvTcp); |
1798 | else { | 1808 | } else { |
1799 | kfree(volume_info.UNC); | 1809 | kfree(volume_info.UNC); |
1800 | kfree(volume_info.password); | 1810 | kfree(volume_info.password); |
1801 | kfree(volume_info.prepath); | 1811 | kfree(volume_info.prepath); |
@@ -1807,17 +1817,23 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1807 | if (srvTcp) { | 1817 | if (srvTcp) { |
1808 | cFYI(1, ("Existing tcp session with server found")); | 1818 | cFYI(1, ("Existing tcp session with server found")); |
1809 | } else { /* create socket */ | 1819 | } else { /* create socket */ |
1810 | if(volume_info.port) | 1820 | if (volume_info.port) |
1811 | sin_server.sin_port = htons(volume_info.port); | 1821 | sin_server.sin_port = htons(volume_info.port); |
1812 | else | 1822 | else |
1813 | sin_server.sin_port = 0; | 1823 | sin_server.sin_port = 0; |
1814 | rc = ipv4_connect(&sin_server,&csocket, | 1824 | if (address_type == AF_INET6) { |
1825 | cFYI(1,("attempting ipv6 connect")); | ||
1826 | /* BB should we allow ipv6 on port 139? */ | ||
1827 | /* other OS never observed in Wild doing 139 with v6 */ | ||
1828 | rc = ipv6_connect(&sin_server6,&csocket); | ||
1829 | } else | ||
1830 | rc = ipv4_connect(&sin_server,&csocket, | ||
1815 | volume_info.source_rfc1001_name, | 1831 | volume_info.source_rfc1001_name, |
1816 | volume_info.target_rfc1001_name); | 1832 | volume_info.target_rfc1001_name); |
1817 | if (rc < 0) { | 1833 | if (rc < 0) { |
1818 | cERROR(1, | 1834 | cERROR(1, |
1819 | ("Error connecting to IPv4 socket. Aborting operation")); | 1835 | ("Error connecting to IPv4 socket. Aborting operation")); |
1820 | if(csocket != NULL) | 1836 | if (csocket != NULL) |
1821 | sock_release(csocket); | 1837 | sock_release(csocket); |
1822 | kfree(volume_info.UNC); | 1838 | kfree(volume_info.UNC); |
1823 | kfree(volume_info.password); | 1839 | kfree(volume_info.password); |
@@ -1850,10 +1866,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1850 | so no need to spinlock this init of tcpStatus */ | 1866 | so no need to spinlock this init of tcpStatus */ |
1851 | srvTcp->tcpStatus = CifsNew; | 1867 | srvTcp->tcpStatus = CifsNew; |
1852 | init_MUTEX(&srvTcp->tcpSem); | 1868 | init_MUTEX(&srvTcp->tcpSem); |
1853 | rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, | 1869 | srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); |
1854 | CLONE_FS | CLONE_FILES | CLONE_VM); | 1870 | if ( IS_ERR(srvTcp->tsk) ) { |
1855 | if(rc < 0) { | 1871 | rc = PTR_ERR(srvTcp->tsk); |
1856 | rc = -ENOMEM; | 1872 | cERROR(1,("error %d create cifsd thread", rc)); |
1873 | srvTcp->tsk = NULL; | ||
1857 | sock_release(csocket); | 1874 | sock_release(csocket); |
1858 | kfree(volume_info.UNC); | 1875 | kfree(volume_info.UNC); |
1859 | kfree(volume_info.password); | 1876 | kfree(volume_info.password); |
@@ -1896,7 +1913,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1896 | int len = strlen(volume_info.domainname); | 1913 | int len = strlen(volume_info.domainname); |
1897 | pSesInfo->domainName = | 1914 | pSesInfo->domainName = |
1898 | kmalloc(len + 1, GFP_KERNEL); | 1915 | kmalloc(len + 1, GFP_KERNEL); |
1899 | if(pSesInfo->domainName) | 1916 | if (pSesInfo->domainName) |
1900 | strcpy(pSesInfo->domainName, | 1917 | strcpy(pSesInfo->domainName, |
1901 | volume_info.domainname); | 1918 | volume_info.domainname); |
1902 | } | 1919 | } |
@@ -1906,7 +1923,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1906 | /* BB FIXME need to pass vol->secFlgs BB */ | 1923 | /* BB FIXME need to pass vol->secFlgs BB */ |
1907 | rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); | 1924 | rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls); |
1908 | up(&pSesInfo->sesSem); | 1925 | up(&pSesInfo->sesSem); |
1909 | if(!rc) | 1926 | if (!rc) |
1910 | atomic_inc(&srvTcp->socketUseCount); | 1927 | atomic_inc(&srvTcp->socketUseCount); |
1911 | } else | 1928 | } else |
1912 | kfree(volume_info.password); | 1929 | kfree(volume_info.password); |
@@ -1914,7 +1931,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1914 | 1931 | ||
1915 | /* search for existing tcon to this server share */ | 1932 | /* search for existing tcon to this server share */ |
1916 | if (!rc) { | 1933 | if (!rc) { |
1917 | if(volume_info.rsize > CIFSMaxBufSize) { | 1934 | if (volume_info.rsize > CIFSMaxBufSize) { |
1918 | cERROR(1,("rsize %d too large, using MaxBufSize", | 1935 | cERROR(1,("rsize %d too large, using MaxBufSize", |
1919 | volume_info.rsize)); | 1936 | volume_info.rsize)); |
1920 | cifs_sb->rsize = CIFSMaxBufSize; | 1937 | cifs_sb->rsize = CIFSMaxBufSize; |
@@ -1923,11 +1940,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1923 | else /* default */ | 1940 | else /* default */ |
1924 | cifs_sb->rsize = CIFSMaxBufSize; | 1941 | cifs_sb->rsize = CIFSMaxBufSize; |
1925 | 1942 | ||
1926 | if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { | 1943 | if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) { |
1927 | cERROR(1,("wsize %d too large using 4096 instead", | 1944 | cERROR(1,("wsize %d too large using 4096 instead", |
1928 | volume_info.wsize)); | 1945 | volume_info.wsize)); |
1929 | cifs_sb->wsize = 4096; | 1946 | cifs_sb->wsize = 4096; |
1930 | } else if(volume_info.wsize) | 1947 | } else if (volume_info.wsize) |
1931 | cifs_sb->wsize = volume_info.wsize; | 1948 | cifs_sb->wsize = volume_info.wsize; |
1932 | else | 1949 | else |
1933 | cifs_sb->wsize = | 1950 | cifs_sb->wsize = |
@@ -1940,14 +1957,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1940 | conjunction with 52K kvec constraint on arch with 4K | 1957 | conjunction with 52K kvec constraint on arch with 4K |
1941 | page size */ | 1958 | page size */ |
1942 | 1959 | ||
1943 | if(cifs_sb->rsize < 2048) { | 1960 | if (cifs_sb->rsize < 2048) { |
1944 | cifs_sb->rsize = 2048; | 1961 | cifs_sb->rsize = 2048; |
1945 | /* Windows ME may prefer this */ | 1962 | /* Windows ME may prefer this */ |
1946 | cFYI(1,("readsize set to minimum 2048")); | 1963 | cFYI(1,("readsize set to minimum 2048")); |
1947 | } | 1964 | } |
1948 | /* calculate prepath */ | 1965 | /* calculate prepath */ |
1949 | cifs_sb->prepath = volume_info.prepath; | 1966 | cifs_sb->prepath = volume_info.prepath; |
1950 | if(cifs_sb->prepath) { | 1967 | if (cifs_sb->prepath) { |
1951 | cifs_sb->prepathlen = strlen(cifs_sb->prepath); | 1968 | cifs_sb->prepathlen = strlen(cifs_sb->prepath); |
1952 | cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); | 1969 | cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb); |
1953 | volume_info.prepath = NULL; | 1970 | volume_info.prepath = NULL; |
@@ -1960,24 +1977,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1960 | cFYI(1,("file mode: 0x%x dir mode: 0x%x", | 1977 | cFYI(1,("file mode: 0x%x dir mode: 0x%x", |
1961 | cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); | 1978 | cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode)); |
1962 | 1979 | ||
1963 | if(volume_info.noperm) | 1980 | if (volume_info.noperm) |
1964 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; | 1981 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; |
1965 | if(volume_info.setuids) | 1982 | if (volume_info.setuids) |
1966 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; | 1983 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; |
1967 | if(volume_info.server_ino) | 1984 | if (volume_info.server_ino) |
1968 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; | 1985 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; |
1969 | if(volume_info.remap) | 1986 | if (volume_info.remap) |
1970 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; | 1987 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; |
1971 | if(volume_info.no_xattr) | 1988 | if (volume_info.no_xattr) |
1972 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; | 1989 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; |
1973 | if(volume_info.sfu_emul) | 1990 | if (volume_info.sfu_emul) |
1974 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; | 1991 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; |
1975 | if(volume_info.nobrl) | 1992 | if (volume_info.nobrl) |
1976 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; | 1993 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; |
1977 | if(volume_info.cifs_acl) | 1994 | if (volume_info.cifs_acl) |
1978 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | 1995 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; |
1979 | 1996 | if (volume_info.override_uid) | |
1980 | if(volume_info.direct_io) { | 1997 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; |
1998 | if (volume_info.override_gid) | ||
1999 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; | ||
2000 | if (volume_info.direct_io) { | ||
1981 | cFYI(1,("mounting share using direct i/o")); | 2001 | cFYI(1,("mounting share using direct i/o")); |
1982 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; | 2002 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; |
1983 | } | 2003 | } |
@@ -2030,7 +2050,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2030 | } | 2050 | } |
2031 | } | 2051 | } |
2032 | } | 2052 | } |
2033 | if(pSesInfo) { | 2053 | if (pSesInfo) { |
2034 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { | 2054 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { |
2035 | sb->s_maxbytes = (u64) 1 << 63; | 2055 | sb->s_maxbytes = (u64) 1 << 63; |
2036 | } else | 2056 | } else |
@@ -2044,13 +2064,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2044 | if (rc) { | 2064 | if (rc) { |
2045 | /* if session setup failed, use count is zero but | 2065 | /* if session setup failed, use count is zero but |
2046 | we still need to free cifsd thread */ | 2066 | we still need to free cifsd thread */ |
2047 | if(atomic_read(&srvTcp->socketUseCount) == 0) { | 2067 | if (atomic_read(&srvTcp->socketUseCount) == 0) { |
2048 | spin_lock(&GlobalMid_Lock); | 2068 | spin_lock(&GlobalMid_Lock); |
2049 | srvTcp->tcpStatus = CifsExiting; | 2069 | srvTcp->tcpStatus = CifsExiting; |
2050 | spin_unlock(&GlobalMid_Lock); | 2070 | spin_unlock(&GlobalMid_Lock); |
2051 | if(srvTcp->tsk) { | 2071 | if (srvTcp->tsk) { |
2052 | send_sig(SIGKILL,srvTcp->tsk,1); | 2072 | send_sig(SIGKILL,srvTcp->tsk,1); |
2053 | wait_for_completion(&cifsd_complete); | 2073 | kthread_stop(srvTcp->tsk); |
2054 | } | 2074 | } |
2055 | } | 2075 | } |
2056 | /* If find_unc succeeded then rc == 0 so we can not end */ | 2076 | /* If find_unc succeeded then rc == 0 so we can not end */ |
@@ -2063,10 +2083,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2063 | int temp_rc; | 2083 | int temp_rc; |
2064 | temp_rc = CIFSSMBLogoff(xid, pSesInfo); | 2084 | temp_rc = CIFSSMBLogoff(xid, pSesInfo); |
2065 | /* if the socketUseCount is now zero */ | 2085 | /* if the socketUseCount is now zero */ |
2066 | if((temp_rc == -ESHUTDOWN) && | 2086 | if ((temp_rc == -ESHUTDOWN) && |
2067 | (pSesInfo->server->tsk)) { | 2087 | (pSesInfo->server) && (pSesInfo->server->tsk)) { |
2068 | send_sig(SIGKILL,pSesInfo->server->tsk,1); | 2088 | send_sig(SIGKILL,pSesInfo->server->tsk,1); |
2069 | wait_for_completion(&cifsd_complete); | 2089 | kthread_stop(pSesInfo->server->tsk); |
2070 | } | 2090 | } |
2071 | } else | 2091 | } else |
2072 | cFYI(1, ("No session or bad tcon")); | 2092 | cFYI(1, ("No session or bad tcon")); |
@@ -2127,7 +2147,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2127 | __u16 count; | 2147 | __u16 count; |
2128 | 2148 | ||
2129 | cFYI(1, ("In sesssetup")); | 2149 | cFYI(1, ("In sesssetup")); |
2130 | if(ses == NULL) | 2150 | if (ses == NULL) |
2131 | return -EINVAL; | 2151 | return -EINVAL; |
2132 | user = ses->userName; | 2152 | user = ses->userName; |
2133 | domain = ses->domainName; | 2153 | domain = ses->domainName; |
@@ -2182,7 +2202,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2182 | *bcc_ptr = 0; | 2202 | *bcc_ptr = 0; |
2183 | bcc_ptr++; | 2203 | bcc_ptr++; |
2184 | } | 2204 | } |
2185 | if(user == NULL) | 2205 | if (user == NULL) |
2186 | bytes_returned = 0; /* skip null user */ | 2206 | bytes_returned = 0; /* skip null user */ |
2187 | else | 2207 | else |
2188 | bytes_returned = | 2208 | bytes_returned = |
@@ -2216,7 +2236,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2216 | bcc_ptr += 2 * bytes_returned; | 2236 | bcc_ptr += 2 * bytes_returned; |
2217 | bcc_ptr += 2; | 2237 | bcc_ptr += 2; |
2218 | } else { | 2238 | } else { |
2219 | if(user != NULL) { | 2239 | if (user != NULL) { |
2220 | strncpy(bcc_ptr, user, 200); | 2240 | strncpy(bcc_ptr, user, 200); |
2221 | bcc_ptr += strnlen(user, 200); | 2241 | bcc_ptr += strnlen(user, 200); |
2222 | } | 2242 | } |
@@ -3316,7 +3336,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3316 | cFYI(1,("Waking up socket by sending it signal")); | 3336 | cFYI(1,("Waking up socket by sending it signal")); |
3317 | if(cifsd_task) { | 3337 | if(cifsd_task) { |
3318 | send_sig(SIGKILL,cifsd_task,1); | 3338 | send_sig(SIGKILL,cifsd_task,1); |
3319 | wait_for_completion(&cifsd_complete); | 3339 | kthread_stop(cifsd_task); |
3320 | } | 3340 | } |
3321 | rc = 0; | 3341 | rc = 0; |
3322 | } /* else - we have an smb session | 3342 | } /* else - we have an smb session |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3fad638d26d3..e5210519ac4b 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -274,7 +274,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
274 | pCifsFile->invalidHandle = FALSE; | 274 | pCifsFile->invalidHandle = FALSE; |
275 | pCifsFile->closePend = FALSE; | 275 | pCifsFile->closePend = FALSE; |
276 | init_MUTEX(&pCifsFile->fh_sem); | 276 | init_MUTEX(&pCifsFile->fh_sem); |
277 | init_MUTEX(&pCifsFile->lock_sem); | 277 | mutex_init(&pCifsFile->lock_mutex); |
278 | INIT_LIST_HEAD(&pCifsFile->llist); | 278 | INIT_LIST_HEAD(&pCifsFile->llist); |
279 | atomic_set(&pCifsFile->wrtPending,0); | 279 | atomic_set(&pCifsFile->wrtPending,0); |
280 | 280 | ||
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 2d3275bedb55..b570530f97bf 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -48,7 +48,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
48 | private_data->netfid = netfid; | 48 | private_data->netfid = netfid; |
49 | private_data->pid = current->tgid; | 49 | private_data->pid = current->tgid; |
50 | init_MUTEX(&private_data->fh_sem); | 50 | init_MUTEX(&private_data->fh_sem); |
51 | init_MUTEX(&private_data->lock_sem); | 51 | mutex_init(&private_data->lock_mutex); |
52 | INIT_LIST_HEAD(&private_data->llist); | 52 | INIT_LIST_HEAD(&private_data->llist); |
53 | private_data->pfile = file; /* needed for writepage */ | 53 | private_data->pfile = file; /* needed for writepage */ |
54 | private_data->pInode = inode; | 54 | private_data->pInode = inode; |
@@ -338,8 +338,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile) | |||
338 | return rc; | 338 | return rc; |
339 | } | 339 | } |
340 | 340 | ||
341 | static int cifs_reopen_file(struct inode *inode, struct file *file, | 341 | static int cifs_reopen_file(struct file *file, int can_flush) |
342 | int can_flush) | ||
343 | { | 342 | { |
344 | int rc = -EACCES; | 343 | int rc = -EACCES; |
345 | int xid, oplock; | 344 | int xid, oplock; |
@@ -347,13 +346,12 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
347 | struct cifsTconInfo *pTcon; | 346 | struct cifsTconInfo *pTcon; |
348 | struct cifsFileInfo *pCifsFile; | 347 | struct cifsFileInfo *pCifsFile; |
349 | struct cifsInodeInfo *pCifsInode; | 348 | struct cifsInodeInfo *pCifsInode; |
349 | struct inode * inode; | ||
350 | char *full_path = NULL; | 350 | char *full_path = NULL; |
351 | int desiredAccess; | 351 | int desiredAccess; |
352 | int disposition = FILE_OPEN; | 352 | int disposition = FILE_OPEN; |
353 | __u16 netfid; | 353 | __u16 netfid; |
354 | 354 | ||
355 | if (inode == NULL) | ||
356 | return -EBADF; | ||
357 | if (file->private_data) { | 355 | if (file->private_data) { |
358 | pCifsFile = (struct cifsFileInfo *)file->private_data; | 356 | pCifsFile = (struct cifsFileInfo *)file->private_data; |
359 | } else | 357 | } else |
@@ -368,25 +366,37 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
368 | } | 366 | } |
369 | 367 | ||
370 | if (file->f_path.dentry == NULL) { | 368 | if (file->f_path.dentry == NULL) { |
371 | up(&pCifsFile->fh_sem); | 369 | cERROR(1, ("no valid name if dentry freed")); |
372 | cFYI(1, ("failed file reopen, no valid name if dentry freed")); | 370 | dump_stack(); |
373 | FreeXid(xid); | 371 | rc = -EBADF; |
374 | return -EBADF; | 372 | goto reopen_error_exit; |
375 | } | 373 | } |
374 | |||
375 | inode = file->f_path.dentry->d_inode; | ||
376 | if(inode == NULL) { | ||
377 | cERROR(1, ("inode not valid")); | ||
378 | dump_stack(); | ||
379 | rc = -EBADF; | ||
380 | goto reopen_error_exit; | ||
381 | } | ||
382 | |||
376 | cifs_sb = CIFS_SB(inode->i_sb); | 383 | cifs_sb = CIFS_SB(inode->i_sb); |
377 | pTcon = cifs_sb->tcon; | 384 | pTcon = cifs_sb->tcon; |
385 | |||
378 | /* can not grab rename sem here because various ops, including | 386 | /* can not grab rename sem here because various ops, including |
379 | those that already have the rename sem can end up causing writepage | 387 | those that already have the rename sem can end up causing writepage |
380 | to get called and if the server was down that means we end up here, | 388 | to get called and if the server was down that means we end up here, |
381 | and we can never tell if the caller already has the rename_sem */ | 389 | and we can never tell if the caller already has the rename_sem */ |
382 | full_path = build_path_from_dentry(file->f_path.dentry); | 390 | full_path = build_path_from_dentry(file->f_path.dentry); |
383 | if (full_path == NULL) { | 391 | if (full_path == NULL) { |
392 | rc = -ENOMEM; | ||
393 | reopen_error_exit: | ||
384 | up(&pCifsFile->fh_sem); | 394 | up(&pCifsFile->fh_sem); |
385 | FreeXid(xid); | 395 | FreeXid(xid); |
386 | return -ENOMEM; | 396 | return rc; |
387 | } | 397 | } |
388 | 398 | ||
389 | cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", | 399 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", |
390 | inode, file->f_flags,full_path)); | 400 | inode, file->f_flags,full_path)); |
391 | desiredAccess = cifs_convert_flags(file->f_flags); | 401 | desiredAccess = cifs_convert_flags(file->f_flags); |
392 | 402 | ||
@@ -401,13 +411,6 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
401 | and server version of file size can be stale. If we knew for sure | 411 | and server version of file size can be stale. If we knew for sure |
402 | that inode was not dirty locally we could do this */ | 412 | that inode was not dirty locally we could do this */ |
403 | 413 | ||
404 | /* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | ||
405 | if (buf == 0) { | ||
406 | up(&pCifsFile->fh_sem); | ||
407 | kfree(full_path); | ||
408 | FreeXid(xid); | ||
409 | return -ENOMEM; | ||
410 | } */ | ||
411 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 414 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
412 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 415 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
413 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 416 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
@@ -508,12 +511,12 @@ int cifs_close(struct inode *inode, struct file *file) | |||
508 | 511 | ||
509 | /* Delete any outstanding lock records. | 512 | /* Delete any outstanding lock records. |
510 | We'll lose them when the file is closed anyway. */ | 513 | We'll lose them when the file is closed anyway. */ |
511 | down(&pSMBFile->lock_sem); | 514 | mutex_lock(&pSMBFile->lock_mutex); |
512 | list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { | 515 | list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { |
513 | list_del(&li->llist); | 516 | list_del(&li->llist); |
514 | kfree(li); | 517 | kfree(li); |
515 | } | 518 | } |
516 | up(&pSMBFile->lock_sem); | 519 | mutex_unlock(&pSMBFile->lock_mutex); |
517 | 520 | ||
518 | write_lock(&GlobalSMBSeslock); | 521 | write_lock(&GlobalSMBSeslock); |
519 | list_del(&pSMBFile->flist); | 522 | list_del(&pSMBFile->flist); |
@@ -598,9 +601,9 @@ static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | |||
598 | li->offset = offset; | 601 | li->offset = offset; |
599 | li->length = len; | 602 | li->length = len; |
600 | li->type = lockType; | 603 | li->type = lockType; |
601 | down(&fid->lock_sem); | 604 | mutex_lock(&fid->lock_mutex); |
602 | list_add(&li->llist, &fid->llist); | 605 | list_add(&li->llist, &fid->llist); |
603 | up(&fid->lock_sem); | 606 | mutex_unlock(&fid->lock_mutex); |
604 | return 0; | 607 | return 0; |
605 | } | 608 | } |
606 | 609 | ||
@@ -757,7 +760,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
757 | struct cifsLockInfo *li, *tmp; | 760 | struct cifsLockInfo *li, *tmp; |
758 | 761 | ||
759 | rc = 0; | 762 | rc = 0; |
760 | down(&fid->lock_sem); | 763 | mutex_lock(&fid->lock_mutex); |
761 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 764 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { |
762 | if (pfLock->fl_start <= li->offset && | 765 | if (pfLock->fl_start <= li->offset && |
763 | length >= li->length) { | 766 | length >= li->length) { |
@@ -771,7 +774,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
771 | kfree(li); | 774 | kfree(li); |
772 | } | 775 | } |
773 | } | 776 | } |
774 | up(&fid->lock_sem); | 777 | mutex_unlock(&fid->lock_mutex); |
775 | } | 778 | } |
776 | } | 779 | } |
777 | 780 | ||
@@ -792,12 +795,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
792 | int xid, long_op; | 795 | int xid, long_op; |
793 | struct cifsFileInfo *open_file; | 796 | struct cifsFileInfo *open_file; |
794 | 797 | ||
795 | if (file->f_path.dentry == NULL) | ||
796 | return -EBADF; | ||
797 | |||
798 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 798 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
799 | if (cifs_sb == NULL) | ||
800 | return -EBADF; | ||
801 | 799 | ||
802 | pTcon = cifs_sb->tcon; | 800 | pTcon = cifs_sb->tcon; |
803 | 801 | ||
@@ -807,14 +805,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
807 | 805 | ||
808 | if (file->private_data == NULL) | 806 | if (file->private_data == NULL) |
809 | return -EBADF; | 807 | return -EBADF; |
810 | else | 808 | open_file = (struct cifsFileInfo *) file->private_data; |
811 | open_file = (struct cifsFileInfo *) file->private_data; | ||
812 | 809 | ||
813 | xid = GetXid(); | 810 | xid = GetXid(); |
814 | if (file->f_path.dentry->d_inode == NULL) { | ||
815 | FreeXid(xid); | ||
816 | return -EBADF; | ||
817 | } | ||
818 | 811 | ||
819 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 812 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
820 | long_op = 2; /* writes past end of file can take a long time */ | 813 | long_op = 2; /* writes past end of file can take a long time */ |
@@ -841,17 +834,11 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
841 | return -EBADF; | 834 | return -EBADF; |
842 | } | 835 | } |
843 | if (open_file->invalidHandle) { | 836 | if (open_file->invalidHandle) { |
844 | if ((file->f_path.dentry == NULL) || | ||
845 | (file->f_path.dentry->d_inode == NULL)) { | ||
846 | FreeXid(xid); | ||
847 | return total_written; | ||
848 | } | ||
849 | /* we could deadlock if we called | 837 | /* we could deadlock if we called |
850 | filemap_fdatawait from here so tell | 838 | filemap_fdatawait from here so tell |
851 | reopen_file not to flush data to server | 839 | reopen_file not to flush data to server |
852 | now */ | 840 | now */ |
853 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 841 | rc = cifs_reopen_file(file, FALSE); |
854 | file, FALSE); | ||
855 | if (rc != 0) | 842 | if (rc != 0) |
856 | break; | 843 | break; |
857 | } | 844 | } |
@@ -908,12 +895,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
908 | int xid, long_op; | 895 | int xid, long_op; |
909 | struct cifsFileInfo *open_file; | 896 | struct cifsFileInfo *open_file; |
910 | 897 | ||
911 | if (file->f_path.dentry == NULL) | ||
912 | return -EBADF; | ||
913 | |||
914 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 898 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
915 | if (cifs_sb == NULL) | ||
916 | return -EBADF; | ||
917 | 899 | ||
918 | pTcon = cifs_sb->tcon; | 900 | pTcon = cifs_sb->tcon; |
919 | 901 | ||
@@ -922,14 +904,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
922 | 904 | ||
923 | if (file->private_data == NULL) | 905 | if (file->private_data == NULL) |
924 | return -EBADF; | 906 | return -EBADF; |
925 | else | 907 | open_file = (struct cifsFileInfo *)file->private_data; |
926 | open_file = (struct cifsFileInfo *)file->private_data; | ||
927 | 908 | ||
928 | xid = GetXid(); | 909 | xid = GetXid(); |
929 | if (file->f_path.dentry->d_inode == NULL) { | ||
930 | FreeXid(xid); | ||
931 | return -EBADF; | ||
932 | } | ||
933 | 910 | ||
934 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 911 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
935 | long_op = 2; /* writes past end of file can take a long time */ | 912 | long_op = 2; /* writes past end of file can take a long time */ |
@@ -957,17 +934,11 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
957 | return -EBADF; | 934 | return -EBADF; |
958 | } | 935 | } |
959 | if (open_file->invalidHandle) { | 936 | if (open_file->invalidHandle) { |
960 | if ((file->f_path.dentry == NULL) || | ||
961 | (file->f_path.dentry->d_inode == NULL)) { | ||
962 | FreeXid(xid); | ||
963 | return total_written; | ||
964 | } | ||
965 | /* we could deadlock if we called | 937 | /* we could deadlock if we called |
966 | filemap_fdatawait from here so tell | 938 | filemap_fdatawait from here so tell |
967 | reopen_file not to flush data to | 939 | reopen_file not to flush data to |
968 | server now */ | 940 | server now */ |
969 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 941 | rc = cifs_reopen_file(file, FALSE); |
970 | file, FALSE); | ||
971 | if (rc != 0) | 942 | if (rc != 0) |
972 | break; | 943 | break; |
973 | } | 944 | } |
@@ -1056,8 +1027,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1056 | read_unlock(&GlobalSMBSeslock); | 1027 | read_unlock(&GlobalSMBSeslock); |
1057 | if((open_file->invalidHandle) && | 1028 | if((open_file->invalidHandle) && |
1058 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { | 1029 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { |
1059 | rc = cifs_reopen_file(&cifs_inode->vfs_inode, | 1030 | rc = cifs_reopen_file(open_file->pfile, FALSE); |
1060 | open_file->pfile, FALSE); | ||
1061 | /* if it fails, try another handle - might be */ | 1031 | /* if it fails, try another handle - might be */ |
1062 | /* dangerous to hold up writepages with retry */ | 1032 | /* dangerous to hold up writepages with retry */ |
1063 | if(rc) { | 1033 | if(rc) { |
@@ -1404,32 +1374,6 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1404 | spin_lock(&inode->i_lock); | 1374 | spin_lock(&inode->i_lock); |
1405 | if (position > inode->i_size) { | 1375 | if (position > inode->i_size) { |
1406 | i_size_write(inode, position); | 1376 | i_size_write(inode, position); |
1407 | /* if (file->private_data == NULL) { | ||
1408 | rc = -EBADF; | ||
1409 | } else { | ||
1410 | open_file = (struct cifsFileInfo *)file->private_data; | ||
1411 | cifs_sb = CIFS_SB(inode->i_sb); | ||
1412 | rc = -EAGAIN; | ||
1413 | while (rc == -EAGAIN) { | ||
1414 | if ((open_file->invalidHandle) && | ||
1415 | (!open_file->closePend)) { | ||
1416 | rc = cifs_reopen_file( | ||
1417 | file->f_path.dentry->d_inode, file); | ||
1418 | if (rc != 0) | ||
1419 | break; | ||
1420 | } | ||
1421 | if (!open_file->closePend) { | ||
1422 | rc = CIFSSMBSetFileSize(xid, | ||
1423 | cifs_sb->tcon, position, | ||
1424 | open_file->netfid, | ||
1425 | open_file->pid, FALSE); | ||
1426 | } else { | ||
1427 | rc = -EBADF; | ||
1428 | break; | ||
1429 | } | ||
1430 | } | ||
1431 | cFYI(1, (" SetEOF (commit write) rc = %d", rc)); | ||
1432 | } */ | ||
1433 | } | 1377 | } |
1434 | spin_unlock(&inode->i_lock); | 1378 | spin_unlock(&inode->i_lock); |
1435 | if (!PageUptodate(page)) { | 1379 | if (!PageUptodate(page)) { |
@@ -1573,8 +1517,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1573 | int buf_type = CIFS_NO_BUFFER; | 1517 | int buf_type = CIFS_NO_BUFFER; |
1574 | if ((open_file->invalidHandle) && | 1518 | if ((open_file->invalidHandle) && |
1575 | (!open_file->closePend)) { | 1519 | (!open_file->closePend)) { |
1576 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1520 | rc = cifs_reopen_file(file, TRUE); |
1577 | file, TRUE); | ||
1578 | if (rc != 0) | 1521 | if (rc != 0) |
1579 | break; | 1522 | break; |
1580 | } | 1523 | } |
@@ -1660,8 +1603,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1660 | while (rc == -EAGAIN) { | 1603 | while (rc == -EAGAIN) { |
1661 | if ((open_file->invalidHandle) && | 1604 | if ((open_file->invalidHandle) && |
1662 | (!open_file->closePend)) { | 1605 | (!open_file->closePend)) { |
1663 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1606 | rc = cifs_reopen_file(file, TRUE); |
1664 | file, TRUE); | ||
1665 | if (rc != 0) | 1607 | if (rc != 0) |
1666 | break; | 1608 | break; |
1667 | } | 1609 | } |
@@ -1817,8 +1759,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1817 | while (rc == -EAGAIN) { | 1759 | while (rc == -EAGAIN) { |
1818 | if ((open_file->invalidHandle) && | 1760 | if ((open_file->invalidHandle) && |
1819 | (!open_file->closePend)) { | 1761 | (!open_file->closePend)) { |
1820 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1762 | rc = cifs_reopen_file(file, TRUE); |
1821 | file, TRUE); | ||
1822 | if (rc != 0) | 1763 | if (rc != 0) |
1823 | break; | 1764 | break; |
1824 | } | 1765 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index f414526e476a..3e87dad3367c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/inode.c | 2 | * fs/cifs/inode.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2005 | 4 | * Copyright (C) International Business Machines Corp., 2002,2007 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -90,7 +90,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
90 | (*pinode)->i_ino = | 90 | (*pinode)->i_ino = |
91 | (unsigned long)findData.UniqueId; | 91 | (unsigned long)findData.UniqueId; |
92 | } /* note ino incremented to unique num in new_inode */ | 92 | } /* note ino incremented to unique num in new_inode */ |
93 | if(sb->s_flags & MS_NOATIME) | 93 | if (sb->s_flags & MS_NOATIME) |
94 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; | 94 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; |
95 | 95 | ||
96 | insert_inode_hash(*pinode); | 96 | insert_inode_hash(*pinode); |
@@ -139,8 +139,17 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
139 | inode->i_mode |= S_IFREG; | 139 | inode->i_mode |= S_IFREG; |
140 | cFYI(1,("unknown type %d",type)); | 140 | cFYI(1,("unknown type %d",type)); |
141 | } | 141 | } |
142 | inode->i_uid = le64_to_cpu(findData.Uid); | 142 | |
143 | inode->i_gid = le64_to_cpu(findData.Gid); | 143 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
144 | inode->i_uid = cifs_sb->mnt_uid; | ||
145 | else | ||
146 | inode->i_uid = le64_to_cpu(findData.Uid); | ||
147 | |||
148 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | ||
149 | inode->i_gid = cifs_sb->mnt_gid; | ||
150 | else | ||
151 | inode->i_gid = le64_to_cpu(findData.Gid); | ||
152 | |||
144 | inode->i_nlink = le64_to_cpu(findData.Nlinks); | 153 | inode->i_nlink = le64_to_cpu(findData.Nlinks); |
145 | 154 | ||
146 | spin_lock(&inode->i_lock); | 155 | spin_lock(&inode->i_lock); |
@@ -178,13 +187,13 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
178 | &cifs_file_direct_nobrl_ops; | 187 | &cifs_file_direct_nobrl_ops; |
179 | else | 188 | else |
180 | inode->i_fop = &cifs_file_direct_ops; | 189 | inode->i_fop = &cifs_file_direct_ops; |
181 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 190 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
182 | inode->i_fop = &cifs_file_nobrl_ops; | 191 | inode->i_fop = &cifs_file_nobrl_ops; |
183 | else /* not direct, send byte range locks */ | 192 | else /* not direct, send byte range locks */ |
184 | inode->i_fop = &cifs_file_ops; | 193 | inode->i_fop = &cifs_file_ops; |
185 | 194 | ||
186 | /* check if server can support readpages */ | 195 | /* check if server can support readpages */ |
187 | if(pTcon->ses->server->maxBuf < | 196 | if (pTcon->ses->server->maxBuf < |
188 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) | 197 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) |
189 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | 198 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; |
190 | else | 199 | else |
@@ -220,7 +229,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
220 | 229 | ||
221 | pbuf = buf; | 230 | pbuf = buf; |
222 | 231 | ||
223 | if(size == 0) { | 232 | if (size == 0) { |
224 | inode->i_mode |= S_IFIFO; | 233 | inode->i_mode |= S_IFIFO; |
225 | return 0; | 234 | return 0; |
226 | } else if (size < 8) { | 235 | } else if (size < 8) { |
@@ -239,11 +248,11 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
239 | netfid, | 248 | netfid, |
240 | 24 /* length */, 0 /* offset */, | 249 | 24 /* length */, 0 /* offset */, |
241 | &bytes_read, &pbuf, &buf_type); | 250 | &bytes_read, &pbuf, &buf_type); |
242 | if((rc == 0) && (bytes_read >= 8)) { | 251 | if ((rc == 0) && (bytes_read >= 8)) { |
243 | if(memcmp("IntxBLK", pbuf, 8) == 0) { | 252 | if (memcmp("IntxBLK", pbuf, 8) == 0) { |
244 | cFYI(1,("Block device")); | 253 | cFYI(1,("Block device")); |
245 | inode->i_mode |= S_IFBLK; | 254 | inode->i_mode |= S_IFBLK; |
246 | if(bytes_read == 24) { | 255 | if (bytes_read == 24) { |
247 | /* we have enough to decode dev num */ | 256 | /* we have enough to decode dev num */ |
248 | __u64 mjr; /* major */ | 257 | __u64 mjr; /* major */ |
249 | __u64 mnr; /* minor */ | 258 | __u64 mnr; /* minor */ |
@@ -251,10 +260,10 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
251 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | 260 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); |
252 | inode->i_rdev = MKDEV(mjr, mnr); | 261 | inode->i_rdev = MKDEV(mjr, mnr); |
253 | } | 262 | } |
254 | } else if(memcmp("IntxCHR", pbuf, 8) == 0) { | 263 | } else if (memcmp("IntxCHR", pbuf, 8) == 0) { |
255 | cFYI(1,("Char device")); | 264 | cFYI(1,("Char device")); |
256 | inode->i_mode |= S_IFCHR; | 265 | inode->i_mode |= S_IFCHR; |
257 | if(bytes_read == 24) { | 266 | if (bytes_read == 24) { |
258 | /* we have enough to decode dev num */ | 267 | /* we have enough to decode dev num */ |
259 | __u64 mjr; /* major */ | 268 | __u64 mjr; /* major */ |
260 | __u64 mnr; /* minor */ | 269 | __u64 mnr; /* minor */ |
@@ -262,7 +271,7 @@ static int decode_sfu_inode(struct inode * inode, __u64 size, | |||
262 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); | 271 | mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); |
263 | inode->i_rdev = MKDEV(mjr, mnr); | 272 | inode->i_rdev = MKDEV(mjr, mnr); |
264 | } | 273 | } |
265 | } else if(memcmp("IntxLNK", pbuf, 7) == 0) { | 274 | } else if (memcmp("IntxLNK", pbuf, 7) == 0) { |
266 | cFYI(1,("Symlink")); | 275 | cFYI(1,("Symlink")); |
267 | inode->i_mode |= S_IFLNK; | 276 | inode->i_mode |= S_IFLNK; |
268 | } else { | 277 | } else { |
@@ -293,7 +302,7 @@ static int get_sfu_uid_mode(struct inode * inode, | |||
293 | rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", | 302 | rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", |
294 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, | 303 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, |
295 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 304 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
296 | if(rc < 0) | 305 | if (rc < 0) |
297 | return (int)rc; | 306 | return (int)rc; |
298 | else if (rc > 3) { | 307 | else if (rc > 3) { |
299 | mode = le32_to_cpu(*((__le32 *)ea_value)); | 308 | mode = le32_to_cpu(*((__le32 *)ea_value)); |
@@ -348,7 +357,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
348 | /* BB optimize code so we do not make the above call | 357 | /* BB optimize code so we do not make the above call |
349 | when server claims no NT SMB support and the above call | 358 | when server claims no NT SMB support and the above call |
350 | failed at least once - set flag in tcon or mount */ | 359 | failed at least once - set flag in tcon or mount */ |
351 | if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { | 360 | if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { |
352 | rc = SMBQueryInformation(xid, pTcon, search_path, | 361 | rc = SMBQueryInformation(xid, pTcon, search_path, |
353 | pfindData, cifs_sb->local_nls, | 362 | pfindData, cifs_sb->local_nls, |
354 | cifs_sb->mnt_cifs_flags & | 363 | cifs_sb->mnt_cifs_flags & |
@@ -425,7 +434,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
425 | } else /* do we need cast or hash to ino? */ | 434 | } else /* do we need cast or hash to ino? */ |
426 | (*pinode)->i_ino = inode_num; | 435 | (*pinode)->i_ino = inode_num; |
427 | } /* else ino incremented to unique num in new_inode*/ | 436 | } /* else ino incremented to unique num in new_inode*/ |
428 | if(sb->s_flags & MS_NOATIME) | 437 | if (sb->s_flags & MS_NOATIME) |
429 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; | 438 | (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME; |
430 | insert_inode_hash(*pinode); | 439 | insert_inode_hash(*pinode); |
431 | } | 440 | } |
@@ -442,7 +451,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
442 | (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ | 451 | (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ |
443 | 452 | ||
444 | /* Linux can not store file creation time so ignore it */ | 453 | /* Linux can not store file creation time so ignore it */ |
445 | if(pfindData->LastAccessTime) | 454 | if (pfindData->LastAccessTime) |
446 | inode->i_atime = cifs_NTtimeToUnix | 455 | inode->i_atime = cifs_NTtimeToUnix |
447 | (le64_to_cpu(pfindData->LastAccessTime)); | 456 | (le64_to_cpu(pfindData->LastAccessTime)); |
448 | else /* do not need to use current_fs_time - time not stored */ | 457 | else /* do not need to use current_fs_time - time not stored */ |
@@ -452,7 +461,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
452 | inode->i_ctime = | 461 | inode->i_ctime = |
453 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 462 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
454 | cFYI(0, ("Attributes came in as 0x%x", attr)); | 463 | cFYI(0, ("Attributes came in as 0x%x", attr)); |
455 | if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { | 464 | if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { |
456 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; | 465 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; |
457 | inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; | 466 | inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; |
458 | } | 467 | } |
@@ -521,8 +530,10 @@ int cifs_get_inode_info(struct inode **pinode, | |||
521 | 530 | ||
522 | /* BB fill in uid and gid here? with help from winbind? | 531 | /* BB fill in uid and gid here? with help from winbind? |
523 | or retrieve from NTFS stream extended attribute */ | 532 | or retrieve from NTFS stream extended attribute */ |
524 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 533 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
525 | /* fill in uid, gid, mode from server ACL */ | 534 | /* fill in uid, gid, mode from server ACL */ |
535 | /* BB FIXME this should also take into account the | ||
536 | * default uid specified on mount if present */ | ||
526 | get_sfu_uid_mode(inode, search_path, cifs_sb, xid); | 537 | get_sfu_uid_mode(inode, search_path, cifs_sb, xid); |
527 | } else if (atomic_read(&cifsInfo->inUse) == 0) { | 538 | } else if (atomic_read(&cifsInfo->inUse) == 0) { |
528 | inode->i_uid = cifs_sb->mnt_uid; | 539 | inode->i_uid = cifs_sb->mnt_uid; |
@@ -541,12 +552,12 @@ int cifs_get_inode_info(struct inode **pinode, | |||
541 | &cifs_file_direct_nobrl_ops; | 552 | &cifs_file_direct_nobrl_ops; |
542 | else | 553 | else |
543 | inode->i_fop = &cifs_file_direct_ops; | 554 | inode->i_fop = &cifs_file_direct_ops; |
544 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 555 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
545 | inode->i_fop = &cifs_file_nobrl_ops; | 556 | inode->i_fop = &cifs_file_nobrl_ops; |
546 | else /* not direct, send byte range locks */ | 557 | else /* not direct, send byte range locks */ |
547 | inode->i_fop = &cifs_file_ops; | 558 | inode->i_fop = &cifs_file_ops; |
548 | 559 | ||
549 | if(pTcon->ses->server->maxBuf < | 560 | if (pTcon->ses->server->maxBuf < |
550 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) | 561 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) |
551 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | 562 | inode->i_data.a_ops = &cifs_addr_ops_smallbuf; |
552 | else | 563 | else |
@@ -597,7 +608,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
597 | 608 | ||
598 | xid = GetXid(); | 609 | xid = GetXid(); |
599 | 610 | ||
600 | if(inode) | 611 | if (inode) |
601 | cifs_sb = CIFS_SB(inode->i_sb); | 612 | cifs_sb = CIFS_SB(inode->i_sb); |
602 | else | 613 | else |
603 | cifs_sb = CIFS_SB(direntry->d_sb); | 614 | cifs_sb = CIFS_SB(direntry->d_sb); |
@@ -723,7 +734,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
723 | when needed */ | 734 | when needed */ |
724 | direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); | 735 | direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); |
725 | } | 736 | } |
726 | if(inode) { | 737 | if (inode) { |
727 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | 738 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); |
728 | cifsInode = CIFS_I(inode); | 739 | cifsInode = CIFS_I(inode); |
729 | cifsInode->time = 0; /* force revalidate of dir as well */ | 740 | cifsInode->time = 0; /* force revalidate of dir as well */ |
@@ -734,6 +745,136 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
734 | return rc; | 745 | return rc; |
735 | } | 746 | } |
736 | 747 | ||
748 | static void posix_fill_in_inode(struct inode *tmp_inode, | ||
749 | FILE_UNIX_BASIC_INFO *pData, int *pobject_type, int isNewInode) | ||
750 | { | ||
751 | loff_t local_size; | ||
752 | struct timespec local_mtime; | ||
753 | |||
754 | struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); | ||
755 | struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); | ||
756 | |||
757 | __u32 type = le32_to_cpu(pData->Type); | ||
758 | __u64 num_of_bytes = le64_to_cpu(pData->NumOfBytes); | ||
759 | __u64 end_of_file = le64_to_cpu(pData->EndOfFile); | ||
760 | cifsInfo->time = jiffies; | ||
761 | atomic_inc(&cifsInfo->inUse); | ||
762 | |||
763 | /* save mtime and size */ | ||
764 | local_mtime = tmp_inode->i_mtime; | ||
765 | local_size = tmp_inode->i_size; | ||
766 | |||
767 | tmp_inode->i_atime = | ||
768 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastAccessTime)); | ||
769 | tmp_inode->i_mtime = | ||
770 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastModificationTime)); | ||
771 | tmp_inode->i_ctime = | ||
772 | cifs_NTtimeToUnix(le64_to_cpu(pData->LastStatusChange)); | ||
773 | |||
774 | tmp_inode->i_mode = le64_to_cpu(pData->Permissions); | ||
775 | /* since we set the inode type below we need to mask off type | ||
776 | to avoid strange results if bits above were corrupt */ | ||
777 | tmp_inode->i_mode &= ~S_IFMT; | ||
778 | if (type == UNIX_FILE) { | ||
779 | *pobject_type = DT_REG; | ||
780 | tmp_inode->i_mode |= S_IFREG; | ||
781 | } else if (type == UNIX_SYMLINK) { | ||
782 | *pobject_type = DT_LNK; | ||
783 | tmp_inode->i_mode |= S_IFLNK; | ||
784 | } else if (type == UNIX_DIR) { | ||
785 | *pobject_type = DT_DIR; | ||
786 | tmp_inode->i_mode |= S_IFDIR; | ||
787 | } else if (type == UNIX_CHARDEV) { | ||
788 | *pobject_type = DT_CHR; | ||
789 | tmp_inode->i_mode |= S_IFCHR; | ||
790 | tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), | ||
791 | le64_to_cpu(pData->DevMinor) & MINORMASK); | ||
792 | } else if (type == UNIX_BLOCKDEV) { | ||
793 | *pobject_type = DT_BLK; | ||
794 | tmp_inode->i_mode |= S_IFBLK; | ||
795 | tmp_inode->i_rdev = MKDEV(le64_to_cpu(pData->DevMajor), | ||
796 | le64_to_cpu(pData->DevMinor) & MINORMASK); | ||
797 | } else if (type == UNIX_FIFO) { | ||
798 | *pobject_type = DT_FIFO; | ||
799 | tmp_inode->i_mode |= S_IFIFO; | ||
800 | } else if (type == UNIX_SOCKET) { | ||
801 | *pobject_type = DT_SOCK; | ||
802 | tmp_inode->i_mode |= S_IFSOCK; | ||
803 | } else { | ||
804 | /* safest to just call it a file */ | ||
805 | *pobject_type = DT_REG; | ||
806 | tmp_inode->i_mode |= S_IFREG; | ||
807 | cFYI(1,("unknown inode type %d",type)); | ||
808 | } | ||
809 | |||
810 | #ifdef CONFIG_CIFS_DEBUG2 | ||
811 | cFYI(1,("object type: %d", type)); | ||
812 | #endif | ||
813 | tmp_inode->i_uid = le64_to_cpu(pData->Uid); | ||
814 | tmp_inode->i_gid = le64_to_cpu(pData->Gid); | ||
815 | tmp_inode->i_nlink = le64_to_cpu(pData->Nlinks); | ||
816 | |||
817 | spin_lock(&tmp_inode->i_lock); | ||
818 | if (is_size_safe_to_change(cifsInfo, end_of_file)) { | ||
819 | /* can not safely change the file size here if the | ||
820 | client is writing to it due to potential races */ | ||
821 | i_size_write(tmp_inode, end_of_file); | ||
822 | |||
823 | /* 512 bytes (2**9) is the fake blocksize that must be used */ | ||
824 | /* for this calculation, not the real blocksize */ | ||
825 | tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; | ||
826 | } | ||
827 | spin_unlock(&tmp_inode->i_lock); | ||
828 | |||
829 | if (S_ISREG(tmp_inode->i_mode)) { | ||
830 | cFYI(1, ("File inode")); | ||
831 | tmp_inode->i_op = &cifs_file_inode_ops; | ||
832 | |||
833 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | ||
834 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
835 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | ||
836 | else | ||
837 | tmp_inode->i_fop = &cifs_file_direct_ops; | ||
838 | |||
839 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
840 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | ||
841 | else | ||
842 | tmp_inode->i_fop = &cifs_file_ops; | ||
843 | |||
844 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | ||
845 | (cifs_sb->tcon->ses->server->maxBuf < | ||
846 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) | ||
847 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | ||
848 | else | ||
849 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | ||
850 | |||
851 | if(isNewInode) | ||
852 | return; /* No sense invalidating pages for new inode since we | ||
853 | have not started caching readahead file data yet */ | ||
854 | |||
855 | if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && | ||
856 | (local_size == tmp_inode->i_size)) { | ||
857 | cFYI(1, ("inode exists but unchanged")); | ||
858 | } else { | ||
859 | /* file may have changed on server */ | ||
860 | cFYI(1, ("invalidate inode, readdir detected change")); | ||
861 | invalidate_remote_inode(tmp_inode); | ||
862 | } | ||
863 | } else if (S_ISDIR(tmp_inode->i_mode)) { | ||
864 | cFYI(1, ("Directory inode")); | ||
865 | tmp_inode->i_op = &cifs_dir_inode_ops; | ||
866 | tmp_inode->i_fop = &cifs_dir_ops; | ||
867 | } else if (S_ISLNK(tmp_inode->i_mode)) { | ||
868 | cFYI(1, ("Symbolic Link inode")); | ||
869 | tmp_inode->i_op = &cifs_symlink_inode_ops; | ||
870 | /* tmp_inode->i_fop = *//* do not need to set to anything */ | ||
871 | } else { | ||
872 | cFYI(1, ("Special inode")); | ||
873 | init_special_inode(tmp_inode, tmp_inode->i_mode, | ||
874 | tmp_inode->i_rdev); | ||
875 | } | ||
876 | } | ||
877 | |||
737 | int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | 878 | int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) |
738 | { | 879 | { |
739 | int rc = 0; | 880 | int rc = 0; |
@@ -755,6 +896,71 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
755 | FreeXid(xid); | 896 | FreeXid(xid); |
756 | return -ENOMEM; | 897 | return -ENOMEM; |
757 | } | 898 | } |
899 | |||
900 | if((pTcon->ses->capabilities & CAP_UNIX) && | ||
901 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | ||
902 | le64_to_cpu(pTcon->fsUnixInfo.Capability))) { | ||
903 | u32 oplock = 0; | ||
904 | FILE_UNIX_BASIC_INFO * pInfo = | ||
905 | kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | ||
906 | if(pInfo == NULL) { | ||
907 | rc = -ENOMEM; | ||
908 | goto mkdir_out; | ||
909 | } | ||
910 | |||
911 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, | ||
912 | mode, NULL /* netfid */, pInfo, &oplock, | ||
913 | full_path, cifs_sb->local_nls, | ||
914 | cifs_sb->mnt_cifs_flags & | ||
915 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
916 | if (rc) { | ||
917 | cFYI(1, ("posix mkdir returned 0x%x", rc)); | ||
918 | d_drop(direntry); | ||
919 | } else { | ||
920 | int obj_type; | ||
921 | if (pInfo->Type == -1) /* no return info - go query */ | ||
922 | goto mkdir_get_info; | ||
923 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */ | ||
924 | inc_nlink(inode); | ||
925 | if (pTcon->nocase) | ||
926 | direntry->d_op = &cifs_ci_dentry_ops; | ||
927 | else | ||
928 | direntry->d_op = &cifs_dentry_ops; | ||
929 | |||
930 | newinode = new_inode(inode->i_sb); | ||
931 | if (newinode == NULL) | ||
932 | goto mkdir_get_info; | ||
933 | /* Is an i_ino of zero legal? */ | ||
934 | /* Are there sanity checks we can use to ensure that | ||
935 | the server is really filling in that field? */ | ||
936 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | ||
937 | newinode->i_ino = | ||
938 | (unsigned long)pInfo->UniqueId; | ||
939 | } /* note ino incremented to unique num in new_inode */ | ||
940 | if(inode->i_sb->s_flags & MS_NOATIME) | ||
941 | newinode->i_flags |= S_NOATIME | S_NOCMTIME; | ||
942 | newinode->i_nlink = 2; | ||
943 | |||
944 | insert_inode_hash(newinode); | ||
945 | d_instantiate(direntry, newinode); | ||
946 | |||
947 | /* we already checked in POSIXCreate whether | ||
948 | frame was long enough */ | ||
949 | posix_fill_in_inode(direntry->d_inode, | ||
950 | pInfo, &obj_type, 1 /* NewInode */); | ||
951 | #ifdef CONFIG_CIFS_DEBUG2 | ||
952 | cFYI(1,("instantiated dentry %p %s to inode %p", | ||
953 | direntry, direntry->d_name.name, newinode)); | ||
954 | |||
955 | if(newinode->i_nlink != 2) | ||
956 | cFYI(1,("unexpected number of links %d", | ||
957 | newinode->i_nlink)); | ||
958 | #endif | ||
959 | } | ||
960 | kfree(pInfo); | ||
961 | goto mkdir_out; | ||
962 | } | ||
963 | |||
758 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 964 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
759 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, | 965 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, |
760 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 966 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -762,6 +968,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
762 | cFYI(1, ("cifs_mkdir returned 0x%x", rc)); | 968 | cFYI(1, ("cifs_mkdir returned 0x%x", rc)); |
763 | d_drop(direntry); | 969 | d_drop(direntry); |
764 | } else { | 970 | } else { |
971 | mkdir_get_info: | ||
765 | inc_nlink(inode); | 972 | inc_nlink(inode); |
766 | if (pTcon->ses->capabilities & CAP_UNIX) | 973 | if (pTcon->ses->capabilities & CAP_UNIX) |
767 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 974 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
@@ -775,8 +982,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
775 | else | 982 | else |
776 | direntry->d_op = &cifs_dentry_ops; | 983 | direntry->d_op = &cifs_dentry_ops; |
777 | d_instantiate(direntry, newinode); | 984 | d_instantiate(direntry, newinode); |
778 | if (direntry->d_inode) | 985 | /* setting nlink not necessary except in cases where we |
779 | direntry->d_inode->i_nlink = 2; | 986 | * failed to get it from the server or was set bogus */ |
987 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) | ||
988 | direntry->d_inode->i_nlink = 2; | ||
780 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) | 989 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) |
781 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 990 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
782 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 991 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
@@ -812,6 +1021,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
812 | } | 1021 | } |
813 | } | 1022 | } |
814 | } | 1023 | } |
1024 | mkdir_out: | ||
815 | kfree(full_path); | 1025 | kfree(full_path); |
816 | FreeXid(xid); | 1026 | FreeXid(xid); |
817 | return rc; | 1027 | return rc; |
@@ -1339,17 +1549,17 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1339 | cpu_to_le32(cifsInode->cifsAttrs | | 1549 | cpu_to_le32(cifsInode->cifsAttrs | |
1340 | ATTR_READONLY); | 1550 | ATTR_READONLY); |
1341 | } | 1551 | } |
1342 | } else if ((mode & S_IWUGO) == S_IWUGO) { | 1552 | } else if (cifsInode->cifsAttrs & ATTR_READONLY) { |
1343 | if (cifsInode->cifsAttrs & ATTR_READONLY) { | 1553 | /* If file is readonly on server, we would |
1344 | set_dosattr = TRUE; | 1554 | not be able to write to it - so if any write |
1345 | time_buf.Attributes = | 1555 | bit is enabled for user or group or other we |
1346 | cpu_to_le32(cifsInode->cifsAttrs & | 1556 | need to at least try to remove r/o dos attr */ |
1347 | (~ATTR_READONLY)); | 1557 | set_dosattr = TRUE; |
1348 | /* Windows ignores set to zero */ | 1558 | time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs & |
1349 | if(time_buf.Attributes == 0) | 1559 | (~ATTR_READONLY)); |
1350 | time_buf.Attributes |= | 1560 | /* Windows ignores set to zero */ |
1351 | cpu_to_le32(ATTR_NORMAL); | 1561 | if(time_buf.Attributes == 0) |
1352 | } | 1562 | time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); |
1353 | } | 1563 | } |
1354 | /* BB to be implemented - | 1564 | /* BB to be implemented - |
1355 | via Windows security descriptors or streams */ | 1565 | via Windows security descriptors or streams */ |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 992e80edc720..53e304d59544 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -30,6 +30,9 @@ | |||
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <asm/div64.h> | 31 | #include <asm/div64.h> |
32 | #include <asm/byteorder.h> | 32 | #include <asm/byteorder.h> |
33 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
34 | #include <linux/inet.h> | ||
35 | #endif | ||
33 | #include "cifsfs.h" | 36 | #include "cifsfs.h" |
34 | #include "cifspdu.h" | 37 | #include "cifspdu.h" |
35 | #include "cifsglob.h" | 38 | #include "cifsglob.h" |
@@ -129,11 +132,27 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |||
129 | /* Convert string containing dotted ip address to binary form */ | 132 | /* Convert string containing dotted ip address to binary form */ |
130 | /* returns 0 if invalid address */ | 133 | /* returns 0 if invalid address */ |
131 | 134 | ||
132 | /* BB add address family, change rc to status flag and return union or for ipv6 */ | ||
133 | /* will need parent to call something like inet_pton to convert ipv6 address BB */ | ||
134 | int | 135 | int |
135 | cifs_inet_pton(int address_family, char *cp,void *dst) | 136 | cifs_inet_pton(int address_family, char *cp,void *dst) |
136 | { | 137 | { |
138 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
139 | int ret = 0; | ||
140 | |||
141 | /* calculate length by finding first slash or NULL */ | ||
142 | /* BB Should we convert '/' slash to '\' here since it seems already done | ||
143 | before this */ | ||
144 | if( address_family == AF_INET ){ | ||
145 | ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); | ||
146 | } else if( address_family == AF_INET6 ){ | ||
147 | ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); | ||
148 | } | ||
149 | #ifdef CONFIG_CIFS_DEBUG2 | ||
150 | cFYI(1,("address conversion returned %d for %s", ret, cp)); | ||
151 | #endif | ||
152 | if (ret > 0) | ||
153 | ret = 1; | ||
154 | return ret; | ||
155 | #else | ||
137 | int value; | 156 | int value; |
138 | int digit; | 157 | int digit; |
139 | int i; | 158 | int i; |
@@ -192,6 +211,7 @@ cifs_inet_pton(int address_family, char *cp,void *dst) | |||
192 | 211 | ||
193 | *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value); | 212 | *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value); |
194 | return 1; /* success */ | 213 | return 1; /* success */ |
214 | #endif /* EXPERIMENTAL */ | ||
195 | } | 215 | } |
196 | 216 | ||
197 | /***************************************************************************** | 217 | /***************************************************************************** |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 2a374d5215ab..b5364f90d551 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -37,19 +37,19 @@ static void dump_cifs_file_struct(struct file *file, char *label) | |||
37 | { | 37 | { |
38 | struct cifsFileInfo * cf; | 38 | struct cifsFileInfo * cf; |
39 | 39 | ||
40 | if(file) { | 40 | if (file) { |
41 | cf = file->private_data; | 41 | cf = file->private_data; |
42 | if(cf == NULL) { | 42 | if (cf == NULL) { |
43 | cFYI(1,("empty cifs private file data")); | 43 | cFYI(1,("empty cifs private file data")); |
44 | return; | 44 | return; |
45 | } | 45 | } |
46 | if(cf->invalidHandle) { | 46 | if (cf->invalidHandle) { |
47 | cFYI(1,("invalid handle")); | 47 | cFYI(1,("invalid handle")); |
48 | } | 48 | } |
49 | if(cf->srch_inf.endOfSearch) { | 49 | if (cf->srch_inf.endOfSearch) { |
50 | cFYI(1,("end of search")); | 50 | cFYI(1,("end of search")); |
51 | } | 51 | } |
52 | if(cf->srch_inf.emptyDir) { | 52 | if (cf->srch_inf.emptyDir) { |
53 | cFYI(1,("empty dir")); | 53 | cFYI(1,("empty dir")); |
54 | } | 54 | } |
55 | 55 | ||
@@ -77,17 +77,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
77 | cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); | 77 | cFYI(0, ("existing dentry with inode 0x%p", tmp_dentry->d_inode)); |
78 | *ptmp_inode = tmp_dentry->d_inode; | 78 | *ptmp_inode = tmp_dentry->d_inode; |
79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ | 79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ |
80 | if(*ptmp_inode == NULL) { | 80 | if (*ptmp_inode == NULL) { |
81 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); | 81 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); |
82 | if(*ptmp_inode == NULL) | 82 | if (*ptmp_inode == NULL) |
83 | return rc; | 83 | return rc; |
84 | rc = 1; | 84 | rc = 1; |
85 | } | 85 | } |
86 | if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | 86 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) |
87 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | 87 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; |
88 | } else { | 88 | } else { |
89 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); | 89 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); |
90 | if(tmp_dentry == NULL) { | 90 | if (tmp_dentry == NULL) { |
91 | cERROR(1,("Failed allocating dentry")); | 91 | cERROR(1,("Failed allocating dentry")); |
92 | *ptmp_inode = NULL; | 92 | *ptmp_inode = NULL; |
93 | return rc; | 93 | return rc; |
@@ -98,9 +98,9 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
98 | tmp_dentry->d_op = &cifs_ci_dentry_ops; | 98 | tmp_dentry->d_op = &cifs_ci_dentry_ops; |
99 | else | 99 | else |
100 | tmp_dentry->d_op = &cifs_dentry_ops; | 100 | tmp_dentry->d_op = &cifs_dentry_ops; |
101 | if(*ptmp_inode == NULL) | 101 | if (*ptmp_inode == NULL) |
102 | return rc; | 102 | return rc; |
103 | if(file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | 103 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) |
104 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | 104 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; |
105 | rc = 2; | 105 | rc = 2; |
106 | } | 106 | } |
@@ -112,7 +112,7 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
112 | 112 | ||
113 | static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) | 113 | static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) |
114 | { | 114 | { |
115 | if((tcon) && (tcon->ses) && (tcon->ses->server)) { | 115 | if ((tcon) && (tcon->ses) && (tcon->ses->server)) { |
116 | inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; | 116 | inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; |
117 | inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; | 117 | inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; |
118 | inode->i_atime.tv_sec += tcon->ses->server->timeAdj; | 118 | inode->i_atime.tv_sec += tcon->ses->server->timeAdj; |
@@ -137,7 +137,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
137 | local_mtime = tmp_inode->i_mtime; | 137 | local_mtime = tmp_inode->i_mtime; |
138 | local_size = tmp_inode->i_size; | 138 | local_size = tmp_inode->i_size; |
139 | 139 | ||
140 | if(new_buf_type) { | 140 | if (new_buf_type) { |
141 | FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; | 141 | FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; |
142 | 142 | ||
143 | attr = le32_to_cpu(pfindData->ExtFileAttributes); | 143 | attr = le32_to_cpu(pfindData->ExtFileAttributes); |
@@ -193,7 +193,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
193 | if (attr & ATTR_DIRECTORY) { | 193 | if (attr & ATTR_DIRECTORY) { |
194 | *pobject_type = DT_DIR; | 194 | *pobject_type = DT_DIR; |
195 | /* override default perms since we do not lock dirs */ | 195 | /* override default perms since we do not lock dirs */ |
196 | if(atomic_read(&cifsInfo->inUse) == 0) { | 196 | if (atomic_read(&cifsInfo->inUse) == 0) { |
197 | tmp_inode->i_mode = cifs_sb->mnt_dir_mode; | 197 | tmp_inode->i_mode = cifs_sb->mnt_dir_mode; |
198 | } | 198 | } |
199 | tmp_inode->i_mode |= S_IFDIR; | 199 | tmp_inode->i_mode |= S_IFDIR; |
@@ -250,25 +250,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
250 | if (S_ISREG(tmp_inode->i_mode)) { | 250 | if (S_ISREG(tmp_inode->i_mode)) { |
251 | cFYI(1, ("File inode")); | 251 | cFYI(1, ("File inode")); |
252 | tmp_inode->i_op = &cifs_file_inode_ops; | 252 | tmp_inode->i_op = &cifs_file_inode_ops; |
253 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | 253 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
254 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 254 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
255 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | 255 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; |
256 | else | 256 | else |
257 | tmp_inode->i_fop = &cifs_file_direct_ops; | 257 | tmp_inode->i_fop = &cifs_file_direct_ops; |
258 | 258 | ||
259 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 259 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
260 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | 260 | tmp_inode->i_fop = &cifs_file_nobrl_ops; |
261 | else | 261 | else |
262 | tmp_inode->i_fop = &cifs_file_ops; | 262 | tmp_inode->i_fop = &cifs_file_ops; |
263 | 263 | ||
264 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | 264 | if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && |
265 | (cifs_sb->tcon->ses->server->maxBuf < | 265 | (cifs_sb->tcon->ses->server->maxBuf < |
266 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) | 266 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) |
267 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | 267 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; |
268 | else | 268 | else |
269 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 269 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
270 | 270 | ||
271 | if(isNewInode) | 271 | if (isNewInode) |
272 | return; /* No sense invalidating pages for new inode | 272 | return; /* No sense invalidating pages for new inode |
273 | since have not started caching readahead file | 273 | since have not started caching readahead file |
274 | data yet */ | 274 | data yet */ |
@@ -357,8 +357,14 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
357 | cFYI(1,("unknown inode type %d",type)); | 357 | cFYI(1,("unknown inode type %d",type)); |
358 | } | 358 | } |
359 | 359 | ||
360 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); | 360 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
361 | tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); | 361 | tmp_inode->i_uid = cifs_sb->mnt_uid; |
362 | else | ||
363 | tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); | ||
364 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | ||
365 | tmp_inode->i_gid = cifs_sb->mnt_gid; | ||
366 | else | ||
367 | tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); | ||
362 | tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); | 368 | tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); |
363 | 369 | ||
364 | spin_lock(&tmp_inode->i_lock); | 370 | spin_lock(&tmp_inode->i_lock); |
@@ -377,25 +383,24 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
377 | cFYI(1, ("File inode")); | 383 | cFYI(1, ("File inode")); |
378 | tmp_inode->i_op = &cifs_file_inode_ops; | 384 | tmp_inode->i_op = &cifs_file_inode_ops; |
379 | 385 | ||
380 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | 386 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
381 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 387 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
382 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; | 388 | tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; |
383 | else | 389 | else |
384 | tmp_inode->i_fop = &cifs_file_direct_ops; | 390 | tmp_inode->i_fop = &cifs_file_direct_ops; |
385 | 391 | } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | |
386 | } else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | ||
387 | tmp_inode->i_fop = &cifs_file_nobrl_ops; | 392 | tmp_inode->i_fop = &cifs_file_nobrl_ops; |
388 | else | 393 | else |
389 | tmp_inode->i_fop = &cifs_file_ops; | 394 | tmp_inode->i_fop = &cifs_file_ops; |
390 | 395 | ||
391 | if((cifs_sb->tcon) && (cifs_sb->tcon->ses) && | 396 | if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && |
392 | (cifs_sb->tcon->ses->server->maxBuf < | 397 | (cifs_sb->tcon->ses->server->maxBuf < |
393 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) | 398 | PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) |
394 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; | 399 | tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; |
395 | else | 400 | else |
396 | tmp_inode->i_data.a_ops = &cifs_addr_ops; | 401 | tmp_inode->i_data.a_ops = &cifs_addr_ops; |
397 | 402 | ||
398 | if(isNewInode) | 403 | if (isNewInode) |
399 | return; /* No sense invalidating pages for new inode since we | 404 | return; /* No sense invalidating pages for new inode since we |
400 | have not started caching readahead file data yet */ | 405 | have not started caching readahead file data yet */ |
401 | 406 | ||
@@ -430,34 +435,28 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
430 | struct cifs_sb_info *cifs_sb; | 435 | struct cifs_sb_info *cifs_sb; |
431 | struct cifsTconInfo *pTcon; | 436 | struct cifsTconInfo *pTcon; |
432 | 437 | ||
433 | if(file->private_data == NULL) { | 438 | if (file->private_data == NULL) { |
434 | file->private_data = | 439 | file->private_data = |
435 | kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); | 440 | kzalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); |
436 | } | 441 | } |
437 | 442 | ||
438 | if(file->private_data == NULL) { | 443 | if (file->private_data == NULL) |
439 | return -ENOMEM; | 444 | return -ENOMEM; |
440 | } else { | ||
441 | memset(file->private_data,0,sizeof(struct cifsFileInfo)); | ||
442 | } | ||
443 | cifsFile = file->private_data; | 445 | cifsFile = file->private_data; |
444 | cifsFile->invalidHandle = TRUE; | 446 | cifsFile->invalidHandle = TRUE; |
445 | cifsFile->srch_inf.endOfSearch = FALSE; | 447 | cifsFile->srch_inf.endOfSearch = FALSE; |
446 | 448 | ||
447 | if(file->f_path.dentry == NULL) | ||
448 | return -ENOENT; | ||
449 | |||
450 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 449 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
451 | if(cifs_sb == NULL) | 450 | if (cifs_sb == NULL) |
452 | return -EINVAL; | 451 | return -EINVAL; |
453 | 452 | ||
454 | pTcon = cifs_sb->tcon; | 453 | pTcon = cifs_sb->tcon; |
455 | if(pTcon == NULL) | 454 | if (pTcon == NULL) |
456 | return -EINVAL; | 455 | return -EINVAL; |
457 | 456 | ||
458 | full_path = build_path_from_dentry(file->f_path.dentry); | 457 | full_path = build_path_from_dentry(file->f_path.dentry); |
459 | 458 | ||
460 | if(full_path == NULL) { | 459 | if (full_path == NULL) { |
461 | return -ENOMEM; | 460 | return -ENOMEM; |
462 | } | 461 | } |
463 | 462 | ||
@@ -480,9 +479,9 @@ ffirst_retry: | |||
480 | &cifsFile->netfid, &cifsFile->srch_inf, | 479 | &cifsFile->netfid, &cifsFile->srch_inf, |
481 | cifs_sb->mnt_cifs_flags & | 480 | cifs_sb->mnt_cifs_flags & |
482 | CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); | 481 | CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); |
483 | if(rc == 0) | 482 | if (rc == 0) |
484 | cifsFile->invalidHandle = FALSE; | 483 | cifsFile->invalidHandle = FALSE; |
485 | if((rc == -EOPNOTSUPP) && | 484 | if ((rc == -EOPNOTSUPP) && |
486 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { | 485 | (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { |
487 | cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; | 486 | cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; |
488 | goto ffirst_retry; | 487 | goto ffirst_retry; |
@@ -498,7 +497,7 @@ static int cifs_unicode_bytelen(char *str) | |||
498 | __le16 * ustr = (__le16 *)str; | 497 | __le16 * ustr = (__le16 *)str; |
499 | 498 | ||
500 | for(len=0;len <= PATH_MAX;len++) { | 499 | for(len=0;len <= PATH_MAX;len++) { |
501 | if(ustr[len] == 0) | 500 | if (ustr[len] == 0) |
502 | return len << 1; | 501 | return len << 1; |
503 | } | 502 | } |
504 | cFYI(1,("Unicode string longer than PATH_MAX found")); | 503 | cFYI(1,("Unicode string longer than PATH_MAX found")); |
@@ -510,7 +509,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) | |||
510 | char * new_entry; | 509 | char * new_entry; |
511 | FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; | 510 | FILE_DIRECTORY_INFO * pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; |
512 | 511 | ||
513 | if(level == SMB_FIND_FILE_INFO_STANDARD) { | 512 | if (level == SMB_FIND_FILE_INFO_STANDARD) { |
514 | FIND_FILE_STANDARD_INFO * pfData; | 513 | FIND_FILE_STANDARD_INFO * pfData; |
515 | pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; | 514 | pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; |
516 | 515 | ||
@@ -520,12 +519,12 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) | |||
520 | new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); | 519 | new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); |
521 | cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); | 520 | cFYI(1,("new entry %p old entry %p",new_entry,old_entry)); |
522 | /* validate that new_entry is not past end of SMB */ | 521 | /* validate that new_entry is not past end of SMB */ |
523 | if(new_entry >= end_of_smb) { | 522 | if (new_entry >= end_of_smb) { |
524 | cERROR(1, | 523 | cERROR(1, |
525 | ("search entry %p began after end of SMB %p old entry %p", | 524 | ("search entry %p began after end of SMB %p old entry %p", |
526 | new_entry, end_of_smb, old_entry)); | 525 | new_entry, end_of_smb, old_entry)); |
527 | return NULL; | 526 | return NULL; |
528 | } else if(((level == SMB_FIND_FILE_INFO_STANDARD) && | 527 | } else if (((level == SMB_FIND_FILE_INFO_STANDARD) && |
529 | (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || | 528 | (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || |
530 | ((level != SMB_FIND_FILE_INFO_STANDARD) && | 529 | ((level != SMB_FIND_FILE_INFO_STANDARD) && |
531 | (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { | 530 | (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { |
@@ -546,39 +545,39 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) | |||
546 | char * filename = NULL; | 545 | char * filename = NULL; |
547 | int len = 0; | 546 | int len = 0; |
548 | 547 | ||
549 | if(cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { | 548 | if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) { |
550 | FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; | 549 | FILE_UNIX_INFO * pFindData = (FILE_UNIX_INFO *)current_entry; |
551 | filename = &pFindData->FileName[0]; | 550 | filename = &pFindData->FileName[0]; |
552 | if(cfile->srch_inf.unicode) { | 551 | if (cfile->srch_inf.unicode) { |
553 | len = cifs_unicode_bytelen(filename); | 552 | len = cifs_unicode_bytelen(filename); |
554 | } else { | 553 | } else { |
555 | /* BB should we make this strnlen of PATH_MAX? */ | 554 | /* BB should we make this strnlen of PATH_MAX? */ |
556 | len = strnlen(filename, 5); | 555 | len = strnlen(filename, 5); |
557 | } | 556 | } |
558 | } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { | 557 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) { |
559 | FILE_DIRECTORY_INFO * pFindData = | 558 | FILE_DIRECTORY_INFO * pFindData = |
560 | (FILE_DIRECTORY_INFO *)current_entry; | 559 | (FILE_DIRECTORY_INFO *)current_entry; |
561 | filename = &pFindData->FileName[0]; | 560 | filename = &pFindData->FileName[0]; |
562 | len = le32_to_cpu(pFindData->FileNameLength); | 561 | len = le32_to_cpu(pFindData->FileNameLength); |
563 | } else if(cfile->srch_inf.info_level == | 562 | } else if (cfile->srch_inf.info_level == |
564 | SMB_FIND_FILE_FULL_DIRECTORY_INFO) { | 563 | SMB_FIND_FILE_FULL_DIRECTORY_INFO) { |
565 | FILE_FULL_DIRECTORY_INFO * pFindData = | 564 | FILE_FULL_DIRECTORY_INFO * pFindData = |
566 | (FILE_FULL_DIRECTORY_INFO *)current_entry; | 565 | (FILE_FULL_DIRECTORY_INFO *)current_entry; |
567 | filename = &pFindData->FileName[0]; | 566 | filename = &pFindData->FileName[0]; |
568 | len = le32_to_cpu(pFindData->FileNameLength); | 567 | len = le32_to_cpu(pFindData->FileNameLength); |
569 | } else if(cfile->srch_inf.info_level == | 568 | } else if (cfile->srch_inf.info_level == |
570 | SMB_FIND_FILE_ID_FULL_DIR_INFO) { | 569 | SMB_FIND_FILE_ID_FULL_DIR_INFO) { |
571 | SEARCH_ID_FULL_DIR_INFO * pFindData = | 570 | SEARCH_ID_FULL_DIR_INFO * pFindData = |
572 | (SEARCH_ID_FULL_DIR_INFO *)current_entry; | 571 | (SEARCH_ID_FULL_DIR_INFO *)current_entry; |
573 | filename = &pFindData->FileName[0]; | 572 | filename = &pFindData->FileName[0]; |
574 | len = le32_to_cpu(pFindData->FileNameLength); | 573 | len = le32_to_cpu(pFindData->FileNameLength); |
575 | } else if(cfile->srch_inf.info_level == | 574 | } else if (cfile->srch_inf.info_level == |
576 | SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { | 575 | SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { |
577 | FILE_BOTH_DIRECTORY_INFO * pFindData = | 576 | FILE_BOTH_DIRECTORY_INFO * pFindData = |
578 | (FILE_BOTH_DIRECTORY_INFO *)current_entry; | 577 | (FILE_BOTH_DIRECTORY_INFO *)current_entry; |
579 | filename = &pFindData->FileName[0]; | 578 | filename = &pFindData->FileName[0]; |
580 | len = le32_to_cpu(pFindData->FileNameLength); | 579 | len = le32_to_cpu(pFindData->FileNameLength); |
581 | } else if(cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { | 580 | } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) { |
582 | FIND_FILE_STANDARD_INFO * pFindData = | 581 | FIND_FILE_STANDARD_INFO * pFindData = |
583 | (FIND_FILE_STANDARD_INFO *)current_entry; | 582 | (FIND_FILE_STANDARD_INFO *)current_entry; |
584 | filename = &pFindData->FileName[0]; | 583 | filename = &pFindData->FileName[0]; |
@@ -587,25 +586,25 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) | |||
587 | cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); | 586 | cFYI(1,("Unknown findfirst level %d",cfile->srch_inf.info_level)); |
588 | } | 587 | } |
589 | 588 | ||
590 | if(filename) { | 589 | if (filename) { |
591 | if(cfile->srch_inf.unicode) { | 590 | if (cfile->srch_inf.unicode) { |
592 | __le16 *ufilename = (__le16 *)filename; | 591 | __le16 *ufilename = (__le16 *)filename; |
593 | if(len == 2) { | 592 | if (len == 2) { |
594 | /* check for . */ | 593 | /* check for . */ |
595 | if(ufilename[0] == UNICODE_DOT) | 594 | if (ufilename[0] == UNICODE_DOT) |
596 | rc = 1; | 595 | rc = 1; |
597 | } else if(len == 4) { | 596 | } else if (len == 4) { |
598 | /* check for .. */ | 597 | /* check for .. */ |
599 | if((ufilename[0] == UNICODE_DOT) | 598 | if ((ufilename[0] == UNICODE_DOT) |
600 | &&(ufilename[1] == UNICODE_DOT)) | 599 | &&(ufilename[1] == UNICODE_DOT)) |
601 | rc = 2; | 600 | rc = 2; |
602 | } | 601 | } |
603 | } else /* ASCII */ { | 602 | } else /* ASCII */ { |
604 | if(len == 1) { | 603 | if (len == 1) { |
605 | if(filename[0] == '.') | 604 | if (filename[0] == '.') |
606 | rc = 1; | 605 | rc = 1; |
607 | } else if(len == 2) { | 606 | } else if (len == 2) { |
608 | if((filename[0] == '.') && (filename[1] == '.')) | 607 | if((filename[0] == '.') && (filename[1] == '.')) |
609 | rc = 2; | 608 | rc = 2; |
610 | } | 609 | } |
611 | } | 610 | } |
@@ -618,20 +617,10 @@ static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile) | |||
618 | whether we can use the cached search results from the previous search */ | 617 | whether we can use the cached search results from the previous search */ |
619 | static int is_dir_changed(struct file * file) | 618 | static int is_dir_changed(struct file * file) |
620 | { | 619 | { |
621 | struct inode * inode; | 620 | struct inode *inode = file->f_path.dentry->d_inode; |
622 | struct cifsInodeInfo *cifsInfo; | 621 | struct cifsInodeInfo *cifsInfo = CIFS_I(inode); |
623 | 622 | ||
624 | if(file->f_path.dentry == NULL) | 623 | if (cifsInfo->time == 0) |
625 | return 0; | ||
626 | |||
627 | inode = file->f_path.dentry->d_inode; | ||
628 | |||
629 | if(inode == NULL) | ||
630 | return 0; | ||
631 | |||
632 | cifsInfo = CIFS_I(inode); | ||
633 | |||
634 | if(cifsInfo->time == 0) | ||
635 | return 1; /* directory was changed, perhaps due to unlink */ | 624 | return 1; /* directory was changed, perhaps due to unlink */ |
636 | else | 625 | else |
637 | return 0; | 626 | return 0; |
@@ -654,7 +643,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
654 | struct cifsFileInfo * cifsFile = file->private_data; | 643 | struct cifsFileInfo * cifsFile = file->private_data; |
655 | /* check if index in the buffer */ | 644 | /* check if index in the buffer */ |
656 | 645 | ||
657 | if((cifsFile == NULL) || (ppCurrentEntry == NULL) || | 646 | if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || |
658 | (num_to_ret == NULL)) | 647 | (num_to_ret == NULL)) |
659 | return -ENOENT; | 648 | return -ENOENT; |
660 | 649 | ||
@@ -672,7 +661,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
672 | #ifdef CONFIG_CIFS_DEBUG2 | 661 | #ifdef CONFIG_CIFS_DEBUG2 |
673 | dump_cifs_file_struct(file, "In fce "); | 662 | dump_cifs_file_struct(file, "In fce "); |
674 | #endif | 663 | #endif |
675 | if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && | 664 | if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && |
676 | is_dir_changed(file)) || | 665 | is_dir_changed(file)) || |
677 | (index_to_find < first_entry_in_buffer)) { | 666 | (index_to_find < first_entry_in_buffer)) { |
678 | /* close and restart search */ | 667 | /* close and restart search */ |
@@ -681,9 +670,9 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
681 | CIFSFindClose(xid, pTcon, cifsFile->netfid); | 670 | CIFSFindClose(xid, pTcon, cifsFile->netfid); |
682 | kfree(cifsFile->search_resume_name); | 671 | kfree(cifsFile->search_resume_name); |
683 | cifsFile->search_resume_name = NULL; | 672 | cifsFile->search_resume_name = NULL; |
684 | if(cifsFile->srch_inf.ntwrk_buf_start) { | 673 | if (cifsFile->srch_inf.ntwrk_buf_start) { |
685 | cFYI(1,("freeing SMB ff cache buf on search rewind")); | 674 | cFYI(1,("freeing SMB ff cache buf on search rewind")); |
686 | if(cifsFile->srch_inf.smallBuf) | 675 | if (cifsFile->srch_inf.smallBuf) |
687 | cifs_small_buf_release(cifsFile->srch_inf. | 676 | cifs_small_buf_release(cifsFile->srch_inf. |
688 | ntwrk_buf_start); | 677 | ntwrk_buf_start); |
689 | else | 678 | else |
@@ -691,7 +680,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
691 | ntwrk_buf_start); | 680 | ntwrk_buf_start); |
692 | } | 681 | } |
693 | rc = initiate_cifs_search(xid,file); | 682 | rc = initiate_cifs_search(xid,file); |
694 | if(rc) { | 683 | if (rc) { |
695 | cFYI(1,("error %d reinitiating a search on rewind",rc)); | 684 | cFYI(1,("error %d reinitiating a search on rewind",rc)); |
696 | return rc; | 685 | return rc; |
697 | } | 686 | } |
@@ -702,10 +691,10 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
702 | cFYI(1,("calling findnext2")); | 691 | cFYI(1,("calling findnext2")); |
703 | rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, | 692 | rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, |
704 | &cifsFile->srch_inf); | 693 | &cifsFile->srch_inf); |
705 | if(rc) | 694 | if (rc) |
706 | return -ENOENT; | 695 | return -ENOENT; |
707 | } | 696 | } |
708 | if(index_to_find < cifsFile->srch_inf.index_of_last_entry) { | 697 | if (index_to_find < cifsFile->srch_inf.index_of_last_entry) { |
709 | /* we found the buffer that contains the entry */ | 698 | /* we found the buffer that contains the entry */ |
710 | /* scan and find it */ | 699 | /* scan and find it */ |
711 | int i; | 700 | int i; |
@@ -851,9 +840,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
851 | if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) | 840 | if((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL)) |
852 | return -ENOENT; | 841 | return -ENOENT; |
853 | 842 | ||
854 | if(file->f_path.dentry == NULL) | ||
855 | return -ENOENT; | ||
856 | |||
857 | rc = cifs_entry_is_dot(pfindEntry,pCifsF); | 843 | rc = cifs_entry_is_dot(pfindEntry,pCifsF); |
858 | /* skip . and .. since we added them first */ | 844 | /* skip . and .. since we added them first */ |
859 | if(rc != 0) | 845 | if(rc != 0) |
@@ -997,11 +983,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
997 | 983 | ||
998 | xid = GetXid(); | 984 | xid = GetXid(); |
999 | 985 | ||
1000 | if(file->f_path.dentry == NULL) { | ||
1001 | FreeXid(xid); | ||
1002 | return -EIO; | ||
1003 | } | ||
1004 | |||
1005 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 986 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
1006 | pTcon = cifs_sb->tcon; | 987 | pTcon = cifs_sb->tcon; |
1007 | if(pTcon == NULL) | 988 | if(pTcon == NULL) |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 614175a3b02e..0aaff3651d14 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -62,8 +62,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
62 | { | 62 | { |
63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; | 63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; |
64 | 64 | ||
65 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 65 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
66 | SLAB_CTOR_CONSTRUCTOR) | ||
67 | inode_init_once(&ei->vfs_inode); | 66 | inode_init_once(&ei->vfs_inode); |
68 | } | 67 | } |
69 | 68 | ||
diff --git a/fs/compat.c b/fs/compat.c index 040a8be38a48..72e5e6923828 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -371,13 +371,14 @@ static void compat_ioctl_error(struct file *filp, unsigned int fd, | |||
371 | fn = "?"; | 371 | fn = "?"; |
372 | } | 372 | } |
373 | 373 | ||
374 | sprintf(buf,"'%c'", (cmd>>24) & 0x3f); | 374 | sprintf(buf,"'%c'", (cmd>>_IOC_TYPESHIFT) & _IOC_TYPEMASK); |
375 | if (!isprint(buf[1])) | 375 | if (!isprint(buf[1])) |
376 | sprintf(buf, "%02x", buf[1]); | 376 | sprintf(buf, "%02x", buf[1]); |
377 | compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " | 377 | compat_printk("ioctl32(%s:%d): Unknown cmd fd(%d) " |
378 | "cmd(%08x){%s} arg(%08x) on %s\n", | 378 | "cmd(%08x){t:%s;sz:%u} arg(%08x) on %s\n", |
379 | current->comm, current->pid, | 379 | current->comm, current->pid, |
380 | (int)fd, (unsigned int)cmd, buf, | 380 | (int)fd, (unsigned int)cmd, buf, |
381 | (cmd >> _IOC_SIZESHIFT) & _IOC_SIZEMASK, | ||
381 | (unsigned int)arg, fn); | 382 | (unsigned int)arg, fn); |
382 | 383 | ||
383 | if (path) | 384 | if (path) |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index c68b055fa26e..464c04a9541d 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -2396,6 +2396,14 @@ lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
2396 | #define ULONG_IOCTL(cmd) \ | 2396 | #define ULONG_IOCTL(cmd) \ |
2397 | { (cmd), (ioctl_trans_handler_t)sys_ioctl }, | 2397 | { (cmd), (ioctl_trans_handler_t)sys_ioctl }, |
2398 | 2398 | ||
2399 | /* ioctl should not be warned about even if it's not implemented. | ||
2400 | Valid reasons to use this: | ||
2401 | - It is implemented with ->compat_ioctl on some device, but programs | ||
2402 | call it on others too. | ||
2403 | - The ioctl is not implemented in the native kernel, but programs | ||
2404 | call it commonly anyways. | ||
2405 | Most other reasons are not valid. */ | ||
2406 | #define IGNORE_IOCTL(cmd) COMPATIBLE_IOCTL(cmd) | ||
2399 | 2407 | ||
2400 | struct ioctl_trans ioctl_start[] = { | 2408 | struct ioctl_trans ioctl_start[] = { |
2401 | #include <linux/compat_ioctl.h> | 2409 | #include <linux/compat_ioctl.h> |
@@ -2594,6 +2602,8 @@ HANDLE_IOCTL(SIOCGIWENCODEEXT, do_wireless_ioctl) | |||
2594 | HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl) | 2602 | HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl) |
2595 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) | 2603 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) |
2596 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) | 2604 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) |
2605 | /* Not implemented in the native kernel */ | ||
2606 | IGNORE_IOCTL(SIOCGIFCOUNT) | ||
2597 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) | 2607 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) |
2598 | HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) | 2608 | HANDLE_IOCTL(RTC_IRQP_SET32, rtc_ioctl) |
2599 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) | 2609 | HANDLE_IOCTL(RTC_EPOCH_READ32, rtc_ioctl) |
@@ -2617,6 +2627,15 @@ COMPATIBLE_IOCTL(LPRESET) | |||
2617 | /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ | 2627 | /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ |
2618 | COMPATIBLE_IOCTL(LPGETFLAGS) | 2628 | COMPATIBLE_IOCTL(LPGETFLAGS) |
2619 | HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) | 2629 | HANDLE_IOCTL(LPSETTIMEOUT, lp_timeout_trans) |
2630 | |||
2631 | /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, | ||
2632 | but we don't want warnings on other file systems. So declare | ||
2633 | them as compatible here. */ | ||
2634 | #define VFAT_IOCTL_READDIR_BOTH32 _IOR('r', 1, struct compat_dirent[2]) | ||
2635 | #define VFAT_IOCTL_READDIR_SHORT32 _IOR('r', 2, struct compat_dirent[2]) | ||
2636 | |||
2637 | IGNORE_IOCTL(VFAT_IOCTL_READDIR_BOTH32) | ||
2638 | IGNORE_IOCTL(VFAT_IOCTL_READDIR_SHORT32) | ||
2620 | }; | 2639 | }; |
2621 | 2640 | ||
2622 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); | 2641 | int ioctl_table_size = ARRAY_SIZE(ioctl_start); |
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 6f573004cd7d..b00d962de833 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -140,7 +140,7 @@ static int __init configfs_init(void) | |||
140 | if (!configfs_dir_cachep) | 140 | if (!configfs_dir_cachep) |
141 | goto out; | 141 | goto out; |
142 | 142 | ||
143 | kset_set_kset_s(&config_subsys, kernel_subsys); | 143 | kobj_set_kset_s(&config_subsys, kernel_subsys); |
144 | err = subsystem_register(&config_subsys); | 144 | err = subsystem_register(&config_subsys); |
145 | if (err) { | 145 | if (err) { |
146 | kmem_cache_destroy(configfs_dir_cachep); | 146 | kmem_cache_destroy(configfs_dir_cachep); |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index facd0c89be8f..3d194a2be3f5 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -180,7 +180,8 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i | |||
180 | struct page *page = NULL; | 180 | struct page *page = NULL; |
181 | 181 | ||
182 | if (blocknr + i < devsize) { | 182 | if (blocknr + i < devsize) { |
183 | page = read_mapping_page(mapping, blocknr + i, NULL); | 183 | page = read_mapping_page_async(mapping, blocknr + i, |
184 | NULL); | ||
184 | /* synchronous error? */ | 185 | /* synchronous error? */ |
185 | if (IS_ERR(page)) | 186 | if (IS_ERR(page)) |
186 | page = NULL; | 187 | page = NULL; |
diff --git a/fs/dcache.c b/fs/dcache.c index d68631f18df1..d1bf5d8aeb5a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2052,12 +2052,8 @@ static void __init dcache_init(unsigned long mempages) | |||
2052 | * but it is probably not worth it because of the cache nature | 2052 | * but it is probably not worth it because of the cache nature |
2053 | * of the dcache. | 2053 | * of the dcache. |
2054 | */ | 2054 | */ |
2055 | dentry_cache = kmem_cache_create("dentry_cache", | 2055 | dentry_cache = KMEM_CACHE(dentry, |
2056 | sizeof(struct dentry), | 2056 | SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD); |
2057 | 0, | ||
2058 | (SLAB_RECLAIM_ACCOUNT|SLAB_PANIC| | ||
2059 | SLAB_MEM_SPREAD), | ||
2060 | NULL, NULL); | ||
2061 | 2057 | ||
2062 | set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory); | 2058 | set_shrinker(DEFAULT_SEEKS, shrink_dcache_memory); |
2063 | 2059 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 7b324cfebcb1..ec8896b264de 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -374,7 +374,7 @@ static int __init debugfs_init(void) | |||
374 | { | 374 | { |
375 | int retval; | 375 | int retval; |
376 | 376 | ||
377 | kset_set_kset_s(&debug_subsys, kernel_subsys); | 377 | kobj_set_kset_s(&debug_subsys, kernel_subsys); |
378 | retval = subsystem_register(&debug_subsys); | 378 | retval = subsystem_register(&debug_subsys); |
379 | if (retval) | 379 | if (retval) |
380 | return retval; | 380 | return retval; |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index f607ca2f0792..a677b2a5eed4 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -167,7 +167,6 @@ static struct kobj_type dlm_ktype = { | |||
167 | }; | 167 | }; |
168 | 168 | ||
169 | static struct kset dlm_kset = { | 169 | static struct kset dlm_kset = { |
170 | .subsys = &kernel_subsys, | ||
171 | .kobj = {.name = "dlm",}, | 170 | .kobj = {.name = "dlm",}, |
172 | .ktype = &dlm_ktype, | 171 | .ktype = &dlm_ktype, |
173 | }; | 172 | }; |
@@ -218,6 +217,7 @@ int dlm_lockspace_init(void) | |||
218 | INIT_LIST_HEAD(&lslist); | 217 | INIT_LIST_HEAD(&lslist); |
219 | spin_lock_init(&lslist_lock); | 218 | spin_lock_init(&lslist_lock); |
220 | 219 | ||
220 | kobj_set_kset_s(&dlm_kset, kernel_subsys); | ||
221 | error = kset_register(&dlm_kset); | 221 | error = kset_register(&dlm_kset); |
222 | if (error) | 222 | if (error) |
223 | printk("dlm_lockspace_init: cannot register kset %d\n", error); | 223 | printk("dlm_lockspace_init: cannot register kset %d\n", error); |
diff --git a/fs/dquot.c b/fs/dquot.c index b16f991662c1..0a5febc159f2 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -1432,7 +1432,7 @@ int vfs_quota_off(struct super_block *sb, int type) | |||
1432 | mutex_unlock(&dqopt->dqonoff_mutex); | 1432 | mutex_unlock(&dqopt->dqonoff_mutex); |
1433 | } | 1433 | } |
1434 | if (sb->s_bdev) | 1434 | if (sb->s_bdev) |
1435 | invalidate_bdev(sb->s_bdev, 0); | 1435 | invalidate_bdev(sb->s_bdev); |
1436 | return 0; | 1436 | return 0; |
1437 | } | 1437 | } |
1438 | 1438 | ||
@@ -1468,7 +1468,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1468 | * we see all the changes from userspace... */ | 1468 | * we see all the changes from userspace... */ |
1469 | write_inode_now(inode, 1); | 1469 | write_inode_now(inode, 1); |
1470 | /* And now flush the block cache so that kernel sees the changes */ | 1470 | /* And now flush the block cache so that kernel sees the changes */ |
1471 | invalidate_bdev(sb->s_bdev, 0); | 1471 | invalidate_bdev(sb->s_bdev); |
1472 | mutex_lock(&inode->i_mutex); | 1472 | mutex_lock(&inode->i_mutex); |
1473 | mutex_lock(&dqopt->dqonoff_mutex); | 1473 | mutex_lock(&dqopt->dqonoff_mutex); |
1474 | if (sb_has_quota_enabled(sb, type)) { | 1474 | if (sb_has_quota_enabled(sb, type)) { |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index fc4a3a224641..8cbf3f69ebe5 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -583,8 +583,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) | |||
583 | { | 583 | { |
584 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; | 584 | struct ecryptfs_inode_info *ei = (struct ecryptfs_inode_info *)vptr; |
585 | 585 | ||
586 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | 586 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
587 | SLAB_CTOR_CONSTRUCTOR) | ||
588 | inode_init_once(&ei->vfs_inode); | 587 | inode_init_once(&ei->vfs_inode); |
589 | } | 588 | } |
590 | 589 | ||
@@ -793,7 +792,7 @@ static int do_sysfs_registration(void) | |||
793 | "Unable to register ecryptfs sysfs subsystem\n"); | 792 | "Unable to register ecryptfs sysfs subsystem\n"); |
794 | goto out; | 793 | goto out; |
795 | } | 794 | } |
796 | rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj, | 795 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, |
797 | &sysfs_attr_version.attr); | 796 | &sysfs_attr_version.attr); |
798 | if (rc) { | 797 | if (rc) { |
799 | printk(KERN_ERR | 798 | printk(KERN_ERR |
@@ -801,12 +800,12 @@ static int do_sysfs_registration(void) | |||
801 | subsystem_unregister(&ecryptfs_subsys); | 800 | subsystem_unregister(&ecryptfs_subsys); |
802 | goto out; | 801 | goto out; |
803 | } | 802 | } |
804 | rc = sysfs_create_file(&ecryptfs_subsys.kset.kobj, | 803 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, |
805 | &sysfs_attr_version_str.attr); | 804 | &sysfs_attr_version_str.attr); |
806 | if (rc) { | 805 | if (rc) { |
807 | printk(KERN_ERR | 806 | printk(KERN_ERR |
808 | "Unable to create ecryptfs version_str attribute\n"); | 807 | "Unable to create ecryptfs version_str attribute\n"); |
809 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | 808 | sysfs_remove_file(&ecryptfs_subsys.kobj, |
810 | &sysfs_attr_version.attr); | 809 | &sysfs_attr_version.attr); |
811 | subsystem_unregister(&ecryptfs_subsys); | 810 | subsystem_unregister(&ecryptfs_subsys); |
812 | goto out; | 811 | goto out; |
@@ -841,7 +840,7 @@ static int __init ecryptfs_init(void) | |||
841 | ecryptfs_free_kmem_caches(); | 840 | ecryptfs_free_kmem_caches(); |
842 | goto out; | 841 | goto out; |
843 | } | 842 | } |
844 | kset_set_kset_s(&ecryptfs_subsys, fs_subsys); | 843 | kobj_set_kset_s(&ecryptfs_subsys, fs_subsys); |
845 | sysfs_attr_version.attr.owner = THIS_MODULE; | 844 | sysfs_attr_version.attr.owner = THIS_MODULE; |
846 | sysfs_attr_version_str.attr.owner = THIS_MODULE; | 845 | sysfs_attr_version_str.attr.owner = THIS_MODULE; |
847 | rc = do_sysfs_registration(); | 846 | rc = do_sysfs_registration(); |
@@ -862,9 +861,9 @@ out: | |||
862 | 861 | ||
863 | static void __exit ecryptfs_exit(void) | 862 | static void __exit ecryptfs_exit(void) |
864 | { | 863 | { |
865 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | 864 | sysfs_remove_file(&ecryptfs_subsys.kobj, |
866 | &sysfs_attr_version.attr); | 865 | &sysfs_attr_version.attr); |
867 | sysfs_remove_file(&ecryptfs_subsys.kset.kobj, | 866 | sysfs_remove_file(&ecryptfs_subsys.kobj, |
868 | &sysfs_attr_version_str.attr); | 867 | &sysfs_attr_version_str.attr); |
869 | subsystem_unregister(&ecryptfs_subsys); | 868 | subsystem_unregister(&ecryptfs_subsys); |
870 | ecryptfs_release_messaging(ecryptfs_transport); | 869 | ecryptfs_release_messaging(ecryptfs_transport); |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index b731b09499cb..0770c4b66f53 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -46,7 +46,6 @@ struct kmem_cache *ecryptfs_lower_page_cache; | |||
46 | */ | 46 | */ |
47 | static struct page *ecryptfs_get1page(struct file *file, int index) | 47 | static struct page *ecryptfs_get1page(struct file *file, int index) |
48 | { | 48 | { |
49 | struct page *page; | ||
50 | struct dentry *dentry; | 49 | struct dentry *dentry; |
51 | struct inode *inode; | 50 | struct inode *inode; |
52 | struct address_space *mapping; | 51 | struct address_space *mapping; |
@@ -54,14 +53,7 @@ static struct page *ecryptfs_get1page(struct file *file, int index) | |||
54 | dentry = file->f_path.dentry; | 53 | dentry = file->f_path.dentry; |
55 | inode = dentry->d_inode; | 54 | inode = dentry->d_inode; |
56 | mapping = inode->i_mapping; | 55 | mapping = inode->i_mapping; |
57 | page = read_cache_page(mapping, index, | 56 | return read_mapping_page(mapping, index, (void *)file); |
58 | (filler_t *)mapping->a_ops->readpage, | ||
59 | (void *)file); | ||
60 | if (IS_ERR(page)) | ||
61 | goto out; | ||
62 | wait_on_page_locked(page); | ||
63 | out: | ||
64 | return page; | ||
65 | } | 57 | } |
66 | 58 | ||
67 | static | 59 | static |
@@ -233,7 +225,6 @@ int ecryptfs_do_readpage(struct file *file, struct page *page, | |||
233 | ecryptfs_printk(KERN_ERR, "Error reading from page cache\n"); | 225 | ecryptfs_printk(KERN_ERR, "Error reading from page cache\n"); |
234 | goto out; | 226 | goto out; |
235 | } | 227 | } |
236 | wait_on_page_locked(lower_page); | ||
237 | page_data = kmap_atomic(page, KM_USER0); | 228 | page_data = kmap_atomic(page, KM_USER0); |
238 | lower_page_data = kmap_atomic(lower_page, KM_USER1); | 229 | lower_page_data = kmap_atomic(lower_page, KM_USER1); |
239 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); | 230 | memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); |
diff --git a/fs/efs/super.c b/fs/efs/super.c index c2235e46edcd..ba7a8b9da0c1 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c | |||
@@ -72,8 +72,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
72 | { | 72 | { |
73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; | 73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; |
74 | 74 | ||
75 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 75 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
76 | SLAB_CTOR_CONSTRUCTOR) | ||
77 | inode_init_once(&ei->vfs_inode); | 76 | inode_init_once(&ei->vfs_inode); |
78 | } | 77 | } |
79 | 78 | ||
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index e89bfc8cf957..1d1e7e30d70e 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -161,10 +161,7 @@ static struct page * ext2_get_page(struct inode *dir, unsigned long n) | |||
161 | struct address_space *mapping = dir->i_mapping; | 161 | struct address_space *mapping = dir->i_mapping; |
162 | struct page *page = read_mapping_page(mapping, n, NULL); | 162 | struct page *page = read_mapping_page(mapping, n, NULL); |
163 | if (!IS_ERR(page)) { | 163 | if (!IS_ERR(page)) { |
164 | wait_on_page_locked(page); | ||
165 | kmap(page); | 164 | kmap(page); |
166 | if (!PageUptodate(page)) | ||
167 | goto fail; | ||
168 | if (!PageChecked(page)) | 165 | if (!PageChecked(page)) |
169 | ext2_check_page(page); | 166 | ext2_check_page(page); |
170 | if (PageError(page)) | 167 | if (PageError(page)) |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index a046a419d8af..685a1c287177 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -160,8 +160,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
160 | { | 160 | { |
161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; | 161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; |
162 | 162 | ||
163 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 163 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
164 | SLAB_CTOR_CONSTRUCTOR) { | ||
165 | rwlock_init(&ei->i_meta_lock); | 164 | rwlock_init(&ei->i_meta_lock); |
166 | #ifdef CONFIG_EXT2_FS_XATTR | 165 | #ifdef CONFIG_EXT2_FS_XATTR |
167 | init_rwsem(&ei->xattr_sem); | 166 | init_rwsem(&ei->xattr_sem); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 4a4fcd6868c7..54d3c9041259 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -420,7 +420,7 @@ static void ext3_put_super (struct super_block * sb) | |||
420 | dump_orphan_list(sb, sbi); | 420 | dump_orphan_list(sb, sbi); |
421 | J_ASSERT(list_empty(&sbi->s_orphan)); | 421 | J_ASSERT(list_empty(&sbi->s_orphan)); |
422 | 422 | ||
423 | invalidate_bdev(sb->s_bdev, 0); | 423 | invalidate_bdev(sb->s_bdev); |
424 | if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { | 424 | if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { |
425 | /* | 425 | /* |
426 | * Invalidate the journal device's buffers. We don't want them | 426 | * Invalidate the journal device's buffers. We don't want them |
@@ -428,7 +428,7 @@ static void ext3_put_super (struct super_block * sb) | |||
428 | * hotswapped, and it breaks the `ro-after' testing code. | 428 | * hotswapped, and it breaks the `ro-after' testing code. |
429 | */ | 429 | */ |
430 | sync_blockdev(sbi->journal_bdev); | 430 | sync_blockdev(sbi->journal_bdev); |
431 | invalidate_bdev(sbi->journal_bdev, 0); | 431 | invalidate_bdev(sbi->journal_bdev); |
432 | ext3_blkdev_remove(sbi); | 432 | ext3_blkdev_remove(sbi); |
433 | } | 433 | } |
434 | sb->s_fs_info = NULL; | 434 | sb->s_fs_info = NULL; |
@@ -466,8 +466,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
466 | { | 466 | { |
467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
468 | 468 | ||
469 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 469 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
470 | SLAB_CTOR_CONSTRUCTOR) { | ||
471 | INIT_LIST_HEAD(&ei->i_orphan); | 470 | INIT_LIST_HEAD(&ei->i_orphan); |
472 | #ifdef CONFIG_EXT3_FS_XATTR | 471 | #ifdef CONFIG_EXT3_FS_XATTR |
473 | init_rwsem(&ei->xattr_sem); | 472 | init_rwsem(&ei->xattr_sem); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 61c4718e4a53..719126932354 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -470,7 +470,7 @@ static void ext4_put_super (struct super_block * sb) | |||
470 | dump_orphan_list(sb, sbi); | 470 | dump_orphan_list(sb, sbi); |
471 | J_ASSERT(list_empty(&sbi->s_orphan)); | 471 | J_ASSERT(list_empty(&sbi->s_orphan)); |
472 | 472 | ||
473 | invalidate_bdev(sb->s_bdev, 0); | 473 | invalidate_bdev(sb->s_bdev); |
474 | if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { | 474 | if (sbi->journal_bdev && sbi->journal_bdev != sb->s_bdev) { |
475 | /* | 475 | /* |
476 | * Invalidate the journal device's buffers. We don't want them | 476 | * Invalidate the journal device's buffers. We don't want them |
@@ -478,7 +478,7 @@ static void ext4_put_super (struct super_block * sb) | |||
478 | * hotswapped, and it breaks the `ro-after' testing code. | 478 | * hotswapped, and it breaks the `ro-after' testing code. |
479 | */ | 479 | */ |
480 | sync_blockdev(sbi->journal_bdev); | 480 | sync_blockdev(sbi->journal_bdev); |
481 | invalidate_bdev(sbi->journal_bdev, 0); | 481 | invalidate_bdev(sbi->journal_bdev); |
482 | ext4_blkdev_remove(sbi); | 482 | ext4_blkdev_remove(sbi); |
483 | } | 483 | } |
484 | sb->s_fs_info = NULL; | 484 | sb->s_fs_info = NULL; |
@@ -517,8 +517,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
517 | { | 517 | { |
518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; | 518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; |
519 | 519 | ||
520 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 520 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
521 | SLAB_CTOR_CONSTRUCTOR) { | ||
522 | INIT_LIST_HEAD(&ei->i_orphan); | 521 | INIT_LIST_HEAD(&ei->i_orphan); |
523 | #ifdef CONFIG_EXT4DEV_FS_XATTR | 522 | #ifdef CONFIG_EXT4DEV_FS_XATTR |
524 | init_rwsem(&ei->xattr_sem); | 523 | init_rwsem(&ei->xattr_sem); |
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 05c2941c74f2..1959143c1d27 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
@@ -40,8 +40,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | |||
40 | { | 40 | { |
41 | struct fat_cache *cache = (struct fat_cache *)foo; | 41 | struct fat_cache *cache = (struct fat_cache *)foo; |
42 | 42 | ||
43 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 43 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
44 | SLAB_CTOR_CONSTRUCTOR) | ||
45 | INIT_LIST_HEAD(&cache->cache_list); | 44 | INIT_LIST_HEAD(&cache->cache_list); |
46 | } | 45 | } |
47 | 46 | ||
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 9bfe607c892e..65cb54bde481 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -499,8 +499,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
499 | { | 499 | { |
500 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; | 500 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; |
501 | 501 | ||
502 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 502 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
503 | SLAB_CTOR_CONSTRUCTOR) { | ||
504 | spin_lock_init(&ei->cache_lru_lock); | 503 | spin_lock_init(&ei->cache_lru_lock); |
505 | ei->nr_caches = 0; | 504 | ei->nr_caches = 0; |
506 | ei->cache_valid_id = FAT_CACHE_VALID + 1; | 505 | ei->cache_valid_id = FAT_CACHE_VALID + 1; |
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c index decac62efe57..ed8f0b0dd880 100644 --- a/fs/freevxfs/vxfs_subr.c +++ b/fs/freevxfs/vxfs_subr.c | |||
@@ -74,10 +74,7 @@ vxfs_get_page(struct address_space *mapping, u_long n) | |||
74 | pp = read_mapping_page(mapping, n, NULL); | 74 | pp = read_mapping_page(mapping, n, NULL); |
75 | 75 | ||
76 | if (!IS_ERR(pp)) { | 76 | if (!IS_ERR(pp)) { |
77 | wait_on_page_locked(pp); | ||
78 | kmap(pp); | 77 | kmap(pp); |
79 | if (!PageUptodate(pp)) | ||
80 | goto fail; | ||
81 | /** if (!PageChecked(pp)) **/ | 78 | /** if (!PageChecked(pp)) **/ |
82 | /** vxfs_check_page(pp); **/ | 79 | /** vxfs_check_page(pp); **/ |
83 | if (PageError(pp)) | 80 | if (PageError(pp)) |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 608db81219a0..d8003be56e05 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -685,8 +685,7 @@ static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, | |||
685 | { | 685 | { |
686 | struct inode * inode = foo; | 686 | struct inode * inode = foo; |
687 | 687 | ||
688 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 688 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
689 | SLAB_CTOR_CONSTRUCTOR) | ||
690 | inode_init_once(inode); | 689 | inode_init_once(inode); |
691 | } | 690 | } |
692 | 691 | ||
@@ -731,12 +730,12 @@ static int fuse_sysfs_init(void) | |||
731 | { | 730 | { |
732 | int err; | 731 | int err; |
733 | 732 | ||
734 | kset_set_kset_s(&fuse_subsys, fs_subsys); | 733 | kobj_set_kset_s(&fuse_subsys, fs_subsys); |
735 | err = subsystem_register(&fuse_subsys); | 734 | err = subsystem_register(&fuse_subsys); |
736 | if (err) | 735 | if (err) |
737 | goto out_err; | 736 | goto out_err; |
738 | 737 | ||
739 | kset_set_kset_s(&connections_subsys, fuse_subsys); | 738 | kobj_set_kset_s(&connections_subsys, fuse_subsys); |
740 | err = subsystem_register(&connections_subsys); | 739 | err = subsystem_register(&connections_subsys); |
741 | if (err) | 740 | if (err) |
742 | goto out_fuse_unregister; | 741 | goto out_fuse_unregister; |
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c index 4746b884662d..d9fe3ca40e18 100644 --- a/fs/gfs2/locking/dlm/sysfs.c +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -190,7 +190,6 @@ static struct kobj_type gdlm_ktype = { | |||
190 | }; | 190 | }; |
191 | 191 | ||
192 | static struct kset gdlm_kset = { | 192 | static struct kset gdlm_kset = { |
193 | .subsys = &kernel_subsys, | ||
194 | .kobj = {.name = "lock_dlm",}, | 193 | .kobj = {.name = "lock_dlm",}, |
195 | .ktype = &gdlm_ktype, | 194 | .ktype = &gdlm_ktype, |
196 | }; | 195 | }; |
@@ -225,6 +224,7 @@ int gdlm_sysfs_init(void) | |||
225 | { | 224 | { |
226 | int error; | 225 | int error; |
227 | 226 | ||
227 | kobj_set_kset_s(&gdlm_kset, kernel_subsys); | ||
228 | error = kset_register(&gdlm_kset); | 228 | error = kset_register(&gdlm_kset); |
229 | if (error) | 229 | if (error) |
230 | printk("lock_dlm: cannot register kset %d\n", error); | 230 | printk("lock_dlm: cannot register kset %d\n", error); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index c4bb374eaf92..e460487c0557 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -27,8 +27,7 @@ | |||
27 | static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | 27 | static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
28 | { | 28 | { |
29 | struct gfs2_inode *ip = foo; | 29 | struct gfs2_inode *ip = foo; |
30 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 30 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
31 | SLAB_CTOR_CONSTRUCTOR) { | ||
32 | inode_init_once(&ip->i_inode); | 31 | inode_init_once(&ip->i_inode); |
33 | spin_lock_init(&ip->i_spin); | 32 | spin_lock_init(&ip->i_spin); |
34 | init_rwsem(&ip->i_rw_mutex); | 33 | init_rwsem(&ip->i_rw_mutex); |
@@ -39,8 +38,7 @@ static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned | |||
39 | static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | 38 | static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
40 | { | 39 | { |
41 | struct gfs2_glock *gl = foo; | 40 | struct gfs2_glock *gl = foo; |
42 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 41 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
43 | SLAB_CTOR_CONSTRUCTOR) { | ||
44 | INIT_HLIST_NODE(&gl->gl_list); | 42 | INIT_HLIST_NODE(&gl->gl_list); |
45 | spin_lock_init(&gl->gl_spin); | 43 | spin_lock_init(&gl->gl_spin); |
46 | INIT_LIST_HEAD(&gl->gl_holders); | 44 | INIT_LIST_HEAD(&gl->gl_holders); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index d01f9f0fda26..c26c21b53c19 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -222,7 +222,6 @@ static struct kobj_type gfs2_ktype = { | |||
222 | }; | 222 | }; |
223 | 223 | ||
224 | static struct kset gfs2_kset = { | 224 | static struct kset gfs2_kset = { |
225 | .subsys = &fs_subsys, | ||
226 | .kobj = {.name = "gfs2"}, | 225 | .kobj = {.name = "gfs2"}, |
227 | .ktype = &gfs2_ktype, | 226 | .ktype = &gfs2_ktype, |
228 | }; | 227 | }; |
@@ -554,6 +553,7 @@ int gfs2_sys_init(void) | |||
554 | { | 553 | { |
555 | gfs2_sys_margs = NULL; | 554 | gfs2_sys_margs = NULL; |
556 | spin_lock_init(&gfs2_sys_margs_lock); | 555 | spin_lock_init(&gfs2_sys_margs_lock); |
556 | kobj_set_kset_s(&gfs2_kset, fs_subsys); | ||
557 | return kset_register(&gfs2_kset); | 557 | return kset_register(&gfs2_kset); |
558 | } | 558 | } |
559 | 559 | ||
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 623f509f1d47..4f1888f16cf0 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -434,7 +434,7 @@ static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flag | |||
434 | { | 434 | { |
435 | struct hfs_inode_info *i = p; | 435 | struct hfs_inode_info *i = p; |
436 | 436 | ||
437 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) | 437 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
438 | inode_init_once(&i->vfs_inode); | 438 | inode_init_once(&i->vfs_inode); |
439 | } | 439 | } |
440 | 440 | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 1a97f9293447..37afbec8a761 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -470,7 +470,7 @@ static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long | |||
470 | { | 470 | { |
471 | struct hfsplus_inode_info *i = p; | 471 | struct hfsplus_inode_info *i = p; |
472 | 472 | ||
473 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) | 473 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
474 | inode_init_once(&i->vfs_inode); | 474 | inode_init_once(&i->vfs_inode); |
475 | } | 475 | } |
476 | 476 | ||
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index e0174e338526..1b95f39fbc37 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -176,8 +176,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
176 | { | 176 | { |
177 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; | 177 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; |
178 | 178 | ||
179 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 179 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
180 | SLAB_CTOR_CONSTRUCTOR) { | ||
181 | mutex_init(&ei->i_mutex); | 180 | mutex_init(&ei->i_mutex); |
182 | mutex_init(&ei->i_parent_mutex); | 181 | mutex_init(&ei->i_parent_mutex); |
183 | inode_init_once(&ei->vfs_inode); | 182 | inode_init_once(&ei->vfs_inode); |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 8c718a3d413f..98959b87cdf8 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/backing-dev.h> | 22 | #include <linux/backing-dev.h> |
23 | #include <linux/hugetlb.h> | 23 | #include <linux/hugetlb.h> |
24 | #include <linux/pagevec.h> | 24 | #include <linux/pagevec.h> |
25 | #include <linux/mman.h> | ||
25 | #include <linux/quotaops.h> | 26 | #include <linux/quotaops.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <linux/dnotify.h> | 28 | #include <linux/dnotify.h> |
@@ -98,10 +99,7 @@ out: | |||
98 | * Called under down_write(mmap_sem). | 99 | * Called under down_write(mmap_sem). |
99 | */ | 100 | */ |
100 | 101 | ||
101 | #ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA | 102 | #ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA |
102 | unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | ||
103 | unsigned long len, unsigned long pgoff, unsigned long flags); | ||
104 | #else | ||
105 | static unsigned long | 103 | static unsigned long |
106 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | 104 | hugetlb_get_unmapped_area(struct file *file, unsigned long addr, |
107 | unsigned long len, unsigned long pgoff, unsigned long flags) | 105 | unsigned long len, unsigned long pgoff, unsigned long flags) |
@@ -115,6 +113,12 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, | |||
115 | if (len > TASK_SIZE) | 113 | if (len > TASK_SIZE) |
116 | return -ENOMEM; | 114 | return -ENOMEM; |
117 | 115 | ||
116 | if (flags & MAP_FIXED) { | ||
117 | if (prepare_hugepage_range(addr, len, pgoff)) | ||
118 | return -EINVAL; | ||
119 | return addr; | ||
120 | } | ||
121 | |||
118 | if (addr) { | 122 | if (addr) { |
119 | addr = ALIGN(addr, HPAGE_SIZE); | 123 | addr = ALIGN(addr, HPAGE_SIZE); |
120 | vma = find_vma(mm, addr); | 124 | vma = find_vma(mm, addr); |
@@ -453,7 +457,7 @@ static int hugetlbfs_symlink(struct inode *dir, | |||
453 | */ | 457 | */ |
454 | static int hugetlbfs_set_page_dirty(struct page *page) | 458 | static int hugetlbfs_set_page_dirty(struct page *page) |
455 | { | 459 | { |
456 | struct page *head = (struct page *)page_private(page); | 460 | struct page *head = compound_head(page); |
457 | 461 | ||
458 | SetPageDirty(head); | 462 | SetPageDirty(head); |
459 | return 0; | 463 | return 0; |
@@ -552,8 +556,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | |||
552 | { | 556 | { |
553 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; | 557 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; |
554 | 558 | ||
555 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 559 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
556 | SLAB_CTOR_CONSTRUCTOR) | ||
557 | inode_init_once(&ei->vfs_inode); | 560 | inode_init_once(&ei->vfs_inode); |
558 | } | 561 | } |
559 | 562 | ||
@@ -744,6 +747,9 @@ struct file *hugetlb_zero_setup(size_t size) | |||
744 | char buf[16]; | 747 | char buf[16]; |
745 | static atomic_t counter; | 748 | static atomic_t counter; |
746 | 749 | ||
750 | if (!hugetlbfs_vfsmount) | ||
751 | return ERR_PTR(-ENOENT); | ||
752 | |||
747 | if (!can_do_hugetlb_shm()) | 753 | if (!can_do_hugetlb_shm()) |
748 | return ERR_PTR(-EPERM); | 754 | return ERR_PTR(-EPERM); |
749 | 755 | ||
diff --git a/fs/inode.c b/fs/inode.c index 5abb097ab1b0..b4296bf62739 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -213,8 +213,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
213 | { | 213 | { |
214 | struct inode * inode = (struct inode *) foo; | 214 | struct inode * inode = (struct inode *) foo; |
215 | 215 | ||
216 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 216 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
217 | SLAB_CTOR_CONSTRUCTOR) | ||
218 | inode_init_once(inode); | 217 | inode_init_once(inode); |
219 | } | 218 | } |
220 | 219 | ||
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 64a96cdfe3a4..e99f7ff4ecb4 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -77,8 +77,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags | |||
77 | { | 77 | { |
78 | struct iso_inode_info *ei = foo; | 78 | struct iso_inode_info *ei = foo; |
79 | 79 | ||
80 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 80 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
81 | SLAB_CTOR_CONSTRUCTOR) | ||
82 | inode_init_once(&ei->vfs_inode); | 81 | inode_init_once(&ei->vfs_inode); |
83 | } | 82 | } |
84 | 83 | ||
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index e51164a8a8d4..45368f8bbe72 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -47,8 +47,7 @@ static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned l | |||
47 | { | 47 | { |
48 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; | 48 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; |
49 | 49 | ||
50 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 50 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
51 | SLAB_CTOR_CONSTRUCTOR) { | ||
52 | init_MUTEX(&ei->sem); | 51 | init_MUTEX(&ei->sem); |
53 | inode_init_once(&ei->vfs_inode); | 52 | inode_init_once(&ei->vfs_inode); |
54 | } | 53 | } |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 58deae007507..6b3acb0b5781 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -184,8 +184,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) | |||
184 | { | 184 | { |
185 | struct metapage *mp = (struct metapage *)foo; | 185 | struct metapage *mp = (struct metapage *)foo; |
186 | 186 | ||
187 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 187 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
188 | SLAB_CTOR_CONSTRUCTOR) { | ||
189 | mp->lid = 0; | 188 | mp->lid = 0; |
190 | mp->lsn = 0; | 189 | mp->lsn = 0; |
191 | mp->flag = 0; | 190 | mp->flag = 0; |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 52d73d54a931..ea9dc3e65dcf 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -752,8 +752,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags | |||
752 | { | 752 | { |
753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; | 753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; |
754 | 754 | ||
755 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | 755 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
756 | SLAB_CTOR_CONSTRUCTOR) { | ||
757 | memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); | 756 | memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); |
758 | INIT_LIST_HEAD(&jfs_ip->anon_inode_list); | 757 | INIT_LIST_HEAD(&jfs_ip->anon_inode_list); |
759 | init_rwsem(&jfs_ip->rdwrlock); | 758 | init_rwsem(&jfs_ip->rdwrlock); |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index eb243edf8932..2102e2d0134d 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -225,16 +225,13 @@ xdr_decode_stat(struct rpc_rqst *rqstp, __be32 *p, struct nsm_res *resp) | |||
225 | #define SM_monres_sz 2 | 225 | #define SM_monres_sz 2 |
226 | #define SM_unmonres_sz 1 | 226 | #define SM_unmonres_sz 1 |
227 | 227 | ||
228 | #ifndef MAX | ||
229 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
230 | #endif | ||
231 | |||
232 | static struct rpc_procinfo nsm_procedures[] = { | 228 | static struct rpc_procinfo nsm_procedures[] = { |
233 | [SM_MON] = { | 229 | [SM_MON] = { |
234 | .p_proc = SM_MON, | 230 | .p_proc = SM_MON, |
235 | .p_encode = (kxdrproc_t) xdr_encode_mon, | 231 | .p_encode = (kxdrproc_t) xdr_encode_mon, |
236 | .p_decode = (kxdrproc_t) xdr_decode_stat_res, | 232 | .p_decode = (kxdrproc_t) xdr_decode_stat_res, |
237 | .p_bufsiz = MAX(SM_mon_sz, SM_monres_sz) << 2, | 233 | .p_arglen = SM_mon_sz, |
234 | .p_replen = SM_monres_sz, | ||
238 | .p_statidx = SM_MON, | 235 | .p_statidx = SM_MON, |
239 | .p_name = "MONITOR", | 236 | .p_name = "MONITOR", |
240 | }, | 237 | }, |
@@ -242,7 +239,8 @@ static struct rpc_procinfo nsm_procedures[] = { | |||
242 | .p_proc = SM_UNMON, | 239 | .p_proc = SM_UNMON, |
243 | .p_encode = (kxdrproc_t) xdr_encode_unmon, | 240 | .p_encode = (kxdrproc_t) xdr_encode_unmon, |
244 | .p_decode = (kxdrproc_t) xdr_decode_stat, | 241 | .p_decode = (kxdrproc_t) xdr_decode_stat, |
245 | .p_bufsiz = MAX(SM_mon_id_sz, SM_unmonres_sz) << 2, | 242 | .p_arglen = SM_mon_id_sz, |
243 | .p_replen = SM_unmonres_sz, | ||
246 | .p_statidx = SM_UNMON, | 244 | .p_statidx = SM_UNMON, |
247 | .p_name = "UNMONITOR", | 245 | .p_name = "UNMONITOR", |
248 | }, | 246 | }, |
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 34dae5d70738..9702956d206c 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c | |||
@@ -510,17 +510,20 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
510 | return 0; | 510 | return 0; |
511 | } | 511 | } |
512 | 512 | ||
513 | #if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) | ||
514 | # error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" | ||
515 | #endif | ||
516 | |||
513 | /* | 517 | /* |
514 | * Buffer requirements for NLM | 518 | * Buffer requirements for NLM |
515 | */ | 519 | */ |
516 | #define NLM_void_sz 0 | 520 | #define NLM_void_sz 0 |
517 | #define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) | 521 | #define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) |
518 | #define NLM_caller_sz 1+XDR_QUADLEN(sizeof(utsname()->nodename)) | 522 | #define NLM_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) |
519 | #define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) | 523 | #define NLM_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) |
520 | /* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */ | ||
521 | #define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) | 524 | #define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) |
522 | #define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz | 525 | #define NLM_lock_sz 3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz |
523 | #define NLM_holder_sz 4+NLM_netobj_sz | 526 | #define NLM_holder_sz 4+NLM_owner_sz |
524 | 527 | ||
525 | #define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz | 528 | #define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz |
526 | #define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz | 529 | #define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz |
@@ -531,10 +534,6 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
531 | #define NLM_res_sz NLM_cookie_sz+1 | 534 | #define NLM_res_sz NLM_cookie_sz+1 |
532 | #define NLM_norep_sz 0 | 535 | #define NLM_norep_sz 0 |
533 | 536 | ||
534 | #ifndef MAX | ||
535 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
536 | #endif | ||
537 | |||
538 | /* | 537 | /* |
539 | * For NLM, a void procedure really returns nothing | 538 | * For NLM, a void procedure really returns nothing |
540 | */ | 539 | */ |
@@ -545,7 +544,8 @@ nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
545 | .p_proc = NLMPROC_##proc, \ | 544 | .p_proc = NLMPROC_##proc, \ |
546 | .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ | 545 | .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ |
547 | .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ | 546 | .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ |
548 | .p_bufsiz = MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2, \ | 547 | .p_arglen = NLM_##argtype##_sz, \ |
548 | .p_replen = NLM_##restype##_sz, \ | ||
549 | .p_statidx = NLMPROC_##proc, \ | 549 | .p_statidx = NLMPROC_##proc, \ |
550 | .p_name = #proc, \ | 550 | .p_name = #proc, \ |
551 | } | 551 | } |
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index a78240551219..ce1efdbe1b3a 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
@@ -516,17 +516,24 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
516 | return 0; | 516 | return 0; |
517 | } | 517 | } |
518 | 518 | ||
519 | #if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) | ||
520 | # error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" | ||
521 | #endif | ||
522 | |||
523 | #if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN) | ||
524 | # error "NLM host name cannot be larger than NLM's maximum string length!" | ||
525 | #endif | ||
526 | |||
519 | /* | 527 | /* |
520 | * Buffer requirements for NLM | 528 | * Buffer requirements for NLM |
521 | */ | 529 | */ |
522 | #define NLM4_void_sz 0 | 530 | #define NLM4_void_sz 0 |
523 | #define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) | 531 | #define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) |
524 | #define NLM4_caller_sz 1+XDR_QUADLEN(NLM_MAXSTRLEN) | 532 | #define NLM4_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) |
525 | #define NLM4_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) | 533 | #define NLM4_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) |
526 | /* #define NLM4_owner_sz 1+XDR_QUADLEN(NLM4_MAXOWNER) */ | ||
527 | #define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE) | 534 | #define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE) |
528 | #define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_netobj_sz+NLM4_fhandle_sz | 535 | #define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz |
529 | #define NLM4_holder_sz 6+NLM4_netobj_sz | 536 | #define NLM4_holder_sz 6+NLM4_owner_sz |
530 | 537 | ||
531 | #define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz | 538 | #define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz |
532 | #define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz | 539 | #define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz |
@@ -537,10 +544,6 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
537 | #define NLM4_res_sz NLM4_cookie_sz+1 | 544 | #define NLM4_res_sz NLM4_cookie_sz+1 |
538 | #define NLM4_norep_sz 0 | 545 | #define NLM4_norep_sz 0 |
539 | 546 | ||
540 | #ifndef MAX | ||
541 | # define MAX(a,b) (((a) > (b))? (a) : (b)) | ||
542 | #endif | ||
543 | |||
544 | /* | 547 | /* |
545 | * For NLM, a void procedure really returns nothing | 548 | * For NLM, a void procedure really returns nothing |
546 | */ | 549 | */ |
@@ -551,7 +554,8 @@ nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) | |||
551 | .p_proc = NLMPROC_##proc, \ | 554 | .p_proc = NLMPROC_##proc, \ |
552 | .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \ | 555 | .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \ |
553 | .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \ | 556 | .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \ |
554 | .p_bufsiz = MAX(NLM4_##argtype##_sz, NLM4_##restype##_sz) << 2, \ | 557 | .p_arglen = NLM4_##argtype##_sz, \ |
558 | .p_replen = NLM4_##restype##_sz, \ | ||
555 | .p_statidx = NLMPROC_##proc, \ | 559 | .p_statidx = NLMPROC_##proc, \ |
556 | .p_name = #proc, \ | 560 | .p_name = #proc, \ |
557 | } | 561 | } |
diff --git a/fs/locks.c b/fs/locks.c index 52a81005dab4..325578074742 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -203,8 +203,7 @@ static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) | |||
203 | { | 203 | { |
204 | struct file_lock *lock = (struct file_lock *) foo; | 204 | struct file_lock *lock = (struct file_lock *) foo; |
205 | 205 | ||
206 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) != | 206 | if (!(flags & SLAB_CTOR_CONSTRUCTOR)) |
207 | SLAB_CTOR_CONSTRUCTOR) | ||
208 | return; | 207 | return; |
209 | 208 | ||
210 | locks_init_lock(lock); | 209 | locks_init_lock(lock); |
diff --git a/fs/minix/dir.c b/fs/minix/dir.c index cb4cb571fddf..e207cbe70951 100644 --- a/fs/minix/dir.c +++ b/fs/minix/dir.c | |||
@@ -65,7 +65,6 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n) | |||
65 | struct address_space *mapping = dir->i_mapping; | 65 | struct address_space *mapping = dir->i_mapping; |
66 | struct page *page = read_mapping_page(mapping, n, NULL); | 66 | struct page *page = read_mapping_page(mapping, n, NULL); |
67 | if (!IS_ERR(page)) { | 67 | if (!IS_ERR(page)) { |
68 | wait_on_page_locked(page); | ||
69 | kmap(page); | 68 | kmap(page); |
70 | if (!PageUptodate(page)) | 69 | if (!PageUptodate(page)) |
71 | goto fail; | 70 | goto fail; |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 92e383af3709..2f4d43a2a310 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -73,8 +73,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
73 | { | 73 | { |
74 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; | 74 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; |
75 | 75 | ||
76 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 76 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
77 | SLAB_CTOR_CONSTRUCTOR) | ||
78 | inode_init_once(&ei->vfs_inode); | 77 | inode_init_once(&ei->vfs_inode); |
79 | } | 78 | } |
80 | 79 | ||
diff --git a/fs/namei.c b/fs/namei.c index 880052cadbcd..94b2f60aec22 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2671,19 +2671,9 @@ static char *page_getlink(struct dentry * dentry, struct page **ppage) | |||
2671 | struct address_space *mapping = dentry->d_inode->i_mapping; | 2671 | struct address_space *mapping = dentry->d_inode->i_mapping; |
2672 | page = read_mapping_page(mapping, 0, NULL); | 2672 | page = read_mapping_page(mapping, 0, NULL); |
2673 | if (IS_ERR(page)) | 2673 | if (IS_ERR(page)) |
2674 | goto sync_fail; | 2674 | return (char*)page; |
2675 | wait_on_page_locked(page); | ||
2676 | if (!PageUptodate(page)) | ||
2677 | goto async_fail; | ||
2678 | *ppage = page; | 2675 | *ppage = page; |
2679 | return kmap(page); | 2676 | return kmap(page); |
2680 | |||
2681 | async_fail: | ||
2682 | page_cache_release(page); | ||
2683 | return ERR_PTR(-EIO); | ||
2684 | |||
2685 | sync_fail: | ||
2686 | return (char*)page; | ||
2687 | } | 2677 | } |
2688 | 2678 | ||
2689 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 2679 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 7285c94956c4..c29f00ad495d 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -60,8 +60,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
60 | { | 60 | { |
61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; | 61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; |
62 | 62 | ||
63 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 63 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
64 | SLAB_CTOR_CONSTRUCTOR) { | ||
65 | mutex_init(&ei->open_mutex); | 64 | mutex_init(&ei->open_mutex); |
66 | inode_init_once(&ei->vfs_inode); | 65 | inode_init_once(&ei->vfs_inode); |
67 | } | 66 | } |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 2190e6c2792e..5bd03b97002e 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -618,7 +618,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat | |||
618 | if (clp->cl_nfsversion == 3) { | 618 | if (clp->cl_nfsversion == 3) { |
619 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) | 619 | if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) |
620 | server->namelen = NFS3_MAXNAMLEN; | 620 | server->namelen = NFS3_MAXNAMLEN; |
621 | server->caps |= NFS_CAP_READDIRPLUS; | 621 | if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) |
622 | server->caps |= NFS_CAP_READDIRPLUS; | ||
622 | } else { | 623 | } else { |
623 | if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) | 624 | if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) |
624 | server->namelen = NFS2_MAXNAMLEN; | 625 | server->namelen = NFS2_MAXNAMLEN; |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index cd3469720cbf..625d8e5fb39d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -154,6 +154,8 @@ typedef struct { | |||
154 | decode_dirent_t decode; | 154 | decode_dirent_t decode; |
155 | int plus; | 155 | int plus; |
156 | int error; | 156 | int error; |
157 | unsigned long timestamp; | ||
158 | int timestamp_valid; | ||
157 | } nfs_readdir_descriptor_t; | 159 | } nfs_readdir_descriptor_t; |
158 | 160 | ||
159 | /* Now we cache directories properly, by stuffing the dirent | 161 | /* Now we cache directories properly, by stuffing the dirent |
@@ -195,6 +197,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
195 | } | 197 | } |
196 | goto error; | 198 | goto error; |
197 | } | 199 | } |
200 | desc->timestamp = timestamp; | ||
201 | desc->timestamp_valid = 1; | ||
198 | SetPageUptodate(page); | 202 | SetPageUptodate(page); |
199 | spin_lock(&inode->i_lock); | 203 | spin_lock(&inode->i_lock); |
200 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | 204 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; |
@@ -225,6 +229,10 @@ int dir_decode(nfs_readdir_descriptor_t *desc) | |||
225 | if (IS_ERR(p)) | 229 | if (IS_ERR(p)) |
226 | return PTR_ERR(p); | 230 | return PTR_ERR(p); |
227 | desc->ptr = p; | 231 | desc->ptr = p; |
232 | if (desc->timestamp_valid) | ||
233 | desc->entry->fattr->time_start = desc->timestamp; | ||
234 | else | ||
235 | desc->entry->fattr->valid &= ~NFS_ATTR_FATTR; | ||
228 | return 0; | 236 | return 0; |
229 | } | 237 | } |
230 | 238 | ||
@@ -316,14 +324,16 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc) | |||
316 | __FUNCTION__, desc->page_index, | 324 | __FUNCTION__, desc->page_index, |
317 | (long long) *desc->dir_cookie); | 325 | (long long) *desc->dir_cookie); |
318 | 326 | ||
327 | /* If we find the page in the page_cache, we cannot be sure | ||
328 | * how fresh the data is, so we will ignore readdir_plus attributes. | ||
329 | */ | ||
330 | desc->timestamp_valid = 0; | ||
319 | page = read_cache_page(inode->i_mapping, desc->page_index, | 331 | page = read_cache_page(inode->i_mapping, desc->page_index, |
320 | (filler_t *)nfs_readdir_filler, desc); | 332 | (filler_t *)nfs_readdir_filler, desc); |
321 | if (IS_ERR(page)) { | 333 | if (IS_ERR(page)) { |
322 | status = PTR_ERR(page); | 334 | status = PTR_ERR(page); |
323 | goto out; | 335 | goto out; |
324 | } | 336 | } |
325 | if (!PageUptodate(page)) | ||
326 | goto read_error; | ||
327 | 337 | ||
328 | /* NOTE: Someone else may have changed the READDIRPLUS flag */ | 338 | /* NOTE: Someone else may have changed the READDIRPLUS flag */ |
329 | desc->page = page; | 339 | desc->page = page; |
@@ -337,9 +347,6 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc) | |||
337 | out: | 347 | out: |
338 | dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __FUNCTION__, status); | 348 | dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __FUNCTION__, status); |
339 | return status; | 349 | return status; |
340 | read_error: | ||
341 | page_cache_release(page); | ||
342 | return -EIO; | ||
343 | } | 350 | } |
344 | 351 | ||
345 | /* | 352 | /* |
@@ -468,6 +475,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
468 | struct rpc_cred *cred = nfs_file_cred(file); | 475 | struct rpc_cred *cred = nfs_file_cred(file); |
469 | struct page *page = NULL; | 476 | struct page *page = NULL; |
470 | int status; | 477 | int status; |
478 | unsigned long timestamp; | ||
471 | 479 | ||
472 | dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", | 480 | dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", |
473 | (unsigned long long)*desc->dir_cookie); | 481 | (unsigned long long)*desc->dir_cookie); |
@@ -477,6 +485,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
477 | status = -ENOMEM; | 485 | status = -ENOMEM; |
478 | goto out; | 486 | goto out; |
479 | } | 487 | } |
488 | timestamp = jiffies; | ||
480 | desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, | 489 | desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, |
481 | page, | 490 | page, |
482 | NFS_SERVER(inode)->dtsize, | 491 | NFS_SERVER(inode)->dtsize, |
@@ -487,6 +496,8 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
487 | desc->page = page; | 496 | desc->page = page; |
488 | desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ | 497 | desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ |
489 | if (desc->error >= 0) { | 498 | if (desc->error >= 0) { |
499 | desc->timestamp = timestamp; | ||
500 | desc->timestamp_valid = 1; | ||
490 | if ((status = dir_decode(desc)) == 0) | 501 | if ((status = dir_decode(desc)) == 0) |
491 | desc->entry->prev_cookie = *desc->dir_cookie; | 502 | desc->entry->prev_cookie = *desc->dir_cookie; |
492 | } else | 503 | } else |
@@ -849,6 +860,10 @@ static int nfs_dentry_delete(struct dentry *dentry) | |||
849 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) | 860 | static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) |
850 | { | 861 | { |
851 | nfs_inode_return_delegation(inode); | 862 | nfs_inode_return_delegation(inode); |
863 | if (S_ISDIR(inode->i_mode)) | ||
864 | /* drop any readdir cache as it could easily be old */ | ||
865 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; | ||
866 | |||
852 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { | 867 | if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { |
853 | lock_kernel(); | 868 | lock_kernel(); |
854 | drop_nlink(inode); | 869 | drop_nlink(inode); |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 2877744cb606..889de60f8a84 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
55 | #include <asm/atomic.h> | 55 | #include <asm/atomic.h> |
56 | 56 | ||
57 | #include "internal.h" | ||
57 | #include "iostat.h" | 58 | #include "iostat.h" |
58 | 59 | ||
59 | #define NFSDBG_FACILITY NFSDBG_VFS | 60 | #define NFSDBG_FACILITY NFSDBG_VFS |
@@ -271,7 +272,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
271 | bytes = min(rsize,count); | 272 | bytes = min(rsize,count); |
272 | 273 | ||
273 | result = -ENOMEM; | 274 | result = -ENOMEM; |
274 | data = nfs_readdata_alloc(pgbase + bytes); | 275 | data = nfs_readdata_alloc(nfs_page_array_len(pgbase, bytes)); |
275 | if (unlikely(!data)) | 276 | if (unlikely(!data)) |
276 | break; | 277 | break; |
277 | 278 | ||
@@ -602,7 +603,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
602 | bytes = min(wsize,count); | 603 | bytes = min(wsize,count); |
603 | 604 | ||
604 | result = -ENOMEM; | 605 | result = -ENOMEM; |
605 | data = nfs_writedata_alloc(pgbase + bytes); | 606 | data = nfs_writedata_alloc(nfs_page_array_len(pgbase, bytes)); |
606 | if (unlikely(!data)) | 607 | if (unlikely(!data)) |
607 | break; | 608 | break; |
608 | 609 | ||
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 44aa9b726573..1e9a915d1fea 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1167,8 +1167,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
1167 | { | 1167 | { |
1168 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; | 1168 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; |
1169 | 1169 | ||
1170 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 1170 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
1171 | SLAB_CTOR_CONSTRUCTOR) { | ||
1172 | inode_init_once(&nfsi->vfs_inode); | 1171 | inode_init_once(&nfsi->vfs_inode); |
1173 | spin_lock_init(&nfsi->req_lock); | 1172 | spin_lock_init(&nfsi->req_lock); |
1174 | INIT_LIST_HEAD(&nfsi->dirty); | 1173 | INIT_LIST_HEAD(&nfsi->dirty); |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 6610f2b02077..ad2b40db1e65 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -231,3 +231,15 @@ unsigned int nfs_page_length(struct page *page) | |||
231 | } | 231 | } |
232 | return 0; | 232 | return 0; |
233 | } | 233 | } |
234 | |||
235 | /* | ||
236 | * Determine the number of pages in an array of length 'len' and | ||
237 | * with a base offset of 'base' | ||
238 | */ | ||
239 | static inline | ||
240 | unsigned int nfs_page_array_len(unsigned int base, size_t len) | ||
241 | { | ||
242 | return ((unsigned long)len + (unsigned long)base + | ||
243 | PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
244 | } | ||
245 | |||
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index f75fe72b4160..ca5a266a3140 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -133,13 +133,15 @@ xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, struct mnt_fhstatus *res) | |||
133 | 133 | ||
134 | #define MNT_dirpath_sz (1 + 256) | 134 | #define MNT_dirpath_sz (1 + 256) |
135 | #define MNT_fhstatus_sz (1 + 8) | 135 | #define MNT_fhstatus_sz (1 + 8) |
136 | #define MNT_fhstatus3_sz (1 + 16) | ||
136 | 137 | ||
137 | static struct rpc_procinfo mnt_procedures[] = { | 138 | static struct rpc_procinfo mnt_procedures[] = { |
138 | [MNTPROC_MNT] = { | 139 | [MNTPROC_MNT] = { |
139 | .p_proc = MNTPROC_MNT, | 140 | .p_proc = MNTPROC_MNT, |
140 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, | 141 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, |
141 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus, | 142 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus, |
142 | .p_bufsiz = MNT_dirpath_sz << 2, | 143 | .p_arglen = MNT_dirpath_sz, |
144 | .p_replen = MNT_fhstatus_sz, | ||
143 | .p_statidx = MNTPROC_MNT, | 145 | .p_statidx = MNTPROC_MNT, |
144 | .p_name = "MOUNT", | 146 | .p_name = "MOUNT", |
145 | }, | 147 | }, |
@@ -150,7 +152,8 @@ static struct rpc_procinfo mnt3_procedures[] = { | |||
150 | .p_proc = MOUNTPROC3_MNT, | 152 | .p_proc = MOUNTPROC3_MNT, |
151 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, | 153 | .p_encode = (kxdrproc_t) xdr_encode_dirpath, |
152 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, | 154 | .p_decode = (kxdrproc_t) xdr_decode_fhstatus3, |
153 | .p_bufsiz = MNT_dirpath_sz << 2, | 155 | .p_arglen = MNT_dirpath_sz, |
156 | .p_replen = MNT_fhstatus3_sz, | ||
154 | .p_statidx = MOUNTPROC3_MNT, | 157 | .p_statidx = MOUNTPROC3_MNT, |
155 | .p_name = "MOUNT", | 158 | .p_name = "MOUNT", |
156 | }, | 159 | }, |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 3be4e72a0227..abd9f8b48943 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -687,16 +687,13 @@ nfs_stat_to_errno(int stat) | |||
687 | return nfs_errtbl[i].errno; | 687 | return nfs_errtbl[i].errno; |
688 | } | 688 | } |
689 | 689 | ||
690 | #ifndef MAX | ||
691 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
692 | #endif | ||
693 | |||
694 | #define PROC(proc, argtype, restype, timer) \ | 690 | #define PROC(proc, argtype, restype, timer) \ |
695 | [NFSPROC_##proc] = { \ | 691 | [NFSPROC_##proc] = { \ |
696 | .p_proc = NFSPROC_##proc, \ | 692 | .p_proc = NFSPROC_##proc, \ |
697 | .p_encode = (kxdrproc_t) nfs_xdr_##argtype, \ | 693 | .p_encode = (kxdrproc_t) nfs_xdr_##argtype, \ |
698 | .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ | 694 | .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ |
699 | .p_bufsiz = MAX(NFS_##argtype##_sz,NFS_##restype##_sz) << 2, \ | 695 | .p_arglen = NFS_##argtype##_sz, \ |
696 | .p_replen = NFS_##restype##_sz, \ | ||
700 | .p_timer = timer, \ | 697 | .p_timer = timer, \ |
701 | .p_statidx = NFSPROC_##proc, \ | 698 | .p_statidx = NFSPROC_##proc, \ |
702 | .p_name = #proc, \ | 699 | .p_name = #proc, \ |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 0ace092d126f..b51df8eb9f01 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -1102,16 +1102,13 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) | |||
1102 | } | 1102 | } |
1103 | #endif /* CONFIG_NFS_V3_ACL */ | 1103 | #endif /* CONFIG_NFS_V3_ACL */ |
1104 | 1104 | ||
1105 | #ifndef MAX | ||
1106 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
1107 | #endif | ||
1108 | |||
1109 | #define PROC(proc, argtype, restype, timer) \ | 1105 | #define PROC(proc, argtype, restype, timer) \ |
1110 | [NFS3PROC_##proc] = { \ | 1106 | [NFS3PROC_##proc] = { \ |
1111 | .p_proc = NFS3PROC_##proc, \ | 1107 | .p_proc = NFS3PROC_##proc, \ |
1112 | .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \ | 1108 | .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \ |
1113 | .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \ | 1109 | .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \ |
1114 | .p_bufsiz = MAX(NFS3_##argtype##_sz,NFS3_##restype##_sz) << 2, \ | 1110 | .p_arglen = NFS3_##argtype##_sz, \ |
1111 | .p_replen = NFS3_##restype##_sz, \ | ||
1115 | .p_timer = timer, \ | 1112 | .p_timer = timer, \ |
1116 | .p_statidx = NFS3PROC_##proc, \ | 1113 | .p_statidx = NFS3PROC_##proc, \ |
1117 | .p_name = #proc, \ | 1114 | .p_name = #proc, \ |
@@ -1153,7 +1150,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { | |||
1153 | .p_proc = ACLPROC3_GETACL, | 1150 | .p_proc = ACLPROC3_GETACL, |
1154 | .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs, | 1151 | .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs, |
1155 | .p_decode = (kxdrproc_t) nfs3_xdr_getaclres, | 1152 | .p_decode = (kxdrproc_t) nfs3_xdr_getaclres, |
1156 | .p_bufsiz = MAX(ACL3_getaclargs_sz, ACL3_getaclres_sz) << 2, | 1153 | .p_arglen = ACL3_getaclargs_sz, |
1154 | .p_replen = ACL3_getaclres_sz, | ||
1157 | .p_timer = 1, | 1155 | .p_timer = 1, |
1158 | .p_name = "GETACL", | 1156 | .p_name = "GETACL", |
1159 | }, | 1157 | }, |
@@ -1161,7 +1159,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { | |||
1161 | .p_proc = ACLPROC3_SETACL, | 1159 | .p_proc = ACLPROC3_SETACL, |
1162 | .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs, | 1160 | .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs, |
1163 | .p_decode = (kxdrproc_t) nfs3_xdr_setaclres, | 1161 | .p_decode = (kxdrproc_t) nfs3_xdr_setaclres, |
1164 | .p_bufsiz = MAX(ACL3_setaclargs_sz, ACL3_setaclres_sz) << 2, | 1162 | .p_arglen = ACL3_setaclargs_sz, |
1163 | .p_replen = ACL3_setaclres_sz, | ||
1165 | .p_timer = 0, | 1164 | .p_timer = 0, |
1166 | .p_name = "SETACL", | 1165 | .p_name = "SETACL", |
1167 | }, | 1166 | }, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index f52cf5c33c6c..3b5ca1b15fe9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2647,8 +2647,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl | |||
2647 | nfs_inode_return_delegation(inode); | 2647 | nfs_inode_return_delegation(inode); |
2648 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 2648 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
2649 | ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 2649 | ret = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
2650 | if (ret == 0) | 2650 | nfs_zap_caches(inode); |
2651 | nfs4_write_cached_acl(inode, buf, buflen); | ||
2652 | return ret; | 2651 | return ret; |
2653 | } | 2652 | } |
2654 | 2653 | ||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f02d522fd788..b8c28f2380a5 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -4546,16 +4546,13 @@ nfs4_stat_to_errno(int stat) | |||
4546 | return stat; | 4546 | return stat; |
4547 | } | 4547 | } |
4548 | 4548 | ||
4549 | #ifndef MAX | ||
4550 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
4551 | #endif | ||
4552 | |||
4553 | #define PROC(proc, argtype, restype) \ | 4549 | #define PROC(proc, argtype, restype) \ |
4554 | [NFSPROC4_CLNT_##proc] = { \ | 4550 | [NFSPROC4_CLNT_##proc] = { \ |
4555 | .p_proc = NFSPROC4_COMPOUND, \ | 4551 | .p_proc = NFSPROC4_COMPOUND, \ |
4556 | .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ | 4552 | .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ |
4557 | .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ | 4553 | .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ |
4558 | .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \ | 4554 | .p_arglen = NFS4_##argtype##_sz, \ |
4555 | .p_replen = NFS4_##restype##_sz, \ | ||
4559 | .p_statidx = NFSPROC4_CLNT_##proc, \ | 4556 | .p_statidx = NFSPROC4_CLNT_##proc, \ |
4560 | .p_name = #proc, \ | 4557 | .p_name = #proc, \ |
4561 | } | 4558 | } |
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 75f819dc0255..49d1008ce1d7 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -428,7 +428,7 @@ static int __init root_nfs_getport(int program, int version, int proto) | |||
428 | printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n", | 428 | printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n", |
429 | program, version, NIPQUAD(servaddr)); | 429 | program, version, NIPQUAD(servaddr)); |
430 | set_sockaddr(&sin, servaddr, 0); | 430 | set_sockaddr(&sin, servaddr, 0); |
431 | return rpc_getport_external(&sin, program, version, proto); | 431 | return rpcb_getport_external(&sin, program, version, proto); |
432 | } | 432 | } |
433 | 433 | ||
434 | 434 | ||
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index ca4b1d4ff42b..388950118f59 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -17,7 +17,8 @@ | |||
17 | #include <linux/nfs_page.h> | 17 | #include <linux/nfs_page.h> |
18 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
19 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
20 | #include <linux/writeback.h> | 20 | |
21 | #include "internal.h" | ||
21 | 22 | ||
22 | #define NFS_PARANOIA 1 | 23 | #define NFS_PARANOIA 1 |
23 | 24 | ||
@@ -50,9 +51,7 @@ nfs_page_free(struct nfs_page *p) | |||
50 | * @count: number of bytes to read/write | 51 | * @count: number of bytes to read/write |
51 | * | 52 | * |
52 | * The page must be locked by the caller. This makes sure we never | 53 | * The page must be locked by the caller. This makes sure we never |
53 | * create two different requests for the same page, and avoids | 54 | * create two different requests for the same page. |
54 | * a possible deadlock when we reach the hard limit on the number | ||
55 | * of dirty pages. | ||
56 | * User should ensure it is safe to sleep in this function. | 55 | * User should ensure it is safe to sleep in this function. |
57 | */ | 56 | */ |
58 | struct nfs_page * | 57 | struct nfs_page * |
@@ -63,16 +62,12 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode, | |||
63 | struct nfs_server *server = NFS_SERVER(inode); | 62 | struct nfs_server *server = NFS_SERVER(inode); |
64 | struct nfs_page *req; | 63 | struct nfs_page *req; |
65 | 64 | ||
66 | /* Deal with hard limits. */ | ||
67 | for (;;) { | 65 | for (;;) { |
68 | /* try to allocate the request struct */ | 66 | /* try to allocate the request struct */ |
69 | req = nfs_page_alloc(); | 67 | req = nfs_page_alloc(); |
70 | if (req != NULL) | 68 | if (req != NULL) |
71 | break; | 69 | break; |
72 | 70 | ||
73 | /* Try to free up at least one request in order to stay | ||
74 | * below the hard limit | ||
75 | */ | ||
76 | if (signalled() && (server->flags & NFS_MOUNT_INTR)) | 71 | if (signalled() && (server->flags & NFS_MOUNT_INTR)) |
77 | return ERR_PTR(-ERESTARTSYS); | 72 | return ERR_PTR(-ERESTARTSYS); |
78 | yield(); | 73 | yield(); |
@@ -223,124 +218,151 @@ out: | |||
223 | } | 218 | } |
224 | 219 | ||
225 | /** | 220 | /** |
226 | * nfs_coalesce_requests - Split coalesced requests out from a list. | 221 | * nfs_pageio_init - initialise a page io descriptor |
227 | * @head: source list | 222 | * @desc: pointer to descriptor |
228 | * @dst: destination list | 223 | * @inode: pointer to inode |
229 | * @nmax: maximum number of requests to coalesce | 224 | * @doio: pointer to io function |
230 | * | 225 | * @bsize: io block size |
231 | * Moves a maximum of 'nmax' elements from one list to another. | 226 | * @io_flags: extra parameters for the io function |
232 | * The elements are checked to ensure that they form a contiguous set | ||
233 | * of pages, and that the RPC credentials are the same. | ||
234 | */ | 227 | */ |
235 | int | 228 | void nfs_pageio_init(struct nfs_pageio_descriptor *desc, |
236 | nfs_coalesce_requests(struct list_head *head, struct list_head *dst, | 229 | struct inode *inode, |
237 | unsigned int nmax) | 230 | int (*doio)(struct inode *, struct list_head *, unsigned int, size_t, int), |
231 | size_t bsize, | ||
232 | int io_flags) | ||
238 | { | 233 | { |
239 | struct nfs_page *req = NULL; | 234 | INIT_LIST_HEAD(&desc->pg_list); |
240 | unsigned int npages = 0; | 235 | desc->pg_bytes_written = 0; |
241 | 236 | desc->pg_count = 0; | |
242 | while (!list_empty(head)) { | 237 | desc->pg_bsize = bsize; |
243 | struct nfs_page *prev = req; | 238 | desc->pg_base = 0; |
244 | 239 | desc->pg_inode = inode; | |
245 | req = nfs_list_entry(head->next); | 240 | desc->pg_doio = doio; |
246 | if (prev) { | 241 | desc->pg_ioflags = io_flags; |
247 | if (req->wb_context->cred != prev->wb_context->cred) | 242 | desc->pg_error = 0; |
248 | break; | ||
249 | if (req->wb_context->lockowner != prev->wb_context->lockowner) | ||
250 | break; | ||
251 | if (req->wb_context->state != prev->wb_context->state) | ||
252 | break; | ||
253 | if (req->wb_index != (prev->wb_index + 1)) | ||
254 | break; | ||
255 | |||
256 | if (req->wb_pgbase != 0) | ||
257 | break; | ||
258 | } | ||
259 | nfs_list_remove_request(req); | ||
260 | nfs_list_add_request(req, dst); | ||
261 | npages++; | ||
262 | if (req->wb_pgbase + req->wb_bytes != PAGE_CACHE_SIZE) | ||
263 | break; | ||
264 | if (npages >= nmax) | ||
265 | break; | ||
266 | } | ||
267 | return npages; | ||
268 | } | 243 | } |
269 | 244 | ||
270 | #define NFS_SCAN_MAXENTRIES 16 | ||
271 | /** | 245 | /** |
272 | * nfs_scan_dirty - Scan the radix tree for dirty requests | 246 | * nfs_can_coalesce_requests - test two requests for compatibility |
273 | * @mapping: pointer to address space | 247 | * @prev: pointer to nfs_page |
274 | * @wbc: writeback_control structure | 248 | * @req: pointer to nfs_page |
275 | * @dst: Destination list | ||
276 | * | 249 | * |
277 | * Moves elements from one of the inode request lists. | 250 | * The nfs_page structures 'prev' and 'req' are compared to ensure that the |
278 | * If the number of requests is set to 0, the entire address_space | 251 | * page data area they describe is contiguous, and that their RPC |
279 | * starting at index idx_start, is scanned. | 252 | * credentials, NFSv4 open state, and lockowners are the same. |
280 | * The requests are *not* checked to ensure that they form a contiguous set. | 253 | * |
281 | * You must be holding the inode's req_lock when calling this function | 254 | * Return 'true' if this is the case, else return 'false'. |
282 | */ | 255 | */ |
283 | long nfs_scan_dirty(struct address_space *mapping, | 256 | static int nfs_can_coalesce_requests(struct nfs_page *prev, |
284 | struct writeback_control *wbc, | 257 | struct nfs_page *req) |
285 | struct list_head *dst) | ||
286 | { | 258 | { |
287 | struct nfs_inode *nfsi = NFS_I(mapping->host); | 259 | if (req->wb_context->cred != prev->wb_context->cred) |
288 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; | ||
289 | struct nfs_page *req; | ||
290 | pgoff_t idx_start, idx_end; | ||
291 | long res = 0; | ||
292 | int found, i; | ||
293 | |||
294 | if (nfsi->ndirty == 0) | ||
295 | return 0; | 260 | return 0; |
296 | if (wbc->range_cyclic) { | 261 | if (req->wb_context->lockowner != prev->wb_context->lockowner) |
297 | idx_start = 0; | 262 | return 0; |
298 | idx_end = ULONG_MAX; | 263 | if (req->wb_context->state != prev->wb_context->state) |
299 | } else if (wbc->range_end == 0) { | 264 | return 0; |
300 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | 265 | if (req->wb_index != (prev->wb_index + 1)) |
301 | idx_end = ULONG_MAX; | 266 | return 0; |
302 | } else { | 267 | if (req->wb_pgbase != 0) |
303 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | 268 | return 0; |
304 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | 269 | if (prev->wb_pgbase + prev->wb_bytes != PAGE_CACHE_SIZE) |
305 | } | 270 | return 0; |
271 | return 1; | ||
272 | } | ||
306 | 273 | ||
307 | for (;;) { | 274 | /** |
308 | unsigned int toscan = NFS_SCAN_MAXENTRIES; | 275 | * nfs_pageio_do_add_request - Attempt to coalesce a request into a page list. |
276 | * @desc: destination io descriptor | ||
277 | * @req: request | ||
278 | * | ||
279 | * Returns true if the request 'req' was successfully coalesced into the | ||
280 | * existing list of pages 'desc'. | ||
281 | */ | ||
282 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | ||
283 | struct nfs_page *req) | ||
284 | { | ||
285 | size_t newlen = req->wb_bytes; | ||
309 | 286 | ||
310 | found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, | 287 | if (desc->pg_count != 0) { |
311 | (void **)&pgvec[0], idx_start, toscan, | 288 | struct nfs_page *prev; |
312 | NFS_PAGE_TAG_DIRTY); | ||
313 | 289 | ||
314 | /* Did we make progress? */ | 290 | /* |
315 | if (found <= 0) | 291 | * FIXME: ideally we should be able to coalesce all requests |
316 | break; | 292 | * that are not block boundary aligned, but currently this |
293 | * is problematic for the case of bsize < PAGE_CACHE_SIZE, | ||
294 | * since nfs_flush_multi and nfs_pagein_multi assume you | ||
295 | * can have only one struct nfs_page. | ||
296 | */ | ||
297 | if (desc->pg_bsize < PAGE_SIZE) | ||
298 | return 0; | ||
299 | newlen += desc->pg_count; | ||
300 | if (newlen > desc->pg_bsize) | ||
301 | return 0; | ||
302 | prev = nfs_list_entry(desc->pg_list.prev); | ||
303 | if (!nfs_can_coalesce_requests(prev, req)) | ||
304 | return 0; | ||
305 | } else | ||
306 | desc->pg_base = req->wb_pgbase; | ||
307 | nfs_list_remove_request(req); | ||
308 | nfs_list_add_request(req, &desc->pg_list); | ||
309 | desc->pg_count = newlen; | ||
310 | return 1; | ||
311 | } | ||
317 | 312 | ||
318 | for (i = 0; i < found; i++) { | 313 | /* |
319 | req = pgvec[i]; | 314 | * Helper for nfs_pageio_add_request and nfs_pageio_complete |
320 | if (!wbc->range_cyclic && req->wb_index > idx_end) | 315 | */ |
321 | goto out; | 316 | static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) |
317 | { | ||
318 | if (!list_empty(&desc->pg_list)) { | ||
319 | int error = desc->pg_doio(desc->pg_inode, | ||
320 | &desc->pg_list, | ||
321 | nfs_page_array_len(desc->pg_base, | ||
322 | desc->pg_count), | ||
323 | desc->pg_count, | ||
324 | desc->pg_ioflags); | ||
325 | if (error < 0) | ||
326 | desc->pg_error = error; | ||
327 | else | ||
328 | desc->pg_bytes_written += desc->pg_count; | ||
329 | } | ||
330 | if (list_empty(&desc->pg_list)) { | ||
331 | desc->pg_count = 0; | ||
332 | desc->pg_base = 0; | ||
333 | } | ||
334 | } | ||
322 | 335 | ||
323 | /* Try to lock request and mark it for writeback */ | 336 | /** |
324 | if (!nfs_set_page_writeback_locked(req)) | 337 | * nfs_pageio_add_request - Attempt to coalesce a request into a page list. |
325 | goto next; | 338 | * @desc: destination io descriptor |
326 | radix_tree_tag_clear(&nfsi->nfs_page_tree, | 339 | * @req: request |
327 | req->wb_index, NFS_PAGE_TAG_DIRTY); | 340 | * |
328 | nfsi->ndirty--; | 341 | * Returns true if the request 'req' was successfully coalesced into the |
329 | nfs_list_remove_request(req); | 342 | * existing list of pages 'desc'. |
330 | nfs_list_add_request(req, dst); | 343 | */ |
331 | res++; | 344 | int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, |
332 | if (res == LONG_MAX) | 345 | struct nfs_page *req) |
333 | goto out; | 346 | { |
334 | next: | 347 | while (!nfs_pageio_do_add_request(desc, req)) { |
335 | idx_start = req->wb_index + 1; | 348 | nfs_pageio_doio(desc); |
336 | } | 349 | if (desc->pg_error < 0) |
350 | return 0; | ||
337 | } | 351 | } |
338 | out: | 352 | return 1; |
339 | WARN_ON ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)); | ||
340 | return res; | ||
341 | } | 353 | } |
342 | 354 | ||
343 | /** | 355 | /** |
356 | * nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor | ||
357 | * @desc: pointer to io descriptor | ||
358 | */ | ||
359 | void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) | ||
360 | { | ||
361 | nfs_pageio_doio(desc); | ||
362 | } | ||
363 | |||
364 | #define NFS_SCAN_MAXENTRIES 16 | ||
365 | /** | ||
344 | * nfs_scan_list - Scan a list for matching requests | 366 | * nfs_scan_list - Scan a list for matching requests |
345 | * @nfsi: NFS inode | 367 | * @nfsi: NFS inode |
346 | * @head: One of the NFS inode request lists | 368 | * @head: One of the NFS inode request lists |
@@ -355,12 +377,12 @@ out: | |||
355 | * You must be holding the inode's req_lock when calling this function | 377 | * You must be holding the inode's req_lock when calling this function |
356 | */ | 378 | */ |
357 | int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, | 379 | int nfs_scan_list(struct nfs_inode *nfsi, struct list_head *head, |
358 | struct list_head *dst, unsigned long idx_start, | 380 | struct list_head *dst, pgoff_t idx_start, |
359 | unsigned int npages) | 381 | unsigned int npages) |
360 | { | 382 | { |
361 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; | 383 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; |
362 | struct nfs_page *req; | 384 | struct nfs_page *req; |
363 | unsigned long idx_end; | 385 | pgoff_t idx_end; |
364 | int found, i; | 386 | int found, i; |
365 | int res; | 387 | int res; |
366 | 388 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6ab4d5a9edf2..9a55807b2a70 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -27,7 +27,8 @@ | |||
27 | 27 | ||
28 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 28 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
29 | 29 | ||
30 | static int nfs_pagein_one(struct list_head *, struct inode *); | 30 | static int nfs_pagein_multi(struct inode *, struct list_head *, unsigned int, size_t, int); |
31 | static int nfs_pagein_one(struct inode *, struct list_head *, unsigned int, size_t, int); | ||
31 | static const struct rpc_call_ops nfs_read_partial_ops; | 32 | static const struct rpc_call_ops nfs_read_partial_ops; |
32 | static const struct rpc_call_ops nfs_read_full_ops; | 33 | static const struct rpc_call_ops nfs_read_full_ops; |
33 | 34 | ||
@@ -36,9 +37,8 @@ static mempool_t *nfs_rdata_mempool; | |||
36 | 37 | ||
37 | #define MIN_POOL_READ (32) | 38 | #define MIN_POOL_READ (32) |
38 | 39 | ||
39 | struct nfs_read_data *nfs_readdata_alloc(size_t len) | 40 | struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) |
40 | { | 41 | { |
41 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
42 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS); | 42 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS); |
43 | 43 | ||
44 | if (p) { | 44 | if (p) { |
@@ -133,7 +133,10 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
133 | memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); | 133 | memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); |
134 | 134 | ||
135 | nfs_list_add_request(new, &one_request); | 135 | nfs_list_add_request(new, &one_request); |
136 | nfs_pagein_one(&one_request, inode); | 136 | if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) |
137 | nfs_pagein_multi(inode, &one_request, 1, len, 0); | ||
138 | else | ||
139 | nfs_pagein_one(inode, &one_request, 1, len, 0); | ||
137 | return 0; | 140 | return 0; |
138 | } | 141 | } |
139 | 142 | ||
@@ -230,7 +233,7 @@ static void nfs_execute_read(struct nfs_read_data *data) | |||
230 | * won't see the new data until our attribute cache is updated. This is more | 233 | * won't see the new data until our attribute cache is updated. This is more |
231 | * or less conventional NFS client behavior. | 234 | * or less conventional NFS client behavior. |
232 | */ | 235 | */ |
233 | static int nfs_pagein_multi(struct list_head *head, struct inode *inode) | 236 | static int nfs_pagein_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) |
234 | { | 237 | { |
235 | struct nfs_page *req = nfs_list_entry(head->next); | 238 | struct nfs_page *req = nfs_list_entry(head->next); |
236 | struct page *page = req->wb_page; | 239 | struct page *page = req->wb_page; |
@@ -242,11 +245,11 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode) | |||
242 | 245 | ||
243 | nfs_list_remove_request(req); | 246 | nfs_list_remove_request(req); |
244 | 247 | ||
245 | nbytes = req->wb_bytes; | 248 | nbytes = count; |
246 | do { | 249 | do { |
247 | size_t len = min(nbytes,rsize); | 250 | size_t len = min(nbytes,rsize); |
248 | 251 | ||
249 | data = nfs_readdata_alloc(len); | 252 | data = nfs_readdata_alloc(1); |
250 | if (!data) | 253 | if (!data) |
251 | goto out_bad; | 254 | goto out_bad; |
252 | INIT_LIST_HEAD(&data->pages); | 255 | INIT_LIST_HEAD(&data->pages); |
@@ -258,23 +261,19 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode) | |||
258 | 261 | ||
259 | ClearPageError(page); | 262 | ClearPageError(page); |
260 | offset = 0; | 263 | offset = 0; |
261 | nbytes = req->wb_bytes; | 264 | nbytes = count; |
262 | do { | 265 | do { |
263 | data = list_entry(list.next, struct nfs_read_data, pages); | 266 | data = list_entry(list.next, struct nfs_read_data, pages); |
264 | list_del_init(&data->pages); | 267 | list_del_init(&data->pages); |
265 | 268 | ||
266 | data->pagevec[0] = page; | 269 | data->pagevec[0] = page; |
267 | 270 | ||
268 | if (nbytes > rsize) { | 271 | if (nbytes < rsize) |
269 | nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, | 272 | rsize = nbytes; |
270 | rsize, offset); | 273 | nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, |
271 | offset += rsize; | 274 | rsize, offset); |
272 | nbytes -= rsize; | 275 | offset += rsize; |
273 | } else { | 276 | nbytes -= rsize; |
274 | nfs_read_rpcsetup(req, data, &nfs_read_partial_ops, | ||
275 | nbytes, offset); | ||
276 | nbytes = 0; | ||
277 | } | ||
278 | nfs_execute_read(data); | 277 | nfs_execute_read(data); |
279 | } while (nbytes != 0); | 278 | } while (nbytes != 0); |
280 | 279 | ||
@@ -291,30 +290,24 @@ out_bad: | |||
291 | return -ENOMEM; | 290 | return -ENOMEM; |
292 | } | 291 | } |
293 | 292 | ||
294 | static int nfs_pagein_one(struct list_head *head, struct inode *inode) | 293 | static int nfs_pagein_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int flags) |
295 | { | 294 | { |
296 | struct nfs_page *req; | 295 | struct nfs_page *req; |
297 | struct page **pages; | 296 | struct page **pages; |
298 | struct nfs_read_data *data; | 297 | struct nfs_read_data *data; |
299 | unsigned int count; | ||
300 | 298 | ||
301 | if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE) | 299 | data = nfs_readdata_alloc(npages); |
302 | return nfs_pagein_multi(head, inode); | ||
303 | |||
304 | data = nfs_readdata_alloc(NFS_SERVER(inode)->rsize); | ||
305 | if (!data) | 300 | if (!data) |
306 | goto out_bad; | 301 | goto out_bad; |
307 | 302 | ||
308 | INIT_LIST_HEAD(&data->pages); | 303 | INIT_LIST_HEAD(&data->pages); |
309 | pages = data->pagevec; | 304 | pages = data->pagevec; |
310 | count = 0; | ||
311 | while (!list_empty(head)) { | 305 | while (!list_empty(head)) { |
312 | req = nfs_list_entry(head->next); | 306 | req = nfs_list_entry(head->next); |
313 | nfs_list_remove_request(req); | 307 | nfs_list_remove_request(req); |
314 | nfs_list_add_request(req, &data->pages); | 308 | nfs_list_add_request(req, &data->pages); |
315 | ClearPageError(req->wb_page); | 309 | ClearPageError(req->wb_page); |
316 | *pages++ = req->wb_page; | 310 | *pages++ = req->wb_page; |
317 | count += req->wb_bytes; | ||
318 | } | 311 | } |
319 | req = nfs_list_entry(data->pages.next); | 312 | req = nfs_list_entry(data->pages.next); |
320 | 313 | ||
@@ -327,28 +320,6 @@ out_bad: | |||
327 | return -ENOMEM; | 320 | return -ENOMEM; |
328 | } | 321 | } |
329 | 322 | ||
330 | static int | ||
331 | nfs_pagein_list(struct list_head *head, int rpages) | ||
332 | { | ||
333 | LIST_HEAD(one_request); | ||
334 | struct nfs_page *req; | ||
335 | int error = 0; | ||
336 | unsigned int pages = 0; | ||
337 | |||
338 | while (!list_empty(head)) { | ||
339 | pages += nfs_coalesce_requests(head, &one_request, rpages); | ||
340 | req = nfs_list_entry(one_request.next); | ||
341 | error = nfs_pagein_one(&one_request, req->wb_context->dentry->d_inode); | ||
342 | if (error < 0) | ||
343 | break; | ||
344 | } | ||
345 | if (error >= 0) | ||
346 | return pages; | ||
347 | |||
348 | nfs_async_read_error(head); | ||
349 | return error; | ||
350 | } | ||
351 | |||
352 | /* | 323 | /* |
353 | * This is the callback from RPC telling us whether a reply was | 324 | * This is the callback from RPC telling us whether a reply was |
354 | * received or some error occurred (timeout or socket shutdown). | 325 | * received or some error occurred (timeout or socket shutdown). |
@@ -538,7 +509,7 @@ out_error: | |||
538 | } | 509 | } |
539 | 510 | ||
540 | struct nfs_readdesc { | 511 | struct nfs_readdesc { |
541 | struct list_head *head; | 512 | struct nfs_pageio_descriptor *pgio; |
542 | struct nfs_open_context *ctx; | 513 | struct nfs_open_context *ctx; |
543 | }; | 514 | }; |
544 | 515 | ||
@@ -562,19 +533,21 @@ readpage_async_filler(void *data, struct page *page) | |||
562 | } | 533 | } |
563 | if (len < PAGE_CACHE_SIZE) | 534 | if (len < PAGE_CACHE_SIZE) |
564 | memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); | 535 | memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len); |
565 | nfs_list_add_request(new, desc->head); | 536 | nfs_pageio_add_request(desc->pgio, new); |
566 | return 0; | 537 | return 0; |
567 | } | 538 | } |
568 | 539 | ||
569 | int nfs_readpages(struct file *filp, struct address_space *mapping, | 540 | int nfs_readpages(struct file *filp, struct address_space *mapping, |
570 | struct list_head *pages, unsigned nr_pages) | 541 | struct list_head *pages, unsigned nr_pages) |
571 | { | 542 | { |
572 | LIST_HEAD(head); | 543 | struct nfs_pageio_descriptor pgio; |
573 | struct nfs_readdesc desc = { | 544 | struct nfs_readdesc desc = { |
574 | .head = &head, | 545 | .pgio = &pgio, |
575 | }; | 546 | }; |
576 | struct inode *inode = mapping->host; | 547 | struct inode *inode = mapping->host; |
577 | struct nfs_server *server = NFS_SERVER(inode); | 548 | struct nfs_server *server = NFS_SERVER(inode); |
549 | size_t rsize = server->rsize; | ||
550 | unsigned long npages; | ||
578 | int ret = -ESTALE; | 551 | int ret = -ESTALE; |
579 | 552 | ||
580 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", | 553 | dprintk("NFS: nfs_readpages (%s/%Ld %d)\n", |
@@ -593,13 +566,16 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
593 | } else | 566 | } else |
594 | desc.ctx = get_nfs_open_context((struct nfs_open_context *) | 567 | desc.ctx = get_nfs_open_context((struct nfs_open_context *) |
595 | filp->private_data); | 568 | filp->private_data); |
569 | if (rsize < PAGE_CACHE_SIZE) | ||
570 | nfs_pageio_init(&pgio, inode, nfs_pagein_multi, rsize, 0); | ||
571 | else | ||
572 | nfs_pageio_init(&pgio, inode, nfs_pagein_one, rsize, 0); | ||
573 | |||
596 | ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); | 574 | ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); |
597 | if (!list_empty(&head)) { | 575 | |
598 | int err = nfs_pagein_list(&head, server->rpages); | 576 | nfs_pageio_complete(&pgio); |
599 | if (!ret) | 577 | npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
600 | nfs_add_stats(inode, NFSIOS_READPAGES, err); | 578 | nfs_add_stats(inode, NFSIOS_READPAGES, npages); |
601 | ret = err; | ||
602 | } | ||
603 | put_nfs_open_context(desc.ctx); | 579 | put_nfs_open_context(desc.ctx); |
604 | out: | 580 | out: |
605 | return ret; | 581 | return ret; |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f1eae44b9a1a..ca20d3cc2609 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -204,9 +204,9 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
204 | lock_kernel(); | 204 | lock_kernel(); |
205 | 205 | ||
206 | error = server->nfs_client->rpc_ops->statfs(server, fh, &res); | 206 | error = server->nfs_client->rpc_ops->statfs(server, fh, &res); |
207 | buf->f_type = NFS_SUPER_MAGIC; | ||
208 | if (error < 0) | 207 | if (error < 0) |
209 | goto out_err; | 208 | goto out_err; |
209 | buf->f_type = NFS_SUPER_MAGIC; | ||
210 | 210 | ||
211 | /* | 211 | /* |
212 | * Current versions of glibc do not correctly handle the | 212 | * Current versions of glibc do not correctly handle the |
@@ -233,15 +233,14 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
233 | buf->f_ffree = res.afiles; | 233 | buf->f_ffree = res.afiles; |
234 | 234 | ||
235 | buf->f_namelen = server->namelen; | 235 | buf->f_namelen = server->namelen; |
236 | out: | 236 | |
237 | unlock_kernel(); | 237 | unlock_kernel(); |
238 | return 0; | 238 | return 0; |
239 | 239 | ||
240 | out_err: | 240 | out_err: |
241 | dprintk("%s: statfs error = %d\n", __FUNCTION__, -error); | 241 | dprintk("%s: statfs error = %d\n", __FUNCTION__, -error); |
242 | buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; | 242 | unlock_kernel(); |
243 | goto out; | 243 | return error; |
244 | |||
245 | } | 244 | } |
246 | 245 | ||
247 | /* | 246 | /* |
@@ -291,6 +290,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
291 | { NFS_MOUNT_NOAC, ",noac", "" }, | 290 | { NFS_MOUNT_NOAC, ",noac", "" }, |
292 | { NFS_MOUNT_NONLM, ",nolock", "" }, | 291 | { NFS_MOUNT_NONLM, ",nolock", "" }, |
293 | { NFS_MOUNT_NOACL, ",noacl", "" }, | 292 | { NFS_MOUNT_NOACL, ",noacl", "" }, |
293 | { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" }, | ||
294 | { 0, NULL, NULL } | 294 | { 0, NULL, NULL } |
295 | }; | 295 | }; |
296 | const struct proc_nfs_info *nfs_infop; | 296 | const struct proc_nfs_info *nfs_infop; |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index f4a0548b9ce8..bc2821331c29 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -61,15 +61,9 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
61 | err = page; | 61 | err = page; |
62 | goto read_failed; | 62 | goto read_failed; |
63 | } | 63 | } |
64 | if (!PageUptodate(page)) { | ||
65 | err = ERR_PTR(-EIO); | ||
66 | goto getlink_read_error; | ||
67 | } | ||
68 | nd_set_link(nd, kmap(page)); | 64 | nd_set_link(nd, kmap(page)); |
69 | return page; | 65 | return page; |
70 | 66 | ||
71 | getlink_read_error: | ||
72 | page_cache_release(page); | ||
73 | read_failed: | 67 | read_failed: |
74 | nd_set_link(nd, err); | 68 | nd_set_link(nd, err); |
75 | return NULL; | 69 | return NULL; |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 797558941745..5d44b8bd1070 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -38,7 +38,8 @@ | |||
38 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, | 38 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, |
39 | struct page *, | 39 | struct page *, |
40 | unsigned int, unsigned int); | 40 | unsigned int, unsigned int); |
41 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); | 41 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *desc, |
42 | struct inode *inode, int ioflags); | ||
42 | static const struct rpc_call_ops nfs_write_partial_ops; | 43 | static const struct rpc_call_ops nfs_write_partial_ops; |
43 | static const struct rpc_call_ops nfs_write_full_ops; | 44 | static const struct rpc_call_ops nfs_write_full_ops; |
44 | static const struct rpc_call_ops nfs_commit_ops; | 45 | static const struct rpc_call_ops nfs_commit_ops; |
@@ -71,9 +72,8 @@ void nfs_commit_free(struct nfs_write_data *wdata) | |||
71 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | 72 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); |
72 | } | 73 | } |
73 | 74 | ||
74 | struct nfs_write_data *nfs_writedata_alloc(size_t len) | 75 | struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) |
75 | { | 76 | { |
76 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
77 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); | 77 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
78 | 78 | ||
79 | if (p) { | 79 | if (p) { |
@@ -139,7 +139,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c | |||
139 | { | 139 | { |
140 | struct inode *inode = page->mapping->host; | 140 | struct inode *inode = page->mapping->host; |
141 | loff_t end, i_size = i_size_read(inode); | 141 | loff_t end, i_size = i_size_read(inode); |
142 | unsigned long end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; | 142 | pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; |
143 | 143 | ||
144 | if (i_size > 0 && page->index < end_index) | 144 | if (i_size > 0 && page->index < end_index) |
145 | return; | 145 | return; |
@@ -201,7 +201,7 @@ static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, | |||
201 | static int wb_priority(struct writeback_control *wbc) | 201 | static int wb_priority(struct writeback_control *wbc) |
202 | { | 202 | { |
203 | if (wbc->for_reclaim) | 203 | if (wbc->for_reclaim) |
204 | return FLUSH_HIGHPRI; | 204 | return FLUSH_HIGHPRI | FLUSH_STABLE; |
205 | if (wbc->for_kupdate) | 205 | if (wbc->for_kupdate) |
206 | return FLUSH_LOWPRI; | 206 | return FLUSH_LOWPRI; |
207 | return 0; | 207 | return 0; |
@@ -251,7 +251,8 @@ static void nfs_end_page_writeback(struct page *page) | |||
251 | * was not tagged. | 251 | * was not tagged. |
252 | * May also return an error if the user signalled nfs_wait_on_request(). | 252 | * May also return an error if the user signalled nfs_wait_on_request(). |
253 | */ | 253 | */ |
254 | static int nfs_page_mark_flush(struct page *page) | 254 | static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, |
255 | struct page *page) | ||
255 | { | 256 | { |
256 | struct nfs_page *req; | 257 | struct nfs_page *req; |
257 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); | 258 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); |
@@ -273,6 +274,8 @@ static int nfs_page_mark_flush(struct page *page) | |||
273 | * request as dirty (in which case we don't care). | 274 | * request as dirty (in which case we don't care). |
274 | */ | 275 | */ |
275 | spin_unlock(req_lock); | 276 | spin_unlock(req_lock); |
277 | /* Prevent deadlock! */ | ||
278 | nfs_pageio_complete(pgio); | ||
276 | ret = nfs_wait_on_request(req); | 279 | ret = nfs_wait_on_request(req); |
277 | nfs_release_request(req); | 280 | nfs_release_request(req); |
278 | if (ret != 0) | 281 | if (ret != 0) |
@@ -283,21 +286,18 @@ static int nfs_page_mark_flush(struct page *page) | |||
283 | /* This request is marked for commit */ | 286 | /* This request is marked for commit */ |
284 | spin_unlock(req_lock); | 287 | spin_unlock(req_lock); |
285 | nfs_unlock_request(req); | 288 | nfs_unlock_request(req); |
289 | nfs_pageio_complete(pgio); | ||
286 | return 1; | 290 | return 1; |
287 | } | 291 | } |
288 | if (nfs_set_page_writeback(page) == 0) { | 292 | if (nfs_set_page_writeback(page) != 0) { |
289 | nfs_list_remove_request(req); | ||
290 | /* add the request to the inode's dirty list. */ | ||
291 | radix_tree_tag_set(&nfsi->nfs_page_tree, | ||
292 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
293 | nfs_list_add_request(req, &nfsi->dirty); | ||
294 | nfsi->ndirty++; | ||
295 | spin_unlock(req_lock); | ||
296 | __mark_inode_dirty(page->mapping->host, I_DIRTY_PAGES); | ||
297 | } else | ||
298 | spin_unlock(req_lock); | 293 | spin_unlock(req_lock); |
294 | BUG(); | ||
295 | } | ||
296 | radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, | ||
297 | NFS_PAGE_TAG_WRITEBACK); | ||
299 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | 298 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); |
300 | nfs_unlock_request(req); | 299 | spin_unlock(req_lock); |
300 | nfs_pageio_add_request(pgio, req); | ||
301 | return ret; | 301 | return ret; |
302 | } | 302 | } |
303 | 303 | ||
@@ -306,6 +306,7 @@ static int nfs_page_mark_flush(struct page *page) | |||
306 | */ | 306 | */ |
307 | static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc) | 307 | static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc) |
308 | { | 308 | { |
309 | struct nfs_pageio_descriptor mypgio, *pgio; | ||
309 | struct nfs_open_context *ctx; | 310 | struct nfs_open_context *ctx; |
310 | struct inode *inode = page->mapping->host; | 311 | struct inode *inode = page->mapping->host; |
311 | unsigned offset; | 312 | unsigned offset; |
@@ -314,7 +315,14 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc | |||
314 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); | 315 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); |
315 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); | 316 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); |
316 | 317 | ||
317 | err = nfs_page_mark_flush(page); | 318 | if (wbc->for_writepages) |
319 | pgio = wbc->fs_private; | ||
320 | else { | ||
321 | nfs_pageio_init_write(&mypgio, inode, wb_priority(wbc)); | ||
322 | pgio = &mypgio; | ||
323 | } | ||
324 | |||
325 | err = nfs_page_async_flush(pgio, page); | ||
318 | if (err <= 0) | 326 | if (err <= 0) |
319 | goto out; | 327 | goto out; |
320 | err = 0; | 328 | err = 0; |
@@ -331,12 +339,12 @@ static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc | |||
331 | put_nfs_open_context(ctx); | 339 | put_nfs_open_context(ctx); |
332 | if (err != 0) | 340 | if (err != 0) |
333 | goto out; | 341 | goto out; |
334 | err = nfs_page_mark_flush(page); | 342 | err = nfs_page_async_flush(pgio, page); |
335 | if (err > 0) | 343 | if (err > 0) |
336 | err = 0; | 344 | err = 0; |
337 | out: | 345 | out: |
338 | if (!wbc->for_writepages) | 346 | if (!wbc->for_writepages) |
339 | nfs_flush_mapping(page->mapping, wbc, FLUSH_STABLE|wb_priority(wbc)); | 347 | nfs_pageio_complete(pgio); |
340 | return err; | 348 | return err; |
341 | } | 349 | } |
342 | 350 | ||
@@ -352,20 +360,20 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
352 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | 360 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) |
353 | { | 361 | { |
354 | struct inode *inode = mapping->host; | 362 | struct inode *inode = mapping->host; |
363 | struct nfs_pageio_descriptor pgio; | ||
355 | int err; | 364 | int err; |
356 | 365 | ||
357 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); | 366 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES); |
358 | 367 | ||
368 | nfs_pageio_init_write(&pgio, inode, wb_priority(wbc)); | ||
369 | wbc->fs_private = &pgio; | ||
359 | err = generic_writepages(mapping, wbc); | 370 | err = generic_writepages(mapping, wbc); |
371 | nfs_pageio_complete(&pgio); | ||
360 | if (err) | 372 | if (err) |
361 | return err; | 373 | return err; |
362 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); | 374 | if (pgio.pg_error) |
363 | if (err < 0) | 375 | return pgio.pg_error; |
364 | goto out; | 376 | return 0; |
365 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | ||
366 | err = 0; | ||
367 | out: | ||
368 | return err; | ||
369 | } | 377 | } |
370 | 378 | ||
371 | /* | 379 | /* |
@@ -503,11 +511,11 @@ int nfs_reschedule_unstable_write(struct nfs_page *req) | |||
503 | * | 511 | * |
504 | * Interruptible by signals only if mounted with intr flag. | 512 | * Interruptible by signals only if mounted with intr flag. |
505 | */ | 513 | */ |
506 | static int nfs_wait_on_requests_locked(struct inode *inode, unsigned long idx_start, unsigned int npages) | 514 | static int nfs_wait_on_requests_locked(struct inode *inode, pgoff_t idx_start, unsigned int npages) |
507 | { | 515 | { |
508 | struct nfs_inode *nfsi = NFS_I(inode); | 516 | struct nfs_inode *nfsi = NFS_I(inode); |
509 | struct nfs_page *req; | 517 | struct nfs_page *req; |
510 | unsigned long idx_end, next; | 518 | pgoff_t idx_end, next; |
511 | unsigned int res = 0; | 519 | unsigned int res = 0; |
512 | int error; | 520 | int error; |
513 | 521 | ||
@@ -536,18 +544,6 @@ static int nfs_wait_on_requests_locked(struct inode *inode, unsigned long idx_st | |||
536 | return res; | 544 | return res; |
537 | } | 545 | } |
538 | 546 | ||
539 | static void nfs_cancel_dirty_list(struct list_head *head) | ||
540 | { | ||
541 | struct nfs_page *req; | ||
542 | while(!list_empty(head)) { | ||
543 | req = nfs_list_entry(head->next); | ||
544 | nfs_list_remove_request(req); | ||
545 | nfs_end_page_writeback(req->wb_page); | ||
546 | nfs_inode_remove_request(req); | ||
547 | nfs_clear_page_writeback(req); | ||
548 | } | ||
549 | } | ||
550 | |||
551 | static void nfs_cancel_commit_list(struct list_head *head) | 547 | static void nfs_cancel_commit_list(struct list_head *head) |
552 | { | 548 | { |
553 | struct nfs_page *req; | 549 | struct nfs_page *req; |
@@ -574,7 +570,7 @@ static void nfs_cancel_commit_list(struct list_head *head) | |||
574 | * The requests are *not* checked to ensure that they form a contiguous set. | 570 | * The requests are *not* checked to ensure that they form a contiguous set. |
575 | */ | 571 | */ |
576 | static int | 572 | static int |
577 | nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) | 573 | nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages) |
578 | { | 574 | { |
579 | struct nfs_inode *nfsi = NFS_I(inode); | 575 | struct nfs_inode *nfsi = NFS_I(inode); |
580 | int res = 0; | 576 | int res = 0; |
@@ -588,40 +584,12 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_st | |||
588 | return res; | 584 | return res; |
589 | } | 585 | } |
590 | #else | 586 | #else |
591 | static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) | 587 | static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, unsigned int npages) |
592 | { | 588 | { |
593 | return 0; | 589 | return 0; |
594 | } | 590 | } |
595 | #endif | 591 | #endif |
596 | 592 | ||
597 | static int nfs_wait_on_write_congestion(struct address_space *mapping) | ||
598 | { | ||
599 | struct inode *inode = mapping->host; | ||
600 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
601 | int ret = 0; | ||
602 | |||
603 | might_sleep(); | ||
604 | |||
605 | if (!bdi_write_congested(bdi)) | ||
606 | return 0; | ||
607 | |||
608 | nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT); | ||
609 | |||
610 | do { | ||
611 | struct rpc_clnt *clnt = NFS_CLIENT(inode); | ||
612 | sigset_t oldset; | ||
613 | |||
614 | rpc_clnt_sigmask(clnt, &oldset); | ||
615 | ret = congestion_wait_interruptible(WRITE, HZ/10); | ||
616 | rpc_clnt_sigunmask(clnt, &oldset); | ||
617 | if (ret == -ERESTARTSYS) | ||
618 | break; | ||
619 | ret = 0; | ||
620 | } while (bdi_write_congested(bdi)); | ||
621 | |||
622 | return ret; | ||
623 | } | ||
624 | |||
625 | /* | 593 | /* |
626 | * Try to update any existing write request, or create one if there is none. | 594 | * Try to update any existing write request, or create one if there is none. |
627 | * In order to match, the request's credentials must match those of | 595 | * In order to match, the request's credentials must match those of |
@@ -636,12 +604,10 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
636 | struct inode *inode = mapping->host; | 604 | struct inode *inode = mapping->host; |
637 | struct nfs_inode *nfsi = NFS_I(inode); | 605 | struct nfs_inode *nfsi = NFS_I(inode); |
638 | struct nfs_page *req, *new = NULL; | 606 | struct nfs_page *req, *new = NULL; |
639 | unsigned long rqend, end; | 607 | pgoff_t rqend, end; |
640 | 608 | ||
641 | end = offset + bytes; | 609 | end = offset + bytes; |
642 | 610 | ||
643 | if (nfs_wait_on_write_congestion(mapping)) | ||
644 | return ERR_PTR(-ERESTARTSYS); | ||
645 | for (;;) { | 611 | for (;;) { |
646 | /* Loop over all inode entries and see if we find | 612 | /* Loop over all inode entries and see if we find |
647 | * A request for the page we wish to update | 613 | * A request for the page we wish to update |
@@ -865,7 +831,7 @@ static void nfs_execute_write(struct nfs_write_data *data) | |||
865 | * Generate multiple small requests to write out a single | 831 | * Generate multiple small requests to write out a single |
866 | * contiguous dirty area on one page. | 832 | * contiguous dirty area on one page. |
867 | */ | 833 | */ |
868 | static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) | 834 | static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how) |
869 | { | 835 | { |
870 | struct nfs_page *req = nfs_list_entry(head->next); | 836 | struct nfs_page *req = nfs_list_entry(head->next); |
871 | struct page *page = req->wb_page; | 837 | struct page *page = req->wb_page; |
@@ -877,11 +843,11 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) | |||
877 | 843 | ||
878 | nfs_list_remove_request(req); | 844 | nfs_list_remove_request(req); |
879 | 845 | ||
880 | nbytes = req->wb_bytes; | 846 | nbytes = count; |
881 | do { | 847 | do { |
882 | size_t len = min(nbytes, wsize); | 848 | size_t len = min(nbytes, wsize); |
883 | 849 | ||
884 | data = nfs_writedata_alloc(len); | 850 | data = nfs_writedata_alloc(1); |
885 | if (!data) | 851 | if (!data) |
886 | goto out_bad; | 852 | goto out_bad; |
887 | list_add(&data->pages, &list); | 853 | list_add(&data->pages, &list); |
@@ -892,23 +858,19 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) | |||
892 | 858 | ||
893 | ClearPageError(page); | 859 | ClearPageError(page); |
894 | offset = 0; | 860 | offset = 0; |
895 | nbytes = req->wb_bytes; | 861 | nbytes = count; |
896 | do { | 862 | do { |
897 | data = list_entry(list.next, struct nfs_write_data, pages); | 863 | data = list_entry(list.next, struct nfs_write_data, pages); |
898 | list_del_init(&data->pages); | 864 | list_del_init(&data->pages); |
899 | 865 | ||
900 | data->pagevec[0] = page; | 866 | data->pagevec[0] = page; |
901 | 867 | ||
902 | if (nbytes > wsize) { | 868 | if (nbytes < wsize) |
903 | nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, | 869 | wsize = nbytes; |
904 | wsize, offset, how); | 870 | nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, |
905 | offset += wsize; | 871 | wsize, offset, how); |
906 | nbytes -= wsize; | 872 | offset += wsize; |
907 | } else { | 873 | nbytes -= wsize; |
908 | nfs_write_rpcsetup(req, data, &nfs_write_partial_ops, | ||
909 | nbytes, offset, how); | ||
910 | nbytes = 0; | ||
911 | } | ||
912 | nfs_execute_write(data); | 874 | nfs_execute_write(data); |
913 | } while (nbytes != 0); | 875 | } while (nbytes != 0); |
914 | 876 | ||
@@ -934,26 +896,23 @@ out_bad: | |||
934 | * This is the case if nfs_updatepage detects a conflicting request | 896 | * This is the case if nfs_updatepage detects a conflicting request |
935 | * that has been written but not committed. | 897 | * that has been written but not committed. |
936 | */ | 898 | */ |
937 | static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | 899 | static int nfs_flush_one(struct inode *inode, struct list_head *head, unsigned int npages, size_t count, int how) |
938 | { | 900 | { |
939 | struct nfs_page *req; | 901 | struct nfs_page *req; |
940 | struct page **pages; | 902 | struct page **pages; |
941 | struct nfs_write_data *data; | 903 | struct nfs_write_data *data; |
942 | unsigned int count; | ||
943 | 904 | ||
944 | data = nfs_writedata_alloc(NFS_SERVER(inode)->wsize); | 905 | data = nfs_writedata_alloc(npages); |
945 | if (!data) | 906 | if (!data) |
946 | goto out_bad; | 907 | goto out_bad; |
947 | 908 | ||
948 | pages = data->pagevec; | 909 | pages = data->pagevec; |
949 | count = 0; | ||
950 | while (!list_empty(head)) { | 910 | while (!list_empty(head)) { |
951 | req = nfs_list_entry(head->next); | 911 | req = nfs_list_entry(head->next); |
952 | nfs_list_remove_request(req); | 912 | nfs_list_remove_request(req); |
953 | nfs_list_add_request(req, &data->pages); | 913 | nfs_list_add_request(req, &data->pages); |
954 | ClearPageError(req->wb_page); | 914 | ClearPageError(req->wb_page); |
955 | *pages++ = req->wb_page; | 915 | *pages++ = req->wb_page; |
956 | count += req->wb_bytes; | ||
957 | } | 916 | } |
958 | req = nfs_list_entry(data->pages.next); | 917 | req = nfs_list_entry(data->pages.next); |
959 | 918 | ||
@@ -973,40 +932,15 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
973 | return -ENOMEM; | 932 | return -ENOMEM; |
974 | } | 933 | } |
975 | 934 | ||
976 | static int nfs_flush_list(struct inode *inode, struct list_head *head, int npages, int how) | 935 | static void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, |
936 | struct inode *inode, int ioflags) | ||
977 | { | 937 | { |
978 | LIST_HEAD(one_request); | ||
979 | int (*flush_one)(struct inode *, struct list_head *, int); | ||
980 | struct nfs_page *req; | ||
981 | int wpages = NFS_SERVER(inode)->wpages; | ||
982 | int wsize = NFS_SERVER(inode)->wsize; | 938 | int wsize = NFS_SERVER(inode)->wsize; |
983 | int error; | ||
984 | 939 | ||
985 | flush_one = nfs_flush_one; | ||
986 | if (wsize < PAGE_CACHE_SIZE) | 940 | if (wsize < PAGE_CACHE_SIZE) |
987 | flush_one = nfs_flush_multi; | 941 | nfs_pageio_init(pgio, inode, nfs_flush_multi, wsize, ioflags); |
988 | /* For single writes, FLUSH_STABLE is more efficient */ | 942 | else |
989 | if (npages <= wpages && npages == NFS_I(inode)->npages | 943 | nfs_pageio_init(pgio, inode, nfs_flush_one, wsize, ioflags); |
990 | && nfs_list_entry(head->next)->wb_bytes <= wsize) | ||
991 | how |= FLUSH_STABLE; | ||
992 | |||
993 | do { | ||
994 | nfs_coalesce_requests(head, &one_request, wpages); | ||
995 | req = nfs_list_entry(one_request.next); | ||
996 | error = flush_one(inode, &one_request, how); | ||
997 | if (error < 0) | ||
998 | goto out_err; | ||
999 | } while (!list_empty(head)); | ||
1000 | return 0; | ||
1001 | out_err: | ||
1002 | while (!list_empty(head)) { | ||
1003 | req = nfs_list_entry(head->next); | ||
1004 | nfs_list_remove_request(req); | ||
1005 | nfs_redirty_request(req); | ||
1006 | nfs_end_page_writeback(req->wb_page); | ||
1007 | nfs_clear_page_writeback(req); | ||
1008 | } | ||
1009 | return error; | ||
1010 | } | 944 | } |
1011 | 945 | ||
1012 | /* | 946 | /* |
@@ -1330,31 +1264,7 @@ static const struct rpc_call_ops nfs_commit_ops = { | |||
1330 | .rpc_call_done = nfs_commit_done, | 1264 | .rpc_call_done = nfs_commit_done, |
1331 | .rpc_release = nfs_commit_release, | 1265 | .rpc_release = nfs_commit_release, |
1332 | }; | 1266 | }; |
1333 | #else | ||
1334 | static inline int nfs_commit_list(struct inode *inode, struct list_head *head, int how) | ||
1335 | { | ||
1336 | return 0; | ||
1337 | } | ||
1338 | #endif | ||
1339 | |||
1340 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) | ||
1341 | { | ||
1342 | struct nfs_inode *nfsi = NFS_I(mapping->host); | ||
1343 | LIST_HEAD(head); | ||
1344 | long res; | ||
1345 | |||
1346 | spin_lock(&nfsi->req_lock); | ||
1347 | res = nfs_scan_dirty(mapping, wbc, &head); | ||
1348 | spin_unlock(&nfsi->req_lock); | ||
1349 | if (res) { | ||
1350 | int error = nfs_flush_list(mapping->host, &head, res, how); | ||
1351 | if (error < 0) | ||
1352 | return error; | ||
1353 | } | ||
1354 | return res; | ||
1355 | } | ||
1356 | 1267 | ||
1357 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | ||
1358 | int nfs_commit_inode(struct inode *inode, int how) | 1268 | int nfs_commit_inode(struct inode *inode, int how) |
1359 | { | 1269 | { |
1360 | struct nfs_inode *nfsi = NFS_I(inode); | 1270 | struct nfs_inode *nfsi = NFS_I(inode); |
@@ -1371,13 +1281,18 @@ int nfs_commit_inode(struct inode *inode, int how) | |||
1371 | } | 1281 | } |
1372 | return res; | 1282 | return res; |
1373 | } | 1283 | } |
1284 | #else | ||
1285 | static inline int nfs_commit_list(struct inode *inode, struct list_head *head, int how) | ||
1286 | { | ||
1287 | return 0; | ||
1288 | } | ||
1374 | #endif | 1289 | #endif |
1375 | 1290 | ||
1376 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) | 1291 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) |
1377 | { | 1292 | { |
1378 | struct inode *inode = mapping->host; | 1293 | struct inode *inode = mapping->host; |
1379 | struct nfs_inode *nfsi = NFS_I(inode); | 1294 | struct nfs_inode *nfsi = NFS_I(inode); |
1380 | unsigned long idx_start, idx_end; | 1295 | pgoff_t idx_start, idx_end; |
1381 | unsigned int npages = 0; | 1296 | unsigned int npages = 0; |
1382 | LIST_HEAD(head); | 1297 | LIST_HEAD(head); |
1383 | int nocommit = how & FLUSH_NOCOMMIT; | 1298 | int nocommit = how & FLUSH_NOCOMMIT; |
@@ -1390,41 +1305,24 @@ long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_contr | |||
1390 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | 1305 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; |
1391 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | 1306 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; |
1392 | if (idx_end > idx_start) { | 1307 | if (idx_end > idx_start) { |
1393 | unsigned long l_npages = 1 + idx_end - idx_start; | 1308 | pgoff_t l_npages = 1 + idx_end - idx_start; |
1394 | npages = l_npages; | 1309 | npages = l_npages; |
1395 | if (sizeof(npages) != sizeof(l_npages) && | 1310 | if (sizeof(npages) != sizeof(l_npages) && |
1396 | (unsigned long)npages != l_npages) | 1311 | (pgoff_t)npages != l_npages) |
1397 | npages = 0; | 1312 | npages = 0; |
1398 | } | 1313 | } |
1399 | } | 1314 | } |
1400 | how &= ~FLUSH_NOCOMMIT; | 1315 | how &= ~FLUSH_NOCOMMIT; |
1401 | spin_lock(&nfsi->req_lock); | 1316 | spin_lock(&nfsi->req_lock); |
1402 | do { | 1317 | do { |
1403 | wbc->pages_skipped = 0; | ||
1404 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); | 1318 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); |
1405 | if (ret != 0) | 1319 | if (ret != 0) |
1406 | continue; | 1320 | continue; |
1407 | pages = nfs_scan_dirty(mapping, wbc, &head); | ||
1408 | if (pages != 0) { | ||
1409 | spin_unlock(&nfsi->req_lock); | ||
1410 | if (how & FLUSH_INVALIDATE) { | ||
1411 | nfs_cancel_dirty_list(&head); | ||
1412 | ret = pages; | ||
1413 | } else | ||
1414 | ret = nfs_flush_list(inode, &head, pages, how); | ||
1415 | spin_lock(&nfsi->req_lock); | ||
1416 | continue; | ||
1417 | } | ||
1418 | if (wbc->pages_skipped != 0) | ||
1419 | continue; | ||
1420 | if (nocommit) | 1321 | if (nocommit) |
1421 | break; | 1322 | break; |
1422 | pages = nfs_scan_commit(inode, &head, idx_start, npages); | 1323 | pages = nfs_scan_commit(inode, &head, idx_start, npages); |
1423 | if (pages == 0) { | 1324 | if (pages == 0) |
1424 | if (wbc->pages_skipped != 0) | ||
1425 | continue; | ||
1426 | break; | 1325 | break; |
1427 | } | ||
1428 | if (how & FLUSH_INVALIDATE) { | 1326 | if (how & FLUSH_INVALIDATE) { |
1429 | spin_unlock(&nfsi->req_lock); | 1327 | spin_unlock(&nfsi->req_lock); |
1430 | nfs_cancel_commit_list(&head); | 1328 | nfs_cancel_commit_list(&head); |
@@ -1456,7 +1354,7 @@ int nfs_wb_all(struct inode *inode) | |||
1456 | }; | 1354 | }; |
1457 | int ret; | 1355 | int ret; |
1458 | 1356 | ||
1459 | ret = generic_writepages(mapping, &wbc); | 1357 | ret = nfs_writepages(mapping, &wbc); |
1460 | if (ret < 0) | 1358 | if (ret < 0) |
1461 | goto out; | 1359 | goto out; |
1462 | ret = nfs_sync_mapping_wait(mapping, &wbc, 0); | 1360 | ret = nfs_sync_mapping_wait(mapping, &wbc, 0); |
@@ -1479,11 +1377,9 @@ int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, lo | |||
1479 | }; | 1377 | }; |
1480 | int ret; | 1378 | int ret; |
1481 | 1379 | ||
1482 | if (!(how & FLUSH_NOWRITEPAGE)) { | 1380 | ret = nfs_writepages(mapping, &wbc); |
1483 | ret = generic_writepages(mapping, &wbc); | 1381 | if (ret < 0) |
1484 | if (ret < 0) | 1382 | goto out; |
1485 | goto out; | ||
1486 | } | ||
1487 | ret = nfs_sync_mapping_wait(mapping, &wbc, how); | 1383 | ret = nfs_sync_mapping_wait(mapping, &wbc, how); |
1488 | if (ret >= 0) | 1384 | if (ret >= 0) |
1489 | return 0; | 1385 | return 0; |
@@ -1506,7 +1402,7 @@ int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) | |||
1506 | int ret; | 1402 | int ret; |
1507 | 1403 | ||
1508 | BUG_ON(!PageLocked(page)); | 1404 | BUG_ON(!PageLocked(page)); |
1509 | if (!(how & FLUSH_NOWRITEPAGE) && clear_page_dirty_for_io(page)) { | 1405 | if (clear_page_dirty_for_io(page)) { |
1510 | ret = nfs_writepage_locked(page, &wbc); | 1406 | ret = nfs_writepage_locked(page, &wbc); |
1511 | if (ret < 0) | 1407 | if (ret < 0) |
1512 | goto out; | 1408 | goto out; |
@@ -1531,10 +1427,18 @@ int nfs_wb_page(struct inode *inode, struct page* page) | |||
1531 | 1427 | ||
1532 | int nfs_set_page_dirty(struct page *page) | 1428 | int nfs_set_page_dirty(struct page *page) |
1533 | { | 1429 | { |
1534 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | 1430 | struct address_space *mapping = page->mapping; |
1431 | struct inode *inode; | ||
1432 | spinlock_t *req_lock; | ||
1535 | struct nfs_page *req; | 1433 | struct nfs_page *req; |
1536 | int ret; | 1434 | int ret; |
1537 | 1435 | ||
1436 | if (!mapping) | ||
1437 | goto out_raced; | ||
1438 | inode = mapping->host; | ||
1439 | if (!inode) | ||
1440 | goto out_raced; | ||
1441 | req_lock = &NFS_I(inode)->req_lock; | ||
1538 | spin_lock(req_lock); | 1442 | spin_lock(req_lock); |
1539 | req = nfs_page_find_request_locked(page); | 1443 | req = nfs_page_find_request_locked(page); |
1540 | if (req != NULL) { | 1444 | if (req != NULL) { |
@@ -1547,6 +1451,8 @@ int nfs_set_page_dirty(struct page *page) | |||
1547 | ret = __set_page_dirty_nobuffers(page); | 1451 | ret = __set_page_dirty_nobuffers(page); |
1548 | spin_unlock(req_lock); | 1452 | spin_unlock(req_lock); |
1549 | return ret; | 1453 | return ret; |
1454 | out_raced: | ||
1455 | return !TestSetPageDirty(page); | ||
1550 | } | 1456 | } |
1551 | 1457 | ||
1552 | 1458 | ||
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index fb14d68eacab..32ffea033c7a 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -315,16 +315,13 @@ out: | |||
315 | /* | 315 | /* |
316 | * RPC procedure tables | 316 | * RPC procedure tables |
317 | */ | 317 | */ |
318 | #ifndef MAX | ||
319 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
320 | #endif | ||
321 | |||
322 | #define PROC(proc, call, argtype, restype) \ | 318 | #define PROC(proc, call, argtype, restype) \ |
323 | [NFSPROC4_CLNT_##proc] = { \ | 319 | [NFSPROC4_CLNT_##proc] = { \ |
324 | .p_proc = NFSPROC4_CB_##call, \ | 320 | .p_proc = NFSPROC4_CB_##call, \ |
325 | .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ | 321 | .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ |
326 | .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ | 322 | .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ |
327 | .p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2, \ | 323 | .p_arglen = NFS4_##argtype##_sz, \ |
324 | .p_replen = NFS4_##restype##_sz, \ | ||
328 | .p_statidx = NFSPROC4_CB_##call, \ | 325 | .p_statidx = NFSPROC4_CB_##call, \ |
329 | .p_name = #proc, \ | 326 | .p_name = #proc, \ |
330 | } | 327 | } |
diff --git a/fs/ntfs/aops.h b/fs/ntfs/aops.h index 9393f4b1e298..caecc58f529c 100644 --- a/fs/ntfs/aops.h +++ b/fs/ntfs/aops.h | |||
@@ -89,9 +89,8 @@ static inline struct page *ntfs_map_page(struct address_space *mapping, | |||
89 | struct page *page = read_mapping_page(mapping, index, NULL); | 89 | struct page *page = read_mapping_page(mapping, index, NULL); |
90 | 90 | ||
91 | if (!IS_ERR(page)) { | 91 | if (!IS_ERR(page)) { |
92 | wait_on_page_locked(page); | ||
93 | kmap(page); | 92 | kmap(page); |
94 | if (PageUptodate(page) && !PageError(page)) | 93 | if (!PageError(page)) |
95 | return page; | 94 | return page; |
96 | ntfs_unmap_page(page); | 95 | ntfs_unmap_page(page); |
97 | return ERR_PTR(-EIO); | 96 | return ERR_PTR(-EIO); |
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 7659cc192995..1c08fefe487a 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
@@ -2532,14 +2532,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val) | |||
2532 | page = read_mapping_page(mapping, idx, NULL); | 2532 | page = read_mapping_page(mapping, idx, NULL); |
2533 | if (IS_ERR(page)) { | 2533 | if (IS_ERR(page)) { |
2534 | ntfs_error(vol->sb, "Failed to read first partial " | 2534 | ntfs_error(vol->sb, "Failed to read first partial " |
2535 | "page (sync error, index 0x%lx).", idx); | 2535 | "page (error, index 0x%lx).", idx); |
2536 | return PTR_ERR(page); | ||
2537 | } | ||
2538 | wait_on_page_locked(page); | ||
2539 | if (unlikely(!PageUptodate(page))) { | ||
2540 | ntfs_error(vol->sb, "Failed to read first partial page " | ||
2541 | "(async error, index 0x%lx).", idx); | ||
2542 | page_cache_release(page); | ||
2543 | return PTR_ERR(page); | 2536 | return PTR_ERR(page); |
2544 | } | 2537 | } |
2545 | /* | 2538 | /* |
@@ -2602,14 +2595,7 @@ int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, const u8 val) | |||
2602 | page = read_mapping_page(mapping, idx, NULL); | 2595 | page = read_mapping_page(mapping, idx, NULL); |
2603 | if (IS_ERR(page)) { | 2596 | if (IS_ERR(page)) { |
2604 | ntfs_error(vol->sb, "Failed to read last partial page " | 2597 | ntfs_error(vol->sb, "Failed to read last partial page " |
2605 | "(sync error, index 0x%lx).", idx); | 2598 | "(error, index 0x%lx).", idx); |
2606 | return PTR_ERR(page); | ||
2607 | } | ||
2608 | wait_on_page_locked(page); | ||
2609 | if (unlikely(!PageUptodate(page))) { | ||
2610 | ntfs_error(vol->sb, "Failed to read last partial page " | ||
2611 | "(async error, index 0x%lx).", idx); | ||
2612 | page_cache_release(page); | ||
2613 | return PTR_ERR(page); | 2599 | return PTR_ERR(page); |
2614 | } | 2600 | } |
2615 | kaddr = kmap_atomic(page, KM_USER0); | 2601 | kaddr = kmap_atomic(page, KM_USER0); |
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index d69c4595ccd0..dbbac5593106 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c | |||
@@ -236,8 +236,7 @@ do_non_resident_extend: | |||
236 | err = PTR_ERR(page); | 236 | err = PTR_ERR(page); |
237 | goto init_err_out; | 237 | goto init_err_out; |
238 | } | 238 | } |
239 | wait_on_page_locked(page); | 239 | if (unlikely(PageError(page))) { |
240 | if (unlikely(!PageUptodate(page) || PageError(page))) { | ||
241 | page_cache_release(page); | 240 | page_cache_release(page); |
242 | err = -EIO; | 241 | err = -EIO; |
243 | goto init_err_out; | 242 | goto init_err_out; |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 1594c90b7164..21d834e5ed73 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -2471,7 +2471,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) | |||
2471 | s64 nr_free = vol->nr_clusters; | 2471 | s64 nr_free = vol->nr_clusters; |
2472 | u32 *kaddr; | 2472 | u32 *kaddr; |
2473 | struct address_space *mapping = vol->lcnbmp_ino->i_mapping; | 2473 | struct address_space *mapping = vol->lcnbmp_ino->i_mapping; |
2474 | filler_t *readpage = (filler_t*)mapping->a_ops->readpage; | ||
2475 | struct page *page; | 2474 | struct page *page; |
2476 | pgoff_t index, max_index; | 2475 | pgoff_t index, max_index; |
2477 | 2476 | ||
@@ -2494,24 +2493,14 @@ static s64 get_nr_free_clusters(ntfs_volume *vol) | |||
2494 | * Read the page from page cache, getting it from backing store | 2493 | * Read the page from page cache, getting it from backing store |
2495 | * if necessary, and increment the use count. | 2494 | * if necessary, and increment the use count. |
2496 | */ | 2495 | */ |
2497 | page = read_cache_page(mapping, index, (filler_t*)readpage, | 2496 | page = read_mapping_page(mapping, index, NULL); |
2498 | NULL); | ||
2499 | /* Ignore pages which errored synchronously. */ | 2497 | /* Ignore pages which errored synchronously. */ |
2500 | if (IS_ERR(page)) { | 2498 | if (IS_ERR(page)) { |
2501 | ntfs_debug("Sync read_cache_page() error. Skipping " | 2499 | ntfs_debug("read_mapping_page() error. Skipping " |
2502 | "page (index 0x%lx).", index); | 2500 | "page (index 0x%lx).", index); |
2503 | nr_free -= PAGE_CACHE_SIZE * 8; | 2501 | nr_free -= PAGE_CACHE_SIZE * 8; |
2504 | continue; | 2502 | continue; |
2505 | } | 2503 | } |
2506 | wait_on_page_locked(page); | ||
2507 | /* Ignore pages which errored asynchronously. */ | ||
2508 | if (!PageUptodate(page)) { | ||
2509 | ntfs_debug("Async read_cache_page() error. Skipping " | ||
2510 | "page (index 0x%lx).", index); | ||
2511 | page_cache_release(page); | ||
2512 | nr_free -= PAGE_CACHE_SIZE * 8; | ||
2513 | continue; | ||
2514 | } | ||
2515 | kaddr = (u32*)kmap_atomic(page, KM_USER0); | 2504 | kaddr = (u32*)kmap_atomic(page, KM_USER0); |
2516 | /* | 2505 | /* |
2517 | * For each 4 bytes, subtract the number of set bits. If this | 2506 | * For each 4 bytes, subtract the number of set bits. If this |
@@ -2562,7 +2551,6 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, | |||
2562 | { | 2551 | { |
2563 | u32 *kaddr; | 2552 | u32 *kaddr; |
2564 | struct address_space *mapping = vol->mftbmp_ino->i_mapping; | 2553 | struct address_space *mapping = vol->mftbmp_ino->i_mapping; |
2565 | filler_t *readpage = (filler_t*)mapping->a_ops->readpage; | ||
2566 | struct page *page; | 2554 | struct page *page; |
2567 | pgoff_t index; | 2555 | pgoff_t index; |
2568 | 2556 | ||
@@ -2576,21 +2564,11 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, | |||
2576 | * Read the page from page cache, getting it from backing store | 2564 | * Read the page from page cache, getting it from backing store |
2577 | * if necessary, and increment the use count. | 2565 | * if necessary, and increment the use count. |
2578 | */ | 2566 | */ |
2579 | page = read_cache_page(mapping, index, (filler_t*)readpage, | 2567 | page = read_mapping_page(mapping, index, NULL); |
2580 | NULL); | ||
2581 | /* Ignore pages which errored synchronously. */ | 2568 | /* Ignore pages which errored synchronously. */ |
2582 | if (IS_ERR(page)) { | 2569 | if (IS_ERR(page)) { |
2583 | ntfs_debug("Sync read_cache_page() error. Skipping " | 2570 | ntfs_debug("read_mapping_page() error. Skipping " |
2584 | "page (index 0x%lx).", index); | ||
2585 | nr_free -= PAGE_CACHE_SIZE * 8; | ||
2586 | continue; | ||
2587 | } | ||
2588 | wait_on_page_locked(page); | ||
2589 | /* Ignore pages which errored asynchronously. */ | ||
2590 | if (!PageUptodate(page)) { | ||
2591 | ntfs_debug("Async read_cache_page() error. Skipping " | ||
2592 | "page (index 0x%lx).", index); | 2571 | "page (index 0x%lx).", index); |
2593 | page_cache_release(page); | ||
2594 | nr_free -= PAGE_CACHE_SIZE * 8; | 2572 | nr_free -= PAGE_CACHE_SIZE * 8; |
2595 | continue; | 2573 | continue; |
2596 | } | 2574 | } |
@@ -3107,8 +3085,7 @@ static void ntfs_big_inode_init_once(void *foo, struct kmem_cache *cachep, | |||
3107 | { | 3085 | { |
3108 | ntfs_inode *ni = (ntfs_inode *)foo; | 3086 | ntfs_inode *ni = (ntfs_inode *)foo; |
3109 | 3087 | ||
3110 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 3088 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
3111 | SLAB_CTOR_CONSTRUCTOR) | ||
3112 | inode_init_once(VFS_I(ni)); | 3089 | inode_init_once(VFS_I(ni)); |
3113 | } | 3090 | } |
3114 | 3091 | ||
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index a0c8667caa72..19712a7d145f 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -2869,7 +2869,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
2869 | tl = &tl_copy->id2.i_dealloc; | 2869 | tl = &tl_copy->id2.i_dealloc; |
2870 | num_recs = le16_to_cpu(tl->tl_used); | 2870 | num_recs = le16_to_cpu(tl->tl_used); |
2871 | mlog(0, "cleanup %u records from %llu\n", num_recs, | 2871 | mlog(0, "cleanup %u records from %llu\n", num_recs, |
2872 | (unsigned long long)tl_copy->i_blkno); | 2872 | (unsigned long long)le64_to_cpu(tl_copy->i_blkno)); |
2873 | 2873 | ||
2874 | mutex_lock(&tl_inode->i_mutex); | 2874 | mutex_lock(&tl_inode->i_mutex); |
2875 | for(i = 0; i < num_recs; i++) { | 2875 | for(i = 0; i < num_recs; i++) { |
@@ -3801,8 +3801,8 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
3801 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 3801 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
3802 | 3802 | ||
3803 | mlog(0, "fe->i_clusters = %u, new_i_clusters = %u, fe->i_size =" | 3803 | mlog(0, "fe->i_clusters = %u, new_i_clusters = %u, fe->i_size =" |
3804 | "%llu\n", fe->i_clusters, new_i_clusters, | 3804 | "%llu\n", le32_to_cpu(fe->i_clusters), new_i_clusters, |
3805 | (unsigned long long)fe->i_size); | 3805 | (unsigned long long)le64_to_cpu(fe->i_size)); |
3806 | 3806 | ||
3807 | *tc = kzalloc(sizeof(struct ocfs2_truncate_context), GFP_KERNEL); | 3807 | *tc = kzalloc(sizeof(struct ocfs2_truncate_context), GFP_KERNEL); |
3808 | if (!(*tc)) { | 3808 | if (!(*tc)) { |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 56963e6c46c0..8e7cafb5fc6c 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -78,7 +78,8 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock, | |||
78 | 78 | ||
79 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 79 | if (!OCFS2_IS_VALID_DINODE(fe)) { |
80 | mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n", | 80 | mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n", |
81 | (unsigned long long)fe->i_blkno, 7, fe->i_signature); | 81 | (unsigned long long)le64_to_cpu(fe->i_blkno), 7, |
82 | fe->i_signature); | ||
82 | goto bail; | 83 | goto bail; |
83 | } | 84 | } |
84 | 85 | ||
@@ -939,9 +940,9 @@ out: | |||
939 | * Returns a negative error code or the number of bytes copied into | 940 | * Returns a negative error code or the number of bytes copied into |
940 | * the page. | 941 | * the page. |
941 | */ | 942 | */ |
942 | int ocfs2_write_data_page(struct inode *inode, handle_t *handle, | 943 | static int ocfs2_write_data_page(struct inode *inode, handle_t *handle, |
943 | u64 *p_blkno, struct page *page, | 944 | u64 *p_blkno, struct page *page, |
944 | struct ocfs2_write_ctxt *wc, int new) | 945 | struct ocfs2_write_ctxt *wc, int new) |
945 | { | 946 | { |
946 | int ret, copied = 0; | 947 | int ret, copied = 0; |
947 | unsigned int from = 0, to = 0; | 948 | unsigned int from = 0, to = 0; |
@@ -1086,7 +1087,7 @@ static ssize_t ocfs2_write(struct file *file, u32 phys, handle_t *handle, | |||
1086 | for(i = 0; i < numpages; i++) { | 1087 | for(i = 0; i < numpages; i++) { |
1087 | index = start + i; | 1088 | index = start + i; |
1088 | 1089 | ||
1089 | cpages[i] = grab_cache_page(mapping, index); | 1090 | cpages[i] = find_or_create_page(mapping, index, GFP_NOFS); |
1090 | if (!cpages[i]) { | 1091 | if (!cpages[i]) { |
1091 | ret = -ENOMEM; | 1092 | ret = -ENOMEM; |
1092 | mlog_errno(ret); | 1093 | mlog_errno(ret); |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index eba282da500e..979113479c66 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -438,7 +438,7 @@ static inline void o2hb_prepare_block(struct o2hb_region *reg, | |||
438 | hb_block)); | 438 | hb_block)); |
439 | 439 | ||
440 | mlog(ML_HB_BIO, "our node generation = 0x%llx, cksum = 0x%x\n", | 440 | mlog(ML_HB_BIO, "our node generation = 0x%llx, cksum = 0x%x\n", |
441 | (long long)cpu_to_le64(generation), | 441 | (long long)generation, |
442 | le32_to_cpu(hb_block->hb_cksum)); | 442 | le32_to_cpu(hb_block->hb_cksum)); |
443 | } | 443 | } |
444 | 444 | ||
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index 636593bf4d17..2e975c0a35e1 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -147,7 +147,7 @@ static struct kset mlog_kset = { | |||
147 | .kobj = {.name = "logmask", .ktype = &mlog_ktype}, | 147 | .kobj = {.name = "logmask", .ktype = &mlog_ktype}, |
148 | }; | 148 | }; |
149 | 149 | ||
150 | int mlog_sys_init(struct subsystem *o2cb_subsys) | 150 | int mlog_sys_init(struct kset *o2cb_subsys) |
151 | { | 151 | { |
152 | int i = 0; | 152 | int i = 0; |
153 | 153 | ||
@@ -157,7 +157,7 @@ int mlog_sys_init(struct subsystem *o2cb_subsys) | |||
157 | } | 157 | } |
158 | mlog_attr_ptrs[i] = NULL; | 158 | mlog_attr_ptrs[i] = NULL; |
159 | 159 | ||
160 | mlog_kset.subsys = o2cb_subsys; | 160 | kobj_set_kset_s(&mlog_kset, o2cb_subsys); |
161 | return kset_register(&mlog_kset); | 161 | return kset_register(&mlog_kset); |
162 | } | 162 | } |
163 | 163 | ||
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index a42628ba9ddf..75cd877f6d42 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h | |||
@@ -278,7 +278,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits; | |||
278 | 278 | ||
279 | #include <linux/kobject.h> | 279 | #include <linux/kobject.h> |
280 | #include <linux/sysfs.h> | 280 | #include <linux/sysfs.h> |
281 | int mlog_sys_init(struct subsystem *o2cb_subsys); | 281 | int mlog_sys_init(struct kset *o2cb_subsys); |
282 | void mlog_sys_shutdown(void); | 282 | void mlog_sys_shutdown(void); |
283 | 283 | ||
284 | #endif /* O2CLUSTER_MASKLOG_H */ | 284 | #endif /* O2CLUSTER_MASKLOG_H */ |
diff --git a/fs/ocfs2/cluster/sys.c b/fs/ocfs2/cluster/sys.c index 1d9f6acafa2e..64f6f378fd09 100644 --- a/fs/ocfs2/cluster/sys.c +++ b/fs/ocfs2/cluster/sys.c | |||
@@ -42,7 +42,6 @@ struct o2cb_attribute { | |||
42 | #define O2CB_ATTR(_name, _mode, _show, _store) \ | 42 | #define O2CB_ATTR(_name, _mode, _show, _store) \ |
43 | struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store) | 43 | struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store) |
44 | 44 | ||
45 | #define to_o2cb_subsys(k) container_of(to_kset(k), struct subsystem, kset) | ||
46 | #define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr) | 45 | #define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr) |
47 | 46 | ||
48 | static ssize_t o2cb_interface_revision_show(char *buf) | 47 | static ssize_t o2cb_interface_revision_show(char *buf) |
@@ -79,7 +78,7 @@ static ssize_t | |||
79 | o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer) | 78 | o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer) |
80 | { | 79 | { |
81 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); | 80 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); |
82 | struct subsystem *sbs = to_o2cb_subsys(kobj); | 81 | struct kset *sbs = to_kset(kobj); |
83 | 82 | ||
84 | BUG_ON(sbs != &o2cb_subsys); | 83 | BUG_ON(sbs != &o2cb_subsys); |
85 | 84 | ||
@@ -93,7 +92,7 @@ o2cb_store(struct kobject * kobj, struct attribute * attr, | |||
93 | const char * buffer, size_t count) | 92 | const char * buffer, size_t count) |
94 | { | 93 | { |
95 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); | 94 | struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr); |
96 | struct subsystem *sbs = to_o2cb_subsys(kobj); | 95 | struct kset *sbs = to_kset(kobj); |
97 | 96 | ||
98 | BUG_ON(sbs != &o2cb_subsys); | 97 | BUG_ON(sbs != &o2cb_subsys); |
99 | 98 | ||
@@ -112,7 +111,7 @@ int o2cb_sys_init(void) | |||
112 | { | 111 | { |
113 | int ret; | 112 | int ret; |
114 | 113 | ||
115 | o2cb_subsys.kset.kobj.ktype = &o2cb_subsys_type; | 114 | o2cb_subsys.kobj.ktype = &o2cb_subsys_type; |
116 | ret = subsystem_register(&o2cb_subsys); | 115 | ret = subsystem_register(&o2cb_subsys); |
117 | if (ret) | 116 | if (ret) |
118 | return ret; | 117 | return ret; |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 69caf3e12fea..0b229a9c7952 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1496,7 +1496,7 @@ static void o2net_start_connect(struct work_struct *work) | |||
1496 | sock->sk->sk_allocation = GFP_ATOMIC; | 1496 | sock->sk->sk_allocation = GFP_ATOMIC; |
1497 | 1497 | ||
1498 | myaddr.sin_family = AF_INET; | 1498 | myaddr.sin_family = AF_INET; |
1499 | myaddr.sin_addr.s_addr = (__force u32)mynode->nd_ipv4_address; | 1499 | myaddr.sin_addr.s_addr = mynode->nd_ipv4_address; |
1500 | myaddr.sin_port = (__force u16)htons(0); /* any port */ | 1500 | myaddr.sin_port = (__force u16)htons(0); /* any port */ |
1501 | 1501 | ||
1502 | ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, | 1502 | ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, |
@@ -1521,8 +1521,8 @@ static void o2net_start_connect(struct work_struct *work) | |||
1521 | spin_unlock(&nn->nn_lock); | 1521 | spin_unlock(&nn->nn_lock); |
1522 | 1522 | ||
1523 | remoteaddr.sin_family = AF_INET; | 1523 | remoteaddr.sin_family = AF_INET; |
1524 | remoteaddr.sin_addr.s_addr = (__force u32)node->nd_ipv4_address; | 1524 | remoteaddr.sin_addr.s_addr = node->nd_ipv4_address; |
1525 | remoteaddr.sin_port = (__force u16)node->nd_ipv4_port; | 1525 | remoteaddr.sin_port = node->nd_ipv4_port; |
1526 | 1526 | ||
1527 | ret = sc->sc_sock->ops->connect(sc->sc_sock, | 1527 | ret = sc->sc_sock->ops->connect(sc->sc_sock, |
1528 | (struct sockaddr *)&remoteaddr, | 1528 | (struct sockaddr *)&remoteaddr, |
@@ -1810,8 +1810,8 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port) | |||
1810 | int ret; | 1810 | int ret; |
1811 | struct sockaddr_in sin = { | 1811 | struct sockaddr_in sin = { |
1812 | .sin_family = PF_INET, | 1812 | .sin_family = PF_INET, |
1813 | .sin_addr = { .s_addr = (__force u32)addr }, | 1813 | .sin_addr = { .s_addr = addr }, |
1814 | .sin_port = (__force u16)port, | 1814 | .sin_port = port, |
1815 | }; | 1815 | }; |
1816 | 1816 | ||
1817 | ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); | 1817 | ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 67e6866a2a4f..c441ef1f2bad 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -403,7 +403,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
403 | struct buffer_head **new_de_bh) | 403 | struct buffer_head **new_de_bh) |
404 | { | 404 | { |
405 | int status = 0; | 405 | int status = 0; |
406 | int credits, num_free_extents; | 406 | int credits, num_free_extents, drop_alloc_sem = 0; |
407 | loff_t dir_i_size; | 407 | loff_t dir_i_size; |
408 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 408 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
409 | struct ocfs2_alloc_context *data_ac = NULL; | 409 | struct ocfs2_alloc_context *data_ac = NULL; |
@@ -452,6 +452,9 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
452 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; | 452 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; |
453 | } | 453 | } |
454 | 454 | ||
455 | down_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
456 | drop_alloc_sem = 1; | ||
457 | |||
455 | handle = ocfs2_start_trans(osb, credits); | 458 | handle = ocfs2_start_trans(osb, credits); |
456 | if (IS_ERR(handle)) { | 459 | if (IS_ERR(handle)) { |
457 | status = PTR_ERR(handle); | 460 | status = PTR_ERR(handle); |
@@ -497,6 +500,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
497 | *new_de_bh = new_bh; | 500 | *new_de_bh = new_bh; |
498 | get_bh(*new_de_bh); | 501 | get_bh(*new_de_bh); |
499 | bail: | 502 | bail: |
503 | if (drop_alloc_sem) | ||
504 | up_write(&OCFS2_I(dir)->ip_alloc_sem); | ||
500 | if (handle) | 505 | if (handle) |
501 | ocfs2_commit_trans(osb, handle); | 506 | ocfs2_commit_trans(osb, handle); |
502 | 507 | ||
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index 241cad342a48..2fd8bded38f3 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c | |||
@@ -312,8 +312,8 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, | |||
312 | past->type != DLM_BAST) { | 312 | past->type != DLM_BAST) { |
313 | mlog(ML_ERROR, "Unknown ast type! %d, cookie=%u:%llu" | 313 | mlog(ML_ERROR, "Unknown ast type! %d, cookie=%u:%llu" |
314 | "name=%.*s\n", past->type, | 314 | "name=%.*s\n", past->type, |
315 | dlm_get_lock_cookie_node(be64_to_cpu(cookie)), | 315 | dlm_get_lock_cookie_node(cookie), |
316 | dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), | 316 | dlm_get_lock_cookie_seq(cookie), |
317 | locklen, name); | 317 | locklen, name); |
318 | ret = DLM_IVLOCKID; | 318 | ret = DLM_IVLOCKID; |
319 | goto leave; | 319 | goto leave; |
@@ -324,8 +324,8 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, | |||
324 | mlog(0, "got %sast for unknown lockres! " | 324 | mlog(0, "got %sast for unknown lockres! " |
325 | "cookie=%u:%llu, name=%.*s, namelen=%u\n", | 325 | "cookie=%u:%llu, name=%.*s, namelen=%u\n", |
326 | past->type == DLM_AST ? "" : "b", | 326 | past->type == DLM_AST ? "" : "b", |
327 | dlm_get_lock_cookie_node(be64_to_cpu(cookie)), | 327 | dlm_get_lock_cookie_node(cookie), |
328 | dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), | 328 | dlm_get_lock_cookie_seq(cookie), |
329 | locklen, name, locklen); | 329 | locklen, name, locklen); |
330 | ret = DLM_IVLOCKID; | 330 | ret = DLM_IVLOCKID; |
331 | goto leave; | 331 | goto leave; |
@@ -370,8 +370,8 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, | |||
370 | 370 | ||
371 | mlog(0, "got %sast for unknown lock! cookie=%u:%llu, " | 371 | mlog(0, "got %sast for unknown lock! cookie=%u:%llu, " |
372 | "name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b", | 372 | "name=%.*s, namelen=%u\n", past->type == DLM_AST ? "" : "b", |
373 | dlm_get_lock_cookie_node(be64_to_cpu(cookie)), | 373 | dlm_get_lock_cookie_node(cookie), |
374 | dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), | 374 | dlm_get_lock_cookie_seq(cookie), |
375 | locklen, name, locklen); | 375 | locklen, name, locklen); |
376 | 376 | ||
377 | ret = DLM_NORMAL; | 377 | ret = DLM_NORMAL; |
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index de952eba29a9..d4e46d067edd 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -263,8 +263,7 @@ static void dlmfs_init_once(void *foo, | |||
263 | struct dlmfs_inode_private *ip = | 263 | struct dlmfs_inode_private *ip = |
264 | (struct dlmfs_inode_private *) foo; | 264 | (struct dlmfs_inode_private *) foo; |
265 | 265 | ||
266 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 266 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
267 | SLAB_CTOR_CONSTRUCTOR) { | ||
268 | ip->ip_dlm = NULL; | 267 | ip->ip_dlm = NULL; |
269 | ip->ip_parent = NULL; | 268 | ip->ip_parent = NULL; |
270 | 269 | ||
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index c1807a42c49f..671c4ed58ee2 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -1769,7 +1769,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, | |||
1769 | /* lock is always created locally first, and | 1769 | /* lock is always created locally first, and |
1770 | * destroyed locally last. it must be on the list */ | 1770 | * destroyed locally last. it must be on the list */ |
1771 | if (!lock) { | 1771 | if (!lock) { |
1772 | u64 c = ml->cookie; | 1772 | __be64 c = ml->cookie; |
1773 | mlog(ML_ERROR, "could not find local lock " | 1773 | mlog(ML_ERROR, "could not find local lock " |
1774 | "with cookie %u:%llu!\n", | 1774 | "with cookie %u:%llu!\n", |
1775 | dlm_get_lock_cookie_node(be64_to_cpu(c)), | 1775 | dlm_get_lock_cookie_node(be64_to_cpu(c)), |
@@ -1878,7 +1878,7 @@ skip_lvb: | |||
1878 | spin_lock(&res->spinlock); | 1878 | spin_lock(&res->spinlock); |
1879 | list_for_each_entry(lock, queue, list) { | 1879 | list_for_each_entry(lock, queue, list) { |
1880 | if (lock->ml.cookie == ml->cookie) { | 1880 | if (lock->ml.cookie == ml->cookie) { |
1881 | u64 c = lock->ml.cookie; | 1881 | __be64 c = lock->ml.cookie; |
1882 | mlog(ML_ERROR, "%s:%.*s: %u:%llu: lock already " | 1882 | mlog(ML_ERROR, "%s:%.*s: %u:%llu: lock already " |
1883 | "exists on this lockres!\n", dlm->name, | 1883 | "exists on this lockres!\n", dlm->name, |
1884 | res->lockname.len, res->lockname.name, | 1884 | res->lockname.len, res->lockname.name, |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 2b264c6ba039..cebd089f8955 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -76,7 +76,7 @@ repeat: | |||
76 | goto repeat; | 76 | goto repeat; |
77 | } | 77 | } |
78 | remove_wait_queue(&res->wq, &wait); | 78 | remove_wait_queue(&res->wq, &wait); |
79 | current->state = TASK_RUNNING; | 79 | __set_current_state(TASK_RUNNING); |
80 | } | 80 | } |
81 | 81 | ||
82 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res) | 82 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res) |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 27e43b0c0eae..024777abc8e3 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -104,6 +104,35 @@ static int ocfs2_dentry_convert_worker(struct ocfs2_lock_res *lockres, | |||
104 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, | 104 | static void ocfs2_dentry_post_unlock(struct ocfs2_super *osb, |
105 | struct ocfs2_lock_res *lockres); | 105 | struct ocfs2_lock_res *lockres); |
106 | 106 | ||
107 | |||
108 | #define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) | ||
109 | |||
110 | /* This aids in debugging situations where a bad LVB might be involved. */ | ||
111 | static void ocfs2_dump_meta_lvb_info(u64 level, | ||
112 | const char *function, | ||
113 | unsigned int line, | ||
114 | struct ocfs2_lock_res *lockres) | ||
115 | { | ||
116 | struct ocfs2_meta_lvb *lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb; | ||
117 | |||
118 | mlog(level, "LVB information for %s (called from %s:%u):\n", | ||
119 | lockres->l_name, function, line); | ||
120 | mlog(level, "version: %u, clusters: %u, generation: 0x%x\n", | ||
121 | lvb->lvb_version, be32_to_cpu(lvb->lvb_iclusters), | ||
122 | be32_to_cpu(lvb->lvb_igeneration)); | ||
123 | mlog(level, "size: %llu, uid %u, gid %u, mode 0x%x\n", | ||
124 | (unsigned long long)be64_to_cpu(lvb->lvb_isize), | ||
125 | be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid), | ||
126 | be16_to_cpu(lvb->lvb_imode)); | ||
127 | mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, " | ||
128 | "mtime_packed 0x%llx iattr 0x%x\n", be16_to_cpu(lvb->lvb_inlink), | ||
129 | (long long)be64_to_cpu(lvb->lvb_iatime_packed), | ||
130 | (long long)be64_to_cpu(lvb->lvb_ictime_packed), | ||
131 | (long long)be64_to_cpu(lvb->lvb_imtime_packed), | ||
132 | be32_to_cpu(lvb->lvb_iattr)); | ||
133 | } | ||
134 | |||
135 | |||
107 | /* | 136 | /* |
108 | * OCFS2 Lock Resource Operations | 137 | * OCFS2 Lock Resource Operations |
109 | * | 138 | * |
@@ -3078,28 +3107,3 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb, | |||
3078 | 3107 | ||
3079 | mlog_exit_void(); | 3108 | mlog_exit_void(); |
3080 | } | 3109 | } |
3081 | |||
3082 | /* This aids in debugging situations where a bad LVB might be involved. */ | ||
3083 | void ocfs2_dump_meta_lvb_info(u64 level, | ||
3084 | const char *function, | ||
3085 | unsigned int line, | ||
3086 | struct ocfs2_lock_res *lockres) | ||
3087 | { | ||
3088 | struct ocfs2_meta_lvb *lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb; | ||
3089 | |||
3090 | mlog(level, "LVB information for %s (called from %s:%u):\n", | ||
3091 | lockres->l_name, function, line); | ||
3092 | mlog(level, "version: %u, clusters: %u, generation: 0x%x\n", | ||
3093 | lvb->lvb_version, be32_to_cpu(lvb->lvb_iclusters), | ||
3094 | be32_to_cpu(lvb->lvb_igeneration)); | ||
3095 | mlog(level, "size: %llu, uid %u, gid %u, mode 0x%x\n", | ||
3096 | (unsigned long long)be64_to_cpu(lvb->lvb_isize), | ||
3097 | be32_to_cpu(lvb->lvb_iuid), be32_to_cpu(lvb->lvb_igid), | ||
3098 | be16_to_cpu(lvb->lvb_imode)); | ||
3099 | mlog(level, "nlink %u, atime_packed 0x%llx, ctime_packed 0x%llx, " | ||
3100 | "mtime_packed 0x%llx iattr 0x%x\n", be16_to_cpu(lvb->lvb_inlink), | ||
3101 | (long long)be64_to_cpu(lvb->lvb_iatime_packed), | ||
3102 | (long long)be64_to_cpu(lvb->lvb_ictime_packed), | ||
3103 | (long long)be64_to_cpu(lvb->lvb_imtime_packed), | ||
3104 | be32_to_cpu(lvb->lvb_iattr)); | ||
3105 | } | ||
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 59cb566e7983..492bad32a8c0 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -119,11 +119,4 @@ void ocfs2_process_blocked_lock(struct ocfs2_super *osb, | |||
119 | struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); | 119 | struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void); |
120 | void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug); | 120 | void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug); |
121 | 121 | ||
122 | /* aids in debugging and tracking lvbs */ | ||
123 | void ocfs2_dump_meta_lvb_info(u64 level, | ||
124 | const char *function, | ||
125 | unsigned int line, | ||
126 | struct ocfs2_lock_res *lockres); | ||
127 | #define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres) | ||
128 | |||
129 | #endif /* DLMGLUE_H */ | 122 | #endif /* DLMGLUE_H */ |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index 56e1fefc1205..bc48177bd183 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -140,7 +140,7 @@ bail: | |||
140 | return parent; | 140 | return parent; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int ocfs2_encode_fh(struct dentry *dentry, __be32 *fh, int *max_len, | 143 | static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len, |
144 | int connectable) | 144 | int connectable) |
145 | { | 145 | { |
146 | struct inode *inode = dentry->d_inode; | 146 | struct inode *inode = dentry->d_inode; |
@@ -148,6 +148,7 @@ static int ocfs2_encode_fh(struct dentry *dentry, __be32 *fh, int *max_len, | |||
148 | int type = 1; | 148 | int type = 1; |
149 | u64 blkno; | 149 | u64 blkno; |
150 | u32 generation; | 150 | u32 generation; |
151 | __le32 *fh = (__force __le32 *) fh_in; | ||
151 | 152 | ||
152 | mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry, | 153 | mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry, |
153 | dentry->d_name.len, dentry->d_name.name, | 154 | dentry->d_name.len, dentry->d_name.name, |
@@ -199,7 +200,7 @@ bail: | |||
199 | return type; | 200 | return type; |
200 | } | 201 | } |
201 | 202 | ||
202 | static struct dentry *ocfs2_decode_fh(struct super_block *sb, __be32 *fh, | 203 | static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in, |
203 | int fh_len, int fileid_type, | 204 | int fh_len, int fileid_type, |
204 | int (*acceptable)(void *context, | 205 | int (*acceptable)(void *context, |
205 | struct dentry *de), | 206 | struct dentry *de), |
@@ -207,6 +208,7 @@ static struct dentry *ocfs2_decode_fh(struct super_block *sb, __be32 *fh, | |||
207 | { | 208 | { |
208 | struct ocfs2_inode_handle handle, parent; | 209 | struct ocfs2_inode_handle handle, parent; |
209 | struct dentry *ret = NULL; | 210 | struct dentry *ret = NULL; |
211 | __le32 *fh = (__force __le32 *) fh_in; | ||
210 | 212 | ||
211 | mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n", | 213 | mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n", |
212 | sb, fh, fh_len, fileid_type, acceptable, context); | 214 | sb, fh, fh_len, fileid_type, acceptable, context); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 520a2a6d7670..9395b4fa547d 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -207,10 +207,10 @@ out: | |||
207 | return ret; | 207 | return ret; |
208 | } | 208 | } |
209 | 209 | ||
210 | int ocfs2_set_inode_size(handle_t *handle, | 210 | static int ocfs2_set_inode_size(handle_t *handle, |
211 | struct inode *inode, | 211 | struct inode *inode, |
212 | struct buffer_head *fe_bh, | 212 | struct buffer_head *fe_bh, |
213 | u64 new_i_size) | 213 | u64 new_i_size) |
214 | { | 214 | { |
215 | int status; | 215 | int status; |
216 | 216 | ||
@@ -713,7 +713,8 @@ restarted_transaction: | |||
713 | } | 713 | } |
714 | 714 | ||
715 | mlog(0, "fe: i_clusters = %u, i_size=%llu\n", | 715 | mlog(0, "fe: i_clusters = %u, i_size=%llu\n", |
716 | fe->i_clusters, (unsigned long long)fe->i_size); | 716 | le32_to_cpu(fe->i_clusters), |
717 | (unsigned long long)le64_to_cpu(fe->i_size)); | ||
717 | mlog(0, "inode: ip_clusters=%u, i_size=%lld\n", | 718 | mlog(0, "inode: ip_clusters=%u, i_size=%lld\n", |
718 | OCFS2_I(inode)->ip_clusters, i_size_read(inode)); | 719 | OCFS2_I(inode)->ip_clusters, i_size_read(inode)); |
719 | 720 | ||
@@ -1853,6 +1854,9 @@ const struct file_operations ocfs2_fops = { | |||
1853 | .aio_read = ocfs2_file_aio_read, | 1854 | .aio_read = ocfs2_file_aio_read, |
1854 | .aio_write = ocfs2_file_aio_write, | 1855 | .aio_write = ocfs2_file_aio_write, |
1855 | .ioctl = ocfs2_ioctl, | 1856 | .ioctl = ocfs2_ioctl, |
1857 | #ifdef CONFIG_COMPAT | ||
1858 | .compat_ioctl = ocfs2_compat_ioctl, | ||
1859 | #endif | ||
1856 | .splice_read = ocfs2_file_splice_read, | 1860 | .splice_read = ocfs2_file_splice_read, |
1857 | .splice_write = ocfs2_file_splice_write, | 1861 | .splice_write = ocfs2_file_splice_write, |
1858 | }; | 1862 | }; |
@@ -1862,4 +1866,7 @@ const struct file_operations ocfs2_dops = { | |||
1862 | .readdir = ocfs2_readdir, | 1866 | .readdir = ocfs2_readdir, |
1863 | .fsync = ocfs2_sync_file, | 1867 | .fsync = ocfs2_sync_file, |
1864 | .ioctl = ocfs2_ioctl, | 1868 | .ioctl = ocfs2_ioctl, |
1869 | #ifdef CONFIG_COMPAT | ||
1870 | .compat_ioctl = ocfs2_compat_ioctl, | ||
1871 | #endif | ||
1865 | }; | 1872 | }; |
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 2c4460fced52..a4dd1fa1822b 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -56,11 +56,6 @@ int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
56 | int ocfs2_permission(struct inode *inode, int mask, | 56 | int ocfs2_permission(struct inode *inode, int mask, |
57 | struct nameidata *nd); | 57 | struct nameidata *nd); |
58 | 58 | ||
59 | int ocfs2_set_inode_size(handle_t *handle, | ||
60 | struct inode *inode, | ||
61 | struct buffer_head *fe_bh, | ||
62 | u64 new_i_size); | ||
63 | |||
64 | int ocfs2_should_update_atime(struct inode *inode, | 59 | int ocfs2_should_update_atime(struct inode *inode, |
65 | struct vfsmount *vfsmnt); | 60 | struct vfsmount *vfsmnt); |
66 | int ocfs2_update_inode_atime(struct inode *inode, | 61 | int ocfs2_update_inode_atime(struct inode *inode, |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 21a605079c62..bc844bfe607c 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -89,6 +89,25 @@ void ocfs2_set_inode_flags(struct inode *inode) | |||
89 | inode->i_flags |= S_DIRSYNC; | 89 | inode->i_flags |= S_DIRSYNC; |
90 | } | 90 | } |
91 | 91 | ||
92 | /* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */ | ||
93 | void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi) | ||
94 | { | ||
95 | unsigned int flags = oi->vfs_inode.i_flags; | ||
96 | |||
97 | oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL| | ||
98 | OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL); | ||
99 | if (flags & S_SYNC) | ||
100 | oi->ip_attr |= OCFS2_SYNC_FL; | ||
101 | if (flags & S_APPEND) | ||
102 | oi->ip_attr |= OCFS2_APPEND_FL; | ||
103 | if (flags & S_IMMUTABLE) | ||
104 | oi->ip_attr |= OCFS2_IMMUTABLE_FL; | ||
105 | if (flags & S_NOATIME) | ||
106 | oi->ip_attr |= OCFS2_NOATIME_FL; | ||
107 | if (flags & S_DIRSYNC) | ||
108 | oi->ip_attr |= OCFS2_DIRSYNC_FL; | ||
109 | } | ||
110 | |||
92 | struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags) | 111 | struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags) |
93 | { | 112 | { |
94 | struct inode *inode = NULL; | 113 | struct inode *inode = NULL; |
@@ -196,7 +215,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
196 | int status = -EINVAL; | 215 | int status = -EINVAL; |
197 | 216 | ||
198 | mlog_entry("(0x%p, size:%llu)\n", inode, | 217 | mlog_entry("(0x%p, size:%llu)\n", inode, |
199 | (unsigned long long)fe->i_size); | 218 | (unsigned long long)le64_to_cpu(fe->i_size)); |
200 | 219 | ||
201 | sb = inode->i_sb; | 220 | sb = inode->i_sb; |
202 | osb = OCFS2_SB(sb); | 221 | osb = OCFS2_SB(sb); |
@@ -248,7 +267,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
248 | mlog(ML_ERROR, | 267 | mlog(ML_ERROR, |
249 | "ip_blkno %llu != i_blkno %llu!\n", | 268 | "ip_blkno %llu != i_blkno %llu!\n", |
250 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 269 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
251 | (unsigned long long)fe->i_blkno); | 270 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
252 | 271 | ||
253 | inode->i_nlink = le16_to_cpu(fe->i_links_count); | 272 | inode->i_nlink = le16_to_cpu(fe->i_links_count); |
254 | 273 | ||
@@ -301,7 +320,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
301 | * the generation argument to | 320 | * the generation argument to |
302 | * ocfs2_inode_lock_res_init() will have to change. | 321 | * ocfs2_inode_lock_res_init() will have to change. |
303 | */ | 322 | */ |
304 | BUG_ON(fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)); | 323 | BUG_ON(le32_to_cpu(fe->i_flags) & OCFS2_SYSTEM_FL); |
305 | 324 | ||
306 | ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres, | 325 | ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres, |
307 | OCFS2_LOCK_TYPE_META, 0, inode); | 326 | OCFS2_LOCK_TYPE_META, 0, inode); |
@@ -437,7 +456,8 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
437 | fe = (struct ocfs2_dinode *) bh->b_data; | 456 | fe = (struct ocfs2_dinode *) bh->b_data; |
438 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 457 | if (!OCFS2_IS_VALID_DINODE(fe)) { |
439 | mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n", | 458 | mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n", |
440 | (unsigned long long)fe->i_blkno, 7, fe->i_signature); | 459 | (unsigned long long)le64_to_cpu(fe->i_blkno), 7, |
460 | fe->i_signature); | ||
441 | goto bail; | 461 | goto bail; |
442 | } | 462 | } |
443 | 463 | ||
@@ -812,8 +832,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, | |||
812 | "Inode %llu (on-disk %llu) not orphaned! " | 832 | "Inode %llu (on-disk %llu) not orphaned! " |
813 | "Disk flags 0x%x, inode flags 0x%x\n", | 833 | "Disk flags 0x%x, inode flags 0x%x\n", |
814 | (unsigned long long)oi->ip_blkno, | 834 | (unsigned long long)oi->ip_blkno, |
815 | (unsigned long long)di->i_blkno, di->i_flags, | 835 | (unsigned long long)le64_to_cpu(di->i_blkno), |
816 | oi->ip_flags); | 836 | le32_to_cpu(di->i_flags), oi->ip_flags); |
817 | goto bail; | 837 | goto bail; |
818 | } | 838 | } |
819 | 839 | ||
@@ -1106,8 +1126,10 @@ struct buffer_head *ocfs2_bread(struct inode *inode, | |||
1106 | return NULL; | 1126 | return NULL; |
1107 | } | 1127 | } |
1108 | 1128 | ||
1129 | down_read(&OCFS2_I(inode)->ip_alloc_sem); | ||
1109 | tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, | 1130 | tmperr = ocfs2_extent_map_get_blocks(inode, block, &p_blkno, NULL, |
1110 | NULL); | 1131 | NULL); |
1132 | up_read(&OCFS2_I(inode)->ip_alloc_sem); | ||
1111 | if (tmperr < 0) { | 1133 | if (tmperr < 0) { |
1112 | mlog_errno(tmperr); | 1134 | mlog_errno(tmperr); |
1113 | goto fail; | 1135 | goto fail; |
@@ -1197,6 +1219,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle, | |||
1197 | 1219 | ||
1198 | spin_lock(&OCFS2_I(inode)->ip_lock); | 1220 | spin_lock(&OCFS2_I(inode)->ip_lock); |
1199 | fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); | 1221 | fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); |
1222 | ocfs2_get_inode_flags(OCFS2_I(inode)); | ||
1200 | fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr); | 1223 | fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr); |
1201 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 1224 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
1202 | 1225 | ||
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 03ae075869ee..a41d0817121b 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h | |||
@@ -141,6 +141,7 @@ int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); | |||
141 | int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb); | 141 | int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb); |
142 | 142 | ||
143 | void ocfs2_set_inode_flags(struct inode *inode); | 143 | void ocfs2_set_inode_flags(struct inode *inode); |
144 | void ocfs2_get_inode_flags(struct ocfs2_inode_info *oi); | ||
144 | 145 | ||
145 | static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode) | 146 | static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode) |
146 | { | 147 | { |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 4768be5f3086..f3ad21ad9aed 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -31,6 +31,7 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) | |||
31 | mlog_errno(status); | 31 | mlog_errno(status); |
32 | return status; | 32 | return status; |
33 | } | 33 | } |
34 | ocfs2_get_inode_flags(OCFS2_I(inode)); | ||
34 | *flags = OCFS2_I(inode)->ip_attr; | 35 | *flags = OCFS2_I(inode)->ip_attr; |
35 | ocfs2_meta_unlock(inode, 0); | 36 | ocfs2_meta_unlock(inode, 0); |
36 | 37 | ||
@@ -134,3 +135,26 @@ int ocfs2_ioctl(struct inode * inode, struct file * filp, | |||
134 | } | 135 | } |
135 | } | 136 | } |
136 | 137 | ||
138 | #ifdef CONFIG_COMPAT | ||
139 | long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) | ||
140 | { | ||
141 | struct inode *inode = file->f_path.dentry->d_inode; | ||
142 | int ret; | ||
143 | |||
144 | switch (cmd) { | ||
145 | case OCFS2_IOC32_GETFLAGS: | ||
146 | cmd = OCFS2_IOC_GETFLAGS; | ||
147 | break; | ||
148 | case OCFS2_IOC32_SETFLAGS: | ||
149 | cmd = OCFS2_IOC_SETFLAGS; | ||
150 | break; | ||
151 | default: | ||
152 | return -ENOIOCTLCMD; | ||
153 | } | ||
154 | |||
155 | lock_kernel(); | ||
156 | ret = ocfs2_ioctl(inode, file, cmd, arg); | ||
157 | unlock_kernel(); | ||
158 | return ret; | ||
159 | } | ||
160 | #endif | ||
diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h index 4a7c82931dba..4d6c4f430d0d 100644 --- a/fs/ocfs2/ioctl.h +++ b/fs/ocfs2/ioctl.h | |||
@@ -12,5 +12,6 @@ | |||
12 | 12 | ||
13 | int ocfs2_ioctl(struct inode * inode, struct file * filp, | 13 | int ocfs2_ioctl(struct inode * inode, struct file * filp, |
14 | unsigned int cmd, unsigned long arg); | 14 | unsigned int cmd, unsigned long arg); |
15 | long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg); | ||
15 | 16 | ||
16 | #endif /* OCFS2_IOCTL_H */ | 17 | #endif /* OCFS2_IOCTL_H */ |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 5a8a90d1c787..dc1188081720 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
@@ -435,7 +435,8 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, | |||
435 | * handle the errors in a specific manner, so no need | 435 | * handle the errors in a specific manner, so no need |
436 | * to call ocfs2_error() here. */ | 436 | * to call ocfs2_error() here. */ |
437 | mlog(ML_ERROR, "Journal dinode %llu has invalid " | 437 | mlog(ML_ERROR, "Journal dinode %llu has invalid " |
438 | "signature: %.*s", (unsigned long long)fe->i_blkno, 7, | 438 | "signature: %.*s", |
439 | (unsigned long long)le64_to_cpu(fe->i_blkno), 7, | ||
439 | fe->i_signature); | 440 | fe->i_signature); |
440 | status = -EIO; | 441 | status = -EIO; |
441 | goto out; | 442 | goto out; |
@@ -742,7 +743,7 @@ void ocfs2_complete_recovery(struct work_struct *work) | |||
742 | la_dinode = item->lri_la_dinode; | 743 | la_dinode = item->lri_la_dinode; |
743 | if (la_dinode) { | 744 | if (la_dinode) { |
744 | mlog(0, "Clean up local alloc %llu\n", | 745 | mlog(0, "Clean up local alloc %llu\n", |
745 | (unsigned long long)la_dinode->i_blkno); | 746 | (unsigned long long)le64_to_cpu(la_dinode->i_blkno)); |
746 | 747 | ||
747 | ret = ocfs2_complete_local_alloc_recovery(osb, | 748 | ret = ocfs2_complete_local_alloc_recovery(osb, |
748 | la_dinode); | 749 | la_dinode); |
@@ -755,7 +756,7 @@ void ocfs2_complete_recovery(struct work_struct *work) | |||
755 | tl_dinode = item->lri_tl_dinode; | 756 | tl_dinode = item->lri_tl_dinode; |
756 | if (tl_dinode) { | 757 | if (tl_dinode) { |
757 | mlog(0, "Clean up truncate log %llu\n", | 758 | mlog(0, "Clean up truncate log %llu\n", |
758 | (unsigned long long)tl_dinode->i_blkno); | 759 | (unsigned long long)le64_to_cpu(tl_dinode->i_blkno)); |
759 | 760 | ||
760 | ret = ocfs2_complete_truncate_log_recovery(osb, | 761 | ret = ocfs2_complete_truncate_log_recovery(osb, |
761 | tl_dinode); | 762 | tl_dinode); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 2bcf353fd7c5..36289e6295ce 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -578,8 +578,9 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
578 | if (ocfs2_populate_inode(inode, fe, 1) < 0) { | 578 | if (ocfs2_populate_inode(inode, fe, 1) < 0) { |
579 | mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, " | 579 | mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, " |
580 | "i_blkno=%llu, i_ino=%lu\n", | 580 | "i_blkno=%llu, i_ino=%lu\n", |
581 | (unsigned long long) (*new_fe_bh)->b_blocknr, | 581 | (unsigned long long)(*new_fe_bh)->b_blocknr, |
582 | (unsigned long long)fe->i_blkno, inode->i_ino); | 582 | (unsigned long long)le64_to_cpu(fe->i_blkno), |
583 | inode->i_ino); | ||
583 | BUG(); | 584 | BUG(); |
584 | } | 585 | } |
585 | 586 | ||
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 82cc92dcf8a6..a860633e833f 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -363,9 +363,9 @@ static inline int ocfs2_mount_local(struct ocfs2_super *osb) | |||
363 | typeof(__di) ____di = (__di); \ | 363 | typeof(__di) ____di = (__di); \ |
364 | ocfs2_error((__sb), \ | 364 | ocfs2_error((__sb), \ |
365 | "Dinode # %llu has bad signature %.*s", \ | 365 | "Dinode # %llu has bad signature %.*s", \ |
366 | (unsigned long long)(____di)->i_blkno, 7, \ | 366 | (unsigned long long)le64_to_cpu((____di)->i_blkno), 7, \ |
367 | (____di)->i_signature); \ | 367 | (____di)->i_signature); \ |
368 | } while (0); | 368 | } while (0) |
369 | 369 | ||
370 | #define OCFS2_IS_VALID_EXTENT_BLOCK(ptr) \ | 370 | #define OCFS2_IS_VALID_EXTENT_BLOCK(ptr) \ |
371 | (!strcmp((ptr)->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE)) | 371 | (!strcmp((ptr)->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE)) |
@@ -374,9 +374,9 @@ static inline int ocfs2_mount_local(struct ocfs2_super *osb) | |||
374 | typeof(__eb) ____eb = (__eb); \ | 374 | typeof(__eb) ____eb = (__eb); \ |
375 | ocfs2_error((__sb), \ | 375 | ocfs2_error((__sb), \ |
376 | "Extent Block # %llu has bad signature %.*s", \ | 376 | "Extent Block # %llu has bad signature %.*s", \ |
377 | (unsigned long long)(____eb)->h_blkno, 7, \ | 377 | (unsigned long long)le64_to_cpu((____eb)->h_blkno), 7, \ |
378 | (____eb)->h_signature); \ | 378 | (____eb)->h_signature); \ |
379 | } while (0); | 379 | } while (0) |
380 | 380 | ||
381 | #define OCFS2_IS_VALID_GROUP_DESC(ptr) \ | 381 | #define OCFS2_IS_VALID_GROUP_DESC(ptr) \ |
382 | (!strcmp((ptr)->bg_signature, OCFS2_GROUP_DESC_SIGNATURE)) | 382 | (!strcmp((ptr)->bg_signature, OCFS2_GROUP_DESC_SIGNATURE)) |
@@ -385,9 +385,9 @@ static inline int ocfs2_mount_local(struct ocfs2_super *osb) | |||
385 | typeof(__gd) ____gd = (__gd); \ | 385 | typeof(__gd) ____gd = (__gd); \ |
386 | ocfs2_error((__sb), \ | 386 | ocfs2_error((__sb), \ |
387 | "Group Descriptor # %llu has bad signature %.*s", \ | 387 | "Group Descriptor # %llu has bad signature %.*s", \ |
388 | (unsigned long long)(____gd)->bg_blkno, 7, \ | 388 | (unsigned long long)le64_to_cpu((____gd)->bg_blkno), 7, \ |
389 | (____gd)->bg_signature); \ | 389 | (____gd)->bg_signature); \ |
390 | } while (0); | 390 | } while (0) |
391 | 391 | ||
392 | static inline unsigned long ino_from_blkno(struct super_block *sb, | 392 | static inline unsigned long ino_from_blkno(struct super_block *sb, |
393 | u64 blkno) | 393 | u64 blkno) |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 71306479c68f..f0d9eb08547a 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -166,6 +166,8 @@ | |||
166 | */ | 166 | */ |
167 | #define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) | 167 | #define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) |
168 | #define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) | 168 | #define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) |
169 | #define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) | ||
170 | #define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) | ||
169 | 171 | ||
170 | /* | 172 | /* |
171 | * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) | 173 | * Journal Flags (ocfs2_dinode.id1.journal1.i_flags) |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 0da655ae5d6f..e3437626d183 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -849,9 +849,9 @@ static int ocfs2_relink_block_group(handle_t *handle, | |||
849 | } | 849 | } |
850 | 850 | ||
851 | mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n", | 851 | mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n", |
852 | (unsigned long long)fe->i_blkno, chain, | 852 | (unsigned long long)le64_to_cpu(fe->i_blkno), chain, |
853 | (unsigned long long)bg->bg_blkno, | 853 | (unsigned long long)le64_to_cpu(bg->bg_blkno), |
854 | (unsigned long long)prev_bg->bg_blkno); | 854 | (unsigned long long)le64_to_cpu(prev_bg->bg_blkno)); |
855 | 855 | ||
856 | fe_ptr = le64_to_cpu(fe->id2.i_chain.cl_recs[chain].c_blkno); | 856 | fe_ptr = le64_to_cpu(fe->id2.i_chain.cl_recs[chain].c_blkno); |
857 | bg_ptr = le64_to_cpu(bg->bg_next_group); | 857 | bg_ptr = le64_to_cpu(bg->bg_next_group); |
@@ -1162,7 +1162,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | mlog(0, "alloc succeeds: we give %u bits from block group %llu\n", | 1164 | mlog(0, "alloc succeeds: we give %u bits from block group %llu\n", |
1165 | tmp_bits, (unsigned long long)bg->bg_blkno); | 1165 | tmp_bits, (unsigned long long)le64_to_cpu(bg->bg_blkno)); |
1166 | 1166 | ||
1167 | *num_bits = tmp_bits; | 1167 | *num_bits = tmp_bits; |
1168 | 1168 | ||
@@ -1227,7 +1227,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | mlog(0, "Allocated %u bits from suballocator %llu\n", *num_bits, | 1229 | mlog(0, "Allocated %u bits from suballocator %llu\n", *num_bits, |
1230 | (unsigned long long)fe->i_blkno); | 1230 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
1231 | 1231 | ||
1232 | *bg_blkno = le64_to_cpu(bg->bg_blkno); | 1232 | *bg_blkno = le64_to_cpu(bg->bg_blkno); |
1233 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); | 1233 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 5c9e8243691f..7c5e3f5d6634 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -937,8 +937,7 @@ static void ocfs2_inode_init_once(void *data, | |||
937 | { | 937 | { |
938 | struct ocfs2_inode_info *oi = data; | 938 | struct ocfs2_inode_info *oi = data; |
939 | 939 | ||
940 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 940 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
941 | SLAB_CTOR_CONSTRUCTOR) { | ||
942 | oi->ip_flags = 0; | 941 | oi->ip_flags = 0; |
943 | oi->ip_open_count = 0; | 942 | oi->ip_open_count = 0; |
944 | spin_lock_init(&oi->ip_lock); | 943 | spin_lock_init(&oi->ip_lock); |
@@ -1538,7 +1537,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, | |||
1538 | } else if (bh->b_blocknr != le64_to_cpu(di->i_blkno)) { | 1537 | } else if (bh->b_blocknr != le64_to_cpu(di->i_blkno)) { |
1539 | mlog(ML_ERROR, "bad block number on superblock: " | 1538 | mlog(ML_ERROR, "bad block number on superblock: " |
1540 | "found %llu, should be %llu\n", | 1539 | "found %llu, should be %llu\n", |
1541 | (unsigned long long)di->i_blkno, | 1540 | (unsigned long long)le64_to_cpu(di->i_blkno), |
1542 | (unsigned long long)bh->b_blocknr); | 1541 | (unsigned long long)bh->b_blocknr); |
1543 | } else if (le32_to_cpu(di->id2.i_super.s_clustersize_bits) < 12 || | 1542 | } else if (le32_to_cpu(di->id2.i_super.s_clustersize_bits) < 12 || |
1544 | le32_to_cpu(di->id2.i_super.s_clustersize_bits) > 20) { | 1543 | le32_to_cpu(di->id2.i_super.s_clustersize_bits) > 20) { |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index 40dc1a51f4a9..7134007ba22f 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -67,16 +67,9 @@ static char *ocfs2_page_getlink(struct dentry * dentry, | |||
67 | page = read_mapping_page(mapping, 0, NULL); | 67 | page = read_mapping_page(mapping, 0, NULL); |
68 | if (IS_ERR(page)) | 68 | if (IS_ERR(page)) |
69 | goto sync_fail; | 69 | goto sync_fail; |
70 | wait_on_page_locked(page); | ||
71 | if (!PageUptodate(page)) | ||
72 | goto async_fail; | ||
73 | *ppage = page; | 70 | *ppage = page; |
74 | return kmap(page); | 71 | return kmap(page); |
75 | 72 | ||
76 | async_fail: | ||
77 | page_cache_release(page); | ||
78 | return ERR_PTR(-EIO); | ||
79 | |||
80 | sync_fail: | 73 | sync_fail: |
81 | return (char*)page; | 74 | return (char*)page; |
82 | } | 75 | } |
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index bde1c164417d..731a90e9f0cd 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -419,8 +419,7 @@ static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned | |||
419 | { | 419 | { |
420 | struct op_inode_info *oi = (struct op_inode_info *) data; | 420 | struct op_inode_info *oi = (struct op_inode_info *) data; |
421 | 421 | ||
422 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 422 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
423 | SLAB_CTOR_CONSTRUCTOR) | ||
424 | inode_init_once(&oi->vfs_inode); | 423 | inode_init_once(&oi->vfs_inode); |
425 | } | 424 | } |
426 | 425 | ||
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c index 1bc9f372c7d4..e3491328596b 100644 --- a/fs/partitions/acorn.c +++ b/fs/partitions/acorn.c | |||
@@ -271,7 +271,7 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev) | |||
271 | extern void xd_set_geometry(struct block_device *, | 271 | extern void xd_set_geometry(struct block_device *, |
272 | unsigned char, unsigned char, unsigned int); | 272 | unsigned char, unsigned char, unsigned int); |
273 | xd_set_geometry(bdev, dr->secspertrack, heads, 1); | 273 | xd_set_geometry(bdev, dr->secspertrack, heads, 1); |
274 | invalidate_bdev(bdev, 1); | 274 | invalidate_bh_lrus(); |
275 | truncate_inode_pages(bdev->bd_inode->i_mapping, 0); | 275 | truncate_inode_pages(bdev->bd_inode->i_mapping, 0); |
276 | } | 276 | } |
277 | #endif | 277 | #endif |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 8a7d0035ad7a..6b9dae3f0e6c 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -312,7 +312,7 @@ static struct attribute * default_attrs[] = { | |||
312 | NULL, | 312 | NULL, |
313 | }; | 313 | }; |
314 | 314 | ||
315 | extern struct subsystem block_subsys; | 315 | extern struct kset block_subsys; |
316 | 316 | ||
317 | static void part_release(struct kobject *kobj) | 317 | static void part_release(struct kobject *kobj) |
318 | { | 318 | { |
@@ -388,7 +388,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, | |||
388 | kobject_add(&p->kobj); | 388 | kobject_add(&p->kobj); |
389 | if (!disk->part_uevent_suppress) | 389 | if (!disk->part_uevent_suppress) |
390 | kobject_uevent(&p->kobj, KOBJ_ADD); | 390 | kobject_uevent(&p->kobj, KOBJ_ADD); |
391 | sysfs_create_link(&p->kobj, &block_subsys.kset.kobj, "subsystem"); | 391 | sysfs_create_link(&p->kobj, &block_subsys.kobj, "subsystem"); |
392 | if (flags & ADDPART_FLAG_WHOLEDISK) { | 392 | if (flags & ADDPART_FLAG_WHOLEDISK) { |
393 | static struct attribute addpartattr = { | 393 | static struct attribute addpartattr = { |
394 | .name = "whole_disk", | 394 | .name = "whole_disk", |
@@ -444,7 +444,7 @@ static int disk_sysfs_symlinks(struct gendisk *disk) | |||
444 | goto err_out_dev_link; | 444 | goto err_out_dev_link; |
445 | } | 445 | } |
446 | 446 | ||
447 | err = sysfs_create_link(&disk->kobj, &block_subsys.kset.kobj, | 447 | err = sysfs_create_link(&disk->kobj, &block_subsys.kobj, |
448 | "subsystem"); | 448 | "subsystem"); |
449 | if (err) | 449 | if (err) |
450 | goto err_out_disk_name_lnk; | 450 | goto err_out_disk_name_lnk; |
@@ -569,9 +569,6 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) | |||
569 | page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), | 569 | page = read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), |
570 | NULL); | 570 | NULL); |
571 | if (!IS_ERR(page)) { | 571 | if (!IS_ERR(page)) { |
572 | wait_on_page_locked(page); | ||
573 | if (!PageUptodate(page)) | ||
574 | goto fail; | ||
575 | if (PageError(page)) | 572 | if (PageError(page)) |
576 | goto fail; | 573 | goto fail; |
577 | p->v = page; | 574 | p->v = page; |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 989af5e55d1b..ec158dd02b3a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -715,6 +715,40 @@ static const struct file_operations proc_oom_adjust_operations = { | |||
715 | .write = oom_adjust_write, | 715 | .write = oom_adjust_write, |
716 | }; | 716 | }; |
717 | 717 | ||
718 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, | ||
719 | size_t count, loff_t *ppos) | ||
720 | { | ||
721 | struct task_struct *task; | ||
722 | char buffer[PROC_NUMBUF], *end; | ||
723 | struct mm_struct *mm; | ||
724 | |||
725 | memset(buffer, 0, sizeof(buffer)); | ||
726 | if (count > sizeof(buffer) - 1) | ||
727 | count = sizeof(buffer) - 1; | ||
728 | if (copy_from_user(buffer, buf, count)) | ||
729 | return -EFAULT; | ||
730 | if (!simple_strtol(buffer, &end, 0)) | ||
731 | return -EINVAL; | ||
732 | if (*end == '\n') | ||
733 | end++; | ||
734 | task = get_proc_task(file->f_path.dentry->d_inode); | ||
735 | if (!task) | ||
736 | return -ESRCH; | ||
737 | mm = get_task_mm(task); | ||
738 | if (mm) { | ||
739 | clear_refs_smap(mm); | ||
740 | mmput(mm); | ||
741 | } | ||
742 | put_task_struct(task); | ||
743 | if (end - buffer == 0) | ||
744 | return -EIO; | ||
745 | return end - buffer; | ||
746 | } | ||
747 | |||
748 | static struct file_operations proc_clear_refs_operations = { | ||
749 | .write = clear_refs_write, | ||
750 | }; | ||
751 | |||
718 | #ifdef CONFIG_AUDITSYSCALL | 752 | #ifdef CONFIG_AUDITSYSCALL |
719 | #define TMPBUFLEN 21 | 753 | #define TMPBUFLEN 21 |
720 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, | 754 | static ssize_t proc_loginuid_read(struct file * file, char __user * buf, |
@@ -1851,6 +1885,7 @@ static struct pid_entry tgid_base_stuff[] = { | |||
1851 | REG("mounts", S_IRUGO, mounts), | 1885 | REG("mounts", S_IRUGO, mounts), |
1852 | REG("mountstats", S_IRUSR, mountstats), | 1886 | REG("mountstats", S_IRUSR, mountstats), |
1853 | #ifdef CONFIG_MMU | 1887 | #ifdef CONFIG_MMU |
1888 | REG("clear_refs", S_IWUSR, clear_refs), | ||
1854 | REG("smaps", S_IRUGO, smaps), | 1889 | REG("smaps", S_IRUGO, smaps), |
1855 | #endif | 1890 | #endif |
1856 | #ifdef CONFIG_SECURITY | 1891 | #ifdef CONFIG_SECURITY |
@@ -2132,6 +2167,7 @@ static struct pid_entry tid_base_stuff[] = { | |||
2132 | LNK("exe", exe), | 2167 | LNK("exe", exe), |
2133 | REG("mounts", S_IRUGO, mounts), | 2168 | REG("mounts", S_IRUGO, mounts), |
2134 | #ifdef CONFIG_MMU | 2169 | #ifdef CONFIG_MMU |
2170 | REG("clear_refs", S_IWUSR, clear_refs), | ||
2135 | REG("smaps", S_IRUGO, smaps), | 2171 | REG("smaps", S_IRUGO, smaps), |
2136 | #endif | 2172 | #endif |
2137 | #ifdef CONFIG_SECURITY | 2173 | #ifdef CONFIG_SECURITY |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index c372eb151a3a..22b1158389ae 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -109,8 +109,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
109 | { | 109 | { |
110 | struct proc_inode *ei = (struct proc_inode *) foo; | 110 | struct proc_inode *ei = (struct proc_inode *) foo; |
111 | 111 | ||
112 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 112 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
113 | SLAB_CTOR_CONSTRUCTOR) | ||
114 | inode_init_once(&ei->vfs_inode); | 113 | inode_init_once(&ei->vfs_inode); |
115 | } | 114 | } |
116 | 115 | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index e2c4c0a5c90d..75ec6523d29a 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -398,8 +398,6 @@ static const struct file_operations proc_modules_operations = { | |||
398 | #endif | 398 | #endif |
399 | 399 | ||
400 | #ifdef CONFIG_SLAB | 400 | #ifdef CONFIG_SLAB |
401 | extern struct seq_operations slabinfo_op; | ||
402 | extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); | ||
403 | static int slabinfo_open(struct inode *inode, struct file *file) | 401 | static int slabinfo_open(struct inode *inode, struct file *file) |
404 | { | 402 | { |
405 | return seq_open(file, &slabinfo_op); | 403 | return seq_open(file, &slabinfo_op); |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 7445980c8022..4008c060f7ef 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -120,6 +120,14 @@ struct mem_size_stats | |||
120 | unsigned long shared_dirty; | 120 | unsigned long shared_dirty; |
121 | unsigned long private_clean; | 121 | unsigned long private_clean; |
122 | unsigned long private_dirty; | 122 | unsigned long private_dirty; |
123 | unsigned long referenced; | ||
124 | }; | ||
125 | |||
126 | struct pmd_walker { | ||
127 | struct vm_area_struct *vma; | ||
128 | void *private; | ||
129 | void (*action)(struct vm_area_struct *, pmd_t *, unsigned long, | ||
130 | unsigned long, void *); | ||
123 | }; | 131 | }; |
124 | 132 | ||
125 | static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss) | 133 | static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss) |
@@ -181,18 +189,20 @@ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats | |||
181 | 189 | ||
182 | if (mss) | 190 | if (mss) |
183 | seq_printf(m, | 191 | seq_printf(m, |
184 | "Size: %8lu kB\n" | 192 | "Size: %8lu kB\n" |
185 | "Rss: %8lu kB\n" | 193 | "Rss: %8lu kB\n" |
186 | "Shared_Clean: %8lu kB\n" | 194 | "Shared_Clean: %8lu kB\n" |
187 | "Shared_Dirty: %8lu kB\n" | 195 | "Shared_Dirty: %8lu kB\n" |
188 | "Private_Clean: %8lu kB\n" | 196 | "Private_Clean: %8lu kB\n" |
189 | "Private_Dirty: %8lu kB\n", | 197 | "Private_Dirty: %8lu kB\n" |
198 | "Referenced: %8lu kB\n", | ||
190 | (vma->vm_end - vma->vm_start) >> 10, | 199 | (vma->vm_end - vma->vm_start) >> 10, |
191 | mss->resident >> 10, | 200 | mss->resident >> 10, |
192 | mss->shared_clean >> 10, | 201 | mss->shared_clean >> 10, |
193 | mss->shared_dirty >> 10, | 202 | mss->shared_dirty >> 10, |
194 | mss->private_clean >> 10, | 203 | mss->private_clean >> 10, |
195 | mss->private_dirty >> 10); | 204 | mss->private_dirty >> 10, |
205 | mss->referenced >> 10); | ||
196 | 206 | ||
197 | if (m->count < m->size) /* vma is copied successfully */ | 207 | if (m->count < m->size) /* vma is copied successfully */ |
198 | m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; | 208 | m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; |
@@ -205,15 +215,16 @@ static int show_map(struct seq_file *m, void *v) | |||
205 | } | 215 | } |
206 | 216 | ||
207 | static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | 217 | static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, |
208 | unsigned long addr, unsigned long end, | 218 | unsigned long addr, unsigned long end, |
209 | struct mem_size_stats *mss) | 219 | void *private) |
210 | { | 220 | { |
221 | struct mem_size_stats *mss = private; | ||
211 | pte_t *pte, ptent; | 222 | pte_t *pte, ptent; |
212 | spinlock_t *ptl; | 223 | spinlock_t *ptl; |
213 | struct page *page; | 224 | struct page *page; |
214 | 225 | ||
215 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); | 226 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); |
216 | do { | 227 | for (; addr != end; pte++, addr += PAGE_SIZE) { |
217 | ptent = *pte; | 228 | ptent = *pte; |
218 | if (!pte_present(ptent)) | 229 | if (!pte_present(ptent)) |
219 | continue; | 230 | continue; |
@@ -224,6 +235,9 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
224 | if (!page) | 235 | if (!page) |
225 | continue; | 236 | continue; |
226 | 237 | ||
238 | /* Accumulate the size in pages that have been accessed. */ | ||
239 | if (pte_young(ptent) || PageReferenced(page)) | ||
240 | mss->referenced += PAGE_SIZE; | ||
227 | if (page_mapcount(page) >= 2) { | 241 | if (page_mapcount(page) >= 2) { |
228 | if (pte_dirty(ptent)) | 242 | if (pte_dirty(ptent)) |
229 | mss->shared_dirty += PAGE_SIZE; | 243 | mss->shared_dirty += PAGE_SIZE; |
@@ -235,57 +249,99 @@ static void smaps_pte_range(struct vm_area_struct *vma, pmd_t *pmd, | |||
235 | else | 249 | else |
236 | mss->private_clean += PAGE_SIZE; | 250 | mss->private_clean += PAGE_SIZE; |
237 | } | 251 | } |
238 | } while (pte++, addr += PAGE_SIZE, addr != end); | 252 | } |
239 | pte_unmap_unlock(pte - 1, ptl); | 253 | pte_unmap_unlock(pte - 1, ptl); |
240 | cond_resched(); | 254 | cond_resched(); |
241 | } | 255 | } |
242 | 256 | ||
243 | static inline void smaps_pmd_range(struct vm_area_struct *vma, pud_t *pud, | 257 | static void clear_refs_pte_range(struct vm_area_struct *vma, pmd_t *pmd, |
244 | unsigned long addr, unsigned long end, | 258 | unsigned long addr, unsigned long end, |
245 | struct mem_size_stats *mss) | 259 | void *private) |
260 | { | ||
261 | pte_t *pte, ptent; | ||
262 | spinlock_t *ptl; | ||
263 | struct page *page; | ||
264 | |||
265 | pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); | ||
266 | for (; addr != end; pte++, addr += PAGE_SIZE) { | ||
267 | ptent = *pte; | ||
268 | if (!pte_present(ptent)) | ||
269 | continue; | ||
270 | |||
271 | page = vm_normal_page(vma, addr, ptent); | ||
272 | if (!page) | ||
273 | continue; | ||
274 | |||
275 | /* Clear accessed and referenced bits. */ | ||
276 | ptep_test_and_clear_young(vma, addr, pte); | ||
277 | ClearPageReferenced(page); | ||
278 | } | ||
279 | pte_unmap_unlock(pte - 1, ptl); | ||
280 | cond_resched(); | ||
281 | } | ||
282 | |||
283 | static inline void walk_pmd_range(struct pmd_walker *walker, pud_t *pud, | ||
284 | unsigned long addr, unsigned long end) | ||
246 | { | 285 | { |
247 | pmd_t *pmd; | 286 | pmd_t *pmd; |
248 | unsigned long next; | 287 | unsigned long next; |
249 | 288 | ||
250 | pmd = pmd_offset(pud, addr); | 289 | for (pmd = pmd_offset(pud, addr); addr != end; |
251 | do { | 290 | pmd++, addr = next) { |
252 | next = pmd_addr_end(addr, end); | 291 | next = pmd_addr_end(addr, end); |
253 | if (pmd_none_or_clear_bad(pmd)) | 292 | if (pmd_none_or_clear_bad(pmd)) |
254 | continue; | 293 | continue; |
255 | smaps_pte_range(vma, pmd, addr, next, mss); | 294 | walker->action(walker->vma, pmd, addr, next, walker->private); |
256 | } while (pmd++, addr = next, addr != end); | 295 | } |
257 | } | 296 | } |
258 | 297 | ||
259 | static inline void smaps_pud_range(struct vm_area_struct *vma, pgd_t *pgd, | 298 | static inline void walk_pud_range(struct pmd_walker *walker, pgd_t *pgd, |
260 | unsigned long addr, unsigned long end, | 299 | unsigned long addr, unsigned long end) |
261 | struct mem_size_stats *mss) | ||
262 | { | 300 | { |
263 | pud_t *pud; | 301 | pud_t *pud; |
264 | unsigned long next; | 302 | unsigned long next; |
265 | 303 | ||
266 | pud = pud_offset(pgd, addr); | 304 | for (pud = pud_offset(pgd, addr); addr != end; |
267 | do { | 305 | pud++, addr = next) { |
268 | next = pud_addr_end(addr, end); | 306 | next = pud_addr_end(addr, end); |
269 | if (pud_none_or_clear_bad(pud)) | 307 | if (pud_none_or_clear_bad(pud)) |
270 | continue; | 308 | continue; |
271 | smaps_pmd_range(vma, pud, addr, next, mss); | 309 | walk_pmd_range(walker, pud, addr, next); |
272 | } while (pud++, addr = next, addr != end); | 310 | } |
273 | } | 311 | } |
274 | 312 | ||
275 | static inline void smaps_pgd_range(struct vm_area_struct *vma, | 313 | /* |
276 | unsigned long addr, unsigned long end, | 314 | * walk_page_range - walk the page tables of a VMA with a callback |
277 | struct mem_size_stats *mss) | 315 | * @vma - VMA to walk |
316 | * @action - callback invoked for every bottom-level (PTE) page table | ||
317 | * @private - private data passed to the callback function | ||
318 | * | ||
319 | * Recursively walk the page table for the memory area in a VMA, calling | ||
320 | * a callback for every bottom-level (PTE) page table. | ||
321 | */ | ||
322 | static inline void walk_page_range(struct vm_area_struct *vma, | ||
323 | void (*action)(struct vm_area_struct *, | ||
324 | pmd_t *, unsigned long, | ||
325 | unsigned long, void *), | ||
326 | void *private) | ||
278 | { | 327 | { |
328 | unsigned long addr = vma->vm_start; | ||
329 | unsigned long end = vma->vm_end; | ||
330 | struct pmd_walker walker = { | ||
331 | .vma = vma, | ||
332 | .private = private, | ||
333 | .action = action, | ||
334 | }; | ||
279 | pgd_t *pgd; | 335 | pgd_t *pgd; |
280 | unsigned long next; | 336 | unsigned long next; |
281 | 337 | ||
282 | pgd = pgd_offset(vma->vm_mm, addr); | 338 | for (pgd = pgd_offset(vma->vm_mm, addr); addr != end; |
283 | do { | 339 | pgd++, addr = next) { |
284 | next = pgd_addr_end(addr, end); | 340 | next = pgd_addr_end(addr, end); |
285 | if (pgd_none_or_clear_bad(pgd)) | 341 | if (pgd_none_or_clear_bad(pgd)) |
286 | continue; | 342 | continue; |
287 | smaps_pud_range(vma, pgd, addr, next, mss); | 343 | walk_pud_range(&walker, pgd, addr, next); |
288 | } while (pgd++, addr = next, addr != end); | 344 | } |
289 | } | 345 | } |
290 | 346 | ||
291 | static int show_smap(struct seq_file *m, void *v) | 347 | static int show_smap(struct seq_file *m, void *v) |
@@ -295,10 +351,22 @@ static int show_smap(struct seq_file *m, void *v) | |||
295 | 351 | ||
296 | memset(&mss, 0, sizeof mss); | 352 | memset(&mss, 0, sizeof mss); |
297 | if (vma->vm_mm && !is_vm_hugetlb_page(vma)) | 353 | if (vma->vm_mm && !is_vm_hugetlb_page(vma)) |
298 | smaps_pgd_range(vma, vma->vm_start, vma->vm_end, &mss); | 354 | walk_page_range(vma, smaps_pte_range, &mss); |
299 | return show_map_internal(m, v, &mss); | 355 | return show_map_internal(m, v, &mss); |
300 | } | 356 | } |
301 | 357 | ||
358 | void clear_refs_smap(struct mm_struct *mm) | ||
359 | { | ||
360 | struct vm_area_struct *vma; | ||
361 | |||
362 | down_read(&mm->mmap_sem); | ||
363 | for (vma = mm->mmap; vma; vma = vma->vm_next) | ||
364 | if (vma->vm_mm && !is_vm_hugetlb_page(vma)) | ||
365 | walk_page_range(vma, clear_refs_pte_range, NULL); | ||
366 | flush_tlb_mm(mm); | ||
367 | up_read(&mm->mmap_sem); | ||
368 | } | ||
369 | |||
302 | static void *m_start(struct seq_file *m, loff_t *pos) | 370 | static void *m_start(struct seq_file *m, loff_t *pos) |
303 | { | 371 | { |
304 | struct proc_maps_private *priv = m->private; | 372 | struct proc_maps_private *priv = m->private; |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index d96050728c43..523e1098ae88 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
@@ -514,7 +514,7 @@ static int __init parse_crash_elf64_headers(void) | |||
514 | /* Do some basic Verification. */ | 514 | /* Do some basic Verification. */ |
515 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || | 515 | if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0 || |
516 | (ehdr.e_type != ET_CORE) || | 516 | (ehdr.e_type != ET_CORE) || |
517 | !elf_check_arch(&ehdr) || | 517 | !vmcore_elf_check_arch(&ehdr) || |
518 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || | 518 | ehdr.e_ident[EI_CLASS] != ELFCLASS64 || |
519 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || | 519 | ehdr.e_ident[EI_VERSION] != EV_CURRENT || |
520 | ehdr.e_version != EV_CURRENT || | 520 | ehdr.e_version != EV_CURRENT || |
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 83bc8e7824cd..75fc8498f2e2 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -536,8 +536,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, | |||
536 | { | 536 | { |
537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; | 537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; |
538 | 538 | ||
539 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | 539 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
540 | SLAB_CTOR_CONSTRUCTOR) | ||
541 | inode_init_once(&ei->vfs_inode); | 540 | inode_init_once(&ei->vfs_inode); |
542 | } | 541 | } |
543 | 542 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f13a7f164dc6..7054aaef0493 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -511,8 +511,7 @@ static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags | |||
511 | { | 511 | { |
512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; | 512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; |
513 | 513 | ||
514 | if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == | 514 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
515 | SLAB_CTOR_CONSTRUCTOR) { | ||
516 | INIT_LIST_HEAD(&ei->i_prealloc_list); | 515 | INIT_LIST_HEAD(&ei->i_prealloc_list); |
517 | inode_init_once(&ei->vfs_inode); | 516 | inode_init_once(&ei->vfs_inode); |
518 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL | 517 | #ifdef CONFIG_REISERFS_FS_POSIX_ACL |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 2cac56210e2b..bf6e58214538 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -410,11 +410,7 @@ static struct page *reiserfs_get_page(struct inode *dir, unsigned long n) | |||
410 | mapping_set_gfp_mask(mapping, GFP_NOFS); | 410 | mapping_set_gfp_mask(mapping, GFP_NOFS); |
411 | page = read_mapping_page(mapping, n, NULL); | 411 | page = read_mapping_page(mapping, n, NULL); |
412 | if (!IS_ERR(page)) { | 412 | if (!IS_ERR(page)) { |
413 | wait_on_page_locked(page); | ||
414 | kmap(page); | 413 | kmap(page); |
415 | if (!PageUptodate(page)) | ||
416 | goto fail; | ||
417 | |||
418 | if (PageError(page)) | 414 | if (PageError(page)) |
419 | goto fail; | 415 | goto fail; |
420 | } | 416 | } |
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index fd601014813e..804285190271 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c | |||
@@ -570,8 +570,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
570 | { | 570 | { |
571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; | 571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; |
572 | 572 | ||
573 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 573 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
574 | SLAB_CTOR_CONSTRUCTOR) | ||
575 | inode_init_once(&ei->vfs_inode); | 574 | inode_init_once(&ei->vfs_inode); |
576 | } | 575 | } |
577 | 576 | ||
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 5faba4f1c9ab..424a3ddf86dd 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -69,9 +69,8 @@ static void smb_destroy_inode(struct inode *inode) | |||
69 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) | 69 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
70 | { | 70 | { |
71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; | 71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; |
72 | unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; | ||
73 | 72 | ||
74 | if ((flags & flagmask) == SLAB_CTOR_CONSTRUCTOR) | 73 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
75 | inode_init_once(&ei->vfs_inode); | 74 | inode_init_once(&ei->vfs_inode); |
76 | } | 75 | } |
77 | 76 | ||
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 8ea2a51ce883..d3b9f5f07db1 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
@@ -59,7 +59,7 @@ read(struct file * file, char __user * userbuf, size_t count, loff_t * off) | |||
59 | if (copy_to_user(userbuf, buffer, count)) | 59 | if (copy_to_user(userbuf, buffer, count)) |
60 | return -EFAULT; | 60 | return -EFAULT; |
61 | 61 | ||
62 | pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count); | 62 | pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count); |
63 | 63 | ||
64 | *off = offs + count; | 64 | *off = offs + count; |
65 | 65 | ||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index db0413a411d6..0e637adc2b87 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -13,8 +13,7 @@ | |||
13 | 13 | ||
14 | #include "sysfs.h" | 14 | #include "sysfs.h" |
15 | 15 | ||
16 | #define to_subsys(k) container_of(k,struct subsystem,kset.kobj) | 16 | #define to_sattr(a) container_of(a,struct subsys_attribute, attr) |
17 | #define to_sattr(a) container_of(a,struct subsys_attribute,attr) | ||
18 | 17 | ||
19 | /* | 18 | /* |
20 | * Subsystem file operations. | 19 | * Subsystem file operations. |
@@ -24,12 +23,12 @@ | |||
24 | static ssize_t | 23 | static ssize_t |
25 | subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page) | 24 | subsys_attr_show(struct kobject * kobj, struct attribute * attr, char * page) |
26 | { | 25 | { |
27 | struct subsystem * s = to_subsys(kobj); | 26 | struct kset *kset = to_kset(kobj); |
28 | struct subsys_attribute * sattr = to_sattr(attr); | 27 | struct subsys_attribute * sattr = to_sattr(attr); |
29 | ssize_t ret = -EIO; | 28 | ssize_t ret = -EIO; |
30 | 29 | ||
31 | if (sattr->show) | 30 | if (sattr->show) |
32 | ret = sattr->show(s,page); | 31 | ret = sattr->show(kset, page); |
33 | return ret; | 32 | return ret; |
34 | } | 33 | } |
35 | 34 | ||
@@ -37,12 +36,12 @@ static ssize_t | |||
37 | subsys_attr_store(struct kobject * kobj, struct attribute * attr, | 36 | subsys_attr_store(struct kobject * kobj, struct attribute * attr, |
38 | const char * page, size_t count) | 37 | const char * page, size_t count) |
39 | { | 38 | { |
40 | struct subsystem * s = to_subsys(kobj); | 39 | struct kset *kset = to_kset(kobj); |
41 | struct subsys_attribute * sattr = to_sattr(attr); | 40 | struct subsys_attribute * sattr = to_sattr(attr); |
42 | ssize_t ret = -EIO; | 41 | ssize_t ret = -EIO; |
43 | 42 | ||
44 | if (sattr->store) | 43 | if (sattr->store) |
45 | ret = sattr->store(s,page,count); | 44 | ret = sattr->store(kset, page, count); |
46 | return ret; | 45 | return ret; |
47 | } | 46 | } |
48 | 47 | ||
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c index ebf7007fa161..e566b387fcf9 100644 --- a/fs/sysv/dir.c +++ b/fs/sysv/dir.c | |||
@@ -54,17 +54,9 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n) | |||
54 | { | 54 | { |
55 | struct address_space *mapping = dir->i_mapping; | 55 | struct address_space *mapping = dir->i_mapping; |
56 | struct page *page = read_mapping_page(mapping, n, NULL); | 56 | struct page *page = read_mapping_page(mapping, n, NULL); |
57 | if (!IS_ERR(page)) { | 57 | if (!IS_ERR(page)) |
58 | wait_on_page_locked(page); | ||
59 | kmap(page); | 58 | kmap(page); |
60 | if (!PageUptodate(page)) | ||
61 | goto fail; | ||
62 | } | ||
63 | return page; | 59 | return page; |
64 | |||
65 | fail: | ||
66 | dir_put_page(page); | ||
67 | return ERR_PTR(-EIO); | ||
68 | } | 60 | } |
69 | 61 | ||
70 | static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) | 62 | static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) |
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index 9311cac186fe..3152d7415606 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -322,8 +322,7 @@ static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) | |||
322 | { | 322 | { |
323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; | 323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; |
324 | 324 | ||
325 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 325 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
326 | SLAB_CTOR_CONSTRUCTOR) | ||
327 | inode_init_once(&si->vfs_inode); | 326 | inode_init_once(&si->vfs_inode); |
328 | } | 327 | } |
329 | 328 | ||
diff --git a/fs/udf/super.c b/fs/udf/super.c index 8672b88f7ff2..023b304fdd99 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -134,9 +134,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
134 | { | 134 | { |
135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; | 135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; |
136 | 136 | ||
137 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 137 | if (flags & SLAB_CTOR_CONSTRUCTOR) { |
138 | SLAB_CTOR_CONSTRUCTOR) | ||
139 | { | ||
140 | ei->i_ext.i_data = NULL; | 138 | ei->i_ext.i_data = NULL; |
141 | inode_init_once(&ei->vfs_inode); | 139 | inode_init_once(&ei->vfs_inode); |
142 | } | 140 | } |
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c index 4890ddf1518e..4fb8b2e077ee 100644 --- a/fs/ufs/dir.c +++ b/fs/ufs/dir.c | |||
@@ -180,13 +180,9 @@ fail: | |||
180 | static struct page *ufs_get_page(struct inode *dir, unsigned long n) | 180 | static struct page *ufs_get_page(struct inode *dir, unsigned long n) |
181 | { | 181 | { |
182 | struct address_space *mapping = dir->i_mapping; | 182 | struct address_space *mapping = dir->i_mapping; |
183 | struct page *page = read_cache_page(mapping, n, | 183 | struct page *page = read_mapping_page(mapping, n, NULL); |
184 | (filler_t*)mapping->a_ops->readpage, NULL); | ||
185 | if (!IS_ERR(page)) { | 184 | if (!IS_ERR(page)) { |
186 | wait_on_page_locked(page); | ||
187 | kmap(page); | 185 | kmap(page); |
188 | if (!PageUptodate(page)) | ||
189 | goto fail; | ||
190 | if (!PageChecked(page)) | 186 | if (!PageChecked(page)) |
191 | ufs_check_page(page); | 187 | ufs_check_page(page); |
192 | if (PageError(page)) | 188 | if (PageError(page)) |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index b5a6461ec66b..be7c48c5f203 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -1237,8 +1237,7 @@ static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flag | |||
1237 | { | 1237 | { |
1238 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; | 1238 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; |
1239 | 1239 | ||
1240 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 1240 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
1241 | SLAB_CTOR_CONSTRUCTOR) | ||
1242 | inode_init_once(&ei->vfs_inode); | 1241 | inode_init_once(&ei->vfs_inode); |
1243 | } | 1242 | } |
1244 | 1243 | ||
diff --git a/fs/ufs/util.c b/fs/ufs/util.c index 17437574f79c..84357f1ff0ec 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c | |||
@@ -251,13 +251,11 @@ struct page *ufs_get_locked_page(struct address_space *mapping, | |||
251 | 251 | ||
252 | page = find_lock_page(mapping, index); | 252 | page = find_lock_page(mapping, index); |
253 | if (!page) { | 253 | if (!page) { |
254 | page = read_cache_page(mapping, index, | 254 | page = read_mapping_page(mapping, index, NULL); |
255 | (filler_t*)mapping->a_ops->readpage, | ||
256 | NULL); | ||
257 | 255 | ||
258 | if (IS_ERR(page)) { | 256 | if (IS_ERR(page)) { |
259 | printk(KERN_ERR "ufs_change_blocknr: " | 257 | printk(KERN_ERR "ufs_change_blocknr: " |
260 | "read_cache_page error: ino %lu, index: %lu\n", | 258 | "read_mapping_page error: ino %lu, index: %lu\n", |
261 | mapping->host->i_ino, index); | 259 | mapping->host->i_ino, index); |
262 | goto out; | 260 | goto out; |
263 | } | 261 | } |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 2f2c40db562e..14e2cbe5a8d5 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -360,8 +360,7 @@ xfs_fs_inode_init_once( | |||
360 | kmem_zone_t *zonep, | 360 | kmem_zone_t *zonep, |
361 | unsigned long flags) | 361 | unsigned long flags) |
362 | { | 362 | { |
363 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 363 | if (flags & SLAB_CTOR_CONSTRUCTOR) |
364 | SLAB_CTOR_CONSTRUCTOR) | ||
365 | inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); | 364 | inode_init_once(vn_to_inode((bhv_vnode_t *)vnode)); |
366 | } | 365 | } |
367 | 366 | ||