Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French:
"Misc small cifs fixes"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
CIFS: Don't let read only caching for mandatory byte-range locked files
CIFS: Fix write after setting a read lock for read oplock files
Revert "CIFS: Fix write after setting a read lock for read oplock files"
cifs: adjust sequence number downward after signing NT_CANCEL request
cifs: move check for NULL socket into smb_send_rqst

+90 -70
-1
fs/cifs/cifsfs.c
··· 228 228 cifs_set_oplock_level(cifs_inode, 0); 229 229 cifs_inode->delete_pending = false; 230 230 cifs_inode->invalid_mapping = false; 231 - cifs_inode->leave_pages_clean = false; 232 231 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 233 232 cifs_inode->server_eof = 0; 234 233 cifs_inode->uniqueid = 0;
+1 -1
fs/cifs/cifsglob.h
··· 386 386 unsigned int cap_unix; 387 387 unsigned int cap_nt_find; 388 388 unsigned int cap_large_files; 389 + unsigned int oplock_read; 389 390 }; 390 391 391 392 #define HEADER_SIZE(server) (server->vals->header_size) ··· 1031 1030 bool clientCanCacheAll; /* read and writebehind oplock */ 1032 1031 bool delete_pending; /* DELETE_ON_CLOSE is set */ 1033 1032 bool invalid_mapping; /* pagecache is invalid */ 1034 - bool leave_pages_clean; /* protected by i_mutex, not set pages dirty */ 1035 1033 unsigned long time; /* jiffies of last update of inode */ 1036 1034 u64 server_eof; /* current file size on server -- protected by i_lock */ 1037 1035 u64 uniqueid; /* server inode number */
+76 -65
fs/cifs/file.c
··· 238 238 return rc; 239 239 } 240 240 241 + static bool 242 + cifs_has_mand_locks(struct cifsInodeInfo *cinode) 243 + { 244 + struct cifs_fid_locks *cur; 245 + bool has_locks = false; 246 + 247 + down_read(&cinode->lock_sem); 248 + list_for_each_entry(cur, &cinode->llist, llist) { 249 + if (!list_empty(&cur->locks)) { 250 + has_locks = true; 251 + break; 252 + } 253 + } 254 + up_read(&cinode->lock_sem); 255 + return has_locks; 256 + } 257 + 241 258 struct cifsFileInfo * 242 259 cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, 243 260 struct tcon_link *tlink, __u32 oplock) ··· 265 248 struct cifsFileInfo *cfile; 266 249 struct cifs_fid_locks *fdlocks; 267 250 struct cifs_tcon *tcon = tlink_tcon(tlink); 251 + struct TCP_Server_Info *server = tcon->ses->server; 268 252 269 253 cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); 270 254 if (cfile == NULL) ··· 294 276 INIT_WORK(&cfile->oplock_break, cifs_oplock_break); 295 277 mutex_init(&cfile->fh_mutex); 296 278 279 + /* 280 + * If the server returned a read oplock and we have mandatory brlocks, 281 + * set oplock level to None. 282 + */ 283 + if (oplock == server->vals->oplock_read && 284 + cifs_has_mand_locks(cinode)) { 285 + cFYI(1, "Reset oplock val from read to None due to mand locks"); 286 + oplock = 0; 287 + } 288 + 297 289 spin_lock(&cifs_file_list_lock); 298 - if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE) 290 + if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock) 299 291 oplock = fid->pending_open->oplock; 300 292 list_del(&fid->pending_open->olist); 301 293 302 - tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock); 294 + server->ops->set_fid(cfile, fid, oplock); 303 295 304 296 list_add(&cfile->tlist, &tcon->openFileList); 305 297 /* if readable file instance put first in list*/ ··· 1450 1422 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1451 1423 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1452 1424 struct TCP_Server_Info *server = tcon->ses->server; 1425 + struct inode *inode = cfile->dentry->d_inode; 1453 1426 1454 1427 if (posix_lck) { 1455 1428 int posix_lock_type; ··· 1487 1458 } 1488 1459 if (!rc) 1489 1460 goto out; 1461 + 1462 + /* 1463 + * Windows 7 server can delay breaking lease from read to None 1464 + * if we set a byte-range lock on a file - break it explicitly 1465 + * before sending the lock to the server to be sure the next 1466 + * read won't conflict with non-overlapted locks due to 1467 + * pagereading. 1468 + */ 1469 + if (!CIFS_I(inode)->clientCanCacheAll && 1470 + CIFS_I(inode)->clientCanCacheRead) { 1471 + cifs_invalidate_mapping(inode); 1472 + cFYI(1, "Set no oplock for inode=%p due to mand locks", 1473 + inode); 1474 + CIFS_I(inode)->clientCanCacheRead = false; 1475 + } 1490 1476 1491 1477 rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, 1492 1478 type, 1, 0, wait_flag); ··· 2147 2103 } else { 2148 2104 rc = copied; 2149 2105 pos += copied; 2150 - /* 2151 - * When we use strict cache mode and cifs_strict_writev was run 2152 - * with level II oplock (indicated by leave_pages_clean field of 2153 - * CIFS_I(inode)), we can leave pages clean - cifs_strict_writev 2154 - * sent the data to the server itself. 2155 - */ 2156 - if (!CIFS_I(inode)->leave_pages_clean || 2157 - !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)) 2158 - set_page_dirty(page); 2106 + set_page_dirty(page); 2159 2107 } 2160 2108 2161 2109 if (rc > 0) { ··· 2498 2462 } 2499 2463 2500 2464 static ssize_t 2501 - cifs_pagecache_writev(struct kiocb *iocb, const struct iovec *iov, 2502 - unsigned long nr_segs, loff_t pos, bool cache_ex) 2465 + cifs_writev(struct kiocb *iocb, const struct iovec *iov, 2466 + unsigned long nr_segs, loff_t pos) 2503 2467 { 2504 2468 struct file *file = iocb->ki_filp; 2505 2469 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; ··· 2521 2485 server->vals->exclusive_lock_type, NULL, 2522 2486 CIFS_WRITE_OP)) { 2523 2487 mutex_lock(&inode->i_mutex); 2524 - if (!cache_ex) 2525 - cinode->leave_pages_clean = true; 2526 2488 rc = __generic_file_aio_write(iocb, iov, nr_segs, 2527 - &iocb->ki_pos); 2528 - if (!cache_ex) 2529 - cinode->leave_pages_clean = false; 2489 + &iocb->ki_pos); 2530 2490 mutex_unlock(&inode->i_mutex); 2531 2491 } 2532 2492 ··· 2549 2517 struct cifsFileInfo *cfile = (struct cifsFileInfo *) 2550 2518 iocb->ki_filp->private_data; 2551 2519 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 2552 - ssize_t written, written2; 2553 - /* 2554 - * We need to store clientCanCacheAll here to prevent race 2555 - * conditions - this value can be changed during an execution 2556 - * of generic_file_aio_write. For CIFS it can be changed from 2557 - * true to false only, but for SMB2 it can be changed both from 2558 - * true to false and vice versa. So, we can end up with a data 2559 - * stored in the cache, not marked dirty and not sent to the 2560 - * server if this value changes its state from false to true 2561 - * after cifs_write_end. 2562 - */ 2563 - bool cache_ex = cinode->clientCanCacheAll; 2564 - bool cache_read = cinode->clientCanCacheRead; 2565 - int rc; 2566 - loff_t saved_pos; 2520 + ssize_t written; 2567 2521 2568 - if (cache_ex) { 2522 + if (cinode->clientCanCacheAll) { 2569 2523 if (cap_unix(tcon->ses) && 2570 - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && 2571 - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( 2572 - tcon->fsUnixInfo.Capability))) 2524 + (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) 2525 + && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 2573 2526 return generic_file_aio_write(iocb, iov, nr_segs, pos); 2574 - return cifs_pagecache_writev(iocb, iov, nr_segs, pos, cache_ex); 2527 + return cifs_writev(iocb, iov, nr_segs, pos); 2575 2528 } 2576 - 2577 2529 /* 2578 - * For files without exclusive oplock in strict cache mode we need to 2579 - * write the data to the server exactly from the pos to pos+len-1 rather 2580 - * than flush all affected pages because it may cause a error with 2581 - * mandatory locks on these pages but not on the region from pos to 2582 - * ppos+len-1. 2530 + * For non-oplocked files in strict cache mode we need to write the data 2531 + * to the server exactly from the pos to pos+len-1 rather than flush all 2532 + * affected pages because it may cause a error with mandatory locks on 2533 + * these pages but not on the region from pos to ppos+len-1. 2583 2534 */ 2584 2535 written = cifs_user_writev(iocb, iov, nr_segs, pos); 2585 - if (!cache_read || written <= 0) 2586 - return written; 2587 - 2588 - saved_pos = iocb->ki_pos; 2589 - iocb->ki_pos = pos; 2590 - /* we have a read oplock - need to store a data in the page cache */ 2591 - if (cap_unix(tcon->ses) && 2592 - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && 2593 - (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( 2594 - tcon->fsUnixInfo.Capability))) 2595 - written2 = generic_file_aio_write(iocb, iov, nr_segs, pos); 2596 - else 2597 - written2 = cifs_pagecache_writev(iocb, iov, nr_segs, pos, 2598 - cache_ex); 2599 - /* errors occured during writing - invalidate the page cache */ 2600 - if (written2 < 0) { 2601 - rc = cifs_invalidate_mapping(inode); 2602 - if (rc) 2603 - written = (ssize_t)rc; 2604 - else 2605 - iocb->ki_pos = saved_pos; 2536 + if (written > 0 && cinode->clientCanCacheRead) { 2537 + /* 2538 + * Windows 7 server can delay breaking level2 oplock if a write 2539 + * request comes - break it on the client to prevent reading 2540 + * an old data. 2541 + */ 2542 + cifs_invalidate_mapping(inode); 2543 + cFYI(1, "Set no oplock for inode=%p after a write operation", 2544 + inode); 2545 + cinode->clientCanCacheRead = false; 2606 2546 } 2607 2547 return written; 2608 2548 } ··· 3580 3576 struct cifsInodeInfo *cinode = CIFS_I(inode); 3581 3577 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 3582 3578 int rc = 0; 3579 + 3580 + if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead && 3581 + cifs_has_mand_locks(cinode)) { 3582 + cFYI(1, "Reset oplock to None for inode=%p due to mand locks", 3583 + inode); 3584 + cinode->clientCanCacheRead = false; 3585 + } 3583 3586 3584 3587 if (inode && S_ISREG(inode->i_mode)) { 3585 3588 if (cinode->clientCanCacheRead)
+8
fs/cifs/smb1ops.c
··· 53 53 mutex_unlock(&server->srv_mutex); 54 54 return rc; 55 55 } 56 + 57 + /* 58 + * The response to this call was already factored into the sequence 59 + * number when the call went out, so we must adjust it back downward 60 + * after signing here. 61 + */ 62 + --server->sequence_number; 56 63 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); 57 64 mutex_unlock(&server->srv_mutex); 58 65 ··· 959 952 .cap_unix = CAP_UNIX, 960 953 .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND, 961 954 .cap_large_files = CAP_LARGE_FILES, 955 + .oplock_read = OPLOCK_READ, 962 956 };
+2
fs/cifs/smb2ops.c
··· 708 708 .cap_unix = 0, 709 709 .cap_nt_find = SMB2_NT_FIND, 710 710 .cap_large_files = SMB2_LARGE_FILES, 711 + .oplock_read = SMB2_OPLOCK_LEVEL_II, 711 712 }; 712 713 713 714 struct smb_version_values smb21_values = { ··· 726 725 .cap_unix = 0, 727 726 .cap_nt_find = SMB2_NT_FIND, 728 727 .cap_large_files = SMB2_LARGE_FILES, 728 + .oplock_read = SMB2_OPLOCK_LEVEL_II, 729 729 }; 730 730 731 731 struct smb_version_values smb30_values = {
+3 -3
fs/cifs/transport.c
··· 144 144 145 145 *sent = 0; 146 146 147 - if (ssocket == NULL) 148 - return -ENOTSOCK; /* BB eventually add reconnect code here */ 149 - 150 147 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; 151 148 smb_msg.msg_namelen = sizeof(struct sockaddr); 152 149 smb_msg.msg_control = NULL; ··· 287 290 size_t total_len = 0, sent; 288 291 struct socket *ssocket = server->ssocket; 289 292 int val = 1; 293 + 294 + if (ssocket == NULL) 295 + return -ENOTSOCK; 290 296 291 297 cFYI(1, "Sending smb: smb_len=%u", smb_buf_length); 292 298 dump_smb(iov[0].iov_base, iov[0].iov_len);