CIFS: Replace clientCanCache* bools with an integer
authorPavel Shilovsky <pshilovsky@samba.org>
Thu, 5 Sep 2013 09:01:06 +0000 (13:01 +0400)
committerSteve French <smfrench@gmail.com>
Sun, 8 Sep 2013 22:49:17 +0000 (17:49 -0500)
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>
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/misc.c
fs/cifs/smb1ops.c
fs/cifs/smb2file.c
fs/cifs/smb2misc.c
fs/cifs/smb2ops.c

index d70e551..ab88efe 100644 (file)
@@ -733,7 +733,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 
        written = generic_file_aio_write(iocb, iov, nr_segs, pos);
 
-       if (CIFS_I(inode)->clientCanCacheAll)
+       if (CIFS_CACHE_WRITE(CIFS_I(inode)))
                return written;
 
        rc = filemap_fdatawrite(inode->i_mapping);
@@ -758,7 +758,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
                 * We need to be sure that all dirty pages are written and the
                 * server has the newest file length.
                 */
-               if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
+               if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping &&
                    inode->i_mapping->nrpages != 0) {
                        rc = filemap_fdatawait(inode->i_mapping);
                        if (rc) {
@@ -782,8 +782,10 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
 
 static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
 {
-       /* note that this is called by vfs setlease with i_lock held
-          to protect *lease from going away */
+       /*
+        * Note that this is called by vfs setlease with i_lock held to
+        * protect *lease from going away.
+        */
        struct inode *inode = file_inode(file);
        struct cifsFileInfo *cfile = file->private_data;
 
@@ -791,20 +793,19 @@ static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
                return -EINVAL;
 
        /* check if file is oplocked */
-       if (((arg == F_RDLCK) &&
-               (CIFS_I(inode)->clientCanCacheRead)) ||
-           ((arg == F_WRLCK) &&
-               (CIFS_I(inode)->clientCanCacheAll)))
+       if (((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) ||
+           ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode))))
                return generic_setlease(file, arg, lease);
        else if (tlink_tcon(cfile->tlink)->local_lease &&
-                !CIFS_I(inode)->clientCanCacheRead)
-               /* If the server claims to support oplock on this
-                  file, then we still need to check oplock even
-                  if the local_lease mount option is set, but there
-                  are servers which do not support oplock for which
-                  this mount option may be useful if the user
-                  knows that the file won't be changed on the server
-                  by anyone else */
+                !CIFS_CACHE_READ(CIFS_I(inode)))
+               /*
+                * If the server claims to support oplock on this file, then we
+                * still need to check oplock even if the local_lease mount
+                * option is set, but there are servers which do not support
+                * oplock for which this mount option may be useful if the user
+                * knows that the file won't be changed on the server by anyone
+                * else.
+                */
                return generic_setlease(file, arg, lease);
        else
                return -EAGAIN;
index 92798f7..fe739bd 100644 (file)
@@ -1031,6 +1031,13 @@ cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
 struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
 void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
 
+#define CIFS_CACHE_READ_FLG    1
+#define CIFS_CACHE_HANDLE_FLG  2
+#define CIFS_CACHE_WRITE_FLG   4
+
+#define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG)
+#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG)
+
 /*
  * One of these for each file inode
  */
@@ -1042,8 +1049,7 @@ struct cifsInodeInfo {
        /* BB add in lists for dirty pages i.e. write caching info for oplock */
        struct list_head openFileList;
        __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
-       bool clientCanCacheRead;        /* read oplock */
-       bool clientCanCacheAll;         /* read and writebehind oplock */
+       unsigned int oplock;            /* oplock/lease level we have */
        bool delete_pending;            /* DELETE_ON_CLOSE is set */
        bool invalid_mapping;           /* pagecache is invalid */
        unsigned long time;             /* jiffies of last update of inode */
index 9d0dd95..ad14d3c 100644 (file)
@@ -1524,12 +1524,12 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
                 * read won't conflict with non-overlapted locks due to
                 * pagereading.
                 */
-               if (!CIFS_I(inode)->clientCanCacheAll &&
-                                       CIFS_I(inode)->clientCanCacheRead) {
+               if (!CIFS_CACHE_WRITE(CIFS_I(inode)) &&
+                                       CIFS_CACHE_READ(CIFS_I(inode))) {
                        cifs_invalidate_mapping(inode);
                        cifs_dbg(FYI, "Set no oplock for inode=%p due to mand locks\n",
                                 inode);
-                       CIFS_I(inode)->clientCanCacheRead = false;
+                       CIFS_I(inode)->oplock = 0;
                }
 
                rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length,
@@ -2213,7 +2213,7 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
        cifs_dbg(FYI, "Sync file - name: %s datasync: 0x%x\n",
                 file->f_path.dentry->d_name.name, datasync);
 
-       if (!CIFS_I(inode)->clientCanCacheRead) {
+       if (!CIFS_CACHE_READ(CIFS_I(inode))) {
                rc = cifs_invalidate_mapping(inode);
                if (rc) {
                        cifs_dbg(FYI, "rc: %d during invalidate phase\n", rc);
@@ -2577,7 +2577,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        ssize_t written;
 
-       if (cinode->clientCanCacheAll) {
+       if (CIFS_CACHE_WRITE(cinode)) {
                if (cap_unix(tcon->ses) &&
                (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
                    && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
@@ -2591,7 +2591,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
         * these pages but not on the region from pos to ppos+len-1.
         */
        written = cifs_user_writev(iocb, iov, nr_segs, pos);
-       if (written > 0 && cinode->clientCanCacheRead) {
+       if (written > 0 && CIFS_CACHE_READ(cinode)) {
                /*
                 * Windows 7 server can delay breaking level2 oplock if a write
                 * request comes - break it on the client to prevent reading
@@ -2600,7 +2600,7 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
                cifs_invalidate_mapping(inode);
                cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n",
                         inode);
-               cinode->clientCanCacheRead = false;
+               cinode->oplock = 0;
        }
        return written;
 }
@@ -2957,7 +2957,7 @@ cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
         * on pages affected by this read but not on the region from pos to
         * pos+len-1.
         */
-       if (!cinode->clientCanCacheRead)
+       if (!CIFS_CACHE_READ(cinode))
                return cifs_user_readv(iocb, iov, nr_segs, pos);
 
        if (cap_unix(tcon->ses) &&
@@ -3093,7 +3093,7 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
 
        xid = get_xid();
 
-       if (!CIFS_I(inode)->clientCanCacheRead) {
+       if (!CIFS_CACHE_READ(CIFS_I(inode))) {
                rc = cifs_invalidate_mapping(inode);
                if (rc)
                        return rc;
@@ -3526,7 +3526,7 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
         * is, when the page lies beyond the EOF, or straddles the EOF
         * and the write will cover all of the existing data.
         */
-       if (CIFS_I(mapping->host)->clientCanCacheRead) {
+       if (CIFS_CACHE_READ(CIFS_I(mapping->host))) {
                i_size = i_size_read(mapping->host);
                if (page_start >= i_size ||
                    (offset == 0 && (pos + len) >= i_size)) {
@@ -3609,20 +3609,20 @@ void cifs_oplock_break(struct work_struct *work)
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
        int rc = 0;
 
-       if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead &&
+       if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) &&
                                                cifs_has_mand_locks(cinode)) {
                cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n",
                         inode);
-               cinode->clientCanCacheRead = false;
+               cinode->oplock = 0;
        }
 
        if (inode && S_ISREG(inode->i_mode)) {
-               if (cinode->clientCanCacheRead)
+               if (CIFS_CACHE_READ(cinode))
                        break_lease(inode, O_RDONLY);
                else
                        break_lease(inode, O_WRONLY);
                rc = filemap_fdatawrite(inode->i_mapping);
-               if (cinode->clientCanCacheRead == 0) {
+               if (!CIFS_CACHE_READ(cinode)) {
                        rc = filemap_fdatawait(inode->i_mapping);
                        mapping_set_error(inode->i_mapping, rc);
                        cifs_invalidate_mapping(inode);
index ec0f342..e3bb647 100644 (file)
@@ -101,7 +101,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
        }
 
        /* don't bother with revalidation if we have an oplock */
-       if (cifs_i->clientCanCacheRead) {
+       if (CIFS_CACHE_READ(cifs_i)) {
                cifs_dbg(FYI, "%s: inode %llu is oplocked\n",
                         __func__, cifs_i->uniqueid);
                return;
@@ -650,7 +650,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
        cifs_dbg(FYI, "Getting info on %s\n", full_path);
 
        if ((data == NULL) && (*inode != NULL)) {
-               if (CIFS_I(*inode)->clientCanCacheRead) {
+               if (CIFS_CACHE_READ(CIFS_I(*inode))) {
                        cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
                        goto cgii_exit;
                }
@@ -1661,7 +1661,7 @@ cifs_inode_needs_reval(struct inode *inode)
        struct cifsInodeInfo *cifs_i = CIFS_I(inode);
        struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
 
-       if (cifs_i->clientCanCacheRead)
+       if (CIFS_CACHE_READ(cifs_i))
                return false;
 
        if (!lookupCacheEnabled)
@@ -1804,7 +1804,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
         * We need to be sure that all dirty pages are written and the server
         * has actual ctime, mtime and file length.
         */
-       if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
+       if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping &&
            inode->i_mapping->nrpages != 0) {
                rc = filemap_fdatawait(inode->i_mapping);
                if (rc) {
index 82a2b9f..138a011 100644 (file)
@@ -546,19 +546,15 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
        oplock &= 0xF;
 
        if (oplock == OPLOCK_EXCLUSIVE) {
-               cinode->clientCanCacheAll = true;
-               cinode->clientCanCacheRead = true;
+               cinode->oplock = CIFS_CACHE_WRITE_FLG | CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
                         &cinode->vfs_inode);
        } else if (oplock == OPLOCK_READ) {
-               cinode->clientCanCacheAll = false;
-               cinode->clientCanCacheRead = true;
+               cinode->oplock = CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
                         &cinode->vfs_inode);
-       } else {
-               cinode->clientCanCacheAll = false;
-               cinode->clientCanCacheRead = false;
-       }
+       } else
+               cinode->oplock = 0;
 }
 
 bool
index 8fe19c9..6fd0677 100644 (file)
@@ -700,7 +700,7 @@ cifs_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
        struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
        cfile->fid.netfid = fid->netfid;
        cifs_set_oplock_level(cinode, oplock);
-       cinode->can_cache_brlcks = cinode->clientCanCacheAll;
+       cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
 }
 
 static void
@@ -837,7 +837,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
 {
        return CIFSSMBLock(0, tcon, fid->netfid, current->tgid, 0, 0, 0, 0,
                           LOCKING_ANDX_OPLOCK_RELEASE, false,
-                          cinode->clientCanCacheRead ? 1 : 0);
+                          CIFS_CACHE_READ(cinode) ? 1 : 0);
 }
 
 static int
index 020245d..4564787 100644 (file)
@@ -40,21 +40,21 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
        oplock &= 0xFF;
        if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
                return;
-       if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE ||
-           oplock == SMB2_OPLOCK_LEVEL_BATCH) {
-               cinode->clientCanCacheAll = true;
-               cinode->clientCanCacheRead = true;
+       if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
+               cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG |
+                                CIFS_CACHE_HANDLE_FLG;
+               cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
+                        &cinode->vfs_inode);
+       } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
+               cinode->oplock = CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG;
                cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
                         &cinode->vfs_inode);
        } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
-               cinode->clientCanCacheAll = false;
-               cinode->clientCanCacheRead = true;
+               cinode->oplock = CIFS_CACHE_READ_FLG;
                cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
                         &cinode->vfs_inode);
-       } else {
-               cinode->clientCanCacheAll = false;
-               cinode->clientCanCacheRead = false;
-       }
+       } else
+               cinode->oplock = 0;
 }
 
 int
index 314bd60..8d1a889 100644 (file)
@@ -380,9 +380,9 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb)
 __le32
 smb2_get_lease_state(struct cifsInodeInfo *cinode)
 {
-       if (cinode->clientCanCacheAll)
+       if (CIFS_CACHE_WRITE(cinode))
                return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
-       else if (cinode->clientCanCacheRead)
+       else if (CIFS_CACHE_READ(cinode))
                return SMB2_LEASE_READ_CACHING;
        return 0;
 }
@@ -576,7 +576,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
                                cifs_dbg(FYI, "file id match, oplock break\n");
                                cinode = CIFS_I(cfile->dentry->d_inode);
 
-                               if (!cinode->clientCanCacheAll &&
+                               if (!CIFS_CACHE_WRITE(cinode) &&
                                    rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
                                        cfile->oplock_break_cancelled = true;
                                else
index 91b9e54..96c9d3d 100644 (file)
@@ -380,7 +380,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
        cfile->fid.persistent_fid = fid->persistent_fid;
        cfile->fid.volatile_fid = fid->volatile_fid;
        smb2_set_oplock_level(cinode, oplock);
-       cinode->can_cache_brlcks = cinode->clientCanCacheAll;
+       cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
 }
 
 static void
@@ -531,7 +531,7 @@ smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
 
        return SMB2_oplock_break(0, tcon, fid->persistent_fid,
                                 fid->volatile_fid,
-                                cinode->clientCanCacheRead ? 1 : 0);
+                                CIFS_CACHE_READ(cinode) ? 1 : 0);
 }
 
 static int