[PATCH] configfs: User-driven configuration filesystem
[linux-2.6/mini2440.git] / fs / cifs / file.c
blob14a1c72ced92e1cc98024494ea217b2a7413921d
1 /*
2 * fs/cifs/file.c
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)
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
23 #include <linux/fs.h>
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>
34 #include "cifsfs.h"
35 #include "cifspdu.h"
36 #include "cifsglob.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);
60 return private_data;
63 static inline int cifs_convert_flags(unsigned int flags)
65 if ((flags & O_ACCMODE) == O_RDONLY)
66 return GENERIC_READ;
67 else if ((flags & O_ACCMODE) == O_WRONLY)
68 return GENERIC_WRITE;
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);
76 return 0x20197;
79 static inline int cifs_get_disposition(unsigned int flags)
81 if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
82 return FILE_CREATE;
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)
86 return FILE_OPEN_IF;
87 else
88 return FILE_OPEN;
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)
97 struct timespec temp;
98 int rc;
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);
106 } else {
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
120 size changed */
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"));
126 } else {
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 "
134 "changed"));
135 invalidate_remote_inode(file->f_dentry->d_inode);
138 client_can_cache:
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);
142 else
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;
154 return rc;
157 int cifs_open(struct inode *inode, struct file *file)
159 int rc = -EACCES;
160 int xid, oplock;
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;
167 int desiredAccess;
168 int disposition;
169 __u16 netfid;
170 FILE_ALL_INFO *buf = NULL;
172 xid = GetXid();
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,
183 flist);
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;
192 break;
195 read_unlock(&GlobalSMBSeslock);
196 if (file->private_data != NULL) {
197 rc = 0;
198 FreeXid(xid);
199 return rc;
200 } else {
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) {
211 FreeXid(xid);
212 return -ENOMEM;
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);
245 if (oplockEnabled)
246 oplock = REQ_OPLOCK;
247 else
248 oplock = FALSE;
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);
260 if (!buf) {
261 rc = -ENOMEM;
262 goto out;
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);
268 if (rc == -EIO) {
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);
275 if (rc) {
276 cFYI(1, ("cifs_open returned 0x%x ", rc));
277 goto out;
279 file->private_data =
280 kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
281 if (file->private_data == NULL) {
282 rc = -ENOMEM;
283 goto out;
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);
291 if (pCifsInode) {
292 rc = cifs_open_inode_helper(inode, file, pCifsInode,
293 pCifsFile, pTcon,
294 &oplock, buf, full_path, xid);
295 } else {
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,
305 inode->i_mode,
306 (__u64)-1, (__u64)-1, 0 /* dev */,
307 cifs_sb->local_nls,
308 cifs_sb->mnt_cifs_flags &
309 CIFS_MOUNT_MAP_SPECIAL_CHR);
310 } else {
311 /* BB implement via Windows security descriptors eg
312 CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
313 -1, -1, local_nls);
314 in the meantime could set r/o dos attribute when
315 perms are eg: mode & 0222 == 0 */
319 out:
320 kfree(buf);
321 kfree(full_path);
322 FreeXid(xid);
323 return rc;
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)
330 int rc = 0;
332 /* BB list all locks open on this file and relock */
334 return rc;
337 static int cifs_reopen_file(struct inode *inode, struct file *file,
338 int can_flush)
340 int rc = -EACCES;
341 int xid, oplock;
342 struct cifs_sb_info *cifs_sb;
343 struct cifsTconInfo *pTcon;
344 struct cifsFileInfo *pCifsFile;
345 struct cifsInodeInfo *pCifsInode;
346 char *full_path = NULL;
347 int desiredAccess;
348 int disposition = FILE_OPEN;
349 __u16 netfid;
351 if (inode == NULL)
352 return -EBADF;
353 if (file->private_data) {
354 pCifsFile = (struct cifsFileInfo *)file->private_data;
355 } else
356 return -EBADF;
358 xid = GetXid();
359 down(&pCifsFile->fh_sem);
360 if (pCifsFile->invalidHandle == FALSE) {
361 up(&pCifsFile->fh_sem);
362 FreeXid(xid);
363 return 0;
366 if (file->f_dentry == NULL) {
367 up(&pCifsFile->fh_sem);
368 cFYI(1, ("failed file reopen, no valid name if dentry freed"));
369 FreeXid(xid);
370 return -EBADF;
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);
381 FreeXid(xid);
382 return -ENOMEM;
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);
389 if (oplockEnabled)
390 oplock = REQ_OPLOCK;
391 else
392 oplock = FALSE;
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);
401 if (buf == 0) {
402 up(&pCifsFile->fh_sem);
403 kfree(full_path);
404 FreeXid(xid);
405 return -ENOMEM;
406 } */
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);
411 if (rc) {
412 up(&pCifsFile->fh_sem);
413 cFYI(1, ("cifs_open returned 0x%x ", rc));
414 cFYI(1, ("oplock: %d ", oplock));
415 } else {
416 pCifsFile->netfid = netfid;
417 pCifsFile->invalidHandle = FALSE;
418 up(&pCifsFile->fh_sem);
419 pCifsInode = CIFS_I(inode);
420 if (pCifsInode) {
421 if (can_flush) {
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);
431 else
432 rc = cifs_get_inode_info(&inode,
433 full_path, NULL, inode->i_sb,
434 xid);
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
440 info */
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;
449 } else {
450 pCifsInode->clientCanCacheRead = FALSE;
451 pCifsInode->clientCanCacheAll = FALSE;
453 cifs_relock_file(pCifsFile);
457 kfree(full_path);
458 FreeXid(xid);
459 return rc;
462 int cifs_close(struct inode *inode, struct file *file)
464 int rc = 0;
465 int xid;
466 struct cifs_sb_info *cifs_sb;
467 struct cifsTconInfo *pTcon;
468 struct cifsFileInfo *pSMBFile =
469 (struct cifsFileInfo *)file->private_data;
471 xid = GetXid();
473 cifs_sb = CIFS_SB(inode->i_sb);
474 pTcon = cifs_sb->tcon;
475 if (pSMBFile) {
476 pSMBFile->closePend = TRUE;
477 write_lock(&file->f_owner.lock);
478 if (pTcon) {
479 /* no sense reconnecting to close a file that is
480 already closed */
481 if (pTcon->tidStatus != CifsNeedReconnect) {
482 int timeout = 2;
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
491 clear the socket */
492 write_unlock(&file->f_owner.lock);
493 cERROR(1,("close with pending writes"));
494 msleep(timeout);
495 write_lock(&file->f_owner.lock);
496 timeout *= 4;
498 write_unlock(&file->f_owner.lock);
499 rc = CIFSSMBClose(xid, pTcon,
500 pSMBFile->netfid);
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;
512 } else
513 rc = -EBADF;
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;
524 FreeXid(xid);
525 return rc;
528 int cifs_closedir(struct inode *inode, struct file *file)
530 int rc = 0;
531 int xid;
532 struct cifsFileInfo *pCFileStruct =
533 (struct cifsFileInfo *)file->private_data;
534 char *ptmp;
536 cFYI(1, ("Closedir inode = 0x%p with ", inode));
538 xid = GetXid();
540 if (pCFileStruct) {
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",
552 rc));
553 /* not much we can do if it fails anyway, ignore rc */
554 rc = 0;
556 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
557 if (ptmp) {
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;
563 if (ptmp) {
564 /* BB removeme BB */ cFYI(1, ("freeing resume name in closedir"));
565 pCFileStruct->search_resume_name = NULL;
566 kfree(ptmp);
568 kfree(file->private_data);
569 file->private_data = NULL;
571 /* BB can we lock the filestruct while this is going on? */
572 FreeXid(xid);
573 return rc;
576 int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
578 int rc, xid;
579 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
580 __u32 numLock = 0;
581 __u32 numUnlock = 0;
582 __u64 length;
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;
588 rc = -EACCES;
589 xid = GetXid();
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,
594 pfLock->fl_end));
596 if (pfLock->fl_flags & FL_POSIX)
597 cFYI(1, ("Posix "));
598 if (pfLock->fl_flags & FL_FLOCK)
599 cFYI(1, ("Flock "));
600 if (pfLock->fl_flags & FL_SLEEP) {
601 cFYI(1, ("Blocking lock "));
602 wait_flag = TRUE;
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 "));
615 numLock = 1;
616 } else if (pfLock->fl_type == F_UNLCK) {
617 cFYI(1, ("F_UNLCK "));
618 numUnlock = 1;
619 } else if (pfLock->fl_type == F_RDLCK) {
620 cFYI(1, ("F_RDLCK "));
621 lockType |= LOCKING_ANDX_SHARED_LOCK;
622 numLock = 1;
623 } else if (pfLock->fl_type == F_EXLCK) {
624 cFYI(1, ("F_EXLCK "));
625 numLock = 1;
626 } else if (pfLock->fl_type == F_SHLCK) {
627 cFYI(1, ("F_SHLCK "));
628 lockType |= LOCKING_ANDX_SHARED_LOCK;
629 numLock = 1;
630 } else
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) {
637 FreeXid(xid);
638 return -EBADF;
641 if (IS_GETLK(cmd)) {
642 rc = CIFSSMBLock(xid, pTcon,
643 ((struct cifsFileInfo *)file->
644 private_data)->netfid,
645 length,
646 pfLock->fl_start, 0, 1, lockType,
647 0 /* wait flag */ );
648 if (rc == 0) {
649 rc = CIFSSMBLock(xid, pTcon,
650 ((struct cifsFileInfo *) file->
651 private_data)->netfid,
652 length,
653 pfLock->fl_start, 1 /* numUnlock */ ,
654 0 /* numLock */ , lockType,
655 0 /* wait flag */ );
656 pfLock->fl_type = F_UNLCK;
657 if (rc != 0)
658 cERROR(1, ("Error unlocking previously locked "
659 "range %d during test of lock ",
660 rc));
661 rc = 0;
663 } else {
664 /* if rc == ERR_SHARING_VIOLATION ? */
665 rc = 0; /* do not change lock type to unlock
666 since range in use */
669 FreeXid(xid);
670 return rc;
673 rc = CIFSSMBLock(xid, pTcon,
674 ((struct cifsFileInfo *) file->private_data)->
675 netfid, length,
676 pfLock->fl_start, numUnlock, numLock, lockType,
677 wait_flag);
678 if (pfLock->fl_flags & FL_POSIX)
679 posix_lock_file_wait(file, pfLock);
680 FreeXid(xid);
681 return rc;
684 ssize_t cifs_user_write(struct file *file, const char __user *write_data,
685 size_t write_size, loff_t *poffset)
687 int rc = 0;
688 unsigned int bytes_written = 0;
689 unsigned int total_written;
690 struct cifs_sb_info *cifs_sb;
691 struct cifsTconInfo *pTcon;
692 int xid, long_op;
693 struct cifsFileInfo *open_file;
695 if (file->f_dentry == NULL)
696 return -EBADF;
698 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
699 if (cifs_sb == NULL)
700 return -EBADF;
702 pTcon = cifs_sb->tcon;
704 /* cFYI(1,
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)
709 return -EBADF;
710 else
711 open_file = (struct cifsFileInfo *) file->private_data;
713 xid = GetXid();
714 if (file->f_dentry->d_inode == NULL) {
715 FreeXid(xid);
716 return -EBADF;
719 if (*poffset > file->f_dentry->d_inode->i_size)
720 long_op = 2; /* writes past end of file can take a long time */
721 else
722 long_op = 1;
724 for (total_written = 0; write_size > total_written;
725 total_written += bytes_written) {
726 rc = -EAGAIN;
727 while (rc == -EAGAIN) {
728 if (file->private_data == NULL) {
729 /* file has been closed on us */
730 FreeXid(xid);
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) {
737 FreeXid(xid);
738 if (total_written)
739 return total_written;
740 else
741 return -EBADF;
743 if (open_file->invalidHandle) {
744 if ((file->f_dentry == NULL) ||
745 (file->f_dentry->d_inode == NULL)) {
746 FreeXid(xid);
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
752 now */
753 rc = cifs_reopen_file(file->f_dentry->d_inode,
754 file, FALSE);
755 if (rc != 0)
756 break;
759 rc = CIFSSMBWrite(xid, pTcon,
760 open_file->netfid,
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)) {
767 if (total_written)
768 break;
769 else {
770 FreeXid(xid);
771 return rc;
773 } else
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,
790 *poffset);
792 mark_inode_dirty_sync(file->f_dentry->d_inode);
795 FreeXid(xid);
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)
802 int rc = 0;
803 unsigned int bytes_written = 0;
804 unsigned int total_written;
805 struct cifs_sb_info *cifs_sb;
806 struct cifsTconInfo *pTcon;
807 int xid, long_op;
808 struct cifsFileInfo *open_file;
810 if (file->f_dentry == NULL)
811 return -EBADF;
813 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
814 if (cifs_sb == NULL)
815 return -EBADF;
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)
823 return -EBADF;
824 else
825 open_file = (struct cifsFileInfo *)file->private_data;
827 xid = GetXid();
828 if (file->f_dentry->d_inode == NULL) {
829 FreeXid(xid);
830 return -EBADF;
833 if (*poffset > file->f_dentry->d_inode->i_size)
834 long_op = 2; /* writes past end of file can take a long time */
835 else
836 long_op = 1;
838 for (total_written = 0; write_size > total_written;
839 total_written += bytes_written) {
840 rc = -EAGAIN;
841 while (rc == -EAGAIN) {
842 if (file->private_data == NULL) {
843 /* file has been closed on us */
844 FreeXid(xid);
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
848 write */
849 return total_written;
851 if (open_file->closePend) {
852 FreeXid(xid);
853 if (total_written)
854 return total_written;
855 else
856 return -EBADF;
858 if (open_file->invalidHandle) {
859 if ((file->f_dentry == NULL) ||
860 (file->f_dentry->d_inode == NULL)) {
861 FreeXid(xid);
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
867 server now */
868 rc = cifs_reopen_file(file->f_dentry->d_inode,
869 file, FALSE);
870 if (rc != 0)
871 break;
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)) {
877 struct kvec iov[2];
878 unsigned int len;
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 +
884 total_written;
885 iov[1].iov_len = len;
886 rc = CIFSSMBWrite2(xid, pTcon,
887 open_file->netfid, len,
888 *poffset, &bytes_written,
889 iov, 1, long_op);
890 } else
891 /* BB FIXME fixup indentation of line below */
892 #endif
893 rc = CIFSSMBWrite(xid, pTcon,
894 open_file->netfid,
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)) {
901 if (total_written)
902 break;
903 else {
904 FreeXid(xid);
905 return rc;
907 } else
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,
923 *poffset);
925 mark_inode_dirty_sync(file->f_dentry->d_inode);
928 FreeXid(xid);
929 return total_written;
932 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
934 struct cifsFileInfo *open_file;
935 int rc;
937 read_lock(&GlobalSMBSeslock);
938 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
939 if (open_file->closePend)
940 continue;
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 */
952 if(rc) {
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 */
957 atomic_dec
958 (&open_file->wrtPending);
959 continue;
962 return open_file;
965 read_unlock(&GlobalSMBSeslock);
966 return NULL;
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;
973 char *write_data;
974 int rc = -EFAULT;
975 int bytes_written = 0;
976 struct cifs_sb_info *cifs_sb;
977 struct cifsTconInfo *pTcon;
978 struct inode *inode;
979 struct cifsFileInfo *open_file;
981 if (!mapping || !mapping->host)
982 return -EFAULT;
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);
990 write_data += from;
992 if ((to > PAGE_CACHE_SIZE) || (from > to)) {
993 kunmap(page);
994 return -EIO;
997 /* racing with truncate? */
998 if (offset > mapping->host->i_size) {
999 kunmap(page);
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));
1008 if (open_file) {
1009 bytes_written = cifs_write(open_file->pfile, write_data,
1010 to-from, &offset);
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)) {
1015 rc = 0;
1016 } else if (bytes_written < 0) {
1017 if (rc != -EBADF)
1018 rc = bytes_written;
1020 } else {
1021 cFYI(1, ("No writeable filehandles for inode"));
1022 rc = -EIO;
1025 kunmap(page);
1026 return rc;
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;
1037 int done = 0;
1038 pgoff_t end = -1;
1039 pgoff_t index;
1040 int is_range = 0;
1041 struct kvec iov[32];
1042 int len;
1043 int n_iov = 0;
1044 pgoff_t next;
1045 int nr_pages;
1046 __u64 offset = 0;
1047 struct cifsFileInfo *open_file;
1048 struct page *page;
1049 struct pagevec pvec;
1050 int rc = 0;
1051 int scanned = 0;
1052 int xid;
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;
1076 return 0;
1079 xid = GetXid();
1081 pagevec_init(&pvec, 0);
1082 if (wbc->sync_mode == WB_SYNC_NONE)
1083 index = mapping->writeback_index; /* Start from prev offset */
1084 else {
1085 index = 0;
1086 scanned = 1;
1088 if (wbc->start || wbc->end) {
1089 index = wbc->start >> PAGE_CACHE_SHIFT;
1090 end = wbc->end >> PAGE_CACHE_SHIFT;
1091 is_range = 1;
1092 scanned = 1;
1094 retry:
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))) {
1099 int first;
1100 unsigned int i;
1102 first = -1;
1103 next = 0;
1104 n_iov = 0;
1105 bytes_to_write = 0;
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
1114 * mapping
1117 if (first < 0)
1118 lock_page(page);
1119 else if (TestSetPageLocked(page))
1120 break;
1122 if (unlikely(page->mapping != mapping)) {
1123 unlock_page(page);
1124 break;
1127 if (unlikely(is_range) && (page->index > end)) {
1128 done = 1;
1129 unlock_page(page);
1130 break;
1133 if (next && (page->index != next)) {
1134 /* Not next consecutive page */
1135 unlock_page(page);
1136 break;
1139 if (wbc->sync_mode != WB_SYNC_NONE)
1140 wait_on_page_writeback(page);
1142 if (PageWriteback(page) ||
1143 !test_clear_page_dirty(page)) {
1144 unlock_page(page);
1145 break;
1148 if (page_offset(page) >= mapping->host->i_size) {
1149 done = 1;
1150 unlock_page(page);
1151 break;
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 */
1163 n_iov++;
1164 iov[n_iov].iov_base = kmap(page);
1165 iov[n_iov].iov_len = len;
1166 bytes_to_write += len;
1168 if (first < 0) {
1169 first = i;
1170 offset = page_offset(page);
1172 next = page->index + 1;
1173 if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
1174 break;
1176 if (n_iov) {
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));
1182 if (!open_file) {
1183 cERROR(1, ("No writable handles for inode"));
1184 rc = -EBADF;
1185 } else {
1186 rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
1187 open_file->netfid,
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);
1198 SetPageError(page);
1199 } else {
1200 cifs_stats_bytes_written(cifs_sb->tcon,
1201 bytes_written);
1204 for (i = 0; i < n_iov; i++) {
1205 page = pvec.pages[first + i];
1206 kunmap(page);
1207 unlock_page(page);
1208 page_cache_release(page);
1210 if ((wbc->nr_to_write -= n_iov) <= 0)
1211 done = 1;
1212 index = next;
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
1221 scanned = 1;
1222 index = 0;
1223 goto retry;
1225 if (!is_range)
1226 mapping->writeback_index = index;
1228 FreeXid(xid);
1230 return rc;
1232 #endif
1234 static int cifs_writepage(struct page* page, struct writeback_control *wbc)
1236 int rc = -EFAULT;
1237 int xid;
1239 xid = GetXid();
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? */
1248 unlock_page(page);
1249 page_cache_release(page);
1250 FreeXid(xid);
1251 return rc;
1254 static int cifs_commit_write(struct file *file, struct page *page,
1255 unsigned offset, unsigned to)
1257 int xid;
1258 int rc = 0;
1259 struct inode *inode = page->mapping->host;
1260 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
1261 char *page_data;
1263 xid = GetXid();
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) {
1269 rc = -EBADF;
1270 } else {
1271 open_file = (struct cifsFileInfo *)file->private_data;
1272 cifs_sb = CIFS_SB(inode->i_sb);
1273 rc = -EAGAIN;
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);
1279 if (rc != 0)
1280 break;
1282 if (!open_file->closePend) {
1283 rc = CIFSSMBSetFileSize(xid,
1284 cifs_sb->tcon, position,
1285 open_file->netfid,
1286 open_file->pid, FALSE);
1287 } else {
1288 rc = -EBADF;
1289 break;
1292 cFYI(1, (" SetEOF (commit write) rc = %d", rc));
1293 } */
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 */
1298 if (to < offset) {
1299 cFYI(1, ("Illegal offsets, can not copy from %d to %d",
1300 offset, to));
1301 FreeXid(xid);
1302 return rc;
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,
1311 &position);
1312 if (rc > 0)
1313 rc = 0;
1314 /* else if (rc < 0) should we set writebehind rc? */
1315 kunmap(page);
1316 } else {
1317 set_page_dirty(page);
1320 FreeXid(xid);
1321 return rc;
1324 int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1326 int xid;
1327 int rc = 0;
1328 struct inode *inode = file->f_dentry->d_inode;
1330 xid = GetXid();
1332 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
1333 dentry->d_name.name, datasync));
1335 rc = filemap_fdatawrite(inode->i_mapping);
1336 if (rc == 0)
1337 CIFS_I(inode)->write_behind_rc = 0;
1338 FreeXid(xid);
1339 return rc;
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;
1348 int rc = 0;
1350 cFYI(1, ("sync page %p",page));
1351 mapping = page->mapping;
1352 if (!mapping)
1353 return 0;
1354 inode = mapping->host;
1355 if (!inode)
1356 return 0; */
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));
1363 if (rc < 0)
1364 return rc;
1365 return 0;
1366 } */
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;
1375 int rc = 0;
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));
1392 return rc;
1395 ssize_t cifs_user_read(struct file *file, char __user *read_data,
1396 size_t read_size, loff_t *poffset)
1398 int rc = -EACCES;
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;
1404 int xid;
1405 struct cifsFileInfo *open_file;
1406 char *smb_read_data;
1407 char __user *current_offset;
1408 struct smb_com_read_rsp *pSMBr;
1410 xid = GetXid();
1411 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1412 pTcon = cifs_sb->tcon;
1414 if (file->private_data == NULL) {
1415 FreeXid(xid);
1416 return -EBADF;
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,
1427 cifs_sb->rsize);
1428 rc = -EAGAIN;
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,
1434 file, TRUE);
1435 if (rc != 0)
1436 break;
1438 rc = CIFSSMBRead(xid, pTcon,
1439 open_file->netfid,
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),
1446 bytes_read)) {
1447 rc = -EFAULT;
1448 FreeXid(xid);
1449 return rc;
1451 if (smb_read_data) {
1452 cifs_buf_release(smb_read_data);
1453 smb_read_data = NULL;
1456 if (rc || (bytes_read == 0)) {
1457 if (total_read) {
1458 break;
1459 } else {
1460 FreeXid(xid);
1461 return rc;
1463 } else {
1464 cifs_stats_bytes_read(pTcon, bytes_read);
1465 *poffset += bytes_read;
1468 FreeXid(xid);
1469 return total_read;
1473 static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1474 loff_t *poffset)
1476 int rc = -EACCES;
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;
1482 int xid;
1483 char *current_offset;
1484 struct cifsFileInfo *open_file;
1486 xid = GetXid();
1487 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1488 pTcon = cifs_sb->tcon;
1490 if (file->private_data == NULL) {
1491 FreeXid(xid);
1492 return -EBADF;
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,
1503 cifs_sb->rsize);
1504 /* For windows me and 9x we do not want to request more
1505 than it negotiated since it will refuse the read then */
1506 if((pTcon->ses) &&
1507 !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
1508 current_read_size = min_t(const int, current_read_size,
1509 pTcon->ses->server->maxBuf - 128);
1511 rc = -EAGAIN;
1512 while (rc == -EAGAIN) {
1513 if ((open_file->invalidHandle) &&
1514 (!open_file->closePend)) {
1515 rc = cifs_reopen_file(file->f_dentry->d_inode,
1516 file, TRUE);
1517 if (rc != 0)
1518 break;
1520 rc = CIFSSMBRead(xid, pTcon,
1521 open_file->netfid,
1522 current_read_size, *poffset,
1523 &bytes_read, &current_offset);
1525 if (rc || (bytes_read == 0)) {
1526 if (total_read) {
1527 break;
1528 } else {
1529 FreeXid(xid);
1530 return rc;
1532 } else {
1533 cifs_stats_bytes_read(pTcon, total_read);
1534 *poffset += bytes_read;
1537 FreeXid(xid);
1538 return total_read;
1541 int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
1543 struct dentry *dentry = file->f_dentry;
1544 int rc, xid;
1546 xid = GetXid();
1547 rc = cifs_revalidate(dentry);
1548 if (rc) {
1549 cFYI(1, ("Validation prior to mmap failed, error=%d", rc));
1550 FreeXid(xid);
1551 return rc;
1553 rc = generic_file_mmap(file, vma);
1554 FreeXid(xid);
1555 return rc;
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)
1563 struct page *page;
1564 char *target;
1566 while (bytes_read > 0) {
1567 if (list_empty(pages))
1568 break;
1570 page = list_entry(pages->prev, struct page, lru);
1571 list_del(&page->lru);
1573 if (add_to_page_cache(page, mapping, page->index,
1574 GFP_KERNEL)) {
1575 page_cache_release(page);
1576 cFYI(1, ("Add page cache failed"));
1577 data += PAGE_CACHE_SIZE;
1578 bytes_read -= PAGE_CACHE_SIZE;
1579 continue;
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);
1589 bytes_read = 0;
1590 } else {
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);
1598 unlock_page(page);
1599 if (!pagevec_add(plru_pvec, page))
1600 __pagevec_lru_add(plru_pvec);
1601 data += PAGE_CACHE_SIZE;
1603 return;
1606 static int cifs_readpages(struct file *file, struct address_space *mapping,
1607 struct list_head *page_list, unsigned num_pages)
1609 int rc = -EACCES;
1610 int xid;
1611 loff_t offset;
1612 struct page *page;
1613 struct cifs_sb_info *cifs_sb;
1614 struct cifsTconInfo *pTcon;
1615 int bytes_read = 0;
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;
1622 xid = GetXid();
1623 if (file->private_data == NULL) {
1624 FreeXid(xid);
1625 return -EBADF;
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))
1639 break;
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 */
1645 contig_pages = 0;
1646 expected_index =
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) {
1650 contig_pages++;
1651 expected_index++;
1652 } else
1653 break;
1655 if (contig_pages + i > num_pages)
1656 contig_pages = num_pages - i;
1658 /* for reads over a certain size could initiate async
1659 read ahead */
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);
1666 rc = -EAGAIN;
1667 while (rc == -EAGAIN) {
1668 if ((open_file->invalidHandle) &&
1669 (!open_file->closePend)) {
1670 rc = cifs_reopen_file(file->f_dentry->d_inode,
1671 file, TRUE);
1672 if (rc != 0)
1673 break;
1676 rc = CIFSSMBRead(xid, pTcon,
1677 open_file->netfid,
1678 read_size, offset,
1679 &bytes_read, &smb_read_data);
1681 /* BB more RC checks ? */
1682 if (rc== -EAGAIN) {
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,
1694 lru);
1695 list_del(&page->lru);
1696 page_cache_release(page);
1698 break;
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
1711 than client */
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,
1718 struct page, list);
1719 list_del(&page->list);
1720 page_cache_release(page);
1722 break; */
1724 } else {
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,
1732 lru);
1733 list_del(&page->lru);
1735 /* BB removeme - replace with zero of page? */
1736 page_cache_release(page);
1738 break;
1740 if (smb_read_data) {
1741 cifs_buf_release(smb_read_data);
1742 smb_read_data = NULL;
1744 bytes_read = 0;
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;
1755 FreeXid(xid);
1756 return rc;
1759 static int cifs_readpage_worker(struct file *file, struct page *page,
1760 loff_t *poffset)
1762 char *read_data;
1763 int rc;
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);
1771 if (rc < 0)
1772 goto io_error;
1773 else
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);
1784 rc = 0;
1786 io_error:
1787 kunmap(page);
1788 page_cache_release(page);
1789 return rc;
1792 static int cifs_readpage(struct file *file, struct page *page)
1794 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1795 int rc = -EACCES;
1796 int xid;
1798 xid = GetXid();
1800 if (file->private_data == NULL) {
1801 FreeXid(xid);
1802 return -EBADF;
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);
1810 unlock_page(page);
1812 FreeXid(xid);
1813 return rc;
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;
1826 if (cifsInode)
1827 open_file = find_writable_file(cifsInode);
1829 if(open_file) {
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);
1834 return 0;
1835 } else
1836 return 1;
1839 static int cifs_prepare_write(struct file *file, struct page *page,
1840 unsigned from, unsigned to)
1842 int rc = 0;
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);
1852 } */
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);
1861 } else {
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 */
1871 return 0;
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,
1880 #endif
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, */
1885 /* .direct_IO = */