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);
220 rc = cifs_get_inode_info(&file->f_dentry->d_inode,
221 full_path, buf, inode->i_sb);
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);
372 rc = cifs_get_inode_info(&inode,
373 full_path, NULL, inode->i_sb);
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,
577 cifs_write(struct file * file, const char *write_data,
578 size_t write_size, loff_t * poffset)
581 unsigned int bytes_written = 0;
582 unsigned int total_written;
583 struct cifs_sb_info *cifs_sb;
584 struct cifsTconInfo *pTcon;
586 struct cifsFileInfo * open_file;
588 if(file->f_dentry == NULL)
593 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
594 pTcon = cifs_sb->tcon;
597 (" write %d bytes to offset %lld of %s", write_size,
598 *poffset, file->f_dentry->d_name.name)); */
600 if (file->private_data == NULL) {
604 open_file = (struct cifsFileInfo *) file->private_data;
606 if(file->f_dentry->d_inode == NULL) {
611 if (*poffset > file->f_dentry->d_inode->i_size)
612 long_op = 2; /* writes past end of file can take a long time */
616 for (total_written = 0; write_size > total_written;
617 total_written += bytes_written) {
619 while(rc == -EAGAIN) {
620 if(file->private_data == NULL) {
621 /* file has been closed on us */
623 return total_written;
625 if ((open_file->invalidHandle) && (!open_file->closePend)) {
626 if((file->f_dentry == NULL) || (file->f_dentry->d_inode == NULL)) {
628 return total_written;
630 /* we could deadlock if we called
631 filemap_fdatawait from here so tell
632 reopen_file not to flush data to server now */
633 rc = cifs_reopen_file(file->f_dentry->d_inode,
639 rc = CIFSSMBWrite(xid, pTcon,
641 write_size - total_written, *poffset,
643 write_data + total_written, long_op);
645 if (rc || (bytes_written == 0)) {
653 *poffset += bytes_written;
654 long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
657 #ifdef CONFIG_CIFS_STATS
658 if(total_written > 0) {
659 atomic_inc(&pTcon->num_writes);
660 spin_lock(&pTcon->stat_lock);
661 pTcon->bytes_written += total_written;
662 spin_unlock(&pTcon->stat_lock);
666 /* since the write may have blocked check these pointers again */
668 if(file->f_dentry->d_inode) {
669 file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
671 if (total_written > 0) {
672 if (*poffset > file->f_dentry->d_inode->i_size)
673 i_size_write(file->f_dentry->d_inode, *poffset);
675 mark_inode_dirty_sync(file->f_dentry->d_inode);
679 return total_written;
683 cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
685 struct address_space *mapping = page->mapping;
686 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
689 int bytes_written = 0;
690 struct cifs_sb_info *cifs_sb;
691 struct cifsTconInfo *pTcon;
693 struct cifsInodeInfo *cifsInode;
694 struct cifsFileInfo *open_file = NULL;
695 struct list_head *tmp;
696 struct list_head *tmp1;
700 } else if(!mapping->host) {
704 inode = page->mapping->host;
705 cifs_sb = CIFS_SB(inode->i_sb);
706 pTcon = cifs_sb->tcon;
708 offset += (loff_t)from;
709 write_data = kmap(page);
712 if((to > PAGE_CACHE_SIZE) || (from > to)) {
717 /* racing with truncate? */
718 if(offset > mapping->host->i_size) {
720 return 0; /* don't care */
723 /* check to make sure that we are not extending the file */
724 if(mapping->host->i_size - offset < (loff_t)to)
725 to = (unsigned)(mapping->host->i_size - offset);
728 cifsInode = CIFS_I(mapping->host);
729 read_lock(&GlobalSMBSeslock);
730 /* BB we should start at the end */
731 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
732 open_file = list_entry(tmp,struct cifsFileInfo, flist);
733 if(open_file->closePend)
735 /* We check if file is open for writing first */
736 if((open_file->pfile) &&
737 ((open_file->pfile->f_flags & O_RDWR) ||
738 (open_file->pfile->f_flags & O_WRONLY))) {
739 read_unlock(&GlobalSMBSeslock);
740 bytes_written = cifs_write(open_file->pfile, write_data,
742 read_lock(&GlobalSMBSeslock);
743 /* Does mm or vfs already set times? */
744 inode->i_atime = inode->i_mtime = CURRENT_TIME;
745 if ((bytes_written > 0) && (offset)) {
747 } else if(bytes_written < 0) {
749 /* have seen a case in which
750 kernel seemed to have closed/freed a file
751 even with writes active so we might as well
752 see if there are other file structs to try
753 for the same inode before giving up */
758 break; /* now that we found a valid file handle
759 and tried to write to it we are done, no
760 sense continuing to loop looking for another */
762 if(tmp->next == NULL) {
763 cFYI(1,("File instance %p removed",tmp));
767 read_unlock(&GlobalSMBSeslock);
768 if(open_file == NULL) {
769 cFYI(1,("No writeable filehandles for inode"));
779 cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
785 /* call 16K write then Setpageuptodate */
792 cifs_writepage(struct page* page, struct writeback_control *wbc)
798 /* BB add check for wbc flags */
799 page_cache_get(page);
800 if (!PageUptodate(page)) {
801 cFYI(1,("ppw - page not up to date"));
804 rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
805 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
807 page_cache_release(page);
813 cifs_commit_write(struct file *file, struct page *page, unsigned offset,
818 struct inode *inode = page->mapping->host;
819 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
823 cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
824 if (position > inode->i_size){
825 i_size_write(inode, position);
826 /*if (file->private_data == NULL) {
829 open_file = (struct cifsFileInfo *)file->private_data;
830 cifs_sb = CIFS_SB(inode->i_sb);
832 while(rc == -EAGAIN) {
833 if((open_file->invalidHandle) &&
834 (!open_file->closePend)) {
835 rc = cifs_reopen_file(file->f_dentry->d_inode,file);
839 if(!open_file->closePend) {
840 rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
841 position, open_file->netfid,
842 open_file->pid,FALSE);
848 cFYI(1,(" SetEOF (commit write) rc = %d",rc));
851 if (!PageUptodate(page)) {
852 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
853 /* can not rely on (or let) writepage write this data */
855 cFYI(1,("Illegal offsets, can not copy from %d to %d",
860 /* this is probably better than directly calling
861 partialpage_write since in this function
862 the file handle is known which we might as well
864 /* BB check if anything else missing out of ppw */
865 /* such as updating last write time */
866 page_data = kmap(page);
867 rc = cifs_write(file, page_data+offset,to-offset,
871 /* else if rc < 0 should we set writebehind rc? */
874 set_page_dirty(page);
882 cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
886 struct inode * inode = file->f_dentry->d_inode;
890 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
891 dentry->d_name.name, datasync));
893 rc = filemap_fdatawrite(inode->i_mapping);
895 CIFS_I(inode)->write_behind_rc = 0;
901 cifs_sync_page(struct page *page)
903 struct address_space *mapping;
905 unsigned long index = page->index;
906 unsigned int rpages = 0;
909 cFYI(1,("sync page %p",page));
910 mapping = page->mapping;
913 inode = mapping->host;
917 /* fill in rpages then
918 result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */
920 /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
928 * As file closes, flush all cached write data for this inode checking
929 * for write behind errors.
932 int cifs_flush(struct file *file)
934 struct inode * inode = file->f_dentry->d_inode;
937 /* Rather than do the steps manually: */
938 /* lock the inode for writing */
939 /* loop through pages looking for write behind data (dirty pages) */
940 /* coalesce into contiguous 16K (or smaller) chunks to write to server */
941 /* send to server (prefer in parallel) */
942 /* deal with writebehind errors */
943 /* unlock inode for writing */
944 /* filemapfdatawrite appears easier for the time being */
946 rc = filemap_fdatawrite(inode->i_mapping);
947 if(rc == 0) /* reset wb rc if we were able to write out dirty pages */
948 CIFS_I(inode)->write_behind_rc = 0;
950 cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
957 cifs_read(struct file * file, char *read_data, size_t read_size,
961 unsigned int bytes_read = 0;
962 unsigned int total_read;
963 unsigned int current_read_size;
964 struct cifs_sb_info *cifs_sb;
965 struct cifsTconInfo *pTcon;
967 char * current_offset;
968 struct cifsFileInfo * open_file;
971 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
972 pTcon = cifs_sb->tcon;
974 if (file->private_data == NULL) {
978 open_file = (struct cifsFileInfo *)file->private_data;
980 if((file->f_flags & O_ACCMODE) == O_WRONLY) {
981 cFYI(1,("attempting read on write only file instance"));
984 for (total_read = 0,current_offset=read_data; read_size > total_read;
985 total_read += bytes_read,current_offset+=bytes_read) {
986 current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
988 while(rc == -EAGAIN) {
989 if ((open_file->invalidHandle) && (!open_file->closePend)) {
990 rc = cifs_reopen_file(file->f_dentry->d_inode,
996 rc = CIFSSMBRead(xid, pTcon,
998 current_read_size, *poffset,
999 &bytes_read, ¤t_offset);
1001 if (rc || (bytes_read == 0)) {
1009 #ifdef CONFIG_CIFS_STATS
1010 atomic_inc(&pTcon->num_reads);
1011 spin_lock(&pTcon->stat_lock);
1012 pTcon->bytes_read += total_read;
1013 spin_unlock(&pTcon->stat_lock);
1015 *poffset += bytes_read;
1022 int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
1024 struct dentry * dentry = file->f_dentry;
1028 rc = cifs_revalidate(dentry);
1030 cFYI(1,("Validation prior to mmap failed, error=%d", rc));
1034 rc = generic_file_mmap(file, vma);
1039 static void cifs_copy_cache_pages(struct address_space *mapping,
1040 struct list_head *pages, int bytes_read,
1041 char *data,struct pagevec * plru_pvec)
1046 while (bytes_read > 0) {
1047 if(list_empty(pages))
1050 page = list_entry(pages->prev, struct page, lru);
1051 list_del(&page->lru);
1053 if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
1054 page_cache_release(page);
1055 cFYI(1,("Add page cache failed"));
1059 target = kmap_atomic(page,KM_USER0);
1061 if(PAGE_CACHE_SIZE > bytes_read) {
1062 memcpy(target,data,bytes_read);
1063 /* zero the tail end of this partial page */
1064 memset(target+bytes_read,0,PAGE_CACHE_SIZE-bytes_read);
1067 memcpy(target,data,PAGE_CACHE_SIZE);
1068 bytes_read -= PAGE_CACHE_SIZE;
1070 kunmap_atomic(target,KM_USER0);
1072 flush_dcache_page(page);
1073 SetPageUptodate(page);
1075 if (!pagevec_add(plru_pvec, page))
1076 __pagevec_lru_add(plru_pvec);
1077 data += PAGE_CACHE_SIZE;
1084 cifs_readpages(struct file *file, struct address_space *mapping,
1085 struct list_head *page_list, unsigned num_pages)
1091 struct cifs_sb_info *cifs_sb;
1092 struct cifsTconInfo *pTcon;
1094 unsigned int read_size,i;
1095 char * smb_read_data = 0;
1096 struct smb_com_read_rsp * pSMBr;
1097 struct pagevec lru_pvec;
1098 struct cifsFileInfo * open_file;
1101 if (file->private_data == NULL) {
1105 open_file = (struct cifsFileInfo *)file->private_data;
1106 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1107 pTcon = cifs_sb->tcon;
1109 pagevec_init(&lru_pvec, 0);
1111 for(i = 0;i<num_pages;) {
1112 unsigned contig_pages;
1113 struct page * tmp_page;
1114 unsigned long expected_index;
1116 if(list_empty(page_list)) {
1119 page = list_entry(page_list->prev, struct page, lru);
1120 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1122 /* count adjacent pages that we will read into */
1124 expected_index = list_entry(page_list->prev,struct page,lru)->index;
1125 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1126 if(tmp_page->index == expected_index) {
1133 if(contig_pages + i > num_pages) {
1134 contig_pages = num_pages - i;
1137 /* for reads over a certain size could initiate async read ahead */
1139 read_size = contig_pages * PAGE_CACHE_SIZE;
1140 /* Read size needs to be in multiples of one page */
1141 read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
1144 while(rc == -EAGAIN) {
1145 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1146 rc = cifs_reopen_file(file->f_dentry->d_inode,
1152 rc = CIFSSMBRead(xid, pTcon,
1155 &bytes_read, &smb_read_data);
1156 /* BB need to check return code here */
1159 cifs_buf_release(smb_read_data);
1164 if ((rc < 0) || (smb_read_data == NULL)) {
1165 cFYI(1,("Read error in readpages: %d",rc));
1166 /* clean up remaing pages off list */
1167 while (!list_empty(page_list) && (i < num_pages)) {
1168 page = list_entry(page_list->prev, struct page, lru);
1169 list_del(&page->lru);
1170 page_cache_release(page);
1173 } else if (bytes_read > 0) {
1174 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1175 cifs_copy_cache_pages(mapping, page_list, bytes_read,
1176 smb_read_data + 4 /* RFC1001 hdr */ +
1177 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1179 i += bytes_read >> PAGE_CACHE_SHIFT;
1180 #ifdef CONFIG_CIFS_STATS
1181 atomic_inc(&pTcon->num_reads);
1182 spin_lock(&pTcon->stat_lock);
1183 pTcon->bytes_read += bytes_read;
1184 spin_unlock(&pTcon->stat_lock);
1186 if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1187 cFYI(1,("Partial page %d of %d read to cache",i++,num_pages));
1189 i++; /* account for partial page */
1191 /* server copy of file can have smaller size than client */
1192 /* BB do we need to verify this common case ? this case is ok -
1193 if we are at server EOF we will hit it on next read */
1195 /* while(!list_empty(page_list) && (i < num_pages)) {
1196 page = list_entry(page_list->prev,struct page, list);
1197 list_del(&page->list);
1198 page_cache_release(page);
1203 cFYI(1,("No bytes read (%d) at offset %lld . Cleaning remaining pages from readahead list",bytes_read,offset));
1204 /* BB turn off caching and do new lookup on file size at server? */
1205 while (!list_empty(page_list) && (i < num_pages)) {
1206 page = list_entry(page_list->prev, struct page, lru);
1207 list_del(&page->lru);
1208 page_cache_release(page); /* BB removeme - replace with zero of page? */
1213 cifs_buf_release(smb_read_data);
1219 pagevec_lru_add(&lru_pvec);
1221 /* need to free smb_read_data buf before exit */
1223 cifs_buf_release(smb_read_data);
1231 static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
1236 page_cache_get(page);
1237 read_data = kmap(page);
1238 /* for reads over a certain size could initiate async read ahead */
1240 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1245 cFYI(1,("Bytes read %d ",rc));
1248 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
1250 if(PAGE_CACHE_SIZE > rc) {
1251 memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
1253 flush_dcache_page(page);
1254 SetPageUptodate(page);
1259 page_cache_release(page);
1264 cifs_readpage(struct file *file, struct page *page)
1266 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1272 if (file->private_data == NULL) {
1277 cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
1279 rc = cifs_readpage_worker(file,page,&offset);
1287 /* We do not want to update the file size from server for inodes
1288 open for write - to avoid races with writepage extending
1289 the file - in the future we could consider allowing
1290 refreshing the inode only on increases in the file size
1291 but this is tricky to do without racing with writebehind
1292 page caching in the current Linux kernel design */
1294 int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
1296 struct list_head *tmp;
1297 struct list_head *tmp1;
1298 struct cifsFileInfo *open_file = NULL;
1301 if(cifsInode == NULL)
1304 read_lock(&GlobalSMBSeslock);
1305 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
1306 open_file = list_entry(tmp,struct cifsFileInfo, flist);
1307 if(open_file == NULL)
1309 if(open_file->closePend)
1311 /* We check if file is open for writing,
1312 BB we could supplement this with a check to see if file size
1313 changes have been flushed to server - ie inode metadata dirty */
1314 if((open_file->pfile) &&
1315 ((open_file->pfile->f_flags & O_RDWR) ||
1316 (open_file->pfile->f_flags & O_WRONLY))) {
1320 if(tmp->next == NULL) {
1321 cFYI(1,("File instance %p removed",tmp));
1325 read_unlock(&GlobalSMBSeslock);
1331 fill_in_inode(struct inode *tmp_inode,
1332 FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
1334 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1335 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
1337 pfindData->ExtFileAttributes =
1338 le32_to_cpu(pfindData->ExtFileAttributes);
1339 pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
1340 pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
1341 cifsInfo->cifsAttrs = pfindData->ExtFileAttributes;
1342 cifsInfo->time = jiffies;
1344 /* Linux can not store file creation time unfortunately so ignore it */
1345 tmp_inode->i_atime =
1346 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1347 tmp_inode->i_mtime =
1348 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
1349 tmp_inode->i_ctime =
1350 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
1351 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
1352 /* 2767 perms - indicate mandatory locking */
1353 /* BB fill in uid and gid here? with help from winbind?
1354 or retrieve from NTFS stream extended attribute */
1355 if(atomic_read(&cifsInfo->inUse) == 0) {
1356 tmp_inode->i_uid = cifs_sb->mnt_uid;
1357 tmp_inode->i_gid = cifs_sb->mnt_gid;
1358 /* set default mode. will override for dirs below */
1359 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
1363 ("CIFS FFIRST: Attributes came in as 0x%x",
1364 pfindData->ExtFileAttributes));
1365 if (pfindData->ExtFileAttributes & ATTR_REPARSE) {
1366 *pobject_type = DT_LNK;
1367 /* BB can this and S_IFREG or S_IFDIR be set as in Windows? */
1368 tmp_inode->i_mode |= S_IFLNK;
1369 } else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) {
1370 *pobject_type = DT_DIR;
1371 /* override default perms since we do not lock dirs */
1372 if(atomic_read(&cifsInfo->inUse) == 0) {
1373 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
1375 tmp_inode->i_mode |= S_IFDIR;
1377 *pobject_type = DT_REG;
1378 tmp_inode->i_mode |= S_IFREG;
1379 if(pfindData->ExtFileAttributes & ATTR_READONLY)
1380 tmp_inode->i_mode &= ~(S_IWUGO);
1382 }/* could add code here - to validate if device or weird share type? */
1384 /* can not fill in nlink here as in qpathinfo version and Unx search */
1385 if(atomic_read(&cifsInfo->inUse) == 0) {
1386 atomic_set(&cifsInfo->inUse,1);
1389 if(is_size_safe_to_change(cifsInfo)) {
1390 /* can not safely change the file size here if the
1391 client is writing to it due to potential races */
1392 i_size_write(tmp_inode,pfindData->EndOfFile);
1394 /* 512 bytes (2**9) is the fake blocksize that must be used */
1395 /* for this calculation, even though the reported blocksize is larger */
1396 tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9;
1399 if (pfindData->AllocationSize < pfindData->EndOfFile)
1400 cFYI(1, ("Possible sparse file: allocation size less than end of file "));
1402 ("File Size %ld and blocks %ld and blocksize %ld",
1403 (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
1404 tmp_inode->i_blksize));
1405 if (S_ISREG(tmp_inode->i_mode)) {
1406 cFYI(1, (" File inode "));
1407 tmp_inode->i_op = &cifs_file_inode_ops;
1408 tmp_inode->i_fop = &cifs_file_ops;
1409 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1410 } else if (S_ISDIR(tmp_inode->i_mode)) {
1411 cFYI(1, (" Directory inode"));
1412 tmp_inode->i_op = &cifs_dir_inode_ops;
1413 tmp_inode->i_fop = &cifs_dir_ops;
1414 } else if (S_ISLNK(tmp_inode->i_mode)) {
1415 cFYI(1, (" Symbolic Link inode "));
1416 tmp_inode->i_op = &cifs_symlink_inode_ops;
1418 cFYI(1, (" Init special inode "));
1419 init_special_inode(tmp_inode, tmp_inode->i_mode,
1425 unix_fill_in_inode(struct inode *tmp_inode,
1426 FILE_UNIX_INFO * pfindData, int *pobject_type)
1428 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1429 cifsInfo->time = jiffies;
1430 atomic_inc(&cifsInfo->inUse);
1432 tmp_inode->i_atime =
1433 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1434 tmp_inode->i_mtime =
1435 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
1436 tmp_inode->i_ctime =
1437 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
1439 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
1440 pfindData->Type = le32_to_cpu(pfindData->Type);
1441 if (pfindData->Type == UNIX_FILE) {
1442 *pobject_type = DT_REG;
1443 tmp_inode->i_mode |= S_IFREG;
1444 } else if (pfindData->Type == UNIX_SYMLINK) {
1445 *pobject_type = DT_LNK;
1446 tmp_inode->i_mode |= S_IFLNK;
1447 } else if (pfindData->Type == UNIX_DIR) {
1448 *pobject_type = DT_DIR;
1449 tmp_inode->i_mode |= S_IFDIR;
1450 } else if (pfindData->Type == UNIX_CHARDEV) {
1451 *pobject_type = DT_CHR;
1452 tmp_inode->i_mode |= S_IFCHR;
1453 } else if (pfindData->Type == UNIX_BLOCKDEV) {
1454 *pobject_type = DT_BLK;
1455 tmp_inode->i_mode |= S_IFBLK;
1456 } else if (pfindData->Type == UNIX_FIFO) {
1457 *pobject_type = DT_FIFO;
1458 tmp_inode->i_mode |= S_IFIFO;
1459 } else if (pfindData->Type == UNIX_SOCKET) {
1460 *pobject_type = DT_SOCK;
1461 tmp_inode->i_mode |= S_IFSOCK;
1464 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
1465 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
1466 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
1468 pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes);
1470 if(is_size_safe_to_change(cifsInfo)) {
1471 /* can not safely change the file size here if the
1472 client is writing to it due to potential races */
1473 pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
1474 i_size_write(tmp_inode,pfindData->EndOfFile);
1476 /* 512 bytes (2**9) is the fake blocksize that must be used */
1477 /* for this calculation, not the real blocksize */
1478 tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9;
1481 if (S_ISREG(tmp_inode->i_mode)) {
1482 cFYI(1, ("File inode"));
1483 tmp_inode->i_op = &cifs_file_inode_ops;
1484 tmp_inode->i_fop = &cifs_file_ops;
1485 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1486 } else if (S_ISDIR(tmp_inode->i_mode)) {
1487 cFYI(1, ("Directory inode"));
1488 tmp_inode->i_op = &cifs_dir_inode_ops;
1489 tmp_inode->i_fop = &cifs_dir_ops;
1490 } else if (S_ISLNK(tmp_inode->i_mode)) {
1491 cFYI(1, ("Symbolic Link inode"));
1492 tmp_inode->i_op = &cifs_symlink_inode_ops;
1493 /* tmp_inode->i_fop = *//* do not need to set to anything */
1495 cFYI(1, ("Special inode"));
1496 init_special_inode(tmp_inode, tmp_inode->i_mode,
1502 construct_dentry(struct qstr *qstring, struct file *file,
1503 struct inode **ptmp_inode, struct dentry **pnew_dentry)
1505 struct dentry *tmp_dentry;
1506 struct cifs_sb_info *cifs_sb;
1507 struct cifsTconInfo *pTcon;
1509 cFYI(1, ("For %s ", qstring->name));
1510 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1511 pTcon = cifs_sb->tcon;
1513 qstring->hash = full_name_hash(qstring->name, qstring->len);
1514 tmp_dentry = d_lookup(file->f_dentry, qstring);
1516 cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
1517 *ptmp_inode = tmp_dentry->d_inode;
1518 /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
1519 if(*ptmp_inode == NULL) {
1520 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1521 if(*ptmp_inode == NULL)
1523 d_instantiate(tmp_dentry, *ptmp_inode);
1526 tmp_dentry = d_alloc(file->f_dentry, qstring);
1527 if(tmp_dentry == NULL) {
1528 cERROR(1,("Failed allocating dentry"));
1533 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1534 tmp_dentry->d_op = &cifs_dentry_ops;
1535 cFYI(0, (" instantiate dentry 0x%p with inode 0x%p ",
1536 tmp_dentry, *ptmp_inode));
1537 if(*ptmp_inode == NULL)
1539 d_instantiate(tmp_dentry, *ptmp_inode);
1540 d_rehash(tmp_dentry);
1543 tmp_dentry->d_time = jiffies;
1544 *pnew_dentry = tmp_dentry;
1547 static void reset_resume_key(struct file * dir_file,
1548 unsigned char * filename,
1549 unsigned int len,int Unicode,struct nls_table * nls_tab) {
1550 struct cifsFileInfo *cifsFile;
1552 cifsFile = (struct cifsFileInfo *)dir_file->private_data;
1553 if(cifsFile == NULL)
1555 if(cifsFile->search_resume_name) {
1556 kfree(cifsFile->search_resume_name);
1561 cifsFile->resume_name_length = len;
1563 cifsFile->search_resume_name =
1564 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1566 if(cifsFile->search_resume_name == NULL) {
1567 cERROR(1,("failed new resume key allocate, length %d",
1568 cifsFile->resume_name_length));
1572 cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
1573 filename, len, nls_tab);
1575 memcpy(cifsFile->search_resume_name, filename,
1576 cifsFile->resume_name_length);
1577 cFYI(1,("Reset resume key to: %s with len %d",filename,len));
1584 cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
1585 struct file *file, filldir_t filldir, void *direntry)
1587 struct inode *tmp_inode;
1588 struct dentry *tmp_dentry;
1591 pqstring->name = pfindData->FileName;
1592 pqstring->len = pfindData->FileNameLength;
1594 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1595 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1598 fill_in_inode(tmp_inode, pfindData, &object_type);
1599 rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
1600 tmp_inode->i_ino, object_type);
1602 /* due to readdir error we need to recalculate resume
1603 key so next readdir will restart on right entry */
1604 cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
1611 cifs_filldir_unix(struct qstr *pqstring,
1612 FILE_UNIX_INFO * pUnixFindData, struct file *file,
1613 filldir_t filldir, void *direntry)
1615 struct inode *tmp_inode;
1616 struct dentry *tmp_dentry;
1617 int object_type, rc;
1619 pqstring->name = pUnixFindData->FileName;
1620 pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
1622 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1623 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1627 unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
1628 rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
1629 file->f_pos, tmp_inode->i_ino, object_type);
1631 /* due to readdir error we need to recalculate resume
1632 key so next readdir will restart on right entry */
1633 cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
1640 cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1644 int Unicode = FALSE;
1645 int UnixSearch = FALSE;
1646 unsigned int bufsize, i;
1648 struct cifs_sb_info *cifs_sb;
1649 struct cifsTconInfo *pTcon;
1650 struct cifsFileInfo *cifsFile = NULL;
1651 char *full_path = NULL;
1653 struct qstr qstring;
1654 T2_FFIRST_RSP_PARMS findParms;
1655 T2_FNEXT_RSP_PARMS findNextParms;
1656 FILE_DIRECTORY_INFO *pfindData;
1657 FILE_DIRECTORY_INFO *lastFindData;
1658 FILE_UNIX_INFO *pfindDataUnix;
1662 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1663 pTcon = cifs_sb->tcon;
1664 bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
1665 if(bufsize > CIFS_MAX_MSGSIZE) {
1669 data = kmalloc(bufsize, GFP_KERNEL);
1670 pfindData = (FILE_DIRECTORY_INFO *) data;
1672 full_path = build_wildcard_path_from_dentry(file->f_dentry);
1674 cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
1676 switch ((int) file->f_pos) {
1678 if (filldir(direntry, ".", 1, file->f_pos,
1679 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
1680 cERROR(1, ("Filldir for current dir failed "));
1686 if (filldir(direntry, "..", 2, file->f_pos,
1687 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
1688 cERROR(1, ("Filldir for parent dir failed "));
1694 if (file->private_data != NULL) {
1696 (struct cifsFileInfo *) file->private_data;
1697 if (cifsFile->endOfSearch) {
1698 if(cifsFile->emptyDir) {
1699 cFYI(1, ("End of search, empty dir"));
1704 cifsFile->invalidHandle = TRUE;
1705 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1707 if(cifsFile->search_resume_name) {
1708 kfree(cifsFile->search_resume_name);
1709 cifsFile->search_resume_name = NULL;
1712 rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
1713 &findParms, cifs_sb->local_nls,
1714 &Unicode, &UnixSearch);
1715 cFYI(1, ("Count: %d End: %d ", findParms.SearchCount,
1716 findParms.EndofSearch));
1719 searchHandle = findParms.SearchHandle;
1720 if(file->private_data == NULL)
1721 file->private_data =
1722 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
1723 if (file->private_data) {
1724 memset(file->private_data, 0,
1725 sizeof (struct cifsFileInfo));
1727 (struct cifsFileInfo *) file->private_data;
1728 cifsFile->netfid = searchHandle;
1729 cifsFile->invalidHandle = FALSE;
1730 init_MUTEX(&cifsFile->fh_sem);
1736 renew_parental_timestamps(file->f_dentry);
1738 (FILE_DIRECTORY_INFO *) ((char *) pfindData +
1739 findParms.LastNameOffset);
1740 if((char *)lastFindData > (char *)pfindData + bufsize) {
1741 cFYI(1,("last search entry past end of packet"));
1745 /* Offset of resume key same for levels 257 and 514 */
1746 cifsFile->resume_key = lastFindData->FileIndex;
1747 if(UnixSearch == FALSE) {
1748 cifsFile->resume_name_length =
1749 le32_to_cpu(lastFindData->FileNameLength);
1750 if(cifsFile->resume_name_length > bufsize - 64) {
1751 cFYI(1,("Illegal resume file name length %d",
1752 cifsFile->resume_name_length));
1756 cifsFile->search_resume_name =
1757 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1758 cFYI(1,("Last file: %s with name %d bytes long",
1759 lastFindData->FileName,
1760 cifsFile->resume_name_length));
1761 memcpy(cifsFile->search_resume_name,
1762 lastFindData->FileName,
1763 cifsFile->resume_name_length);
1765 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1766 if (Unicode == TRUE) {
1767 for(i=0;(pfindDataUnix->FileName[i]
1768 | pfindDataUnix->FileName[i+1]);
1773 cifsFile->resume_name_length = i + 2;
1775 cifsFile->resume_name_length =
1776 strnlen(pfindDataUnix->FileName,
1779 if(cifsFile->resume_name_length > bufsize - 64) {
1780 cFYI(1,("Illegal resume file name length %d",
1781 cifsFile->resume_name_length));
1785 cifsFile->search_resume_name =
1786 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1787 cFYI(1,("Last file: %s with name %d bytes long",
1788 pfindDataUnix->FileName,
1789 cifsFile->resume_name_length));
1790 memcpy(cifsFile->search_resume_name,
1791 pfindDataUnix->FileName,
1792 cifsFile->resume_name_length);
1794 for (i = 2; i < (unsigned int)findParms.SearchCount + 2; i++) {
1795 if (UnixSearch == FALSE) {
1796 pfindData->FileNameLength =
1797 le32_to_cpu(pfindData->FileNameLength);
1798 if (Unicode == TRUE)
1799 pfindData->FileNameLength =
1801 (pfindData->FileName,
1803 pfindData->FileName,
1805 FileNameLength) / 2,
1806 cifs_sb->local_nls);
1807 qstring.len = pfindData->FileNameLength;
1808 if (((qstring.len != 1)
1809 || (pfindData->FileName[0] != '.'))
1810 && ((qstring.len != 2)
1814 FileName[1] != '.'))) {
1815 if(cifs_filldir(&qstring,
1819 /* do not end search if
1820 kernel not ready to take
1821 remaining entries yet */
1822 reset_resume_key(file, pfindData->FileName,qstring.len,
1823 Unicode, cifs_sb->local_nls);
1824 findParms.EndofSearch = 0;
1829 } else { /* UnixSearch */
1831 (FILE_UNIX_INFO *) pfindData;
1832 if (Unicode == TRUE)
1835 (pfindDataUnix->FileName,
1837 pfindDataUnix->FileName,
1839 cifs_sb->local_nls);
1842 strnlen(pfindDataUnix->
1845 if (((qstring.len != 1)
1847 FileName[0] != '.'))
1848 && ((qstring.len != 2)
1852 FileName[1] != '.'))) {
1853 if(cifs_filldir_unix(&qstring,
1858 /* do not end search if
1859 kernel not ready to take
1860 remaining entries yet */
1861 findParms.EndofSearch = 0;
1862 reset_resume_key(file, pfindDataUnix->FileName,
1863 qstring.len,Unicode,cifs_sb->local_nls);
1869 /* works also for Unix ff struct since first field of both */
1871 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1872 + le32_to_cpu(pfindData->NextEntryOffset));
1873 /* BB also should check to make sure that pointer is not beyond the end of the SMB */
1874 /* if(pfindData > lastFindData) rc = -EIO; break; */
1875 } /* end for loop */
1876 if ((findParms.EndofSearch != 0) && cifsFile) {
1877 cifsFile->endOfSearch = TRUE;
1878 if(findParms.SearchCount == 2)
1879 cifsFile->emptyDir = TRUE;
1883 cifsFile->endOfSearch = TRUE;
1884 /* unless parent directory gone do not return error */
1889 if (file->private_data == NULL) {
1892 ("Readdir on closed srch, pos = %lld",
1895 cifsFile = (struct cifsFileInfo *) file->private_data;
1896 if (cifsFile->endOfSearch) {
1898 cFYI(1, ("End of search "));
1901 searchHandle = cifsFile->netfid;
1902 rc = CIFSFindNext(xid, pTcon, pfindData,
1903 &findNextParms, searchHandle,
1904 cifsFile->search_resume_name,
1905 cifsFile->resume_name_length,
1906 cifsFile->resume_key,
1907 &Unicode, &UnixSearch);
1908 cFYI(1,("Count: %d End: %d ",
1909 findNextParms.SearchCount,
1910 findNextParms.EndofSearch));
1911 if ((rc == 0) && (findNextParms.SearchCount != 0)) {
1912 /* BB save off resume key, key name and name length */
1914 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1915 + findNextParms.LastNameOffset);
1916 if((char *)lastFindData > (char *)pfindData + bufsize) {
1917 cFYI(1,("last search entry past end of packet"));
1921 /* Offset of resume key same for levels 257 and 514 */
1922 cifsFile->resume_key = lastFindData->FileIndex;
1924 if(UnixSearch == FALSE) {
1925 cifsFile->resume_name_length =
1926 le32_to_cpu(lastFindData->FileNameLength);
1927 if(cifsFile->resume_name_length > bufsize - 64) {
1928 cFYI(1,("Illegal resume file name length %d",
1929 cifsFile->resume_name_length));
1933 /* Free the memory allocated by previous findfirst
1934 or findnext call - we can not reuse the memory since
1935 the resume name may not be same string length */
1936 if(cifsFile->search_resume_name)
1937 kfree(cifsFile->search_resume_name);
1938 cifsFile->search_resume_name =
1939 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1940 cFYI(1,("Last file: %s with name %d bytes long",
1941 lastFindData->FileName,
1942 cifsFile->resume_name_length));
1943 memcpy(cifsFile->search_resume_name,
1944 lastFindData->FileName,
1945 cifsFile->resume_name_length);
1947 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1948 if (Unicode == TRUE) {
1949 for(i=0;(pfindDataUnix->FileName[i]
1950 | pfindDataUnix->FileName[i+1]);
1955 cifsFile->resume_name_length = i + 2;
1957 cifsFile->resume_name_length =
1958 strnlen(pfindDataUnix->
1962 if(cifsFile->resume_name_length > bufsize - 64) {
1963 cFYI(1,("Illegal resume file name length %d",
1964 cifsFile->resume_name_length));
1968 /* Free the memory allocated by previous findfirst
1969 or findnext call - we can not reuse the memory since
1970 the resume name may not be same string length */
1971 if(cifsFile->search_resume_name)
1972 kfree(cifsFile->search_resume_name);
1973 cifsFile->search_resume_name =
1974 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1975 cFYI(1,("fnext last file: %s with name %d bytes long",
1976 pfindDataUnix->FileName,
1977 cifsFile->resume_name_length));
1978 memcpy(cifsFile->search_resume_name,
1979 pfindDataUnix->FileName,
1980 cifsFile->resume_name_length);
1983 for (i = 0; i < findNextParms.SearchCount; i++) {
1984 pfindData->FileNameLength =
1985 le32_to_cpu(pfindData->
1987 if (UnixSearch == FALSE) {
1988 if (Unicode == TRUE)
1989 pfindData->FileNameLength =
1991 (pfindData->FileName,
1993 pfindData->FileName,
1994 (pfindData->FileNameLength)/ 2,
1995 cifs_sb->local_nls);
1997 pfindData->FileNameLength;
1998 if (((qstring.len != 1)
1999 || (pfindData->FileName[0] != '.'))
2000 && ((qstring.len != 2)
2001 || (pfindData->FileName[0] != '.')
2002 || (pfindData->FileName[1] !=
2009 /* do not end search if
2010 kernel not ready to take
2011 remaining entries yet */
2012 findNextParms.EndofSearch = 0;
2013 reset_resume_key(file, pfindData->FileName,qstring.len,
2014 Unicode,cifs_sb->local_nls);
2019 } else { /* UnixSearch */
2023 if (Unicode == TRUE)
2026 (pfindDataUnix->FileName,
2028 pfindDataUnix->FileName,
2030 cifs_sb->local_nls);
2037 if (((qstring.len != 1)
2039 FileName[0] != '.'))
2040 && ((qstring.len != 2)
2046 if(cifs_filldir_unix
2051 /* do not end search if
2052 kernel not ready to take
2053 remaining entries yet */
2054 findNextParms.EndofSearch = 0;
2055 reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
2056 Unicode,cifs_sb->local_nls);
2062 pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData +
2063 le32_to_cpu(pfindData->NextEntryOffset));
2064 /* works also for Unix find struct since first field of both */
2065 /* BB also should check to ensure pointer not beyond end of SMB */
2066 } /* end for loop */
2067 if (findNextParms.EndofSearch != 0) {
2068 cifsFile->endOfSearch = TRUE;
2071 cifsFile->endOfSearch = TRUE;
2072 rc = 0; /* unless parent directory disappeared - do not
2073 return error here (eg Access Denied or no more files) */
2085 int cifs_prepare_write(struct file *file, struct page *page,
2086 unsigned from, unsigned to)
2089 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
2090 cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
2091 if (!PageUptodate(page)) {
2092 /* if (to - from != PAGE_CACHE_SIZE) {
2093 void *kaddr = kmap_atomic(page, KM_USER0);
2094 memset(kaddr, 0, from);
2095 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
2096 flush_dcache_page(page);
2097 kunmap_atomic(kaddr, KM_USER0);
2099 /* If we are writing a full page it will be up to date,
2100 no need to read from the server */
2101 if((to==PAGE_CACHE_SIZE) && (from == 0))
2102 SetPageUptodate(page);
2104 /* might as well read a page, it is fast enough */
2105 if((file->f_flags & O_ACCMODE) != O_WRONLY) {
2106 rc = cifs_readpage_worker(file,page,&offset);
2108 /* should we try using another
2109 file handle if there is one - how would we lock it
2110 to prevent close of that handle racing with this read? */
2111 /* In any case this will be written out by commit_write */
2115 /* BB should we pass any errors back? e.g. if we do not have read access to the file */
2120 struct address_space_operations cifs_addr_ops = {
2121 .readpage = cifs_readpage,
2122 .readpages = cifs_readpages,
2123 .writepage = cifs_writepage,
2124 .prepare_write = cifs_prepare_write,
2125 .commit_write = cifs_commit_write,
2126 /* .sync_page = cifs_sync_page, */