[CIFS] Change semaphore to mutex for cifs lock_sem
[safe/jmp/linux-2.6] / fs / cifs / file.c
1 /*
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  *              Jeremy Allison (jra@samba.org)
9  *
10  *   This library is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU Lesser General Public License as published
12  *   by the Free Software Foundation; either version 2.1 of the License, or
13  *   (at your option) any later version.
14  *
15  *   This library is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
18  *   the GNU Lesser General Public License for more details.
19  *
20  *   You should have received a copy of the GNU Lesser General Public License
21  *   along with this library; if not, write to the Free Software
22  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 #include <linux/fs.h>
25 #include <linux/backing-dev.h>
26 #include <linux/stat.h>
27 #include <linux/fcntl.h>
28 #include <linux/pagemap.h>
29 #include <linux/pagevec.h>
30 #include <linux/smp_lock.h>
31 #include <linux/writeback.h>
32 #include <linux/task_io_accounting_ops.h>
33 #include <linux/delay.h>
34 #include <asm/div64.h>
35 #include "cifsfs.h"
36 #include "cifspdu.h"
37 #include "cifsglob.h"
38 #include "cifsproto.h"
39 #include "cifs_unicode.h"
40 #include "cifs_debug.h"
41 #include "cifs_fs_sb.h"
42
43 static inline struct cifsFileInfo *cifs_init_private(
44         struct cifsFileInfo *private_data, struct inode *inode,
45         struct file *file, __u16 netfid)
46 {
47         memset(private_data, 0, sizeof(struct cifsFileInfo));
48         private_data->netfid = netfid;
49         private_data->pid = current->tgid;      
50         init_MUTEX(&private_data->fh_sem);
51         mutex_init(&private_data->lock_mutex);
52         INIT_LIST_HEAD(&private_data->llist);
53         private_data->pfile = file; /* needed for writepage */
54         private_data->pInode = inode;
55         private_data->invalidHandle = FALSE;
56         private_data->closePend = FALSE;
57         /* we have to track num writers to the inode, since writepages
58         does not tell us which handle the write is for so there can
59         be a close (overlapping with write) of the filehandle that
60         cifs_writepages chose to use */
61         atomic_set(&private_data->wrtPending,0); 
62
63         return private_data;
64 }
65
66 static inline int cifs_convert_flags(unsigned int flags)
67 {
68         if ((flags & O_ACCMODE) == O_RDONLY)
69                 return GENERIC_READ;
70         else if ((flags & O_ACCMODE) == O_WRONLY)
71                 return GENERIC_WRITE;
72         else if ((flags & O_ACCMODE) == O_RDWR) {
73                 /* GENERIC_ALL is too much permission to request
74                    can cause unnecessary access denied on create */
75                 /* return GENERIC_ALL; */
76                 return (GENERIC_READ | GENERIC_WRITE);
77         }
78
79         return 0x20197;
80 }
81
82 static inline int cifs_get_disposition(unsigned int flags)
83 {
84         if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
85                 return FILE_CREATE;
86         else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
87                 return FILE_OVERWRITE_IF;
88         else if ((flags & O_CREAT) == O_CREAT)
89                 return FILE_OPEN_IF;
90         else if ((flags & O_TRUNC) == O_TRUNC)
91                 return FILE_OVERWRITE;
92         else
93                 return FILE_OPEN;
94 }
95
96 /* all arguments to this function must be checked for validity in caller */
97 static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
98         struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile,
99         struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf,
100         char *full_path, int xid)
101 {
102         struct timespec temp;
103         int rc;
104
105         /* want handles we can use to read with first
106            in the list so we do not have to walk the
107            list to search for one in prepare_write */
108         if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
109                 list_add_tail(&pCifsFile->flist, 
110                               &pCifsInode->openFileList);
111         } else {
112                 list_add(&pCifsFile->flist,
113                          &pCifsInode->openFileList);
114         }
115         write_unlock(&GlobalSMBSeslock);
116         if (pCifsInode->clientCanCacheRead) {
117                 /* we have the inode open somewhere else
118                    no need to discard cache data */
119                 goto client_can_cache;
120         }
121
122         /* BB need same check in cifs_create too? */
123         /* if not oplocked, invalidate inode pages if mtime or file
124            size changed */
125         temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
126         if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
127                            (file->f_path.dentry->d_inode->i_size ==
128                             (loff_t)le64_to_cpu(buf->EndOfFile))) {
129                 cFYI(1, ("inode unchanged on server"));
130         } else {
131                 if (file->f_path.dentry->d_inode->i_mapping) {
132                 /* BB no need to lock inode until after invalidate
133                    since namei code should already have it locked? */
134                         filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
135                 }
136                 cFYI(1, ("invalidating remote inode since open detected it "
137                          "changed"));
138                 invalidate_remote_inode(file->f_path.dentry->d_inode);
139         }
140
141 client_can_cache:
142         if (pTcon->ses->capabilities & CAP_UNIX)
143                 rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode,
144                         full_path, inode->i_sb, xid);
145         else
146                 rc = cifs_get_inode_info(&file->f_path.dentry->d_inode,
147                         full_path, buf, inode->i_sb, xid);
148
149         if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) {
150                 pCifsInode->clientCanCacheAll = TRUE;
151                 pCifsInode->clientCanCacheRead = TRUE;
152                 cFYI(1, ("Exclusive Oplock granted on inode %p",
153                          file->f_path.dentry->d_inode));
154         } else if ((*oplock & 0xF) == OPLOCK_READ)
155                 pCifsInode->clientCanCacheRead = TRUE;
156
157         return rc;
158 }
159
160 int cifs_open(struct inode *inode, struct file *file)
161 {
162         int rc = -EACCES;
163         int xid, oplock;
164         struct cifs_sb_info *cifs_sb;
165         struct cifsTconInfo *pTcon;
166         struct cifsFileInfo *pCifsFile;
167         struct cifsInodeInfo *pCifsInode;
168         struct list_head *tmp;
169         char *full_path = NULL;
170         int desiredAccess;
171         int disposition;
172         __u16 netfid;
173         FILE_ALL_INFO *buf = NULL;
174
175         xid = GetXid();
176
177         cifs_sb = CIFS_SB(inode->i_sb);
178         pTcon = cifs_sb->tcon;
179
180         if (file->f_flags & O_CREAT) {
181                 /* search inode for this file and fill in file->private_data */
182                 pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
183                 read_lock(&GlobalSMBSeslock);
184                 list_for_each(tmp, &pCifsInode->openFileList) {
185                         pCifsFile = list_entry(tmp, struct cifsFileInfo,
186                                                flist);
187                         if ((pCifsFile->pfile == NULL) &&
188                             (pCifsFile->pid == current->tgid)) {
189                                 /* mode set in cifs_create */
190
191                                 /* needed for writepage */
192                                 pCifsFile->pfile = file;
193                                 
194                                 file->private_data = pCifsFile;
195                                 break;
196                         }
197                 }
198                 read_unlock(&GlobalSMBSeslock);
199                 if (file->private_data != NULL) {
200                         rc = 0;
201                         FreeXid(xid);
202                         return rc;
203                 } else {
204                         if (file->f_flags & O_EXCL)
205                                 cERROR(1, ("could not find file instance for "
206                                            "new file %p", file));
207                 }
208         }
209
210         full_path = build_path_from_dentry(file->f_path.dentry);
211         if (full_path == NULL) {
212                 FreeXid(xid);
213                 return -ENOMEM;
214         }
215
216         cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
217                  inode, file->f_flags, full_path));
218         desiredAccess = cifs_convert_flags(file->f_flags);
219
220 /*********************************************************************
221  *  open flag mapping table:
222  *  
223  *      POSIX Flag            CIFS Disposition
224  *      ----------            ---------------- 
225  *      O_CREAT               FILE_OPEN_IF
226  *      O_CREAT | O_EXCL      FILE_CREATE
227  *      O_CREAT | O_TRUNC     FILE_OVERWRITE_IF
228  *      O_TRUNC               FILE_OVERWRITE
229  *      none of the above     FILE_OPEN
230  *
231  *      Note that there is not a direct match between disposition
232  *      FILE_SUPERSEDE (ie create whether or not file exists although 
233  *      O_CREAT | O_TRUNC is similar but truncates the existing
234  *      file rather than creating a new file as FILE_SUPERSEDE does
235  *      (which uses the attributes / metadata passed in on open call)
236  *?
237  *?  O_SYNC is a reasonable match to CIFS writethrough flag  
238  *?  and the read write flags match reasonably.  O_LARGEFILE
239  *?  is irrelevant because largefile support is always used
240  *?  by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
241  *       O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
242  *********************************************************************/
243
244         disposition = cifs_get_disposition(file->f_flags);
245
246         if (oplockEnabled)
247                 oplock = REQ_OPLOCK;
248         else
249                 oplock = FALSE;
250
251         /* BB pass O_SYNC flag through on file attributes .. BB */
252
253         /* Also refresh inode by passing in file_info buf returned by SMBOpen
254            and calling get_inode_info with returned buf (at least helps
255            non-Unix server case) */
256
257         /* BB we can not do this if this is the second open of a file 
258            and the first handle has writebehind data, we might be 
259            able to simply do a filemap_fdatawrite/filemap_fdatawait first */
260         buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
261         if (!buf) {
262                 rc = -ENOMEM;
263                 goto out;
264         }
265
266         if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
267                 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 
268                          desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
269                          cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
270                                  & CIFS_MOUNT_MAP_SPECIAL_CHR);
271         else
272                 rc = -EIO; /* no NT SMB support fall into legacy open below */
273
274         if (rc == -EIO) {
275                 /* Old server, try legacy style OpenX */
276                 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
277                         desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
278                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
279                                 & CIFS_MOUNT_MAP_SPECIAL_CHR);
280         }
281         if (rc) {
282                 cFYI(1, ("cifs_open returned 0x%x", rc));
283                 goto out;
284         }
285         file->private_data =
286                 kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
287         if (file->private_data == NULL) {
288                 rc = -ENOMEM;
289                 goto out;
290         }
291         pCifsFile = cifs_init_private(file->private_data, inode, file, netfid);
292         write_lock(&GlobalSMBSeslock);
293         list_add(&pCifsFile->tlist, &pTcon->openFileList);
294
295         pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
296         if (pCifsInode) {
297                 rc = cifs_open_inode_helper(inode, file, pCifsInode,
298                                             pCifsFile, pTcon,
299                                             &oplock, buf, full_path, xid);
300         } else {
301                 write_unlock(&GlobalSMBSeslock);
302         }
303
304         if (oplock & CIFS_CREATE_ACTION) {           
305                 /* time to set mode which we can not set earlier due to
306                    problems creating new read-only files */
307                 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
308                         CIFSSMBUnixSetPerms(xid, pTcon, full_path,
309                                             inode->i_mode,
310                                             (__u64)-1, (__u64)-1, 0 /* dev */,
311                                             cifs_sb->local_nls,
312                                             cifs_sb->mnt_cifs_flags & 
313                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
314                 } else {
315                         /* BB implement via Windows security descriptors eg
316                            CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
317                                               -1, -1, local_nls);
318                            in the meantime could set r/o dos attribute when
319                            perms are eg: mode & 0222 == 0 */
320                 }
321         }
322
323 out:
324         kfree(buf);
325         kfree(full_path);
326         FreeXid(xid);
327         return rc;
328 }
329
330 /* Try to reacquire byte range locks that were released when session */
331 /* to server was lost */
332 static int cifs_relock_file(struct cifsFileInfo *cifsFile)
333 {
334         int rc = 0;
335
336 /* BB list all locks open on this file and relock */
337
338         return rc;
339 }
340
341 static int cifs_reopen_file(struct file *file, int can_flush)
342 {
343         int rc = -EACCES;
344         int xid, oplock;
345         struct cifs_sb_info *cifs_sb;
346         struct cifsTconInfo *pTcon;
347         struct cifsFileInfo *pCifsFile;
348         struct cifsInodeInfo *pCifsInode;
349         struct inode * inode;
350         char *full_path = NULL;
351         int desiredAccess;
352         int disposition = FILE_OPEN;
353         __u16 netfid;
354
355         if (file->private_data) {
356                 pCifsFile = (struct cifsFileInfo *)file->private_data;
357         } else
358                 return -EBADF;
359
360         xid = GetXid();
361         down(&pCifsFile->fh_sem);
362         if (pCifsFile->invalidHandle == FALSE) {
363                 up(&pCifsFile->fh_sem);
364                 FreeXid(xid);
365                 return 0;
366         }
367
368         if (file->f_path.dentry == NULL) {
369                 cERROR(1, ("no valid name if dentry freed"));
370                 dump_stack();
371                 rc = -EBADF;
372                 goto reopen_error_exit;
373         }
374
375         inode = file->f_path.dentry->d_inode;
376         if(inode == NULL) {
377                 cERROR(1, ("inode not valid"));
378                 dump_stack();
379                 rc = -EBADF;
380                 goto reopen_error_exit;
381         }
382                 
383         cifs_sb = CIFS_SB(inode->i_sb);
384         pTcon = cifs_sb->tcon;
385
386 /* can not grab rename sem here because various ops, including
387    those that already have the rename sem can end up causing writepage
388    to get called and if the server was down that means we end up here,
389    and we can never tell if the caller already has the rename_sem */
390         full_path = build_path_from_dentry(file->f_path.dentry);
391         if (full_path == NULL) {
392                 rc = -ENOMEM;
393 reopen_error_exit:
394                 up(&pCifsFile->fh_sem);
395                 FreeXid(xid);
396                 return rc;
397         }
398
399         cFYI(1, ("inode = 0x%p file flags 0x%x for %s",
400                  inode, file->f_flags,full_path));
401         desiredAccess = cifs_convert_flags(file->f_flags);
402
403         if (oplockEnabled)
404                 oplock = REQ_OPLOCK;
405         else
406                 oplock = FALSE;
407
408         /* Can not refresh inode by passing in file_info buf to be returned
409            by SMBOpen and then calling get_inode_info with returned buf 
410            since file might have write behind data that needs to be flushed 
411            and server version of file size can be stale. If we knew for sure
412            that inode was not dirty locally we could do this */
413
414         rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
415                          CREATE_NOT_DIR, &netfid, &oplock, NULL,
416                          cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 
417                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
418         if (rc) {
419                 up(&pCifsFile->fh_sem);
420                 cFYI(1, ("cifs_open returned 0x%x", rc));
421                 cFYI(1, ("oplock: %d", oplock));
422         } else {
423                 pCifsFile->netfid = netfid;
424                 pCifsFile->invalidHandle = FALSE;
425                 up(&pCifsFile->fh_sem);
426                 pCifsInode = CIFS_I(inode);
427                 if (pCifsInode) {
428                         if (can_flush) {
429                                 filemap_write_and_wait(inode->i_mapping);
430                         /* temporarily disable caching while we
431                            go to server to get inode info */
432                                 pCifsInode->clientCanCacheAll = FALSE;
433                                 pCifsInode->clientCanCacheRead = FALSE;
434                                 if (pTcon->ses->capabilities & CAP_UNIX)
435                                         rc = cifs_get_inode_info_unix(&inode,
436                                                 full_path, inode->i_sb, xid);
437                                 else
438                                         rc = cifs_get_inode_info(&inode,
439                                                 full_path, NULL, inode->i_sb,
440                                                 xid);
441                         } /* else we are writing out data to server already
442                              and could deadlock if we tried to flush data, and
443                              since we do not know if we have data that would
444                              invalidate the current end of file on the server
445                              we can not go to the server to get the new inod
446                              info */
447                         if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
448                                 pCifsInode->clientCanCacheAll = TRUE;
449                                 pCifsInode->clientCanCacheRead = TRUE;
450                                 cFYI(1, ("Exclusive Oplock granted on inode %p",
451                                          file->f_path.dentry->d_inode));
452                         } else if ((oplock & 0xF) == OPLOCK_READ) {
453                                 pCifsInode->clientCanCacheRead = TRUE;
454                                 pCifsInode->clientCanCacheAll = FALSE;
455                         } else {
456                                 pCifsInode->clientCanCacheRead = FALSE;
457                                 pCifsInode->clientCanCacheAll = FALSE;
458                         }
459                         cifs_relock_file(pCifsFile);
460                 }
461         }
462
463         kfree(full_path);
464         FreeXid(xid);
465         return rc;
466 }
467
468 int cifs_close(struct inode *inode, struct file *file)
469 {
470         int rc = 0;
471         int xid;
472         struct cifs_sb_info *cifs_sb;
473         struct cifsTconInfo *pTcon;
474         struct cifsFileInfo *pSMBFile =
475                 (struct cifsFileInfo *)file->private_data;
476
477         xid = GetXid();
478
479         cifs_sb = CIFS_SB(inode->i_sb);
480         pTcon = cifs_sb->tcon;
481         if (pSMBFile) {
482                 struct cifsLockInfo *li, *tmp;
483
484                 pSMBFile->closePend = TRUE;
485                 if (pTcon) {
486                         /* no sense reconnecting to close a file that is
487                            already closed */
488                         if (pTcon->tidStatus != CifsNeedReconnect) {
489                                 int timeout = 2;
490                                 while((atomic_read(&pSMBFile->wrtPending) != 0)
491                                          && (timeout < 1000) ) {
492                                         /* Give write a better chance to get to
493                                         server ahead of the close.  We do not
494                                         want to add a wait_q here as it would
495                                         increase the memory utilization as
496                                         the struct would be in each open file,
497                                         but this should give enough time to 
498                                         clear the socket */
499 #ifdef CONFIG_CIFS_DEBUG2
500                                         cFYI(1,("close delay, write pending"));
501 #endif /* DEBUG2 */
502                                         msleep(timeout);
503                                         timeout *= 4;
504                                 }
505                                 if(atomic_read(&pSMBFile->wrtPending))
506                                         cERROR(1,("close with pending writes"));
507                                 rc = CIFSSMBClose(xid, pTcon,
508                                                   pSMBFile->netfid);
509                         }
510                 }
511
512                 /* Delete any outstanding lock records.
513                    We'll lose them when the file is closed anyway. */
514                 mutex_lock(&pSMBFile->lock_mutex);
515                 list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) {
516                         list_del(&li->llist);
517                         kfree(li);
518                 }
519                 mutex_unlock(&pSMBFile->lock_mutex);
520
521                 write_lock(&GlobalSMBSeslock);
522                 list_del(&pSMBFile->flist);
523                 list_del(&pSMBFile->tlist);
524                 write_unlock(&GlobalSMBSeslock);
525                 kfree(pSMBFile->search_resume_name);
526                 kfree(file->private_data);
527                 file->private_data = NULL;
528         } else
529                 rc = -EBADF;
530
531         if (list_empty(&(CIFS_I(inode)->openFileList))) {
532                 cFYI(1, ("closing last open instance for inode %p", inode));
533                 /* if the file is not open we do not know if we can cache info
534                    on this inode, much less write behind and read ahead */
535                 CIFS_I(inode)->clientCanCacheRead = FALSE;
536                 CIFS_I(inode)->clientCanCacheAll  = FALSE;
537         }
538         if ((rc ==0) && CIFS_I(inode)->write_behind_rc)
539                 rc = CIFS_I(inode)->write_behind_rc;
540         FreeXid(xid);
541         return rc;
542 }
543
544 int cifs_closedir(struct inode *inode, struct file *file)
545 {
546         int rc = 0;
547         int xid;
548         struct cifsFileInfo *pCFileStruct =
549             (struct cifsFileInfo *)file->private_data;
550         char *ptmp;
551
552         cFYI(1, ("Closedir inode = 0x%p", inode));
553
554         xid = GetXid();
555
556         if (pCFileStruct) {
557                 struct cifsTconInfo *pTcon;
558                 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
559
560                 pTcon = cifs_sb->tcon;
561
562                 cFYI(1, ("Freeing private data in close dir"));
563                 if ((pCFileStruct->srch_inf.endOfSearch == FALSE) &&
564                    (pCFileStruct->invalidHandle == FALSE)) {
565                         pCFileStruct->invalidHandle = TRUE;
566                         rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
567                         cFYI(1, ("Closing uncompleted readdir with rc %d",
568                                  rc));
569                         /* not much we can do if it fails anyway, ignore rc */
570                         rc = 0;
571                 }
572                 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
573                 if (ptmp) {
574                         cFYI(1, ("closedir free smb buf in srch struct"));
575                         pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
576                         if(pCFileStruct->srch_inf.smallBuf)
577                                 cifs_small_buf_release(ptmp);
578                         else
579                                 cifs_buf_release(ptmp);
580                 }
581                 ptmp = pCFileStruct->search_resume_name;
582                 if (ptmp) {
583                         cFYI(1, ("closedir free resume name"));
584                         pCFileStruct->search_resume_name = NULL;
585                         kfree(ptmp);
586                 }
587                 kfree(file->private_data);
588                 file->private_data = NULL;
589         }
590         /* BB can we lock the filestruct while this is going on? */
591         FreeXid(xid);
592         return rc;
593 }
594
595 static int store_file_lock(struct cifsFileInfo *fid, __u64 len,
596                                 __u64 offset, __u8 lockType)
597 {
598         struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
599         if (li == NULL)
600                 return -ENOMEM;
601         li->offset = offset;
602         li->length = len;
603         li->type = lockType;
604         mutex_lock(&fid->lock_mutex);
605         list_add(&li->llist, &fid->llist);
606         mutex_unlock(&fid->lock_mutex);
607         return 0;
608 }
609
610 int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
611 {
612         int rc, xid;
613         __u32 numLock = 0;
614         __u32 numUnlock = 0;
615         __u64 length;
616         int wait_flag = FALSE;
617         struct cifs_sb_info *cifs_sb;
618         struct cifsTconInfo *pTcon;
619         __u16 netfid;
620         __u8 lockType = LOCKING_ANDX_LARGE_FILES;
621         int posix_locking;
622
623         length = 1 + pfLock->fl_end - pfLock->fl_start;
624         rc = -EACCES;
625         xid = GetXid();
626
627         cFYI(1, ("Lock parm: 0x%x flockflags: "
628                  "0x%x flocktype: 0x%x start: %lld end: %lld",
629                 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
630                 pfLock->fl_end));
631
632         if (pfLock->fl_flags & FL_POSIX)
633                 cFYI(1, ("Posix"));
634         if (pfLock->fl_flags & FL_FLOCK)
635                 cFYI(1, ("Flock"));
636         if (pfLock->fl_flags & FL_SLEEP) {
637                 cFYI(1, ("Blocking lock"));
638                 wait_flag = TRUE;
639         }
640         if (pfLock->fl_flags & FL_ACCESS)
641                 cFYI(1, ("Process suspended by mandatory locking - "
642                          "not implemented yet"));
643         if (pfLock->fl_flags & FL_LEASE)
644                 cFYI(1, ("Lease on file - not implemented yet"));
645         if (pfLock->fl_flags & 
646             (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
647                 cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags));
648
649         if (pfLock->fl_type == F_WRLCK) {
650                 cFYI(1, ("F_WRLCK "));
651                 numLock = 1;
652         } else if (pfLock->fl_type == F_UNLCK) {
653                 cFYI(1, ("F_UNLCK"));
654                 numUnlock = 1;
655                 /* Check if unlock includes more than
656                 one lock range */
657         } else if (pfLock->fl_type == F_RDLCK) {
658                 cFYI(1, ("F_RDLCK"));
659                 lockType |= LOCKING_ANDX_SHARED_LOCK;
660                 numLock = 1;
661         } else if (pfLock->fl_type == F_EXLCK) {
662                 cFYI(1, ("F_EXLCK"));
663                 numLock = 1;
664         } else if (pfLock->fl_type == F_SHLCK) {
665                 cFYI(1, ("F_SHLCK"));
666                 lockType |= LOCKING_ANDX_SHARED_LOCK;
667                 numLock = 1;
668         } else
669                 cFYI(1, ("Unknown type of lock"));
670
671         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
672         pTcon = cifs_sb->tcon;
673
674         if (file->private_data == NULL) {
675                 FreeXid(xid);
676                 return -EBADF;
677         }
678         netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
679
680         posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
681                         (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability));
682
683         /* BB add code here to normalize offset and length to
684         account for negative length which we can not accept over the
685         wire */
686         if (IS_GETLK(cmd)) {
687                 if(posix_locking) {
688                         int posix_lock_type;
689                         if(lockType & LOCKING_ANDX_SHARED_LOCK)
690                                 posix_lock_type = CIFS_RDLCK;
691                         else
692                                 posix_lock_type = CIFS_WRLCK;
693                         rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
694                                         length, pfLock,
695                                         posix_lock_type, wait_flag);
696                         FreeXid(xid);
697                         return rc;
698                 }
699
700                 /* BB we could chain these into one lock request BB */
701                 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
702                                  0, 1, lockType, 0 /* wait flag */ );
703                 if (rc == 0) {
704                         rc = CIFSSMBLock(xid, pTcon, netfid, length, 
705                                          pfLock->fl_start, 1 /* numUnlock */ ,
706                                          0 /* numLock */ , lockType,
707                                          0 /* wait flag */ );
708                         pfLock->fl_type = F_UNLCK;
709                         if (rc != 0)
710                                 cERROR(1, ("Error unlocking previously locked "
711                                            "range %d during test of lock", rc));
712                         rc = 0;
713
714                 } else {
715                         /* if rc == ERR_SHARING_VIOLATION ? */
716                         rc = 0; /* do not change lock type to unlock
717                                    since range in use */
718                 }
719
720                 FreeXid(xid);
721                 return rc;
722         }
723
724         if (!numLock && !numUnlock) {
725                 /* if no lock or unlock then nothing
726                 to do since we do not know what it is */
727                 FreeXid(xid);
728                 return -EOPNOTSUPP;
729         }
730
731         if (posix_locking) {
732                 int posix_lock_type;
733                 if(lockType & LOCKING_ANDX_SHARED_LOCK)
734                         posix_lock_type = CIFS_RDLCK;
735                 else
736                         posix_lock_type = CIFS_WRLCK;
737                 
738                 if(numUnlock == 1)
739                         posix_lock_type = CIFS_UNLCK;
740
741                 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
742                                       length, pfLock,
743                                       posix_lock_type, wait_flag);
744         } else {
745                 struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data;
746
747                 if (numLock) {
748                         rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
749                                         0, numLock, lockType, wait_flag);
750
751                         if (rc == 0) {
752                                 /* For Windows locks we must store them. */
753                                 rc = store_file_lock(fid, length,
754                                                 pfLock->fl_start, lockType);
755                         }
756                 } else if (numUnlock) {
757                         /* For each stored lock that this unlock overlaps
758                            completely, unlock it. */
759                         int stored_rc = 0;
760                         struct cifsLockInfo *li, *tmp;
761
762                         rc = 0;
763                         mutex_lock(&fid->lock_mutex);
764                         list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
765                                 if (pfLock->fl_start <= li->offset &&
766                                                 length >= li->length) {
767                                         stored_rc = CIFSSMBLock(xid, pTcon, netfid,
768                                                         li->length, li->offset,
769                                                         1, 0, li->type, FALSE);
770                                         if (stored_rc)
771                                                 rc = stored_rc;
772
773                                         list_del(&li->llist);
774                                         kfree(li);
775                                 }
776                         }
777                         mutex_unlock(&fid->lock_mutex);
778                 }
779         }
780
781         if (pfLock->fl_flags & FL_POSIX)
782                 posix_lock_file_wait(file, pfLock);
783         FreeXid(xid);
784         return rc;
785 }
786
787 ssize_t cifs_user_write(struct file *file, const char __user *write_data,
788         size_t write_size, loff_t *poffset)
789 {
790         int rc = 0;
791         unsigned int bytes_written = 0;
792         unsigned int total_written;
793         struct cifs_sb_info *cifs_sb;
794         struct cifsTconInfo *pTcon;
795         int xid, long_op;
796         struct cifsFileInfo *open_file;
797
798         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
799
800         pTcon = cifs_sb->tcon;
801
802         /* cFYI(1,
803            (" write %d bytes to offset %lld of %s", write_size,
804            *poffset, file->f_path.dentry->d_name.name)); */
805
806         if (file->private_data == NULL)
807                 return -EBADF;
808         open_file = (struct cifsFileInfo *) file->private_data;
809         
810         xid = GetXid();
811
812         if (*poffset > file->f_path.dentry->d_inode->i_size)
813                 long_op = 2; /* writes past end of file can take a long time */
814         else
815                 long_op = 1;
816
817         for (total_written = 0; write_size > total_written;
818              total_written += bytes_written) {
819                 rc = -EAGAIN;
820                 while (rc == -EAGAIN) {
821                         if (file->private_data == NULL) {
822                                 /* file has been closed on us */
823                                 FreeXid(xid);
824                         /* if we have gotten here we have written some data
825                            and blocked, and the file has been freed on us while
826                            we blocked so return what we managed to write */
827                                 return total_written;
828                         } 
829                         if (open_file->closePend) {
830                                 FreeXid(xid);
831                                 if (total_written)
832                                         return total_written;
833                                 else
834                                         return -EBADF;
835                         }
836                         if (open_file->invalidHandle) {
837                                 /* we could deadlock if we called
838                                    filemap_fdatawait from here so tell
839                                    reopen_file not to flush data to server
840                                    now */
841                                 rc = cifs_reopen_file(file, FALSE);
842                                 if (rc != 0)
843                                         break;
844                         }
845
846                         rc = CIFSSMBWrite(xid, pTcon,
847                                 open_file->netfid,
848                                 min_t(const int, cifs_sb->wsize,
849                                       write_size - total_written),
850                                 *poffset, &bytes_written,
851                                 NULL, write_data + total_written, long_op);
852                 }
853                 if (rc || (bytes_written == 0)) {
854                         if (total_written)
855                                 break;
856                         else {
857                                 FreeXid(xid);
858                                 return rc;
859                         }
860                 } else
861                         *poffset += bytes_written;
862                 long_op = FALSE; /* subsequent writes fast -
863                                     15 seconds is plenty */
864         }
865
866         cifs_stats_bytes_written(pTcon, total_written);
867
868         /* since the write may have blocked check these pointers again */
869         if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
870                 struct inode *inode = file->f_path.dentry->d_inode;
871 /* Do not update local mtime - server will set its actual value on write                
872  *              inode->i_ctime = inode->i_mtime = 
873  *                      current_fs_time(inode->i_sb);*/
874                 if (total_written > 0) {
875                         spin_lock(&inode->i_lock);
876                         if (*poffset > file->f_path.dentry->d_inode->i_size)
877                                 i_size_write(file->f_path.dentry->d_inode,
878                                         *poffset);
879                         spin_unlock(&inode->i_lock);
880                 }
881                 mark_inode_dirty_sync(file->f_path.dentry->d_inode);    
882         }
883         FreeXid(xid);
884         return total_written;
885 }
886
887 static ssize_t cifs_write(struct file *file, const char *write_data,
888         size_t write_size, loff_t *poffset)
889 {
890         int rc = 0;
891         unsigned int bytes_written = 0;
892         unsigned int total_written;
893         struct cifs_sb_info *cifs_sb;
894         struct cifsTconInfo *pTcon;
895         int xid, long_op;
896         struct cifsFileInfo *open_file;
897
898         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
899
900         pTcon = cifs_sb->tcon;
901
902         cFYI(1,("write %zd bytes to offset %lld of %s", write_size,
903            *poffset, file->f_path.dentry->d_name.name));
904
905         if (file->private_data == NULL)
906                 return -EBADF;
907         open_file = (struct cifsFileInfo *)file->private_data;
908         
909         xid = GetXid();
910
911         if (*poffset > file->f_path.dentry->d_inode->i_size)
912                 long_op = 2; /* writes past end of file can take a long time */
913         else
914                 long_op = 1;
915
916         for (total_written = 0; write_size > total_written;
917              total_written += bytes_written) {
918                 rc = -EAGAIN;
919                 while (rc == -EAGAIN) {
920                         if (file->private_data == NULL) {
921                                 /* file has been closed on us */
922                                 FreeXid(xid);
923                         /* if we have gotten here we have written some data
924                            and blocked, and the file has been freed on us
925                            while we blocked so return what we managed to 
926                            write */
927                                 return total_written;
928                         } 
929                         if (open_file->closePend) {
930                                 FreeXid(xid);
931                                 if (total_written)
932                                         return total_written;
933                                 else
934                                         return -EBADF;
935                         }
936                         if (open_file->invalidHandle) {
937                                 /* we could deadlock if we called
938                                    filemap_fdatawait from here so tell
939                                    reopen_file not to flush data to 
940                                    server now */
941                                 rc = cifs_reopen_file(file, FALSE);
942                                 if (rc != 0)
943                                         break;
944                         }
945                         if(experimEnabled || (pTcon->ses->server &&
946                                 ((pTcon->ses->server->secMode & 
947                                 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
948                                 == 0))) {
949                                 struct kvec iov[2];
950                                 unsigned int len;
951
952                                 len = min((size_t)cifs_sb->wsize,
953                                           write_size - total_written);
954                                 /* iov[0] is reserved for smb header */
955                                 iov[1].iov_base = (char *)write_data +
956                                                   total_written;
957                                 iov[1].iov_len = len;
958                                 rc = CIFSSMBWrite2(xid, pTcon,
959                                                 open_file->netfid, len,
960                                                 *poffset, &bytes_written,
961                                                 iov, 1, long_op);
962                         } else
963                                 rc = CIFSSMBWrite(xid, pTcon,
964                                          open_file->netfid,
965                                          min_t(const int, cifs_sb->wsize,
966                                                write_size - total_written),
967                                          *poffset, &bytes_written,
968                                          write_data + total_written,
969                                          NULL, long_op);
970                 }
971                 if (rc || (bytes_written == 0)) {
972                         if (total_written)
973                                 break;
974                         else {
975                                 FreeXid(xid);
976                                 return rc;
977                         }
978                 } else
979                         *poffset += bytes_written;
980                 long_op = FALSE; /* subsequent writes fast - 
981                                     15 seconds is plenty */
982         }
983
984         cifs_stats_bytes_written(pTcon, total_written);
985
986         /* since the write may have blocked check these pointers again */
987         if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) {
988 /*BB We could make this contingent on superblock ATIME flag too */
989 /*              file->f_path.dentry->d_inode->i_ctime =
990                 file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/
991                 if (total_written > 0) {
992                         spin_lock(&file->f_path.dentry->d_inode->i_lock);
993                         if (*poffset > file->f_path.dentry->d_inode->i_size)
994                                 i_size_write(file->f_path.dentry->d_inode,
995                                              *poffset);
996                         spin_unlock(&file->f_path.dentry->d_inode->i_lock);
997                 }
998                 mark_inode_dirty_sync(file->f_path.dentry->d_inode);
999         }
1000         FreeXid(xid);
1001         return total_written;
1002 }
1003
1004 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
1005 {
1006         struct cifsFileInfo *open_file;
1007         int rc;
1008
1009         /* Having a null inode here (because mapping->host was set to zero by
1010         the VFS or MM) should not happen but we had reports of on oops (due to
1011         it being zero) during stress testcases so we need to check for it */
1012
1013         if(cifs_inode == NULL) {
1014                 cERROR(1,("Null inode passed to cifs_writeable_file"));
1015                 dump_stack();
1016                 return NULL;
1017         }
1018
1019         read_lock(&GlobalSMBSeslock);
1020         list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1021                 if (open_file->closePend)
1022                         continue;
1023                 if (open_file->pfile &&
1024                     ((open_file->pfile->f_flags & O_RDWR) ||
1025                      (open_file->pfile->f_flags & O_WRONLY))) {
1026                         atomic_inc(&open_file->wrtPending);
1027                         read_unlock(&GlobalSMBSeslock);
1028                         if((open_file->invalidHandle) && 
1029                            (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
1030                                 rc = cifs_reopen_file(open_file->pfile, FALSE);
1031                                 /* if it fails, try another handle - might be */
1032                                 /* dangerous to hold up writepages with retry */
1033                                 if(rc) {
1034                                         cFYI(1,("failed on reopen file in wp"));
1035                                         read_lock(&GlobalSMBSeslock);
1036                                         /* can not use this handle, no write
1037                                         pending on this one after all */
1038                                         atomic_dec
1039                                              (&open_file->wrtPending);
1040                                         continue;
1041                                 }
1042                         }
1043                         return open_file;
1044                 }
1045         }
1046         read_unlock(&GlobalSMBSeslock);
1047         return NULL;
1048 }
1049
1050 static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1051 {
1052         struct address_space *mapping = page->mapping;
1053         loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1054         char *write_data;
1055         int rc = -EFAULT;
1056         int bytes_written = 0;
1057         struct cifs_sb_info *cifs_sb;
1058         struct cifsTconInfo *pTcon;
1059         struct inode *inode;
1060         struct cifsFileInfo *open_file;
1061
1062         if (!mapping || !mapping->host)
1063                 return -EFAULT;
1064
1065         inode = page->mapping->host;
1066         cifs_sb = CIFS_SB(inode->i_sb);
1067         pTcon = cifs_sb->tcon;
1068
1069         offset += (loff_t)from;
1070         write_data = kmap(page);
1071         write_data += from;
1072
1073         if ((to > PAGE_CACHE_SIZE) || (from > to)) {
1074                 kunmap(page);
1075                 return -EIO;
1076         }
1077
1078         /* racing with truncate? */
1079         if (offset > mapping->host->i_size) {
1080                 kunmap(page);
1081                 return 0; /* don't care */
1082         }
1083
1084         /* check to make sure that we are not extending the file */
1085         if (mapping->host->i_size - offset < (loff_t)to)
1086                 to = (unsigned)(mapping->host->i_size - offset); 
1087
1088         open_file = find_writable_file(CIFS_I(mapping->host));
1089         if (open_file) {
1090                 bytes_written = cifs_write(open_file->pfile, write_data,
1091                                            to-from, &offset);
1092                 atomic_dec(&open_file->wrtPending);
1093                 /* Does mm or vfs already set times? */
1094                 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
1095                 if ((bytes_written > 0) && (offset)) {
1096                         rc = 0;
1097                 } else if (bytes_written < 0) {
1098                         if (rc != -EBADF)
1099                                 rc = bytes_written;
1100                 }
1101         } else {
1102                 cFYI(1, ("No writeable filehandles for inode"));
1103                 rc = -EIO;
1104         }
1105
1106         kunmap(page);
1107         return rc;
1108 }
1109
1110 static int cifs_writepages(struct address_space *mapping,
1111                            struct writeback_control *wbc)
1112 {
1113         struct backing_dev_info *bdi = mapping->backing_dev_info;
1114         unsigned int bytes_to_write;
1115         unsigned int bytes_written;
1116         struct cifs_sb_info *cifs_sb;
1117         int done = 0;
1118         pgoff_t end;
1119         pgoff_t index;
1120         int range_whole = 0;
1121         struct kvec * iov;
1122         int len;
1123         int n_iov = 0;
1124         pgoff_t next;
1125         int nr_pages;
1126         __u64 offset = 0;
1127         struct cifsFileInfo *open_file;
1128         struct page *page;
1129         struct pagevec pvec;
1130         int rc = 0;
1131         int scanned = 0;
1132         int xid;
1133
1134         cifs_sb = CIFS_SB(mapping->host->i_sb);
1135         
1136         /*
1137          * If wsize is smaller that the page cache size, default to writing
1138          * one page at a time via cifs_writepage
1139          */
1140         if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1141                 return generic_writepages(mapping, wbc);
1142
1143         if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
1144                 if(cifs_sb->tcon->ses->server->secMode &
1145                           (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1146                         if(!experimEnabled) 
1147                                 return generic_writepages(mapping, wbc);
1148
1149         iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1150         if(iov == NULL)
1151                 return generic_writepages(mapping, wbc);
1152
1153
1154         /*
1155          * BB: Is this meaningful for a non-block-device file system?
1156          * If it is, we should test it again after we do I/O
1157          */
1158         if (wbc->nonblocking && bdi_write_congested(bdi)) {
1159                 wbc->encountered_congestion = 1;
1160                 kfree(iov);
1161                 return 0;
1162         }
1163
1164         xid = GetXid();
1165
1166         pagevec_init(&pvec, 0);
1167         if (wbc->range_cyclic) {
1168                 index = mapping->writeback_index; /* Start from prev offset */
1169                 end = -1;
1170         } else {
1171                 index = wbc->range_start >> PAGE_CACHE_SHIFT;
1172                 end = wbc->range_end >> PAGE_CACHE_SHIFT;
1173                 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
1174                         range_whole = 1;
1175                 scanned = 1;
1176         }
1177 retry:
1178         while (!done && (index <= end) &&
1179                (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
1180                         PAGECACHE_TAG_DIRTY,
1181                         min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
1182                 int first;
1183                 unsigned int i;
1184
1185                 first = -1;
1186                 next = 0;
1187                 n_iov = 0;
1188                 bytes_to_write = 0;
1189
1190                 for (i = 0; i < nr_pages; i++) {
1191                         page = pvec.pages[i];
1192                         /*
1193                          * At this point we hold neither mapping->tree_lock nor
1194                          * lock on the page itself: the page may be truncated or
1195                          * invalidated (changing page->mapping to NULL), or even
1196                          * swizzled back from swapper_space to tmpfs file
1197                          * mapping
1198                          */
1199
1200                         if (first < 0)
1201                                 lock_page(page);
1202                         else if (TestSetPageLocked(page))
1203                                 break;
1204
1205                         if (unlikely(page->mapping != mapping)) {
1206                                 unlock_page(page);
1207                                 break;
1208                         }
1209
1210                         if (!wbc->range_cyclic && page->index > end) {
1211                                 done = 1;
1212                                 unlock_page(page);
1213                                 break;
1214                         }
1215
1216                         if (next && (page->index != next)) {
1217                                 /* Not next consecutive page */
1218                                 unlock_page(page);
1219                                 break;
1220                         }
1221
1222                         if (wbc->sync_mode != WB_SYNC_NONE)
1223                                 wait_on_page_writeback(page);
1224
1225                         if (PageWriteback(page) ||
1226                                         !clear_page_dirty_for_io(page)) {
1227                                 unlock_page(page);
1228                                 break;
1229                         }
1230
1231                         /*
1232                          * This actually clears the dirty bit in the radix tree.
1233                          * See cifs_writepage() for more commentary.
1234                          */
1235                         set_page_writeback(page);
1236
1237                         if (page_offset(page) >= mapping->host->i_size) {
1238                                 done = 1;
1239                                 unlock_page(page);
1240                                 end_page_writeback(page);
1241                                 break;
1242                         }
1243
1244                         /*
1245                          * BB can we get rid of this?  pages are held by pvec
1246                          */
1247                         page_cache_get(page);
1248
1249                         len = min(mapping->host->i_size - page_offset(page),
1250                                   (loff_t)PAGE_CACHE_SIZE);
1251
1252                         /* reserve iov[0] for the smb header */
1253                         n_iov++;
1254                         iov[n_iov].iov_base = kmap(page);
1255                         iov[n_iov].iov_len = len;
1256                         bytes_to_write += len;
1257
1258                         if (first < 0) {
1259                                 first = i;
1260                                 offset = page_offset(page);
1261                         }
1262                         next = page->index + 1;
1263                         if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
1264                                 break;
1265                 }
1266                 if (n_iov) {
1267                         /* Search for a writable handle every time we call
1268                          * CIFSSMBWrite2.  We can't rely on the last handle
1269                          * we used to still be valid
1270                          */
1271                         open_file = find_writable_file(CIFS_I(mapping->host));
1272                         if (!open_file) {
1273                                 cERROR(1, ("No writable handles for inode"));
1274                                 rc = -EBADF;
1275                         } else {
1276                                 rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
1277                                                    open_file->netfid,
1278                                                    bytes_to_write, offset,
1279                                                    &bytes_written, iov, n_iov,
1280                                                    1);
1281                                 atomic_dec(&open_file->wrtPending);
1282                                 if (rc || bytes_written < bytes_to_write) {
1283                                         cERROR(1,("Write2 ret %d, written = %d",
1284                                                   rc, bytes_written));
1285                                         /* BB what if continued retry is
1286                                            requested via mount flags? */
1287                                         set_bit(AS_EIO, &mapping->flags);
1288                                 } else {
1289                                         cifs_stats_bytes_written(cifs_sb->tcon,
1290                                                                  bytes_written);
1291                                 }
1292                         }
1293                         for (i = 0; i < n_iov; i++) {
1294                                 page = pvec.pages[first + i];
1295                                 /* Should we also set page error on
1296                                 success rc but too little data written? */
1297                                 /* BB investigate retry logic on temporary
1298                                 server crash cases and how recovery works
1299                                 when page marked as error */ 
1300                                 if(rc)
1301                                         SetPageError(page);
1302                                 kunmap(page);
1303                                 unlock_page(page);
1304                                 end_page_writeback(page);
1305                                 page_cache_release(page);
1306                         }
1307                         if ((wbc->nr_to_write -= n_iov) <= 0)
1308                                 done = 1;
1309                         index = next;
1310                 }
1311                 pagevec_release(&pvec);
1312         }
1313         if (!scanned && !done) {
1314                 /*
1315                  * We hit the last page and there is more work to be done: wrap
1316                  * back to the start of the file
1317                  */
1318                 scanned = 1;
1319                 index = 0;
1320                 goto retry;
1321         }
1322         if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
1323                 mapping->writeback_index = index;
1324
1325         FreeXid(xid);
1326         kfree(iov);
1327         return rc;
1328 }
1329
1330 static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1331 {
1332         int rc = -EFAULT;
1333         int xid;
1334
1335         xid = GetXid();
1336 /* BB add check for wbc flags */
1337         page_cache_get(page);
1338         if (!PageUptodate(page)) {
1339                 cFYI(1, ("ppw - page not up to date"));
1340         }
1341
1342         /*
1343          * Set the "writeback" flag, and clear "dirty" in the radix tree.
1344          *
1345          * A writepage() implementation always needs to do either this,
1346          * or re-dirty the page with "redirty_page_for_writepage()" in
1347          * the case of a failure.
1348          *
1349          * Just unlocking the page will cause the radix tree tag-bits
1350          * to fail to update with the state of the page correctly.
1351          */
1352         set_page_writeback(page);               
1353         rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
1354         SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
1355         unlock_page(page);
1356         end_page_writeback(page);
1357         page_cache_release(page);
1358         FreeXid(xid);
1359         return rc;
1360 }
1361
1362 static int cifs_commit_write(struct file *file, struct page *page,
1363         unsigned offset, unsigned to)
1364 {
1365         int xid;
1366         int rc = 0;
1367         struct inode *inode = page->mapping->host;
1368         loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
1369         char *page_data;
1370
1371         xid = GetXid();
1372         cFYI(1, ("commit write for page %p up to position %lld for %d", 
1373                  page, position, to));
1374         spin_lock(&inode->i_lock);
1375         if (position > inode->i_size) {
1376                 i_size_write(inode, position);
1377         }
1378         spin_unlock(&inode->i_lock);
1379         if (!PageUptodate(page)) {
1380                 position =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
1381                 /* can not rely on (or let) writepage write this data */
1382                 if (to < offset) {
1383                         cFYI(1, ("Illegal offsets, can not copy from %d to %d",
1384                                 offset, to));
1385                         FreeXid(xid);
1386                         return rc;
1387                 }
1388                 /* this is probably better than directly calling
1389                    partialpage_write since in this function the file handle is
1390                    known which we might as well leverage */
1391                 /* BB check if anything else missing out of ppw
1392                    such as updating last write time */
1393                 page_data = kmap(page);
1394                 rc = cifs_write(file, page_data + offset, to-offset,
1395                                 &position);
1396                 if (rc > 0)
1397                         rc = 0;
1398                 /* else if (rc < 0) should we set writebehind rc? */
1399                 kunmap(page);
1400         } else {        
1401                 set_page_dirty(page);
1402         }
1403
1404         FreeXid(xid);
1405         return rc;
1406 }
1407
1408 int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1409 {
1410         int xid;
1411         int rc = 0;
1412         struct inode *inode = file->f_path.dentry->d_inode;
1413
1414         xid = GetXid();
1415
1416         cFYI(1, ("Sync file - name: %s datasync: 0x%x", 
1417                 dentry->d_name.name, datasync));
1418         
1419         rc = filemap_fdatawrite(inode->i_mapping);
1420         if (rc == 0)
1421                 CIFS_I(inode)->write_behind_rc = 0;
1422         FreeXid(xid);
1423         return rc;
1424 }
1425
1426 /* static void cifs_sync_page(struct page *page)
1427 {
1428         struct address_space *mapping;
1429         struct inode *inode;
1430         unsigned long index = page->index;
1431         unsigned int rpages = 0;
1432         int rc = 0;
1433
1434         cFYI(1, ("sync page %p",page));
1435         mapping = page->mapping;
1436         if (!mapping)
1437                 return 0;
1438         inode = mapping->host;
1439         if (!inode)
1440                 return; */
1441
1442 /*      fill in rpages then 
1443         result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1444
1445 /*      cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index));
1446
1447 #if 0
1448         if (rc < 0)
1449                 return rc;
1450         return 0;
1451 #endif
1452 } */
1453
1454 /*
1455  * As file closes, flush all cached write data for this inode checking
1456  * for write behind errors.
1457  */
1458 int cifs_flush(struct file *file, fl_owner_t id)
1459 {
1460         struct inode * inode = file->f_path.dentry->d_inode;
1461         int rc = 0;
1462
1463         /* Rather than do the steps manually:
1464            lock the inode for writing
1465            loop through pages looking for write behind data (dirty pages)
1466            coalesce into contiguous 16K (or smaller) chunks to write to server
1467            send to server (prefer in parallel)
1468            deal with writebehind errors
1469            unlock inode for writing
1470            filemapfdatawrite appears easier for the time being */
1471
1472         rc = filemap_fdatawrite(inode->i_mapping);
1473         if (!rc) /* reset wb rc if we were able to write out dirty pages */
1474                 CIFS_I(inode)->write_behind_rc = 0;
1475                 
1476         cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc));
1477
1478         return rc;
1479 }
1480
1481 ssize_t cifs_user_read(struct file *file, char __user *read_data,
1482         size_t read_size, loff_t *poffset)
1483 {
1484         int rc = -EACCES;
1485         unsigned int bytes_read = 0;
1486         unsigned int total_read = 0;
1487         unsigned int current_read_size;
1488         struct cifs_sb_info *cifs_sb;
1489         struct cifsTconInfo *pTcon;
1490         int xid;
1491         struct cifsFileInfo *open_file;
1492         char *smb_read_data;
1493         char __user *current_offset;
1494         struct smb_com_read_rsp *pSMBr;
1495
1496         xid = GetXid();
1497         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1498         pTcon = cifs_sb->tcon;
1499
1500         if (file->private_data == NULL) {
1501                 FreeXid(xid);
1502                 return -EBADF;
1503         }
1504         open_file = (struct cifsFileInfo *)file->private_data;
1505
1506         if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
1507                 cFYI(1, ("attempting read on write only file instance"));
1508         }
1509         for (total_read = 0, current_offset = read_data;
1510              read_size > total_read;
1511              total_read += bytes_read, current_offset += bytes_read) {
1512                 current_read_size = min_t(const int, read_size - total_read, 
1513                                           cifs_sb->rsize);
1514                 rc = -EAGAIN;
1515                 smb_read_data = NULL;
1516                 while (rc == -EAGAIN) {
1517                         int buf_type = CIFS_NO_BUFFER;
1518                         if ((open_file->invalidHandle) && 
1519                             (!open_file->closePend)) {
1520                                 rc = cifs_reopen_file(file, TRUE);
1521                                 if (rc != 0)
1522                                         break;
1523                         }
1524                         rc = CIFSSMBRead(xid, pTcon,
1525                                          open_file->netfid,
1526                                          current_read_size, *poffset,
1527                                          &bytes_read, &smb_read_data,
1528                                          &buf_type);
1529                         pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1530                         if (smb_read_data) {
1531                                 if (copy_to_user(current_offset,
1532                                                 smb_read_data +
1533                                                 4 /* RFC1001 length field */ +
1534                                                 le16_to_cpu(pSMBr->DataOffset),
1535                                                 bytes_read)) {
1536                                         rc = -EFAULT;
1537                                 }
1538
1539                                 if(buf_type == CIFS_SMALL_BUFFER)
1540                                         cifs_small_buf_release(smb_read_data);
1541                                 else if(buf_type == CIFS_LARGE_BUFFER)
1542                                         cifs_buf_release(smb_read_data);
1543                                 smb_read_data = NULL;
1544                         }
1545                 }
1546                 if (rc || (bytes_read == 0)) {
1547                         if (total_read) {
1548                                 break;
1549                         } else {
1550                                 FreeXid(xid);
1551                                 return rc;
1552                         }
1553                 } else {
1554                         cifs_stats_bytes_read(pTcon, bytes_read);
1555                         *poffset += bytes_read;
1556                 }
1557         }
1558         FreeXid(xid);
1559         return total_read;
1560 }
1561
1562
1563 static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1564         loff_t *poffset)
1565 {
1566         int rc = -EACCES;
1567         unsigned int bytes_read = 0;
1568         unsigned int total_read;
1569         unsigned int current_read_size;
1570         struct cifs_sb_info *cifs_sb;
1571         struct cifsTconInfo *pTcon;
1572         int xid;
1573         char *current_offset;
1574         struct cifsFileInfo *open_file;
1575         int buf_type = CIFS_NO_BUFFER;
1576
1577         xid = GetXid();
1578         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1579         pTcon = cifs_sb->tcon;
1580
1581         if (file->private_data == NULL) {
1582                 FreeXid(xid);
1583                 return -EBADF;
1584         }
1585         open_file = (struct cifsFileInfo *)file->private_data;
1586
1587         if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1588                 cFYI(1, ("attempting read on write only file instance"));
1589
1590         for (total_read = 0, current_offset = read_data; 
1591              read_size > total_read;
1592              total_read += bytes_read, current_offset += bytes_read) {
1593                 current_read_size = min_t(const int, read_size - total_read,
1594                                           cifs_sb->rsize);
1595                 /* For windows me and 9x we do not want to request more
1596                 than it negotiated since it will refuse the read then */
1597                 if((pTcon->ses) && 
1598                         !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
1599                         current_read_size = min_t(const int, current_read_size,
1600                                         pTcon->ses->server->maxBuf - 128);
1601                 }
1602                 rc = -EAGAIN;
1603                 while (rc == -EAGAIN) {
1604                         if ((open_file->invalidHandle) && 
1605                             (!open_file->closePend)) {
1606                                 rc = cifs_reopen_file(file, TRUE);
1607                                 if (rc != 0)
1608                                         break;
1609                         }
1610                         rc = CIFSSMBRead(xid, pTcon,
1611                                          open_file->netfid,
1612                                          current_read_size, *poffset,
1613                                          &bytes_read, &current_offset,
1614                                          &buf_type);
1615                 }
1616                 if (rc || (bytes_read == 0)) {
1617                         if (total_read) {
1618                                 break;
1619                         } else {
1620                                 FreeXid(xid);
1621                                 return rc;
1622                         }
1623                 } else {
1624                         cifs_stats_bytes_read(pTcon, total_read);
1625                         *poffset += bytes_read;
1626                 }
1627         }
1628         FreeXid(xid);
1629         return total_read;
1630 }
1631
1632 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1633 {
1634         struct dentry *dentry = file->f_path.dentry;
1635         int rc, xid;
1636
1637         xid = GetXid();
1638         rc = cifs_revalidate(dentry);
1639         if (rc) {
1640                 cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
1641                 FreeXid(xid);
1642                 return rc;
1643         }
1644         rc = generic_file_mmap(file, vma);
1645         FreeXid(xid);
1646         return rc;
1647 }
1648
1649
1650 static void cifs_copy_cache_pages(struct address_space *mapping, 
1651         struct list_head *pages, int bytes_read, char *data,
1652         struct pagevec *plru_pvec)
1653 {
1654         struct page *page;
1655         char *target;
1656
1657         while (bytes_read > 0) {
1658                 if (list_empty(pages))
1659                         break;
1660
1661                 page = list_entry(pages->prev, struct page, lru);
1662                 list_del(&page->lru);
1663
1664                 if (add_to_page_cache(page, mapping, page->index,
1665                                       GFP_KERNEL)) {
1666                         page_cache_release(page);
1667                         cFYI(1, ("Add page cache failed"));
1668                         data += PAGE_CACHE_SIZE;
1669                         bytes_read -= PAGE_CACHE_SIZE;
1670                         continue;
1671                 }
1672
1673                 target = kmap_atomic(page,KM_USER0);
1674
1675                 if (PAGE_CACHE_SIZE > bytes_read) {
1676                         memcpy(target, data, bytes_read);
1677                         /* zero the tail end of this partial page */
1678                         memset(target + bytes_read, 0, 
1679                                PAGE_CACHE_SIZE - bytes_read);
1680                         bytes_read = 0;
1681                 } else {
1682                         memcpy(target, data, PAGE_CACHE_SIZE);
1683                         bytes_read -= PAGE_CACHE_SIZE;
1684                 }
1685                 kunmap_atomic(target, KM_USER0);
1686
1687                 flush_dcache_page(page);
1688                 SetPageUptodate(page);
1689                 unlock_page(page);
1690                 if (!pagevec_add(plru_pvec, page))
1691                         __pagevec_lru_add(plru_pvec);
1692                 data += PAGE_CACHE_SIZE;
1693         }
1694         return;
1695 }
1696
1697 static int cifs_readpages(struct file *file, struct address_space *mapping,
1698         struct list_head *page_list, unsigned num_pages)
1699 {
1700         int rc = -EACCES;
1701         int xid;
1702         loff_t offset;
1703         struct page *page;
1704         struct cifs_sb_info *cifs_sb;
1705         struct cifsTconInfo *pTcon;
1706         int bytes_read = 0;
1707         unsigned int read_size,i;
1708         char *smb_read_data = NULL;
1709         struct smb_com_read_rsp *pSMBr;
1710         struct pagevec lru_pvec;
1711         struct cifsFileInfo *open_file;
1712         int buf_type = CIFS_NO_BUFFER;
1713
1714         xid = GetXid();
1715         if (file->private_data == NULL) {
1716                 FreeXid(xid);
1717                 return -EBADF;
1718         }
1719         open_file = (struct cifsFileInfo *)file->private_data;
1720         cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1721         pTcon = cifs_sb->tcon;
1722
1723         pagevec_init(&lru_pvec, 0);
1724
1725         for (i = 0; i < num_pages; ) {
1726                 unsigned contig_pages;
1727                 struct page *tmp_page;
1728                 unsigned long expected_index;
1729
1730                 if (list_empty(page_list))
1731                         break;
1732
1733                 page = list_entry(page_list->prev, struct page, lru);
1734                 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1735
1736                 /* count adjacent pages that we will read into */
1737                 contig_pages = 0;
1738                 expected_index = 
1739                         list_entry(page_list->prev, struct page, lru)->index;
1740                 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1741                         if (tmp_page->index == expected_index) {
1742                                 contig_pages++;
1743                                 expected_index++;
1744                         } else
1745                                 break; 
1746                 }
1747                 if (contig_pages + i >  num_pages)
1748                         contig_pages = num_pages - i;
1749
1750                 /* for reads over a certain size could initiate async
1751                    read ahead */
1752
1753                 read_size = contig_pages * PAGE_CACHE_SIZE;
1754                 /* Read size needs to be in multiples of one page */
1755                 read_size = min_t(const unsigned int, read_size,
1756                                   cifs_sb->rsize & PAGE_CACHE_MASK);
1757
1758                 rc = -EAGAIN;
1759                 while (rc == -EAGAIN) {
1760                         if ((open_file->invalidHandle) && 
1761                             (!open_file->closePend)) {
1762                                 rc = cifs_reopen_file(file, TRUE);
1763                                 if (rc != 0)
1764                                         break;
1765                         }
1766
1767                         rc = CIFSSMBRead(xid, pTcon,
1768                                          open_file->netfid,
1769                                          read_size, offset,
1770                                          &bytes_read, &smb_read_data,
1771                                          &buf_type);
1772                         /* BB more RC checks ? */
1773                         if (rc== -EAGAIN) {
1774                                 if (smb_read_data) {
1775                                         if(buf_type == CIFS_SMALL_BUFFER)
1776                                                 cifs_small_buf_release(smb_read_data);
1777                                         else if(buf_type == CIFS_LARGE_BUFFER)
1778                                                 cifs_buf_release(smb_read_data);
1779                                         smb_read_data = NULL;
1780                                 }
1781                         }
1782                 }
1783                 if ((rc < 0) || (smb_read_data == NULL)) {
1784                         cFYI(1, ("Read error in readpages: %d", rc));
1785                         break;
1786                 } else if (bytes_read > 0) {
1787                         task_io_account_read(bytes_read);
1788                         pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1789                         cifs_copy_cache_pages(mapping, page_list, bytes_read,
1790                                 smb_read_data + 4 /* RFC1001 hdr */ +
1791                                 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1792
1793                         i +=  bytes_read >> PAGE_CACHE_SHIFT;
1794                         cifs_stats_bytes_read(pTcon, bytes_read);
1795                         if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1796                                 i++; /* account for partial page */
1797
1798                                 /* server copy of file can have smaller size 
1799                                    than client */
1800                                 /* BB do we need to verify this common case ? 
1801                                    this case is ok - if we are at server EOF 
1802                                    we will hit it on next read */
1803
1804                                 /* break; */
1805                         }
1806                 } else {
1807                         cFYI(1, ("No bytes read (%d) at offset %lld . "
1808                                  "Cleaning remaining pages from readahead list",
1809                                  bytes_read, offset));
1810                         /* BB turn off caching and do new lookup on 
1811                            file size at server? */
1812                         break;
1813                 }
1814                 if (smb_read_data) {
1815                         if(buf_type == CIFS_SMALL_BUFFER)
1816                                 cifs_small_buf_release(smb_read_data);
1817                         else if(buf_type == CIFS_LARGE_BUFFER)
1818                                 cifs_buf_release(smb_read_data);
1819                         smb_read_data = NULL;
1820                 }
1821                 bytes_read = 0;
1822         }
1823
1824         pagevec_lru_add(&lru_pvec);
1825
1826 /* need to free smb_read_data buf before exit */
1827         if (smb_read_data) {
1828                 if(buf_type == CIFS_SMALL_BUFFER)
1829                         cifs_small_buf_release(smb_read_data);
1830                 else if(buf_type == CIFS_LARGE_BUFFER)
1831                         cifs_buf_release(smb_read_data);
1832                 smb_read_data = NULL;
1833         } 
1834
1835         FreeXid(xid);
1836         return rc;
1837 }
1838
1839 static int cifs_readpage_worker(struct file *file, struct page *page,
1840         loff_t *poffset)
1841 {
1842         char *read_data;
1843         int rc;
1844
1845         page_cache_get(page);
1846         read_data = kmap(page);
1847         /* for reads over a certain size could initiate async read ahead */
1848                                                                                                                            
1849         rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1850                                                                                                                            
1851         if (rc < 0)
1852                 goto io_error;
1853         else
1854                 cFYI(1, ("Bytes read %d",rc));
1855                                                                                                                            
1856         file->f_path.dentry->d_inode->i_atime =
1857                 current_fs_time(file->f_path.dentry->d_inode->i_sb);
1858                                                                                                                            
1859         if (PAGE_CACHE_SIZE > rc)
1860                 memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);
1861
1862         flush_dcache_page(page);
1863         SetPageUptodate(page);
1864         rc = 0;
1865                                                                                                                            
1866 io_error:
1867         kunmap(page);
1868         page_cache_release(page);
1869         return rc;
1870 }
1871
1872 static int cifs_readpage(struct file *file, struct page *page)
1873 {
1874         loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1875         int rc = -EACCES;
1876         int xid;
1877
1878         xid = GetXid();
1879
1880         if (file->private_data == NULL) {
1881                 FreeXid(xid);
1882                 return -EBADF;
1883         }
1884
1885         cFYI(1, ("readpage %p at offset %d 0x%x\n", 
1886                  page, (int)offset, (int)offset));
1887
1888         rc = cifs_readpage_worker(file, page, &offset);
1889
1890         unlock_page(page);
1891
1892         FreeXid(xid);
1893         return rc;
1894 }
1895
1896 /* We do not want to update the file size from server for inodes
1897    open for write - to avoid races with writepage extending
1898    the file - in the future we could consider allowing
1899    refreshing the inode only on increases in the file size 
1900    but this is tricky to do without racing with writebehind
1901    page caching in the current Linux kernel design */
1902 int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
1903 {
1904         struct cifsFileInfo *open_file = NULL;
1905
1906         if (cifsInode)
1907                 open_file =  find_writable_file(cifsInode);
1908  
1909         if(open_file) {
1910                 struct cifs_sb_info *cifs_sb;
1911
1912                 /* there is not actually a write pending so let
1913                 this handle go free and allow it to
1914                 be closable if needed */
1915                 atomic_dec(&open_file->wrtPending);
1916
1917                 cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
1918                 if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) {
1919                         /* since no page cache to corrupt on directio 
1920                         we can change size safely */
1921                         return 1;
1922                 }
1923
1924                 if(i_size_read(&cifsInode->vfs_inode) < end_of_file)
1925                         return 1;
1926
1927                 return 0;
1928         } else
1929                 return 1;
1930 }
1931
1932 static int cifs_prepare_write(struct file *file, struct page *page,
1933         unsigned from, unsigned to)
1934 {
1935         int rc = 0;
1936         loff_t i_size;
1937         loff_t offset;
1938
1939         cFYI(1, ("prepare write for page %p from %d to %d",page,from,to));
1940         if (PageUptodate(page))
1941                 return 0;
1942
1943         /* If we are writing a full page it will be up to date,
1944            no need to read from the server */
1945         if ((to == PAGE_CACHE_SIZE) && (from == 0)) {
1946                 SetPageUptodate(page);
1947                 return 0;
1948         }
1949
1950         offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1951         i_size = i_size_read(page->mapping->host);
1952
1953         if ((offset >= i_size) ||
1954             ((from == 0) && (offset + to) >= i_size)) {
1955                 /*
1956                  * We don't need to read data beyond the end of the file.
1957                  * zero it, and set the page uptodate
1958                  */
1959                 void *kaddr = kmap_atomic(page, KM_USER0);
1960
1961                 if (from)
1962                         memset(kaddr, 0, from);
1963                 if (to < PAGE_CACHE_SIZE)
1964                         memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1965                 flush_dcache_page(page);
1966                 kunmap_atomic(kaddr, KM_USER0);
1967                 SetPageUptodate(page);
1968         } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
1969                 /* might as well read a page, it is fast enough */
1970                 rc = cifs_readpage_worker(file, page, &offset);
1971         } else {
1972                 /* we could try using another file handle if there is one -
1973                    but how would we lock it to prevent close of that handle
1974                    racing with this read? In any case
1975                    this will be written out by commit_write so is fine */
1976         }
1977
1978         /* we do not need to pass errors back 
1979            e.g. if we do not have read access to the file 
1980            because cifs_commit_write will do the right thing.  -- shaggy */
1981
1982         return 0;
1983 }
1984
1985 const struct address_space_operations cifs_addr_ops = {
1986         .readpage = cifs_readpage,
1987         .readpages = cifs_readpages,
1988         .writepage = cifs_writepage,
1989         .writepages = cifs_writepages,
1990         .prepare_write = cifs_prepare_write,
1991         .commit_write = cifs_commit_write,
1992         .set_page_dirty = __set_page_dirty_nobuffers,
1993         /* .sync_page = cifs_sync_page, */
1994         /* .direct_IO = */
1995 };
1996
1997 /*
1998  * cifs_readpages requires the server to support a buffer large enough to
1999  * contain the header plus one complete page of data.  Otherwise, we need
2000  * to leave cifs_readpages out of the address space operations.
2001  */
2002 const struct address_space_operations cifs_addr_ops_smallbuf = {
2003         .readpage = cifs_readpage,
2004         .writepage = cifs_writepage,
2005         .writepages = cifs_writepages,
2006         .prepare_write = cifs_prepare_write,
2007         .commit_write = cifs_commit_write,
2008         .set_page_dirty = __set_page_dirty_nobuffers,
2009         /* .sync_page = cifs_sync_page, */
2010         /* .direct_IO = */
2011 };