diff options
| -rw-r--r-- | fs/cifs/cifsfs.c | 14 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 8 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 3 | ||||
| -rw-r--r-- | fs/cifs/file.c | 31 | ||||
| -rw-r--r-- | fs/cifs/misc.c | 74 | ||||
| -rw-r--r-- | fs/cifs/smb1ops.c | 11 | ||||
| -rw-r--r-- | fs/cifs/smb2misc.c | 18 | ||||
| -rw-r--r-- | fs/cifs/smb2ops.c | 14 |
8 files changed, 164 insertions, 9 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index df9c9141c099..5be1f997ecde 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -253,6 +253,11 @@ cifs_alloc_inode(struct super_block *sb) | |||
| 253 | cifs_set_oplock_level(cifs_inode, 0); | 253 | cifs_set_oplock_level(cifs_inode, 0); |
| 254 | cifs_inode->delete_pending = false; | 254 | cifs_inode->delete_pending = false; |
| 255 | cifs_inode->invalid_mapping = false; | 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 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 261 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
| 257 | cifs_inode->server_eof = 0; | 262 | cifs_inode->server_eof = 0; |
| 258 | cifs_inode->uniqueid = 0; | 263 | cifs_inode->uniqueid = 0; |
| @@ -732,19 +737,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 732 | unsigned long nr_segs, loff_t pos) | 737 | unsigned long nr_segs, loff_t pos) |
| 733 | { | 738 | { |
| 734 | struct inode *inode = file_inode(iocb->ki_filp); | 739 | struct inode *inode = file_inode(iocb->ki_filp); |
| 740 | struct cifsInodeInfo *cinode = CIFS_I(inode); | ||
| 735 | ssize_t written; | 741 | ssize_t written; |
| 736 | int rc; | 742 | int rc; |
| 737 | 743 | ||
| 744 | written = cifs_get_writer(cinode); | ||
| 745 | if (written) | ||
| 746 | return written; | ||
| 747 | |||
| 738 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); | 748 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); |
| 739 | 749 | ||
| 740 | if (CIFS_CACHE_WRITE(CIFS_I(inode))) | 750 | if (CIFS_CACHE_WRITE(CIFS_I(inode))) |
| 741 | return written; | 751 | goto out; |
| 742 | 752 | ||
| 743 | rc = filemap_fdatawrite(inode->i_mapping); | 753 | rc = filemap_fdatawrite(inode->i_mapping); |
| 744 | if (rc) | 754 | if (rc) |
| 745 | cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", | 755 | cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", |
| 746 | rc, inode); | 756 | rc, inode); |
| 747 | 757 | ||
| 758 | out: | ||
| 759 | cifs_put_writer(cinode); | ||
| 748 | return written; | 760 | return written; |
| 749 | } | 761 | } |
| 750 | 762 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c0f3718b77a8..30f6e9251a4a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -228,6 +228,8 @@ struct smb_version_operations { | |||
| 228 | /* verify the message */ | 228 | /* verify the message */ |
| 229 | int (*check_message)(char *, unsigned int); | 229 | int (*check_message)(char *, unsigned int); |
| 230 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); | 230 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); |
| 231 | void (*downgrade_oplock)(struct TCP_Server_Info *, | ||
| 232 | struct cifsInodeInfo *, bool); | ||
| 231 | /* process transaction2 response */ | 233 | /* process transaction2 response */ |
| 232 | bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, | 234 | bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, |
| 233 | char *, int); | 235 | char *, int); |
| @@ -1113,6 +1115,12 @@ struct cifsInodeInfo { | |||
| 1113 | unsigned int epoch; /* used to track lease state changes */ | 1115 | unsigned int epoch; /* used to track lease state changes */ |
| 1114 | bool delete_pending; /* DELETE_ON_CLOSE is set */ | 1116 | bool delete_pending; /* DELETE_ON_CLOSE is set */ |
| 1115 | bool invalid_mapping; /* pagecache is invalid */ | 1117 | bool invalid_mapping; /* pagecache is invalid */ |
| 1118 | unsigned long flags; | ||
| 1119 | #define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ | ||
| 1120 | #define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ | ||
| 1121 | #define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */ | ||
| 1122 | spinlock_t writers_lock; | ||
| 1123 | unsigned int writers; /* Number of writers on this inode */ | ||
| 1116 | unsigned long time; /* jiffies of last update of inode */ | 1124 | unsigned long time; /* jiffies of last update of inode */ |
| 1117 | u64 server_eof; /* current file size on server -- protected by i_lock */ | 1125 | u64 server_eof; /* current file size on server -- protected by i_lock */ |
| 1118 | u64 uniqueid; /* server inode number */ | 1126 | u64 uniqueid; /* server inode number */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index acc4ee8ed075..ca7980a1e303 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec); | |||
| 127 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, | 127 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
| 128 | int offset); | 128 | int offset); |
| 129 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | 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 | extern int cifs_unlock_range(struct cifsFileInfo *cfile, | 133 | extern int cifs_unlock_range(struct cifsFileInfo *cfile, |
| 131 | struct file_lock *flock, const unsigned int xid); | 134 | struct file_lock *flock, const unsigned int xid); |
| 132 | extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); | 135 | extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8add25538a3b..d8ee76241b64 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -2621,12 +2621,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2621 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 2621 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 2622 | ssize_t written; | 2622 | ssize_t written; |
| 2623 | 2623 | ||
| 2624 | written = cifs_get_writer(cinode); | ||
| 2625 | if (written) | ||
| 2626 | return written; | ||
| 2627 | |||
| 2624 | if (CIFS_CACHE_WRITE(cinode)) { | 2628 | if (CIFS_CACHE_WRITE(cinode)) { |
| 2625 | if (cap_unix(tcon->ses) && | 2629 | if (cap_unix(tcon->ses) && |
| 2626 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) | 2630 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) |
| 2627 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | 2631 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { |
| 2628 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 2632 | written = generic_file_aio_write( |
| 2629 | return cifs_writev(iocb, iov, nr_segs, pos); | 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 | * For non-oplocked files in strict cache mode we need to write the data | 2640 | * For non-oplocked files in strict cache mode we need to write the data |
| @@ -2646,6 +2654,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2646 | inode); | 2654 | inode); |
| 2647 | cinode->oplock = 0; | 2655 | cinode->oplock = 0; |
| 2648 | } | 2656 | } |
| 2657 | out: | ||
| 2658 | cifs_put_writer(cinode); | ||
| 2649 | return written; | 2659 | return written; |
| 2650 | } | 2660 | } |
| 2651 | 2661 | ||
| @@ -3621,6 +3631,13 @@ static int cifs_launder_page(struct page *page) | |||
| 3621 | return rc; | 3631 | return rc; |
| 3622 | } | 3632 | } |
| 3623 | 3633 | ||
| 3634 | static int | ||
| 3635 | cifs_pending_writers_wait(void *unused) | ||
| 3636 | { | ||
| 3637 | schedule(); | ||
| 3638 | return 0; | ||
| 3639 | } | ||
| 3640 | |||
| 3624 | void cifs_oplock_break(struct work_struct *work) | 3641 | void cifs_oplock_break(struct work_struct *work) |
| 3625 | { | 3642 | { |
| 3626 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, | 3643 | struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, |
| @@ -3628,8 +3645,15 @@ void cifs_oplock_break(struct work_struct *work) | |||
| 3628 | struct inode *inode = cfile->dentry->d_inode; | 3645 | struct inode *inode = cfile->dentry->d_inode; |
| 3629 | struct cifsInodeInfo *cinode = CIFS_I(inode); | 3646 | struct cifsInodeInfo *cinode = CIFS_I(inode); |
| 3630 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 3647 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 3648 | struct TCP_Server_Info *server = tcon->ses->server; | ||
| 3631 | int rc = 0; | 3649 | int rc = 0; |
| 3632 | 3650 | ||
| 3651 | wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, | ||
| 3652 | cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE); | ||
| 3653 | |||
| 3654 | server->ops->downgrade_oplock(server, cinode, | ||
| 3655 | test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags)); | ||
| 3656 | |||
| 3633 | if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && | 3657 | if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && |
| 3634 | cifs_has_mand_locks(cinode)) { | 3658 | cifs_has_mand_locks(cinode)) { |
| 3635 | cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", | 3659 | cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", |
| @@ -3666,6 +3690,7 @@ void cifs_oplock_break(struct work_struct *work) | |||
| 3666 | cinode); | 3690 | cinode); |
| 3667 | cifs_dbg(FYI, "Oplock release rc = %d\n", rc); | 3691 | cifs_dbg(FYI, "Oplock release rc = %d\n", rc); |
| 3668 | } | 3692 | } |
| 3693 | cifs_done_oplock_break(cinode); | ||
| 3669 | } | 3694 | } |
| 3670 | 3695 | ||
| 3671 | /* | 3696 | /* |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 2f9f3790679d..3b0c62e622da 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -466,8 +466,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) | |||
| 466 | cifs_dbg(FYI, "file id match, oplock break\n"); | 466 | cifs_dbg(FYI, "file id match, oplock break\n"); |
| 467 | pCifsInode = CIFS_I(netfile->dentry->d_inode); | 467 | pCifsInode = CIFS_I(netfile->dentry->d_inode); |
| 468 | 468 | ||
| 469 | cifs_set_oplock_level(pCifsInode, | 469 | set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, |
| 470 | pSMB->OplockLevel ? OPLOCK_READ : 0); | 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 | queue_work(cifsiod_wq, | 485 | queue_work(cifsiod_wq, |
| 472 | &netfile->oplock_break); | 486 | &netfile->oplock_break); |
| 473 | netfile->oplock_break_cancelled = false; | 487 | netfile->oplock_break_cancelled = false; |
| @@ -551,6 +565,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | |||
| 551 | cinode->oplock = 0; | 565 | cinode->oplock = 0; |
| 552 | } | 566 | } |
| 553 | 567 | ||
| 568 | static int | ||
| 569 | cifs_oplock_break_wait(void *unused) | ||
| 570 | { | ||
| 571 | schedule(); | ||
| 572 | return signal_pending(current) ? -ERESTARTSYS : 0; | ||
| 573 | } | ||
| 574 | |||
| 575 | /* | ||
| 576 | * We wait for oplock breaks to be processed before we attempt to perform | ||
| 577 | * writes. | ||
| 578 | */ | ||
| 579 | int cifs_get_writer(struct cifsInodeInfo *cinode) | ||
| 580 | { | ||
| 581 | int rc; | ||
| 582 | |||
| 583 | start: | ||
| 584 | rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK, | ||
| 585 | cifs_oplock_break_wait, TASK_KILLABLE); | ||
| 586 | if (rc) | ||
| 587 | return rc; | ||
| 588 | |||
| 589 | spin_lock(&cinode->writers_lock); | ||
| 590 | if (!cinode->writers) | ||
| 591 | set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
| 592 | cinode->writers++; | ||
| 593 | /* Check to see if we have started servicing an oplock break */ | ||
| 594 | if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) { | ||
| 595 | cinode->writers--; | ||
| 596 | if (cinode->writers == 0) { | ||
| 597 | clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
| 598 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); | ||
| 599 | } | ||
| 600 | spin_unlock(&cinode->writers_lock); | ||
| 601 | goto start; | ||
| 602 | } | ||
| 603 | spin_unlock(&cinode->writers_lock); | ||
| 604 | return 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | void cifs_put_writer(struct cifsInodeInfo *cinode) | ||
| 608 | { | ||
| 609 | spin_lock(&cinode->writers_lock); | ||
| 610 | cinode->writers--; | ||
| 611 | if (cinode->writers == 0) { | ||
| 612 | clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); | ||
| 613 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); | ||
| 614 | } | ||
| 615 | spin_unlock(&cinode->writers_lock); | ||
| 616 | } | ||
| 617 | |||
| 618 | void cifs_done_oplock_break(struct cifsInodeInfo *cinode) | ||
| 619 | { | ||
| 620 | clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); | ||
| 621 | wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK); | ||
| 622 | } | ||
| 623 | |||
| 554 | bool | 624 | bool |
| 555 | backup_cred(struct cifs_sb_info *cifs_sb) | 625 | backup_cred(struct cifs_sb_info *cifs_sb) |
| 556 | { | 626 | { |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 526fb89f9230..d1fdfa848703 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
| @@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) | |||
| 372 | return 0; | 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 | static bool | 385 | static bool |
| 376 | cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, | 386 | cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, |
| 377 | char *buf, int malformed) | 387 | char *buf, int malformed) |
| @@ -1019,6 +1029,7 @@ struct smb_version_operations smb1_operations = { | |||
| 1019 | .clear_stats = cifs_clear_stats, | 1029 | .clear_stats = cifs_clear_stats, |
| 1020 | .print_stats = cifs_print_stats, | 1030 | .print_stats = cifs_print_stats, |
| 1021 | .is_oplock_break = is_valid_oplock_break, | 1031 | .is_oplock_break = is_valid_oplock_break, |
| 1032 | .downgrade_oplock = cifs_downgrade_oplock, | ||
| 1022 | .check_trans2 = cifs_check_trans2, | 1033 | .check_trans2 = cifs_check_trans2, |
| 1023 | .need_neg = cifs_need_neg, | 1034 | .need_neg = cifs_need_neg, |
| 1024 | .negotiate = cifs_negotiate, | 1035 | .negotiate = cifs_negotiate, |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index fb3966265b6e..b8021fde987d 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
| @@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) | |||
| 575 | else | 575 | else |
| 576 | cfile->oplock_break_cancelled = false; | 576 | cfile->oplock_break_cancelled = false; |
| 577 | 577 | ||
| 578 | server->ops->set_oplock_level(cinode, | 578 | set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, |
| 579 | rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0, | 579 | &cinode->flags); |
| 580 | 0, NULL); | 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 | queue_work(cifsiod_wq, &cfile->oplock_break); | 594 | queue_work(cifsiod_wq, &cfile->oplock_break); |
| 583 | 595 | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 192f51a12cf1..35ddc3ed119d 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -905,6 +905,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 905 | } | 905 | } |
| 906 | 906 | ||
| 907 | static void | 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 | smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, | 919 | smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, |
| 909 | unsigned int epoch, bool *purge_cache) | 920 | unsigned int epoch, bool *purge_cache) |
| 910 | { | 921 | { |
| @@ -1110,6 +1121,7 @@ struct smb_version_operations smb20_operations = { | |||
| 1110 | .clear_stats = smb2_clear_stats, | 1121 | .clear_stats = smb2_clear_stats, |
| 1111 | .print_stats = smb2_print_stats, | 1122 | .print_stats = smb2_print_stats, |
| 1112 | .is_oplock_break = smb2_is_valid_oplock_break, | 1123 | .is_oplock_break = smb2_is_valid_oplock_break, |
| 1124 | .downgrade_oplock = smb2_downgrade_oplock, | ||
| 1113 | .need_neg = smb2_need_neg, | 1125 | .need_neg = smb2_need_neg, |
| 1114 | .negotiate = smb2_negotiate, | 1126 | .negotiate = smb2_negotiate, |
| 1115 | .negotiate_wsize = smb2_negotiate_wsize, | 1127 | .negotiate_wsize = smb2_negotiate_wsize, |
| @@ -1184,6 +1196,7 @@ struct smb_version_operations smb21_operations = { | |||
| 1184 | .clear_stats = smb2_clear_stats, | 1196 | .clear_stats = smb2_clear_stats, |
| 1185 | .print_stats = smb2_print_stats, | 1197 | .print_stats = smb2_print_stats, |
| 1186 | .is_oplock_break = smb2_is_valid_oplock_break, | 1198 | .is_oplock_break = smb2_is_valid_oplock_break, |
| 1199 | .downgrade_oplock = smb2_downgrade_oplock, | ||
| 1187 | .need_neg = smb2_need_neg, | 1200 | .need_neg = smb2_need_neg, |
| 1188 | .negotiate = smb2_negotiate, | 1201 | .negotiate = smb2_negotiate, |
| 1189 | .negotiate_wsize = smb2_negotiate_wsize, | 1202 | .negotiate_wsize = smb2_negotiate_wsize, |
| @@ -1259,6 +1272,7 @@ struct smb_version_operations smb30_operations = { | |||
| 1259 | .print_stats = smb2_print_stats, | 1272 | .print_stats = smb2_print_stats, |
| 1260 | .dump_share_caps = smb2_dump_share_caps, | 1273 | .dump_share_caps = smb2_dump_share_caps, |
| 1261 | .is_oplock_break = smb2_is_valid_oplock_break, | 1274 | .is_oplock_break = smb2_is_valid_oplock_break, |
| 1275 | .downgrade_oplock = smb2_downgrade_oplock, | ||
| 1262 | .need_neg = smb2_need_neg, | 1276 | .need_neg = smb2_need_neg, |
| 1263 | .negotiate = smb2_negotiate, | 1277 | .negotiate = smb2_negotiate, |
| 1264 | .negotiate_wsize = smb2_negotiate_wsize, | 1278 | .negotiate_wsize = smb2_negotiate_wsize, |
