diff options
Diffstat (limited to 'fs')
40 files changed, 750 insertions, 417 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index fa8ea33ab0be..08e4414b8374 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1499,6 +1499,9 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1499 | #endif | 1499 | #endif |
1500 | int thread_status_size = 0; | 1500 | int thread_status_size = 0; |
1501 | elf_addr_t *auxv; | 1501 | elf_addr_t *auxv; |
1502 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1503 | int extra_notes_size; | ||
1504 | #endif | ||
1502 | 1505 | ||
1503 | /* | 1506 | /* |
1504 | * We no longer stop all VM operations. | 1507 | * We no longer stop all VM operations. |
@@ -1628,7 +1631,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1628 | sz += thread_status_size; | 1631 | sz += thread_status_size; |
1629 | 1632 | ||
1630 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | 1633 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES |
1631 | sz += ELF_CORE_EXTRA_NOTES_SIZE; | 1634 | extra_notes_size = ELF_CORE_EXTRA_NOTES_SIZE; |
1635 | sz += extra_notes_size; | ||
1632 | #endif | 1636 | #endif |
1633 | 1637 | ||
1634 | fill_elf_note_phdr(&phdr, sz, offset); | 1638 | fill_elf_note_phdr(&phdr, sz, offset); |
@@ -1674,6 +1678,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1674 | 1678 | ||
1675 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | 1679 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES |
1676 | ELF_CORE_WRITE_EXTRA_NOTES; | 1680 | ELF_CORE_WRITE_EXTRA_NOTES; |
1681 | foffset += extra_notes_size; | ||
1677 | #endif | 1682 | #endif |
1678 | 1683 | ||
1679 | /* write out the thread status notes section */ | 1684 | /* write out the thread status notes section */ |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 7b0265d7f3a8..861141b4f6d6 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -558,7 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
558 | if (!realdatastart) | 558 | if (!realdatastart) |
559 | realdatastart = (unsigned long) -ENOMEM; | 559 | realdatastart = (unsigned long) -ENOMEM; |
560 | printk("Unable to allocate RAM for process data, errno %d\n", | 560 | printk("Unable to allocate RAM for process data, errno %d\n", |
561 | (int)-datapos); | 561 | (int)-realdatastart); |
562 | do_munmap(current->mm, textpos, text_len); | 562 | do_munmap(current->mm, textpos, text_len); |
563 | ret = realdatastart; | 563 | ret = realdatastart; |
564 | goto err; | 564 | goto err; |
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 6017c465440e..07838b2ac1ce 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -7,16 +7,16 @@ | |||
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
16 | * the GNU General Public License for more details. | 16 | * the GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
@@ -39,7 +39,7 @@ cifs_dump_mem(char *label, void *data, int length) | |||
39 | char *charptr = data; | 39 | char *charptr = data; |
40 | char buf[10], line[80]; | 40 | char buf[10], line[80]; |
41 | 41 | ||
42 | printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", | 42 | printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n", |
43 | label, length, data); | 43 | label, length, data); |
44 | for (i = 0; i < length; i += 16) { | 44 | for (i = 0; i < length; i += 16) { |
45 | line[0] = 0; | 45 | line[0] = 0; |
@@ -60,10 +60,10 @@ cifs_dump_mem(char *label, void *data, int length) | |||
60 | #ifdef CONFIG_CIFS_DEBUG2 | 60 | #ifdef CONFIG_CIFS_DEBUG2 |
61 | void cifs_dump_detail(struct smb_hdr * smb) | 61 | void cifs_dump_detail(struct smb_hdr * smb) |
62 | { | 62 | { |
63 | cERROR(1,("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", | 63 | cERROR(1, ("Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", |
64 | smb->Command, smb->Status.CifsError, | 64 | smb->Command, smb->Status.CifsError, |
65 | smb->Flags, smb->Flags2, smb->Mid, smb->Pid)); | 65 | smb->Flags, smb->Flags2, smb->Mid, smb->Pid)); |
66 | cERROR(1,("smb buf %p len %d", smb, smbCalcSize_LE(smb))); | 66 | cERROR(1, ("smb buf %p len %d", smb, smbCalcSize_LE(smb))); |
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
@@ -72,36 +72,35 @@ void cifs_dump_mids(struct TCP_Server_Info * server) | |||
72 | struct list_head *tmp; | 72 | struct list_head *tmp; |
73 | struct mid_q_entry * mid_entry; | 73 | struct mid_q_entry * mid_entry; |
74 | 74 | ||
75 | if(server == NULL) | 75 | if (server == NULL) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | cERROR(1,("Dump pending requests:")); | 78 | cERROR(1, ("Dump pending requests:")); |
79 | spin_lock(&GlobalMid_Lock); | 79 | spin_lock(&GlobalMid_Lock); |
80 | list_for_each(tmp, &server->pending_mid_q) { | 80 | list_for_each(tmp, &server->pending_mid_q) { |
81 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 81 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
82 | if(mid_entry) { | 82 | if (mid_entry) { |
83 | cERROR(1,("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", | 83 | cERROR(1, ("State: %d Cmd: %d Pid: %d Tsk: %p Mid %d", |
84 | mid_entry->midState, | 84 | mid_entry->midState, |
85 | (int)mid_entry->command, | 85 | (int)mid_entry->command, |
86 | mid_entry->pid, | 86 | mid_entry->pid, |
87 | mid_entry->tsk, | 87 | mid_entry->tsk, |
88 | mid_entry->mid)); | 88 | mid_entry->mid)); |
89 | #ifdef CONFIG_CIFS_STATS2 | 89 | #ifdef CONFIG_CIFS_STATS2 |
90 | cERROR(1,("IsLarge: %d buf: %p time rcv: %ld now: %ld", | 90 | cERROR(1, ("IsLarge: %d buf: %p time rcv: %ld now: %ld", |
91 | mid_entry->largeBuf, | 91 | mid_entry->largeBuf, |
92 | mid_entry->resp_buf, | 92 | mid_entry->resp_buf, |
93 | mid_entry->when_received, | 93 | mid_entry->when_received, |
94 | jiffies)); | 94 | jiffies)); |
95 | #endif /* STATS2 */ | 95 | #endif /* STATS2 */ |
96 | cERROR(1,("IsMult: %d IsEnd: %d", mid_entry->multiRsp, | 96 | cERROR(1, ("IsMult: %d IsEnd: %d", mid_entry->multiRsp, |
97 | mid_entry->multiEnd)); | 97 | mid_entry->multiEnd)); |
98 | if(mid_entry->resp_buf) { | 98 | if (mid_entry->resp_buf) { |
99 | cifs_dump_detail(mid_entry->resp_buf); | 99 | cifs_dump_detail(mid_entry->resp_buf); |
100 | cifs_dump_mem("existing buf: ", | 100 | cifs_dump_mem("existing buf: ", |
101 | mid_entry->resp_buf, | 101 | mid_entry->resp_buf, |
102 | 62 /* fixme */); | 102 | 62 /* fixme */); |
103 | } | 103 | } |
104 | |||
105 | } | 104 | } |
106 | } | 105 | } |
107 | spin_unlock(&GlobalMid_Lock); | 106 | spin_unlock(&GlobalMid_Lock); |
@@ -129,9 +128,10 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
129 | "Display Internal CIFS Data Structures for Debugging\n" | 128 | "Display Internal CIFS Data Structures for Debugging\n" |
130 | "---------------------------------------------------\n"); | 129 | "---------------------------------------------------\n"); |
131 | buf += length; | 130 | buf += length; |
132 | length = sprintf(buf,"CIFS Version %s\n",CIFS_VERSION); | 131 | length = sprintf(buf, "CIFS Version %s\n", CIFS_VERSION); |
133 | buf += length; | 132 | buf += length; |
134 | length = sprintf(buf,"Active VFS Requests: %d\n", GlobalTotalActiveXid); | 133 | length = sprintf(buf, |
134 | "Active VFS Requests: %d\n", GlobalTotalActiveXid); | ||
135 | buf += length; | 135 | buf += length; |
136 | length = sprintf(buf, "Servers:"); | 136 | length = sprintf(buf, "Servers:"); |
137 | buf += length; | 137 | buf += length; |
@@ -141,7 +141,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
141 | list_for_each(tmp, &GlobalSMBSessionList) { | 141 | list_for_each(tmp, &GlobalSMBSessionList) { |
142 | i++; | 142 | i++; |
143 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); | 143 | ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); |
144 | if((ses->serverDomain == NULL) || (ses->serverOS == NULL) || | 144 | if ((ses->serverDomain == NULL) || (ses->serverOS == NULL) || |
145 | (ses->serverNOS == NULL)) { | 145 | (ses->serverNOS == NULL)) { |
146 | buf += sprintf(buf, "\nentry for %s not fully " | 146 | buf += sprintf(buf, "\nentry for %s not fully " |
147 | "displayed\n\t", ses->serverName); | 147 | "displayed\n\t", ses->serverName); |
@@ -149,15 +149,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
149 | } else { | 149 | } else { |
150 | length = | 150 | length = |
151 | sprintf(buf, | 151 | sprintf(buf, |
152 | "\n%d) Name: %s Domain: %s Mounts: %d OS: %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB session status: %d\t", | 152 | "\n%d) Name: %s Domain: %s Mounts: %d OS:" |
153 | " %s \n\tNOS: %s\tCapability: 0x%x\n\tSMB" | ||
154 | " session status: %d\t", | ||
153 | i, ses->serverName, ses->serverDomain, | 155 | i, ses->serverName, ses->serverDomain, |
154 | atomic_read(&ses->inUse), | 156 | atomic_read(&ses->inUse), |
155 | ses->serverOS, ses->serverNOS, | 157 | ses->serverOS, ses->serverNOS, |
156 | ses->capabilities,ses->status); | 158 | ses->capabilities, ses->status); |
157 | buf += length; | 159 | buf += length; |
158 | } | 160 | } |
159 | if(ses->server) { | 161 | if (ses->server) { |
160 | buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d", | 162 | buf += sprintf(buf, "TCP status: %d\n\tLocal Users To " |
163 | "Server: %d SecMode: 0x%x Req On Wire: %d", | ||
161 | ses->server->tcpStatus, | 164 | ses->server->tcpStatus, |
162 | atomic_read(&ses->server->socketUseCount), | 165 | atomic_read(&ses->server->socketUseCount), |
163 | ses->server->secMode, | 166 | ses->server->secMode, |
@@ -165,7 +168,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
165 | 168 | ||
166 | #ifdef CONFIG_CIFS_STATS2 | 169 | #ifdef CONFIG_CIFS_STATS2 |
167 | buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", | 170 | buf += sprintf(buf, " In Send: %d In MaxReq Wait: %d", |
168 | atomic_read(&ses->server->inSend), | 171 | atomic_read(&ses->server->inSend), |
169 | atomic_read(&ses->server->num_waiters)); | 172 | atomic_read(&ses->server->num_waiters)); |
170 | #endif | 173 | #endif |
171 | 174 | ||
@@ -177,17 +180,19 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
177 | mid_entry = list_entry(tmp1, struct | 180 | mid_entry = list_entry(tmp1, struct |
178 | mid_q_entry, | 181 | mid_q_entry, |
179 | qhead); | 182 | qhead); |
180 | if(mid_entry) { | 183 | if (mid_entry) { |
181 | length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p mid %d\n", | 184 | length = sprintf(buf, |
182 | mid_entry->midState, | 185 | "State: %d com: %d pid:" |
183 | (int)mid_entry->command, | 186 | " %d tsk: %p mid %d\n", |
184 | mid_entry->pid, | 187 | mid_entry->midState, |
185 | mid_entry->tsk, | 188 | (int)mid_entry->command, |
186 | mid_entry->mid); | 189 | mid_entry->pid, |
190 | mid_entry->tsk, | ||
191 | mid_entry->mid); | ||
187 | buf += length; | 192 | buf += length; |
188 | } | 193 | } |
189 | } | 194 | } |
190 | spin_unlock(&GlobalMid_Lock); | 195 | spin_unlock(&GlobalMid_Lock); |
191 | } | 196 | } |
192 | 197 | ||
193 | } | 198 | } |
@@ -207,7 +212,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
207 | dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); | 212 | dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); |
208 | length = | 213 | length = |
209 | sprintf(buf, | 214 | sprintf(buf, |
210 | "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d", | 215 | "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x " |
216 | "Attributes: 0x%x\nPathComponentMax: %d Status: %d", | ||
211 | i, tcon->treeName, | 217 | i, tcon->treeName, |
212 | atomic_read(&tcon->useCount), | 218 | atomic_read(&tcon->useCount), |
213 | tcon->nativeFileSystem, | 219 | tcon->nativeFileSystem, |
@@ -215,7 +221,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
215 | le32_to_cpu(tcon->fsAttrInfo.Attributes), | 221 | le32_to_cpu(tcon->fsAttrInfo.Attributes), |
216 | le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), | 222 | le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), |
217 | tcon->tidStatus); | 223 | tcon->tidStatus); |
218 | buf += length; | 224 | buf += length; |
219 | if (dev_type == FILE_DEVICE_DISK) | 225 | if (dev_type == FILE_DEVICE_DISK) |
220 | length = sprintf(buf, " type: DISK "); | 226 | length = sprintf(buf, " type: DISK "); |
221 | else if (dev_type == FILE_DEVICE_CD_ROM) | 227 | else if (dev_type == FILE_DEVICE_CD_ROM) |
@@ -224,7 +230,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
224 | length = | 230 | length = |
225 | sprintf(buf, " type: %d ", dev_type); | 231 | sprintf(buf, " type: %d ", dev_type); |
226 | buf += length; | 232 | buf += length; |
227 | if(tcon->tidStatus == CifsNeedReconnect) { | 233 | if (tcon->tidStatus == CifsNeedReconnect) { |
228 | buf += sprintf(buf, "\tDISCONNECTED "); | 234 | buf += sprintf(buf, "\tDISCONNECTED "); |
229 | length += 14; | 235 | length += 14; |
230 | } | 236 | } |
@@ -238,9 +244,9 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
238 | /* Now calculate total size of returned data */ | 244 | /* Now calculate total size of returned data */ |
239 | length = buf - original_buf; | 245 | length = buf - original_buf; |
240 | 246 | ||
241 | if(offset + count >= length) | 247 | if (offset + count >= length) |
242 | *eof = 1; | 248 | *eof = 1; |
243 | if(length < offset) { | 249 | if (length < offset) { |
244 | *eof = 1; | 250 | *eof = 1; |
245 | return 0; | 251 | return 0; |
246 | } else { | 252 | } else { |
@@ -256,18 +262,18 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
256 | 262 | ||
257 | static int | 263 | static int |
258 | cifs_stats_write(struct file *file, const char __user *buffer, | 264 | cifs_stats_write(struct file *file, const char __user *buffer, |
259 | unsigned long count, void *data) | 265 | unsigned long count, void *data) |
260 | { | 266 | { |
261 | char c; | 267 | char c; |
262 | int rc; | 268 | int rc; |
263 | struct list_head *tmp; | 269 | struct list_head *tmp; |
264 | struct cifsTconInfo *tcon; | 270 | struct cifsTconInfo *tcon; |
265 | 271 | ||
266 | rc = get_user(c, buffer); | 272 | rc = get_user(c, buffer); |
267 | if (rc) | 273 | if (rc) |
268 | return rc; | 274 | return rc; |
269 | 275 | ||
270 | if (c == '1' || c == 'y' || c == 'Y' || c == '0') { | 276 | if (c == '1' || c == 'y' || c == 'Y' || c == '0') { |
271 | read_lock(&GlobalSMBSeslock); | 277 | read_lock(&GlobalSMBSeslock); |
272 | #ifdef CONFIG_CIFS_STATS2 | 278 | #ifdef CONFIG_CIFS_STATS2 |
273 | atomic_set(&totBufAllocCount, 0); | 279 | atomic_set(&totBufAllocCount, 0); |
@@ -297,14 +303,14 @@ cifs_stats_write(struct file *file, const char __user *buffer, | |||
297 | read_unlock(&GlobalSMBSeslock); | 303 | read_unlock(&GlobalSMBSeslock); |
298 | } | 304 | } |
299 | 305 | ||
300 | return count; | 306 | return count; |
301 | } | 307 | } |
302 | 308 | ||
303 | static int | 309 | static int |
304 | cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | 310 | cifs_stats_read(char *buf, char **beginBuffer, off_t offset, |
305 | int count, int *eof, void *data) | 311 | int count, int *eof, void *data) |
306 | { | 312 | { |
307 | int item_length,i,length; | 313 | int item_length, i, length; |
308 | struct list_head *tmp; | 314 | struct list_head *tmp; |
309 | struct cifsTconInfo *tcon; | 315 | struct cifsTconInfo *tcon; |
310 | 316 | ||
@@ -314,44 +320,44 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
314 | "Resources in use\nCIFS Session: %d\n", | 320 | "Resources in use\nCIFS Session: %d\n", |
315 | sesInfoAllocCount.counter); | 321 | sesInfoAllocCount.counter); |
316 | buf += length; | 322 | buf += length; |
317 | item_length = | 323 | item_length = |
318 | sprintf(buf,"Share (unique mount targets): %d\n", | 324 | sprintf(buf, "Share (unique mount targets): %d\n", |
319 | tconInfoAllocCount.counter); | 325 | tconInfoAllocCount.counter); |
320 | length += item_length; | 326 | length += item_length; |
321 | buf += item_length; | 327 | buf += item_length; |
322 | item_length = | 328 | item_length = |
323 | sprintf(buf,"SMB Request/Response Buffer: %d Pool size: %d\n", | 329 | sprintf(buf, "SMB Request/Response Buffer: %d Pool size: %d\n", |
324 | bufAllocCount.counter, | 330 | bufAllocCount.counter, |
325 | cifs_min_rcv + tcpSesAllocCount.counter); | 331 | cifs_min_rcv + tcpSesAllocCount.counter); |
326 | length += item_length; | 332 | length += item_length; |
327 | buf += item_length; | 333 | buf += item_length; |
328 | item_length = | 334 | item_length = |
329 | sprintf(buf,"SMB Small Req/Resp Buffer: %d Pool size: %d\n", | 335 | sprintf(buf, "SMB Small Req/Resp Buffer: %d Pool size: %d\n", |
330 | smBufAllocCount.counter,cifs_min_small); | 336 | smBufAllocCount.counter, cifs_min_small); |
331 | length += item_length; | 337 | length += item_length; |
332 | buf += item_length; | 338 | buf += item_length; |
333 | #ifdef CONFIG_CIFS_STATS2 | 339 | #ifdef CONFIG_CIFS_STATS2 |
334 | item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", | 340 | item_length = sprintf(buf, "Total Large %d Small %d Allocations\n", |
335 | atomic_read(&totBufAllocCount), | 341 | atomic_read(&totBufAllocCount), |
336 | atomic_read(&totSmBufAllocCount)); | 342 | atomic_read(&totSmBufAllocCount)); |
337 | length += item_length; | 343 | length += item_length; |
338 | buf += item_length; | 344 | buf += item_length; |
339 | #endif /* CONFIG_CIFS_STATS2 */ | 345 | #endif /* CONFIG_CIFS_STATS2 */ |
340 | 346 | ||
341 | item_length = | 347 | item_length = |
342 | sprintf(buf,"Operations (MIDs): %d\n", | 348 | sprintf(buf, "Operations (MIDs): %d\n", |
343 | midCount.counter); | 349 | midCount.counter); |
344 | length += item_length; | 350 | length += item_length; |
345 | buf += item_length; | 351 | buf += item_length; |
346 | item_length = sprintf(buf, | 352 | item_length = sprintf(buf, |
347 | "\n%d session %d share reconnects\n", | 353 | "\n%d session %d share reconnects\n", |
348 | tcpSesReconnectCount.counter,tconInfoReconnectCount.counter); | 354 | tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); |
349 | length += item_length; | 355 | length += item_length; |
350 | buf += item_length; | 356 | buf += item_length; |
351 | 357 | ||
352 | item_length = sprintf(buf, | 358 | item_length = sprintf(buf, |
353 | "Total vfs operations: %d maximum at one time: %d\n", | 359 | "Total vfs operations: %d maximum at one time: %d\n", |
354 | GlobalCurrentXid,GlobalMaxActiveXid); | 360 | GlobalCurrentXid, GlobalMaxActiveXid); |
355 | length += item_length; | 361 | length += item_length; |
356 | buf += item_length; | 362 | buf += item_length; |
357 | 363 | ||
@@ -360,10 +366,10 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
360 | list_for_each(tmp, &GlobalTreeConnectionList) { | 366 | list_for_each(tmp, &GlobalTreeConnectionList) { |
361 | i++; | 367 | i++; |
362 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); | 368 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); |
363 | item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName); | 369 | item_length = sprintf(buf, "\n%d) %s", i, tcon->treeName); |
364 | buf += item_length; | 370 | buf += item_length; |
365 | length += item_length; | 371 | length += item_length; |
366 | if(tcon->tidStatus == CifsNeedReconnect) { | 372 | if (tcon->tidStatus == CifsNeedReconnect) { |
367 | buf += sprintf(buf, "\tDISCONNECTED "); | 373 | buf += sprintf(buf, "\tDISCONNECTED "); |
368 | length += 14; | 374 | length += 14; |
369 | } | 375 | } |
@@ -380,15 +386,15 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
380 | item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", | 386 | item_length = sprintf(buf, "\nWrites: %d Bytes: %lld", |
381 | atomic_read(&tcon->num_writes), | 387 | atomic_read(&tcon->num_writes), |
382 | (long long)(tcon->bytes_written)); | 388 | (long long)(tcon->bytes_written)); |
383 | buf += item_length; | 389 | buf += item_length; |
384 | length += item_length; | 390 | length += item_length; |
385 | item_length = sprintf(buf, | 391 | item_length = sprintf(buf, |
386 | "\nLocks: %d HardLinks: %d Symlinks: %d", | 392 | "\nLocks: %d HardLinks: %d Symlinks: %d", |
387 | atomic_read(&tcon->num_locks), | 393 | atomic_read(&tcon->num_locks), |
388 | atomic_read(&tcon->num_hardlinks), | 394 | atomic_read(&tcon->num_hardlinks), |
389 | atomic_read(&tcon->num_symlinks)); | 395 | atomic_read(&tcon->num_symlinks)); |
390 | buf += item_length; | 396 | buf += item_length; |
391 | length += item_length; | 397 | length += item_length; |
392 | 398 | ||
393 | item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", | 399 | item_length = sprintf(buf, "\nOpens: %d Closes: %d Deletes: %d", |
394 | atomic_read(&tcon->num_opens), | 400 | atomic_read(&tcon->num_opens), |
@@ -415,12 +421,12 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
415 | } | 421 | } |
416 | read_unlock(&GlobalSMBSeslock); | 422 | read_unlock(&GlobalSMBSeslock); |
417 | 423 | ||
418 | buf += sprintf(buf,"\n"); | 424 | buf += sprintf(buf, "\n"); |
419 | length++; | 425 | length++; |
420 | 426 | ||
421 | if(offset + count >= length) | 427 | if (offset + count >= length) |
422 | *eof = 1; | 428 | *eof = 1; |
423 | if(length < offset) { | 429 | if (length < offset) { |
424 | *eof = 1; | 430 | *eof = 1; |
425 | return 0; | 431 | return 0; |
426 | } else { | 432 | } else { |
@@ -428,7 +434,7 @@ cifs_stats_read(char *buf, char **beginBuffer, off_t offset, | |||
428 | } | 434 | } |
429 | if (length > count) | 435 | if (length > count) |
430 | length = count; | 436 | length = count; |
431 | 437 | ||
432 | return length; | 438 | return length; |
433 | } | 439 | } |
434 | #endif | 440 | #endif |
@@ -547,11 +553,11 @@ cifs_proc_clean(void) | |||
547 | remove_proc_entry("MultiuserMount", proc_fs_cifs); | 553 | remove_proc_entry("MultiuserMount", proc_fs_cifs); |
548 | remove_proc_entry("OplockEnabled", proc_fs_cifs); | 554 | remove_proc_entry("OplockEnabled", proc_fs_cifs); |
549 | /* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ | 555 | /* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */ |
550 | remove_proc_entry("SecurityFlags",proc_fs_cifs); | 556 | remove_proc_entry("SecurityFlags", proc_fs_cifs); |
551 | /* remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); */ | 557 | /* remove_proc_entry("PacketSigningEnabled", proc_fs_cifs); */ |
552 | remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs); | 558 | remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); |
553 | remove_proc_entry("Experimental",proc_fs_cifs); | 559 | remove_proc_entry("Experimental", proc_fs_cifs); |
554 | remove_proc_entry("LookupCacheEnabled",proc_fs_cifs); | 560 | remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); |
555 | remove_proc_entry("cifs", proc_root_fs); | 561 | remove_proc_entry("cifs", proc_root_fs); |
556 | } | 562 | } |
557 | 563 | ||
@@ -590,7 +596,7 @@ cifsFYI_write(struct file *file, const char __user *buffer, | |||
590 | cifsFYI = 0; | 596 | cifsFYI = 0; |
591 | else if (c == '1' || c == 'y' || c == 'Y') | 597 | else if (c == '1' || c == 'y' || c == 'Y') |
592 | cifsFYI = 1; | 598 | cifsFYI = 1; |
593 | else if((c > '1') && (c <= '9')) | 599 | else if ((c > '1') && (c <= '9')) |
594 | cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ | 600 | cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */ |
595 | 601 | ||
596 | return count; | 602 | return count; |
@@ -637,28 +643,28 @@ oplockEnabled_write(struct file *file, const char __user *buffer, | |||
637 | 643 | ||
638 | static int | 644 | static int |
639 | experimEnabled_read(char *page, char **start, off_t off, | 645 | experimEnabled_read(char *page, char **start, off_t off, |
640 | int count, int *eof, void *data) | 646 | int count, int *eof, void *data) |
641 | { | 647 | { |
642 | int len; | 648 | int len; |
643 | 649 | ||
644 | len = sprintf(page, "%d\n", experimEnabled); | 650 | len = sprintf(page, "%d\n", experimEnabled); |
645 | 651 | ||
646 | len -= off; | 652 | len -= off; |
647 | *start = page + off; | 653 | *start = page + off; |
648 | 654 | ||
649 | if (len > count) | 655 | if (len > count) |
650 | len = count; | 656 | len = count; |
651 | else | 657 | else |
652 | *eof = 1; | 658 | *eof = 1; |
653 | 659 | ||
654 | if (len < 0) | 660 | if (len < 0) |
655 | len = 0; | 661 | len = 0; |
656 | 662 | ||
657 | return len; | 663 | return len; |
658 | } | 664 | } |
659 | static int | 665 | static int |
660 | experimEnabled_write(struct file *file, const char __user *buffer, | 666 | experimEnabled_write(struct file *file, const char __user *buffer, |
661 | unsigned long count, void *data) | 667 | unsigned long count, void *data) |
662 | { | 668 | { |
663 | char c; | 669 | char c; |
664 | int rc; | 670 | int rc; |
@@ -678,46 +684,46 @@ experimEnabled_write(struct file *file, const char __user *buffer, | |||
678 | 684 | ||
679 | static int | 685 | static int |
680 | linuxExtensionsEnabled_read(char *page, char **start, off_t off, | 686 | linuxExtensionsEnabled_read(char *page, char **start, off_t off, |
681 | int count, int *eof, void *data) | 687 | int count, int *eof, void *data) |
682 | { | 688 | { |
683 | int len; | 689 | int len; |
684 | 690 | ||
685 | len = sprintf(page, "%d\n", linuxExtEnabled); | 691 | len = sprintf(page, "%d\n", linuxExtEnabled); |
686 | len -= off; | 692 | len -= off; |
687 | *start = page + off; | 693 | *start = page + off; |
688 | 694 | ||
689 | if (len > count) | 695 | if (len > count) |
690 | len = count; | 696 | len = count; |
691 | else | 697 | else |
692 | *eof = 1; | 698 | *eof = 1; |
693 | 699 | ||
694 | if (len < 0) | 700 | if (len < 0) |
695 | len = 0; | 701 | len = 0; |
696 | 702 | ||
697 | return len; | 703 | return len; |
698 | } | 704 | } |
699 | static int | 705 | static int |
700 | linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, | 706 | linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, |
701 | unsigned long count, void *data) | 707 | unsigned long count, void *data) |
702 | { | 708 | { |
703 | char c; | 709 | char c; |
704 | int rc; | 710 | int rc; |
705 | 711 | ||
706 | rc = get_user(c, buffer); | 712 | rc = get_user(c, buffer); |
707 | if (rc) | 713 | if (rc) |
708 | return rc; | 714 | return rc; |
709 | if (c == '0' || c == 'n' || c == 'N') | 715 | if (c == '0' || c == 'n' || c == 'N') |
710 | linuxExtEnabled = 0; | 716 | linuxExtEnabled = 0; |
711 | else if (c == '1' || c == 'y' || c == 'Y') | 717 | else if (c == '1' || c == 'y' || c == 'Y') |
712 | linuxExtEnabled = 1; | 718 | linuxExtEnabled = 1; |
713 | 719 | ||
714 | return count; | 720 | return count; |
715 | } | 721 | } |
716 | 722 | ||
717 | 723 | ||
718 | static int | 724 | static int |
719 | lookupFlag_read(char *page, char **start, off_t off, | 725 | lookupFlag_read(char *page, char **start, off_t off, |
720 | int count, int *eof, void *data) | 726 | int count, int *eof, void *data) |
721 | { | 727 | { |
722 | int len; | 728 | int len; |
723 | 729 | ||
@@ -860,15 +866,15 @@ security_flags_write(struct file *file, const char __user *buffer, | |||
860 | char flags_string[12]; | 866 | char flags_string[12]; |
861 | char c; | 867 | char c; |
862 | 868 | ||
863 | if((count < 1) || (count > 11)) | 869 | if ((count < 1) || (count > 11)) |
864 | return -EINVAL; | 870 | return -EINVAL; |
865 | 871 | ||
866 | memset(flags_string, 0, 12); | 872 | memset(flags_string, 0, 12); |
867 | 873 | ||
868 | if(copy_from_user(flags_string, buffer, count)) | 874 | if (copy_from_user(flags_string, buffer, count)) |
869 | return -EFAULT; | 875 | return -EFAULT; |
870 | 876 | ||
871 | if(count < 3) { | 877 | if (count < 3) { |
872 | /* single char or single char followed by null */ | 878 | /* single char or single char followed by null */ |
873 | c = flags_string[0]; | 879 | c = flags_string[0]; |
874 | if (c == '0' || c == 'n' || c == 'N') | 880 | if (c == '0' || c == 'n' || c == 'N') |
@@ -881,15 +887,15 @@ security_flags_write(struct file *file, const char __user *buffer, | |||
881 | 887 | ||
882 | flags = simple_strtoul(flags_string, NULL, 0); | 888 | flags = simple_strtoul(flags_string, NULL, 0); |
883 | 889 | ||
884 | cFYI(1,("sec flags 0x%x", flags)); | 890 | cFYI(1, ("sec flags 0x%x", flags)); |
885 | 891 | ||
886 | if(flags <= 0) { | 892 | if (flags <= 0) { |
887 | cERROR(1,("invalid security flags %s",flags_string)); | 893 | cERROR(1, ("invalid security flags %s", flags_string)); |
888 | return -EINVAL; | 894 | return -EINVAL; |
889 | } | 895 | } |
890 | 896 | ||
891 | if(flags & ~CIFSSEC_MASK) { | 897 | if (flags & ~CIFSSEC_MASK) { |
892 | cERROR(1,("attempt to set unsupported security flags 0x%x", | 898 | cERROR(1, ("attempt to set unsupported security flags 0x%x", |
893 | flags & ~CIFSSEC_MASK)); | 899 | flags & ~CIFSSEC_MASK)); |
894 | return -EINVAL; | 900 | return -EINVAL; |
895 | } | 901 | } |
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 793c4b95c164..701e9a9185f2 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c | |||
@@ -6,16 +6,16 @@ | |||
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
15 | * the GNU General Public License for more details. | 15 | * the GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
@@ -32,7 +32,7 @@ | |||
32 | * | 32 | * |
33 | */ | 33 | */ |
34 | int | 34 | int |
35 | cifs_strfromUCS_le(char *to, const __le16 * from, | 35 | cifs_strfromUCS_le(char *to, const __le16 * from, |
36 | int len, const struct nls_table *codepage) | 36 | int len, const struct nls_table *codepage) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
@@ -66,7 +66,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len, | |||
66 | { | 66 | { |
67 | int charlen; | 67 | int charlen; |
68 | int i; | 68 | int i; |
69 | wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */ | 69 | wchar_t * wchar_to = (wchar_t *)to; /* needed to quiet sparse */ |
70 | 70 | ||
71 | for (i = 0; len && *from; i++, from += charlen, len -= charlen) { | 71 | for (i = 0; len && *from; i++, from += charlen, len -= charlen) { |
72 | 72 | ||
@@ -79,7 +79,7 @@ cifs_strtoUCS(__le16 * to, const char *from, int len, | |||
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; |
82 | } else | 82 | } else |
83 | to[i] = cpu_to_le16(wchar_to[i]); | 83 | to[i] = cpu_to_le16(wchar_to[i]); |
84 | 84 | ||
85 | } | 85 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d38c69b591cf..7c04752b76cb 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -825,8 +825,8 @@ cifs_init_mids(void) | |||
825 | sizeof (struct oplock_q_entry), 0, | 825 | sizeof (struct oplock_q_entry), 0, |
826 | SLAB_HWCACHE_ALIGN, NULL, NULL); | 826 | SLAB_HWCACHE_ALIGN, NULL, NULL); |
827 | if (cifs_oplock_cachep == NULL) { | 827 | if (cifs_oplock_cachep == NULL) { |
828 | kmem_cache_destroy(cifs_mid_cachep); | ||
829 | mempool_destroy(cifs_mid_poolp); | 828 | mempool_destroy(cifs_mid_poolp); |
829 | kmem_cache_destroy(cifs_mid_cachep); | ||
830 | return -ENOMEM; | 830 | return -ENOMEM; |
831 | } | 831 | } |
832 | 832 | ||
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 14de58fa1437..57419a176688 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -433,8 +433,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
433 | cFYI(1,("secFlags 0x%x",secFlags)); | 433 | cFYI(1,("secFlags 0x%x",secFlags)); |
434 | 434 | ||
435 | pSMB->hdr.Mid = GetNextMid(server); | 435 | pSMB->hdr.Mid = GetNextMid(server); |
436 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 436 | pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); |
437 | if((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) | 437 | if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) |
438 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | 438 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; |
439 | 439 | ||
440 | count = 0; | 440 | count = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 216fb625843f..f4e92661b223 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -2069,8 +2069,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2069 | srvTcp->tcpStatus = CifsExiting; | 2069 | srvTcp->tcpStatus = CifsExiting; |
2070 | spin_unlock(&GlobalMid_Lock); | 2070 | spin_unlock(&GlobalMid_Lock); |
2071 | if (srvTcp->tsk) { | 2071 | if (srvTcp->tsk) { |
2072 | struct task_struct *tsk; | ||
2073 | /* If we could verify that kthread_stop would | ||
2074 | always wake up processes blocked in | ||
2075 | tcp in recv_mesg then we could remove the | ||
2076 | send_sig call */ | ||
2072 | send_sig(SIGKILL,srvTcp->tsk,1); | 2077 | send_sig(SIGKILL,srvTcp->tsk,1); |
2073 | kthread_stop(srvTcp->tsk); | 2078 | tsk = srvTcp->tsk; |
2079 | if(tsk) | ||
2080 | kthread_stop(tsk); | ||
2074 | } | 2081 | } |
2075 | } | 2082 | } |
2076 | /* If find_unc succeeded then rc == 0 so we can not end */ | 2083 | /* If find_unc succeeded then rc == 0 so we can not end */ |
@@ -2085,8 +2092,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2085 | /* if the socketUseCount is now zero */ | 2092 | /* if the socketUseCount is now zero */ |
2086 | if ((temp_rc == -ESHUTDOWN) && | 2093 | if ((temp_rc == -ESHUTDOWN) && |
2087 | (pSesInfo->server) && (pSesInfo->server->tsk)) { | 2094 | (pSesInfo->server) && (pSesInfo->server->tsk)) { |
2095 | struct task_struct *tsk; | ||
2088 | send_sig(SIGKILL,pSesInfo->server->tsk,1); | 2096 | send_sig(SIGKILL,pSesInfo->server->tsk,1); |
2089 | kthread_stop(pSesInfo->server->tsk); | 2097 | tsk = pSesInfo->server->tsk; |
2098 | if (tsk) | ||
2099 | kthread_stop(tsk); | ||
2090 | } | 2100 | } |
2091 | } else | 2101 | } else |
2092 | cFYI(1, ("No session or bad tcon")); | 2102 | cFYI(1, ("No session or bad tcon")); |
@@ -3334,7 +3344,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | |||
3334 | return 0; | 3344 | return 0; |
3335 | } else if (rc == -ESHUTDOWN) { | 3345 | } else if (rc == -ESHUTDOWN) { |
3336 | cFYI(1,("Waking up socket by sending it signal")); | 3346 | cFYI(1,("Waking up socket by sending it signal")); |
3337 | if(cifsd_task) { | 3347 | if (cifsd_task) { |
3338 | send_sig(SIGKILL,cifsd_task,1); | 3348 | send_sig(SIGKILL,cifsd_task,1); |
3339 | kthread_stop(cifsd_task); | 3349 | kthread_stop(cifsd_task); |
3340 | } | 3350 | } |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e5210519ac4b..8e86aaceb68a 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * fs/cifs/dir.c | 2 | * fs/cifs/dir.c |
3 | * | 3 | * |
4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2002,2005 | 6 | * Copyright (C) International Business Machines Corp., 2002,2005 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
@@ -34,11 +34,12 @@ | |||
34 | static void | 34 | static void |
35 | renew_parental_timestamps(struct dentry *direntry) | 35 | renew_parental_timestamps(struct dentry *direntry) |
36 | { | 36 | { |
37 | /* BB check if there is a way to get the kernel to do this or if we really need this */ | 37 | /* BB check if there is a way to get the kernel to do this or if we |
38 | really need this */ | ||
38 | do { | 39 | do { |
39 | direntry->d_time = jiffies; | 40 | direntry->d_time = jiffies; |
40 | direntry = direntry->d_parent; | 41 | direntry = direntry->d_parent; |
41 | } while (!IS_ROOT(direntry)); | 42 | } while (!IS_ROOT(direntry)); |
42 | } | 43 | } |
43 | 44 | ||
44 | /* Note: caller must free return buffer */ | 45 | /* Note: caller must free return buffer */ |
@@ -51,7 +52,7 @@ build_path_from_dentry(struct dentry *direntry) | |||
51 | char *full_path; | 52 | char *full_path; |
52 | char dirsep; | 53 | char dirsep; |
53 | 54 | ||
54 | if(direntry == NULL) | 55 | if (direntry == NULL) |
55 | return NULL; /* not much we can do if dentry is freed and | 56 | return NULL; /* not much we can do if dentry is freed and |
56 | we need to reopen the file after it was closed implicitly | 57 | we need to reopen the file after it was closed implicitly |
57 | when the server crashed */ | 58 | when the server crashed */ |
@@ -59,18 +60,18 @@ build_path_from_dentry(struct dentry *direntry) | |||
59 | dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); | 60 | dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); |
60 | pplen = CIFS_SB(direntry->d_sb)->prepathlen; | 61 | pplen = CIFS_SB(direntry->d_sb)->prepathlen; |
61 | cifs_bp_rename_retry: | 62 | cifs_bp_rename_retry: |
62 | namelen = pplen; | 63 | namelen = pplen; |
63 | for (temp = direntry; !IS_ROOT(temp);) { | 64 | for (temp = direntry; !IS_ROOT(temp);) { |
64 | namelen += (1 + temp->d_name.len); | 65 | namelen += (1 + temp->d_name.len); |
65 | temp = temp->d_parent; | 66 | temp = temp->d_parent; |
66 | if(temp == NULL) { | 67 | if (temp == NULL) { |
67 | cERROR(1,("corrupt dentry")); | 68 | cERROR(1, ("corrupt dentry")); |
68 | return NULL; | 69 | return NULL; |
69 | } | 70 | } |
70 | } | 71 | } |
71 | 72 | ||
72 | full_path = kmalloc(namelen+1, GFP_KERNEL); | 73 | full_path = kmalloc(namelen+1, GFP_KERNEL); |
73 | if(full_path == NULL) | 74 | if (full_path == NULL) |
74 | return full_path; | 75 | return full_path; |
75 | full_path[namelen] = 0; /* trailing null */ | 76 | full_path[namelen] = 0; /* trailing null */ |
76 | for (temp = direntry; !IS_ROOT(temp);) { | 77 | for (temp = direntry; !IS_ROOT(temp);) { |
@@ -84,8 +85,8 @@ cifs_bp_rename_retry: | |||
84 | cFYI(0, ("name: %s", full_path + namelen)); | 85 | cFYI(0, ("name: %s", full_path + namelen)); |
85 | } | 86 | } |
86 | temp = temp->d_parent; | 87 | temp = temp->d_parent; |
87 | if(temp == NULL) { | 88 | if (temp == NULL) { |
88 | cERROR(1,("corrupt dentry")); | 89 | cERROR(1, ("corrupt dentry")); |
89 | kfree(full_path); | 90 | kfree(full_path); |
90 | return NULL; | 91 | return NULL; |
91 | } | 92 | } |
@@ -94,7 +95,7 @@ cifs_bp_rename_retry: | |||
94 | cERROR(1, | 95 | cERROR(1, |
95 | ("did not end path lookup where expected namelen is %d", | 96 | ("did not end path lookup where expected namelen is %d", |
96 | namelen)); | 97 | namelen)); |
97 | /* presumably this is only possible if racing with a rename | 98 | /* presumably this is only possible if racing with a rename |
98 | of one of the parent directories (we can not lock the dentries | 99 | of one of the parent directories (we can not lock the dentries |
99 | above us to prevent this, but retrying should be harmless) */ | 100 | above us to prevent this, but retrying should be harmless) */ |
100 | kfree(full_path); | 101 | kfree(full_path); |
@@ -106,7 +107,7 @@ cifs_bp_rename_retry: | |||
106 | since the '\' is a valid posix character so we can not switch | 107 | since the '\' is a valid posix character so we can not switch |
107 | those safely to '/' if any are found in the middle of the prepath */ | 108 | those safely to '/' if any are found in the middle of the prepath */ |
108 | /* BB test paths to Windows with '/' in the midst of prepath */ | 109 | /* BB test paths to Windows with '/' in the midst of prepath */ |
109 | strncpy(full_path,CIFS_SB(direntry->d_sb)->prepath,pplen); | 110 | strncpy(full_path, CIFS_SB(direntry->d_sb)->prepath, pplen); |
110 | return full_path; | 111 | return full_path; |
111 | } | 112 | } |
112 | 113 | ||
@@ -147,12 +148,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
147 | pTcon = cifs_sb->tcon; | 148 | pTcon = cifs_sb->tcon; |
148 | 149 | ||
149 | full_path = build_path_from_dentry(direntry); | 150 | full_path = build_path_from_dentry(direntry); |
150 | if(full_path == NULL) { | 151 | if (full_path == NULL) { |
151 | FreeXid(xid); | 152 | FreeXid(xid); |
152 | return -ENOMEM; | 153 | return -ENOMEM; |
153 | } | 154 | } |
154 | 155 | ||
155 | if(nd && (nd->flags & LOOKUP_OPEN)) { | 156 | if (nd && (nd->flags & LOOKUP_OPEN)) { |
156 | int oflags = nd->intent.open.flags; | 157 | int oflags = nd->intent.open.flags; |
157 | 158 | ||
158 | desiredAccess = 0; | 159 | desiredAccess = 0; |
@@ -164,28 +165,29 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
164 | write_only = TRUE; | 165 | write_only = TRUE; |
165 | } | 166 | } |
166 | 167 | ||
167 | if((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) | 168 | if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) |
168 | disposition = FILE_CREATE; | 169 | disposition = FILE_CREATE; |
169 | else if((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) | 170 | else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC)) |
170 | disposition = FILE_OVERWRITE_IF; | 171 | disposition = FILE_OVERWRITE_IF; |
171 | else if((oflags & O_CREAT) == O_CREAT) | 172 | else if ((oflags & O_CREAT) == O_CREAT) |
172 | disposition = FILE_OPEN_IF; | 173 | disposition = FILE_OPEN_IF; |
173 | else { | 174 | else { |
174 | cFYI(1,("Create flag not set in create function")); | 175 | cFYI(1, ("Create flag not set in create function")); |
175 | } | 176 | } |
176 | } | 177 | } |
177 | 178 | ||
178 | /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ | 179 | /* BB add processing to set equivalent of mode - e.g. via CreateX with |
180 | ACLs */ | ||
179 | if (oplockEnabled) | 181 | if (oplockEnabled) |
180 | oplock = REQ_OPLOCK; | 182 | oplock = REQ_OPLOCK; |
181 | 183 | ||
182 | buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); | 184 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
183 | if(buf == NULL) { | 185 | if (buf == NULL) { |
184 | kfree(full_path); | 186 | kfree(full_path); |
185 | FreeXid(xid); | 187 | FreeXid(xid); |
186 | return -ENOMEM; | 188 | return -ENOMEM; |
187 | } | 189 | } |
188 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) | 190 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
189 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 191 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
190 | desiredAccess, CREATE_NOT_DIR, | 192 | desiredAccess, CREATE_NOT_DIR, |
191 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 193 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
@@ -193,27 +195,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
193 | else | 195 | else |
194 | rc = -EIO; /* no NT SMB support fall into legacy open below */ | 196 | rc = -EIO; /* no NT SMB support fall into legacy open below */ |
195 | 197 | ||
196 | if(rc == -EIO) { | 198 | if (rc == -EIO) { |
197 | /* old server, retry the open legacy style */ | 199 | /* old server, retry the open legacy style */ |
198 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, | 200 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, |
199 | desiredAccess, CREATE_NOT_DIR, | 201 | desiredAccess, CREATE_NOT_DIR, |
200 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 202 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
201 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 203 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
202 | } | 204 | } |
203 | if (rc) { | 205 | if (rc) { |
204 | cFYI(1, ("cifs_create returned 0x%x", rc)); | 206 | cFYI(1, ("cifs_create returned 0x%x", rc)); |
205 | } else { | 207 | } else { |
206 | /* If Open reported that we actually created a file | 208 | /* If Open reported that we actually created a file |
207 | then we now have to set the mode if possible */ | 209 | then we now have to set the mode if possible */ |
208 | if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && | 210 | if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX) && |
209 | (oplock & CIFS_CREATE_ACTION)) | 211 | (oplock & CIFS_CREATE_ACTION)) { |
210 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 212 | mode &= ~current->fs->umask; |
213 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | ||
211 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 214 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
212 | (__u64)current->fsuid, | 215 | (__u64)current->fsuid, |
213 | (__u64)current->fsgid, | 216 | (__u64)current->fsgid, |
214 | 0 /* dev */, | 217 | 0 /* dev */, |
215 | cifs_sb->local_nls, | 218 | cifs_sb->local_nls, |
216 | cifs_sb->mnt_cifs_flags & | 219 | cifs_sb->mnt_cifs_flags & |
217 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 220 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
218 | } else { | 221 | } else { |
219 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 222 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
@@ -221,26 +224,28 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
221 | (__u64)-1, | 224 | (__u64)-1, |
222 | 0 /* dev */, | 225 | 0 /* dev */, |
223 | cifs_sb->local_nls, | 226 | cifs_sb->local_nls, |
224 | cifs_sb->mnt_cifs_flags & | 227 | cifs_sb->mnt_cifs_flags & |
225 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 228 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
226 | } | 229 | } |
227 | else { | 230 | } else { |
228 | /* BB implement mode setting via Windows security descriptors */ | 231 | /* BB implement mode setting via Windows security |
229 | /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ | 232 | descriptors e.g. */ |
230 | /* could set r/o dos attribute if mode & 0222 == 0 */ | 233 | /* CIFSSMBWinSetPerms(xid,pTcon,path,mode,-1,-1,nls);*/ |
234 | |||
235 | /* Could set r/o dos attribute if mode & 0222 == 0 */ | ||
231 | } | 236 | } |
232 | 237 | ||
233 | /* BB server might mask mode so we have to query for Unix case*/ | 238 | /* BB server might mask mode so we have to query for Unix case*/ |
234 | if (pTcon->ses->capabilities & CAP_UNIX) | 239 | if (pTcon->ses->capabilities & CAP_UNIX) |
235 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 240 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
236 | inode->i_sb,xid); | 241 | inode->i_sb, xid); |
237 | else { | 242 | else { |
238 | rc = cifs_get_inode_info(&newinode, full_path, | 243 | rc = cifs_get_inode_info(&newinode, full_path, |
239 | buf, inode->i_sb,xid); | 244 | buf, inode->i_sb, xid); |
240 | if(newinode) { | 245 | if (newinode) { |
241 | newinode->i_mode = mode; | 246 | newinode->i_mode = mode; |
242 | if((oplock & CIFS_CREATE_ACTION) && | 247 | if ((oplock & CIFS_CREATE_ACTION) && |
243 | (cifs_sb->mnt_cifs_flags & | 248 | (cifs_sb->mnt_cifs_flags & |
244 | CIFS_MOUNT_SET_UID)) { | 249 | CIFS_MOUNT_SET_UID)) { |
245 | newinode->i_uid = current->fsuid; | 250 | newinode->i_uid = current->fsuid; |
246 | newinode->i_gid = current->fsgid; | 251 | newinode->i_gid = current->fsgid; |
@@ -259,14 +264,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
259 | direntry->d_op = &cifs_dentry_ops; | 264 | direntry->d_op = &cifs_dentry_ops; |
260 | d_instantiate(direntry, newinode); | 265 | d_instantiate(direntry, newinode); |
261 | } | 266 | } |
262 | if((nd->flags & LOOKUP_OPEN) == FALSE) { | 267 | if ((nd->flags & LOOKUP_OPEN) == FALSE) { |
263 | /* mknod case - do not leave file open */ | 268 | /* mknod case - do not leave file open */ |
264 | CIFSSMBClose(xid, pTcon, fileHandle); | 269 | CIFSSMBClose(xid, pTcon, fileHandle); |
265 | } else if(newinode) { | 270 | } else if (newinode) { |
266 | pCifsFile = | 271 | pCifsFile = |
267 | kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); | 272 | kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); |
268 | 273 | ||
269 | if(pCifsFile == NULL) | 274 | if (pCifsFile == NULL) |
270 | goto cifs_create_out; | 275 | goto cifs_create_out; |
271 | pCifsFile->netfid = fileHandle; | 276 | pCifsFile->netfid = fileHandle; |
272 | pCifsFile->pid = current->tgid; | 277 | pCifsFile->pid = current->tgid; |
@@ -276,33 +281,33 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
276 | init_MUTEX(&pCifsFile->fh_sem); | 281 | init_MUTEX(&pCifsFile->fh_sem); |
277 | mutex_init(&pCifsFile->lock_mutex); | 282 | mutex_init(&pCifsFile->lock_mutex); |
278 | INIT_LIST_HEAD(&pCifsFile->llist); | 283 | INIT_LIST_HEAD(&pCifsFile->llist); |
279 | atomic_set(&pCifsFile->wrtPending,0); | 284 | atomic_set(&pCifsFile->wrtPending, 0); |
280 | 285 | ||
281 | /* set the following in open now | 286 | /* set the following in open now |
282 | pCifsFile->pfile = file; */ | 287 | pCifsFile->pfile = file; */ |
283 | write_lock(&GlobalSMBSeslock); | 288 | write_lock(&GlobalSMBSeslock); |
284 | list_add(&pCifsFile->tlist,&pTcon->openFileList); | 289 | list_add(&pCifsFile->tlist, &pTcon->openFileList); |
285 | pCifsInode = CIFS_I(newinode); | 290 | pCifsInode = CIFS_I(newinode); |
286 | if(pCifsInode) { | 291 | if (pCifsInode) { |
287 | /* if readable file instance put first in list*/ | 292 | /* if readable file instance put first in list*/ |
288 | if (write_only == TRUE) { | 293 | if (write_only == TRUE) { |
289 | list_add_tail(&pCifsFile->flist, | 294 | list_add_tail(&pCifsFile->flist, |
290 | &pCifsInode->openFileList); | 295 | &pCifsInode->openFileList); |
291 | } else { | 296 | } else { |
292 | list_add(&pCifsFile->flist, | 297 | list_add(&pCifsFile->flist, |
293 | &pCifsInode->openFileList); | 298 | &pCifsInode->openFileList); |
294 | } | 299 | } |
295 | if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 300 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
296 | pCifsInode->clientCanCacheAll = TRUE; | 301 | pCifsInode->clientCanCacheAll = TRUE; |
297 | pCifsInode->clientCanCacheRead = TRUE; | 302 | pCifsInode->clientCanCacheRead = TRUE; |
298 | cFYI(1,("Exclusive Oplock for inode %p", | 303 | cFYI(1, ("Exclusive Oplock inode %p", |
299 | newinode)); | 304 | newinode)); |
300 | } else if((oplock & 0xF) == OPLOCK_READ) | 305 | } else if ((oplock & 0xF) == OPLOCK_READ) |
301 | pCifsInode->clientCanCacheRead = TRUE; | 306 | pCifsInode->clientCanCacheRead = TRUE; |
302 | } | 307 | } |
303 | write_unlock(&GlobalSMBSeslock); | 308 | write_unlock(&GlobalSMBSeslock); |
304 | } | 309 | } |
305 | } | 310 | } |
306 | cifs_create_out: | 311 | cifs_create_out: |
307 | kfree(buf); | 312 | kfree(buf); |
308 | kfree(full_path); | 313 | kfree(full_path); |
@@ -310,8 +315,8 @@ cifs_create_out: | |||
310 | return rc; | 315 | return rc; |
311 | } | 316 | } |
312 | 317 | ||
313 | int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | 318 | int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, |
314 | dev_t device_number) | 319 | dev_t device_number) |
315 | { | 320 | { |
316 | int rc = -EPERM; | 321 | int rc = -EPERM; |
317 | int xid; | 322 | int xid; |
@@ -329,43 +334,45 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
329 | pTcon = cifs_sb->tcon; | 334 | pTcon = cifs_sb->tcon; |
330 | 335 | ||
331 | full_path = build_path_from_dentry(direntry); | 336 | full_path = build_path_from_dentry(direntry); |
332 | if(full_path == NULL) | 337 | if (full_path == NULL) |
333 | rc = -ENOMEM; | 338 | rc = -ENOMEM; |
334 | else if (pTcon->ses->capabilities & CAP_UNIX) { | 339 | else if (pTcon->ses->capabilities & CAP_UNIX) { |
335 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 340 | mode &= ~current->fs->umask; |
341 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | ||
336 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 342 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
337 | mode,(__u64)current->fsuid,(__u64)current->fsgid, | 343 | mode, (__u64)current->fsuid, |
344 | (__u64)current->fsgid, | ||
338 | device_number, cifs_sb->local_nls, | 345 | device_number, cifs_sb->local_nls, |
339 | cifs_sb->mnt_cifs_flags & | 346 | cifs_sb->mnt_cifs_flags & |
340 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 347 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
341 | } else { | 348 | } else { |
342 | rc = CIFSSMBUnixSetPerms(xid, pTcon, | 349 | rc = CIFSSMBUnixSetPerms(xid, pTcon, |
343 | full_path, mode, (__u64)-1, (__u64)-1, | 350 | full_path, mode, (__u64)-1, (__u64)-1, |
344 | device_number, cifs_sb->local_nls, | 351 | device_number, cifs_sb->local_nls, |
345 | cifs_sb->mnt_cifs_flags & | 352 | cifs_sb->mnt_cifs_flags & |
346 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 353 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
347 | } | 354 | } |
348 | 355 | ||
349 | if(!rc) { | 356 | if (!rc) { |
350 | rc = cifs_get_inode_info_unix(&newinode, full_path, | 357 | rc = cifs_get_inode_info_unix(&newinode, full_path, |
351 | inode->i_sb,xid); | 358 | inode->i_sb, xid); |
352 | if (pTcon->nocase) | 359 | if (pTcon->nocase) |
353 | direntry->d_op = &cifs_ci_dentry_ops; | 360 | direntry->d_op = &cifs_ci_dentry_ops; |
354 | else | 361 | else |
355 | direntry->d_op = &cifs_dentry_ops; | 362 | direntry->d_op = &cifs_dentry_ops; |
356 | if(rc == 0) | 363 | if (rc == 0) |
357 | d_instantiate(direntry, newinode); | 364 | d_instantiate(direntry, newinode); |
358 | } | 365 | } |
359 | } else { | 366 | } else { |
360 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 367 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
361 | int oplock = 0; | 368 | int oplock = 0; |
362 | u16 fileHandle; | 369 | u16 fileHandle; |
363 | FILE_ALL_INFO * buf; | 370 | FILE_ALL_INFO * buf; |
364 | 371 | ||
365 | cFYI(1,("sfu compat create special file")); | 372 | cFYI(1, ("sfu compat create special file")); |
366 | 373 | ||
367 | buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); | 374 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
368 | if(buf == NULL) { | 375 | if (buf == NULL) { |
369 | kfree(full_path); | 376 | kfree(full_path); |
370 | FreeXid(xid); | 377 | FreeXid(xid); |
371 | return -ENOMEM; | 378 | return -ENOMEM; |
@@ -373,39 +380,38 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
373 | 380 | ||
374 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 381 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
375 | FILE_CREATE, /* fail if exists */ | 382 | FILE_CREATE, /* fail if exists */ |
376 | GENERIC_WRITE /* BB would | 383 | GENERIC_WRITE /* BB would |
377 | WRITE_OWNER | WRITE_DAC be better? */, | 384 | WRITE_OWNER | WRITE_DAC be better? */, |
378 | /* Create a file and set the | 385 | /* Create a file and set the |
379 | file attribute to SYSTEM */ | 386 | file attribute to SYSTEM */ |
380 | CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, | 387 | CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, |
381 | &fileHandle, &oplock, buf, | 388 | &fileHandle, &oplock, buf, |
382 | cifs_sb->local_nls, | 389 | cifs_sb->local_nls, |
383 | cifs_sb->mnt_cifs_flags & | 390 | cifs_sb->mnt_cifs_flags & |
384 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 391 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
385 | 392 | ||
386 | /* BB FIXME - add handling for backlevel servers | 393 | /* BB FIXME - add handling for backlevel servers |
387 | which need legacy open and check for all | 394 | which need legacy open and check for all |
388 | calls to SMBOpen for fallback to | 395 | calls to SMBOpen for fallback to SMBLeagcyOpen */ |
389 | SMBLeagcyOpen */ | 396 | if (!rc) { |
390 | if(!rc) { | ||
391 | /* BB Do not bother to decode buf since no | 397 | /* BB Do not bother to decode buf since no |
392 | local inode yet to put timestamps in, | 398 | local inode yet to put timestamps in, |
393 | but we can reuse it safely */ | 399 | but we can reuse it safely */ |
394 | int bytes_written; | 400 | int bytes_written; |
395 | struct win_dev *pdev; | 401 | struct win_dev *pdev; |
396 | pdev = (struct win_dev *)buf; | 402 | pdev = (struct win_dev *)buf; |
397 | if(S_ISCHR(mode)) { | 403 | if (S_ISCHR(mode)) { |
398 | memcpy(pdev->type, "IntxCHR", 8); | 404 | memcpy(pdev->type, "IntxCHR", 8); |
399 | pdev->major = | 405 | pdev->major = |
400 | cpu_to_le64(MAJOR(device_number)); | 406 | cpu_to_le64(MAJOR(device_number)); |
401 | pdev->minor = | 407 | pdev->minor = |
402 | cpu_to_le64(MINOR(device_number)); | 408 | cpu_to_le64(MINOR(device_number)); |
403 | rc = CIFSSMBWrite(xid, pTcon, | 409 | rc = CIFSSMBWrite(xid, pTcon, |
404 | fileHandle, | 410 | fileHandle, |
405 | sizeof(struct win_dev), | 411 | sizeof(struct win_dev), |
406 | 0, &bytes_written, (char *)pdev, | 412 | 0, &bytes_written, (char *)pdev, |
407 | NULL, 0); | 413 | NULL, 0); |
408 | } else if(S_ISBLK(mode)) { | 414 | } else if (S_ISBLK(mode)) { |
409 | memcpy(pdev->type, "IntxBLK", 8); | 415 | memcpy(pdev->type, "IntxBLK", 8); |
410 | pdev->major = | 416 | pdev->major = |
411 | cpu_to_le64(MAJOR(device_number)); | 417 | cpu_to_le64(MAJOR(device_number)); |
@@ -432,7 +438,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
432 | 438 | ||
433 | 439 | ||
434 | struct dentry * | 440 | struct dentry * |
435 | cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct nameidata *nd) | 441 | cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, |
442 | struct nameidata *nd) | ||
436 | { | 443 | { |
437 | int xid; | 444 | int xid; |
438 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ | 445 | int rc = 0; /* to get around spurious gcc warning, set to zero here */ |
@@ -447,8 +454,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
447 | (" parent inode = 0x%p name is: %s and dentry = 0x%p", | 454 | (" parent inode = 0x%p name is: %s and dentry = 0x%p", |
448 | parent_dir_inode, direntry->d_name.name, direntry)); | 455 | parent_dir_inode, direntry->d_name.name, direntry)); |
449 | 456 | ||
450 | /* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */ | ||
451 | |||
452 | /* check whether path exists */ | 457 | /* check whether path exists */ |
453 | 458 | ||
454 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); | 459 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); |
@@ -472,7 +477,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
472 | deadlock in the cases (beginning of sys_rename itself) | 477 | deadlock in the cases (beginning of sys_rename itself) |
473 | in which we already have the sb rename sem */ | 478 | in which we already have the sb rename sem */ |
474 | full_path = build_path_from_dentry(direntry); | 479 | full_path = build_path_from_dentry(direntry); |
475 | if(full_path == NULL) { | 480 | if (full_path == NULL) { |
476 | FreeXid(xid); | 481 | FreeXid(xid); |
477 | return ERR_PTR(-ENOMEM); | 482 | return ERR_PTR(-ENOMEM); |
478 | } | 483 | } |
@@ -487,10 +492,10 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
487 | 492 | ||
488 | if (pTcon->ses->capabilities & CAP_UNIX) | 493 | if (pTcon->ses->capabilities & CAP_UNIX) |
489 | rc = cifs_get_inode_info_unix(&newInode, full_path, | 494 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
490 | parent_dir_inode->i_sb,xid); | 495 | parent_dir_inode->i_sb, xid); |
491 | else | 496 | else |
492 | rc = cifs_get_inode_info(&newInode, full_path, NULL, | 497 | rc = cifs_get_inode_info(&newInode, full_path, NULL, |
493 | parent_dir_inode->i_sb,xid); | 498 | parent_dir_inode->i_sb, xid); |
494 | 499 | ||
495 | if ((rc == 0) && (newInode != NULL)) { | 500 | if ((rc == 0) && (newInode != NULL)) { |
496 | if (pTcon->nocase) | 501 | if (pTcon->nocase) |
@@ -499,7 +504,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
499 | direntry->d_op = &cifs_dentry_ops; | 504 | direntry->d_op = &cifs_dentry_ops; |
500 | d_add(direntry, newInode); | 505 | d_add(direntry, newInode); |
501 | 506 | ||
502 | /* since paths are not looked up by component - the parent | 507 | /* since paths are not looked up by component - the parent |
503 | directories are presumed to be good here */ | 508 | directories are presumed to be good here */ |
504 | renew_parental_timestamps(direntry); | 509 | renew_parental_timestamps(direntry); |
505 | 510 | ||
@@ -511,13 +516,13 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
511 | else | 516 | else |
512 | direntry->d_op = &cifs_dentry_ops; | 517 | direntry->d_op = &cifs_dentry_ops; |
513 | d_add(direntry, NULL); | 518 | d_add(direntry, NULL); |
514 | /* if it was once a directory (but how can we tell?) we could do | 519 | /* if it was once a directory (but how can we tell?) we could do |
515 | shrink_dcache_parent(direntry); */ | 520 | shrink_dcache_parent(direntry); */ |
516 | } else { | 521 | } else { |
517 | cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", | 522 | cERROR(1, ("Error 0x%x on cifs_get_inode_info in lookup of %s", |
518 | rc,full_path)); | 523 | rc, full_path)); |
519 | /* BB special case check for Access Denied - watch security | 524 | /* BB special case check for Access Denied - watch security |
520 | exposure of returning dir info implicitly via different rc | 525 | exposure of returning dir info implicitly via different rc |
521 | if file exists or not but no access BB */ | 526 | if file exists or not but no access BB */ |
522 | } | 527 | } |
523 | 528 | ||
@@ -538,11 +543,11 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
538 | } else { | 543 | } else { |
539 | cFYI(1, ("neg dentry 0x%p name = %s", | 544 | cFYI(1, ("neg dentry 0x%p name = %s", |
540 | direntry, direntry->d_name.name)); | 545 | direntry, direntry->d_name.name)); |
541 | if(time_after(jiffies, direntry->d_time + HZ) || | 546 | if (time_after(jiffies, direntry->d_time + HZ) || |
542 | !lookupCacheEnabled) { | 547 | !lookupCacheEnabled) { |
543 | d_drop(direntry); | 548 | d_drop(direntry); |
544 | isValid = 0; | 549 | isValid = 0; |
545 | } | 550 | } |
546 | } | 551 | } |
547 | 552 | ||
548 | return isValid; | 553 | return isValid; |
@@ -559,8 +564,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
559 | 564 | ||
560 | struct dentry_operations cifs_dentry_ops = { | 565 | struct dentry_operations cifs_dentry_ops = { |
561 | .d_revalidate = cifs_d_revalidate, | 566 | .d_revalidate = cifs_d_revalidate, |
562 | /* d_delete: cifs_d_delete, *//* not needed except for debugging */ | 567 | /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ |
563 | /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */ | ||
564 | }; | 568 | }; |
565 | 569 | ||
566 | static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) | 570 | static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index da12b482ebe5..8e375bb4b379 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * fs/cifs/fcntl.c | 2 | * fs/cifs/fcntl.c |
3 | * | 3 | * |
4 | * vfs operations that deal with the file control API | 4 | * vfs operations that deal with the file control API |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2003,2004 | 6 | * Copyright (C) International Business Machines Corp., 2003,2004 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
@@ -35,35 +35,34 @@ static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) | |||
35 | 35 | ||
36 | /* No way on Linux VFS to ask to monitor xattr | 36 | /* No way on Linux VFS to ask to monitor xattr |
37 | changes (and no stream support either */ | 37 | changes (and no stream support either */ |
38 | if(fcntl_notify_flags & DN_ACCESS) { | 38 | if (fcntl_notify_flags & DN_ACCESS) { |
39 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; | 39 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS; |
40 | } | 40 | } |
41 | if(fcntl_notify_flags & DN_MODIFY) { | 41 | if (fcntl_notify_flags & DN_MODIFY) { |
42 | /* What does this mean on directories? */ | 42 | /* What does this mean on directories? */ |
43 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | | 43 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE | |
44 | FILE_NOTIFY_CHANGE_SIZE; | 44 | FILE_NOTIFY_CHANGE_SIZE; |
45 | } | 45 | } |
46 | if(fcntl_notify_flags & DN_CREATE) { | 46 | if (fcntl_notify_flags & DN_CREATE) { |
47 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | | 47 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION | |
48 | FILE_NOTIFY_CHANGE_LAST_WRITE; | 48 | FILE_NOTIFY_CHANGE_LAST_WRITE; |
49 | } | 49 | } |
50 | if(fcntl_notify_flags & DN_DELETE) { | 50 | if (fcntl_notify_flags & DN_DELETE) { |
51 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; | 51 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE; |
52 | } | 52 | } |
53 | if(fcntl_notify_flags & DN_RENAME) { | 53 | if (fcntl_notify_flags & DN_RENAME) { |
54 | /* BB review this - checking various server behaviors */ | 54 | /* BB review this - checking various server behaviors */ |
55 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | | 55 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME | |
56 | FILE_NOTIFY_CHANGE_FILE_NAME; | 56 | FILE_NOTIFY_CHANGE_FILE_NAME; |
57 | } | 57 | } |
58 | if(fcntl_notify_flags & DN_ATTRIB) { | 58 | if (fcntl_notify_flags & DN_ATTRIB) { |
59 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY | | 59 | cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY | |
60 | FILE_NOTIFY_CHANGE_ATTRIBUTES; | 60 | FILE_NOTIFY_CHANGE_ATTRIBUTES; |
61 | } | 61 | } |
62 | /* if(fcntl_notify_flags & DN_MULTISHOT) { | 62 | /* if (fcntl_notify_flags & DN_MULTISHOT) { |
63 | cifs_ntfy_flags |= ; | 63 | cifs_ntfy_flags |= ; |
64 | } */ /* BB fixme - not sure how to handle this with CIFS yet */ | 64 | } */ /* BB fixme - not sure how to handle this with CIFS yet */ |
65 | 65 | ||
66 | |||
67 | return cifs_ntfy_flags; | 66 | return cifs_ntfy_flags; |
68 | } | 67 | } |
69 | 68 | ||
@@ -78,8 +77,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
78 | __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; | 77 | __u32 filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES; |
79 | __u16 netfid; | 78 | __u16 netfid; |
80 | 79 | ||
81 | 80 | if (experimEnabled == 0) | |
82 | if(experimEnabled == 0) | ||
83 | return 0; | 81 | return 0; |
84 | 82 | ||
85 | xid = GetXid(); | 83 | xid = GetXid(); |
@@ -88,21 +86,21 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
88 | 86 | ||
89 | full_path = build_path_from_dentry(file->f_path.dentry); | 87 | full_path = build_path_from_dentry(file->f_path.dentry); |
90 | 88 | ||
91 | if(full_path == NULL) { | 89 | if (full_path == NULL) { |
92 | rc = -ENOMEM; | 90 | rc = -ENOMEM; |
93 | } else { | 91 | } else { |
94 | cFYI(1,("dir notify on file %s Arg 0x%lx",full_path,arg)); | 92 | cFYI(1, ("dir notify on file %s Arg 0x%lx", full_path, arg)); |
95 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, | 93 | rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, |
96 | GENERIC_READ | SYNCHRONIZE, 0 /* create options */, | 94 | GENERIC_READ | SYNCHRONIZE, 0 /* create options */, |
97 | &netfid, &oplock,NULL, cifs_sb->local_nls, | 95 | &netfid, &oplock, NULL, cifs_sb->local_nls, |
98 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 96 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
99 | /* BB fixme - add this handle to a notify handle list */ | 97 | /* BB fixme - add this handle to a notify handle list */ |
100 | if(rc) { | 98 | if (rc) { |
101 | cFYI(1,("Could not open directory for notify")); | 99 | cFYI(1, ("Could not open directory for notify")); |
102 | } else { | 100 | } else { |
103 | filter = convert_to_cifs_notify_flags(arg); | 101 | filter = convert_to_cifs_notify_flags(arg); |
104 | if(filter != 0) { | 102 | if (filter != 0) { |
105 | rc = CIFSSMBNotify(xid, pTcon, | 103 | rc = CIFSSMBNotify(xid, pTcon, |
106 | 0 /* no subdirs */, netfid, | 104 | 0 /* no subdirs */, netfid, |
107 | filter, file, arg & DN_MULTISHOT, | 105 | filter, file, arg & DN_MULTISHOT, |
108 | cifs_sb->local_nls); | 106 | cifs_sb->local_nls); |
@@ -113,10 +111,10 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
113 | it would close automatically but may be a way | 111 | it would close automatically but may be a way |
114 | to do it easily when inode freed or when | 112 | to do it easily when inode freed or when |
115 | notify info is cleared/changed */ | 113 | notify info is cleared/changed */ |
116 | cFYI(1,("notify rc %d",rc)); | 114 | cFYI(1, ("notify rc %d", rc)); |
117 | } | 115 | } |
118 | } | 116 | } |
119 | 117 | ||
120 | FreeXid(xid); | 118 | FreeXid(xid); |
121 | return rc; | 119 | return rc; |
122 | } | 120 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 3e87dad3367c..f0ff12b3f398 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -986,7 +986,8 @@ mkdir_get_info: | |||
986 | * failed to get it from the server or was set bogus */ | 986 | * failed to get it from the server or was set bogus */ |
987 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) | 987 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) |
988 | direntry->d_inode->i_nlink = 2; | 988 | direntry->d_inode->i_nlink = 2; |
989 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) | 989 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { |
990 | mode &= ~current->fs->umask; | ||
990 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 991 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
991 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 992 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
992 | mode, | 993 | mode, |
@@ -1004,7 +1005,7 @@ mkdir_get_info: | |||
1004 | cifs_sb->mnt_cifs_flags & | 1005 | cifs_sb->mnt_cifs_flags & |
1005 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1006 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1006 | } | 1007 | } |
1007 | else { | 1008 | } else { |
1008 | /* BB to be implemented via Windows secrty descriptors | 1009 | /* BB to be implemented via Windows secrty descriptors |
1009 | eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, | 1010 | eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, |
1010 | -1, -1, local_nls); */ | 1011 | -1, -1, local_nls); */ |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index e34c7db00f6f..a414f1775ae0 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) | 31 | #define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2) |
32 | 32 | ||
33 | int cifs_ioctl (struct inode * inode, struct file * filep, | 33 | int cifs_ioctl (struct inode * inode, struct file * filep, |
34 | unsigned int command, unsigned long arg) | 34 | unsigned int command, unsigned long arg) |
35 | { | 35 | { |
36 | int rc = -ENOTTY; /* strange error - but the precedent */ | 36 | int rc = -ENOTTY; /* strange error - but the precedent */ |
@@ -47,13 +47,13 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
47 | 47 | ||
48 | xid = GetXid(); | 48 | xid = GetXid(); |
49 | 49 | ||
50 | cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); | 50 | cFYI(1, ("ioctl file %p cmd %u arg %lu", filep, command, arg)); |
51 | 51 | ||
52 | cifs_sb = CIFS_SB(inode->i_sb); | 52 | cifs_sb = CIFS_SB(inode->i_sb); |
53 | 53 | ||
54 | #ifdef CONFIG_CIFS_POSIX | 54 | #ifdef CONFIG_CIFS_POSIX |
55 | tcon = cifs_sb->tcon; | 55 | tcon = cifs_sb->tcon; |
56 | if(tcon) | 56 | if (tcon) |
57 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); | 57 | caps = le64_to_cpu(tcon->fsUnixInfo.Capability); |
58 | else { | 58 | else { |
59 | rc = -EIO; | 59 | rc = -EIO; |
@@ -62,24 +62,24 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
62 | } | 62 | } |
63 | #endif /* CONFIG_CIFS_POSIX */ | 63 | #endif /* CONFIG_CIFS_POSIX */ |
64 | 64 | ||
65 | switch(command) { | 65 | switch (command) { |
66 | case CIFS_IOC_CHECKUMOUNT: | 66 | case CIFS_IOC_CHECKUMOUNT: |
67 | cFYI(1,("User unmount attempted")); | 67 | cFYI(1, ("User unmount attempted")); |
68 | if(cifs_sb->mnt_uid == current->uid) | 68 | if (cifs_sb->mnt_uid == current->uid) |
69 | rc = 0; | 69 | rc = 0; |
70 | else { | 70 | else { |
71 | rc = -EACCES; | 71 | rc = -EACCES; |
72 | cFYI(1,("uids do not match")); | 72 | cFYI(1, ("uids do not match")); |
73 | } | 73 | } |
74 | break; | 74 | break; |
75 | #ifdef CONFIG_CIFS_POSIX | 75 | #ifdef CONFIG_CIFS_POSIX |
76 | case FS_IOC_GETFLAGS: | 76 | case FS_IOC_GETFLAGS: |
77 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | 77 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
78 | if (pSMBFile == NULL) | 78 | if (pSMBFile == NULL) |
79 | break; | 79 | break; |
80 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | 80 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, |
81 | &ExtAttrBits, &ExtAttrMask); | 81 | &ExtAttrBits, &ExtAttrMask); |
82 | if(rc == 0) | 82 | if (rc == 0) |
83 | rc = put_user(ExtAttrBits & | 83 | rc = put_user(ExtAttrBits & |
84 | FS_FL_USER_VISIBLE, | 84 | FS_FL_USER_VISIBLE, |
85 | (int __user *)arg); | 85 | (int __user *)arg); |
@@ -87,8 +87,8 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
87 | break; | 87 | break; |
88 | 88 | ||
89 | case FS_IOC_SETFLAGS: | 89 | case FS_IOC_SETFLAGS: |
90 | if(CIFS_UNIX_EXTATTR_CAP & caps) { | 90 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
91 | if(get_user(ExtAttrBits,(int __user *)arg)) { | 91 | if (get_user(ExtAttrBits, (int __user *)arg)) { |
92 | rc = -EFAULT; | 92 | rc = -EFAULT; |
93 | break; | 93 | break; |
94 | } | 94 | } |
@@ -96,16 +96,15 @@ int cifs_ioctl (struct inode * inode, struct file * filep, | |||
96 | break; | 96 | break; |
97 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, | 97 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, |
98 | extAttrBits, &ExtAttrMask);*/ | 98 | extAttrBits, &ExtAttrMask);*/ |
99 | |||
100 | } | 99 | } |
101 | cFYI(1,("set flags not implemented yet")); | 100 | cFYI(1, ("set flags not implemented yet")); |
102 | break; | 101 | break; |
103 | #endif /* CONFIG_CIFS_POSIX */ | 102 | #endif /* CONFIG_CIFS_POSIX */ |
104 | default: | 103 | default: |
105 | cFYI(1,("unsupported ioctl")); | 104 | cFYI(1, ("unsupported ioctl")); |
106 | break; | 105 | break; |
107 | } | 106 | } |
108 | 107 | ||
109 | FreeXid(xid); | 108 | FreeXid(xid); |
110 | return rc; | 109 | return rc; |
111 | } | 110 | } |
diff --git a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h index aede606132aa..8b69fcceb597 100644 --- a/fs/cifs/rfc1002pdu.h +++ b/fs/cifs/rfc1002pdu.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * | 18 | * |
19 | * You should have received a copy of the GNU Lesser General Public License | 19 | * You should have received a copy of the GNU Lesser General Public License |
20 | * along with this library; if not, write to the Free Software | 20 | * along with this library; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ | 24 | /* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */ |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 8593f3dfd299..52bb2638f7ab 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1106,7 +1106,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1106 | spin_lock_irqsave(&dio->bio_lock, flags); | 1106 | spin_lock_irqsave(&dio->bio_lock, flags); |
1107 | ret2 = --dio->refcount; | 1107 | ret2 = --dio->refcount; |
1108 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 1108 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
1109 | BUG_ON(!dio->is_async && ret2 != 0); | 1109 | |
1110 | if (ret2 == 0) { | 1110 | if (ret2 == 0) { |
1111 | ret = dio_complete(dio, offset, ret); | 1111 | ret = dio_complete(dio, offset, ret); |
1112 | kfree(dio); | 1112 | kfree(dio); |
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig index 69a94690e493..54bcc00ec8df 100644 --- a/fs/dlm/Kconfig +++ b/fs/dlm/Kconfig | |||
@@ -3,7 +3,7 @@ menu "Distributed Lock Manager" | |||
3 | 3 | ||
4 | config DLM | 4 | config DLM |
5 | tristate "Distributed Lock Manager (DLM)" | 5 | tristate "Distributed Lock Manager (DLM)" |
6 | depends on IPV6 || IPV6=n | 6 | depends on SYSFS && (IPV6 || IPV6=n) |
7 | select CONFIGFS_FS | 7 | select CONFIGFS_FS |
8 | select IP_SCTP | 8 | select IP_SCTP |
9 | help | 9 | help |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 403e3bad1455..1b9dd9a96f19 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -580,5 +580,7 @@ void | |||
580 | ecryptfs_write_header_metadata(char *virt, | 580 | ecryptfs_write_header_metadata(char *virt, |
581 | struct ecryptfs_crypt_stat *crypt_stat, | 581 | struct ecryptfs_crypt_stat *crypt_stat, |
582 | size_t *written); | 582 | size_t *written); |
583 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, | ||
584 | int num_zeros); | ||
583 | 585 | ||
584 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 586 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 1548be26b5e6..83e94fedd4e9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -800,6 +800,25 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
800 | goto out_fput; | 800 | goto out_fput; |
801 | } | 801 | } |
802 | } else { /* new_length < i_size_read(inode) */ | 802 | } else { /* new_length < i_size_read(inode) */ |
803 | pgoff_t index = 0; | ||
804 | int end_pos_in_page = -1; | ||
805 | |||
806 | if (new_length != 0) { | ||
807 | index = ((new_length - 1) >> PAGE_CACHE_SHIFT); | ||
808 | end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); | ||
809 | } | ||
810 | if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) { | ||
811 | if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file, | ||
812 | index, | ||
813 | (end_pos_in_page + 1), | ||
814 | ((PAGE_CACHE_SIZE - 1) | ||
815 | - end_pos_in_page)))) { | ||
816 | printk(KERN_ERR "Error attempting to zero out " | ||
817 | "the remainder of the end page on " | ||
818 | "reducing truncate; rc = [%d]\n", rc); | ||
819 | goto out_fput; | ||
820 | } | ||
821 | } | ||
803 | vmtruncate(inode, new_length); | 822 | vmtruncate(inode, new_length); |
804 | rc = ecryptfs_write_inode_size_to_metadata( | 823 | rc = ecryptfs_write_inode_size_to_metadata( |
805 | lower_file, lower_dentry->d_inode, inode, dentry, | 824 | lower_file, lower_dentry->d_inode, inode, dentry, |
@@ -875,9 +894,54 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
875 | struct ecryptfs_crypt_stat *crypt_stat; | 894 | struct ecryptfs_crypt_stat *crypt_stat; |
876 | 895 | ||
877 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 896 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
878 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 897 | if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) |
898 | ecryptfs_init_crypt_stat(crypt_stat); | ||
879 | inode = dentry->d_inode; | 899 | inode = dentry->d_inode; |
880 | lower_inode = ecryptfs_inode_to_lower(inode); | 900 | lower_inode = ecryptfs_inode_to_lower(inode); |
901 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
902 | mutex_lock(&crypt_stat->cs_mutex); | ||
903 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
904 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
905 | else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | ||
906 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | ||
907 | struct vfsmount *lower_mnt; | ||
908 | struct file *lower_file = NULL; | ||
909 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
910 | int lower_flags; | ||
911 | |||
912 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
913 | lower_flags = O_RDONLY; | ||
914 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, | ||
915 | lower_mnt, lower_flags))) { | ||
916 | printk(KERN_ERR | ||
917 | "Error opening lower file; rc = [%d]\n", rc); | ||
918 | mutex_unlock(&crypt_stat->cs_mutex); | ||
919 | goto out; | ||
920 | } | ||
921 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
922 | dentry->d_sb)->mount_crypt_stat; | ||
923 | if ((rc = ecryptfs_read_metadata(dentry, lower_file))) { | ||
924 | if (!(mount_crypt_stat->flags | ||
925 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
926 | rc = -EIO; | ||
927 | printk(KERN_WARNING "Attempt to read file that " | ||
928 | "is not in a valid eCryptfs format, " | ||
929 | "and plaintext passthrough mode is not " | ||
930 | "enabled; returning -EIO\n"); | ||
931 | |||
932 | mutex_unlock(&crypt_stat->cs_mutex); | ||
933 | fput(lower_file); | ||
934 | goto out; | ||
935 | } | ||
936 | rc = 0; | ||
937 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
938 | mutex_unlock(&crypt_stat->cs_mutex); | ||
939 | fput(lower_file); | ||
940 | goto out; | ||
941 | } | ||
942 | fput(lower_file); | ||
943 | } | ||
944 | mutex_unlock(&crypt_stat->cs_mutex); | ||
881 | if (ia->ia_valid & ATTR_SIZE) { | 945 | if (ia->ia_valid & ATTR_SIZE) { |
882 | ecryptfs_printk(KERN_DEBUG, | 946 | ecryptfs_printk(KERN_DEBUG, |
883 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", | 947 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 55cec98a84e7..7d5a43cb0d5c 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -56,9 +56,6 @@ static struct page *ecryptfs_get1page(struct file *file, int index) | |||
56 | return read_mapping_page(mapping, index, (void *)file); | 56 | return read_mapping_page(mapping, index, (void *)file); |
57 | } | 57 | } |
58 | 58 | ||
59 | static | ||
60 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros); | ||
61 | |||
62 | /** | 59 | /** |
63 | * ecryptfs_fill_zeros | 60 | * ecryptfs_fill_zeros |
64 | * @file: The ecryptfs file | 61 | * @file: The ecryptfs file |
@@ -101,10 +98,13 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
101 | if (old_end_page_index == new_end_page_index) { | 98 | if (old_end_page_index == new_end_page_index) { |
102 | /* Start and end are in the same page; we just need to | 99 | /* Start and end are in the same page; we just need to |
103 | * set a portion of the existing page to zero's */ | 100 | * set a portion of the existing page to zero's */ |
104 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | 101 | rc = ecryptfs_write_zeros(file, index, |
105 | (new_end_pos_in_page - old_end_pos_in_page)); | 102 | (old_end_pos_in_page + 1), |
103 | (new_end_pos_in_page | ||
104 | - old_end_pos_in_page)); | ||
106 | if (rc) | 105 | if (rc) |
107 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 106 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" |
107 | "file=[%p], " | ||
108 | "index=[0x%.16x], " | 108 | "index=[0x%.16x], " |
109 | "old_end_pos_in_page=[d], " | 109 | "old_end_pos_in_page=[d], " |
110 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | 110 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" |
@@ -117,10 +117,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
117 | goto out; | 117 | goto out; |
118 | } | 118 | } |
119 | /* Fill the remainder of the previous last page with zeros */ | 119 | /* Fill the remainder of the previous last page with zeros */ |
120 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | 120 | rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1), |
121 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); | 121 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); |
122 | if (rc) { | 122 | if (rc) { |
123 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 123 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], " |
124 | "index=[0x%.16x], old_end_pos_in_page=[d], " | 124 | "index=[0x%.16x], old_end_pos_in_page=[d], " |
125 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " | 125 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " |
126 | "returned [%d]\n", file, index, | 126 | "returned [%d]\n", file, index, |
@@ -131,9 +131,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
131 | index++; | 131 | index++; |
132 | while (index < new_end_page_index) { | 132 | while (index < new_end_page_index) { |
133 | /* Fill all intermediate pages with zeros */ | 133 | /* Fill all intermediate pages with zeros */ |
134 | rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE); | 134 | rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE); |
135 | if (rc) { | 135 | if (rc) { |
136 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 136 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" |
137 | "file=[%p], " | ||
137 | "index=[0x%.16x], " | 138 | "index=[0x%.16x], " |
138 | "old_end_pos_in_page=[d], " | 139 | "old_end_pos_in_page=[d], " |
139 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | 140 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" |
@@ -149,9 +150,9 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
149 | } | 150 | } |
150 | /* Fill the portion at the beginning of the last new page with | 151 | /* Fill the portion at the beginning of the last new page with |
151 | * zero's */ | 152 | * zero's */ |
152 | rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1)); | 153 | rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1)); |
153 | if (rc) { | 154 | if (rc) { |
154 | ecryptfs_printk(KERN_ERR, "write_zeros(file=" | 155 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=" |
155 | "[%p], index=[0x%.16x], 0, " | 156 | "[%p], index=[0x%.16x], 0, " |
156 | "new_end_pos_in_page=[%d]" | 157 | "new_end_pos_in_page=[%d]" |
157 | "returned [%d]\n", file, index, | 158 | "returned [%d]\n", file, index, |
@@ -400,7 +401,6 @@ out: | |||
400 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 401 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
401 | unsigned from, unsigned to) | 402 | unsigned from, unsigned to) |
402 | { | 403 | { |
403 | loff_t pos; | ||
404 | int rc = 0; | 404 | int rc = 0; |
405 | 405 | ||
406 | if (from == 0 && to == PAGE_CACHE_SIZE) | 406 | if (from == 0 && to == PAGE_CACHE_SIZE) |
@@ -408,15 +408,22 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
408 | up to date. */ | 408 | up to date. */ |
409 | if (!PageUptodate(page)) | 409 | if (!PageUptodate(page)) |
410 | rc = ecryptfs_do_readpage(file, page, page->index); | 410 | rc = ecryptfs_do_readpage(file, page, page->index); |
411 | pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; | 411 | if (page->index != 0) { |
412 | if (pos > i_size_read(page->mapping->host)) { | 412 | loff_t end_of_prev_pg_pos = |
413 | rc = ecryptfs_truncate(file->f_path.dentry, pos); | 413 | (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); |
414 | if (rc) { | 414 | |
415 | printk(KERN_ERR "Error on attempt to " | 415 | if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { |
416 | "truncate to (higher) offset [%lld];" | 416 | rc = ecryptfs_truncate(file->f_path.dentry, |
417 | " rc = [%d]\n", pos, rc); | 417 | end_of_prev_pg_pos); |
418 | goto out; | 418 | if (rc) { |
419 | printk(KERN_ERR "Error on attempt to " | ||
420 | "truncate to (higher) offset [%lld];" | ||
421 | " rc = [%d]\n", end_of_prev_pg_pos, rc); | ||
422 | goto out; | ||
423 | } | ||
419 | } | 424 | } |
425 | if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) | ||
426 | zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); | ||
420 | } | 427 | } |
421 | out: | 428 | out: |
422 | return rc; | 429 | return rc; |
@@ -753,7 +760,7 @@ out: | |||
753 | } | 760 | } |
754 | 761 | ||
755 | /** | 762 | /** |
756 | * write_zeros | 763 | * ecryptfs_write_zeros |
757 | * @file: The ecryptfs file | 764 | * @file: The ecryptfs file |
758 | * @index: The index in which we are writing | 765 | * @index: The index in which we are writing |
759 | * @start: The position after the last block of data | 766 | * @start: The position after the last block of data |
@@ -763,8 +770,8 @@ out: | |||
763 | * | 770 | * |
764 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE | 771 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE |
765 | */ | 772 | */ |
766 | static | 773 | int |
767 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | 774 | ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) |
768 | { | 775 | { |
769 | int rc = 0; | 776 | int rc = 0; |
770 | struct page *tmp_page; | 777 | struct page *tmp_page; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 16337bff0272..5de5061eb331 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1038,6 +1038,15 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1038 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 1038 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
1039 | ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 1039 | ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); |
1040 | 1040 | ||
1041 | ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset | ||
1042 | EXT2_MOUNT_XIP if not */ | ||
1043 | |||
1044 | if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { | ||
1045 | printk("XIP: Unsupported blocksize\n"); | ||
1046 | err = -EINVAL; | ||
1047 | goto restore_opts; | ||
1048 | } | ||
1049 | |||
1041 | es = sbi->s_es; | 1050 | es = sbi->s_es; |
1042 | if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != | 1051 | if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != |
1043 | (old_mount_opt & EXT2_MOUNT_XIP)) && | 1052 | (old_mount_opt & EXT2_MOUNT_XIP)) && |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a6cb6171c3af..2a85ddee4740 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -2677,8 +2677,10 @@ void ext3_read_inode(struct inode * inode) | |||
2677 | */ | 2677 | */ |
2678 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); | 2678 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); |
2679 | if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > | 2679 | if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > |
2680 | EXT3_INODE_SIZE(inode->i_sb)) | 2680 | EXT3_INODE_SIZE(inode->i_sb)) { |
2681 | brelse (bh); | ||
2681 | goto bad_inode; | 2682 | goto bad_inode; |
2683 | } | ||
2682 | if (ei->i_extra_isize == 0) { | 2684 | if (ei->i_extra_isize == 0) { |
2683 | /* The extra space is currently unused. Use it. */ | 2685 | /* The extra space is currently unused. Use it. */ |
2684 | ei->i_extra_isize = sizeof(struct ext3_inode) - | 2686 | ei->i_extra_isize = sizeof(struct ext3_inode) - |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0bcf62a750ff..8416fa28c422 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2673,8 +2673,10 @@ void ext4_read_inode(struct inode * inode) | |||
2673 | */ | 2673 | */ |
2674 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); | 2674 | ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); |
2675 | if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > | 2675 | if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > |
2676 | EXT4_INODE_SIZE(inode->i_sb)) | 2676 | EXT4_INODE_SIZE(inode->i_sb)) { |
2677 | brelse (bh); | ||
2677 | goto bad_inode; | 2678 | goto bad_inode; |
2679 | } | ||
2678 | if (ei->i_extra_isize == 0) { | 2680 | if (ei->i_extra_isize == 0) { |
2679 | /* The extra space is currently unused. Use it. */ | 2681 | /* The extra space is currently unused. Use it. */ |
2680 | ei->i_extra_isize = sizeof(struct ext4_inode) - | 2682 | ei->i_extra_isize = sizeof(struct ext4_inode) - |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 9804c0cdcb42..cc5efc13496a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -655,10 +655,9 @@ static int fuse_get_sb_blk(struct file_system_type *fs_type, | |||
655 | static struct file_system_type fuseblk_fs_type = { | 655 | static struct file_system_type fuseblk_fs_type = { |
656 | .owner = THIS_MODULE, | 656 | .owner = THIS_MODULE, |
657 | .name = "fuseblk", | 657 | .name = "fuseblk", |
658 | .fs_flags = FS_HAS_SUBTYPE, | ||
659 | .get_sb = fuse_get_sb_blk, | 658 | .get_sb = fuse_get_sb_blk, |
660 | .kill_sb = kill_block_super, | 659 | .kill_sb = kill_block_super, |
661 | .fs_flags = FS_REQUIRES_DEV, | 660 | .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, |
662 | }; | 661 | }; |
663 | 662 | ||
664 | static inline int register_fuseblk(void) | 663 | static inline int register_fuseblk(void) |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index aa083dd34e92..e6b46b3ac2fe 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -736,15 +736,13 @@ static int can_do_hugetlb_shm(void) | |||
736 | can_do_mlock()); | 736 | can_do_mlock()); |
737 | } | 737 | } |
738 | 738 | ||
739 | struct file *hugetlb_zero_setup(size_t size) | 739 | struct file *hugetlb_file_setup(const char *name, size_t size) |
740 | { | 740 | { |
741 | int error = -ENOMEM; | 741 | int error = -ENOMEM; |
742 | struct file *file; | 742 | struct file *file; |
743 | struct inode *inode; | 743 | struct inode *inode; |
744 | struct dentry *dentry, *root; | 744 | struct dentry *dentry, *root; |
745 | struct qstr quick_string; | 745 | struct qstr quick_string; |
746 | char buf[16]; | ||
747 | static atomic_t counter; | ||
748 | 746 | ||
749 | if (!hugetlbfs_vfsmount) | 747 | if (!hugetlbfs_vfsmount) |
750 | return ERR_PTR(-ENOENT); | 748 | return ERR_PTR(-ENOENT); |
@@ -756,8 +754,7 @@ struct file *hugetlb_zero_setup(size_t size) | |||
756 | return ERR_PTR(-ENOMEM); | 754 | return ERR_PTR(-ENOMEM); |
757 | 755 | ||
758 | root = hugetlbfs_vfsmount->mnt_root; | 756 | root = hugetlbfs_vfsmount->mnt_root; |
759 | snprintf(buf, 16, "%u", atomic_inc_return(&counter)); | 757 | quick_string.name = name; |
760 | quick_string.name = buf; | ||
761 | quick_string.len = strlen(quick_string.name); | 758 | quick_string.len = strlen(quick_string.name); |
762 | quick_string.hash = 0; | 759 | quick_string.hash = 0; |
763 | dentry = d_alloc(root, &quick_string); | 760 | dentry = d_alloc(root, &quick_string); |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 12e83f67eee4..7b363786c2d2 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -210,8 +210,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info * | |||
210 | * offset, and the one with the smallest length will come first in the | 210 | * offset, and the one with the smallest length will come first in the |
211 | * ordering. | 211 | * ordering. |
212 | * | 212 | * |
213 | * Returns 0 if the node was inserted | 213 | * Returns 0 if the node was handled (including marking it obsolete) |
214 | * 1 if the node is obsolete (because we can't mark it so yet) | ||
215 | * < 0 an if error occurred | 214 | * < 0 an if error occurred |
216 | */ | 215 | */ |
217 | static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | 216 | static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, |
@@ -572,8 +571,7 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r | |||
572 | * Helper function for jffs2_get_inode_nodes(). | 571 | * Helper function for jffs2_get_inode_nodes(). |
573 | * It is called every time an directory entry node is found. | 572 | * It is called every time an directory entry node is found. |
574 | * | 573 | * |
575 | * Returns: 0 on succes; | 574 | * Returns: 0 on success; |
576 | * 1 if the node should be marked obsolete; | ||
577 | * negative error code on failure. | 575 | * negative error code on failure. |
578 | */ | 576 | */ |
579 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 577 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
@@ -680,8 +678,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
680 | * Helper function for jffs2_get_inode_nodes(). | 678 | * Helper function for jffs2_get_inode_nodes(). |
681 | * It is called every time an inode node is found. | 679 | * It is called every time an inode node is found. |
682 | * | 680 | * |
683 | * Returns: 0 on success; | 681 | * Returns: 0 on success (possibly after marking a bad node obsolete); |
684 | * 1 if the node should be marked obsolete; | ||
685 | * negative error code on failure. | 682 | * negative error code on failure. |
686 | */ | 683 | */ |
687 | static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 684 | static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
@@ -690,7 +687,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
690 | { | 687 | { |
691 | struct jffs2_tmp_dnode_info *tn; | 688 | struct jffs2_tmp_dnode_info *tn; |
692 | uint32_t len, csize; | 689 | uint32_t len, csize; |
693 | int ret = 1; | 690 | int ret = 0; |
694 | uint32_t crc; | 691 | uint32_t crc; |
695 | 692 | ||
696 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ | 693 | /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ |
@@ -719,8 +716,9 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
719 | /* Sanity checks */ | 716 | /* Sanity checks */ |
720 | if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || | 717 | if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || |
721 | unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { | 718 | unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { |
722 | JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); | 719 | JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); |
723 | jffs2_dbg_dump_node(c, ref_offset(ref)); | 720 | jffs2_dbg_dump_node(c, ref_offset(ref)); |
721 | jffs2_mark_node_obsolete(c, ref); | ||
724 | goto free_out; | 722 | goto free_out; |
725 | } | 723 | } |
726 | 724 | ||
@@ -775,6 +773,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
775 | if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { | 773 | if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { |
776 | JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", | 774 | JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", |
777 | ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); | 775 | ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); |
776 | jffs2_mark_node_obsolete(c, ref); | ||
778 | goto free_out; | 777 | goto free_out; |
779 | } | 778 | } |
780 | 779 | ||
@@ -854,7 +853,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
854 | * It is called every time an unknown node is found. | 853 | * It is called every time an unknown node is found. |
855 | * | 854 | * |
856 | * Returns: 0 on success; | 855 | * Returns: 0 on success; |
857 | * 1 if the node should be marked obsolete; | ||
858 | * negative error code on failure. | 856 | * negative error code on failure. |
859 | */ | 857 | */ |
860 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) | 858 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) |
@@ -1088,10 +1086,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
1088 | } | 1086 | } |
1089 | 1087 | ||
1090 | err = read_unknown(c, ref, &node->u); | 1088 | err = read_unknown(c, ref, &node->u); |
1091 | if (err == 1) { | 1089 | if (unlikely(err)) |
1092 | jffs2_mark_node_obsolete(c, ref); | ||
1093 | break; | ||
1094 | } else if (unlikely(err)) | ||
1095 | goto free_out; | 1090 | goto free_out; |
1096 | 1091 | ||
1097 | } | 1092 | } |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 0023b31e48a8..a480b09c79b9 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -798,6 +798,11 @@ int ocfs2_map_and_write_splice_data(struct inode *inode, | |||
798 | } | 798 | } |
799 | to = from + bytes; | 799 | to = from + bytes; |
800 | 800 | ||
801 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
802 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
803 | BUG_ON(from < cluster_start); | ||
804 | BUG_ON(to > cluster_end); | ||
805 | |||
801 | if (wc->w_this_page_new) | 806 | if (wc->w_this_page_new) |
802 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, | 807 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, |
803 | cluster_start, cluster_end, 1); | 808 | cluster_start, cluster_end, 1); |
@@ -809,11 +814,6 @@ int ocfs2_map_and_write_splice_data(struct inode *inode, | |||
809 | goto out; | 814 | goto out; |
810 | } | 815 | } |
811 | 816 | ||
812 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
813 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
814 | BUG_ON(from > osb->s_clustersize); | ||
815 | BUG_ON(to > osb->s_clustersize); | ||
816 | |||
817 | src = buf->ops->map(sp->s_pipe, buf, 1); | 817 | src = buf->ops->map(sp->s_pipe, buf, 1); |
818 | dst = kmap_atomic(wc->w_this_page, KM_USER1); | 818 | dst = kmap_atomic(wc->w_this_page, KM_USER1); |
819 | memcpy(dst + from, src + src_from, bytes); | 819 | memcpy(dst + from, src + src_from, bytes); |
@@ -890,6 +890,11 @@ int ocfs2_map_and_write_user_data(struct inode *inode, | |||
890 | 890 | ||
891 | to = from + bytes; | 891 | to = from + bytes; |
892 | 892 | ||
893 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
894 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
895 | BUG_ON(from < cluster_start); | ||
896 | BUG_ON(to > cluster_end); | ||
897 | |||
893 | if (wc->w_this_page_new) | 898 | if (wc->w_this_page_new) |
894 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, | 899 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, |
895 | cluster_start, cluster_end, 1); | 900 | cluster_start, cluster_end, 1); |
@@ -901,11 +906,6 @@ int ocfs2_map_and_write_user_data(struct inode *inode, | |||
901 | goto out; | 906 | goto out; |
902 | } | 907 | } |
903 | 908 | ||
904 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
905 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
906 | BUG_ON(from > osb->s_clustersize); | ||
907 | BUG_ON(to > osb->s_clustersize); | ||
908 | |||
909 | dst = kmap(wc->w_this_page); | 909 | dst = kmap(wc->w_this_page); |
910 | memcpy(dst + from, bp->b_src_buf + src_from, bytes); | 910 | memcpy(dst + from, bp->b_src_buf + src_from, bytes); |
911 | kunmap(wc->w_this_page); | 911 | kunmap(wc->w_this_page); |
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index a93620ce4aca..2b205f5d5790 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -144,8 +144,7 @@ static struct kobj_type mlog_ktype = { | |||
144 | }; | 144 | }; |
145 | 145 | ||
146 | static struct kset mlog_kset = { | 146 | static struct kset mlog_kset = { |
147 | .kobj = {.name = "logmask"}, | 147 | .kobj = {.name = "logmask", .ktype = &mlog_ktype}, |
148 | .ktype = &mlog_ktype | ||
149 | }; | 148 | }; |
150 | 149 | ||
151 | int mlog_sys_init(struct kset *o2cb_subsys) | 150 | int mlog_sys_init(struct kset *o2cb_subsys) |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 74f30e0c0381..98e78e2f18d6 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -165,7 +165,6 @@ static inline char * task_state(struct task_struct *p, char *buffer) | |||
165 | rcu_read_lock(); | 165 | rcu_read_lock(); |
166 | buffer += sprintf(buffer, | 166 | buffer += sprintf(buffer, |
167 | "State:\t%s\n" | 167 | "State:\t%s\n" |
168 | "SleepAVG:\t%lu%%\n" | ||
169 | "Tgid:\t%d\n" | 168 | "Tgid:\t%d\n" |
170 | "Pid:\t%d\n" | 169 | "Pid:\t%d\n" |
171 | "PPid:\t%d\n" | 170 | "PPid:\t%d\n" |
@@ -173,7 +172,6 @@ static inline char * task_state(struct task_struct *p, char *buffer) | |||
173 | "Uid:\t%d\t%d\t%d\t%d\n" | 172 | "Uid:\t%d\t%d\t%d\t%d\n" |
174 | "Gid:\t%d\t%d\t%d\t%d\n", | 173 | "Gid:\t%d\t%d\t%d\t%d\n", |
175 | get_task_state(p), | 174 | get_task_state(p), |
176 | (p->sleep_avg/1024)*100/(1020000000/1024), | ||
177 | p->tgid, p->pid, | 175 | p->tgid, p->pid, |
178 | pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, | 176 | pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, |
179 | pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, | 177 | pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, |
@@ -312,6 +310,41 @@ int proc_pid_status(struct task_struct *task, char * buffer) | |||
312 | return buffer - orig; | 310 | return buffer - orig; |
313 | } | 311 | } |
314 | 312 | ||
313 | static clock_t task_utime(struct task_struct *p) | ||
314 | { | ||
315 | clock_t utime = cputime_to_clock_t(p->utime), | ||
316 | total = utime + cputime_to_clock_t(p->stime); | ||
317 | u64 temp; | ||
318 | |||
319 | /* | ||
320 | * Use CFS's precise accounting: | ||
321 | */ | ||
322 | temp = (u64)nsec_to_clock_t(p->se.sum_exec_runtime); | ||
323 | |||
324 | if (total) { | ||
325 | temp *= utime; | ||
326 | do_div(temp, total); | ||
327 | } | ||
328 | utime = (clock_t)temp; | ||
329 | |||
330 | return utime; | ||
331 | } | ||
332 | |||
333 | static clock_t task_stime(struct task_struct *p) | ||
334 | { | ||
335 | clock_t stime = cputime_to_clock_t(p->stime); | ||
336 | |||
337 | /* | ||
338 | * Use CFS's precise accounting. (we subtract utime from | ||
339 | * the total, to make sure the total observed by userspace | ||
340 | * grows monotonically - apps rely on that): | ||
341 | */ | ||
342 | stime = nsec_to_clock_t(p->se.sum_exec_runtime) - task_utime(p); | ||
343 | |||
344 | return stime; | ||
345 | } | ||
346 | |||
347 | |||
315 | static int do_task_stat(struct task_struct *task, char * buffer, int whole) | 348 | static int do_task_stat(struct task_struct *task, char * buffer, int whole) |
316 | { | 349 | { |
317 | unsigned long vsize, eip, esp, wchan = ~0UL; | 350 | unsigned long vsize, eip, esp, wchan = ~0UL; |
@@ -326,7 +359,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
326 | unsigned long long start_time; | 359 | unsigned long long start_time; |
327 | unsigned long cmin_flt = 0, cmaj_flt = 0; | 360 | unsigned long cmin_flt = 0, cmaj_flt = 0; |
328 | unsigned long min_flt = 0, maj_flt = 0; | 361 | unsigned long min_flt = 0, maj_flt = 0; |
329 | cputime_t cutime, cstime, utime, stime; | 362 | cputime_t cutime, cstime; |
363 | clock_t utime, stime; | ||
330 | unsigned long rsslim = 0; | 364 | unsigned long rsslim = 0; |
331 | char tcomm[sizeof(task->comm)]; | 365 | char tcomm[sizeof(task->comm)]; |
332 | unsigned long flags; | 366 | unsigned long flags; |
@@ -344,7 +378,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
344 | 378 | ||
345 | sigemptyset(&sigign); | 379 | sigemptyset(&sigign); |
346 | sigemptyset(&sigcatch); | 380 | sigemptyset(&sigcatch); |
347 | cutime = cstime = utime = stime = cputime_zero; | 381 | cutime = cstime = cputime_zero; |
382 | utime = stime = 0; | ||
348 | 383 | ||
349 | rcu_read_lock(); | 384 | rcu_read_lock(); |
350 | if (lock_task_sighand(task, &flags)) { | 385 | if (lock_task_sighand(task, &flags)) { |
@@ -370,15 +405,15 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
370 | do { | 405 | do { |
371 | min_flt += t->min_flt; | 406 | min_flt += t->min_flt; |
372 | maj_flt += t->maj_flt; | 407 | maj_flt += t->maj_flt; |
373 | utime = cputime_add(utime, t->utime); | 408 | utime += task_utime(t); |
374 | stime = cputime_add(stime, t->stime); | 409 | stime += task_stime(t); |
375 | t = next_thread(t); | 410 | t = next_thread(t); |
376 | } while (t != task); | 411 | } while (t != task); |
377 | 412 | ||
378 | min_flt += sig->min_flt; | 413 | min_flt += sig->min_flt; |
379 | maj_flt += sig->maj_flt; | 414 | maj_flt += sig->maj_flt; |
380 | utime = cputime_add(utime, sig->utime); | 415 | utime += cputime_to_clock_t(sig->utime); |
381 | stime = cputime_add(stime, sig->stime); | 416 | stime += cputime_to_clock_t(sig->stime); |
382 | } | 417 | } |
383 | 418 | ||
384 | sid = signal_session(sig); | 419 | sid = signal_session(sig); |
@@ -394,8 +429,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
394 | if (!whole) { | 429 | if (!whole) { |
395 | min_flt = task->min_flt; | 430 | min_flt = task->min_flt; |
396 | maj_flt = task->maj_flt; | 431 | maj_flt = task->maj_flt; |
397 | utime = task->utime; | 432 | utime = task_utime(task); |
398 | stime = task->stime; | 433 | stime = task_stime(task); |
399 | } | 434 | } |
400 | 435 | ||
401 | /* scale priority and nice values from timeslices to -20..20 */ | 436 | /* scale priority and nice values from timeslices to -20..20 */ |
@@ -426,8 +461,8 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) | |||
426 | cmin_flt, | 461 | cmin_flt, |
427 | maj_flt, | 462 | maj_flt, |
428 | cmaj_flt, | 463 | cmaj_flt, |
429 | cputime_to_clock_t(utime), | 464 | utime, |
430 | cputime_to_clock_t(stime), | 465 | stime, |
431 | cputime_to_clock_t(cutime), | 466 | cputime_to_clock_t(cutime), |
432 | cputime_to_clock_t(cstime), | 467 | cputime_to_clock_t(cstime), |
433 | priority, | 468 | priority, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index a5fa1fdafc4e..46ea5d56e1bb 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -296,7 +296,7 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer) | |||
296 | */ | 296 | */ |
297 | static int proc_pid_schedstat(struct task_struct *task, char *buffer) | 297 | static int proc_pid_schedstat(struct task_struct *task, char *buffer) |
298 | { | 298 | { |
299 | return sprintf(buffer, "%lu %lu %lu\n", | 299 | return sprintf(buffer, "%llu %llu %lu\n", |
300 | task->sched_info.cpu_time, | 300 | task->sched_info.cpu_time, |
301 | task->sched_info.run_delay, | 301 | task->sched_info.run_delay, |
302 | task->sched_info.pcnt); | 302 | task->sched_info.pcnt); |
@@ -929,6 +929,69 @@ static const struct file_operations proc_fault_inject_operations = { | |||
929 | }; | 929 | }; |
930 | #endif | 930 | #endif |
931 | 931 | ||
932 | #ifdef CONFIG_SCHED_DEBUG | ||
933 | /* | ||
934 | * Print out various scheduling related per-task fields: | ||
935 | */ | ||
936 | static int sched_show(struct seq_file *m, void *v) | ||
937 | { | ||
938 | struct inode *inode = m->private; | ||
939 | struct task_struct *p; | ||
940 | |||
941 | WARN_ON(!inode); | ||
942 | |||
943 | p = get_proc_task(inode); | ||
944 | if (!p) | ||
945 | return -ESRCH; | ||
946 | proc_sched_show_task(p, m); | ||
947 | |||
948 | put_task_struct(p); | ||
949 | |||
950 | return 0; | ||
951 | } | ||
952 | |||
953 | static ssize_t | ||
954 | sched_write(struct file *file, const char __user *buf, | ||
955 | size_t count, loff_t *offset) | ||
956 | { | ||
957 | struct inode *inode = file->f_path.dentry->d_inode; | ||
958 | struct task_struct *p; | ||
959 | |||
960 | WARN_ON(!inode); | ||
961 | |||
962 | p = get_proc_task(inode); | ||
963 | if (!p) | ||
964 | return -ESRCH; | ||
965 | proc_sched_set_task(p); | ||
966 | |||
967 | put_task_struct(p); | ||
968 | |||
969 | return count; | ||
970 | } | ||
971 | |||
972 | static int sched_open(struct inode *inode, struct file *filp) | ||
973 | { | ||
974 | int ret; | ||
975 | |||
976 | ret = single_open(filp, sched_show, NULL); | ||
977 | if (!ret) { | ||
978 | struct seq_file *m = filp->private_data; | ||
979 | |||
980 | m->private = inode; | ||
981 | } | ||
982 | return ret; | ||
983 | } | ||
984 | |||
985 | static const struct file_operations proc_pid_sched_operations = { | ||
986 | .open = sched_open, | ||
987 | .read = seq_read, | ||
988 | .write = sched_write, | ||
989 | .llseek = seq_lseek, | ||
990 | .release = seq_release, | ||
991 | }; | ||
992 | |||
993 | #endif | ||
994 | |||
932 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 995 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
933 | { | 996 | { |
934 | struct inode *inode = dentry->d_inode; | 997 | struct inode *inode = dentry->d_inode; |
@@ -1963,6 +2026,9 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
1963 | INF("environ", S_IRUSR, pid_environ), | 2026 | INF("environ", S_IRUSR, pid_environ), |
1964 | INF("auxv", S_IRUSR, pid_auxv), | 2027 | INF("auxv", S_IRUSR, pid_auxv), |
1965 | INF("status", S_IRUGO, pid_status), | 2028 | INF("status", S_IRUGO, pid_status), |
2029 | #ifdef CONFIG_SCHED_DEBUG | ||
2030 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | ||
2031 | #endif | ||
1966 | INF("cmdline", S_IRUGO, pid_cmdline), | 2032 | INF("cmdline", S_IRUGO, pid_cmdline), |
1967 | INF("stat", S_IRUGO, tgid_stat), | 2033 | INF("stat", S_IRUGO, tgid_stat), |
1968 | INF("statm", S_IRUGO, pid_statm), | 2034 | INF("statm", S_IRUGO, pid_statm), |
@@ -2247,6 +2313,9 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2247 | INF("environ", S_IRUSR, pid_environ), | 2313 | INF("environ", S_IRUSR, pid_environ), |
2248 | INF("auxv", S_IRUSR, pid_auxv), | 2314 | INF("auxv", S_IRUSR, pid_auxv), |
2249 | INF("status", S_IRUGO, pid_status), | 2315 | INF("status", S_IRUGO, pid_status), |
2316 | #ifdef CONFIG_SCHED_DEBUG | ||
2317 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | ||
2318 | #endif | ||
2250 | INF("cmdline", S_IRUGO, pid_cmdline), | 2319 | INF("cmdline", S_IRUGO, pid_cmdline), |
2251 | INF("stat", S_IRUGO, tid_stat), | 2320 | INF("stat", S_IRUGO, tid_stat), |
2252 | INF("statm", S_IRUGO, pid_statm), | 2321 | INF("statm", S_IRUGO, pid_statm), |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 9345a46ffb32..5d258c40a2fd 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -195,6 +195,11 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) | |||
195 | unsigned int old_ia_valid = ia->ia_valid; | 195 | unsigned int old_ia_valid = ia->ia_valid; |
196 | int ret = 0; | 196 | int ret = 0; |
197 | 197 | ||
198 | /* POSIX UID/GID verification for setting inode attributes */ | ||
199 | ret = inode_change_ok(inode, ia); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | |||
198 | /* by providing our own setattr() method, we skip this quotaism */ | 203 | /* by providing our own setattr() method, we skip this quotaism */ |
199 | if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || | 204 | if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || |
200 | (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) | 205 | (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) |
diff --git a/fs/signalfd.c b/fs/signalfd.c index f1da89203a9a..3b07f26d984d 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -133,7 +133,8 @@ static unsigned int signalfd_poll(struct file *file, poll_table *wait) | |||
133 | * the peer disconnects. | 133 | * the peer disconnects. |
134 | */ | 134 | */ |
135 | if (signalfd_lock(ctx, &lk)) { | 135 | if (signalfd_lock(ctx, &lk)) { |
136 | if (next_signal(&lk.tsk->pending, &ctx->sigmask) > 0 || | 136 | if ((lk.tsk == current && |
137 | next_signal(&lk.tsk->pending, &ctx->sigmask) > 0) || | ||
137 | next_signal(&lk.tsk->signal->shared_pending, | 138 | next_signal(&lk.tsk->signal->shared_pending, |
138 | &ctx->sigmask) > 0) | 139 | &ctx->sigmask) > 0) |
139 | events |= POLLIN; | 140 | events |= POLLIN; |
diff --git a/fs/splice.c b/fs/splice.c index 12f28281d2b1..e7d7080de2f9 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -176,6 +176,7 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = { | |||
176 | static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | 176 | static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, |
177 | struct splice_pipe_desc *spd) | 177 | struct splice_pipe_desc *spd) |
178 | { | 178 | { |
179 | unsigned int spd_pages = spd->nr_pages; | ||
179 | int ret, do_wakeup, page_nr; | 180 | int ret, do_wakeup, page_nr; |
180 | 181 | ||
181 | ret = 0; | 182 | ret = 0; |
@@ -244,17 +245,18 @@ static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, | |||
244 | pipe->waiting_writers--; | 245 | pipe->waiting_writers--; |
245 | } | 246 | } |
246 | 247 | ||
247 | if (pipe->inode) | 248 | if (pipe->inode) { |
248 | mutex_unlock(&pipe->inode->i_mutex); | 249 | mutex_unlock(&pipe->inode->i_mutex); |
249 | 250 | ||
250 | if (do_wakeup) { | 251 | if (do_wakeup) { |
251 | smp_mb(); | 252 | smp_mb(); |
252 | if (waitqueue_active(&pipe->wait)) | 253 | if (waitqueue_active(&pipe->wait)) |
253 | wake_up_interruptible(&pipe->wait); | 254 | wake_up_interruptible(&pipe->wait); |
254 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 255 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
256 | } | ||
255 | } | 257 | } |
256 | 258 | ||
257 | while (page_nr < spd->nr_pages) | 259 | while (page_nr < spd_pages) |
258 | page_cache_release(spd->pages[page_nr++]); | 260 | page_cache_release(spd->pages[page_nr++]); |
259 | 261 | ||
260 | return ret; | 262 | return ret; |
@@ -272,7 +274,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
272 | struct page *page; | 274 | struct page *page; |
273 | pgoff_t index, end_index; | 275 | pgoff_t index, end_index; |
274 | loff_t isize; | 276 | loff_t isize; |
275 | size_t total_len; | ||
276 | int error, page_nr; | 277 | int error, page_nr; |
277 | struct splice_pipe_desc spd = { | 278 | struct splice_pipe_desc spd = { |
278 | .pages = pages, | 279 | .pages = pages, |
@@ -298,7 +299,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
298 | * Now fill in the holes: | 299 | * Now fill in the holes: |
299 | */ | 300 | */ |
300 | error = 0; | 301 | error = 0; |
301 | total_len = 0; | ||
302 | 302 | ||
303 | /* | 303 | /* |
304 | * Lookup the (hopefully) full range of pages we need. | 304 | * Lookup the (hopefully) full range of pages we need. |
@@ -415,43 +415,47 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
415 | 415 | ||
416 | break; | 416 | break; |
417 | } | 417 | } |
418 | } | ||
419 | fill_it: | ||
420 | /* | ||
421 | * i_size must be checked after PageUptodate. | ||
422 | */ | ||
423 | isize = i_size_read(mapping->host); | ||
424 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; | ||
425 | if (unlikely(!isize || index > end_index)) | ||
426 | break; | ||
427 | |||
428 | /* | ||
429 | * if this is the last page, see if we need to shrink | ||
430 | * the length and stop | ||
431 | */ | ||
432 | if (end_index == index) { | ||
433 | unsigned int plen; | ||
418 | 434 | ||
419 | /* | 435 | /* |
420 | * i_size must be checked after ->readpage(). | 436 | * max good bytes in this page |
421 | */ | 437 | */ |
422 | isize = i_size_read(mapping->host); | 438 | plen = ((isize - 1) & ~PAGE_CACHE_MASK) + 1; |
423 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; | 439 | if (plen <= loff) |
424 | if (unlikely(!isize || index > end_index)) | ||
425 | break; | 440 | break; |
426 | 441 | ||
427 | /* | 442 | /* |
428 | * if this is the last page, see if we need to shrink | 443 | * force quit after adding this page |
429 | * the length and stop | ||
430 | */ | 444 | */ |
431 | if (end_index == index) { | 445 | this_len = min(this_len, plen - loff); |
432 | loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK); | 446 | len = this_len; |
433 | if (total_len + loff > isize) | ||
434 | break; | ||
435 | /* | ||
436 | * force quit after adding this page | ||
437 | */ | ||
438 | len = this_len; | ||
439 | this_len = min(this_len, loff); | ||
440 | loff = 0; | ||
441 | } | ||
442 | } | 447 | } |
443 | fill_it: | 448 | |
444 | partial[page_nr].offset = loff; | 449 | partial[page_nr].offset = loff; |
445 | partial[page_nr].len = this_len; | 450 | partial[page_nr].len = this_len; |
446 | len -= this_len; | 451 | len -= this_len; |
447 | total_len += this_len; | ||
448 | loff = 0; | 452 | loff = 0; |
449 | spd.nr_pages++; | 453 | spd.nr_pages++; |
450 | index++; | 454 | index++; |
451 | } | 455 | } |
452 | 456 | ||
453 | /* | 457 | /* |
454 | * Release any pages at the end, if we quit early. 'i' is how far | 458 | * Release any pages at the end, if we quit early. 'page_nr' is how far |
455 | * we got, 'nr_pages' is how many pages are in the map. | 459 | * we got, 'nr_pages' is how many pages are in the map. |
456 | */ | 460 | */ |
457 | while (page_nr < nr_pages) | 461 | while (page_nr < nr_pages) |
@@ -478,10 +482,18 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
478 | { | 482 | { |
479 | ssize_t spliced; | 483 | ssize_t spliced; |
480 | int ret; | 484 | int ret; |
485 | loff_t isize, left; | ||
486 | |||
487 | isize = i_size_read(in->f_mapping->host); | ||
488 | if (unlikely(*ppos >= isize)) | ||
489 | return 0; | ||
490 | |||
491 | left = isize - *ppos; | ||
492 | if (unlikely(left < len)) | ||
493 | len = left; | ||
481 | 494 | ||
482 | ret = 0; | 495 | ret = 0; |
483 | spliced = 0; | 496 | spliced = 0; |
484 | |||
485 | while (len) { | 497 | while (len) { |
486 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); | 498 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); |
487 | 499 | ||
@@ -644,7 +656,6 @@ find_page: | |||
644 | * accessed, we are now done! | 656 | * accessed, we are now done! |
645 | */ | 657 | */ |
646 | mark_page_accessed(page); | 658 | mark_page_accessed(page); |
647 | balance_dirty_pages_ratelimited(mapping); | ||
648 | out: | 659 | out: |
649 | page_cache_release(page); | 660 | page_cache_release(page); |
650 | unlock_page(page); | 661 | unlock_page(page); |
@@ -802,7 +813,10 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, | |||
802 | 813 | ||
803 | ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); | 814 | ret = __splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); |
804 | if (ret > 0) { | 815 | if (ret > 0) { |
816 | unsigned long nr_pages; | ||
817 | |||
805 | *ppos += ret; | 818 | *ppos += ret; |
819 | nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
806 | 820 | ||
807 | /* | 821 | /* |
808 | * If file or inode is SYNC and we actually wrote some data, | 822 | * If file or inode is SYNC and we actually wrote some data, |
@@ -815,6 +829,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out, | |||
815 | if (err) | 829 | if (err) |
816 | ret = err; | 830 | ret = err; |
817 | } | 831 | } |
832 | balance_dirty_pages_ratelimited_nr(mapping, nr_pages); | ||
818 | } | 833 | } |
819 | 834 | ||
820 | return ret; | 835 | return ret; |
@@ -853,7 +868,10 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
853 | 868 | ||
854 | ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); | 869 | ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); |
855 | if (ret > 0) { | 870 | if (ret > 0) { |
871 | unsigned long nr_pages; | ||
872 | |||
856 | *ppos += ret; | 873 | *ppos += ret; |
874 | nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
857 | 875 | ||
858 | /* | 876 | /* |
859 | * If file or inode is SYNC and we actually wrote some data, | 877 | * If file or inode is SYNC and we actually wrote some data, |
@@ -868,6 +886,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
868 | if (err) | 886 | if (err) |
869 | ret = err; | 887 | ret = err; |
870 | } | 888 | } |
889 | balance_dirty_pages_ratelimited_nr(mapping, nr_pages); | ||
871 | } | 890 | } |
872 | 891 | ||
873 | return ret; | 892 | return ret; |
@@ -922,7 +941,6 @@ static long do_splice_to(struct file *in, loff_t *ppos, | |||
922 | struct pipe_inode_info *pipe, size_t len, | 941 | struct pipe_inode_info *pipe, size_t len, |
923 | unsigned int flags) | 942 | unsigned int flags) |
924 | { | 943 | { |
925 | loff_t isize, left; | ||
926 | int ret; | 944 | int ret; |
927 | 945 | ||
928 | if (unlikely(!in->f_op || !in->f_op->splice_read)) | 946 | if (unlikely(!in->f_op || !in->f_op->splice_read)) |
@@ -935,14 +953,6 @@ static long do_splice_to(struct file *in, loff_t *ppos, | |||
935 | if (unlikely(ret < 0)) | 953 | if (unlikely(ret < 0)) |
936 | return ret; | 954 | return ret; |
937 | 955 | ||
938 | isize = i_size_read(in->f_mapping->host); | ||
939 | if (unlikely(*ppos >= isize)) | ||
940 | return 0; | ||
941 | |||
942 | left = isize - *ppos; | ||
943 | if (unlikely(left < len)) | ||
944 | len = left; | ||
945 | |||
946 | return in->f_op->splice_read(in, ppos, pipe, len, flags); | 956 | return in->f_op->splice_read(in, ppos, pipe, len, flags); |
947 | } | 957 | } |
948 | 958 | ||
@@ -1058,8 +1068,6 @@ out_release: | |||
1058 | return ret; | 1068 | return ret; |
1059 | } | 1069 | } |
1060 | 1070 | ||
1061 | EXPORT_SYMBOL(do_splice_direct); | ||
1062 | |||
1063 | /* | 1071 | /* |
1064 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | 1072 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same |
1065 | * location, so checking ->i_pipe is not enough to verify that this is a | 1073 | * location, so checking ->i_pipe is not enough to verify that this is a |
@@ -236,6 +236,14 @@ out: | |||
236 | return ret; | 236 | return ret; |
237 | } | 237 | } |
238 | 238 | ||
239 | /* It would be nice if people remember that not all the world's an i386 | ||
240 | when they introduce new system calls */ | ||
241 | asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, | ||
242 | loff_t offset, loff_t nbytes) | ||
243 | { | ||
244 | return sys_sync_file_range(fd, offset, nbytes, flags); | ||
245 | } | ||
246 | |||
239 | /* | 247 | /* |
240 | * `endbyte' is inclusive | 248 | * `endbyte' is inclusive |
241 | */ | 249 | */ |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 85a668680f82..c4342a019972 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -13,14 +13,26 @@ | |||
13 | #include "sysfs.h" | 13 | #include "sysfs.h" |
14 | 14 | ||
15 | DECLARE_RWSEM(sysfs_rename_sem); | 15 | DECLARE_RWSEM(sysfs_rename_sem); |
16 | spinlock_t sysfs_lock = SPIN_LOCK_UNLOCKED; | ||
16 | 17 | ||
17 | static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) | 18 | static void sysfs_d_iput(struct dentry * dentry, struct inode * inode) |
18 | { | 19 | { |
19 | struct sysfs_dirent * sd = dentry->d_fsdata; | 20 | struct sysfs_dirent * sd = dentry->d_fsdata; |
20 | 21 | ||
21 | if (sd) { | 22 | if (sd) { |
22 | BUG_ON(sd->s_dentry != dentry); | 23 | /* sd->s_dentry is protected with sysfs_lock. This |
23 | sd->s_dentry = NULL; | 24 | * allows sysfs_drop_dentry() to dereference it. |
25 | */ | ||
26 | spin_lock(&sysfs_lock); | ||
27 | |||
28 | /* The dentry might have been deleted or another | ||
29 | * lookup could have happened updating sd->s_dentry to | ||
30 | * point the new dentry. Ignore if it isn't pointing | ||
31 | * to this dentry. | ||
32 | */ | ||
33 | if (sd->s_dentry == dentry) | ||
34 | sd->s_dentry = NULL; | ||
35 | spin_unlock(&sysfs_lock); | ||
24 | sysfs_put(sd); | 36 | sysfs_put(sd); |
25 | } | 37 | } |
26 | iput(inode); | 38 | iput(inode); |
@@ -30,6 +42,14 @@ static struct dentry_operations sysfs_dentry_ops = { | |||
30 | .d_iput = sysfs_d_iput, | 42 | .d_iput = sysfs_d_iput, |
31 | }; | 43 | }; |
32 | 44 | ||
45 | static unsigned int sysfs_inode_counter; | ||
46 | ino_t sysfs_get_inum(void) | ||
47 | { | ||
48 | if (unlikely(sysfs_inode_counter < 3)) | ||
49 | sysfs_inode_counter = 3; | ||
50 | return sysfs_inode_counter++; | ||
51 | } | ||
52 | |||
33 | /* | 53 | /* |
34 | * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent | 54 | * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent |
35 | */ | 55 | */ |
@@ -41,6 +61,7 @@ static struct sysfs_dirent * __sysfs_new_dirent(void * element) | |||
41 | if (!sd) | 61 | if (!sd) |
42 | return NULL; | 62 | return NULL; |
43 | 63 | ||
64 | sd->s_ino = sysfs_get_inum(); | ||
44 | atomic_set(&sd->s_count, 1); | 65 | atomic_set(&sd->s_count, 1); |
45 | atomic_set(&sd->s_event, 1); | 66 | atomic_set(&sd->s_event, 1); |
46 | INIT_LIST_HEAD(&sd->s_children); | 67 | INIT_LIST_HEAD(&sd->s_children); |
@@ -238,7 +259,10 @@ static int sysfs_attach_attr(struct sysfs_dirent * sd, struct dentry * dentry) | |||
238 | } | 259 | } |
239 | 260 | ||
240 | dentry->d_fsdata = sysfs_get(sd); | 261 | dentry->d_fsdata = sysfs_get(sd); |
262 | /* protect sd->s_dentry against sysfs_d_iput */ | ||
263 | spin_lock(&sysfs_lock); | ||
241 | sd->s_dentry = dentry; | 264 | sd->s_dentry = dentry; |
265 | spin_unlock(&sysfs_lock); | ||
242 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); | 266 | error = sysfs_create(dentry, (attr->mode & S_IALLUGO) | S_IFREG, init); |
243 | if (error) { | 267 | if (error) { |
244 | sysfs_put(sd); | 268 | sysfs_put(sd); |
@@ -260,7 +284,10 @@ static int sysfs_attach_link(struct sysfs_dirent * sd, struct dentry * dentry) | |||
260 | int err = 0; | 284 | int err = 0; |
261 | 285 | ||
262 | dentry->d_fsdata = sysfs_get(sd); | 286 | dentry->d_fsdata = sysfs_get(sd); |
287 | /* protect sd->s_dentry against sysfs_d_iput */ | ||
288 | spin_lock(&sysfs_lock); | ||
263 | sd->s_dentry = dentry; | 289 | sd->s_dentry = dentry; |
290 | spin_unlock(&sysfs_lock); | ||
264 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); | 291 | err = sysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink); |
265 | if (!err) { | 292 | if (!err) { |
266 | dentry->d_op = &sysfs_dentry_ops; | 293 | dentry->d_op = &sysfs_dentry_ops; |
@@ -509,7 +536,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
509 | 536 | ||
510 | switch (i) { | 537 | switch (i) { |
511 | case 0: | 538 | case 0: |
512 | ino = dentry->d_inode->i_ino; | 539 | ino = parent_sd->s_ino; |
513 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) | 540 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) |
514 | break; | 541 | break; |
515 | filp->f_pos++; | 542 | filp->f_pos++; |
@@ -538,10 +565,7 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
538 | 565 | ||
539 | name = sysfs_get_name(next); | 566 | name = sysfs_get_name(next); |
540 | len = strlen(name); | 567 | len = strlen(name); |
541 | if (next->s_dentry) | 568 | ino = next->s_ino; |
542 | ino = next->s_dentry->d_inode->i_ino; | ||
543 | else | ||
544 | ino = iunique(sysfs_sb, 2); | ||
545 | 569 | ||
546 | if (filldir(dirent, name, len, filp->f_pos, ino, | 570 | if (filldir(dirent, name, len, filp->f_pos, ino, |
547 | dt_type(next)) < 0) | 571 | dt_type(next)) < 0) |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index bdd30e74de6b..5266eec15f6e 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -141,6 +141,7 @@ struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd) | |||
141 | inode->i_mapping->a_ops = &sysfs_aops; | 141 | inode->i_mapping->a_ops = &sysfs_aops; |
142 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; | 142 | inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; |
143 | inode->i_op = &sysfs_inode_operations; | 143 | inode->i_op = &sysfs_inode_operations; |
144 | inode->i_ino = sd->s_ino; | ||
144 | lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); | 145 | lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); |
145 | 146 | ||
146 | if (sd->s_iattr) { | 147 | if (sd->s_iattr) { |
@@ -245,13 +246,27 @@ static inline void orphan_all_buffers(struct inode *node) | |||
245 | */ | 246 | */ |
246 | void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) | 247 | void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) |
247 | { | 248 | { |
248 | struct dentry * dentry = sd->s_dentry; | 249 | struct dentry *dentry = NULL; |
249 | struct inode *inode; | 250 | struct inode *inode; |
250 | 251 | ||
252 | /* We're not holding a reference to ->s_dentry dentry but the | ||
253 | * field will stay valid as long as sysfs_lock is held. | ||
254 | */ | ||
255 | spin_lock(&sysfs_lock); | ||
256 | spin_lock(&dcache_lock); | ||
257 | |||
258 | /* dget dentry if it's still alive */ | ||
259 | if (sd->s_dentry && sd->s_dentry->d_inode) | ||
260 | dentry = dget_locked(sd->s_dentry); | ||
261 | |||
262 | spin_unlock(&dcache_lock); | ||
263 | spin_unlock(&sysfs_lock); | ||
264 | |||
265 | /* drop dentry */ | ||
251 | if (dentry) { | 266 | if (dentry) { |
252 | spin_lock(&dcache_lock); | 267 | spin_lock(&dcache_lock); |
253 | spin_lock(&dentry->d_lock); | 268 | spin_lock(&dentry->d_lock); |
254 | if (!(d_unhashed(dentry) && dentry->d_inode)) { | 269 | if (!d_unhashed(dentry) && dentry->d_inode) { |
255 | inode = dentry->d_inode; | 270 | inode = dentry->d_inode; |
256 | spin_lock(&inode->i_lock); | 271 | spin_lock(&inode->i_lock); |
257 | __iget(inode); | 272 | __iget(inode); |
@@ -267,6 +282,8 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent) | |||
267 | spin_unlock(&dentry->d_lock); | 282 | spin_unlock(&dentry->d_lock); |
268 | spin_unlock(&dcache_lock); | 283 | spin_unlock(&dcache_lock); |
269 | } | 284 | } |
285 | |||
286 | dput(dentry); | ||
270 | } | 287 | } |
271 | } | 288 | } |
272 | 289 | ||
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 23a48a38e6af..00ab9125d398 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -33,6 +33,7 @@ static struct sysfs_dirent sysfs_root = { | |||
33 | .s_element = NULL, | 33 | .s_element = NULL, |
34 | .s_type = SYSFS_ROOT, | 34 | .s_type = SYSFS_ROOT, |
35 | .s_iattr = NULL, | 35 | .s_iattr = NULL, |
36 | .s_ino = 1, | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | static void sysfs_clear_inode(struct inode *inode) | 39 | static void sysfs_clear_inode(struct inode *inode) |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index a77c57e5a6d5..502c949c402d 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -5,6 +5,7 @@ struct sysfs_dirent { | |||
5 | void * s_element; | 5 | void * s_element; |
6 | int s_type; | 6 | int s_type; |
7 | umode_t s_mode; | 7 | umode_t s_mode; |
8 | ino_t s_ino; | ||
8 | struct dentry * s_dentry; | 9 | struct dentry * s_dentry; |
9 | struct iattr * s_iattr; | 10 | struct iattr * s_iattr; |
10 | atomic_t s_event; | 11 | atomic_t s_event; |
@@ -32,6 +33,7 @@ extern const unsigned char * sysfs_get_name(struct sysfs_dirent *sd); | |||
32 | extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); | 33 | extern void sysfs_drop_dentry(struct sysfs_dirent *sd, struct dentry *parent); |
33 | extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | 34 | extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); |
34 | 35 | ||
36 | extern spinlock_t sysfs_lock; | ||
35 | extern struct rw_semaphore sysfs_rename_sem; | 37 | extern struct rw_semaphore sysfs_rename_sem; |
36 | extern struct super_block * sysfs_sb; | 38 | extern struct super_block * sysfs_sb; |
37 | extern const struct file_operations sysfs_dir_operations; | 39 | extern const struct file_operations sysfs_dir_operations; |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 1f0129405cf4..bf7de0bdbab3 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -100,14 +100,23 @@ no_delete: | |||
100 | clear_inode(inode); | 100 | clear_inode(inode); |
101 | } | 101 | } |
102 | 102 | ||
103 | /* | ||
104 | * If we are going to release inode from memory, we discard preallocation and | ||
105 | * truncate last inode extent to proper length. We could use drop_inode() but | ||
106 | * it's called under inode_lock and thus we cannot mark inode dirty there. We | ||
107 | * use clear_inode() but we have to make sure to write inode as it's not written | ||
108 | * automatically. | ||
109 | */ | ||
103 | void udf_clear_inode(struct inode *inode) | 110 | void udf_clear_inode(struct inode *inode) |
104 | { | 111 | { |
105 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { | 112 | if (!(inode->i_sb->s_flags & MS_RDONLY)) { |
106 | lock_kernel(); | 113 | lock_kernel(); |
114 | /* Discard preallocation for directories, symlinks, etc. */ | ||
107 | udf_discard_prealloc(inode); | 115 | udf_discard_prealloc(inode); |
116 | udf_truncate_tail_extent(inode); | ||
108 | unlock_kernel(); | 117 | unlock_kernel(); |
118 | write_inode_now(inode, 1); | ||
109 | } | 119 | } |
110 | |||
111 | kfree(UDF_I_DATA(inode)); | 120 | kfree(UDF_I_DATA(inode)); |
112 | UDF_I_DATA(inode) = NULL; | 121 | UDF_I_DATA(inode) = NULL; |
113 | } | 122 | } |
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c index 77975ae291a5..60d277644248 100644 --- a/fs/udf/truncate.c +++ b/fs/udf/truncate.c | |||
@@ -61,7 +61,11 @@ static void extent_trunc(struct inode * inode, struct extent_position *epos, | |||
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | void udf_discard_prealloc(struct inode * inode) | 64 | /* |
65 | * Truncate the last extent to match i_size. This function assumes | ||
66 | * that preallocation extent is already truncated. | ||
67 | */ | ||
68 | void udf_truncate_tail_extent(struct inode *inode) | ||
65 | { | 69 | { |
66 | struct extent_position epos = { NULL, 0, {0, 0}}; | 70 | struct extent_position epos = { NULL, 0, {0, 0}}; |
67 | kernel_lb_addr eloc; | 71 | kernel_lb_addr eloc; |
@@ -71,7 +75,10 @@ void udf_discard_prealloc(struct inode * inode) | |||
71 | int adsize; | 75 | int adsize; |
72 | 76 | ||
73 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | 77 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || |
74 | inode->i_size == UDF_I_LENEXTENTS(inode)) | 78 | inode->i_size == UDF_I_LENEXTENTS(inode)) |
79 | return; | ||
80 | /* Are we going to delete the file anyway? */ | ||
81 | if (inode->i_nlink == 0) | ||
75 | return; | 82 | return; |
76 | 83 | ||
77 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | 84 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) |
@@ -79,36 +86,76 @@ void udf_discard_prealloc(struct inode * inode) | |||
79 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | 86 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) |
80 | adsize = sizeof(long_ad); | 87 | adsize = sizeof(long_ad); |
81 | else | 88 | else |
82 | adsize = 0; | 89 | BUG(); |
83 | |||
84 | epos.block = UDF_I_LOCATION(inode); | ||
85 | 90 | ||
86 | /* Find the last extent in the file */ | 91 | /* Find the last extent in the file */ |
87 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) | 92 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) |
88 | { | 93 | { |
89 | etype = netype; | 94 | etype = netype; |
90 | lbcount += elen; | 95 | lbcount += elen; |
91 | if (lbcount > inode->i_size && lbcount - elen < inode->i_size) | 96 | if (lbcount > inode->i_size) { |
92 | { | 97 | if (lbcount - inode->i_size >= inode->i_sb->s_blocksize) |
93 | WARN_ON(lbcount - inode->i_size >= inode->i_sb->s_blocksize); | 98 | printk(KERN_WARNING |
99 | "udf_truncate_tail_extent(): Too long " | ||
100 | "extent after EOF in inode %u: i_size: " | ||
101 | "%Ld lbcount: %Ld extent %u+%u\n", | ||
102 | (unsigned)inode->i_ino, | ||
103 | (long long)inode->i_size, | ||
104 | (long long)lbcount, | ||
105 | (unsigned)eloc.logicalBlockNum, | ||
106 | (unsigned)elen); | ||
94 | nelen = elen - (lbcount - inode->i_size); | 107 | nelen = elen - (lbcount - inode->i_size); |
95 | epos.offset -= adsize; | 108 | epos.offset -= adsize; |
96 | extent_trunc(inode, &epos, eloc, etype, elen, nelen); | 109 | extent_trunc(inode, &epos, eloc, etype, elen, nelen); |
97 | epos.offset += adsize; | 110 | epos.offset += adsize; |
98 | lbcount = inode->i_size; | 111 | if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1) |
112 | printk(KERN_ERR "udf_truncate_tail_extent(): " | ||
113 | "Extent after EOF in inode %u.\n", | ||
114 | (unsigned)inode->i_ino); | ||
115 | break; | ||
99 | } | 116 | } |
100 | } | 117 | } |
118 | /* This inode entry is in-memory only and thus we don't have to mark | ||
119 | * the inode dirty */ | ||
120 | UDF_I_LENEXTENTS(inode) = inode->i_size; | ||
121 | brelse(epos.bh); | ||
122 | } | ||
123 | |||
124 | void udf_discard_prealloc(struct inode *inode) | ||
125 | { | ||
126 | struct extent_position epos = { NULL, 0, {0, 0}}; | ||
127 | kernel_lb_addr eloc; | ||
128 | uint32_t elen; | ||
129 | uint64_t lbcount = 0; | ||
130 | int8_t etype = -1, netype; | ||
131 | int adsize; | ||
132 | |||
133 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB || | ||
134 | inode->i_size == UDF_I_LENEXTENTS(inode)) | ||
135 | return; | ||
136 | |||
137 | if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT) | ||
138 | adsize = sizeof(short_ad); | ||
139 | else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG) | ||
140 | adsize = sizeof(long_ad); | ||
141 | else | ||
142 | adsize = 0; | ||
143 | |||
144 | epos.block = UDF_I_LOCATION(inode); | ||
145 | |||
146 | /* Find the last extent in the file */ | ||
147 | while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1) { | ||
148 | etype = netype; | ||
149 | lbcount += elen; | ||
150 | } | ||
101 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { | 151 | if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) { |
102 | epos.offset -= adsize; | 152 | epos.offset -= adsize; |
103 | lbcount -= elen; | 153 | lbcount -= elen; |
104 | extent_trunc(inode, &epos, eloc, etype, elen, 0); | 154 | extent_trunc(inode, &epos, eloc, etype, elen, 0); |
105 | if (!epos.bh) | 155 | if (!epos.bh) { |
106 | { | ||
107 | UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); | 156 | UDF_I_LENALLOC(inode) = epos.offset - udf_file_entry_alloc_offset(inode); |
108 | mark_inode_dirty(inode); | 157 | mark_inode_dirty(inode); |
109 | } | 158 | } else { |
110 | else | ||
111 | { | ||
112 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); | 159 | struct allocExtDesc *aed = (struct allocExtDesc *)(epos.bh->b_data); |
113 | aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc)); | 160 | aed->lengthAllocDescs = cpu_to_le32(epos.offset - sizeof(struct allocExtDesc)); |
114 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) | 161 | if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) || UDF_SB_UDFREV(inode->i_sb) >= 0x0201) |
@@ -118,9 +165,9 @@ void udf_discard_prealloc(struct inode * inode) | |||
118 | mark_buffer_dirty_inode(epos.bh, inode); | 165 | mark_buffer_dirty_inode(epos.bh, inode); |
119 | } | 166 | } |
120 | } | 167 | } |
168 | /* This inode entry is in-memory only and thus we don't have to mark | ||
169 | * the inode dirty */ | ||
121 | UDF_I_LENEXTENTS(inode) = lbcount; | 170 | UDF_I_LENEXTENTS(inode) = lbcount; |
122 | |||
123 | WARN_ON(lbcount != inode->i_size); | ||
124 | brelse(epos.bh); | 171 | brelse(epos.bh); |
125 | } | 172 | } |
126 | 173 | ||
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 67ded289497c..f581f2f69c0f 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -146,6 +146,7 @@ extern void udf_free_inode(struct inode *); | |||
146 | extern struct inode * udf_new_inode (struct inode *, int, int *); | 146 | extern struct inode * udf_new_inode (struct inode *, int, int *); |
147 | 147 | ||
148 | /* truncate.c */ | 148 | /* truncate.c */ |
149 | extern void udf_truncate_tail_extent(struct inode *); | ||
149 | extern void udf_discard_prealloc(struct inode *); | 150 | extern void udf_discard_prealloc(struct inode *); |
150 | extern void udf_truncate_extents(struct inode *); | 151 | extern void udf_truncate_extents(struct inode *); |
151 | 152 | ||
diff --git a/fs/utimes.c b/fs/utimes.c index 480f7c8c29da..b3c88952465f 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -106,9 +106,16 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags | |||
106 | if (IS_IMMUTABLE(inode)) | 106 | if (IS_IMMUTABLE(inode)) |
107 | goto dput_and_out; | 107 | goto dput_and_out; |
108 | 108 | ||
109 | if (current->fsuid != inode->i_uid && | 109 | if (current->fsuid != inode->i_uid) { |
110 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 110 | if (f) { |
111 | goto dput_and_out; | 111 | if (!(f->f_mode & FMODE_WRITE)) |
112 | goto dput_and_out; | ||
113 | } else { | ||
114 | error = vfs_permission(&nd, MAY_WRITE); | ||
115 | if (error) | ||
116 | goto dput_and_out; | ||
117 | } | ||
118 | } | ||
112 | } | 119 | } |
113 | mutex_lock(&inode->i_mutex); | 120 | mutex_lock(&inode->i_mutex); |
114 | error = notify_change(dentry, &newattrs); | 121 | error = notify_change(dentry, &newattrs); |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 86fb671a8bcc..ed90403f0ee7 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -159,7 +159,7 @@ xfs_iozero( | |||
159 | if (status) | 159 | if (status) |
160 | goto unlock; | 160 | goto unlock; |
161 | 161 | ||
162 | memclear_highpage_flush(page, offset, bytes); | 162 | zero_user_page(page, offset, bytes, KM_USER0); |
163 | 163 | ||
164 | status = mapping->a_ops->commit_write(NULL, page, offset, | 164 | status = mapping->a_ops->commit_write(NULL, page, offset, |
165 | offset + bytes); | 165 | offset + bytes); |