Commit 18cceb6a78f46b65df654e8348fa2093b91b30f6
Committed by
Steve French
1 parent
77993be3f3
Exists in
master
and in
20 other branches
CIFS: Replace clientCanCache* bools with an integer
that prepare the code to handle different types of SMB2 leases. Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Showing 9 changed files with 64 additions and 61 deletions Side-by-side Diff
fs/cifs/cifsfs.c
... | ... | @@ -733,7 +733,7 @@ |
733 | 733 | |
734 | 734 | written = generic_file_aio_write(iocb, iov, nr_segs, pos); |
735 | 735 | |
736 | - if (CIFS_I(inode)->clientCanCacheAll) | |
736 | + if (CIFS_CACHE_WRITE(CIFS_I(inode))) | |
737 | 737 | return written; |
738 | 738 | |
739 | 739 | rc = filemap_fdatawrite(inode->i_mapping); |
... | ... | @@ -758,7 +758,7 @@ |
758 | 758 | * We need to be sure that all dirty pages are written and the |
759 | 759 | * server has the newest file length. |
760 | 760 | */ |
761 | - if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && | |
761 | + if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && | |
762 | 762 | inode->i_mapping->nrpages != 0) { |
763 | 763 | rc = filemap_fdatawait(inode->i_mapping); |
764 | 764 | if (rc) { |
... | ... | @@ -782,8 +782,10 @@ |
782 | 782 | |
783 | 783 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) |
784 | 784 | { |
785 | - /* note that this is called by vfs setlease with i_lock held | |
786 | - to protect *lease from going away */ | |
785 | + /* | |
786 | + * Note that this is called by vfs setlease with i_lock held to | |
787 | + * protect *lease from going away. | |
788 | + */ | |
787 | 789 | struct inode *inode = file_inode(file); |
788 | 790 | struct cifsFileInfo *cfile = file->private_data; |
789 | 791 | |
790 | 792 | |
... | ... | @@ -791,20 +793,19 @@ |
791 | 793 | return -EINVAL; |
792 | 794 | |
793 | 795 | /* check if file is oplocked */ |
794 | - if (((arg == F_RDLCK) && | |
795 | - (CIFS_I(inode)->clientCanCacheRead)) || | |
796 | - ((arg == F_WRLCK) && | |
797 | - (CIFS_I(inode)->clientCanCacheAll))) | |
796 | + if (((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || | |
797 | + ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) | |
798 | 798 | return generic_setlease(file, arg, lease); |
799 | 799 | else if (tlink_tcon(cfile->tlink)->local_lease && |
800 | - !CIFS_I(inode)->clientCanCacheRead) | |
801 | - /* If the server claims to support oplock on this | |
802 | - file, then we still need to check oplock even | |
803 | - if the local_lease mount option is set, but there | |
804 | - are servers which do not support oplock for which | |
805 | - this mount option may be useful if the user | |
806 | - knows that the file won't be changed on the server | |
807 | - by anyone else */ | |
800 | + !CIFS_CACHE_READ(CIFS_I(inode))) | |
801 | + /* | |
802 | + * If the server claims to support oplock on this file, then we | |
803 | + * still need to check oplock even if the local_lease mount | |
804 | + * option is set, but there are servers which do not support | |
805 | + * oplock for which this mount option may be useful if the user | |
806 | + * knows that the file won't be changed on the server by anyone | |
807 | + * else. | |
808 | + */ | |
808 | 809 | return generic_setlease(file, arg, lease); |
809 | 810 | else |
810 | 811 | return -EAGAIN; |
fs/cifs/cifsglob.h
... | ... | @@ -1031,6 +1031,13 @@ |
1031 | 1031 | struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file); |
1032 | 1032 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file); |
1033 | 1033 | |
1034 | +#define CIFS_CACHE_READ_FLG 1 | |
1035 | +#define CIFS_CACHE_HANDLE_FLG 2 | |
1036 | +#define CIFS_CACHE_WRITE_FLG 4 | |
1037 | + | |
1038 | +#define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) | |
1039 | +#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) | |
1040 | + | |
1034 | 1041 | /* |
1035 | 1042 | * One of these for each file inode |
1036 | 1043 | */ |
... | ... | @@ -1042,8 +1049,7 @@ |
1042 | 1049 | /* BB add in lists for dirty pages i.e. write caching info for oplock */ |
1043 | 1050 | struct list_head openFileList; |
1044 | 1051 | __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ |
1045 | - bool clientCanCacheRead; /* read oplock */ | |
1046 | - bool clientCanCacheAll; /* read and writebehind oplock */ | |
1052 | + unsigned int oplock; /* oplock/lease level we have */ | |
1047 | 1053 | bool delete_pending; /* DELETE_ON_CLOSE is set */ |
1048 | 1054 | bool invalid_mapping; /* pagecache is invalid */ |
1049 | 1055 | unsigned long time; /* jiffies of last update of inode */ |
fs/cifs/file.c
... | ... | @@ -1524,12 +1524,12 @@ |
1524 | 1524 | * read won't conflict with non-overlapted locks due to |
1525 | 1525 | * pagereading. |
1526 | 1526 | */ |
1527 | - if (!CIFS_I(inode)->clientCanCacheAll && | |
1528 | - CIFS_I(inode)->clientCanCacheRead) { | |
1527 | + if (!CIFS_CACHE_WRITE(CIFS_I(inode)) && | |
1528 | + CIFS_CACHE_READ(CIFS_I(inode))) { | |
1529 | 1529 | cifs_invalidate_mapping(inode); |
1530 | 1530 | cifs_dbg(FYI, "Set no oplock for inode=%p due to mand locks\n", |
1531 | 1531 | inode); |
1532 | - CIFS_I(inode)->clientCanCacheRead = false; | |
1532 | + CIFS_I(inode)->oplock = 0; | |
1533 | 1533 | } |
1534 | 1534 | |
1535 | 1535 | rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, |
... | ... | @@ -2213,7 +2213,7 @@ |
2213 | 2213 | cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n", |
2214 | 2214 | file->f_path.dentry->d_name.name, datasync); |
2215 | 2215 | |
2216 | - if (!CIFS_I(inode)->clientCanCacheRead) { | |
2216 | + if (!CIFS_CACHE_READ(CIFS_I(inode))) { | |
2217 | 2217 | rc = cifs_invalidate_mapping(inode); |
2218 | 2218 | if (rc) { |
2219 | 2219 | cifs_dbg(FYI, "rc: %d during invalidate phase\n", rc); |
... | ... | @@ -2577,7 +2577,7 @@ |
2577 | 2577 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
2578 | 2578 | ssize_t written; |
2579 | 2579 | |
2580 | - if (cinode->clientCanCacheAll) { | |
2580 | + if (CIFS_CACHE_WRITE(cinode)) { | |
2581 | 2581 | if (cap_unix(tcon->ses) && |
2582 | 2582 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) |
2583 | 2583 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) |
... | ... | @@ -2591,7 +2591,7 @@ |
2591 | 2591 | * these pages but not on the region from pos to ppos+len-1. |
2592 | 2592 | */ |
2593 | 2593 | written = cifs_user_writev(iocb, iov, nr_segs, pos); |
2594 | - if (written > 0 && cinode->clientCanCacheRead) { | |
2594 | + if (written > 0 && CIFS_CACHE_READ(cinode)) { | |
2595 | 2595 | /* |
2596 | 2596 | * Windows 7 server can delay breaking level2 oplock if a write |
2597 | 2597 | * request comes - break it on the client to prevent reading |
... | ... | @@ -2600,7 +2600,7 @@ |
2600 | 2600 | cifs_invalidate_mapping(inode); |
2601 | 2601 | cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", |
2602 | 2602 | inode); |
2603 | - cinode->clientCanCacheRead = false; | |
2603 | + cinode->oplock = 0; | |
2604 | 2604 | } |
2605 | 2605 | return written; |
2606 | 2606 | } |
... | ... | @@ -2957,7 +2957,7 @@ |
2957 | 2957 | * on pages affected by this read but not on the region from pos to |
2958 | 2958 | * pos+len-1. |
2959 | 2959 | */ |
2960 | - if (!cinode->clientCanCacheRead) | |
2960 | + if (!CIFS_CACHE_READ(cinode)) | |
2961 | 2961 | return cifs_user_readv(iocb, iov, nr_segs, pos); |
2962 | 2962 | |
2963 | 2963 | if (cap_unix(tcon->ses) && |
... | ... | @@ -3093,7 +3093,7 @@ |
3093 | 3093 | |
3094 | 3094 | xid = get_xid(); |
3095 | 3095 | |
3096 | - if (!CIFS_I(inode)->clientCanCacheRead) { | |
3096 | + if (!CIFS_CACHE_READ(CIFS_I(inode))) { | |
3097 | 3097 | rc = cifs_invalidate_mapping(inode); |
3098 | 3098 | if (rc) |
3099 | 3099 | return rc; |
... | ... | @@ -3526,7 +3526,7 @@ |
3526 | 3526 | * is, when the page lies beyond the EOF, or straddles the EOF |
3527 | 3527 | * and the write will cover all of the existing data. |
3528 | 3528 | */ |
3529 | - if (CIFS_I(mapping->host)->clientCanCacheRead) { | |
3529 | + if (CIFS_CACHE_READ(CIFS_I(mapping->host))) { | |
3530 | 3530 | i_size = i_size_read(mapping->host); |
3531 | 3531 | if (page_start >= i_size || |
3532 | 3532 | (offset == 0 && (pos + len) >= i_size)) { |
3533 | 3533 | |
3534 | 3534 | |
3535 | 3535 | |
... | ... | @@ -3609,20 +3609,20 @@ |
3609 | 3609 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
3610 | 3610 | int rc = 0; |
3611 | 3611 | |
3612 | - if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead && | |
3612 | + if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && | |
3613 | 3613 | cifs_has_mand_locks(cinode)) { |
3614 | 3614 | cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", |
3615 | 3615 | inode); |
3616 | - cinode->clientCanCacheRead = false; | |
3616 | + cinode->oplock = 0; | |
3617 | 3617 | } |
3618 | 3618 | |
3619 | 3619 | if (inode && S_ISREG(inode->i_mode)) { |
3620 | - if (cinode->clientCanCacheRead) | |
3620 | + if (CIFS_CACHE_READ(cinode)) | |
3621 | 3621 | break_lease(inode, O_RDONLY); |
3622 | 3622 | else |
3623 | 3623 | break_lease(inode, O_WRONLY); |
3624 | 3624 | rc = filemap_fdatawrite(inode->i_mapping); |
3625 | - if (cinode->clientCanCacheRead == 0) { | |
3625 | + if (!CIFS_CACHE_READ(cinode)) { | |
3626 | 3626 | rc = filemap_fdatawait(inode->i_mapping); |
3627 | 3627 | mapping_set_error(inode->i_mapping, rc); |
3628 | 3628 | cifs_invalidate_mapping(inode); |
fs/cifs/inode.c
... | ... | @@ -101,7 +101,7 @@ |
101 | 101 | } |
102 | 102 | |
103 | 103 | /* don't bother with revalidation if we have an oplock */ |
104 | - if (cifs_i->clientCanCacheRead) { | |
104 | + if (CIFS_CACHE_READ(cifs_i)) { | |
105 | 105 | cifs_dbg(FYI, "%s: inode %llu is oplocked\n", |
106 | 106 | __func__, cifs_i->uniqueid); |
107 | 107 | return; |
... | ... | @@ -650,7 +650,7 @@ |
650 | 650 | cifs_dbg(FYI, "Getting info on %s\n", full_path); |
651 | 651 | |
652 | 652 | if ((data == NULL) && (*inode != NULL)) { |
653 | - if (CIFS_I(*inode)->clientCanCacheRead) { | |
653 | + if (CIFS_CACHE_READ(CIFS_I(*inode))) { | |
654 | 654 | cifs_dbg(FYI, "No need to revalidate cached inode sizes\n"); |
655 | 655 | goto cgii_exit; |
656 | 656 | } |
... | ... | @@ -1661,7 +1661,7 @@ |
1661 | 1661 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
1662 | 1662 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1663 | 1663 | |
1664 | - if (cifs_i->clientCanCacheRead) | |
1664 | + if (CIFS_CACHE_READ(cifs_i)) | |
1665 | 1665 | return false; |
1666 | 1666 | |
1667 | 1667 | if (!lookupCacheEnabled) |
... | ... | @@ -1804,7 +1804,7 @@ |
1804 | 1804 | * We need to be sure that all dirty pages are written and the server |
1805 | 1805 | * has actual ctime, mtime and file length. |
1806 | 1806 | */ |
1807 | - if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && | |
1807 | + if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && | |
1808 | 1808 | inode->i_mapping->nrpages != 0) { |
1809 | 1809 | rc = filemap_fdatawait(inode->i_mapping); |
1810 | 1810 | if (rc) { |
fs/cifs/misc.c
... | ... | @@ -546,19 +546,15 @@ |
546 | 546 | oplock &= 0xF; |
547 | 547 | |
548 | 548 | if (oplock == OPLOCK_EXCLUSIVE) { |
549 | - cinode->clientCanCacheAll = true; | |
550 | - cinode->clientCanCacheRead = true; | |
549 | + cinode->oplock = CIFS_CACHE_WRITE_FLG | CIFS_CACHE_READ_FLG; | |
551 | 550 | cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", |
552 | 551 | &cinode->vfs_inode); |
553 | 552 | } else if (oplock == OPLOCK_READ) { |
554 | - cinode->clientCanCacheAll = false; | |
555 | - cinode->clientCanCacheRead = true; | |
553 | + cinode->oplock = CIFS_CACHE_READ_FLG; | |
556 | 554 | cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", |
557 | 555 | &cinode->vfs_inode); |
558 | - } else { | |
559 | - cinode->clientCanCacheAll = false; | |
560 | - cinode->clientCanCacheRead = false; | |
561 | - } | |
556 | + } else | |
557 | + cinode->oplock = 0; | |
562 | 558 | } |
563 | 559 | |
564 | 560 | bool |
fs/cifs/smb1ops.c
... | ... | @@ -700,7 +700,7 @@ |
700 | 700 | struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); |
701 | 701 | cfile->fid.netfid = fid->netfid; |
702 | 702 | cifs_set_oplock_level(cinode, oplock); |
703 | - cinode->can_cache_brlcks = cinode->clientCanCacheAll; | |
703 | + cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); | |
704 | 704 | } |
705 | 705 | |
706 | 706 | static void |
... | ... | @@ -837,7 +837,7 @@ |
837 | 837 | { |
838 | 838 | return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0, |
839 | 839 | LOCKING_ANDX_OPLOCK_RELEASE, false, |
840 | - cinode->clientCanCacheRead ? 1 : 0); | |
840 | + CIFS_CACHE_READ(cinode) ? 1 : 0); | |
841 | 841 | } |
842 | 842 | |
843 | 843 | static int |
fs/cifs/smb2file.c
... | ... | @@ -40,21 +40,21 @@ |
40 | 40 | oplock &= 0xFF; |
41 | 41 | if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) |
42 | 42 | return; |
43 | - if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE || | |
44 | - oplock == SMB2_OPLOCK_LEVEL_BATCH) { | |
45 | - cinode->clientCanCacheAll = true; | |
46 | - cinode->clientCanCacheRead = true; | |
43 | + if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { | |
44 | + cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG | | |
45 | + CIFS_CACHE_HANDLE_FLG; | |
46 | + cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", | |
47 | + &cinode->vfs_inode); | |
48 | + } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { | |
49 | + cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG; | |
47 | 50 | cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", |
48 | 51 | &cinode->vfs_inode); |
49 | 52 | } else if (oplock == SMB2_OPLOCK_LEVEL_II) { |
50 | - cinode->clientCanCacheAll = false; | |
51 | - cinode->clientCanCacheRead = true; | |
53 | + cinode->oplock = CIFS_CACHE_READ_FLG; | |
52 | 54 | cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", |
53 | 55 | &cinode->vfs_inode); |
54 | - } else { | |
55 | - cinode->clientCanCacheAll = false; | |
56 | - cinode->clientCanCacheRead = false; | |
57 | - } | |
56 | + } else | |
57 | + cinode->oplock = 0; | |
58 | 58 | } |
59 | 59 | |
60 | 60 | int |
fs/cifs/smb2misc.c
... | ... | @@ -380,9 +380,9 @@ |
380 | 380 | __le32 |
381 | 381 | smb2_get_lease_state(struct cifsInodeInfo *cinode) |
382 | 382 | { |
383 | - if (cinode->clientCanCacheAll) | |
383 | + if (CIFS_CACHE_WRITE(cinode)) | |
384 | 384 | return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING; |
385 | - else if (cinode->clientCanCacheRead) | |
385 | + else if (CIFS_CACHE_READ(cinode)) | |
386 | 386 | return SMB2_LEASE_READ_CACHING; |
387 | 387 | return 0; |
388 | 388 | } |
... | ... | @@ -576,7 +576,7 @@ |
576 | 576 | cifs_dbg(FYI, "file id match, oplock break\n"); |
577 | 577 | cinode = CIFS_I(cfile->dentry->d_inode); |
578 | 578 | |
579 | - if (!cinode->clientCanCacheAll && | |
579 | + if (!CIFS_CACHE_WRITE(cinode) && | |
580 | 580 | rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE) |
581 | 581 | cfile->oplock_break_cancelled = true; |
582 | 582 | else |
fs/cifs/smb2ops.c
... | ... | @@ -380,7 +380,7 @@ |
380 | 380 | cfile->fid.persistent_fid = fid->persistent_fid; |
381 | 381 | cfile->fid.volatile_fid = fid->volatile_fid; |
382 | 382 | smb2_set_oplock_level(cinode, oplock); |
383 | - cinode->can_cache_brlcks = cinode->clientCanCacheAll; | |
383 | + cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); | |
384 | 384 | } |
385 | 385 | |
386 | 386 | static void |
... | ... | @@ -531,7 +531,7 @@ |
531 | 531 | |
532 | 532 | return SMB2_oplock_break(0, tcon, fid->persistent_fid, |
533 | 533 | fid->volatile_fid, |
534 | - cinode->clientCanCacheRead ? 1 : 0); | |
534 | + CIFS_CACHE_READ(cinode) ? 1 : 0); | |
535 | 535 | } |
536 | 536 | |
537 | 537 | static int |