diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cifs/Kconfig | 1 | ||||
-rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 9 | ||||
-rw-r--r-- | fs/cifs/cifsencrypt.c | 5 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 3 | ||||
-rw-r--r-- | fs/cifs/file.c | 8 | ||||
-rw-r--r-- | fs/cifs/link.c | 3 | ||||
-rw-r--r-- | fs/cifs/misc.c | 116 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 3 | ||||
-rw-r--r-- | fs/cifs/smbencrypt.c | 3 | ||||
-rw-r--r-- | fs/cifs/transport.c | 62 | ||||
-rw-r--r-- | fs/eventpoll.c | 16 | ||||
-rw-r--r-- | fs/exec.c | 4 | ||||
-rw-r--r-- | fs/exofs/inode.c | 2 | ||||
-rw-r--r-- | fs/fcntl.c | 2 | ||||
-rw-r--r-- | fs/file_table.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/extents.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/part_tbl.c | 4 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 106 | ||||
-rw-r--r-- | fs/hfsplus/wrapper.c | 4 | ||||
-rw-r--r-- | fs/ioctl.c | 7 |
21 files changed, 221 insertions, 145 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig index ee45648b0d1a..7cb0f7f847e4 100644 --- a/fs/cifs/Kconfig +++ b/fs/cifs/Kconfig | |||
@@ -3,6 +3,7 @@ config CIFS | |||
3 | depends on INET | 3 | depends on INET |
4 | select NLS | 4 | select NLS |
5 | select CRYPTO | 5 | select CRYPTO |
6 | select CRYPTO_MD4 | ||
6 | select CRYPTO_MD5 | 7 | select CRYPTO_MD5 |
7 | select CRYPTO_HMAC | 8 | select CRYPTO_HMAC |
8 | select CRYPTO_ARC4 | 9 | select CRYPTO_ARC4 |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index f1c68629f277..0a265ad9e426 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
@@ -282,8 +282,6 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
282 | cFYI(1, "in %s", __func__); | 282 | cFYI(1, "in %s", __func__); |
283 | BUG_ON(IS_ROOT(mntpt)); | 283 | BUG_ON(IS_ROOT(mntpt)); |
284 | 284 | ||
285 | xid = GetXid(); | ||
286 | |||
287 | /* | 285 | /* |
288 | * The MSDFS spec states that paths in DFS referral requests and | 286 | * The MSDFS spec states that paths in DFS referral requests and |
289 | * responses must be prefixed by a single '\' character instead of | 287 | * responses must be prefixed by a single '\' character instead of |
@@ -293,7 +291,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
293 | mnt = ERR_PTR(-ENOMEM); | 291 | mnt = ERR_PTR(-ENOMEM); |
294 | full_path = build_path_from_dentry(mntpt); | 292 | full_path = build_path_from_dentry(mntpt); |
295 | if (full_path == NULL) | 293 | if (full_path == NULL) |
296 | goto free_xid; | 294 | goto cdda_exit; |
297 | 295 | ||
298 | cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); | 296 | cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); |
299 | tlink = cifs_sb_tlink(cifs_sb); | 297 | tlink = cifs_sb_tlink(cifs_sb); |
@@ -303,9 +301,11 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) | |||
303 | } | 301 | } |
304 | ses = tlink_tcon(tlink)->ses; | 302 | ses = tlink_tcon(tlink)->ses; |
305 | 303 | ||
304 | xid = GetXid(); | ||
306 | rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, | 305 | rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, |
307 | &num_referrals, &referrals, | 306 | &num_referrals, &referrals, |
308 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 307 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
308 | FreeXid(xid); | ||
309 | 309 | ||
310 | cifs_put_tlink(tlink); | 310 | cifs_put_tlink(tlink); |
311 | 311 | ||
@@ -338,8 +338,7 @@ success: | |||
338 | free_dfs_info_array(referrals, num_referrals); | 338 | free_dfs_info_array(referrals, num_referrals); |
339 | free_full_path: | 339 | free_full_path: |
340 | kfree(full_path); | 340 | kfree(full_path); |
341 | free_xid: | 341 | cdda_exit: |
342 | FreeXid(xid); | ||
343 | cFYI(1, "leaving %s" , __func__); | 342 | cFYI(1, "leaving %s" , __func__); |
344 | return mnt; | 343 | return mnt; |
345 | } | 344 | } |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 0db5f1de0227..a51585f9852b 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -657,9 +657,10 @@ calc_seckey(struct cifsSesInfo *ses) | |||
657 | get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); | 657 | get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); |
658 | 658 | ||
659 | tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); | 659 | tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); |
660 | if (!tfm_arc4 || IS_ERR(tfm_arc4)) { | 660 | if (IS_ERR(tfm_arc4)) { |
661 | rc = PTR_ERR(tfm_arc4); | ||
661 | cERROR(1, "could not allocate crypto API arc4\n"); | 662 | cERROR(1, "could not allocate crypto API arc4\n"); |
662 | return PTR_ERR(tfm_arc4); | 663 | return rc; |
663 | } | 664 | } |
664 | 665 | ||
665 | desc.tfm = tfm_arc4; | 666 | desc.tfm = tfm_arc4; |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 14789a97304e..4a3330235d55 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -127,5 +127,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
127 | extern const struct export_operations cifs_export_ops; | 127 | extern const struct export_operations cifs_export_ops; |
128 | #endif /* EXPERIMENTAL */ | 128 | #endif /* EXPERIMENTAL */ |
129 | 129 | ||
130 | #define CIFS_VERSION "1.69" | 130 | #define CIFS_VERSION "1.70" |
131 | #endif /* _CIFSFS_H */ | 131 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3106f5e5c633..46c66ed01af4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -4914,7 +4914,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
4914 | __u16 fid, __u32 pid_of_opener, bool SetAllocation) | 4914 | __u16 fid, __u32 pid_of_opener, bool SetAllocation) |
4915 | { | 4915 | { |
4916 | struct smb_com_transaction2_sfi_req *pSMB = NULL; | 4916 | struct smb_com_transaction2_sfi_req *pSMB = NULL; |
4917 | char *data_offset; | ||
4918 | struct file_end_of_file_info *parm_data; | 4917 | struct file_end_of_file_info *parm_data; |
4919 | int rc = 0; | 4918 | int rc = 0; |
4920 | __u16 params, param_offset, offset, byte_count, count; | 4919 | __u16 params, param_offset, offset, byte_count, count; |
@@ -4938,8 +4937,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, | |||
4938 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; | 4937 | param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; |
4939 | offset = param_offset + params; | 4938 | offset = param_offset + params; |
4940 | 4939 | ||
4941 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | ||
4942 | |||
4943 | count = sizeof(struct file_end_of_file_info); | 4940 | count = sizeof(struct file_end_of_file_info); |
4944 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4941 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4945 | /* BB find exact max SMB PDU from sess structure BB */ | 4942 | /* BB find exact max SMB PDU from sess structure BB */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0de17c1db608..74c0a282d012 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -346,7 +346,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
346 | struct cifsTconInfo *tcon; | 346 | struct cifsTconInfo *tcon; |
347 | struct tcon_link *tlink; | 347 | struct tcon_link *tlink; |
348 | struct cifsFileInfo *pCifsFile = NULL; | 348 | struct cifsFileInfo *pCifsFile = NULL; |
349 | struct cifsInodeInfo *pCifsInode; | ||
350 | char *full_path = NULL; | 349 | char *full_path = NULL; |
351 | bool posix_open_ok = false; | 350 | bool posix_open_ok = false; |
352 | __u16 netfid; | 351 | __u16 netfid; |
@@ -361,8 +360,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
361 | } | 360 | } |
362 | tcon = tlink_tcon(tlink); | 361 | tcon = tlink_tcon(tlink); |
363 | 362 | ||
364 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
365 | |||
366 | full_path = build_path_from_dentry(file->f_path.dentry); | 363 | full_path = build_path_from_dentry(file->f_path.dentry); |
367 | if (full_path == NULL) { | 364 | if (full_path == NULL) { |
368 | rc = -ENOMEM; | 365 | rc = -ENOMEM; |
@@ -1146,7 +1143,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1146 | char *write_data; | 1143 | char *write_data; |
1147 | int rc = -EFAULT; | 1144 | int rc = -EFAULT; |
1148 | int bytes_written = 0; | 1145 | int bytes_written = 0; |
1149 | struct cifs_sb_info *cifs_sb; | ||
1150 | struct inode *inode; | 1146 | struct inode *inode; |
1151 | struct cifsFileInfo *open_file; | 1147 | struct cifsFileInfo *open_file; |
1152 | 1148 | ||
@@ -1154,7 +1150,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1154 | return -EFAULT; | 1150 | return -EFAULT; |
1155 | 1151 | ||
1156 | inode = page->mapping->host; | 1152 | inode = page->mapping->host; |
1157 | cifs_sb = CIFS_SB(inode->i_sb); | ||
1158 | 1153 | ||
1159 | offset += (loff_t)from; | 1154 | offset += (loff_t)from; |
1160 | write_data = kmap(page); | 1155 | write_data = kmap(page); |
@@ -1667,7 +1662,8 @@ static ssize_t | |||
1667 | cifs_iovec_write(struct file *file, const struct iovec *iov, | 1662 | cifs_iovec_write(struct file *file, const struct iovec *iov, |
1668 | unsigned long nr_segs, loff_t *poffset) | 1663 | unsigned long nr_segs, loff_t *poffset) |
1669 | { | 1664 | { |
1670 | size_t total_written = 0, written = 0; | 1665 | size_t total_written = 0; |
1666 | unsigned int written = 0; | ||
1671 | unsigned long num_pages, npages; | 1667 | unsigned long num_pages, npages; |
1672 | size_t copied, len, cur_len, i; | 1668 | size_t copied, len, cur_len, i; |
1673 | struct kvec *to_send; | 1669 | struct kvec *to_send; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 02cd60aefbff..e8804d373404 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -55,8 +55,9 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | |||
55 | 55 | ||
56 | md5 = crypto_alloc_shash("md5", 0, 0); | 56 | md5 = crypto_alloc_shash("md5", 0, 0); |
57 | if (IS_ERR(md5)) { | 57 | if (IS_ERR(md5)) { |
58 | rc = PTR_ERR(md5); | ||
58 | cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); | 59 | cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); |
59 | return PTR_ERR(md5); | 60 | return rc; |
60 | } | 61 | } |
61 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); | 62 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); |
62 | sdescmd5 = kmalloc(size, GFP_KERNEL); | 63 | sdescmd5 = kmalloc(size, GFP_KERNEL); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index a09e077ba925..2a930a752a78 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -236,10 +236,7 @@ __u16 GetNextMid(struct TCP_Server_Info *server) | |||
236 | { | 236 | { |
237 | __u16 mid = 0; | 237 | __u16 mid = 0; |
238 | __u16 last_mid; | 238 | __u16 last_mid; |
239 | int collision; | 239 | bool collision; |
240 | |||
241 | if (server == NULL) | ||
242 | return mid; | ||
243 | 240 | ||
244 | spin_lock(&GlobalMid_Lock); | 241 | spin_lock(&GlobalMid_Lock); |
245 | last_mid = server->CurrentMid; /* we do not want to loop forever */ | 242 | last_mid = server->CurrentMid; /* we do not want to loop forever */ |
@@ -252,24 +249,38 @@ __u16 GetNextMid(struct TCP_Server_Info *server) | |||
252 | (and it would also have to have been a request that | 249 | (and it would also have to have been a request that |
253 | did not time out) */ | 250 | did not time out) */ |
254 | while (server->CurrentMid != last_mid) { | 251 | while (server->CurrentMid != last_mid) { |
255 | struct list_head *tmp; | ||
256 | struct mid_q_entry *mid_entry; | 252 | struct mid_q_entry *mid_entry; |
253 | unsigned int num_mids; | ||
257 | 254 | ||
258 | collision = 0; | 255 | collision = false; |
259 | if (server->CurrentMid == 0) | 256 | if (server->CurrentMid == 0) |
260 | server->CurrentMid++; | 257 | server->CurrentMid++; |
261 | 258 | ||
262 | list_for_each(tmp, &server->pending_mid_q) { | 259 | num_mids = 0; |
263 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); | 260 | list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { |
264 | 261 | ++num_mids; | |
265 | if ((mid_entry->mid == server->CurrentMid) && | 262 | if (mid_entry->mid == server->CurrentMid && |
266 | (mid_entry->midState == MID_REQUEST_SUBMITTED)) { | 263 | mid_entry->midState == MID_REQUEST_SUBMITTED) { |
267 | /* This mid is in use, try a different one */ | 264 | /* This mid is in use, try a different one */ |
268 | collision = 1; | 265 | collision = true; |
269 | break; | 266 | break; |
270 | } | 267 | } |
271 | } | 268 | } |
272 | if (collision == 0) { | 269 | |
270 | /* | ||
271 | * if we have more than 32k mids in the list, then something | ||
272 | * is very wrong. Possibly a local user is trying to DoS the | ||
273 | * box by issuing long-running calls and SIGKILL'ing them. If | ||
274 | * we get to 2^16 mids then we're in big trouble as this | ||
275 | * function could loop forever. | ||
276 | * | ||
277 | * Go ahead and assign out the mid in this situation, but force | ||
278 | * an eventual reconnect to clean out the pending_mid_q. | ||
279 | */ | ||
280 | if (num_mids > 32768) | ||
281 | server->tcpStatus = CifsNeedReconnect; | ||
282 | |||
283 | if (!collision) { | ||
273 | mid = server->CurrentMid; | 284 | mid = server->CurrentMid; |
274 | break; | 285 | break; |
275 | } | 286 | } |
@@ -381,29 +392,31 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
381 | } | 392 | } |
382 | 393 | ||
383 | static int | 394 | static int |
384 | checkSMBhdr(struct smb_hdr *smb, __u16 mid) | 395 | check_smb_hdr(struct smb_hdr *smb, __u16 mid) |
385 | { | 396 | { |
386 | /* Make sure that this really is an SMB, that it is a response, | 397 | /* does it have the right SMB "signature" ? */ |
387 | and that the message ids match */ | 398 | if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) { |
388 | if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && | 399 | cERROR(1, "Bad protocol string signature header 0x%x", |
389 | (mid == smb->Mid)) { | 400 | *(unsigned int *)smb->Protocol); |
390 | if (smb->Flags & SMBFLG_RESPONSE) | 401 | return 1; |
391 | return 0; | 402 | } |
392 | else { | 403 | |
393 | /* only one valid case where server sends us request */ | 404 | /* Make sure that message ids match */ |
394 | if (smb->Command == SMB_COM_LOCKING_ANDX) | 405 | if (mid != smb->Mid) { |
395 | return 0; | 406 | cERROR(1, "Mids do not match. received=%u expected=%u", |
396 | else | 407 | smb->Mid, mid); |
397 | cERROR(1, "Received Request not response"); | 408 | return 1; |
398 | } | ||
399 | } else { /* bad signature or mid */ | ||
400 | if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) | ||
401 | cERROR(1, "Bad protocol string signature header %x", | ||
402 | *(unsigned int *) smb->Protocol); | ||
403 | if (mid != smb->Mid) | ||
404 | cERROR(1, "Mids do not match"); | ||
405 | } | 409 | } |
406 | cERROR(1, "bad smb detected. The Mid=%d", smb->Mid); | 410 | |
411 | /* if it's a response then accept */ | ||
412 | if (smb->Flags & SMBFLG_RESPONSE) | ||
413 | return 0; | ||
414 | |||
415 | /* only one valid case where server sends us request */ | ||
416 | if (smb->Command == SMB_COM_LOCKING_ANDX) | ||
417 | return 0; | ||
418 | |||
419 | cERROR(1, "Server sent request, not response. mid=%u", smb->Mid); | ||
407 | return 1; | 420 | return 1; |
408 | } | 421 | } |
409 | 422 | ||
@@ -448,7 +461,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
448 | return 1; | 461 | return 1; |
449 | } | 462 | } |
450 | 463 | ||
451 | if (checkSMBhdr(smb, mid)) | 464 | if (check_smb_hdr(smb, mid)) |
452 | return 1; | 465 | return 1; |
453 | clc_len = smbCalcSize_LE(smb); | 466 | clc_len = smbCalcSize_LE(smb); |
454 | 467 | ||
@@ -465,25 +478,26 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) | |||
465 | if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) | 478 | if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) |
466 | return 0; /* bcc wrapped */ | 479 | return 0; /* bcc wrapped */ |
467 | } | 480 | } |
468 | cFYI(1, "Calculated size %d vs length %d mismatch for mid %d", | 481 | cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u", |
469 | clc_len, 4 + len, smb->Mid); | 482 | clc_len, 4 + len, smb->Mid); |
470 | /* Windows XP can return a few bytes too much, presumably | 483 | |
471 | an illegal pad, at the end of byte range lock responses | 484 | if (4 + len < clc_len) { |
472 | so we allow for that three byte pad, as long as actual | 485 | cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u", |
473 | received length is as long or longer than calculated length */ | ||
474 | /* We have now had to extend this more, since there is a | ||
475 | case in which it needs to be bigger still to handle a | ||
476 | malformed response to transact2 findfirst from WinXP when | ||
477 | access denied is returned and thus bcc and wct are zero | ||
478 | but server says length is 0x21 bytes too long as if the server | ||
479 | forget to reset the smb rfc1001 length when it reset the | ||
480 | wct and bcc to minimum size and drop the t2 parms and data */ | ||
481 | if ((4+len > clc_len) && (len <= clc_len + 512)) | ||
482 | return 0; | ||
483 | else { | ||
484 | cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d", | ||
485 | len, smb->Mid); | 486 | len, smb->Mid); |
486 | return 1; | 487 | return 1; |
488 | } else if (len > clc_len + 512) { | ||
489 | /* | ||
490 | * Some servers (Windows XP in particular) send more | ||
491 | * data than the lengths in the SMB packet would | ||
492 | * indicate on certain calls (byte range locks and | ||
493 | * trans2 find first calls in particular). While the | ||
494 | * client can handle such a frame by ignoring the | ||
495 | * trailing data, we choose limit the amount of extra | ||
496 | * data to 512 bytes. | ||
497 | */ | ||
498 | cERROR(1, "RFC1001 size %u more than 512 bytes larger " | ||
499 | "than SMB for mid=%u", len, smb->Mid); | ||
500 | return 1; | ||
487 | } | 501 | } |
488 | } | 502 | } |
489 | return 0; | 503 | return 0; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 7f25cc3d2256..f8e4cd2a7912 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -764,7 +764,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
764 | { | 764 | { |
765 | int rc = 0; | 765 | int rc = 0; |
766 | int xid, i; | 766 | int xid, i; |
767 | struct cifs_sb_info *cifs_sb; | ||
768 | struct cifsTconInfo *pTcon; | 767 | struct cifsTconInfo *pTcon; |
769 | struct cifsFileInfo *cifsFile = NULL; | 768 | struct cifsFileInfo *cifsFile = NULL; |
770 | char *current_entry; | 769 | char *current_entry; |
@@ -775,8 +774,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
775 | 774 | ||
776 | xid = GetXid(); | 775 | xid = GetXid(); |
777 | 776 | ||
778 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
779 | |||
780 | /* | 777 | /* |
781 | * Ensure FindFirst doesn't fail before doing filldir() for '.' and | 778 | * Ensure FindFirst doesn't fail before doing filldir() for '.' and |
782 | * '..'. Otherwise we won't be able to notify VFS in case of failure. | 779 | * '..'. Otherwise we won't be able to notify VFS in case of failure. |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index b5450e9f40c0..b5041c849981 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -58,8 +58,9 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) | |||
58 | 58 | ||
59 | md4 = crypto_alloc_shash("md4", 0, 0); | 59 | md4 = crypto_alloc_shash("md4", 0, 0); |
60 | if (IS_ERR(md4)) { | 60 | if (IS_ERR(md4)) { |
61 | rc = PTR_ERR(md4); | ||
61 | cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); | 62 | cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); |
62 | return PTR_ERR(md4); | 63 | return rc; |
63 | } | 64 | } |
64 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); | 65 | size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); |
65 | sdescmd4 = kmalloc(size, GFP_KERNEL); | 66 | sdescmd4 = kmalloc(size, GFP_KERNEL); |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index c1ccca1a933f..b8c5e2eb43d0 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -236,9 +236,9 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) | |||
236 | server->tcpStatus = CifsNeedReconnect; | 236 | server->tcpStatus = CifsNeedReconnect; |
237 | } | 237 | } |
238 | 238 | ||
239 | if (rc < 0) { | 239 | if (rc < 0 && rc != -EINTR) |
240 | cERROR(1, "Error %d sending data on socket to server", rc); | 240 | cERROR(1, "Error %d sending data on socket to server", rc); |
241 | } else | 241 | else |
242 | rc = 0; | 242 | rc = 0; |
243 | 243 | ||
244 | /* Don't want to modify the buffer as a | 244 | /* Don't want to modify the buffer as a |
@@ -570,17 +570,33 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
570 | #endif | 570 | #endif |
571 | 571 | ||
572 | mutex_unlock(&ses->server->srv_mutex); | 572 | mutex_unlock(&ses->server->srv_mutex); |
573 | cifs_small_buf_release(in_buf); | ||
574 | 573 | ||
575 | if (rc < 0) | 574 | if (rc < 0) { |
575 | cifs_small_buf_release(in_buf); | ||
576 | goto out; | 576 | goto out; |
577 | } | ||
577 | 578 | ||
578 | if (long_op == CIFS_ASYNC_OP) | 579 | if (long_op == CIFS_ASYNC_OP) { |
580 | cifs_small_buf_release(in_buf); | ||
579 | goto out; | 581 | goto out; |
582 | } | ||
580 | 583 | ||
581 | rc = wait_for_response(ses->server, midQ); | 584 | rc = wait_for_response(ses->server, midQ); |
582 | if (rc != 0) | 585 | if (rc != 0) { |
583 | goto out; | 586 | send_nt_cancel(ses->server, in_buf, midQ); |
587 | spin_lock(&GlobalMid_Lock); | ||
588 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
589 | midQ->callback = DeleteMidQEntry; | ||
590 | spin_unlock(&GlobalMid_Lock); | ||
591 | cifs_small_buf_release(in_buf); | ||
592 | atomic_dec(&ses->server->inFlight); | ||
593 | wake_up(&ses->server->request_q); | ||
594 | return rc; | ||
595 | } | ||
596 | spin_unlock(&GlobalMid_Lock); | ||
597 | } | ||
598 | |||
599 | cifs_small_buf_release(in_buf); | ||
584 | 600 | ||
585 | rc = sync_mid_result(midQ, ses->server); | 601 | rc = sync_mid_result(midQ, ses->server); |
586 | if (rc != 0) { | 602 | if (rc != 0) { |
@@ -724,8 +740,19 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
724 | goto out; | 740 | goto out; |
725 | 741 | ||
726 | rc = wait_for_response(ses->server, midQ); | 742 | rc = wait_for_response(ses->server, midQ); |
727 | if (rc != 0) | 743 | if (rc != 0) { |
728 | goto out; | 744 | send_nt_cancel(ses->server, in_buf, midQ); |
745 | spin_lock(&GlobalMid_Lock); | ||
746 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
747 | /* no longer considered to be "in-flight" */ | ||
748 | midQ->callback = DeleteMidQEntry; | ||
749 | spin_unlock(&GlobalMid_Lock); | ||
750 | atomic_dec(&ses->server->inFlight); | ||
751 | wake_up(&ses->server->request_q); | ||
752 | return rc; | ||
753 | } | ||
754 | spin_unlock(&GlobalMid_Lock); | ||
755 | } | ||
729 | 756 | ||
730 | rc = sync_mid_result(midQ, ses->server); | 757 | rc = sync_mid_result(midQ, ses->server); |
731 | if (rc != 0) { | 758 | if (rc != 0) { |
@@ -922,10 +949,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
922 | } | 949 | } |
923 | } | 950 | } |
924 | 951 | ||
925 | if (wait_for_response(ses->server, midQ) == 0) { | 952 | rc = wait_for_response(ses->server, midQ); |
926 | /* We got the response - restart system call. */ | 953 | if (rc) { |
927 | rstart = 1; | 954 | send_nt_cancel(ses->server, in_buf, midQ); |
955 | spin_lock(&GlobalMid_Lock); | ||
956 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | ||
957 | /* no longer considered to be "in-flight" */ | ||
958 | midQ->callback = DeleteMidQEntry; | ||
959 | spin_unlock(&GlobalMid_Lock); | ||
960 | return rc; | ||
961 | } | ||
962 | spin_unlock(&GlobalMid_Lock); | ||
928 | } | 963 | } |
964 | |||
965 | /* We got the response - restart system call. */ | ||
966 | rstart = 1; | ||
929 | } | 967 | } |
930 | 968 | ||
931 | rc = sync_mid_result(midQ, ses->server); | 969 | rc = sync_mid_result(midQ, ses->server); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index cc8a9b7d6064..267d0ada4541 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1114,6 +1114,17 @@ static int ep_send_events(struct eventpoll *ep, | |||
1114 | return ep_scan_ready_list(ep, ep_send_events_proc, &esed); | 1114 | return ep_scan_ready_list(ep, ep_send_events_proc, &esed); |
1115 | } | 1115 | } |
1116 | 1116 | ||
1117 | static inline struct timespec ep_set_mstimeout(long ms) | ||
1118 | { | ||
1119 | struct timespec now, ts = { | ||
1120 | .tv_sec = ms / MSEC_PER_SEC, | ||
1121 | .tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC), | ||
1122 | }; | ||
1123 | |||
1124 | ktime_get_ts(&now); | ||
1125 | return timespec_add_safe(now, ts); | ||
1126 | } | ||
1127 | |||
1117 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | 1128 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, |
1118 | int maxevents, long timeout) | 1129 | int maxevents, long timeout) |
1119 | { | 1130 | { |
@@ -1121,12 +1132,11 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | |||
1121 | unsigned long flags; | 1132 | unsigned long flags; |
1122 | long slack; | 1133 | long slack; |
1123 | wait_queue_t wait; | 1134 | wait_queue_t wait; |
1124 | struct timespec end_time; | ||
1125 | ktime_t expires, *to = NULL; | 1135 | ktime_t expires, *to = NULL; |
1126 | 1136 | ||
1127 | if (timeout > 0) { | 1137 | if (timeout > 0) { |
1128 | ktime_get_ts(&end_time); | 1138 | struct timespec end_time = ep_set_mstimeout(timeout); |
1129 | timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC); | 1139 | |
1130 | slack = select_estimate_accuracy(&end_time); | 1140 | slack = select_estimate_accuracy(&end_time); |
1131 | to = &expires; | 1141 | to = &expires; |
1132 | *to = timespec_to_ktime(end_time); | 1142 | *to = timespec_to_ktime(end_time); |
@@ -120,7 +120,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) | |||
120 | goto out; | 120 | goto out; |
121 | 121 | ||
122 | file = do_filp_open(AT_FDCWD, tmp, | 122 | file = do_filp_open(AT_FDCWD, tmp, |
123 | O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, | 123 | O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0, |
124 | MAY_READ | MAY_EXEC | MAY_OPEN); | 124 | MAY_READ | MAY_EXEC | MAY_OPEN); |
125 | putname(tmp); | 125 | putname(tmp); |
126 | error = PTR_ERR(file); | 126 | error = PTR_ERR(file); |
@@ -723,7 +723,7 @@ struct file *open_exec(const char *name) | |||
723 | int err; | 723 | int err; |
724 | 724 | ||
725 | file = do_filp_open(AT_FDCWD, name, | 725 | file = do_filp_open(AT_FDCWD, name, |
726 | O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, | 726 | O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0, |
727 | MAY_EXEC | MAY_OPEN); | 727 | MAY_EXEC | MAY_OPEN); |
728 | if (IS_ERR(file)) | 728 | if (IS_ERR(file)) |
729 | goto out; | 729 | goto out; |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 42685424817b..a7555238c41a 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -1030,7 +1030,6 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) | |||
1030 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); | 1030 | memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data)); |
1031 | } | 1031 | } |
1032 | 1032 | ||
1033 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1034 | if (S_ISREG(inode->i_mode)) { | 1033 | if (S_ISREG(inode->i_mode)) { |
1035 | inode->i_op = &exofs_file_inode_operations; | 1034 | inode->i_op = &exofs_file_inode_operations; |
1036 | inode->i_fop = &exofs_file_operations; | 1035 | inode->i_fop = &exofs_file_operations; |
@@ -1131,7 +1130,6 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) | |||
1131 | 1130 | ||
1132 | sbi = sb->s_fs_info; | 1131 | sbi = sb->s_fs_info; |
1133 | 1132 | ||
1134 | inode->i_mapping->backing_dev_info = sb->s_bdi; | ||
1135 | sb->s_dirt = 1; | 1133 | sb->s_dirt = 1; |
1136 | inode_init_owner(inode, dir, mode); | 1134 | inode_init_owner(inode, dir, mode); |
1137 | inode->i_ino = sbi->s_nextid++; | 1135 | inode->i_ino = sbi->s_nextid++; |
diff --git a/fs/fcntl.c b/fs/fcntl.c index ecc8b3954ed6..cb1026181bdc 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -815,7 +815,7 @@ static int __init fcntl_init(void) | |||
815 | __O_SYNC | O_DSYNC | FASYNC | | 815 | __O_SYNC | O_DSYNC | FASYNC | |
816 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | | 816 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
817 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | | 817 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
818 | FMODE_EXEC | 818 | __FMODE_EXEC |
819 | )); | 819 | )); |
820 | 820 | ||
821 | fasync_cache = kmem_cache_create("fasync_cache", | 821 | fasync_cache = kmem_cache_create("fasync_cache", |
diff --git a/fs/file_table.c b/fs/file_table.c index c3e89adf53c0..eb36b6b17e26 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -125,13 +125,13 @@ struct file *get_empty_filp(void) | |||
125 | goto fail; | 125 | goto fail; |
126 | 126 | ||
127 | percpu_counter_inc(&nr_files); | 127 | percpu_counter_inc(&nr_files); |
128 | f->f_cred = get_cred(cred); | ||
128 | if (security_file_alloc(f)) | 129 | if (security_file_alloc(f)) |
129 | goto fail_sec; | 130 | goto fail_sec; |
130 | 131 | ||
131 | INIT_LIST_HEAD(&f->f_u.fu_list); | 132 | INIT_LIST_HEAD(&f->f_u.fu_list); |
132 | atomic_long_set(&f->f_count, 1); | 133 | atomic_long_set(&f->f_count, 1); |
133 | rwlock_init(&f->f_owner.lock); | 134 | rwlock_init(&f->f_owner.lock); |
134 | f->f_cred = get_cred(cred); | ||
135 | spin_lock_init(&f->f_lock); | 135 | spin_lock_init(&f->f_lock); |
136 | eventpoll_init_file(f); | 136 | eventpoll_init_file(f); |
137 | /* f->f_version: 0 */ | 137 | /* f->f_version: 0 */ |
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 52a0bcaa7b6d..b1991a2a08e0 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
@@ -397,8 +397,8 @@ int hfsplus_file_extend(struct inode *inode) | |||
397 | u32 start, len, goal; | 397 | u32 start, len, goal; |
398 | int res; | 398 | int res; |
399 | 399 | ||
400 | if (sbi->total_blocks - sbi->free_blocks + 8 > | 400 | if (sbi->alloc_file->i_size * 8 < |
401 | sbi->alloc_file->i_size * 8) { | 401 | sbi->total_blocks - sbi->free_blocks + 8) { |
402 | /* extend alloc file */ | 402 | /* extend alloc file */ |
403 | printk(KERN_ERR "hfs: extend alloc file! " | 403 | printk(KERN_ERR "hfs: extend alloc file! " |
404 | "(%llu,%u,%u)\n", | 404 | "(%llu,%u,%u)\n", |
diff --git a/fs/hfsplus/part_tbl.c b/fs/hfsplus/part_tbl.c index d66ad113b1cc..40ad88c12c64 100644 --- a/fs/hfsplus/part_tbl.c +++ b/fs/hfsplus/part_tbl.c | |||
@@ -134,7 +134,7 @@ int hfs_part_find(struct super_block *sb, | |||
134 | res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, | 134 | res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK, |
135 | data, READ); | 135 | data, READ); |
136 | if (res) | 136 | if (res) |
137 | return res; | 137 | goto out; |
138 | 138 | ||
139 | switch (be16_to_cpu(*((__be16 *)data))) { | 139 | switch (be16_to_cpu(*((__be16 *)data))) { |
140 | case HFS_OLD_PMAP_MAGIC: | 140 | case HFS_OLD_PMAP_MAGIC: |
@@ -147,7 +147,7 @@ int hfs_part_find(struct super_block *sb, | |||
147 | res = -ENOENT; | 147 | res = -ENOENT; |
148 | break; | 148 | break; |
149 | } | 149 | } |
150 | 150 | out: | |
151 | kfree(data); | 151 | kfree(data); |
152 | return res; | 152 | return res; |
153 | } | 153 | } |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 9a3b4795f43c..b49b55584c84 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -338,20 +338,22 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
338 | struct inode *root, *inode; | 338 | struct inode *root, *inode; |
339 | struct qstr str; | 339 | struct qstr str; |
340 | struct nls_table *nls = NULL; | 340 | struct nls_table *nls = NULL; |
341 | int err = -EINVAL; | 341 | int err; |
342 | 342 | ||
343 | err = -EINVAL; | ||
343 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); | 344 | sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); |
344 | if (!sbi) | 345 | if (!sbi) |
345 | return -ENOMEM; | 346 | goto out; |
346 | 347 | ||
347 | sb->s_fs_info = sbi; | 348 | sb->s_fs_info = sbi; |
348 | mutex_init(&sbi->alloc_mutex); | 349 | mutex_init(&sbi->alloc_mutex); |
349 | mutex_init(&sbi->vh_mutex); | 350 | mutex_init(&sbi->vh_mutex); |
350 | hfsplus_fill_defaults(sbi); | 351 | hfsplus_fill_defaults(sbi); |
352 | |||
353 | err = -EINVAL; | ||
351 | if (!hfsplus_parse_options(data, sbi)) { | 354 | if (!hfsplus_parse_options(data, sbi)) { |
352 | printk(KERN_ERR "hfs: unable to parse mount options\n"); | 355 | printk(KERN_ERR "hfs: unable to parse mount options\n"); |
353 | err = -EINVAL; | 356 | goto out_unload_nls; |
354 | goto cleanup; | ||
355 | } | 357 | } |
356 | 358 | ||
357 | /* temporarily use utf8 to correctly find the hidden dir below */ | 359 | /* temporarily use utf8 to correctly find the hidden dir below */ |
@@ -359,16 +361,14 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
359 | sbi->nls = load_nls("utf8"); | 361 | sbi->nls = load_nls("utf8"); |
360 | if (!sbi->nls) { | 362 | if (!sbi->nls) { |
361 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); | 363 | printk(KERN_ERR "hfs: unable to load nls for utf8\n"); |
362 | err = -EINVAL; | 364 | goto out_unload_nls; |
363 | goto cleanup; | ||
364 | } | 365 | } |
365 | 366 | ||
366 | /* Grab the volume header */ | 367 | /* Grab the volume header */ |
367 | if (hfsplus_read_wrapper(sb)) { | 368 | if (hfsplus_read_wrapper(sb)) { |
368 | if (!silent) | 369 | if (!silent) |
369 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); | 370 | printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n"); |
370 | err = -EINVAL; | 371 | goto out_unload_nls; |
371 | goto cleanup; | ||
372 | } | 372 | } |
373 | vhdr = sbi->s_vhdr; | 373 | vhdr = sbi->s_vhdr; |
374 | 374 | ||
@@ -377,7 +377,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
377 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || | 377 | if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION || |
378 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { | 378 | be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) { |
379 | printk(KERN_ERR "hfs: wrong filesystem version\n"); | 379 | printk(KERN_ERR "hfs: wrong filesystem version\n"); |
380 | goto cleanup; | 380 | goto out_free_vhdr; |
381 | } | 381 | } |
382 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); | 382 | sbi->total_blocks = be32_to_cpu(vhdr->total_blocks); |
383 | sbi->free_blocks = be32_to_cpu(vhdr->free_blocks); | 383 | sbi->free_blocks = be32_to_cpu(vhdr->free_blocks); |
@@ -421,19 +421,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
421 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); | 421 | sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); |
422 | if (!sbi->ext_tree) { | 422 | if (!sbi->ext_tree) { |
423 | printk(KERN_ERR "hfs: failed to load extents file\n"); | 423 | printk(KERN_ERR "hfs: failed to load extents file\n"); |
424 | goto cleanup; | 424 | goto out_free_vhdr; |
425 | } | 425 | } |
426 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); | 426 | sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID); |
427 | if (!sbi->cat_tree) { | 427 | if (!sbi->cat_tree) { |
428 | printk(KERN_ERR "hfs: failed to load catalog file\n"); | 428 | printk(KERN_ERR "hfs: failed to load catalog file\n"); |
429 | goto cleanup; | 429 | goto out_close_ext_tree; |
430 | } | 430 | } |
431 | 431 | ||
432 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); | 432 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); |
433 | if (IS_ERR(inode)) { | 433 | if (IS_ERR(inode)) { |
434 | printk(KERN_ERR "hfs: failed to load allocation file\n"); | 434 | printk(KERN_ERR "hfs: failed to load allocation file\n"); |
435 | err = PTR_ERR(inode); | 435 | err = PTR_ERR(inode); |
436 | goto cleanup; | 436 | goto out_close_cat_tree; |
437 | } | 437 | } |
438 | sbi->alloc_file = inode; | 438 | sbi->alloc_file = inode; |
439 | 439 | ||
@@ -442,14 +442,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
442 | if (IS_ERR(root)) { | 442 | if (IS_ERR(root)) { |
443 | printk(KERN_ERR "hfs: failed to load root directory\n"); | 443 | printk(KERN_ERR "hfs: failed to load root directory\n"); |
444 | err = PTR_ERR(root); | 444 | err = PTR_ERR(root); |
445 | goto cleanup; | 445 | goto out_put_alloc_file; |
446 | } | ||
447 | sb->s_d_op = &hfsplus_dentry_operations; | ||
448 | sb->s_root = d_alloc_root(root); | ||
449 | if (!sb->s_root) { | ||
450 | iput(root); | ||
451 | err = -ENOMEM; | ||
452 | goto cleanup; | ||
453 | } | 446 | } |
454 | 447 | ||
455 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; | 448 | str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1; |
@@ -459,46 +452,69 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
459 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { | 452 | if (!hfs_brec_read(&fd, &entry, sizeof(entry))) { |
460 | hfs_find_exit(&fd); | 453 | hfs_find_exit(&fd); |
461 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) | 454 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) |
462 | goto cleanup; | 455 | goto out_put_root; |
463 | inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); | 456 | inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); |
464 | if (IS_ERR(inode)) { | 457 | if (IS_ERR(inode)) { |
465 | err = PTR_ERR(inode); | 458 | err = PTR_ERR(inode); |
466 | goto cleanup; | 459 | goto out_put_root; |
467 | } | 460 | } |
468 | sbi->hidden_dir = inode; | 461 | sbi->hidden_dir = inode; |
469 | } else | 462 | } else |
470 | hfs_find_exit(&fd); | 463 | hfs_find_exit(&fd); |
471 | 464 | ||
472 | if (sb->s_flags & MS_RDONLY) | 465 | if (!(sb->s_flags & MS_RDONLY)) { |
473 | goto out; | 466 | /* |
467 | * H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused | ||
468 | * all three are registered with Apple for our use | ||
469 | */ | ||
470 | vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); | ||
471 | vhdr->modify_date = hfsp_now2mt(); | ||
472 | be32_add_cpu(&vhdr->write_count, 1); | ||
473 | vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); | ||
474 | vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); | ||
475 | hfsplus_sync_fs(sb, 1); | ||
474 | 476 | ||
475 | /* H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused | 477 | if (!sbi->hidden_dir) { |
476 | * all three are registered with Apple for our use | 478 | mutex_lock(&sbi->vh_mutex); |
477 | */ | 479 | sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); |
478 | vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION); | 480 | hfsplus_create_cat(sbi->hidden_dir->i_ino, root, &str, |
479 | vhdr->modify_date = hfsp_now2mt(); | 481 | sbi->hidden_dir); |
480 | be32_add_cpu(&vhdr->write_count, 1); | 482 | mutex_unlock(&sbi->vh_mutex); |
481 | vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT); | 483 | |
482 | vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT); | 484 | hfsplus_mark_inode_dirty(sbi->hidden_dir, |
483 | hfsplus_sync_fs(sb, 1); | 485 | HFSPLUS_I_CAT_DIRTY); |
484 | 486 | } | |
485 | if (!sbi->hidden_dir) { | ||
486 | mutex_lock(&sbi->vh_mutex); | ||
487 | sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); | ||
488 | hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode, | ||
489 | &str, sbi->hidden_dir); | ||
490 | mutex_unlock(&sbi->vh_mutex); | ||
491 | |||
492 | hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY); | ||
493 | } | 487 | } |
494 | out: | 488 | |
489 | sb->s_d_op = &hfsplus_dentry_operations; | ||
490 | sb->s_root = d_alloc_root(root); | ||
491 | if (!sb->s_root) { | ||
492 | err = -ENOMEM; | ||
493 | goto out_put_hidden_dir; | ||
494 | } | ||
495 | |||
495 | unload_nls(sbi->nls); | 496 | unload_nls(sbi->nls); |
496 | sbi->nls = nls; | 497 | sbi->nls = nls; |
497 | return 0; | 498 | return 0; |
498 | 499 | ||
499 | cleanup: | 500 | out_put_hidden_dir: |
500 | hfsplus_put_super(sb); | 501 | iput(sbi->hidden_dir); |
502 | out_put_root: | ||
503 | iput(sbi->alloc_file); | ||
504 | out_put_alloc_file: | ||
505 | iput(sbi->alloc_file); | ||
506 | out_close_cat_tree: | ||
507 | hfs_btree_close(sbi->cat_tree); | ||
508 | out_close_ext_tree: | ||
509 | hfs_btree_close(sbi->ext_tree); | ||
510 | out_free_vhdr: | ||
511 | kfree(sbi->s_vhdr); | ||
512 | kfree(sbi->s_backup_vhdr); | ||
513 | out_unload_nls: | ||
514 | unload_nls(sbi->nls); | ||
501 | unload_nls(nls); | 515 | unload_nls(nls); |
516 | kfree(sbi); | ||
517 | out: | ||
502 | return err; | 518 | return err; |
503 | } | 519 | } |
504 | 520 | ||
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 196231794f64..3031d81f5f0f 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -167,7 +167,7 @@ reread: | |||
167 | break; | 167 | break; |
168 | case cpu_to_be16(HFSP_WRAP_MAGIC): | 168 | case cpu_to_be16(HFSP_WRAP_MAGIC): |
169 | if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) | 169 | if (!hfsplus_read_mdb(sbi->s_vhdr, &wd)) |
170 | goto out; | 170 | goto out_free_backup_vhdr; |
171 | wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; | 171 | wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT; |
172 | part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; | 172 | part_start += wd.ablk_start + wd.embed_start * wd.ablk_size; |
173 | part_size = wd.embed_count * wd.ablk_size; | 173 | part_size = wd.embed_count * wd.ablk_size; |
@@ -179,7 +179,7 @@ reread: | |||
179 | * (should do this only for cdrom/loop though) | 179 | * (should do this only for cdrom/loop though) |
180 | */ | 180 | */ |
181 | if (hfs_part_find(sb, &part_start, &part_size)) | 181 | if (hfs_part_find(sb, &part_start, &part_size)) |
182 | goto out; | 182 | goto out_free_backup_vhdr; |
183 | goto reread; | 183 | goto reread; |
184 | } | 184 | } |
185 | 185 | ||
diff --git a/fs/ioctl.c b/fs/ioctl.c index a59635e295fa..1eebeb72b202 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -273,6 +273,13 @@ int __generic_block_fiemap(struct inode *inode, | |||
273 | len = isize; | 273 | len = isize; |
274 | } | 274 | } |
275 | 275 | ||
276 | /* | ||
277 | * Some filesystems can't deal with being asked to map less than | ||
278 | * blocksize, so make sure our len is at least block length. | ||
279 | */ | ||
280 | if (logical_to_blk(inode, len) == 0) | ||
281 | len = blk_to_logical(inode, 1); | ||
282 | |||
276 | start_blk = logical_to_blk(inode, start); | 283 | start_blk = logical_to_blk(inode, start); |
277 | last_blk = logical_to_blk(inode, start + len - 1); | 284 | last_blk = logical_to_blk(inode, start + len - 1); |
278 | 285 | ||