blob: ca74c1151be932f6d75d1565ecf9f4100207f705 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * fs/cifs/file.c
3 *
4 * vfs operations that deal with files
5 *
6 * Copyright (C) International Business Machines Corp., 2002,2003
7 * Author(s): Steve French (sfrench@us.ibm.com)
8 *
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23#include <linux/fs.h>
24#include <linux/stat.h>
25#include <linux/fcntl.h>
26#include <linux/pagemap.h>
27#include <linux/pagevec.h>
28#include <linux/smp_lock.h>
29#include <asm/div64.h>
30#include "cifsfs.h"
31#include "cifspdu.h"
32#include "cifsglob.h"
33#include "cifsproto.h"
34#include "cifs_unicode.h"
35#include "cifs_debug.h"
36#include "cifs_fs_sb.h"
37
38static inline struct cifsFileInfo *cifs_init_private(
39 struct cifsFileInfo *private_data, struct inode *inode,
40 struct file *file, __u16 netfid)
41{
42 memset(private_data, 0, sizeof(struct cifsFileInfo));
43 private_data->netfid = netfid;
44 private_data->pid = current->tgid;
45 init_MUTEX(&private_data->fh_sem);
46 private_data->pfile = file; /* needed for writepage */
47 private_data->pInode = inode;
48 private_data->invalidHandle = FALSE;
49 private_data->closePend = FALSE;
50
51 return private_data;
52}
53
54static inline int cifs_convert_flags(unsigned int flags)
55{
56 if ((flags & O_ACCMODE) == O_RDONLY)
57 return GENERIC_READ;
58 else if ((flags & O_ACCMODE) == O_WRONLY)
59 return GENERIC_WRITE;
60 else if ((flags & O_ACCMODE) == O_RDWR) {
61 /* GENERIC_ALL is too much permission to request
62 can cause unnecessary access denied on create */
63 /* return GENERIC_ALL; */
64 return (GENERIC_READ | GENERIC_WRITE);
65 }
66
67 return 0x20197;
68}
69
70static inline int cifs_get_disposition(unsigned int flags)
71{
72 if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
73 return FILE_CREATE;
74 else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
75 return FILE_OVERWRITE_IF;
76 else if ((flags & O_CREAT) == O_CREAT)
77 return FILE_OPEN_IF;
78 else
79 return FILE_OPEN;
80}
81
82/* all arguments to this function must be checked for validity in caller */
83static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
84 struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile,
85 struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf,
86 char *full_path, int xid)
87{
88 struct timespec temp;
89 int rc;
90
91 /* want handles we can use to read with first
92 in the list so we do not have to walk the
93 list to search for one in prepare_write */
94 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
95 list_add_tail(&pCifsFile->flist,
96 &pCifsInode->openFileList);
97 } else {
98 list_add(&pCifsFile->flist,
99 &pCifsInode->openFileList);
100 }
101 write_unlock(&GlobalSMBSeslock);
102 write_unlock(&file->f_owner.lock);
103 if (pCifsInode->clientCanCacheRead) {
104 /* we have the inode open somewhere else
105 no need to discard cache data */
106 goto client_can_cache;
107 }
108
109 /* BB need same check in cifs_create too? */
110 /* if not oplocked, invalidate inode pages if mtime or file
111 size changed */
112 temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
113 if (timespec_equal(&file->f_dentry->d_inode->i_mtime, &temp) &&
114 (file->f_dentry->d_inode->i_size ==
115 (loff_t)le64_to_cpu(buf->EndOfFile))) {
116 cFYI(1, ("inode unchanged on server"));
117 } else {
118 if (file->f_dentry->d_inode->i_mapping) {
119 /* BB no need to lock inode until after invalidate
120 since namei code should already have it locked? */
121 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
122 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
123 }
124 cFYI(1, ("invalidating remote inode since open detected it "
125 "changed"));
126 invalidate_remote_inode(file->f_dentry->d_inode);
127 }
128
129client_can_cache:
130 if (pTcon->ses->capabilities & CAP_UNIX)
131 rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
132 full_path, inode->i_sb, xid);
133 else
134 rc = cifs_get_inode_info(&file->f_dentry->d_inode,
135 full_path, buf, inode->i_sb, xid);
136
137 if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
138 pCifsInode->clientCanCacheAll = TRUE;
139 pCifsInode->clientCanCacheRead = TRUE;
140 cFYI(1, ("Exclusive Oplock granted on inode %p",
141 file->f_dentry->d_inode));
142 } else if ((*oplock & 0xF) == OPLOCK_READ)
143 pCifsInode->clientCanCacheRead = TRUE;
144
145 return rc;
146}
147
148int cifs_open(struct inode *inode, struct file *file)
149{
150 int rc = -EACCES;
151 int xid, oplock;
152 struct cifs_sb_info *cifs_sb;
153 struct cifsTconInfo *pTcon;
154 struct cifsFileInfo *pCifsFile;
155 struct cifsInodeInfo *pCifsInode;
156 struct list_head *tmp;
157 char *full_path = NULL;
158 int desiredAccess;
159 int disposition;
160 __u16 netfid;
161 FILE_ALL_INFO *buf = NULL;
162
163 xid = GetXid();
164
165 cifs_sb = CIFS_SB(inode->i_sb);
166 pTcon = cifs_sb->tcon;
167
168 if (file->f_flags & O_CREAT) {
169 /* search inode for this file and fill in file->private_data */
170 pCifsInode = CIFS_I(file->f_dentry->d_inode);
171 read_lock(&GlobalSMBSeslock);
172 list_for_each(tmp, &pCifsInode->openFileList) {
173 pCifsFile = list_entry(tmp, struct cifsFileInfo,
174 flist);
175 if ((pCifsFile->pfile == NULL) &&
176 (pCifsFile->pid == current->tgid)) {
177 /* mode set in cifs_create */
178
179 /* needed for writepage */
180 pCifsFile->pfile = file;
181
182 file->private_data = pCifsFile;
183 break;
184 }
185 }
186 read_unlock(&GlobalSMBSeslock);
187 if (file->private_data != NULL) {
188 rc = 0;
189 FreeXid(xid);
190 return rc;
191 } else {
192 if (file->f_flags & O_EXCL)
193 cERROR(1, ("could not find file instance for "
194 "new file %p ", file));
195 }
196 }
197
198 down(&inode->i_sb->s_vfs_rename_sem);
199 full_path = build_path_from_dentry(file->f_dentry);
200 up(&inode->i_sb->s_vfs_rename_sem);
201 if (full_path == NULL) {
202 FreeXid(xid);
203 return -ENOMEM;
204 }
205
206 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
207 inode, file->f_flags, full_path));
208 desiredAccess = cifs_convert_flags(file->f_flags);
209
210/*********************************************************************
211 * open flag mapping table:
212 *
213 * POSIX Flag CIFS Disposition
214 * ---------- ----------------
215 * O_CREAT FILE_OPEN_IF
216 * O_CREAT | O_EXCL FILE_CREATE
217 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
218 * O_TRUNC FILE_OVERWRITE
219 * none of the above FILE_OPEN
220 *
221 * Note that there is not a direct match between disposition
222 * FILE_SUPERSEDE (ie create whether or not file exists although
223 * O_CREAT | O_TRUNC is similar but truncates the existing
224 * file rather than creating a new file as FILE_SUPERSEDE does
225 * (which uses the attributes / metadata passed in on open call)
226 *?
227 *? O_SYNC is a reasonable match to CIFS writethrough flag
228 *? and the read write flags match reasonably. O_LARGEFILE
229 *? is irrelevant because largefile support is always used
230 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
231 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
232 *********************************************************************/
233
234 disposition = cifs_get_disposition(file->f_flags);
235
236 if (oplockEnabled)
237 oplock = REQ_OPLOCK;
238 else
239 oplock = FALSE;
240
241 /* BB pass O_SYNC flag through on file attributes .. BB */
242
243 /* Also refresh inode by passing in file_info buf returned by SMBOpen
244 and calling get_inode_info with returned buf (at least helps
245 non-Unix server case) */
246
247 /* BB we can not do this if this is the second open of a file
248 and the first handle has writebehind data, we might be
249 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
250 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
251 if (!buf) {
252 rc = -ENOMEM;
253 goto out;
254 }
255 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
256 CREATE_NOT_DIR, &netfid, &oplock, buf,
Steve French737b7582005-04-28 22:41:06 -0700257 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
258 & CIFS_MOUNT_MAP_SPECIAL_CHR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 if (rc) {
260 cFYI(1, ("cifs_open returned 0x%x ", rc));
261 goto out;
262 }
263 file->private_data =
264 kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
265 if (file->private_data == NULL) {
266 rc = -ENOMEM;
267 goto out;
268 }
269 pCifsFile = cifs_init_private(file->private_data, inode, file, netfid);
270 write_lock(&file->f_owner.lock);
271 write_lock(&GlobalSMBSeslock);
272 list_add(&pCifsFile->tlist, &pTcon->openFileList);
273
274 pCifsInode = CIFS_I(file->f_dentry->d_inode);
275 if (pCifsInode) {
276 rc = cifs_open_inode_helper(inode, file, pCifsInode,
277 pCifsFile, pTcon,
278 &oplock, buf, full_path, xid);
279 } else {
280 write_unlock(&GlobalSMBSeslock);
281 write_unlock(&file->f_owner.lock);
282 }
283
284 if (oplock & CIFS_CREATE_ACTION) {
285 /* time to set mode which we can not set earlier due to
286 problems creating new read-only files */
287 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
288 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
289 inode->i_mode,
290 (__u64)-1, (__u64)-1, 0 /* dev */,
Steve French737b7582005-04-28 22:41:06 -0700291 cifs_sb->local_nls,
292 cifs_sb->mnt_cifs_flags &
293 CIFS_MOUNT_MAP_SPECIAL_CHR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 } else {
295 /* BB implement via Windows security descriptors eg
296 CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
297 -1, -1, local_nls);
298 in the meantime could set r/o dos attribute when
299 perms are eg: mode & 0222 == 0 */
300 }
301 }
302
303out:
304 kfree(buf);
305 kfree(full_path);
306 FreeXid(xid);
307 return rc;
308}
309
310/* Try to reaquire byte range locks that were released when session */
311/* to server was lost */
312static int cifs_relock_file(struct cifsFileInfo *cifsFile)
313{
314 int rc = 0;
315
316/* BB list all locks open on this file and relock */
317
318 return rc;
319}
320
321static int cifs_reopen_file(struct inode *inode, struct file *file,
322 int can_flush)
323{
324 int rc = -EACCES;
325 int xid, oplock;
326 struct cifs_sb_info *cifs_sb;
327 struct cifsTconInfo *pTcon;
328 struct cifsFileInfo *pCifsFile;
329 struct cifsInodeInfo *pCifsInode;
330 char *full_path = NULL;
331 int desiredAccess;
332 int disposition = FILE_OPEN;
333 __u16 netfid;
334
335 if (inode == NULL)
336 return -EBADF;
337 if (file->private_data) {
338 pCifsFile = (struct cifsFileInfo *)file->private_data;
339 } else
340 return -EBADF;
341
342 xid = GetXid();
343 down(&pCifsFile->fh_sem);
344 if (pCifsFile->invalidHandle == FALSE) {
345 up(&pCifsFile->fh_sem);
346 FreeXid(xid);
347 return 0;
348 }
349
350 if (file->f_dentry == NULL) {
351 up(&pCifsFile->fh_sem);
352 cFYI(1, ("failed file reopen, no valid name if dentry freed"));
353 FreeXid(xid);
354 return -EBADF;
355 }
356 cifs_sb = CIFS_SB(inode->i_sb);
357 pTcon = cifs_sb->tcon;
358/* can not grab rename sem here because various ops, including
359 those that already have the rename sem can end up causing writepage
360 to get called and if the server was down that means we end up here,
361 and we can never tell if the caller already has the rename_sem */
362 full_path = build_path_from_dentry(file->f_dentry);
363 if (full_path == NULL) {
364 up(&pCifsFile->fh_sem);
365 FreeXid(xid);
366 return -ENOMEM;
367 }
368
369 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
370 inode, file->f_flags,full_path));
371 desiredAccess = cifs_convert_flags(file->f_flags);
372
373 if (oplockEnabled)
374 oplock = REQ_OPLOCK;
375 else
376 oplock = FALSE;
377
378 /* Can not refresh inode by passing in file_info buf to be returned
379 by SMBOpen and then calling get_inode_info with returned buf
380 since file might have write behind data that needs to be flushed
381 and server version of file size can be stale. If we knew for sure
382 that inode was not dirty locally we could do this */
383
384/* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
385 if (buf == 0) {
386 up(&pCifsFile->fh_sem);
387 kfree(full_path);
388 FreeXid(xid);
389 return -ENOMEM;
390 } */
391 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
392 CREATE_NOT_DIR, &netfid, &oplock, NULL,
Steve French737b7582005-04-28 22:41:06 -0700393 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
394 CIFS_MOUNT_MAP_SPECIAL_CHR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 if (rc) {
396 up(&pCifsFile->fh_sem);
397 cFYI(1, ("cifs_open returned 0x%x ", rc));
398 cFYI(1, ("oplock: %d ", oplock));
399 } else {
400 pCifsFile->netfid = netfid;
401 pCifsFile->invalidHandle = FALSE;
402 up(&pCifsFile->fh_sem);
403 pCifsInode = CIFS_I(inode);
404 if (pCifsInode) {
405 if (can_flush) {
406 filemap_fdatawrite(inode->i_mapping);
407 filemap_fdatawait(inode->i_mapping);
408 /* temporarily disable caching while we
409 go to server to get inode info */
410 pCifsInode->clientCanCacheAll = FALSE;
411 pCifsInode->clientCanCacheRead = FALSE;
412 if (pTcon->ses->capabilities & CAP_UNIX)
413 rc = cifs_get_inode_info_unix(&inode,
414 full_path, inode->i_sb, xid);
415 else
416 rc = cifs_get_inode_info(&inode,
417 full_path, NULL, inode->i_sb,
418 xid);
419 } /* else we are writing out data to server already
420 and could deadlock if we tried to flush data, and
421 since we do not know if we have data that would
422 invalidate the current end of file on the server
423 we can not go to the server to get the new inod
424 info */
425 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
426 pCifsInode->clientCanCacheAll = TRUE;
427 pCifsInode->clientCanCacheRead = TRUE;
428 cFYI(1, ("Exclusive Oplock granted on inode %p",
429 file->f_dentry->d_inode));
430 } else if ((oplock & 0xF) == OPLOCK_READ) {
431 pCifsInode->clientCanCacheRead = TRUE;
432 pCifsInode->clientCanCacheAll = FALSE;
433 } else {
434 pCifsInode->clientCanCacheRead = FALSE;
435 pCifsInode->clientCanCacheAll = FALSE;
436 }
437 cifs_relock_file(pCifsFile);
438 }
439 }
440
441 kfree(full_path);
442 FreeXid(xid);
443 return rc;
444}
445
446int cifs_close(struct inode *inode, struct file *file)
447{
448 int rc = 0;
449 int xid;
450 struct cifs_sb_info *cifs_sb;
451 struct cifsTconInfo *pTcon;
452 struct cifsFileInfo *pSMBFile =
453 (struct cifsFileInfo *)file->private_data;
454
455 xid = GetXid();
456
457 cifs_sb = CIFS_SB(inode->i_sb);
458 pTcon = cifs_sb->tcon;
459 if (pSMBFile) {
460 pSMBFile->closePend = TRUE;
461 write_lock(&file->f_owner.lock);
462 if (pTcon) {
463 /* no sense reconnecting to close a file that is
464 already closed */
465 if (pTcon->tidStatus != CifsNeedReconnect) {
466 write_unlock(&file->f_owner.lock);
467 rc = CIFSSMBClose(xid, pTcon,
468 pSMBFile->netfid);
469 write_lock(&file->f_owner.lock);
470 }
471 }
Steve Frenchcbe04762005-04-28 22:41:05 -0700472 write_lock(&GlobalSMBSeslock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 list_del(&pSMBFile->flist);
474 list_del(&pSMBFile->tlist);
Steve Frenchcbe04762005-04-28 22:41:05 -0700475 write_unlock(&GlobalSMBSeslock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 write_unlock(&file->f_owner.lock);
477 kfree(pSMBFile->search_resume_name);
478 kfree(file->private_data);
479 file->private_data = NULL;
480 } else
481 rc = -EBADF;
482
483 if (list_empty(&(CIFS_I(inode)->openFileList))) {
484 cFYI(1, ("closing last open instance for inode %p", inode));
485 /* if the file is not open we do not know if we can cache info
486 on this inode, much less write behind and read ahead */
487 CIFS_I(inode)->clientCanCacheRead = FALSE;
488 CIFS_I(inode)->clientCanCacheAll = FALSE;
489 }
490 if ((rc ==0) && CIFS_I(inode)->write_behind_rc)
491 rc = CIFS_I(inode)->write_behind_rc;
492 FreeXid(xid);
493 return rc;
494}
495
496int cifs_closedir(struct inode *inode, struct file *file)
497{
498 int rc = 0;
499 int xid;
500 struct cifsFileInfo *pCFileStruct =
501 (struct cifsFileInfo *)file->private_data;
502 char *ptmp;
503
504 cFYI(1, ("Closedir inode = 0x%p with ", inode));
505
506 xid = GetXid();
507
508 if (pCFileStruct) {
509 struct cifsTconInfo *pTcon;
510 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_dentry->d_sb);
511
512 pTcon = cifs_sb->tcon;
513
514 cFYI(1, ("Freeing private data in close dir"));
Steve French31ca3bc2005-04-28 22:41:11 -0700515 if ((pCFileStruct->srch_inf.endOfSearch == FALSE) &&
516 (pCFileStruct->invalidHandle == FALSE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 pCFileStruct->invalidHandle = TRUE;
518 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
519 cFYI(1, ("Closing uncompleted readdir with rc %d",
520 rc));
521 /* not much we can do if it fails anyway, ignore rc */
522 rc = 0;
523 }
524 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
525 if (ptmp) {
526 /* BB removeme BB */ cFYI(1, ("freeing smb buf in srch struct in closedir"));
527 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
528 cifs_buf_release(ptmp);
529 }
530 ptmp = pCFileStruct->search_resume_name;
531 if (ptmp) {
532 /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir"));
533 pCFileStruct->search_resume_name = NULL;
534 kfree(ptmp);
535 }
536 kfree(file->private_data);
537 file->private_data = NULL;
538 }
539 /* BB can we lock the filestruct while this is going on? */
540 FreeXid(xid);
541 return rc;
542}
543
544int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
545{
546 int rc, xid;
547 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
548 __u32 numLock = 0;
549 __u32 numUnlock = 0;
550 __u64 length;
551 int wait_flag = FALSE;
552 struct cifs_sb_info *cifs_sb;
553 struct cifsTconInfo *pTcon;
554
555 length = 1 + pfLock->fl_end - pfLock->fl_start;
556 rc = -EACCES;
557 xid = GetXid();
558
559 cFYI(1, ("Lock parm: 0x%x flockflags: "
560 "0x%x flocktype: 0x%x start: %lld end: %lld",
561 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
562 pfLock->fl_end));
563
564 if (pfLock->fl_flags & FL_POSIX)
565 cFYI(1, ("Posix "));
566 if (pfLock->fl_flags & FL_FLOCK)
567 cFYI(1, ("Flock "));
568 if (pfLock->fl_flags & FL_SLEEP) {
569 cFYI(1, ("Blocking lock "));
570 wait_flag = TRUE;
571 }
572 if (pfLock->fl_flags & FL_ACCESS)
573 cFYI(1, ("Process suspended by mandatory locking - "
574 "not implemented yet "));
575 if (pfLock->fl_flags & FL_LEASE)
576 cFYI(1, ("Lease on file - not implemented yet"));
577 if (pfLock->fl_flags &
578 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
579 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
580
581 if (pfLock->fl_type == F_WRLCK) {
582 cFYI(1, ("F_WRLCK "));
583 numLock = 1;
584 } else if (pfLock->fl_type == F_UNLCK) {
585 cFYI(1, ("F_UNLCK "));
586 numUnlock = 1;
587 } else if (pfLock->fl_type == F_RDLCK) {
588 cFYI(1, ("F_RDLCK "));
589 lockType |= LOCKING_ANDX_SHARED_LOCK;
590 numLock = 1;
591 } else if (pfLock->fl_type == F_EXLCK) {
592 cFYI(1, ("F_EXLCK "));
593 numLock = 1;
594 } else if (pfLock->fl_type == F_SHLCK) {
595 cFYI(1, ("F_SHLCK "));
596 lockType |= LOCKING_ANDX_SHARED_LOCK;
597 numLock = 1;
598 } else
599 cFYI(1, ("Unknown type of lock "));
600
601 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
602 pTcon = cifs_sb->tcon;
603
604 if (file->private_data == NULL) {
605 FreeXid(xid);
606 return -EBADF;
607 }
608
609 if (IS_GETLK(cmd)) {
610 rc = CIFSSMBLock(xid, pTcon,
611 ((struct cifsFileInfo *)file->
612 private_data)->netfid,
613 length,
614 pfLock->fl_start, 0, 1, lockType,
615 0 /* wait flag */ );
616 if (rc == 0) {
617 rc = CIFSSMBLock(xid, pTcon,
618 ((struct cifsFileInfo *) file->
619 private_data)->netfid,
620 length,
621 pfLock->fl_start, 1 /* numUnlock */ ,
622 0 /* numLock */ , lockType,
623 0 /* wait flag */ );
624 pfLock->fl_type = F_UNLCK;
625 if (rc != 0)
626 cERROR(1, ("Error unlocking previously locked "
627 "range %d during test of lock ",
628 rc));
629 rc = 0;
630
631 } else {
632 /* if rc == ERR_SHARING_VIOLATION ? */
633 rc = 0; /* do not change lock type to unlock
634 since range in use */
635 }
636
637 FreeXid(xid);
638 return rc;
639 }
640
641 rc = CIFSSMBLock(xid, pTcon,
642 ((struct cifsFileInfo *) file->private_data)->
643 netfid, length,
644 pfLock->fl_start, numUnlock, numLock, lockType,
645 wait_flag);
646 if (rc == 0 && (pfLock->fl_flags & FL_POSIX))
647 posix_lock_file_wait(file, pfLock);
648 FreeXid(xid);
649 return rc;
650}
651
652ssize_t cifs_user_write(struct file *file, const char __user *write_data,
653 size_t write_size, loff_t *poffset)
654{
655 int rc = 0;
656 unsigned int bytes_written = 0;
657 unsigned int total_written;
658 struct cifs_sb_info *cifs_sb;
659 struct cifsTconInfo *pTcon;
660 int xid, long_op;
661 struct cifsFileInfo *open_file;
662
663 if (file->f_dentry == NULL)
664 return -EBADF;
665
666 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
667 if (cifs_sb == NULL)
668 return -EBADF;
669
670 pTcon = cifs_sb->tcon;
671
672 /* cFYI(1,
673 (" write %d bytes to offset %lld of %s", write_size,
674 *poffset, file->f_dentry->d_name.name)); */
675
676 if (file->private_data == NULL)
677 return -EBADF;
678 else
679 open_file = (struct cifsFileInfo *) file->private_data;
680
681 xid = GetXid();
682 if (file->f_dentry->d_inode == NULL) {
683 FreeXid(xid);
684 return -EBADF;
685 }
686
687 if (*poffset > file->f_dentry->d_inode->i_size)
688 long_op = 2; /* writes past end of file can take a long time */
689 else
690 long_op = 1;
691
692 for (total_written = 0; write_size > total_written;
693 total_written += bytes_written) {
694 rc = -EAGAIN;
695 while (rc == -EAGAIN) {
696 if (file->private_data == NULL) {
697 /* file has been closed on us */
698 FreeXid(xid);
699 /* if we have gotten here we have written some data
700 and blocked, and the file has been freed on us while
701 we blocked so return what we managed to write */
702 return total_written;
703 }
704 if (open_file->closePend) {
705 FreeXid(xid);
706 if (total_written)
707 return total_written;
708 else
709 return -EBADF;
710 }
711 if (open_file->invalidHandle) {
712 if ((file->f_dentry == NULL) ||
713 (file->f_dentry->d_inode == NULL)) {
714 FreeXid(xid);
715 return total_written;
716 }
717 /* we could deadlock if we called
718 filemap_fdatawait from here so tell
719 reopen_file not to flush data to server
720 now */
721 rc = cifs_reopen_file(file->f_dentry->d_inode,
722 file, FALSE);
723 if (rc != 0)
724 break;
725 }
726
727 rc = CIFSSMBWrite(xid, pTcon,
728 open_file->netfid,
729 min_t(const int, cifs_sb->wsize,
730 write_size - total_written),
731 *poffset, &bytes_written,
732 NULL, write_data + total_written, long_op);
733 }
734 if (rc || (bytes_written == 0)) {
735 if (total_written)
736 break;
737 else {
738 FreeXid(xid);
739 return rc;
740 }
741 } else
742 *poffset += bytes_written;
743 long_op = FALSE; /* subsequent writes fast -
744 15 seconds is plenty */
745 }
746
747#ifdef CONFIG_CIFS_STATS
748 if (total_written > 0) {
749 atomic_inc(&pTcon->num_writes);
750 spin_lock(&pTcon->stat_lock);
751 pTcon->bytes_written += total_written;
752 spin_unlock(&pTcon->stat_lock);
753 }
754#endif
755
756 /* since the write may have blocked check these pointers again */
757 if (file->f_dentry) {
758 if (file->f_dentry->d_inode) {
759 struct inode *inode = file->f_dentry->d_inode;
760 inode->i_ctime = inode->i_mtime =
761 current_fs_time(inode->i_sb);
762 if (total_written > 0) {
763 if (*poffset > file->f_dentry->d_inode->i_size)
764 i_size_write(file->f_dentry->d_inode,
765 *poffset);
766 }
767 mark_inode_dirty_sync(file->f_dentry->d_inode);
768 }
769 }
770 FreeXid(xid);
771 return total_written;
772}
773
774static ssize_t cifs_write(struct file *file, const char *write_data,
775 size_t write_size, loff_t *poffset)
776{
777 int rc = 0;
778 unsigned int bytes_written = 0;
779 unsigned int total_written;
780 struct cifs_sb_info *cifs_sb;
781 struct cifsTconInfo *pTcon;
782 int xid, long_op;
783 struct cifsFileInfo *open_file;
784
785 if (file->f_dentry == NULL)
786 return -EBADF;
787
788 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
789 if (cifs_sb == NULL)
790 return -EBADF;
791
792 pTcon = cifs_sb->tcon;
793
Steve Frenchd6e04ae2005-06-13 13:24:43 -0500794 cFYI(1,(" write %d bytes to offset %lld of %s", write_size,
795 *poffset, file->f_dentry->d_name.name)); /* BB removeme BB */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796
797 if (file->private_data == NULL)
798 return -EBADF;
799 else
800 open_file = (struct cifsFileInfo *)file->private_data;
801
802 xid = GetXid();
803 if (file->f_dentry->d_inode == NULL) {
804 FreeXid(xid);
805 return -EBADF;
806 }
807
808 if (*poffset > file->f_dentry->d_inode->i_size)
809 long_op = 2; /* writes past end of file can take a long time */
810 else
811 long_op = 1;
812
813 for (total_written = 0; write_size > total_written;
814 total_written += bytes_written) {
815 rc = -EAGAIN;
816 while (rc == -EAGAIN) {
817 if (file->private_data == NULL) {
818 /* file has been closed on us */
819 FreeXid(xid);
820 /* if we have gotten here we have written some data
821 and blocked, and the file has been freed on us
822 while we blocked so return what we managed to
823 write */
824 return total_written;
825 }
826 if (open_file->closePend) {
827 FreeXid(xid);
828 if (total_written)
829 return total_written;
830 else
831 return -EBADF;
832 }
833 if (open_file->invalidHandle) {
834 if ((file->f_dentry == NULL) ||
835 (file->f_dentry->d_inode == NULL)) {
836 FreeXid(xid);
837 return total_written;
838 }
839 /* we could deadlock if we called
840 filemap_fdatawait from here so tell
841 reopen_file not to flush data to
842 server now */
843 rc = cifs_reopen_file(file->f_dentry->d_inode,
844 file, FALSE);
845 if (rc != 0)
846 break;
847 }
Steve Frenchd6e04ae2005-06-13 13:24:43 -0500848#ifdef CIFS_EXPERIMENTAL
849 /* BB FIXME We can not sign across two buffers yet */
850 cERROR(1,("checking signing")); /* BB removeme BB */
851 if(pTcon->ses->server->secMode &
852 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED) == 0)
853 rc = CIFSSMBWrite2(xid, pTcon,
854 open_file->netfid,
855 min_t(const int, cifs_sb->wsize,
856 write_size - total_written),
857 *poffset, &bytes_written,
858 write_data + total_written,
859 long_op);
860 } else
861 /* BB FIXME fixup indentation of line below */
862#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863 rc = CIFSSMBWrite(xid, pTcon,
864 open_file->netfid,
865 min_t(const int, cifs_sb->wsize,
866 write_size - total_written),
867 *poffset, &bytes_written,
868 write_data + total_written, NULL, long_op);
869 }
870 if (rc || (bytes_written == 0)) {
871 if (total_written)
872 break;
873 else {
874 FreeXid(xid);
875 return rc;
876 }
877 } else
878 *poffset += bytes_written;
879 long_op = FALSE; /* subsequent writes fast -
880 15 seconds is plenty */
881 }
882
883#ifdef CONFIG_CIFS_STATS
884 if (total_written > 0) {
885 atomic_inc(&pTcon->num_writes);
886 spin_lock(&pTcon->stat_lock);
887 pTcon->bytes_written += total_written;
888 spin_unlock(&pTcon->stat_lock);
889 }
890#endif
891
892 /* since the write may have blocked check these pointers again */
893 if (file->f_dentry) {
894 if (file->f_dentry->d_inode) {
895 file->f_dentry->d_inode->i_ctime =
896 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
897 if (total_written > 0) {
898 if (*poffset > file->f_dentry->d_inode->i_size)
899 i_size_write(file->f_dentry->d_inode,
900 *poffset);
901 }
902 mark_inode_dirty_sync(file->f_dentry->d_inode);
903 }
904 }
905 FreeXid(xid);
906 return total_written;
907}
908
909static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
910{
911 struct address_space *mapping = page->mapping;
912 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
913 char *write_data;
914 int rc = -EFAULT;
915 int bytes_written = 0;
916 struct cifs_sb_info *cifs_sb;
917 struct cifsTconInfo *pTcon;
918 struct inode *inode;
919 struct cifsInodeInfo *cifsInode;
920 struct cifsFileInfo *open_file = NULL;
921 struct list_head *tmp;
922 struct list_head *tmp1;
923
924 if (!mapping || !mapping->host)
925 return -EFAULT;
926
927 inode = page->mapping->host;
928 cifs_sb = CIFS_SB(inode->i_sb);
929 pTcon = cifs_sb->tcon;
930
931 offset += (loff_t)from;
932 write_data = kmap(page);
933 write_data += from;
934
935 if ((to > PAGE_CACHE_SIZE) || (from > to)) {
936 kunmap(page);
937 return -EIO;
938 }
939
940 /* racing with truncate? */
941 if (offset > mapping->host->i_size) {
942 kunmap(page);
943 return 0; /* don't care */
944 }
945
946 /* check to make sure that we are not extending the file */
947 if (mapping->host->i_size - offset < (loff_t)to)
948 to = (unsigned)(mapping->host->i_size - offset);
949
950 cifsInode = CIFS_I(mapping->host);
951 read_lock(&GlobalSMBSeslock);
952 /* BB we should start at the end */
953 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
954 open_file = list_entry(tmp, struct cifsFileInfo, flist);
955 if (open_file->closePend)
956 continue;
957 /* We check if file is open for writing first */
958 if ((open_file->pfile) &&
959 ((open_file->pfile->f_flags & O_RDWR) ||
960 (open_file->pfile->f_flags & O_WRONLY))) {
961 read_unlock(&GlobalSMBSeslock);
962 bytes_written = cifs_write(open_file->pfile,
963 write_data, to-from,
964 &offset);
965 read_lock(&GlobalSMBSeslock);
966 /* Does mm or vfs already set times? */
967 inode->i_atime =
968 inode->i_mtime = current_fs_time(inode->i_sb);
969 if ((bytes_written > 0) && (offset)) {
970 rc = 0;
971 } else if (bytes_written < 0) {
972 if (rc == -EBADF) {
973 /* have seen a case in which kernel seemed to
974 have closed/freed a file even with writes
975 active so we might as well see if there are
976 other file structs to try for the same
977 inode before giving up */
978 continue;
979 } else
980 rc = bytes_written;
981 }
982 break; /* now that we found a valid file handle and
983 tried to write to it we are done, no sense
984 continuing to loop looking for another */
985 }
986 if (tmp->next == NULL) {
987 cFYI(1, ("File instance %p removed", tmp));
988 break;
989 }
990 }
991 read_unlock(&GlobalSMBSeslock);
992 if (open_file == NULL) {
993 cFYI(1, ("No writeable filehandles for inode"));
994 rc = -EIO;
995 }
996
997 kunmap(page);
998 return rc;
999}
1000
1001#if 0
1002static int cifs_writepages(struct address_space *mapping,
1003 struct writeback_control *wbc)
1004{
1005 int rc = -EFAULT;
1006 int xid;
1007
1008 xid = GetXid();
1009
1010 /* Find contiguous pages then iterate through repeating
1011 call 16K write then Setpageuptodate or if LARGE_WRITE_X
1012 support then send larger writes via kevec so as to eliminate
1013 a memcpy */
1014 FreeXid(xid);
1015 return rc;
1016}
1017#endif
1018
1019static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1020{
1021 int rc = -EFAULT;
1022 int xid;
1023
1024 xid = GetXid();
1025/* BB add check for wbc flags */
1026 page_cache_get(page);
1027 if (!PageUptodate(page)) {
1028 cFYI(1, ("ppw - page not up to date"));
1029 }
1030
1031 rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
1032 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
1033 unlock_page(page);
1034 page_cache_release(page);
1035 FreeXid(xid);
1036 return rc;
1037}
1038
1039static int cifs_commit_write(struct file *file, struct page *page,
1040 unsigned offset, unsigned to)
1041{
1042 int xid;
1043 int rc = 0;
1044 struct inode *inode = page->mapping->host;
1045 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
1046 char *page_data;
1047
1048 xid = GetXid();
1049 cFYI(1, ("commit write for page %p up to position %lld for %d",
1050 page, position, to));
1051 if (position > inode->i_size) {
1052 i_size_write(inode, position);
1053 /* if (file->private_data == NULL) {
1054 rc = -EBADF;
1055 } else {
1056 open_file = (struct cifsFileInfo *)file->private_data;
1057 cifs_sb = CIFS_SB(inode->i_sb);
1058 rc = -EAGAIN;
1059 while (rc == -EAGAIN) {
1060 if ((open_file->invalidHandle) &&
1061 (!open_file->closePend)) {
1062 rc = cifs_reopen_file(
1063 file->f_dentry->d_inode, file);
1064 if (rc != 0)
1065 break;
1066 }
1067 if (!open_file->closePend) {
1068 rc = CIFSSMBSetFileSize(xid,
1069 cifs_sb->tcon, position,
1070 open_file->netfid,
1071 open_file->pid, FALSE);
1072 } else {
1073 rc = -EBADF;
1074 break;
1075 }
1076 }
1077 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1078 } */
1079 }
1080 if (!PageUptodate(page)) {
1081 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
1082 /* can not rely on (or let) writepage write this data */
1083 if (to < offset) {
1084 cFYI(1, ("Illegal offsets, can not copy from %d to %d",
1085 offset, to));
1086 FreeXid(xid);
1087 return rc;
1088 }
1089 /* this is probably better than directly calling
1090 partialpage_write since in this function the file handle is
1091 known which we might as well leverage */
1092 /* BB check if anything else missing out of ppw
1093 such as updating last write time */
1094 page_data = kmap(page);
1095 rc = cifs_write(file, page_data + offset, to-offset,
1096 &position);
1097 if (rc > 0)
1098 rc = 0;
1099 /* else if (rc < 0) should we set writebehind rc? */
1100 kunmap(page);
1101 } else {
1102 set_page_dirty(page);
1103 }
1104
1105 FreeXid(xid);
1106 return rc;
1107}
1108
1109int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1110{
1111 int xid;
1112 int rc = 0;
1113 struct inode *inode = file->f_dentry->d_inode;
1114
1115 xid = GetXid();
1116
1117 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
1118 dentry->d_name.name, datasync));
1119
1120 rc = filemap_fdatawrite(inode->i_mapping);
1121 if (rc == 0)
1122 CIFS_I(inode)->write_behind_rc = 0;
1123 FreeXid(xid);
1124 return rc;
1125}
1126
1127/* static int cifs_sync_page(struct page *page)
1128{
1129 struct address_space *mapping;
1130 struct inode *inode;
1131 unsigned long index = page->index;
1132 unsigned int rpages = 0;
1133 int rc = 0;
1134
1135 cFYI(1, ("sync page %p",page));
1136 mapping = page->mapping;
1137 if (!mapping)
1138 return 0;
1139 inode = mapping->host;
1140 if (!inode)
1141 return 0; */
1142
1143/* fill in rpages then
1144 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1145
1146/* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
1147
1148 if (rc < 0)
1149 return rc;
1150 return 0;
1151} */
1152
1153/*
1154 * As file closes, flush all cached write data for this inode checking
1155 * for write behind errors.
1156 */
1157int cifs_flush(struct file *file)
1158{
1159 struct inode * inode = file->f_dentry->d_inode;
1160 int rc = 0;
1161
1162 /* Rather than do the steps manually:
1163 lock the inode for writing
1164 loop through pages looking for write behind data (dirty pages)
1165 coalesce into contiguous 16K (or smaller) chunks to write to server
1166 send to server (prefer in parallel)
1167 deal with writebehind errors
1168 unlock inode for writing
1169 filemapfdatawrite appears easier for the time being */
1170
1171 rc = filemap_fdatawrite(inode->i_mapping);
1172 if (!rc) /* reset wb rc if we were able to write out dirty pages */
1173 CIFS_I(inode)->write_behind_rc = 0;
1174
1175 cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc));
1176
1177 return rc;
1178}
1179
1180ssize_t cifs_user_read(struct file *file, char __user *read_data,
1181 size_t read_size, loff_t *poffset)
1182{
1183 int rc = -EACCES;
1184 unsigned int bytes_read = 0;
1185 unsigned int total_read = 0;
1186 unsigned int current_read_size;
1187 struct cifs_sb_info *cifs_sb;
1188 struct cifsTconInfo *pTcon;
1189 int xid;
1190 struct cifsFileInfo *open_file;
1191 char *smb_read_data;
1192 char __user *current_offset;
1193 struct smb_com_read_rsp *pSMBr;
1194
1195 xid = GetXid();
1196 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1197 pTcon = cifs_sb->tcon;
1198
1199 if (file->private_data == NULL) {
1200 FreeXid(xid);
1201 return -EBADF;
1202 }
1203 open_file = (struct cifsFileInfo *)file->private_data;
1204
1205 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
1206 cFYI(1, ("attempting read on write only file instance"));
1207 }
1208 for (total_read = 0, current_offset = read_data;
1209 read_size > total_read;
1210 total_read += bytes_read, current_offset += bytes_read) {
1211 current_read_size = min_t(const int, read_size - total_read,
1212 cifs_sb->rsize);
1213 rc = -EAGAIN;
1214 smb_read_data = NULL;
1215 while (rc == -EAGAIN) {
1216 if ((open_file->invalidHandle) &&
1217 (!open_file->closePend)) {
1218 rc = cifs_reopen_file(file->f_dentry->d_inode,
1219 file, TRUE);
1220 if (rc != 0)
1221 break;
1222 }
1223
1224 rc = CIFSSMBRead(xid, pTcon,
1225 open_file->netfid,
1226 current_read_size, *poffset,
1227 &bytes_read, &smb_read_data);
1228
1229 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1230 if (copy_to_user(current_offset,
1231 smb_read_data + 4 /* RFC1001 hdr */
1232 + le16_to_cpu(pSMBr->DataOffset),
1233 bytes_read)) {
1234 rc = -EFAULT;
1235 FreeXid(xid);
1236 return rc;
1237 }
1238 if (smb_read_data) {
1239 cifs_buf_release(smb_read_data);
1240 smb_read_data = NULL;
1241 }
1242 }
1243 if (rc || (bytes_read == 0)) {
1244 if (total_read) {
1245 break;
1246 } else {
1247 FreeXid(xid);
1248 return rc;
1249 }
1250 } else {
1251#ifdef CONFIG_CIFS_STATS
1252 atomic_inc(&pTcon->num_reads);
1253 spin_lock(&pTcon->stat_lock);
1254 pTcon->bytes_read += total_read;
1255 spin_unlock(&pTcon->stat_lock);
1256#endif
1257 *poffset += bytes_read;
1258 }
1259 }
1260 FreeXid(xid);
1261 return total_read;
1262}
1263
1264
1265static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1266 loff_t *poffset)
1267{
1268 int rc = -EACCES;
1269 unsigned int bytes_read = 0;
1270 unsigned int total_read;
1271 unsigned int current_read_size;
1272 struct cifs_sb_info *cifs_sb;
1273 struct cifsTconInfo *pTcon;
1274 int xid;
1275 char *current_offset;
1276 struct cifsFileInfo *open_file;
1277
1278 xid = GetXid();
1279 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1280 pTcon = cifs_sb->tcon;
1281
1282 if (file->private_data == NULL) {
1283 FreeXid(xid);
1284 return -EBADF;
1285 }
1286 open_file = (struct cifsFileInfo *)file->private_data;
1287
1288 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1289 cFYI(1, ("attempting read on write only file instance"));
1290
1291 for (total_read = 0, current_offset = read_data;
1292 read_size > total_read;
1293 total_read += bytes_read, current_offset += bytes_read) {
1294 current_read_size = min_t(const int, read_size - total_read,
1295 cifs_sb->rsize);
1296 rc = -EAGAIN;
1297 while (rc == -EAGAIN) {
1298 if ((open_file->invalidHandle) &&
1299 (!open_file->closePend)) {
1300 rc = cifs_reopen_file(file->f_dentry->d_inode,
1301 file, TRUE);
1302 if (rc != 0)
1303 break;
1304 }
1305
1306 rc = CIFSSMBRead(xid, pTcon,
1307 open_file->netfid,
1308 current_read_size, *poffset,
1309 &bytes_read, &current_offset);
1310 }
1311 if (rc || (bytes_read == 0)) {
1312 if (total_read) {
1313 break;
1314 } else {
1315 FreeXid(xid);
1316 return rc;
1317 }
1318 } else {
1319#ifdef CONFIG_CIFS_STATS
1320 atomic_inc(&pTcon->num_reads);
1321 spin_lock(&pTcon->stat_lock);
1322 pTcon->bytes_read += total_read;
1323 spin_unlock(&pTcon->stat_lock);
1324#endif
1325 *poffset += bytes_read;
1326 }
1327 }
1328 FreeXid(xid);
1329 return total_read;
1330}
1331
1332int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1333{
1334 struct dentry *dentry = file->f_dentry;
1335 int rc, xid;
1336
1337 xid = GetXid();
1338 rc = cifs_revalidate(dentry);
1339 if (rc) {
1340 cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
1341 FreeXid(xid);
1342 return rc;
1343 }
1344 rc = generic_file_mmap(file, vma);
1345 FreeXid(xid);
1346 return rc;
1347}
1348
1349
1350static void cifs_copy_cache_pages(struct address_space *mapping,
1351 struct list_head *pages, int bytes_read, char *data,
1352 struct pagevec *plru_pvec)
1353{
1354 struct page *page;
1355 char *target;
1356
1357 while (bytes_read > 0) {
1358 if (list_empty(pages))
1359 break;
1360
1361 page = list_entry(pages->prev, struct page, lru);
1362 list_del(&page->lru);
1363
1364 if (add_to_page_cache(page, mapping, page->index,
1365 GFP_KERNEL)) {
1366 page_cache_release(page);
1367 cFYI(1, ("Add page cache failed"));
1368 continue;
1369 }
1370
1371 target = kmap_atomic(page,KM_USER0);
1372
1373 if (PAGE_CACHE_SIZE > bytes_read) {
1374 memcpy(target, data, bytes_read);
1375 /* zero the tail end of this partial page */
1376 memset(target + bytes_read, 0,
1377 PAGE_CACHE_SIZE - bytes_read);
1378 bytes_read = 0;
1379 } else {
1380 memcpy(target, data, PAGE_CACHE_SIZE);
1381 bytes_read -= PAGE_CACHE_SIZE;
1382 }
1383 kunmap_atomic(target, KM_USER0);
1384
1385 flush_dcache_page(page);
1386 SetPageUptodate(page);
1387 unlock_page(page);
1388 if (!pagevec_add(plru_pvec, page))
1389 __pagevec_lru_add(plru_pvec);
1390 data += PAGE_CACHE_SIZE;
1391 }
1392 return;
1393}
1394
1395static int cifs_readpages(struct file *file, struct address_space *mapping,
1396 struct list_head *page_list, unsigned num_pages)
1397{
1398 int rc = -EACCES;
1399 int xid;
1400 loff_t offset;
1401 struct page *page;
1402 struct cifs_sb_info *cifs_sb;
1403 struct cifsTconInfo *pTcon;
1404 int bytes_read = 0;
1405 unsigned int read_size,i;
1406 char *smb_read_data = NULL;
1407 struct smb_com_read_rsp *pSMBr;
1408 struct pagevec lru_pvec;
1409 struct cifsFileInfo *open_file;
1410
1411 xid = GetXid();
1412 if (file->private_data == NULL) {
1413 FreeXid(xid);
1414 return -EBADF;
1415 }
1416 open_file = (struct cifsFileInfo *)file->private_data;
1417 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1418 pTcon = cifs_sb->tcon;
1419
1420 pagevec_init(&lru_pvec, 0);
1421
1422 for (i = 0; i < num_pages; ) {
1423 unsigned contig_pages;
1424 struct page *tmp_page;
1425 unsigned long expected_index;
1426
1427 if (list_empty(page_list))
1428 break;
1429
1430 page = list_entry(page_list->prev, struct page, lru);
1431 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1432
1433 /* count adjacent pages that we will read into */
1434 contig_pages = 0;
1435 expected_index =
1436 list_entry(page_list->prev, struct page, lru)->index;
1437 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1438 if (tmp_page->index == expected_index) {
1439 contig_pages++;
1440 expected_index++;
1441 } else
1442 break;
1443 }
1444 if (contig_pages + i > num_pages)
1445 contig_pages = num_pages - i;
1446
1447 /* for reads over a certain size could initiate async
1448 read ahead */
1449
1450 read_size = contig_pages * PAGE_CACHE_SIZE;
1451 /* Read size needs to be in multiples of one page */
1452 read_size = min_t(const unsigned int, read_size,
1453 cifs_sb->rsize & PAGE_CACHE_MASK);
1454
1455 rc = -EAGAIN;
1456 while (rc == -EAGAIN) {
1457 if ((open_file->invalidHandle) &&
1458 (!open_file->closePend)) {
1459 rc = cifs_reopen_file(file->f_dentry->d_inode,
1460 file, TRUE);
1461 if (rc != 0)
1462 break;
1463 }
1464
1465 rc = CIFSSMBRead(xid, pTcon,
1466 open_file->netfid,
1467 read_size, offset,
1468 &bytes_read, &smb_read_data);
1469 /* BB need to check return code here */
1470 if (rc== -EAGAIN) {
1471 if (smb_read_data) {
1472 cifs_buf_release(smb_read_data);
1473 smb_read_data = NULL;
1474 }
1475 }
1476 }
1477 if ((rc < 0) || (smb_read_data == NULL)) {
1478 cFYI(1, ("Read error in readpages: %d", rc));
1479 /* clean up remaing pages off list */
1480 while (!list_empty(page_list) && (i < num_pages)) {
1481 page = list_entry(page_list->prev, struct page,
1482 lru);
1483 list_del(&page->lru);
1484 page_cache_release(page);
1485 }
1486 break;
1487 } else if (bytes_read > 0) {
1488 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1489 cifs_copy_cache_pages(mapping, page_list, bytes_read,
1490 smb_read_data + 4 /* RFC1001 hdr */ +
1491 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1492
1493 i += bytes_read >> PAGE_CACHE_SHIFT;
1494#ifdef CONFIG_CIFS_STATS
1495 atomic_inc(&pTcon->num_reads);
1496 spin_lock(&pTcon->stat_lock);
1497 pTcon->bytes_read += bytes_read;
1498 spin_unlock(&pTcon->stat_lock);
1499#endif
1500 if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1501 i++; /* account for partial page */
1502
1503 /* server copy of file can have smaller size
1504 than client */
1505 /* BB do we need to verify this common case ?
1506 this case is ok - if we are at server EOF
1507 we will hit it on next read */
1508
1509 /* while (!list_empty(page_list) && (i < num_pages)) {
1510 page = list_entry(page_list->prev,
1511 struct page, list);
1512 list_del(&page->list);
1513 page_cache_release(page);
1514 }
1515 break; */
1516 }
1517 } else {
1518 cFYI(1, ("No bytes read (%d) at offset %lld . "
1519 "Cleaning remaining pages from readahead list",
1520 bytes_read, offset));
1521 /* BB turn off caching and do new lookup on
1522 file size at server? */
1523 while (!list_empty(page_list) && (i < num_pages)) {
1524 page = list_entry(page_list->prev, struct page,
1525 lru);
1526 list_del(&page->lru);
1527
1528 /* BB removeme - replace with zero of page? */
1529 page_cache_release(page);
1530 }
1531 break;
1532 }
1533 if (smb_read_data) {
1534 cifs_buf_release(smb_read_data);
1535 smb_read_data = NULL;
1536 }
1537 bytes_read = 0;
1538 }
1539
1540 pagevec_lru_add(&lru_pvec);
1541
1542/* need to free smb_read_data buf before exit */
1543 if (smb_read_data) {
1544 cifs_buf_release(smb_read_data);
1545 smb_read_data = NULL;
1546 }
1547
1548 FreeXid(xid);
1549 return rc;
1550}
1551
1552static int cifs_readpage_worker(struct file *file, struct page *page,
1553 loff_t *poffset)
1554{
1555 char *read_data;
1556 int rc;
1557
1558 page_cache_get(page);
1559 read_data = kmap(page);
1560 /* for reads over a certain size could initiate async read ahead */
1561
1562 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1563
1564 if (rc < 0)
1565 goto io_error;
1566 else
1567 cFYI(1, ("Bytes read %d ",rc));
1568
1569 file->f_dentry->d_inode->i_atime =
1570 current_fs_time(file->f_dentry->d_inode->i_sb);
1571
1572 if (PAGE_CACHE_SIZE > rc)
1573 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);
1574
1575 flush_dcache_page(page);
1576 SetPageUptodate(page);
1577 rc = 0;
1578
1579io_error:
1580 kunmap(page);
1581 page_cache_release(page);
1582 return rc;
1583}
1584
1585static int cifs_readpage(struct file *file, struct page *page)
1586{
1587 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1588 int rc = -EACCES;
1589 int xid;
1590
1591 xid = GetXid();
1592
1593 if (file->private_data == NULL) {
1594 FreeXid(xid);
1595 return -EBADF;
1596 }
1597
1598 cFYI(1, ("readpage %p at offset %d 0x%x\n",
1599 page, (int)offset, (int)offset));
1600
1601 rc = cifs_readpage_worker(file, page, &offset);
1602
1603 unlock_page(page);
1604
1605 FreeXid(xid);
1606 return rc;
1607}
1608
1609/* We do not want to update the file size from server for inodes
1610 open for write - to avoid races with writepage extending
1611 the file - in the future we could consider allowing
1612 refreshing the inode only on increases in the file size
1613 but this is tricky to do without racing with writebehind
1614 page caching in the current Linux kernel design */
1615int is_size_safe_to_change(struct cifsInodeInfo *cifsInode)
1616{
1617 struct list_head *tmp;
1618 struct list_head *tmp1;
1619 struct cifsFileInfo *open_file = NULL;
1620 int rc = TRUE;
1621
1622 if (cifsInode == NULL)
1623 return rc;
1624
1625 read_lock(&GlobalSMBSeslock);
1626 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
1627 open_file = list_entry(tmp, struct cifsFileInfo, flist);
1628 if (open_file == NULL)
1629 break;
1630 if (open_file->closePend)
1631 continue;
1632 /* We check if file is open for writing,
1633 BB we could supplement this with a check to see if file size
1634 changes have been flushed to server - ie inode metadata dirty */
1635 if ((open_file->pfile) &&
1636 ((open_file->pfile->f_flags & O_RDWR) ||
1637 (open_file->pfile->f_flags & O_WRONLY))) {
1638 rc = FALSE;
1639 break;
1640 }
1641 if (tmp->next == NULL) {
1642 cFYI(1, ("File instance %p removed", tmp));
1643 break;
1644 }
1645 }
1646 read_unlock(&GlobalSMBSeslock);
1647 return rc;
1648}
1649
1650
1651static int cifs_prepare_write(struct file *file, struct page *page,
1652 unsigned from, unsigned to)
1653{
1654 int rc = 0;
1655 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1656 cFYI(1, ("prepare write for page %p from %d to %d",page,from,to));
1657 if (!PageUptodate(page)) {
1658 /* if (to - from != PAGE_CACHE_SIZE) {
1659 void *kaddr = kmap_atomic(page, KM_USER0);
1660 memset(kaddr, 0, from);
1661 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1662 flush_dcache_page(page);
1663 kunmap_atomic(kaddr, KM_USER0);
1664 } */
1665 /* If we are writing a full page it will be up to date,
1666 no need to read from the server */
1667 if ((to == PAGE_CACHE_SIZE) && (from == 0))
1668 SetPageUptodate(page);
1669
1670 /* might as well read a page, it is fast enough */
1671 if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
1672 rc = cifs_readpage_worker(file, page, &offset);
1673 } else {
1674 /* should we try using another file handle if there is one -
1675 how would we lock it to prevent close of that handle
1676 racing with this read?
1677 In any case this will be written out by commit_write */
1678 }
1679 }
1680
1681 /* BB should we pass any errors back?
1682 e.g. if we do not have read access to the file */
1683 return 0;
1684}
1685
1686struct address_space_operations cifs_addr_ops = {
1687 .readpage = cifs_readpage,
1688 .readpages = cifs_readpages,
1689 .writepage = cifs_writepage,
1690 .prepare_write = cifs_prepare_write,
1691 .commit_write = cifs_commit_write,
1692 .set_page_dirty = __set_page_dirty_nobuffers,
1693 /* .sync_page = cifs_sync_page, */
1694 /* .direct_IO = */
1695};