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/stat.h>
25 #include <linux/fcntl.h>
26 #include <linux/pagemap.h>
27 #include <linux/pagevec.h>
28 #include <linux/smp_lock.h>
29 #include <asm/div64.h>
33 #include "cifsproto.h"
34 #include "cifs_unicode.h"
35 #include "cifs_debug.h"
36 #include "cifs_fs_sb.h"
39 cifs_open(struct inode *inode, struct file *file)
43 struct cifs_sb_info *cifs_sb;
44 struct cifsTconInfo *pTcon;
45 struct cifsFileInfo *pCifsFile;
46 struct cifsInodeInfo *pCifsInode;
47 struct list_head * tmp;
48 char *full_path = NULL;
49 int desiredAccess = 0x20197;
52 FILE_ALL_INFO * buf = NULL;
56 cifs_sb = CIFS_SB(inode->i_sb);
57 pTcon = cifs_sb->tcon;
59 if (file->f_flags & O_CREAT) {
60 /* search inode for this file and fill in file->private_data = */
61 pCifsInode = CIFS_I(file->f_dentry->d_inode);
62 read_lock(&GlobalSMBSeslock);
63 list_for_each(tmp, &pCifsInode->openFileList) {
64 pCifsFile = list_entry(tmp,struct cifsFileInfo, flist);
65 if((pCifsFile->pfile == NULL)&& (pCifsFile->pid = current->pid)){
66 /* mode set in cifs_create */
67 pCifsFile->pfile = file; /* needed for writepage */
68 file->private_data = pCifsFile;
72 read_unlock(&GlobalSMBSeslock);
73 if(file->private_data != NULL) {
78 if(file->f_flags & O_EXCL)
79 cERROR(1,("could not find file instance for new file %p ",file));
83 down(&inode->i_sb->s_vfs_rename_sem);
84 full_path = build_path_from_dentry(file->f_dentry);
85 up(&inode->i_sb->s_vfs_rename_sem);
86 if(full_path == NULL) {
91 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
92 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
93 desiredAccess = GENERIC_READ;
94 else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
95 desiredAccess = GENERIC_WRITE;
96 else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
97 /* GENERIC_ALL is too much permission to request */
98 /* can cause unnecessary access denied on create */
99 /* desiredAccess = GENERIC_ALL; */
100 desiredAccess = GENERIC_READ | GENERIC_WRITE;
103 /*********************************************************************
104 * open flag mapping table:
106 * POSIX Flag CIFS Disposition
107 * ---------- ----------------
108 * O_CREAT FILE_OPEN_IF
109 * O_CREAT | O_EXCL FILE_CREATE
110 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
111 * O_TRUNC FILE_OVERWRITE
112 * none of the above FILE_OPEN
114 * Note that there is not a direct match between disposition
115 * FILE_SUPERSEDE (ie create whether or not file exists although
116 * O_CREAT | O_TRUNC is similar but truncates the existing
117 * file rather than creating a new file as FILE_SUPERSEDE does
118 * (which uses the attributes / metadata passed in on open call)
120 *? O_SYNC is a reasonable match to CIFS writethrough flag
121 *? and the read write flags match reasonably. O_LARGEFILE
122 *? is irrelevant because largefile support is always used
123 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
124 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
125 *********************************************************************/
127 if((file->f_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
128 disposition = FILE_CREATE;
129 else if((file->f_flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
130 disposition = FILE_OVERWRITE_IF;
131 else if((file->f_flags & O_CREAT) == O_CREAT)
132 disposition = FILE_OPEN_IF;
134 disposition = FILE_OPEN;
141 /* BB pass O_SYNC flag through on file attributes .. BB */
143 /* Also refresh inode by passing in file_info buf returned by SMBOpen
144 and calling get_inode_info with returned buf (at least
145 helps non-Unix server case */
147 /* BB we can not do this if this is the second open of a file
148 and the first handle has writebehind data, we might be
149 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
150 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
157 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
158 CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls);
160 cFYI(1, ("cifs_open returned 0x%x ", rc));
161 cFYI(1, ("oplock: %d ", oplock));
164 kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
165 if (file->private_data) {
166 memset(file->private_data, 0, sizeof(struct cifsFileInfo));
167 pCifsFile = (struct cifsFileInfo *) file->private_data;
168 pCifsFile->netfid = netfid;
169 pCifsFile->pid = current->pid;
170 init_MUTEX(&pCifsFile->fh_sem);
171 pCifsFile->pfile = file; /* needed for writepage */
172 pCifsFile->pInode = inode;
173 pCifsFile->invalidHandle = FALSE;
174 pCifsFile->closePend = FALSE;
175 write_lock(&file->f_owner.lock);
176 write_lock(&GlobalSMBSeslock);
177 list_add(&pCifsFile->tlist,&pTcon->openFileList);
178 pCifsInode = CIFS_I(file->f_dentry->d_inode);
180 /* want handles we can use to read with first */
181 /* in the list so we do not have to walk the */
182 /* list to search for one in prepare_write */
183 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
184 list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList);
186 list_add(&pCifsFile->flist,&pCifsInode->openFileList);
188 write_unlock(&GlobalSMBSeslock);
189 write_unlock(&file->f_owner.lock);
190 if(pCifsInode->clientCanCacheRead) {
191 /* we have the inode open somewhere else
192 no need to discard cache data */
195 /* BB need same check in cifs_create too? */
197 /* if not oplocked, invalidate inode pages if mtime
198 or file size changed */
199 struct timespec temp;
200 temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
201 if(timespec_equal(&file->f_dentry->d_inode->i_mtime,&temp) &&
202 (file->f_dentry->d_inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) {
203 cFYI(1,("inode unchanged on server"));
205 if(file->f_dentry->d_inode->i_mapping) {
206 /* BB no need to lock inode until after invalidate*/
207 /* since namei code should already have it locked?*/
208 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
209 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
211 cFYI(1,("invalidating remote inode since open detected it changed"));
212 invalidate_remote_inode(file->f_dentry->d_inode);
216 if (pTcon->ses->capabilities & CAP_UNIX)
217 rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
218 full_path, inode->i_sb,xid);
220 rc = cifs_get_inode_info(&file->f_dentry->d_inode,
221 full_path, buf, inode->i_sb,xid);
223 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
224 pCifsInode->clientCanCacheAll = TRUE;
225 pCifsInode->clientCanCacheRead = TRUE;
226 cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
227 } else if((oplock & 0xF) == OPLOCK_READ)
228 pCifsInode->clientCanCacheRead = TRUE;
230 write_unlock(&GlobalSMBSeslock);
231 write_unlock(&file->f_owner.lock);
233 if(oplock & CIFS_CREATE_ACTION) {
234 /* time to set mode which we can not set earlier due
235 to problems creating new read-only files */
236 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
237 CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
242 else {/* BB implement via Windows security descriptors */
243 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
244 /* in the meantime could set r/o dos attribute when perms are eg:
259 /* Try to reaquire byte range locks that were released when session */
260 /* to server was lost */
261 static int cifs_relock_file(struct cifsFileInfo * cifsFile)
265 /* BB list all locks open on this file and relock */
270 static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush)
274 struct cifs_sb_info *cifs_sb;
275 struct cifsTconInfo *pTcon;
276 struct cifsFileInfo *pCifsFile;
277 struct cifsInodeInfo *pCifsInode;
278 char *full_path = NULL;
279 int desiredAccess = 0x20197;
280 int disposition = FILE_OPEN;
285 if (file->private_data) {
286 pCifsFile = (struct cifsFileInfo *) file->private_data;
291 down(&pCifsFile->fh_sem);
292 if(pCifsFile->invalidHandle == FALSE) {
293 up(&pCifsFile->fh_sem);
298 if(file->f_dentry == NULL) {
299 up(&pCifsFile->fh_sem);
300 cFYI(1,("failed file reopen, no valid name if dentry freed"));
304 cifs_sb = CIFS_SB(inode->i_sb);
305 pTcon = cifs_sb->tcon;
306 /* can not grab rename sem here because various ops, including
307 those that already have the rename sem can end up causing writepage
308 to get called and if the server was down that means we end up here,
309 and we can never tell if the caller already has the rename_sem */
310 full_path = build_path_from_dentry(file->f_dentry);
311 if(full_path == NULL) {
312 up(&pCifsFile->fh_sem);
317 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
318 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
319 desiredAccess = GENERIC_READ;
320 else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
321 desiredAccess = GENERIC_WRITE;
322 else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
323 /* GENERIC_ALL is too much permission to request */
324 /* can cause unnecessary access denied on create */
325 /* desiredAccess = GENERIC_ALL; */
326 desiredAccess = GENERIC_READ | GENERIC_WRITE;
335 /* Can not refresh inode by passing in file_info buf to be returned
336 by SMBOpen and then calling get_inode_info with returned buf
337 since file might have write behind data that needs to be flushed
338 and server version of file size can be stale. If we
339 knew for sure that inode was not dirty locally we could do this */
341 /* buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
343 up(&pCifsFile->fh_sem);
349 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
350 CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
352 up(&pCifsFile->fh_sem);
353 cFYI(1, ("cifs_open returned 0x%x ", rc));
354 cFYI(1, ("oplock: %d ", oplock));
356 pCifsFile->netfid = netfid;
357 pCifsFile->invalidHandle = FALSE;
358 up(&pCifsFile->fh_sem);
359 pCifsInode = CIFS_I(inode);
362 filemap_fdatawrite(inode->i_mapping);
363 filemap_fdatawait(inode->i_mapping);
364 /* temporarily disable caching while we
365 go to server to get inode info */
366 pCifsInode->clientCanCacheAll = FALSE;
367 pCifsInode->clientCanCacheRead = FALSE;
368 if (pTcon->ses->capabilities & CAP_UNIX)
369 rc = cifs_get_inode_info_unix(&inode,
370 full_path, inode->i_sb,xid);
372 rc = cifs_get_inode_info(&inode,
373 full_path, NULL, inode->i_sb,xid);
374 } /* else we are writing out data to server already
375 and could deadlock if we tried to flush data, and
376 since we do not know if we have data that would
377 invalidate the current end of file on the server
378 we can not go to the server to get the new
380 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
381 pCifsInode->clientCanCacheAll = TRUE;
382 pCifsInode->clientCanCacheRead = TRUE;
383 cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
384 } else if((oplock & 0xF) == OPLOCK_READ) {
385 pCifsInode->clientCanCacheRead = TRUE;
386 pCifsInode->clientCanCacheAll = FALSE;
388 pCifsInode->clientCanCacheRead = FALSE;
389 pCifsInode->clientCanCacheAll = FALSE;
391 cifs_relock_file(pCifsFile);
402 cifs_close(struct inode *inode, struct file *file)
406 struct cifs_sb_info *cifs_sb;
407 struct cifsTconInfo *pTcon;
408 struct cifsFileInfo *pSMBFile =
409 (struct cifsFileInfo *) file->private_data;
413 cifs_sb = CIFS_SB(inode->i_sb);
414 pTcon = cifs_sb->tcon;
416 pSMBFile->closePend = TRUE;
417 write_lock(&file->f_owner.lock);
419 /* no sense reconnecting to close a file that is
421 if (pTcon->tidStatus != CifsNeedReconnect) {
422 write_unlock(&file->f_owner.lock);
423 rc = CIFSSMBClose(xid,pTcon,pSMBFile->netfid);
424 write_lock(&file->f_owner.lock);
427 list_del(&pSMBFile->flist);
428 list_del(&pSMBFile->tlist);
429 write_unlock(&file->f_owner.lock);
430 if(pSMBFile->search_resume_name)
431 kfree(pSMBFile->search_resume_name);
432 kfree(file->private_data);
433 file->private_data = NULL;
437 if(list_empty(&(CIFS_I(inode)->openFileList))) {
438 cFYI(1,("closing last open instance for inode %p",inode));
439 /* if the file is not open we do not know if we can cache
440 info on this inode, much less write behind and read ahead */
441 CIFS_I(inode)->clientCanCacheRead = FALSE;
442 CIFS_I(inode)->clientCanCacheAll = FALSE;
444 if((rc ==0) && CIFS_I(inode)->write_behind_rc)
445 rc = CIFS_I(inode)->write_behind_rc;
451 cifs_closedir(struct inode *inode, struct file *file)
455 struct cifsFileInfo *pSMBFileStruct =
456 (struct cifsFileInfo *) file->private_data;
458 cFYI(1, ("Closedir inode = 0x%p with ", inode));
462 if (pSMBFileStruct) {
463 cFYI(1, ("Freeing private data in close dir"));
464 kfree(file->private_data);
465 file->private_data = NULL;
472 cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
475 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
479 int wait_flag = FALSE;
480 struct cifs_sb_info *cifs_sb;
481 struct cifsTconInfo *pTcon;
482 length = 1 + pfLock->fl_end - pfLock->fl_start;
489 ("Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld",
490 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
493 if (pfLock->fl_flags & FL_POSIX)
495 if (pfLock->fl_flags & FL_FLOCK)
497 if (pfLock->fl_flags & FL_SLEEP) {
498 cFYI(1, ("Blocking lock "));
501 if (pfLock->fl_flags & FL_ACCESS)
502 cFYI(1, ("Process suspended by mandatory locking - not implemented yet "));
503 if (pfLock->fl_flags & FL_LEASE)
504 cFYI(1, ("Lease on file - not implemented yet"));
505 if (pfLock->fl_flags & (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
506 cFYI(1, ("Unknown lock flags 0x%x",pfLock->fl_flags));
508 if (pfLock->fl_type == F_WRLCK) {
509 cFYI(1, ("F_WRLCK "));
511 } else if (pfLock->fl_type == F_UNLCK) {
512 cFYI(1, ("F_UNLCK "));
514 } else if (pfLock->fl_type == F_RDLCK) {
515 cFYI(1, ("F_RDLCK "));
516 lockType |= LOCKING_ANDX_SHARED_LOCK;
518 } else if (pfLock->fl_type == F_EXLCK) {
519 cFYI(1, ("F_EXLCK "));
521 } else if (pfLock->fl_type == F_SHLCK) {
522 cFYI(1, ("F_SHLCK "));
523 lockType |= LOCKING_ANDX_SHARED_LOCK;
526 cFYI(1, ("Unknown type of lock "));
528 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
529 pTcon = cifs_sb->tcon;
531 if (file->private_data == NULL) {
537 rc = CIFSSMBLock(xid, pTcon,
538 ((struct cifsFileInfo *) file->
539 private_data)->netfid,
541 pfLock->fl_start, 0, 1, lockType,
544 rc = CIFSSMBLock(xid, pTcon,
545 ((struct cifsFileInfo *) file->
546 private_data)->netfid,
548 pfLock->fl_start, 1 /* numUnlock */ ,
549 0 /* numLock */ , lockType,
551 pfLock->fl_type = F_UNLCK;
554 ("Error unlocking previously locked range %d during test of lock ",
559 /* if rc == ERR_SHARING_VIOLATION ? */
560 rc = 0; /* do not change lock type to unlock since range in use */
567 rc = CIFSSMBLock(xid, pTcon,
568 ((struct cifsFileInfo *) file->private_data)->
570 pfLock->fl_start, numUnlock, numLock, lockType,
572 if (rc == 0 && (pfLock->fl_flags & FL_POSIX))
573 posix_lock_file(file, pfLock);
579 cifs_write(struct file * file, const char *write_data,
580 size_t write_size, loff_t * poffset)
583 unsigned int bytes_written = 0;
584 unsigned int total_written;
585 struct cifs_sb_info *cifs_sb;
586 struct cifsTconInfo *pTcon;
588 struct cifsFileInfo * open_file;
590 if(file->f_dentry == NULL)
593 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
594 if(cifs_sb == NULL) {
597 pTcon = cifs_sb->tcon;
600 (" write %d bytes to offset %lld of %s", write_size,
601 *poffset, file->f_dentry->d_name.name)); */
603 if (file->private_data == NULL) {
606 open_file = (struct cifsFileInfo *) file->private_data;
610 if(file->f_dentry->d_inode == NULL) {
615 if (*poffset > file->f_dentry->d_inode->i_size)
616 long_op = 2; /* writes past end of file can take a long time */
620 for (total_written = 0; write_size > total_written;
621 total_written += bytes_written) {
623 while(rc == -EAGAIN) {
624 if(file->private_data == NULL) {
625 /* file has been closed on us */
627 /* if we have gotten here we have written some data
628 and blocked, and the file has been freed on us
629 while we blocked so return what we managed to write */
630 return total_written;
632 if(open_file->closePend) {
635 return total_written;
639 if (open_file->invalidHandle) {
640 if((file->f_dentry == NULL) ||
641 (file->f_dentry->d_inode == NULL)) {
643 return total_written;
645 /* we could deadlock if we called
646 filemap_fdatawait from here so tell
647 reopen_file not to flush data to server now */
648 rc = cifs_reopen_file(file->f_dentry->d_inode,
654 rc = CIFSSMBWrite(xid, pTcon,
656 write_size - total_written, *poffset,
658 write_data + total_written, long_op);
660 if (rc || (bytes_written == 0)) {
668 *poffset += bytes_written;
669 long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
672 #ifdef CONFIG_CIFS_STATS
673 if(total_written > 0) {
674 atomic_inc(&pTcon->num_writes);
675 spin_lock(&pTcon->stat_lock);
676 pTcon->bytes_written += total_written;
677 spin_unlock(&pTcon->stat_lock);
681 /* since the write may have blocked check these pointers again */
683 if(file->f_dentry->d_inode) {
684 file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
686 if (total_written > 0) {
687 if (*poffset > file->f_dentry->d_inode->i_size)
688 i_size_write(file->f_dentry->d_inode, *poffset);
690 mark_inode_dirty_sync(file->f_dentry->d_inode);
694 return total_written;
698 cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
700 struct address_space *mapping = page->mapping;
701 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
704 int bytes_written = 0;
705 struct cifs_sb_info *cifs_sb;
706 struct cifsTconInfo *pTcon;
708 struct cifsInodeInfo *cifsInode;
709 struct cifsFileInfo *open_file = NULL;
710 struct list_head *tmp;
711 struct list_head *tmp1;
715 } else if(!mapping->host) {
719 inode = page->mapping->host;
720 cifs_sb = CIFS_SB(inode->i_sb);
721 pTcon = cifs_sb->tcon;
723 offset += (loff_t)from;
724 write_data = kmap(page);
727 if((to > PAGE_CACHE_SIZE) || (from > to)) {
732 /* racing with truncate? */
733 if(offset > mapping->host->i_size) {
735 return 0; /* don't care */
738 /* check to make sure that we are not extending the file */
739 if(mapping->host->i_size - offset < (loff_t)to)
740 to = (unsigned)(mapping->host->i_size - offset);
743 cifsInode = CIFS_I(mapping->host);
744 read_lock(&GlobalSMBSeslock);
745 /* BB we should start at the end */
746 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
747 open_file = list_entry(tmp,struct cifsFileInfo, flist);
748 if(open_file->closePend)
750 /* We check if file is open for writing first */
751 if((open_file->pfile) &&
752 ((open_file->pfile->f_flags & O_RDWR) ||
753 (open_file->pfile->f_flags & O_WRONLY))) {
754 read_unlock(&GlobalSMBSeslock);
755 bytes_written = cifs_write(open_file->pfile, write_data,
757 read_lock(&GlobalSMBSeslock);
758 /* Does mm or vfs already set times? */
759 inode->i_atime = inode->i_mtime = CURRENT_TIME;
760 if ((bytes_written > 0) && (offset)) {
762 } else if(bytes_written < 0) {
764 /* have seen a case in which
765 kernel seemed to have closed/freed a file
766 even with writes active so we might as well
767 see if there are other file structs to try
768 for the same inode before giving up */
773 break; /* now that we found a valid file handle
774 and tried to write to it we are done, no
775 sense continuing to loop looking for another */
777 if(tmp->next == NULL) {
778 cFYI(1,("File instance %p removed",tmp));
782 read_unlock(&GlobalSMBSeslock);
783 if(open_file == NULL) {
784 cFYI(1,("No writeable filehandles for inode"));
794 cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
800 /* call 16K write then Setpageuptodate */
807 cifs_writepage(struct page* page, struct writeback_control *wbc)
813 /* BB add check for wbc flags */
814 page_cache_get(page);
815 if (!PageUptodate(page)) {
816 cFYI(1,("ppw - page not up to date"));
819 rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
820 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
822 page_cache_release(page);
828 cifs_commit_write(struct file *file, struct page *page, unsigned offset,
833 struct inode *inode = page->mapping->host;
834 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
838 cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
839 if (position > inode->i_size){
840 i_size_write(inode, position);
841 /*if (file->private_data == NULL) {
844 open_file = (struct cifsFileInfo *)file->private_data;
845 cifs_sb = CIFS_SB(inode->i_sb);
847 while(rc == -EAGAIN) {
848 if((open_file->invalidHandle) &&
849 (!open_file->closePend)) {
850 rc = cifs_reopen_file(file->f_dentry->d_inode,file);
854 if(!open_file->closePend) {
855 rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
856 position, open_file->netfid,
857 open_file->pid,FALSE);
863 cFYI(1,(" SetEOF (commit write) rc = %d",rc));
866 if (!PageUptodate(page)) {
867 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
868 /* can not rely on (or let) writepage write this data */
870 cFYI(1,("Illegal offsets, can not copy from %d to %d",
875 /* this is probably better than directly calling
876 partialpage_write since in this function
877 the file handle is known which we might as well
879 /* BB check if anything else missing out of ppw */
880 /* such as updating last write time */
881 page_data = kmap(page);
882 rc = cifs_write(file, page_data+offset,to-offset,
886 /* else if rc < 0 should we set writebehind rc? */
889 set_page_dirty(page);
897 cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
901 struct inode * inode = file->f_dentry->d_inode;
905 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
906 dentry->d_name.name, datasync));
908 rc = filemap_fdatawrite(inode->i_mapping);
910 CIFS_I(inode)->write_behind_rc = 0;
916 cifs_sync_page(struct page *page)
918 struct address_space *mapping;
920 unsigned long index = page->index;
921 unsigned int rpages = 0;
924 cFYI(1,("sync page %p",page));
925 mapping = page->mapping;
928 inode = mapping->host;
932 /* fill in rpages then
933 result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */
935 /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
943 * As file closes, flush all cached write data for this inode checking
944 * for write behind errors.
947 int cifs_flush(struct file *file)
949 struct inode * inode = file->f_dentry->d_inode;
952 /* Rather than do the steps manually: */
953 /* lock the inode for writing */
954 /* loop through pages looking for write behind data (dirty pages) */
955 /* coalesce into contiguous 16K (or smaller) chunks to write to server */
956 /* send to server (prefer in parallel) */
957 /* deal with writebehind errors */
958 /* unlock inode for writing */
959 /* filemapfdatawrite appears easier for the time being */
961 rc = filemap_fdatawrite(inode->i_mapping);
962 if(rc == 0) /* reset wb rc if we were able to write out dirty pages */
963 CIFS_I(inode)->write_behind_rc = 0;
965 cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
972 cifs_read(struct file * file, char *read_data, size_t read_size,
976 unsigned int bytes_read = 0;
977 unsigned int total_read;
978 unsigned int current_read_size;
979 struct cifs_sb_info *cifs_sb;
980 struct cifsTconInfo *pTcon;
982 char * current_offset;
983 struct cifsFileInfo * open_file;
986 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
987 pTcon = cifs_sb->tcon;
989 if (file->private_data == NULL) {
993 open_file = (struct cifsFileInfo *)file->private_data;
995 if((file->f_flags & O_ACCMODE) == O_WRONLY) {
996 cFYI(1,("attempting read on write only file instance"));
999 for (total_read = 0,current_offset=read_data; read_size > total_read;
1000 total_read += bytes_read,current_offset+=bytes_read) {
1001 current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
1003 while(rc == -EAGAIN) {
1004 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1005 rc = cifs_reopen_file(file->f_dentry->d_inode,
1011 rc = CIFSSMBRead(xid, pTcon,
1013 current_read_size, *poffset,
1014 &bytes_read, ¤t_offset);
1016 if (rc || (bytes_read == 0)) {
1024 #ifdef CONFIG_CIFS_STATS
1025 atomic_inc(&pTcon->num_reads);
1026 spin_lock(&pTcon->stat_lock);
1027 pTcon->bytes_read += total_read;
1028 spin_unlock(&pTcon->stat_lock);
1030 *poffset += bytes_read;
1037 int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
1039 struct dentry * dentry = file->f_dentry;
1043 rc = cifs_revalidate(dentry);
1045 cFYI(1,("Validation prior to mmap failed, error=%d", rc));
1049 rc = generic_file_mmap(file, vma);
1054 static void cifs_copy_cache_pages(struct address_space *mapping,
1055 struct list_head *pages, int bytes_read,
1056 char *data,struct pagevec * plru_pvec)
1061 while (bytes_read > 0) {
1062 if(list_empty(pages))
1065 page = list_entry(pages->prev, struct page, lru);
1066 list_del(&page->lru);
1068 if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
1069 page_cache_release(page);
1070 cFYI(1,("Add page cache failed"));
1074 target = kmap_atomic(page,KM_USER0);
1076 if(PAGE_CACHE_SIZE > bytes_read) {
1077 memcpy(target,data,bytes_read);
1078 /* zero the tail end of this partial page */
1079 memset(target+bytes_read,0,PAGE_CACHE_SIZE-bytes_read);
1082 memcpy(target,data,PAGE_CACHE_SIZE);
1083 bytes_read -= PAGE_CACHE_SIZE;
1085 kunmap_atomic(target,KM_USER0);
1087 flush_dcache_page(page);
1088 SetPageUptodate(page);
1090 if (!pagevec_add(plru_pvec, page))
1091 __pagevec_lru_add(plru_pvec);
1092 data += PAGE_CACHE_SIZE;
1099 cifs_readpages(struct file *file, struct address_space *mapping,
1100 struct list_head *page_list, unsigned num_pages)
1106 struct cifs_sb_info *cifs_sb;
1107 struct cifsTconInfo *pTcon;
1109 unsigned int read_size,i;
1110 char * smb_read_data = NULL;
1111 struct smb_com_read_rsp * pSMBr;
1112 struct pagevec lru_pvec;
1113 struct cifsFileInfo * open_file;
1116 if (file->private_data == NULL) {
1120 open_file = (struct cifsFileInfo *)file->private_data;
1121 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1122 pTcon = cifs_sb->tcon;
1124 pagevec_init(&lru_pvec, 0);
1126 for(i = 0;i<num_pages;) {
1127 unsigned contig_pages;
1128 struct page * tmp_page;
1129 unsigned long expected_index;
1131 if(list_empty(page_list)) {
1134 page = list_entry(page_list->prev, struct page, lru);
1135 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1137 /* count adjacent pages that we will read into */
1139 expected_index = list_entry(page_list->prev,struct page,lru)->index;
1140 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1141 if(tmp_page->index == expected_index) {
1148 if(contig_pages + i > num_pages) {
1149 contig_pages = num_pages - i;
1152 /* for reads over a certain size could initiate async read ahead */
1154 read_size = contig_pages * PAGE_CACHE_SIZE;
1155 /* Read size needs to be in multiples of one page */
1156 read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
1159 while(rc == -EAGAIN) {
1160 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1161 rc = cifs_reopen_file(file->f_dentry->d_inode,
1167 rc = CIFSSMBRead(xid, pTcon,
1170 &bytes_read, &smb_read_data);
1171 /* BB need to check return code here */
1174 cifs_buf_release(smb_read_data);
1175 smb_read_data = NULL;
1179 if ((rc < 0) || (smb_read_data == NULL)) {
1180 cFYI(1,("Read error in readpages: %d",rc));
1181 /* clean up remaing pages off list */
1182 while (!list_empty(page_list) && (i < num_pages)) {
1183 page = list_entry(page_list->prev, struct page, lru);
1184 list_del(&page->lru);
1185 page_cache_release(page);
1188 } else if (bytes_read > 0) {
1189 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1190 cifs_copy_cache_pages(mapping, page_list, bytes_read,
1191 smb_read_data + 4 /* RFC1001 hdr */ +
1192 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1194 i += bytes_read >> PAGE_CACHE_SHIFT;
1195 #ifdef CONFIG_CIFS_STATS
1196 atomic_inc(&pTcon->num_reads);
1197 spin_lock(&pTcon->stat_lock);
1198 pTcon->bytes_read += bytes_read;
1199 spin_unlock(&pTcon->stat_lock);
1201 if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1202 cFYI(1,("Partial page %d of %d read to cache",i++,num_pages));
1204 i++; /* account for partial page */
1206 /* server copy of file can have smaller size than client */
1207 /* BB do we need to verify this common case ? this case is ok -
1208 if we are at server EOF we will hit it on next read */
1210 /* while(!list_empty(page_list) && (i < num_pages)) {
1211 page = list_entry(page_list->prev,struct page, list);
1212 list_del(&page->list);
1213 page_cache_release(page);
1218 cFYI(1,("No bytes read (%d) at offset %lld . Cleaning remaining pages from readahead list",bytes_read,offset));
1219 /* BB turn off caching and do new lookup on file size at server? */
1220 while (!list_empty(page_list) && (i < num_pages)) {
1221 page = list_entry(page_list->prev, struct page, lru);
1222 list_del(&page->lru);
1223 page_cache_release(page); /* BB removeme - replace with zero of page? */
1228 cifs_buf_release(smb_read_data);
1229 smb_read_data = NULL;
1234 pagevec_lru_add(&lru_pvec);
1236 /* need to free smb_read_data buf before exit */
1238 cifs_buf_release(smb_read_data);
1239 smb_read_data = NULL;
1246 static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
1251 page_cache_get(page);
1252 read_data = kmap(page);
1253 /* for reads over a certain size could initiate async read ahead */
1255 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1260 cFYI(1,("Bytes read %d ",rc));
1263 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
1265 if(PAGE_CACHE_SIZE > rc) {
1266 memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
1268 flush_dcache_page(page);
1269 SetPageUptodate(page);
1274 page_cache_release(page);
1279 cifs_readpage(struct file *file, struct page *page)
1281 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1287 if (file->private_data == NULL) {
1292 cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
1294 rc = cifs_readpage_worker(file,page,&offset);
1302 /* We do not want to update the file size from server for inodes
1303 open for write - to avoid races with writepage extending
1304 the file - in the future we could consider allowing
1305 refreshing the inode only on increases in the file size
1306 but this is tricky to do without racing with writebehind
1307 page caching in the current Linux kernel design */
1309 int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
1311 struct list_head *tmp;
1312 struct list_head *tmp1;
1313 struct cifsFileInfo *open_file = NULL;
1316 if(cifsInode == NULL)
1319 read_lock(&GlobalSMBSeslock);
1320 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
1321 open_file = list_entry(tmp,struct cifsFileInfo, flist);
1322 if(open_file == NULL)
1324 if(open_file->closePend)
1326 /* We check if file is open for writing,
1327 BB we could supplement this with a check to see if file size
1328 changes have been flushed to server - ie inode metadata dirty */
1329 if((open_file->pfile) &&
1330 ((open_file->pfile->f_flags & O_RDWR) ||
1331 (open_file->pfile->f_flags & O_WRONLY))) {
1335 if(tmp->next == NULL) {
1336 cFYI(1,("File instance %p removed",tmp));
1340 read_unlock(&GlobalSMBSeslock);
1346 fill_in_inode(struct inode *tmp_inode,
1347 FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
1349 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1350 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
1351 __u32 attr = le32_to_cpu(pfindData->ExtFileAttributes);
1352 __u64 allocation_size = le64_to_cpu(pfindData->AllocationSize);
1353 __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
1355 cifsInfo->cifsAttrs = attr;
1356 cifsInfo->time = jiffies;
1358 /* Linux can not store file creation time unfortunately so ignore it */
1359 tmp_inode->i_atime =
1360 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1361 tmp_inode->i_mtime =
1362 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
1363 tmp_inode->i_ctime =
1364 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
1365 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
1366 /* 2767 perms - indicate mandatory locking */
1367 /* BB fill in uid and gid here? with help from winbind?
1368 or retrieve from NTFS stream extended attribute */
1369 if(atomic_read(&cifsInfo->inUse) == 0) {
1370 tmp_inode->i_uid = cifs_sb->mnt_uid;
1371 tmp_inode->i_gid = cifs_sb->mnt_gid;
1372 /* set default mode. will override for dirs below */
1373 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
1377 ("CIFS FFIRST: Attributes came in as 0x%x",
1379 if (attr & ATTR_REPARSE) {
1380 *pobject_type = DT_LNK;
1381 /* BB can this and S_IFREG or S_IFDIR be set as in Windows? */
1382 tmp_inode->i_mode |= S_IFLNK;
1383 } else if (attr & ATTR_DIRECTORY) {
1384 *pobject_type = DT_DIR;
1385 /* override default perms since we do not lock dirs */
1386 if(atomic_read(&cifsInfo->inUse) == 0) {
1387 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
1389 tmp_inode->i_mode |= S_IFDIR;
1391 *pobject_type = DT_REG;
1392 tmp_inode->i_mode |= S_IFREG;
1393 if(attr & ATTR_READONLY)
1394 tmp_inode->i_mode &= ~(S_IWUGO);
1396 }/* could add code here - to validate if device or weird share type? */
1398 /* can not fill in nlink here as in qpathinfo version and Unx search */
1399 if(atomic_read(&cifsInfo->inUse) == 0) {
1400 atomic_set(&cifsInfo->inUse,1);
1403 if(is_size_safe_to_change(cifsInfo)) {
1404 /* can not safely change the file size here if the
1405 client is writing to it due to potential races */
1406 i_size_write(tmp_inode,end_of_file);
1408 /* 512 bytes (2**9) is the fake blocksize that must be used */
1409 /* for this calculation, even though the reported blocksize is larger */
1410 tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9;
1413 if (allocation_size < end_of_file)
1414 cFYI(1, ("Possible sparse file: allocation size less than end of file "));
1416 ("File Size %ld and blocks %ld and blocksize %ld",
1417 (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
1418 tmp_inode->i_blksize));
1419 if (S_ISREG(tmp_inode->i_mode)) {
1420 cFYI(1, (" File inode "));
1421 tmp_inode->i_op = &cifs_file_inode_ops;
1422 tmp_inode->i_fop = &cifs_file_ops;
1423 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1424 } else if (S_ISDIR(tmp_inode->i_mode)) {
1425 cFYI(1, (" Directory inode"));
1426 tmp_inode->i_op = &cifs_dir_inode_ops;
1427 tmp_inode->i_fop = &cifs_dir_ops;
1428 } else if (S_ISLNK(tmp_inode->i_mode)) {
1429 cFYI(1, (" Symbolic Link inode "));
1430 tmp_inode->i_op = &cifs_symlink_inode_ops;
1432 cFYI(1, (" Init special inode "));
1433 init_special_inode(tmp_inode, tmp_inode->i_mode,
1439 unix_fill_in_inode(struct inode *tmp_inode,
1440 FILE_UNIX_INFO * pfindData, int *pobject_type)
1442 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1443 __u32 type = le32_to_cpu(pfindData->Type);
1444 __u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes);
1445 __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
1446 cifsInfo->time = jiffies;
1447 atomic_inc(&cifsInfo->inUse);
1449 tmp_inode->i_atime =
1450 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1451 tmp_inode->i_mtime =
1452 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
1453 tmp_inode->i_ctime =
1454 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
1456 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
1457 if (type == UNIX_FILE) {
1458 *pobject_type = DT_REG;
1459 tmp_inode->i_mode |= S_IFREG;
1460 } else if (type == UNIX_SYMLINK) {
1461 *pobject_type = DT_LNK;
1462 tmp_inode->i_mode |= S_IFLNK;
1463 } else if (type == UNIX_DIR) {
1464 *pobject_type = DT_DIR;
1465 tmp_inode->i_mode |= S_IFDIR;
1466 } else if (type == UNIX_CHARDEV) {
1467 *pobject_type = DT_CHR;
1468 tmp_inode->i_mode |= S_IFCHR;
1469 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1470 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1471 } else if (type == UNIX_BLOCKDEV) {
1472 *pobject_type = DT_BLK;
1473 tmp_inode->i_mode |= S_IFBLK;
1474 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1475 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1476 } else if (type == UNIX_FIFO) {
1477 *pobject_type = DT_FIFO;
1478 tmp_inode->i_mode |= S_IFIFO;
1479 } else if (type == UNIX_SOCKET) {
1480 *pobject_type = DT_SOCK;
1481 tmp_inode->i_mode |= S_IFSOCK;
1484 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
1485 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
1486 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
1489 if(is_size_safe_to_change(cifsInfo)) {
1490 /* can not safely change the file size here if the
1491 client is writing to it due to potential races */
1492 i_size_write(tmp_inode,end_of_file);
1494 /* 512 bytes (2**9) is the fake blocksize that must be used */
1495 /* for this calculation, not the real blocksize */
1496 tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
1499 if (S_ISREG(tmp_inode->i_mode)) {
1500 cFYI(1, ("File inode"));
1501 tmp_inode->i_op = &cifs_file_inode_ops;
1502 tmp_inode->i_fop = &cifs_file_ops;
1503 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1504 } else if (S_ISDIR(tmp_inode->i_mode)) {
1505 cFYI(1, ("Directory inode"));
1506 tmp_inode->i_op = &cifs_dir_inode_ops;
1507 tmp_inode->i_fop = &cifs_dir_ops;
1508 } else if (S_ISLNK(tmp_inode->i_mode)) {
1509 cFYI(1, ("Symbolic Link inode"));
1510 tmp_inode->i_op = &cifs_symlink_inode_ops;
1511 /* tmp_inode->i_fop = *//* do not need to set to anything */
1513 cFYI(1, ("Special inode"));
1514 init_special_inode(tmp_inode, tmp_inode->i_mode,
1520 construct_dentry(struct qstr *qstring, struct file *file,
1521 struct inode **ptmp_inode, struct dentry **pnew_dentry)
1523 struct dentry *tmp_dentry;
1524 struct cifs_sb_info *cifs_sb;
1525 struct cifsTconInfo *pTcon;
1527 cFYI(1, ("For %s ", qstring->name));
1528 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1529 pTcon = cifs_sb->tcon;
1531 qstring->hash = full_name_hash(qstring->name, qstring->len);
1532 tmp_dentry = d_lookup(file->f_dentry, qstring);
1534 cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
1535 *ptmp_inode = tmp_dentry->d_inode;
1536 /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
1537 if(*ptmp_inode == NULL) {
1538 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1539 if(*ptmp_inode == NULL)
1541 d_instantiate(tmp_dentry, *ptmp_inode);
1542 insert_inode_hash(*ptmp_inode);
1545 tmp_dentry = d_alloc(file->f_dentry, qstring);
1546 if(tmp_dentry == NULL) {
1547 cERROR(1,("Failed allocating dentry"));
1552 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1553 tmp_dentry->d_op = &cifs_dentry_ops;
1554 if(*ptmp_inode == NULL)
1556 d_instantiate(tmp_dentry, *ptmp_inode);
1557 d_rehash(tmp_dentry);
1558 insert_inode_hash(*ptmp_inode);
1561 tmp_dentry->d_time = jiffies;
1562 *pnew_dentry = tmp_dentry;
1565 static void reset_resume_key(struct file * dir_file,
1566 unsigned char * filename,
1567 unsigned int len,int Unicode,struct nls_table * nls_tab) {
1568 struct cifsFileInfo *cifsFile;
1570 cifsFile = (struct cifsFileInfo *)dir_file->private_data;
1571 if(cifsFile == NULL)
1573 if(cifsFile->search_resume_name) {
1574 kfree(cifsFile->search_resume_name);
1579 cifsFile->resume_name_length = len;
1581 cifsFile->search_resume_name =
1582 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1584 if(cifsFile->search_resume_name == NULL) {
1585 cERROR(1,("failed new resume key allocate, length %d",
1586 cifsFile->resume_name_length));
1590 cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
1591 filename, len, nls_tab);
1593 memcpy(cifsFile->search_resume_name, filename,
1594 cifsFile->resume_name_length);
1595 cFYI(1,("Reset resume key to: %s with len %d",filename,len));
1602 cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
1603 struct file *file, filldir_t filldir, void *direntry)
1605 struct inode *tmp_inode;
1606 struct dentry *tmp_dentry;
1609 pqstring->name = pfindData->FileName;
1610 /* pqstring->len is already set by caller */
1612 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1613 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1616 fill_in_inode(tmp_inode, pfindData, &object_type);
1617 rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
1618 tmp_inode->i_ino, object_type);
1620 /* due to readdir error we need to recalculate resume
1621 key so next readdir will restart on right entry */
1622 cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
1629 cifs_filldir_unix(struct qstr *pqstring,
1630 FILE_UNIX_INFO * pUnixFindData, struct file *file,
1631 filldir_t filldir, void *direntry)
1633 struct inode *tmp_inode;
1634 struct dentry *tmp_dentry;
1635 int object_type, rc;
1637 pqstring->name = pUnixFindData->FileName;
1638 pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
1640 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1641 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1645 unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
1646 rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
1647 file->f_pos, tmp_inode->i_ino, object_type);
1649 /* due to readdir error we need to recalculate resume
1650 key so next readdir will restart on right entry */
1651 cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
1658 cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1662 int Unicode = FALSE;
1663 int UnixSearch = FALSE;
1664 unsigned int bufsize, i;
1666 struct cifs_sb_info *cifs_sb;
1667 struct cifsTconInfo *pTcon;
1668 struct cifsFileInfo *cifsFile = NULL;
1669 char *full_path = NULL;
1671 struct qstr qstring;
1672 T2_FFIRST_RSP_PARMS findParms;
1673 T2_FNEXT_RSP_PARMS findNextParms;
1674 FILE_DIRECTORY_INFO *pfindData;
1675 FILE_DIRECTORY_INFO *lastFindData;
1676 FILE_UNIX_INFO *pfindDataUnix;
1680 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1681 pTcon = cifs_sb->tcon;
1682 bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
1683 if(bufsize > CIFS_MAX_MSGSIZE) {
1687 data = kmalloc(bufsize, GFP_KERNEL);
1688 pfindData = (FILE_DIRECTORY_INFO *) data;
1693 if(file->f_dentry == NULL) {
1698 down(&file->f_dentry->d_sb->s_vfs_rename_sem);
1699 full_path = build_wildcard_path_from_dentry(file->f_dentry);
1700 up(&file->f_dentry->d_sb->s_vfs_rename_sem);
1702 if(full_path == NULL) {
1707 cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
1709 switch ((int) file->f_pos) {
1711 if (filldir(direntry, ".", 1, file->f_pos,
1712 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
1713 cERROR(1, ("Filldir for current dir failed "));
1719 if (filldir(direntry, "..", 2, file->f_pos,
1720 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
1721 cERROR(1, ("Filldir for parent dir failed "));
1727 if (file->private_data != NULL) {
1729 (struct cifsFileInfo *) file->private_data;
1730 if (cifsFile->endOfSearch) {
1731 if(cifsFile->emptyDir) {
1732 cFYI(1, ("End of search, empty dir"));
1737 cifsFile->invalidHandle = TRUE;
1738 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1740 if(cifsFile->search_resume_name) {
1741 kfree(cifsFile->search_resume_name);
1742 cifsFile->search_resume_name = NULL;
1745 rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
1746 &findParms, cifs_sb->local_nls,
1747 &Unicode, &UnixSearch);
1748 cFYI(1, ("Count: %d End: %d ",
1749 le16_to_cpu(findParms.SearchCount),
1750 le16_to_cpu(findParms.EndofSearch)));
1753 __u16 count = le16_to_cpu(findParms.SearchCount);
1754 searchHandle = findParms.SearchHandle;
1755 if(file->private_data == NULL)
1756 file->private_data =
1757 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
1758 if (file->private_data) {
1759 memset(file->private_data, 0,
1760 sizeof (struct cifsFileInfo));
1762 (struct cifsFileInfo *) file->private_data;
1763 cifsFile->netfid = searchHandle;
1764 cifsFile->invalidHandle = FALSE;
1765 init_MUTEX(&cifsFile->fh_sem);
1771 renew_parental_timestamps(file->f_dentry);
1773 (FILE_DIRECTORY_INFO *) ((char *) pfindData +
1774 le16_to_cpu(findParms.LastNameOffset));
1775 if((char *)lastFindData > (char *)pfindData + bufsize) {
1776 cFYI(1,("last search entry past end of packet"));
1780 /* Offset of resume key same for levels 257 and 514 */
1781 cifsFile->resume_key = lastFindData->FileIndex;
1782 if(UnixSearch == FALSE) {
1783 cifsFile->resume_name_length =
1784 le32_to_cpu(lastFindData->FileNameLength);
1785 if(cifsFile->resume_name_length > bufsize - 64) {
1786 cFYI(1,("Illegal resume file name length %d",
1787 cifsFile->resume_name_length));
1791 cifsFile->search_resume_name =
1792 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1793 cFYI(1,("Last file: %s with name %d bytes long",
1794 lastFindData->FileName,
1795 cifsFile->resume_name_length));
1796 if(cifsFile->search_resume_name == NULL) {
1800 memcpy(cifsFile->search_resume_name,
1801 lastFindData->FileName,
1802 cifsFile->resume_name_length);
1804 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1805 if (Unicode == TRUE) {
1806 for(i=0;(pfindDataUnix->FileName[i]
1807 | pfindDataUnix->FileName[i+1]);
1812 cifsFile->resume_name_length = i + 2;
1814 cifsFile->resume_name_length =
1815 strnlen(pfindDataUnix->FileName,
1818 if(cifsFile->resume_name_length > bufsize - 64) {
1819 cFYI(1,("Illegal resume file name length %d",
1820 cifsFile->resume_name_length));
1824 cifsFile->search_resume_name =
1825 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1826 cFYI(1,("Last file: %s with name %d bytes long",
1827 pfindDataUnix->FileName,
1828 cifsFile->resume_name_length));
1829 if(cifsFile->search_resume_name == NULL) {
1833 memcpy(cifsFile->search_resume_name,
1834 pfindDataUnix->FileName,
1835 cifsFile->resume_name_length);
1837 for (i = 2; i < count + 2; i++) {
1838 if (UnixSearch == FALSE) {
1839 __u32 len = le32_to_cpu(pfindData->FileNameLength);
1840 if (Unicode == TRUE)
1843 (pfindData->FileName,
1845 pfindData->FileName,
1847 cifs_sb->local_nls);
1850 || (pfindData->FileName[0] != '.'))
1855 FileName[1] != '.'))) {
1856 if(cifs_filldir(&qstring,
1860 /* do not end search if
1861 kernel not ready to take
1862 remaining entries yet */
1863 reset_resume_key(file, pfindData->FileName,qstring.len,
1864 Unicode, cifs_sb->local_nls);
1865 findParms.EndofSearch = 0;
1870 } else { /* UnixSearch */
1872 (FILE_UNIX_INFO *) pfindData;
1873 if (Unicode == TRUE)
1876 (pfindDataUnix->FileName,
1878 pfindDataUnix->FileName,
1880 cifs_sb->local_nls);
1883 strnlen(pfindDataUnix->
1886 if (((qstring.len != 1)
1888 FileName[0] != '.'))
1889 && ((qstring.len != 2)
1893 FileName[1] != '.'))) {
1894 if(cifs_filldir_unix(&qstring,
1899 /* do not end search if
1900 kernel not ready to take
1901 remaining entries yet */
1902 findParms.EndofSearch = 0;
1903 reset_resume_key(file, pfindDataUnix->FileName,
1904 qstring.len,Unicode,cifs_sb->local_nls);
1910 /* works also for Unix ff struct since first field of both */
1912 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1913 + le32_to_cpu(pfindData->NextEntryOffset));
1914 /* BB also should check to make sure that pointer is not beyond the end of the SMB */
1915 /* if(pfindData > lastFindData) rc = -EIO; break; */
1916 } /* end for loop */
1917 if ((findParms.EndofSearch != 0) && cifsFile) {
1918 cifsFile->endOfSearch = TRUE;
1919 if(findParms.SearchCount == cpu_to_le16(2))
1920 cifsFile->emptyDir = TRUE;
1924 cifsFile->endOfSearch = TRUE;
1925 /* unless parent directory gone do not return error */
1930 if (file->private_data == NULL) {
1933 ("Readdir on closed srch, pos = %lld",
1936 cifsFile = (struct cifsFileInfo *) file->private_data;
1937 if (cifsFile->endOfSearch) {
1939 cFYI(1, ("End of search "));
1942 searchHandle = cifsFile->netfid;
1943 rc = CIFSFindNext(xid, pTcon, pfindData,
1944 &findNextParms, searchHandle,
1945 cifsFile->search_resume_name,
1946 cifsFile->resume_name_length,
1947 cifsFile->resume_key,
1948 &Unicode, &UnixSearch);
1949 cFYI(1,("Count: %d End: %d ",
1950 le16_to_cpu(findNextParms.SearchCount),
1951 le16_to_cpu(findNextParms.EndofSearch)));
1952 if ((rc == 0) && (findNextParms.SearchCount != 0)) {
1953 /* BB save off resume key, key name and name length */
1954 __u16 count = le16_to_cpu(findNextParms.SearchCount);
1956 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1957 + le16_to_cpu(findNextParms.LastNameOffset));
1958 if((char *)lastFindData > (char *)pfindData + bufsize) {
1959 cFYI(1,("last search entry past end of packet"));
1963 /* Offset of resume key same for levels 257 and 514 */
1964 cifsFile->resume_key = lastFindData->FileIndex;
1966 if(UnixSearch == FALSE) {
1967 cifsFile->resume_name_length =
1968 le32_to_cpu(lastFindData->FileNameLength);
1969 if(cifsFile->resume_name_length > bufsize - 64) {
1970 cFYI(1,("Illegal resume file name length %d",
1971 cifsFile->resume_name_length));
1975 /* Free the memory allocated by previous findfirst
1976 or findnext call - we can not reuse the memory since
1977 the resume name may not be same string length */
1978 if(cifsFile->search_resume_name)
1979 kfree(cifsFile->search_resume_name);
1980 cifsFile->search_resume_name =
1981 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1982 cFYI(1,("Last file: %s with name %d bytes long",
1983 lastFindData->FileName,
1984 cifsFile->resume_name_length));
1985 if(cifsFile->search_resume_name == NULL) {
1990 memcpy(cifsFile->search_resume_name,
1991 lastFindData->FileName,
1992 cifsFile->resume_name_length);
1994 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1995 if (Unicode == TRUE) {
1996 for(i=0;(pfindDataUnix->FileName[i]
1997 | pfindDataUnix->FileName[i+1]);
2002 cifsFile->resume_name_length = i + 2;
2004 cifsFile->resume_name_length =
2005 strnlen(pfindDataUnix->
2009 if(cifsFile->resume_name_length > bufsize - 64) {
2010 cFYI(1,("Illegal resume file name length %d",
2011 cifsFile->resume_name_length));
2015 /* Free the memory allocated by previous findfirst
2016 or findnext call - we can not reuse the memory since
2017 the resume name may not be same string length */
2018 if(cifsFile->search_resume_name)
2019 kfree(cifsFile->search_resume_name);
2020 cifsFile->search_resume_name =
2021 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
2022 cFYI(1,("fnext last file: %s with name %d bytes long",
2023 pfindDataUnix->FileName,
2024 cifsFile->resume_name_length));
2025 if(cifsFile->search_resume_name == NULL) {
2029 memcpy(cifsFile->search_resume_name,
2030 pfindDataUnix->FileName,
2031 cifsFile->resume_name_length);
2034 for (i = 0; i < count; i++) {
2035 __u32 len = le32_to_cpu(pfindData->
2037 if (UnixSearch == FALSE) {
2038 if (Unicode == TRUE)
2041 (pfindData->FileName,
2043 pfindData->FileName,
2045 cifs_sb->local_nls);
2048 || (pfindData->FileName[0] != '.'))
2050 || (pfindData->FileName[0] != '.')
2051 || (pfindData->FileName[1] !=
2058 /* do not end search if
2059 kernel not ready to take
2060 remaining entries yet */
2061 findNextParms.EndofSearch = 0;
2062 reset_resume_key(file, pfindData->FileName,qstring.len,
2063 Unicode,cifs_sb->local_nls);
2068 } else { /* UnixSearch */
2072 if (Unicode == TRUE)
2075 (pfindDataUnix->FileName,
2077 pfindDataUnix->FileName,
2079 cifs_sb->local_nls);
2086 if (((qstring.len != 1)
2088 FileName[0] != '.'))
2089 && ((qstring.len != 2)
2095 if(cifs_filldir_unix
2100 /* do not end search if
2101 kernel not ready to take
2102 remaining entries yet */
2103 findNextParms.EndofSearch = 0;
2104 reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
2105 Unicode,cifs_sb->local_nls);
2111 pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData +
2112 le32_to_cpu(pfindData->NextEntryOffset));
2113 /* works also for Unix find struct since first field of both */
2114 /* BB also should check to ensure pointer not beyond end of SMB */
2115 } /* end for loop */
2116 if (findNextParms.EndofSearch != 0) {
2117 cifsFile->endOfSearch = TRUE;
2120 cifsFile->endOfSearch = TRUE;
2121 rc = 0; /* unless parent directory disappeared - do not
2122 return error here (eg Access Denied or no more files) */
2134 int cifs_prepare_write(struct file *file, struct page *page,
2135 unsigned from, unsigned to)
2138 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
2139 cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
2140 if (!PageUptodate(page)) {
2141 /* if (to - from != PAGE_CACHE_SIZE) {
2142 void *kaddr = kmap_atomic(page, KM_USER0);
2143 memset(kaddr, 0, from);
2144 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
2145 flush_dcache_page(page);
2146 kunmap_atomic(kaddr, KM_USER0);
2148 /* If we are writing a full page it will be up to date,
2149 no need to read from the server */
2150 if((to==PAGE_CACHE_SIZE) && (from == 0))
2151 SetPageUptodate(page);
2153 /* might as well read a page, it is fast enough */
2154 if((file->f_flags & O_ACCMODE) != O_WRONLY) {
2155 rc = cifs_readpage_worker(file,page,&offset);
2157 /* should we try using another
2158 file handle if there is one - how would we lock it
2159 to prevent close of that handle racing with this read? */
2160 /* In any case this will be written out by commit_write */
2164 /* BB should we pass any errors back? e.g. if we do not have read access to the file */
2169 struct address_space_operations cifs_addr_ops = {
2170 .readpage = cifs_readpage,
2171 .readpages = cifs_readpages,
2172 .writepage = cifs_writepage,
2173 .prepare_write = cifs_prepare_write,
2174 .commit_write = cifs_commit_write,
2175 .set_page_dirty = __set_page_dirty_nobuffers,
2176 /* .sync_page = cifs_sync_page, */