4 * vfs operations that deal with files
6 * Copyright (C) International Business Machines Corp., 2002,2003
7 * Author(s): Steve French (sfrench@us.ibm.com)
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.
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.
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
24 #include <linux/backing-dev.h>
25 #include <linux/stat.h>
26 #include <linux/fcntl.h>
27 #include <linux/mpage.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/delay.h>
33 #include <asm/div64.h>
37 #include "cifsproto.h"
38 #include "cifs_unicode.h"
39 #include "cifs_debug.h"
40 #include "cifs_fs_sb.h"
42 static inline struct cifsFileInfo
*cifs_init_private(
43 struct cifsFileInfo
*private_data
, struct inode
*inode
,
44 struct file
*file
, __u16 netfid
)
46 memset(private_data
, 0, sizeof(struct cifsFileInfo
));
47 private_data
->netfid
= netfid
;
48 private_data
->pid
= current
->tgid
;
49 init_MUTEX(&private_data
->fh_sem
);
50 private_data
->pfile
= file
; /* needed for writepage */
51 private_data
->pInode
= inode
;
52 private_data
->invalidHandle
= FALSE
;
53 private_data
->closePend
= FALSE
;
54 /* we have to track num writers to the inode, since writepages
55 does not tell us which handle the write is for so there can
56 be a close (overlapping with write) of the filehandle that
57 cifs_writepages chose to use */
58 atomic_set(&private_data
->wrtPending
,0);
63 static inline int cifs_convert_flags(unsigned int flags
)
65 if ((flags
& O_ACCMODE
) == O_RDONLY
)
67 else if ((flags
& O_ACCMODE
) == O_WRONLY
)
69 else if ((flags
& O_ACCMODE
) == O_RDWR
) {
70 /* GENERIC_ALL is too much permission to request
71 can cause unnecessary access denied on create */
72 /* return GENERIC_ALL; */
73 return (GENERIC_READ
| GENERIC_WRITE
);
79 static inline int cifs_get_disposition(unsigned int flags
)
81 if ((flags
& (O_CREAT
| O_EXCL
)) == (O_CREAT
| O_EXCL
))
83 else if ((flags
& (O_CREAT
| O_TRUNC
)) == (O_CREAT
| O_TRUNC
))
84 return FILE_OVERWRITE_IF
;
85 else if ((flags
& O_CREAT
) == O_CREAT
)
91 /* all arguments to this function must be checked for validity in caller */
92 static inline int cifs_open_inode_helper(struct inode
*inode
, struct file
*file
,
93 struct cifsInodeInfo
*pCifsInode
, struct cifsFileInfo
*pCifsFile
,
94 struct cifsTconInfo
*pTcon
, int *oplock
, FILE_ALL_INFO
*buf
,
95 char *full_path
, int xid
)
100 /* want handles we can use to read with first
101 in the list so we do not have to walk the
102 list to search for one in prepare_write */
103 if ((file
->f_flags
& O_ACCMODE
) == O_WRONLY
) {
104 list_add_tail(&pCifsFile
->flist
,
105 &pCifsInode
->openFileList
);
107 list_add(&pCifsFile
->flist
,
108 &pCifsInode
->openFileList
);
110 write_unlock(&GlobalSMBSeslock
);
111 write_unlock(&file
->f_owner
.lock
);
112 if (pCifsInode
->clientCanCacheRead
) {
113 /* we have the inode open somewhere else
114 no need to discard cache data */
115 goto client_can_cache
;
118 /* BB need same check in cifs_create too? */
119 /* if not oplocked, invalidate inode pages if mtime or file
121 temp
= cifs_NTtimeToUnix(le64_to_cpu(buf
->LastWriteTime
));
122 if (timespec_equal(&file
->f_dentry
->d_inode
->i_mtime
, &temp
) &&
123 (file
->f_dentry
->d_inode
->i_size
==
124 (loff_t
)le64_to_cpu(buf
->EndOfFile
))) {
125 cFYI(1, ("inode unchanged on server"));
127 if (file
->f_dentry
->d_inode
->i_mapping
) {
128 /* BB no need to lock inode until after invalidate
129 since namei code should already have it locked? */
130 filemap_fdatawrite(file
->f_dentry
->d_inode
->i_mapping
);
131 filemap_fdatawait(file
->f_dentry
->d_inode
->i_mapping
);
133 cFYI(1, ("invalidating remote inode since open detected it "
135 invalidate_remote_inode(file
->f_dentry
->d_inode
);
139 if (pTcon
->ses
->capabilities
& CAP_UNIX
)
140 rc
= cifs_get_inode_info_unix(&file
->f_dentry
->d_inode
,
141 full_path
, inode
->i_sb
, xid
);
143 rc
= cifs_get_inode_info(&file
->f_dentry
->d_inode
,
144 full_path
, buf
, inode
->i_sb
, xid
);
146 if ((*oplock
& 0xF) == OPLOCK_EXCLUSIVE
) {
147 pCifsInode
->clientCanCacheAll
= TRUE
;
148 pCifsInode
->clientCanCacheRead
= TRUE
;
149 cFYI(1, ("Exclusive Oplock granted on inode %p",
150 file
->f_dentry
->d_inode
));
151 } else if ((*oplock
& 0xF) == OPLOCK_READ
)
152 pCifsInode
->clientCanCacheRead
= TRUE
;
157 int cifs_open(struct inode
*inode
, struct file
*file
)
161 struct cifs_sb_info
*cifs_sb
;
162 struct cifsTconInfo
*pTcon
;
163 struct cifsFileInfo
*pCifsFile
;
164 struct cifsInodeInfo
*pCifsInode
;
165 struct list_head
*tmp
;
166 char *full_path
= NULL
;
170 FILE_ALL_INFO
*buf
= NULL
;
174 cifs_sb
= CIFS_SB(inode
->i_sb
);
175 pTcon
= cifs_sb
->tcon
;
177 if (file
->f_flags
& O_CREAT
) {
178 /* search inode for this file and fill in file->private_data */
179 pCifsInode
= CIFS_I(file
->f_dentry
->d_inode
);
180 read_lock(&GlobalSMBSeslock
);
181 list_for_each(tmp
, &pCifsInode
->openFileList
) {
182 pCifsFile
= list_entry(tmp
, struct cifsFileInfo
,
184 if ((pCifsFile
->pfile
== NULL
) &&
185 (pCifsFile
->pid
== current
->tgid
)) {
186 /* mode set in cifs_create */
188 /* needed for writepage */
189 pCifsFile
->pfile
= file
;
191 file
->private_data
= pCifsFile
;
195 read_unlock(&GlobalSMBSeslock
);
196 if (file
->private_data
!= NULL
) {
201 if (file
->f_flags
& O_EXCL
)
202 cERROR(1, ("could not find file instance for "
203 "new file %p ", file
));
207 down(&inode
->i_sb
->s_vfs_rename_sem
);
208 full_path
= build_path_from_dentry(file
->f_dentry
);
209 up(&inode
->i_sb
->s_vfs_rename_sem
);
210 if (full_path
== NULL
) {
215 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
216 inode
, file
->f_flags
, full_path
));
217 desiredAccess
= cifs_convert_flags(file
->f_flags
);
219 /*********************************************************************
220 * open flag mapping table:
222 * POSIX Flag CIFS Disposition
223 * ---------- ----------------
224 * O_CREAT FILE_OPEN_IF
225 * O_CREAT | O_EXCL FILE_CREATE
226 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
227 * O_TRUNC FILE_OVERWRITE
228 * none of the above FILE_OPEN
230 * Note that there is not a direct match between disposition
231 * FILE_SUPERSEDE (ie create whether or not file exists although
232 * O_CREAT | O_TRUNC is similar but truncates the existing
233 * file rather than creating a new file as FILE_SUPERSEDE does
234 * (which uses the attributes / metadata passed in on open call)
236 *? O_SYNC is a reasonable match to CIFS writethrough flag
237 *? and the read write flags match reasonably. O_LARGEFILE
238 *? is irrelevant because largefile support is always used
239 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
240 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
241 *********************************************************************/
243 disposition
= cifs_get_disposition(file
->f_flags
);
250 /* BB pass O_SYNC flag through on file attributes .. BB */
252 /* Also refresh inode by passing in file_info buf returned by SMBOpen
253 and calling get_inode_info with returned buf (at least helps
254 non-Unix server case) */
256 /* BB we can not do this if this is the second open of a file
257 and the first handle has writebehind data, we might be
258 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
259 buf
= kmalloc(sizeof(FILE_ALL_INFO
), GFP_KERNEL
);
264 rc
= CIFSSMBOpen(xid
, pTcon
, full_path
, disposition
, desiredAccess
,
265 CREATE_NOT_DIR
, &netfid
, &oplock
, buf
,
266 cifs_sb
->local_nls
, cifs_sb
->mnt_cifs_flags
267 & CIFS_MOUNT_MAP_SPECIAL_CHR
);
269 /* Old server, try legacy style OpenX */
270 rc
= SMBLegacyOpen(xid
, pTcon
, full_path
, disposition
,
271 desiredAccess
, CREATE_NOT_DIR
, &netfid
, &oplock
, buf
,
272 cifs_sb
->local_nls
, cifs_sb
->mnt_cifs_flags
273 & CIFS_MOUNT_MAP_SPECIAL_CHR
);
276 cFYI(1, ("cifs_open returned 0x%x ", rc
));
280 kmalloc(sizeof(struct cifsFileInfo
), GFP_KERNEL
);
281 if (file
->private_data
== NULL
) {
285 pCifsFile
= cifs_init_private(file
->private_data
, inode
, file
, netfid
);
286 write_lock(&file
->f_owner
.lock
);
287 write_lock(&GlobalSMBSeslock
);
288 list_add(&pCifsFile
->tlist
, &pTcon
->openFileList
);
290 pCifsInode
= CIFS_I(file
->f_dentry
->d_inode
);
292 rc
= cifs_open_inode_helper(inode
, file
, pCifsInode
,
294 &oplock
, buf
, full_path
, xid
);
296 write_unlock(&GlobalSMBSeslock
);
297 write_unlock(&file
->f_owner
.lock
);
300 if (oplock
& CIFS_CREATE_ACTION
) {
301 /* time to set mode which we can not set earlier due to
302 problems creating new read-only files */
303 if (cifs_sb
->tcon
->ses
->capabilities
& CAP_UNIX
) {
304 CIFSSMBUnixSetPerms(xid
, pTcon
, full_path
,
306 (__u64
)-1, (__u64
)-1, 0 /* dev */,
308 cifs_sb
->mnt_cifs_flags
&
309 CIFS_MOUNT_MAP_SPECIAL_CHR
);
311 /* BB implement via Windows security descriptors eg
312 CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
314 in the meantime could set r/o dos attribute when
315 perms are eg: mode & 0222 == 0 */
326 /* Try to reaquire byte range locks that were released when session */
327 /* to server was lost */
328 static int cifs_relock_file(struct cifsFileInfo
*cifsFile
)
332 /* BB list all locks open on this file and relock */
337 static int cifs_reopen_file(struct inode
*inode
, struct file
*file
,
342 struct cifs_sb_info
*cifs_sb
;
343 struct cifsTconInfo
*pTcon
;
344 struct cifsFileInfo
*pCifsFile
;
345 struct cifsInodeInfo
*pCifsInode
;
346 char *full_path
= NULL
;
348 int disposition
= FILE_OPEN
;
353 if (file
->private_data
) {
354 pCifsFile
= (struct cifsFileInfo
*)file
->private_data
;
359 down(&pCifsFile
->fh_sem
);
360 if (pCifsFile
->invalidHandle
== FALSE
) {
361 up(&pCifsFile
->fh_sem
);
366 if (file
->f_dentry
== NULL
) {
367 up(&pCifsFile
->fh_sem
);
368 cFYI(1, ("failed file reopen, no valid name if dentry freed"));
372 cifs_sb
= CIFS_SB(inode
->i_sb
);
373 pTcon
= cifs_sb
->tcon
;
374 /* can not grab rename sem here because various ops, including
375 those that already have the rename sem can end up causing writepage
376 to get called and if the server was down that means we end up here,
377 and we can never tell if the caller already has the rename_sem */
378 full_path
= build_path_from_dentry(file
->f_dentry
);
379 if (full_path
== NULL
) {
380 up(&pCifsFile
->fh_sem
);
385 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s",
386 inode
, file
->f_flags
,full_path
));
387 desiredAccess
= cifs_convert_flags(file
->f_flags
);
394 /* Can not refresh inode by passing in file_info buf to be returned
395 by SMBOpen and then calling get_inode_info with returned buf
396 since file might have write behind data that needs to be flushed
397 and server version of file size can be stale. If we knew for sure
398 that inode was not dirty locally we could do this */
400 /* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
402 up(&pCifsFile->fh_sem);
407 rc
= CIFSSMBOpen(xid
, pTcon
, full_path
, disposition
, desiredAccess
,
408 CREATE_NOT_DIR
, &netfid
, &oplock
, NULL
,
409 cifs_sb
->local_nls
, cifs_sb
->mnt_cifs_flags
&
410 CIFS_MOUNT_MAP_SPECIAL_CHR
);
412 up(&pCifsFile
->fh_sem
);
413 cFYI(1, ("cifs_open returned 0x%x ", rc
));
414 cFYI(1, ("oplock: %d ", oplock
));
416 pCifsFile
->netfid
= netfid
;
417 pCifsFile
->invalidHandle
= FALSE
;
418 up(&pCifsFile
->fh_sem
);
419 pCifsInode
= CIFS_I(inode
);
422 filemap_fdatawrite(inode
->i_mapping
);
423 filemap_fdatawait(inode
->i_mapping
);
424 /* temporarily disable caching while we
425 go to server to get inode info */
426 pCifsInode
->clientCanCacheAll
= FALSE
;
427 pCifsInode
->clientCanCacheRead
= FALSE
;
428 if (pTcon
->ses
->capabilities
& CAP_UNIX
)
429 rc
= cifs_get_inode_info_unix(&inode
,
430 full_path
, inode
->i_sb
, xid
);
432 rc
= cifs_get_inode_info(&inode
,
433 full_path
, NULL
, inode
->i_sb
,
435 } /* else we are writing out data to server already
436 and could deadlock if we tried to flush data, and
437 since we do not know if we have data that would
438 invalidate the current end of file on the server
439 we can not go to the server to get the new inod
441 if ((oplock
& 0xF) == OPLOCK_EXCLUSIVE
) {
442 pCifsInode
->clientCanCacheAll
= TRUE
;
443 pCifsInode
->clientCanCacheRead
= TRUE
;
444 cFYI(1, ("Exclusive Oplock granted on inode %p",
445 file
->f_dentry
->d_inode
));
446 } else if ((oplock
& 0xF) == OPLOCK_READ
) {
447 pCifsInode
->clientCanCacheRead
= TRUE
;
448 pCifsInode
->clientCanCacheAll
= FALSE
;
450 pCifsInode
->clientCanCacheRead
= FALSE
;
451 pCifsInode
->clientCanCacheAll
= FALSE
;
453 cifs_relock_file(pCifsFile
);
462 int cifs_close(struct inode
*inode
, struct file
*file
)
466 struct cifs_sb_info
*cifs_sb
;
467 struct cifsTconInfo
*pTcon
;
468 struct cifsFileInfo
*pSMBFile
=
469 (struct cifsFileInfo
*)file
->private_data
;
473 cifs_sb
= CIFS_SB(inode
->i_sb
);
474 pTcon
= cifs_sb
->tcon
;
476 pSMBFile
->closePend
= TRUE
;
477 write_lock(&file
->f_owner
.lock
);
479 /* no sense reconnecting to close a file that is
481 if (pTcon
->tidStatus
!= CifsNeedReconnect
) {
483 while((atomic_read(&pSMBFile
->wrtPending
) != 0)
484 && (timeout
< 1000) ) {
485 /* Give write a better chance to get to
486 server ahead of the close. We do not
487 want to add a wait_q here as it would
488 increase the memory utilization as
489 the struct would be in each open file,
490 but this should give enough time to
492 write_unlock(&file
->f_owner
.lock
);
493 cERROR(1,("close with pending writes"));
495 write_lock(&file
->f_owner
.lock
);
498 write_unlock(&file
->f_owner
.lock
);
499 rc
= CIFSSMBClose(xid
, pTcon
,
501 write_lock(&file
->f_owner
.lock
);
504 write_lock(&GlobalSMBSeslock
);
505 list_del(&pSMBFile
->flist
);
506 list_del(&pSMBFile
->tlist
);
507 write_unlock(&GlobalSMBSeslock
);
508 write_unlock(&file
->f_owner
.lock
);
509 kfree(pSMBFile
->search_resume_name
);
510 kfree(file
->private_data
);
511 file
->private_data
= NULL
;
515 if (list_empty(&(CIFS_I(inode
)->openFileList
))) {
516 cFYI(1, ("closing last open instance for inode %p", inode
));
517 /* if the file is not open we do not know if we can cache info
518 on this inode, much less write behind and read ahead */
519 CIFS_I(inode
)->clientCanCacheRead
= FALSE
;
520 CIFS_I(inode
)->clientCanCacheAll
= FALSE
;
522 if ((rc
==0) && CIFS_I(inode
)->write_behind_rc
)
523 rc
= CIFS_I(inode
)->write_behind_rc
;
528 int cifs_closedir(struct inode
*inode
, struct file
*file
)
532 struct cifsFileInfo
*pCFileStruct
=
533 (struct cifsFileInfo
*)file
->private_data
;
536 cFYI(1, ("Closedir inode = 0x%p with ", inode
));
541 struct cifsTconInfo
*pTcon
;
542 struct cifs_sb_info
*cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
544 pTcon
= cifs_sb
->tcon
;
546 cFYI(1, ("Freeing private data in close dir"));
547 if ((pCFileStruct
->srch_inf
.endOfSearch
== FALSE
) &&
548 (pCFileStruct
->invalidHandle
== FALSE
)) {
549 pCFileStruct
->invalidHandle
= TRUE
;
550 rc
= CIFSFindClose(xid
, pTcon
, pCFileStruct
->netfid
);
551 cFYI(1, ("Closing uncompleted readdir with rc %d",
553 /* not much we can do if it fails anyway, ignore rc */
556 ptmp
= pCFileStruct
->srch_inf
.ntwrk_buf_start
;
558 /* BB removeme BB */ cFYI(1, ("freeing smb buf in srch struct in closedir"));
559 pCFileStruct
->srch_inf
.ntwrk_buf_start
= NULL
;
560 cifs_buf_release(ptmp
);
562 ptmp
= pCFileStruct
->search_resume_name
;
564 /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir"));
565 pCFileStruct
->search_resume_name
= NULL
;
568 kfree(file
->private_data
);
569 file
->private_data
= NULL
;
571 /* BB can we lock the filestruct while this is going on? */
576 int cifs_lock(struct file
*file
, int cmd
, struct file_lock
*pfLock
)
579 __u32 lockType
= LOCKING_ANDX_LARGE_FILES
;
583 int wait_flag
= FALSE
;
584 struct cifs_sb_info
*cifs_sb
;
585 struct cifsTconInfo
*pTcon
;
587 length
= 1 + pfLock
->fl_end
- pfLock
->fl_start
;
591 cFYI(1, ("Lock parm: 0x%x flockflags: "
592 "0x%x flocktype: 0x%x start: %lld end: %lld",
593 cmd
, pfLock
->fl_flags
, pfLock
->fl_type
, pfLock
->fl_start
,
596 if (pfLock
->fl_flags
& FL_POSIX
)
598 if (pfLock
->fl_flags
& FL_FLOCK
)
600 if (pfLock
->fl_flags
& FL_SLEEP
) {
601 cFYI(1, ("Blocking lock "));
604 if (pfLock
->fl_flags
& FL_ACCESS
)
605 cFYI(1, ("Process suspended by mandatory locking - "
606 "not implemented yet "));
607 if (pfLock
->fl_flags
& FL_LEASE
)
608 cFYI(1, ("Lease on file - not implemented yet"));
609 if (pfLock
->fl_flags
&
610 (~(FL_POSIX
| FL_FLOCK
| FL_SLEEP
| FL_ACCESS
| FL_LEASE
)))
611 cFYI(1, ("Unknown lock flags 0x%x", pfLock
->fl_flags
));
613 if (pfLock
->fl_type
== F_WRLCK
) {
614 cFYI(1, ("F_WRLCK "));
616 } else if (pfLock
->fl_type
== F_UNLCK
) {
617 cFYI(1, ("F_UNLCK "));
619 } else if (pfLock
->fl_type
== F_RDLCK
) {
620 cFYI(1, ("F_RDLCK "));
621 lockType
|= LOCKING_ANDX_SHARED_LOCK
;
623 } else if (pfLock
->fl_type
== F_EXLCK
) {
624 cFYI(1, ("F_EXLCK "));
626 } else if (pfLock
->fl_type
== F_SHLCK
) {
627 cFYI(1, ("F_SHLCK "));
628 lockType
|= LOCKING_ANDX_SHARED_LOCK
;
631 cFYI(1, ("Unknown type of lock "));
633 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
634 pTcon
= cifs_sb
->tcon
;
636 if (file
->private_data
== NULL
) {
642 rc
= CIFSSMBLock(xid
, pTcon
,
643 ((struct cifsFileInfo
*)file
->
644 private_data
)->netfid
,
646 pfLock
->fl_start
, 0, 1, lockType
,
649 rc
= CIFSSMBLock(xid
, pTcon
,
650 ((struct cifsFileInfo
*) file
->
651 private_data
)->netfid
,
653 pfLock
->fl_start
, 1 /* numUnlock */ ,
654 0 /* numLock */ , lockType
,
656 pfLock
->fl_type
= F_UNLCK
;
658 cERROR(1, ("Error unlocking previously locked "
659 "range %d during test of lock ",
664 /* if rc == ERR_SHARING_VIOLATION ? */
665 rc
= 0; /* do not change lock type to unlock
666 since range in use */
673 rc
= CIFSSMBLock(xid
, pTcon
,
674 ((struct cifsFileInfo
*) file
->private_data
)->
676 pfLock
->fl_start
, numUnlock
, numLock
, lockType
,
678 if (pfLock
->fl_flags
& FL_POSIX
)
679 posix_lock_file_wait(file
, pfLock
);
684 ssize_t
cifs_user_write(struct file
*file
, const char __user
*write_data
,
685 size_t write_size
, loff_t
*poffset
)
688 unsigned int bytes_written
= 0;
689 unsigned int total_written
;
690 struct cifs_sb_info
*cifs_sb
;
691 struct cifsTconInfo
*pTcon
;
693 struct cifsFileInfo
*open_file
;
695 if (file
->f_dentry
== NULL
)
698 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
702 pTcon
= cifs_sb
->tcon
;
705 (" write %d bytes to offset %lld of %s", write_size,
706 *poffset, file->f_dentry->d_name.name)); */
708 if (file
->private_data
== NULL
)
711 open_file
= (struct cifsFileInfo
*) file
->private_data
;
714 if (file
->f_dentry
->d_inode
== NULL
) {
719 if (*poffset
> file
->f_dentry
->d_inode
->i_size
)
720 long_op
= 2; /* writes past end of file can take a long time */
724 for (total_written
= 0; write_size
> total_written
;
725 total_written
+= bytes_written
) {
727 while (rc
== -EAGAIN
) {
728 if (file
->private_data
== NULL
) {
729 /* file has been closed on us */
731 /* if we have gotten here we have written some data
732 and blocked, and the file has been freed on us while
733 we blocked so return what we managed to write */
734 return total_written
;
736 if (open_file
->closePend
) {
739 return total_written
;
743 if (open_file
->invalidHandle
) {
744 if ((file
->f_dentry
== NULL
) ||
745 (file
->f_dentry
->d_inode
== NULL
)) {
747 return total_written
;
749 /* we could deadlock if we called
750 filemap_fdatawait from here so tell
751 reopen_file not to flush data to server
753 rc
= cifs_reopen_file(file
->f_dentry
->d_inode
,
759 rc
= CIFSSMBWrite(xid
, pTcon
,
761 min_t(const int, cifs_sb
->wsize
,
762 write_size
- total_written
),
763 *poffset
, &bytes_written
,
764 NULL
, write_data
+ total_written
, long_op
);
766 if (rc
|| (bytes_written
== 0)) {
774 *poffset
+= bytes_written
;
775 long_op
= FALSE
; /* subsequent writes fast -
776 15 seconds is plenty */
779 cifs_stats_bytes_written(pTcon
, total_written
);
781 /* since the write may have blocked check these pointers again */
782 if (file
->f_dentry
) {
783 if (file
->f_dentry
->d_inode
) {
784 struct inode
*inode
= file
->f_dentry
->d_inode
;
785 inode
->i_ctime
= inode
->i_mtime
=
786 current_fs_time(inode
->i_sb
);
787 if (total_written
> 0) {
788 if (*poffset
> file
->f_dentry
->d_inode
->i_size
)
789 i_size_write(file
->f_dentry
->d_inode
,
792 mark_inode_dirty_sync(file
->f_dentry
->d_inode
);
796 return total_written
;
799 static ssize_t
cifs_write(struct file
*file
, const char *write_data
,
800 size_t write_size
, loff_t
*poffset
)
803 unsigned int bytes_written
= 0;
804 unsigned int total_written
;
805 struct cifs_sb_info
*cifs_sb
;
806 struct cifsTconInfo
*pTcon
;
808 struct cifsFileInfo
*open_file
;
810 if (file
->f_dentry
== NULL
)
813 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
817 pTcon
= cifs_sb
->tcon
;
819 cFYI(1,("write %zd bytes to offset %lld of %s", write_size
,
820 *poffset
, file
->f_dentry
->d_name
.name
));
822 if (file
->private_data
== NULL
)
825 open_file
= (struct cifsFileInfo
*)file
->private_data
;
828 if (file
->f_dentry
->d_inode
== NULL
) {
833 if (*poffset
> file
->f_dentry
->d_inode
->i_size
)
834 long_op
= 2; /* writes past end of file can take a long time */
838 for (total_written
= 0; write_size
> total_written
;
839 total_written
+= bytes_written
) {
841 while (rc
== -EAGAIN
) {
842 if (file
->private_data
== NULL
) {
843 /* file has been closed on us */
845 /* if we have gotten here we have written some data
846 and blocked, and the file has been freed on us
847 while we blocked so return what we managed to
849 return total_written
;
851 if (open_file
->closePend
) {
854 return total_written
;
858 if (open_file
->invalidHandle
) {
859 if ((file
->f_dentry
== NULL
) ||
860 (file
->f_dentry
->d_inode
== NULL
)) {
862 return total_written
;
864 /* we could deadlock if we called
865 filemap_fdatawait from here so tell
866 reopen_file not to flush data to
868 rc
= cifs_reopen_file(file
->f_dentry
->d_inode
,
873 #ifdef CONFIG_CIFS_EXPERIMENTAL
874 /* BB FIXME We can not sign across two buffers yet */
875 if((experimEnabled
) && ((pTcon
->ses
->server
->secMode
&
876 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
)) == 0)) {
880 len
= min((size_t)cifs_sb
->wsize
,
881 write_size
- total_written
);
882 /* iov[0] is reserved for smb header */
883 iov
[1].iov_base
= (char *)write_data
+
885 iov
[1].iov_len
= len
;
886 rc
= CIFSSMBWrite2(xid
, pTcon
,
887 open_file
->netfid
, len
,
888 *poffset
, &bytes_written
,
891 /* BB FIXME fixup indentation of line below */
893 rc
= CIFSSMBWrite(xid
, pTcon
,
895 min_t(const int, cifs_sb
->wsize
,
896 write_size
- total_written
),
897 *poffset
, &bytes_written
,
898 write_data
+ total_written
, NULL
, long_op
);
900 if (rc
|| (bytes_written
== 0)) {
908 *poffset
+= bytes_written
;
909 long_op
= FALSE
; /* subsequent writes fast -
910 15 seconds is plenty */
913 cifs_stats_bytes_written(pTcon
, total_written
);
915 /* since the write may have blocked check these pointers again */
916 if (file
->f_dentry
) {
917 if (file
->f_dentry
->d_inode
) {
918 file
->f_dentry
->d_inode
->i_ctime
=
919 file
->f_dentry
->d_inode
->i_mtime
= CURRENT_TIME
;
920 if (total_written
> 0) {
921 if (*poffset
> file
->f_dentry
->d_inode
->i_size
)
922 i_size_write(file
->f_dentry
->d_inode
,
925 mark_inode_dirty_sync(file
->f_dentry
->d_inode
);
929 return total_written
;
932 struct cifsFileInfo
*find_writable_file(struct cifsInodeInfo
*cifs_inode
)
934 struct cifsFileInfo
*open_file
;
937 read_lock(&GlobalSMBSeslock
);
938 list_for_each_entry(open_file
, &cifs_inode
->openFileList
, flist
) {
939 if (open_file
->closePend
)
941 if (open_file
->pfile
&&
942 ((open_file
->pfile
->f_flags
& O_RDWR
) ||
943 (open_file
->pfile
->f_flags
& O_WRONLY
))) {
944 atomic_inc(&open_file
->wrtPending
);
945 read_unlock(&GlobalSMBSeslock
);
946 if((open_file
->invalidHandle
) &&
947 (!open_file
->closePend
) /* BB fixme -since the second clause can not be true remove it BB */) {
948 rc
= cifs_reopen_file(&cifs_inode
->vfs_inode
,
949 open_file
->pfile
, FALSE
);
950 /* if it fails, try another handle - might be */
951 /* dangerous to hold up writepages with retry */
953 cFYI(1,("failed on reopen file in wp"));
954 read_lock(&GlobalSMBSeslock
);
955 /* can not use this handle, no write
956 pending on this one after all */
958 (&open_file
->wrtPending
);
965 read_unlock(&GlobalSMBSeslock
);
969 static int cifs_partialpagewrite(struct page
*page
, unsigned from
, unsigned to
)
971 struct address_space
*mapping
= page
->mapping
;
972 loff_t offset
= (loff_t
)page
->index
<< PAGE_CACHE_SHIFT
;
975 int bytes_written
= 0;
976 struct cifs_sb_info
*cifs_sb
;
977 struct cifsTconInfo
*pTcon
;
979 struct cifsFileInfo
*open_file
;
981 if (!mapping
|| !mapping
->host
)
984 inode
= page
->mapping
->host
;
985 cifs_sb
= CIFS_SB(inode
->i_sb
);
986 pTcon
= cifs_sb
->tcon
;
988 offset
+= (loff_t
)from
;
989 write_data
= kmap(page
);
992 if ((to
> PAGE_CACHE_SIZE
) || (from
> to
)) {
997 /* racing with truncate? */
998 if (offset
> mapping
->host
->i_size
) {
1000 return 0; /* don't care */
1003 /* check to make sure that we are not extending the file */
1004 if (mapping
->host
->i_size
- offset
< (loff_t
)to
)
1005 to
= (unsigned)(mapping
->host
->i_size
- offset
);
1007 open_file
= find_writable_file(CIFS_I(mapping
->host
));
1009 bytes_written
= cifs_write(open_file
->pfile
, write_data
,
1011 atomic_dec(&open_file
->wrtPending
);
1012 /* Does mm or vfs already set times? */
1013 inode
->i_atime
= inode
->i_mtime
= current_fs_time(inode
->i_sb
);
1014 if ((bytes_written
> 0) && (offset
)) {
1016 } else if (bytes_written
< 0) {
1021 cFYI(1, ("No writeable filehandles for inode"));
1029 #ifdef CONFIG_CIFS_EXPERIMENTAL
1030 static int cifs_writepages(struct address_space
*mapping
,
1031 struct writeback_control
*wbc
)
1033 struct backing_dev_info
*bdi
= mapping
->backing_dev_info
;
1034 unsigned int bytes_to_write
;
1035 unsigned int bytes_written
;
1036 struct cifs_sb_info
*cifs_sb
;
1041 struct kvec iov
[32];
1047 struct cifsFileInfo
*open_file
;
1049 struct pagevec pvec
;
1054 cifs_sb
= CIFS_SB(mapping
->host
->i_sb
);
1057 * If wsize is smaller that the page cache size, default to writing
1058 * one page at a time via cifs_writepage
1060 if (cifs_sb
->wsize
< PAGE_CACHE_SIZE
)
1061 return generic_writepages(mapping
, wbc
);
1063 /* BB FIXME we do not have code to sign across multiple buffers yet,
1064 so go to older writepage style write which we can sign if needed */
1065 if((cifs_sb
->tcon
->ses
) && (cifs_sb
->tcon
->ses
->server
))
1066 if(cifs_sb
->tcon
->ses
->server
->secMode
&
1067 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
1068 return generic_writepages(mapping
, wbc
);
1071 * BB: Is this meaningful for a non-block-device file system?
1072 * If it is, we should test it again after we do I/O
1074 if (wbc
->nonblocking
&& bdi_write_congested(bdi
)) {
1075 wbc
->encountered_congestion
= 1;
1081 pagevec_init(&pvec
, 0);
1082 if (wbc
->sync_mode
== WB_SYNC_NONE
)
1083 index
= mapping
->writeback_index
; /* Start from prev offset */
1088 if (wbc
->start
|| wbc
->end
) {
1089 index
= wbc
->start
>> PAGE_CACHE_SHIFT
;
1090 end
= wbc
->end
>> PAGE_CACHE_SHIFT
;
1095 while (!done
&& (index
<= end
) &&
1096 (nr_pages
= pagevec_lookup_tag(&pvec
, mapping
, &index
,
1097 PAGECACHE_TAG_DIRTY
,
1098 min(end
- index
, (pgoff_t
)PAGEVEC_SIZE
- 1) + 1))) {
1107 for (i
= 0; i
< nr_pages
; i
++) {
1108 page
= pvec
.pages
[i
];
1110 * At this point we hold neither mapping->tree_lock nor
1111 * lock on the page itself: the page may be truncated or
1112 * invalidated (changing page->mapping to NULL), or even
1113 * swizzled back from swapper_space to tmpfs file
1119 else if (TestSetPageLocked(page
))
1122 if (unlikely(page
->mapping
!= mapping
)) {
1127 if (unlikely(is_range
) && (page
->index
> end
)) {
1133 if (next
&& (page
->index
!= next
)) {
1134 /* Not next consecutive page */
1139 if (wbc
->sync_mode
!= WB_SYNC_NONE
)
1140 wait_on_page_writeback(page
);
1142 if (PageWriteback(page
) ||
1143 !test_clear_page_dirty(page
)) {
1148 if (page_offset(page
) >= mapping
->host
->i_size
) {
1155 * BB can we get rid of this? pages are held by pvec
1157 page_cache_get(page
);
1159 len
= min(mapping
->host
->i_size
- page_offset(page
),
1160 (loff_t
)PAGE_CACHE_SIZE
);
1162 /* reserve iov[0] for the smb header */
1164 iov
[n_iov
].iov_base
= kmap(page
);
1165 iov
[n_iov
].iov_len
= len
;
1166 bytes_to_write
+= len
;
1170 offset
= page_offset(page
);
1172 next
= page
->index
+ 1;
1173 if (bytes_to_write
+ PAGE_CACHE_SIZE
> cifs_sb
->wsize
)
1177 /* Search for a writable handle every time we call
1178 * CIFSSMBWrite2. We can't rely on the last handle
1179 * we used to still be valid
1181 open_file
= find_writable_file(CIFS_I(mapping
->host
));
1183 cERROR(1, ("No writable handles for inode"));
1186 rc
= CIFSSMBWrite2(xid
, cifs_sb
->tcon
,
1188 bytes_to_write
, offset
,
1189 &bytes_written
, iov
, n_iov
,
1191 atomic_dec(&open_file
->wrtPending
);
1192 if (rc
|| bytes_written
< bytes_to_write
) {
1193 cERROR(1,("Write2 ret %d, written = %d",
1194 rc
, bytes_written
));
1195 /* BB what if continued retry is
1196 requested via mount flags? */
1197 set_bit(AS_EIO
, &mapping
->flags
);
1200 cifs_stats_bytes_written(cifs_sb
->tcon
,
1204 for (i
= 0; i
< n_iov
; i
++) {
1205 page
= pvec
.pages
[first
+ i
];
1208 page_cache_release(page
);
1210 if ((wbc
->nr_to_write
-= n_iov
) <= 0)
1214 pagevec_release(&pvec
);
1216 if (!scanned
&& !done
) {
1218 * We hit the last page and there is more work to be done: wrap
1219 * back to the start of the file
1226 mapping
->writeback_index
= index
;
1234 static int cifs_writepage(struct page
* page
, struct writeback_control
*wbc
)
1240 /* BB add check for wbc flags */
1241 page_cache_get(page
);
1242 if (!PageUptodate(page
)) {
1243 cFYI(1, ("ppw - page not up to date"));
1246 rc
= cifs_partialpagewrite(page
, 0, PAGE_CACHE_SIZE
);
1247 SetPageUptodate(page
); /* BB add check for error and Clearuptodate? */
1249 page_cache_release(page
);
1254 static int cifs_commit_write(struct file
*file
, struct page
*page
,
1255 unsigned offset
, unsigned to
)
1259 struct inode
*inode
= page
->mapping
->host
;
1260 loff_t position
= ((loff_t
)page
->index
<< PAGE_CACHE_SHIFT
) + to
;
1264 cFYI(1, ("commit write for page %p up to position %lld for %d",
1265 page
, position
, to
));
1266 if (position
> inode
->i_size
) {
1267 i_size_write(inode
, position
);
1268 /* if (file->private_data == NULL) {
1271 open_file = (struct cifsFileInfo *)file->private_data;
1272 cifs_sb = CIFS_SB(inode->i_sb);
1274 while (rc == -EAGAIN) {
1275 if ((open_file->invalidHandle) &&
1276 (!open_file->closePend)) {
1277 rc = cifs_reopen_file(
1278 file->f_dentry->d_inode, file);
1282 if (!open_file->closePend) {
1283 rc = CIFSSMBSetFileSize(xid,
1284 cifs_sb->tcon, position,
1286 open_file->pid, FALSE);
1292 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1295 if (!PageUptodate(page
)) {
1296 position
= ((loff_t
)page
->index
<< PAGE_CACHE_SHIFT
) + offset
;
1297 /* can not rely on (or let) writepage write this data */
1299 cFYI(1, ("Illegal offsets, can not copy from %d to %d",
1304 /* this is probably better than directly calling
1305 partialpage_write since in this function the file handle is
1306 known which we might as well leverage */
1307 /* BB check if anything else missing out of ppw
1308 such as updating last write time */
1309 page_data
= kmap(page
);
1310 rc
= cifs_write(file
, page_data
+ offset
, to
-offset
,
1314 /* else if (rc < 0) should we set writebehind rc? */
1317 set_page_dirty(page
);
1324 int cifs_fsync(struct file
*file
, struct dentry
*dentry
, int datasync
)
1328 struct inode
*inode
= file
->f_dentry
->d_inode
;
1332 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
1333 dentry
->d_name
.name
, datasync
));
1335 rc
= filemap_fdatawrite(inode
->i_mapping
);
1337 CIFS_I(inode
)->write_behind_rc
= 0;
1342 /* static int cifs_sync_page(struct page *page)
1344 struct address_space *mapping;
1345 struct inode *inode;
1346 unsigned long index = page->index;
1347 unsigned int rpages = 0;
1350 cFYI(1, ("sync page %p",page));
1351 mapping = page->mapping;
1354 inode = mapping->host;
1358 /* fill in rpages then
1359 result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */
1361 /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
1369 * As file closes, flush all cached write data for this inode checking
1370 * for write behind errors.
1372 int cifs_flush(struct file
*file
)
1374 struct inode
* inode
= file
->f_dentry
->d_inode
;
1377 /* Rather than do the steps manually:
1378 lock the inode for writing
1379 loop through pages looking for write behind data (dirty pages)
1380 coalesce into contiguous 16K (or smaller) chunks to write to server
1381 send to server (prefer in parallel)
1382 deal with writebehind errors
1383 unlock inode for writing
1384 filemapfdatawrite appears easier for the time being */
1386 rc
= filemap_fdatawrite(inode
->i_mapping
);
1387 if (!rc
) /* reset wb rc if we were able to write out dirty pages */
1388 CIFS_I(inode
)->write_behind_rc
= 0;
1390 cFYI(1, ("Flush inode %p file %p rc %d",inode
,file
,rc
));
1395 ssize_t
cifs_user_read(struct file
*file
, char __user
*read_data
,
1396 size_t read_size
, loff_t
*poffset
)
1399 unsigned int bytes_read
= 0;
1400 unsigned int total_read
= 0;
1401 unsigned int current_read_size
;
1402 struct cifs_sb_info
*cifs_sb
;
1403 struct cifsTconInfo
*pTcon
;
1405 struct cifsFileInfo
*open_file
;
1406 char *smb_read_data
;
1407 char __user
*current_offset
;
1408 struct smb_com_read_rsp
*pSMBr
;
1411 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
1412 pTcon
= cifs_sb
->tcon
;
1414 if (file
->private_data
== NULL
) {
1418 open_file
= (struct cifsFileInfo
*)file
->private_data
;
1420 if ((file
->f_flags
& O_ACCMODE
) == O_WRONLY
) {
1421 cFYI(1, ("attempting read on write only file instance"));
1423 for (total_read
= 0, current_offset
= read_data
;
1424 read_size
> total_read
;
1425 total_read
+= bytes_read
, current_offset
+= bytes_read
) {
1426 current_read_size
= min_t(const int, read_size
- total_read
,
1429 smb_read_data
= NULL
;
1430 while (rc
== -EAGAIN
) {
1431 if ((open_file
->invalidHandle
) &&
1432 (!open_file
->closePend
)) {
1433 rc
= cifs_reopen_file(file
->f_dentry
->d_inode
,
1438 rc
= CIFSSMBRead(xid
, pTcon
,
1440 current_read_size
, *poffset
,
1441 &bytes_read
, &smb_read_data
);
1442 pSMBr
= (struct smb_com_read_rsp
*)smb_read_data
;
1443 if (copy_to_user(current_offset
,
1444 smb_read_data
+ 4 /* RFC1001 hdr */
1445 + le16_to_cpu(pSMBr
->DataOffset
),
1451 if (smb_read_data
) {
1452 cifs_buf_release(smb_read_data
);
1453 smb_read_data
= NULL
;
1456 if (rc
|| (bytes_read
== 0)) {
1464 cifs_stats_bytes_read(pTcon
, bytes_read
);
1465 *poffset
+= bytes_read
;
1473 static ssize_t
cifs_read(struct file
*file
, char *read_data
, size_t read_size
,
1477 unsigned int bytes_read
= 0;
1478 unsigned int total_read
;
1479 unsigned int current_read_size
;
1480 struct cifs_sb_info
*cifs_sb
;
1481 struct cifsTconInfo
*pTcon
;
1483 char *current_offset
;
1484 struct cifsFileInfo
*open_file
;
1487 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
1488 pTcon
= cifs_sb
->tcon
;
1490 if (file
->private_data
== NULL
) {
1494 open_file
= (struct cifsFileInfo
*)file
->private_data
;
1496 if ((file
->f_flags
& O_ACCMODE
) == O_WRONLY
)
1497 cFYI(1, ("attempting read on write only file instance"));
1499 for (total_read
= 0, current_offset
= read_data
;
1500 read_size
> total_read
;
1501 total_read
+= bytes_read
, current_offset
+= bytes_read
) {
1502 current_read_size
= min_t(const int, read_size
- total_read
,
1504 /* For windows me and 9x we do not want to request more
1505 than it negotiated since it will refuse the read then */
1507 !(pTcon
->ses
->capabilities
& CAP_LARGE_FILES
)) {
1508 current_read_size
= min_t(const int, current_read_size
,
1509 pTcon
->ses
->server
->maxBuf
- 128);
1512 while (rc
== -EAGAIN
) {
1513 if ((open_file
->invalidHandle
) &&
1514 (!open_file
->closePend
)) {
1515 rc
= cifs_reopen_file(file
->f_dentry
->d_inode
,
1520 rc
= CIFSSMBRead(xid
, pTcon
,
1522 current_read_size
, *poffset
,
1523 &bytes_read
, ¤t_offset
);
1525 if (rc
|| (bytes_read
== 0)) {
1533 cifs_stats_bytes_read(pTcon
, total_read
);
1534 *poffset
+= bytes_read
;
1541 int cifs_file_mmap(struct file
*file
, struct vm_area_struct
*vma
)
1543 struct dentry
*dentry
= file
->f_dentry
;
1547 rc
= cifs_revalidate(dentry
);
1549 cFYI(1, ("Validation prior to mmap failed, error=%d", rc
));
1553 rc
= generic_file_mmap(file
, vma
);
1559 static void cifs_copy_cache_pages(struct address_space
*mapping
,
1560 struct list_head
*pages
, int bytes_read
, char *data
,
1561 struct pagevec
*plru_pvec
)
1566 while (bytes_read
> 0) {
1567 if (list_empty(pages
))
1570 page
= list_entry(pages
->prev
, struct page
, lru
);
1571 list_del(&page
->lru
);
1573 if (add_to_page_cache(page
, mapping
, page
->index
,
1575 page_cache_release(page
);
1576 cFYI(1, ("Add page cache failed"));
1577 data
+= PAGE_CACHE_SIZE
;
1578 bytes_read
-= PAGE_CACHE_SIZE
;
1582 target
= kmap_atomic(page
,KM_USER0
);
1584 if (PAGE_CACHE_SIZE
> bytes_read
) {
1585 memcpy(target
, data
, bytes_read
);
1586 /* zero the tail end of this partial page */
1587 memset(target
+ bytes_read
, 0,
1588 PAGE_CACHE_SIZE
- bytes_read
);
1591 memcpy(target
, data
, PAGE_CACHE_SIZE
);
1592 bytes_read
-= PAGE_CACHE_SIZE
;
1594 kunmap_atomic(target
, KM_USER0
);
1596 flush_dcache_page(page
);
1597 SetPageUptodate(page
);
1599 if (!pagevec_add(plru_pvec
, page
))
1600 __pagevec_lru_add(plru_pvec
);
1601 data
+= PAGE_CACHE_SIZE
;
1606 static int cifs_readpages(struct file
*file
, struct address_space
*mapping
,
1607 struct list_head
*page_list
, unsigned num_pages
)
1613 struct cifs_sb_info
*cifs_sb
;
1614 struct cifsTconInfo
*pTcon
;
1616 unsigned int read_size
,i
;
1617 char *smb_read_data
= NULL
;
1618 struct smb_com_read_rsp
*pSMBr
;
1619 struct pagevec lru_pvec
;
1620 struct cifsFileInfo
*open_file
;
1623 if (file
->private_data
== NULL
) {
1627 open_file
= (struct cifsFileInfo
*)file
->private_data
;
1628 cifs_sb
= CIFS_SB(file
->f_dentry
->d_sb
);
1629 pTcon
= cifs_sb
->tcon
;
1631 pagevec_init(&lru_pvec
, 0);
1633 for (i
= 0; i
< num_pages
; ) {
1634 unsigned contig_pages
;
1635 struct page
*tmp_page
;
1636 unsigned long expected_index
;
1638 if (list_empty(page_list
))
1641 page
= list_entry(page_list
->prev
, struct page
, lru
);
1642 offset
= (loff_t
)page
->index
<< PAGE_CACHE_SHIFT
;
1644 /* count adjacent pages that we will read into */
1647 list_entry(page_list
->prev
, struct page
, lru
)->index
;
1648 list_for_each_entry_reverse(tmp_page
,page_list
,lru
) {
1649 if (tmp_page
->index
== expected_index
) {
1655 if (contig_pages
+ i
> num_pages
)
1656 contig_pages
= num_pages
- i
;
1658 /* for reads over a certain size could initiate async
1661 read_size
= contig_pages
* PAGE_CACHE_SIZE
;
1662 /* Read size needs to be in multiples of one page */
1663 read_size
= min_t(const unsigned int, read_size
,
1664 cifs_sb
->rsize
& PAGE_CACHE_MASK
);
1667 while (rc
== -EAGAIN
) {
1668 if ((open_file
->invalidHandle
) &&
1669 (!open_file
->closePend
)) {
1670 rc
= cifs_reopen_file(file
->f_dentry
->d_inode
,
1676 rc
= CIFSSMBRead(xid
, pTcon
,
1679 &bytes_read
, &smb_read_data
);
1681 /* BB more RC checks ? */
1683 if (smb_read_data
) {
1684 cifs_buf_release(smb_read_data
);
1685 smb_read_data
= NULL
;
1689 if ((rc
< 0) || (smb_read_data
== NULL
)) {
1690 cFYI(1, ("Read error in readpages: %d", rc
));
1691 /* clean up remaing pages off list */
1692 while (!list_empty(page_list
) && (i
< num_pages
)) {
1693 page
= list_entry(page_list
->prev
, struct page
,
1695 list_del(&page
->lru
);
1696 page_cache_release(page
);
1699 } else if (bytes_read
> 0) {
1700 pSMBr
= (struct smb_com_read_rsp
*)smb_read_data
;
1701 cifs_copy_cache_pages(mapping
, page_list
, bytes_read
,
1702 smb_read_data
+ 4 /* RFC1001 hdr */ +
1703 le16_to_cpu(pSMBr
->DataOffset
), &lru_pvec
);
1705 i
+= bytes_read
>> PAGE_CACHE_SHIFT
;
1706 cifs_stats_bytes_read(pTcon
, bytes_read
);
1707 if ((int)(bytes_read
& PAGE_CACHE_MASK
) != bytes_read
) {
1708 i
++; /* account for partial page */
1710 /* server copy of file can have smaller size
1712 /* BB do we need to verify this common case ?
1713 this case is ok - if we are at server EOF
1714 we will hit it on next read */
1716 /* while (!list_empty(page_list) && (i < num_pages)) {
1717 page = list_entry(page_list->prev,
1719 list_del(&page->list);
1720 page_cache_release(page);
1725 cFYI(1, ("No bytes read (%d) at offset %lld . "
1726 "Cleaning remaining pages from readahead list",
1727 bytes_read
, offset
));
1728 /* BB turn off caching and do new lookup on
1729 file size at server? */
1730 while (!list_empty(page_list
) && (i
< num_pages
)) {
1731 page
= list_entry(page_list
->prev
, struct page
,
1733 list_del(&page
->lru
);
1735 /* BB removeme - replace with zero of page? */
1736 page_cache_release(page
);
1740 if (smb_read_data
) {
1741 cifs_buf_release(smb_read_data
);
1742 smb_read_data
= NULL
;
1747 pagevec_lru_add(&lru_pvec
);
1749 /* need to free smb_read_data buf before exit */
1750 if (smb_read_data
) {
1751 cifs_buf_release(smb_read_data
);
1752 smb_read_data
= NULL
;
1759 static int cifs_readpage_worker(struct file
*file
, struct page
*page
,
1765 page_cache_get(page
);
1766 read_data
= kmap(page
);
1767 /* for reads over a certain size could initiate async read ahead */
1769 rc
= cifs_read(file
, read_data
, PAGE_CACHE_SIZE
, poffset
);
1774 cFYI(1, ("Bytes read %d ",rc
));
1776 file
->f_dentry
->d_inode
->i_atime
=
1777 current_fs_time(file
->f_dentry
->d_inode
->i_sb
);
1779 if (PAGE_CACHE_SIZE
> rc
)
1780 memset(read_data
+ rc
, 0, PAGE_CACHE_SIZE
- rc
);
1782 flush_dcache_page(page
);
1783 SetPageUptodate(page
);
1788 page_cache_release(page
);
1792 static int cifs_readpage(struct file
*file
, struct page
*page
)
1794 loff_t offset
= (loff_t
)page
->index
<< PAGE_CACHE_SHIFT
;
1800 if (file
->private_data
== NULL
) {
1805 cFYI(1, ("readpage %p at offset %d 0x%x\n",
1806 page
, (int)offset
, (int)offset
));
1808 rc
= cifs_readpage_worker(file
, page
, &offset
);
1816 /* We do not want to update the file size from server for inodes
1817 open for write - to avoid races with writepage extending
1818 the file - in the future we could consider allowing
1819 refreshing the inode only on increases in the file size
1820 but this is tricky to do without racing with writebehind
1821 page caching in the current Linux kernel design */
1822 int is_size_safe_to_change(struct cifsInodeInfo
*cifsInode
)
1824 struct cifsFileInfo
*open_file
= NULL
;
1827 open_file
= find_writable_file(cifsInode
);
1830 /* there is not actually a write pending so let
1831 this handle go free and allow it to
1832 be closable if needed */
1833 atomic_dec(&open_file
->wrtPending
);
1839 static int cifs_prepare_write(struct file
*file
, struct page
*page
,
1840 unsigned from
, unsigned to
)
1843 loff_t offset
= (loff_t
)page
->index
<< PAGE_CACHE_SHIFT
;
1844 cFYI(1, ("prepare write for page %p from %d to %d",page
,from
,to
));
1845 if (!PageUptodate(page
)) {
1846 /* if (to - from != PAGE_CACHE_SIZE) {
1847 void *kaddr = kmap_atomic(page, KM_USER0);
1848 memset(kaddr, 0, from);
1849 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
1850 flush_dcache_page(page);
1851 kunmap_atomic(kaddr, KM_USER0);
1853 /* If we are writing a full page it will be up to date,
1854 no need to read from the server */
1855 if ((to
== PAGE_CACHE_SIZE
) && (from
== 0))
1856 SetPageUptodate(page
);
1858 /* might as well read a page, it is fast enough */
1859 if ((file
->f_flags
& O_ACCMODE
) != O_WRONLY
) {
1860 rc
= cifs_readpage_worker(file
, page
, &offset
);
1862 /* should we try using another file handle if there is one -
1863 how would we lock it to prevent close of that handle
1864 racing with this read?
1865 In any case this will be written out by commit_write */
1869 /* BB should we pass any errors back?
1870 e.g. if we do not have read access to the file */
1874 struct address_space_operations cifs_addr_ops
= {
1875 .readpage
= cifs_readpage
,
1876 .readpages
= cifs_readpages
,
1877 .writepage
= cifs_writepage
,
1878 #ifdef CONFIG_CIFS_EXPERIMENTAL
1879 .writepages
= cifs_writepages
,
1881 .prepare_write
= cifs_prepare_write
,
1882 .commit_write
= cifs_commit_write
,
1883 .set_page_dirty
= __set_page_dirty_nobuffers
,
1884 /* .sync_page = cifs_sync_page, */