static int cifs_setlease(struct file *file, long arg, struct file_lock **lease, void **priv) { /* * 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; if (!(S_ISREG(inode->i_mode))) return -EINVAL; /* Check if file is oplocked if this is request for new lease */ if (arg == F_UNLCK || ((arg == F_RDLCK) && CIFS_CACHE_READ(CIFS_I(inode))) || ((arg == F_WRLCK) && CIFS_CACHE_WRITE(CIFS_I(inode)))) return generic_setlease(file, arg, lease, priv); else if (tlink_tcon(cfile->tlink)->local_lease && !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, priv); else return -EAGAIN; }
static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) { /* * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate * the cached file length */ if (whence != SEEK_SET && whence != SEEK_CUR) { int rc; struct inode *inode = file_inode(file); /* * We need to be sure that all dirty pages are written and the * server has the newest file length. */ if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); if (rc) { mapping_set_error(inode->i_mapping, rc); return rc; } } /* * Some applications poll for the file length in this strange * way so we must seek to end on non-oplocked files by * setting the revalidate time to zero. */ CIFS_I(inode)->time = 0; rc = cifs_revalidate_file_attr(file); if (rc < 0) return (loff_t)rc; } return generic_file_llseek(file, offset, whence); }
__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode) { __le32 lease = 0; if (CIFS_CACHE_WRITE(cinode)) lease |= SMB2_LEASE_WRITE_CACHING; if (CIFS_CACHE_HANDLE(cinode)) lease |= SMB2_LEASE_HANDLE_CACHING; if (CIFS_CACHE_READ(cinode)) lease |= SMB2_LEASE_READ_CACHING; return lease; }
static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) { struct inode *inode = file_inode(iocb->ki_filp); struct cifsInodeInfo *cinode = CIFS_I(inode); ssize_t written; int rc; if (iocb->ki_filp->f_flags & O_DIRECT) { written = cifs_user_writev(iocb, from); if (written > 0 && CIFS_CACHE_READ(cinode)) { cifs_zap_mapping(inode); cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", inode); cinode->oplock = 0; } return written; } written = cifs_get_writer(cinode); if (written) return written; written = generic_file_write_iter(iocb, from); if (CIFS_CACHE_WRITE(CIFS_I(inode))) goto out; rc = filemap_fdatawrite(inode->i_mapping); if (rc) cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n", rc, inode); out: cifs_put_writer(cinode); return written; }