diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index c27d236738fc..faf59529e847 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -575,8 +575,10 @@ reopen_error_exit: | |||
575 | 575 | ||
576 | int cifs_close(struct inode *inode, struct file *file) | 576 | int cifs_close(struct inode *inode, struct file *file) |
577 | { | 577 | { |
578 | cifsFileInfo_put(file->private_data); | 578 | if (file->private_data != NULL) { |
579 | file->private_data = NULL; | 579 | cifsFileInfo_put(file->private_data); |
580 | file->private_data = NULL; | ||
581 | } | ||
580 | 582 | ||
581 | /* return code from the ->release op is always ignored */ | 583 | /* return code from the ->release op is always ignored */ |
582 | return 0; | 584 | return 0; |
@@ -970,6 +972,9 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
970 | total_written += bytes_written) { | 972 | total_written += bytes_written) { |
971 | rc = -EAGAIN; | 973 | rc = -EAGAIN; |
972 | while (rc == -EAGAIN) { | 974 | while (rc == -EAGAIN) { |
975 | struct kvec iov[2]; | ||
976 | unsigned int len; | ||
977 | |||
973 | if (open_file->invalidHandle) { | 978 | if (open_file->invalidHandle) { |
974 | /* we could deadlock if we called | 979 | /* we could deadlock if we called |
975 | filemap_fdatawait from here so tell | 980 | filemap_fdatawait from here so tell |
@@ -979,31 +984,14 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
979 | if (rc != 0) | 984 | if (rc != 0) |
980 | break; | 985 | break; |
981 | } | 986 | } |
982 | if (experimEnabled || (pTcon->ses->server && | 987 | |
983 | ((pTcon->ses->server->secMode & | 988 | len = min((size_t)cifs_sb->wsize, |
984 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 989 | write_size - total_written); |
985 | == 0))) { | 990 | /* iov[0] is reserved for smb header */ |
986 | struct kvec iov[2]; | 991 | iov[1].iov_base = (char *)write_data + total_written; |
987 | unsigned int len; | 992 | iov[1].iov_len = len; |
988 | 993 | rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len, | |
989 | len = min((size_t)cifs_sb->wsize, | 994 | *poffset, &bytes_written, iov, 1, 0); |
990 | write_size - total_written); | ||
991 | /* iov[0] is reserved for smb header */ | ||
992 | iov[1].iov_base = (char *)write_data + | ||
993 | total_written; | ||
994 | iov[1].iov_len = len; | ||
995 | rc = CIFSSMBWrite2(xid, pTcon, | ||
996 | open_file->netfid, len, | ||
997 | *poffset, &bytes_written, | ||
998 | iov, 1, 0); | ||
999 | } else | ||
1000 | rc = CIFSSMBWrite(xid, pTcon, | ||
1001 | open_file->netfid, | ||
1002 | min_t(const int, cifs_sb->wsize, | ||
1003 | write_size - total_written), | ||
1004 | *poffset, &bytes_written, | ||
1005 | write_data + total_written, | ||
1006 | NULL, 0); | ||
1007 | } | 995 | } |
1008 | if (rc || (bytes_written == 0)) { | 996 | if (rc || (bytes_written == 0)) { |
1009 | if (total_written) | 997 | if (total_written) |
@@ -1240,12 +1228,6 @@ static int cifs_writepages(struct address_space *mapping, | |||
1240 | } | 1228 | } |
1241 | 1229 | ||
1242 | tcon = tlink_tcon(open_file->tlink); | 1230 | tcon = tlink_tcon(open_file->tlink); |
1243 | if (!experimEnabled && tcon->ses->server->secMode & | ||
1244 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | ||
1245 | cifsFileInfo_put(open_file); | ||
1246 | kfree(iov); | ||
1247 | return generic_writepages(mapping, wbc); | ||
1248 | } | ||
1249 | cifsFileInfo_put(open_file); | 1231 | cifsFileInfo_put(open_file); |
1250 | 1232 | ||
1251 | xid = GetXid(); | 1233 | xid = GetXid(); |
@@ -1980,6 +1962,24 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1980 | return total_read; | 1962 | return total_read; |
1981 | } | 1963 | } |
1982 | 1964 | ||
1965 | /* | ||
1966 | * If the page is mmap'ed into a process' page tables, then we need to make | ||
1967 | * sure that it doesn't change while being written back. | ||
1968 | */ | ||
1969 | static int | ||
1970 | cifs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
1971 | { | ||
1972 | struct page *page = vmf->page; | ||
1973 | |||
1974 | lock_page(page); | ||
1975 | return VM_FAULT_LOCKED; | ||
1976 | } | ||
1977 | |||
1978 | static struct vm_operations_struct cifs_file_vm_ops = { | ||
1979 | .fault = filemap_fault, | ||
1980 | .page_mkwrite = cifs_page_mkwrite, | ||
1981 | }; | ||
1982 | |||
1983 | int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) | 1983 | int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) |
1984 | { | 1984 | { |
1985 | int rc, xid; | 1985 | int rc, xid; |
@@ -1991,6 +1991,8 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma) | |||
1991 | cifs_invalidate_mapping(inode); | 1991 | cifs_invalidate_mapping(inode); |
1992 | 1992 | ||
1993 | rc = generic_file_mmap(file, vma); | 1993 | rc = generic_file_mmap(file, vma); |
1994 | if (rc == 0) | ||
1995 | vma->vm_ops = &cifs_file_vm_ops; | ||
1994 | FreeXid(xid); | 1996 | FreeXid(xid); |
1995 | return rc; | 1997 | return rc; |
1996 | } | 1998 | } |
@@ -2007,6 +2009,8 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
2007 | return rc; | 2009 | return rc; |
2008 | } | 2010 | } |
2009 | rc = generic_file_mmap(file, vma); | 2011 | rc = generic_file_mmap(file, vma); |
2012 | if (rc == 0) | ||
2013 | vma->vm_ops = &cifs_file_vm_ops; | ||
2010 | FreeXid(xid); | 2014 | FreeXid(xid); |
2011 | return rc; | 2015 | return rc; |
2012 | } | 2016 | } |