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:
"A set of 5 small cifs fixes"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
cif: fix dead code
cifs: fix error handling cifs_user_readv
fs: cifs: remove unused variable.
Return correct error on query of xattr on file with empty xattrs
cifs: Wait for writebacks to complete before attempting write.

+169 -13
+13 -1
fs/cifs/cifsfs.c
··· 253 253 cifs_set_oplock_level(cifs_inode, 0); 254 254 cifs_inode->delete_pending = false; 255 255 cifs_inode->invalid_mapping = false; 256 + clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags); 257 + clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags); 258 + clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags); 259 + spin_lock_init(&cifs_inode->writers_lock); 260 + cifs_inode->writers = 0; 256 261 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 257 262 cifs_inode->server_eof = 0; 258 263 cifs_inode->uniqueid = 0; ··· 737 732 unsigned long nr_segs, loff_t pos) 738 733 { 739 734 struct inode *inode = file_inode(iocb->ki_filp); 735 + struct cifsInodeInfo *cinode = CIFS_I(inode); 740 736 ssize_t written; 741 737 int rc; 738 + 739 + written = cifs_get_writer(cinode); 740 + if (written) 741 + return written; 742 742 743 743 written = generic_file_aio_write(iocb, iov, nr_segs, pos); 744 744 745 745 if (CIFS_CACHE_WRITE(CIFS_I(inode))) 746 - return written; 746 + goto out; 747 747 748 748 rc = filemap_fdatawrite(inode->i_mapping); 749 749 if (rc) 750 750 cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", 751 751 rc, inode); 752 752 753 + out: 754 + cifs_put_writer(cinode); 753 755 return written; 754 756 } 755 757
+8
fs/cifs/cifsglob.h
··· 228 228 /* verify the message */ 229 229 int (*check_message)(char *, unsigned int); 230 230 bool (*is_oplock_break)(char *, struct TCP_Server_Info *); 231 + void (*downgrade_oplock)(struct TCP_Server_Info *, 232 + struct cifsInodeInfo *, bool); 231 233 /* process transaction2 response */ 232 234 bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, 233 235 char *, int); ··· 1115 1113 unsigned int epoch; /* used to track lease state changes */ 1116 1114 bool delete_pending; /* DELETE_ON_CLOSE is set */ 1117 1115 bool invalid_mapping; /* pagecache is invalid */ 1116 + unsigned long flags; 1117 + #define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ 1118 + #define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ 1119 + #define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */ 1120 + spinlock_t writers_lock; 1121 + unsigned int writers; /* Number of writers on this inode */ 1118 1122 unsigned long time; /* jiffies of last update of inode */ 1119 1123 u64 server_eof; /* current file size on server -- protected by i_lock */ 1120 1124 u64 uniqueid; /* server inode number */
+3
fs/cifs/cifsproto.h
··· 127 127 extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 128 128 int offset); 129 129 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); 130 + extern int cifs_get_writer(struct cifsInodeInfo *cinode); 131 + extern void cifs_put_writer(struct cifsInodeInfo *cinode); 132 + extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode); 130 133 extern int cifs_unlock_range(struct cifsFileInfo *cfile, 131 134 struct file_lock *flock, const unsigned int xid); 132 135 extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
+3
fs/cifs/cifssmb.c
··· 6197 6197 cifs_dbg(FYI, "ea length %d\n", list_len); 6198 6198 if (list_len <= 8) { 6199 6199 cifs_dbg(FYI, "empty EA list returned from server\n"); 6200 + /* didn't find the named attribute */ 6201 + if (ea_name) 6202 + rc = -ENODATA; 6200 6203 goto QAllEAsOut; 6201 6204 } 6202 6205
+30 -5
fs/cifs/file.c
··· 2599 2599 ssize_t err; 2600 2600 2601 2601 err = generic_write_sync(file, iocb->ki_pos - rc, rc); 2602 - if (rc < 0) 2602 + if (err < 0) 2603 2603 rc = err; 2604 2604 } 2605 2605 } else { ··· 2621 2621 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 2622 2622 ssize_t written; 2623 2623 2624 + written = cifs_get_writer(cinode); 2625 + if (written) 2626 + return written; 2627 + 2624 2628 if (CIFS_CACHE_WRITE(cinode)) { 2625 2629 if (cap_unix(tcon->ses) && 2626 2630 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) 2627 - && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) 2628 - return generic_file_aio_write(iocb, iov, nr_segs, pos); 2629 - return cifs_writev(iocb, iov, nr_segs, pos); 2631 + && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { 2632 + written = generic_file_aio_write( 2633 + iocb, iov, nr_segs, pos); 2634 + goto out; 2635 + } 2636 + written = cifs_writev(iocb, iov, nr_segs, pos); 2637 + goto out; 2630 2638 } 2631 2639 /* 2632 2640 * For non-oplocked files in strict cache mode we need to write the data ··· 2654 2646 inode); 2655 2647 cinode->oplock = 0; 2656 2648 } 2649 + out: 2650 + cifs_put_writer(cinode); 2657 2651 return written; 2658 2652 } 2659 2653 ··· 2882 2872 cifs_uncached_readv_complete); 2883 2873 if (!rdata) { 2884 2874 rc = -ENOMEM; 2885 - goto error; 2875 + break; 2886 2876 } 2887 2877 2888 2878 rc = cifs_read_allocate_pages(rdata, npages); ··· 3631 3621 return rc; 3632 3622 } 3633 3623 3624 + static int 3625 + cifs_pending_writers_wait(void *unused) 3626 + { 3627 + schedule(); 3628 + return 0; 3629 + } 3630 + 3634 3631 void cifs_oplock_break(struct work_struct *work) 3635 3632 { 3636 3633 struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, ··· 3645 3628 struct inode *inode = cfile->dentry->d_inode; 3646 3629 struct cifsInodeInfo *cinode = CIFS_I(inode); 3647 3630 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 3631 + struct TCP_Server_Info *server = tcon->ses->server; 3648 3632 int rc = 0; 3633 + 3634 + wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, 3635 + cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE); 3636 + 3637 + server->ops->downgrade_oplock(server, cinode, 3638 + test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags)); 3649 3639 3650 3640 if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && 3651 3641 cifs_has_mand_locks(cinode)) { ··· 3690 3666 cinode); 3691 3667 cifs_dbg(FYI, "Oplock release rc = %d\n", rc); 3692 3668 } 3669 + cifs_done_oplock_break(cinode); 3693 3670 } 3694 3671 3695 3672 /*
+72 -2
fs/cifs/misc.c
··· 466 466 cifs_dbg(FYI, "file id match, oplock break\n"); 467 467 pCifsInode = CIFS_I(netfile->dentry->d_inode); 468 468 469 - cifs_set_oplock_level(pCifsInode, 470 - pSMB->OplockLevel ? OPLOCK_READ : 0); 469 + set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, 470 + &pCifsInode->flags); 471 + 472 + /* 473 + * Set flag if the server downgrades the oplock 474 + * to L2 else clear. 475 + */ 476 + if (pSMB->OplockLevel) 477 + set_bit( 478 + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, 479 + &pCifsInode->flags); 480 + else 481 + clear_bit( 482 + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, 483 + &pCifsInode->flags); 484 + 471 485 queue_work(cifsiod_wq, 472 486 &netfile->oplock_break); 473 487 netfile->oplock_break_cancelled = false; ··· 563 549 &cinode->vfs_inode); 564 550 } else 565 551 cinode->oplock = 0; 552 + } 553 + 554 + static int 555 + cifs_oplock_break_wait(void *unused) 556 + { 557 + schedule(); 558 + return signal_pending(current) ? -ERESTARTSYS : 0; 559 + } 560 + 561 + /* 562 + * We wait for oplock breaks to be processed before we attempt to perform 563 + * writes. 564 + */ 565 + int cifs_get_writer(struct cifsInodeInfo *cinode) 566 + { 567 + int rc; 568 + 569 + start: 570 + rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK, 571 + cifs_oplock_break_wait, TASK_KILLABLE); 572 + if (rc) 573 + return rc; 574 + 575 + spin_lock(&cinode->writers_lock); 576 + if (!cinode->writers) 577 + set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); 578 + cinode->writers++; 579 + /* Check to see if we have started servicing an oplock break */ 580 + if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) { 581 + cinode->writers--; 582 + if (cinode->writers == 0) { 583 + clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); 584 + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); 585 + } 586 + spin_unlock(&cinode->writers_lock); 587 + goto start; 588 + } 589 + spin_unlock(&cinode->writers_lock); 590 + return 0; 591 + } 592 + 593 + void cifs_put_writer(struct cifsInodeInfo *cinode) 594 + { 595 + spin_lock(&cinode->writers_lock); 596 + cinode->writers--; 597 + if (cinode->writers == 0) { 598 + clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); 599 + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); 600 + } 601 + spin_unlock(&cinode->writers_lock); 602 + } 603 + 604 + void cifs_done_oplock_break(struct cifsInodeInfo *cinode) 605 + { 606 + clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); 607 + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK); 566 608 } 567 609 568 610 bool
+11
fs/cifs/smb1ops.c
··· 372 372 return 0; 373 373 } 374 374 375 + static void 376 + cifs_downgrade_oplock(struct TCP_Server_Info *server, 377 + struct cifsInodeInfo *cinode, bool set_level2) 378 + { 379 + if (set_level2) 380 + cifs_set_oplock_level(cinode, OPLOCK_READ); 381 + else 382 + cifs_set_oplock_level(cinode, 0); 383 + } 384 + 375 385 static bool 376 386 cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, 377 387 char *buf, int malformed) ··· 1029 1019 .clear_stats = cifs_clear_stats, 1030 1020 .print_stats = cifs_print_stats, 1031 1021 .is_oplock_break = is_valid_oplock_break, 1022 + .downgrade_oplock = cifs_downgrade_oplock, 1032 1023 .check_trans2 = cifs_check_trans2, 1033 1024 .need_neg = cifs_need_neg, 1034 1025 .negotiate = cifs_negotiate,
+15 -3
fs/cifs/smb2misc.c
··· 575 575 else 576 576 cfile->oplock_break_cancelled = false; 577 577 578 - server->ops->set_oplock_level(cinode, 579 - rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0, 580 - 0, NULL); 578 + set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, 579 + &cinode->flags); 580 + 581 + /* 582 + * Set flag if the server downgrades the oplock 583 + * to L2 else clear. 584 + */ 585 + if (rsp->OplockLevel) 586 + set_bit( 587 + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, 588 + &cinode->flags); 589 + else 590 + clear_bit( 591 + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, 592 + &cinode->flags); 581 593 582 594 queue_work(cifsiod_wq, &cfile->oplock_break); 583 595
+14
fs/cifs/smb2ops.c
··· 905 905 } 906 906 907 907 static void 908 + smb2_downgrade_oplock(struct TCP_Server_Info *server, 909 + struct cifsInodeInfo *cinode, bool set_level2) 910 + { 911 + if (set_level2) 912 + server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II, 913 + 0, NULL); 914 + else 915 + server->ops->set_oplock_level(cinode, 0, 0, NULL); 916 + } 917 + 918 + static void 908 919 smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, 909 920 unsigned int epoch, bool *purge_cache) 910 921 { ··· 1121 1110 .clear_stats = smb2_clear_stats, 1122 1111 .print_stats = smb2_print_stats, 1123 1112 .is_oplock_break = smb2_is_valid_oplock_break, 1113 + .downgrade_oplock = smb2_downgrade_oplock, 1124 1114 .need_neg = smb2_need_neg, 1125 1115 .negotiate = smb2_negotiate, 1126 1116 .negotiate_wsize = smb2_negotiate_wsize, ··· 1196 1184 .clear_stats = smb2_clear_stats, 1197 1185 .print_stats = smb2_print_stats, 1198 1186 .is_oplock_break = smb2_is_valid_oplock_break, 1187 + .downgrade_oplock = smb2_downgrade_oplock, 1199 1188 .need_neg = smb2_need_neg, 1200 1189 .negotiate = smb2_negotiate, 1201 1190 .negotiate_wsize = smb2_negotiate_wsize, ··· 1272 1259 .print_stats = smb2_print_stats, 1273 1260 .dump_share_caps = smb2_dump_share_caps, 1274 1261 .is_oplock_break = smb2_is_valid_oplock_break, 1262 + .downgrade_oplock = smb2_downgrade_oplock, 1275 1263 .need_neg = smb2_need_neg, 1276 1264 .negotiate = smb2_negotiate, 1277 1265 .negotiate_wsize = smb2_negotiate_wsize,
-2
fs/cifs/smb2pdu.c
··· 1352 1352 u64 persistent_fid, u64 volatile_fid) 1353 1353 { 1354 1354 int rc; 1355 - char *res_key = NULL; 1356 1355 struct compress_ioctl fsctl_input; 1357 1356 char *ret_data = NULL; 1358 1357 ··· 1364 1365 2 /* in data len */, &ret_data /* out data */, NULL); 1365 1366 1366 1367 cifs_dbg(FYI, "set compression rc %d\n", rc); 1367 - kfree(res_key); 1368 1368 1369 1369 return rc; 1370 1370 }