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,
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)
591 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
592 if(cifs_sb == NULL) {
595 pTcon = cifs_sb->tcon;
598 (" write %d bytes to offset %lld of %s", write_size,
599 *poffset, file->f_dentry->d_name.name)); */
601 if (file->private_data == NULL) {
604 open_file = (struct cifsFileInfo *) file->private_data;
608 if(file->f_dentry->d_inode == NULL) {
613 if (*poffset > file->f_dentry->d_inode->i_size)
614 long_op = 2; /* writes past end of file can take a long time */
618 for (total_written = 0; write_size > total_written;
619 total_written += bytes_written) {
621 while(rc == -EAGAIN) {
622 if(file->private_data == NULL) {
623 /* file has been closed on us */
625 /* if we have gotten here we have written some data
626 and blocked, and the file has been freed on us
627 while we blocked so return what we managed to write */
628 return total_written;
630 if(open_file->closePend) {
633 return total_written;
637 if (open_file->invalidHandle) {
638 if((file->f_dentry == NULL) ||
639 (file->f_dentry->d_inode == NULL)) {
641 return total_written;
643 /* we could deadlock if we called
644 filemap_fdatawait from here so tell
645 reopen_file not to flush data to server now */
646 rc = cifs_reopen_file(file->f_dentry->d_inode,
652 rc = CIFSSMBWrite(xid, pTcon,
654 write_size - total_written, *poffset,
656 write_data + total_written, long_op);
658 if (rc || (bytes_written == 0)) {
666 *poffset += bytes_written;
667 long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
670 #ifdef CONFIG_CIFS_STATS
671 if(total_written > 0) {
672 atomic_inc(&pTcon->num_writes);
673 spin_lock(&pTcon->stat_lock);
674 pTcon->bytes_written += total_written;
675 spin_unlock(&pTcon->stat_lock);
679 /* since the write may have blocked check these pointers again */
681 if(file->f_dentry->d_inode) {
682 file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
684 if (total_written > 0) {
685 if (*poffset > file->f_dentry->d_inode->i_size)
686 i_size_write(file->f_dentry->d_inode, *poffset);
688 mark_inode_dirty_sync(file->f_dentry->d_inode);
692 return total_written;
696 cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
698 struct address_space *mapping = page->mapping;
699 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
702 int bytes_written = 0;
703 struct cifs_sb_info *cifs_sb;
704 struct cifsTconInfo *pTcon;
706 struct cifsInodeInfo *cifsInode;
707 struct cifsFileInfo *open_file = NULL;
708 struct list_head *tmp;
709 struct list_head *tmp1;
713 } else if(!mapping->host) {
717 inode = page->mapping->host;
718 cifs_sb = CIFS_SB(inode->i_sb);
719 pTcon = cifs_sb->tcon;
721 offset += (loff_t)from;
722 write_data = kmap(page);
725 if((to > PAGE_CACHE_SIZE) || (from > to)) {
730 /* racing with truncate? */
731 if(offset > mapping->host->i_size) {
733 return 0; /* don't care */
736 /* check to make sure that we are not extending the file */
737 if(mapping->host->i_size - offset < (loff_t)to)
738 to = (unsigned)(mapping->host->i_size - offset);
741 cifsInode = CIFS_I(mapping->host);
742 read_lock(&GlobalSMBSeslock);
743 /* BB we should start at the end */
744 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
745 open_file = list_entry(tmp,struct cifsFileInfo, flist);
746 if(open_file->closePend)
748 /* We check if file is open for writing first */
749 if((open_file->pfile) &&
750 ((open_file->pfile->f_flags & O_RDWR) ||
751 (open_file->pfile->f_flags & O_WRONLY))) {
752 read_unlock(&GlobalSMBSeslock);
753 bytes_written = cifs_write(open_file->pfile, write_data,
755 read_lock(&GlobalSMBSeslock);
756 /* Does mm or vfs already set times? */
757 inode->i_atime = inode->i_mtime = CURRENT_TIME;
758 if ((bytes_written > 0) && (offset)) {
760 } else if(bytes_written < 0) {
762 /* have seen a case in which
763 kernel seemed to have closed/freed a file
764 even with writes active so we might as well
765 see if there are other file structs to try
766 for the same inode before giving up */
771 break; /* now that we found a valid file handle
772 and tried to write to it we are done, no
773 sense continuing to loop looking for another */
775 if(tmp->next == NULL) {
776 cFYI(1,("File instance %p removed",tmp));
780 read_unlock(&GlobalSMBSeslock);
781 if(open_file == NULL) {
782 cFYI(1,("No writeable filehandles for inode"));
792 cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
798 /* call 16K write then Setpageuptodate */
805 cifs_writepage(struct page* page, struct writeback_control *wbc)
811 /* BB add check for wbc flags */
812 page_cache_get(page);
813 if (!PageUptodate(page)) {
814 cFYI(1,("ppw - page not up to date"));
817 rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
818 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
820 page_cache_release(page);
826 cifs_commit_write(struct file *file, struct page *page, unsigned offset,
831 struct inode *inode = page->mapping->host;
832 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
836 cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
837 if (position > inode->i_size){
838 i_size_write(inode, position);
839 /*if (file->private_data == NULL) {
842 open_file = (struct cifsFileInfo *)file->private_data;
843 cifs_sb = CIFS_SB(inode->i_sb);
845 while(rc == -EAGAIN) {
846 if((open_file->invalidHandle) &&
847 (!open_file->closePend)) {
848 rc = cifs_reopen_file(file->f_dentry->d_inode,file);
852 if(!open_file->closePend) {
853 rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
854 position, open_file->netfid,
855 open_file->pid,FALSE);
861 cFYI(1,(" SetEOF (commit write) rc = %d",rc));
864 if (!PageUptodate(page)) {
865 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
866 /* can not rely on (or let) writepage write this data */
868 cFYI(1,("Illegal offsets, can not copy from %d to %d",
873 /* this is probably better than directly calling
874 partialpage_write since in this function
875 the file handle is known which we might as well
877 /* BB check if anything else missing out of ppw */
878 /* such as updating last write time */
879 page_data = kmap(page);
880 rc = cifs_write(file, page_data+offset,to-offset,
884 /* else if rc < 0 should we set writebehind rc? */
887 set_page_dirty(page);
895 cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
899 struct inode * inode = file->f_dentry->d_inode;
903 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
904 dentry->d_name.name, datasync));
906 rc = filemap_fdatawrite(inode->i_mapping);
908 CIFS_I(inode)->write_behind_rc = 0;
914 cifs_sync_page(struct page *page)
916 struct address_space *mapping;
918 unsigned long index = page->index;
919 unsigned int rpages = 0;
922 cFYI(1,("sync page %p",page));
923 mapping = page->mapping;
926 inode = mapping->host;
930 /* fill in rpages then
931 result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */
933 /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
941 * As file closes, flush all cached write data for this inode checking
942 * for write behind errors.
945 int cifs_flush(struct file *file)
947 struct inode * inode = file->f_dentry->d_inode;
950 /* Rather than do the steps manually: */
951 /* lock the inode for writing */
952 /* loop through pages looking for write behind data (dirty pages) */
953 /* coalesce into contiguous 16K (or smaller) chunks to write to server */
954 /* send to server (prefer in parallel) */
955 /* deal with writebehind errors */
956 /* unlock inode for writing */
957 /* filemapfdatawrite appears easier for the time being */
959 rc = filemap_fdatawrite(inode->i_mapping);
960 if(rc == 0) /* reset wb rc if we were able to write out dirty pages */
961 CIFS_I(inode)->write_behind_rc = 0;
963 cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
970 cifs_read(struct file * file, char *read_data, size_t read_size,
974 unsigned int bytes_read = 0;
975 unsigned int total_read;
976 unsigned int current_read_size;
977 struct cifs_sb_info *cifs_sb;
978 struct cifsTconInfo *pTcon;
980 char * current_offset;
981 struct cifsFileInfo * open_file;
984 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
985 pTcon = cifs_sb->tcon;
987 if (file->private_data == NULL) {
991 open_file = (struct cifsFileInfo *)file->private_data;
993 if((file->f_flags & O_ACCMODE) == O_WRONLY) {
994 cFYI(1,("attempting read on write only file instance"));
997 for (total_read = 0,current_offset=read_data; read_size > total_read;
998 total_read += bytes_read,current_offset+=bytes_read) {
999 current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
1001 while(rc == -EAGAIN) {
1002 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1003 rc = cifs_reopen_file(file->f_dentry->d_inode,
1009 rc = CIFSSMBRead(xid, pTcon,
1011 current_read_size, *poffset,
1012 &bytes_read, ¤t_offset);
1014 if (rc || (bytes_read == 0)) {
1022 #ifdef CONFIG_CIFS_STATS
1023 atomic_inc(&pTcon->num_reads);
1024 spin_lock(&pTcon->stat_lock);
1025 pTcon->bytes_read += total_read;
1026 spin_unlock(&pTcon->stat_lock);
1028 *poffset += bytes_read;
1035 int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
1037 struct dentry * dentry = file->f_dentry;
1041 rc = cifs_revalidate(dentry);
1043 cFYI(1,("Validation prior to mmap failed, error=%d", rc));
1047 rc = generic_file_mmap(file, vma);
1052 static void cifs_copy_cache_pages(struct address_space *mapping,
1053 struct list_head *pages, int bytes_read,
1054 char *data,struct pagevec * plru_pvec)
1059 while (bytes_read > 0) {
1060 if(list_empty(pages))
1063 page = list_entry(pages->prev, struct page, lru);
1064 list_del(&page->lru);
1066 if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
1067 page_cache_release(page);
1068 cFYI(1,("Add page cache failed"));
1072 target = kmap_atomic(page,KM_USER0);
1074 if(PAGE_CACHE_SIZE > bytes_read) {
1075 memcpy(target,data,bytes_read);
1076 /* zero the tail end of this partial page */
1077 memset(target+bytes_read,0,PAGE_CACHE_SIZE-bytes_read);
1080 memcpy(target,data,PAGE_CACHE_SIZE);
1081 bytes_read -= PAGE_CACHE_SIZE;
1083 kunmap_atomic(target,KM_USER0);
1085 flush_dcache_page(page);
1086 SetPageUptodate(page);
1088 if (!pagevec_add(plru_pvec, page))
1089 __pagevec_lru_add(plru_pvec);
1090 data += PAGE_CACHE_SIZE;
1097 cifs_readpages(struct file *file, struct address_space *mapping,
1098 struct list_head *page_list, unsigned num_pages)
1104 struct cifs_sb_info *cifs_sb;
1105 struct cifsTconInfo *pTcon;
1107 unsigned int read_size,i;
1108 char * smb_read_data = NULL;
1109 struct smb_com_read_rsp * pSMBr;
1110 struct pagevec lru_pvec;
1111 struct cifsFileInfo * open_file;
1114 if (file->private_data == NULL) {
1118 open_file = (struct cifsFileInfo *)file->private_data;
1119 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1120 pTcon = cifs_sb->tcon;
1122 pagevec_init(&lru_pvec, 0);
1124 for(i = 0;i<num_pages;) {
1125 unsigned contig_pages;
1126 struct page * tmp_page;
1127 unsigned long expected_index;
1129 if(list_empty(page_list)) {
1132 page = list_entry(page_list->prev, struct page, lru);
1133 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1135 /* count adjacent pages that we will read into */
1137 expected_index = list_entry(page_list->prev,struct page,lru)->index;
1138 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1139 if(tmp_page->index == expected_index) {
1146 if(contig_pages + i > num_pages) {
1147 contig_pages = num_pages - i;
1150 /* for reads over a certain size could initiate async read ahead */
1152 read_size = contig_pages * PAGE_CACHE_SIZE;
1153 /* Read size needs to be in multiples of one page */
1154 read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
1157 while(rc == -EAGAIN) {
1158 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1159 rc = cifs_reopen_file(file->f_dentry->d_inode,
1165 rc = CIFSSMBRead(xid, pTcon,
1168 &bytes_read, &smb_read_data);
1169 /* BB need to check return code here */
1172 cifs_buf_release(smb_read_data);
1173 smb_read_data = NULL;
1177 if ((rc < 0) || (smb_read_data == NULL)) {
1178 cFYI(1,("Read error in readpages: %d",rc));
1179 /* clean up remaing pages off list */
1180 while (!list_empty(page_list) && (i < num_pages)) {
1181 page = list_entry(page_list->prev, struct page, lru);
1182 list_del(&page->lru);
1183 page_cache_release(page);
1186 } else if (bytes_read > 0) {
1187 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1188 cifs_copy_cache_pages(mapping, page_list, bytes_read,
1189 smb_read_data + 4 /* RFC1001 hdr */ +
1190 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1192 i += bytes_read >> PAGE_CACHE_SHIFT;
1193 #ifdef CONFIG_CIFS_STATS
1194 atomic_inc(&pTcon->num_reads);
1195 spin_lock(&pTcon->stat_lock);
1196 pTcon->bytes_read += bytes_read;
1197 spin_unlock(&pTcon->stat_lock);
1199 if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1200 cFYI(1,("Partial page %d of %d read to cache",i++,num_pages));
1202 i++; /* account for partial page */
1204 /* server copy of file can have smaller size than client */
1205 /* BB do we need to verify this common case ? this case is ok -
1206 if we are at server EOF we will hit it on next read */
1208 /* while(!list_empty(page_list) && (i < num_pages)) {
1209 page = list_entry(page_list->prev,struct page, list);
1210 list_del(&page->list);
1211 page_cache_release(page);
1216 cFYI(1,("No bytes read (%d) at offset %lld . Cleaning remaining pages from readahead list",bytes_read,offset));
1217 /* BB turn off caching and do new lookup on file size at server? */
1218 while (!list_empty(page_list) && (i < num_pages)) {
1219 page = list_entry(page_list->prev, struct page, lru);
1220 list_del(&page->lru);
1221 page_cache_release(page); /* BB removeme - replace with zero of page? */
1226 cifs_buf_release(smb_read_data);
1227 smb_read_data = NULL;
1232 pagevec_lru_add(&lru_pvec);
1234 /* need to free smb_read_data buf before exit */
1236 cifs_buf_release(smb_read_data);
1237 smb_read_data = NULL;
1244 static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
1249 page_cache_get(page);
1250 read_data = kmap(page);
1251 /* for reads over a certain size could initiate async read ahead */
1253 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1258 cFYI(1,("Bytes read %d ",rc));
1261 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
1263 if(PAGE_CACHE_SIZE > rc) {
1264 memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
1266 flush_dcache_page(page);
1267 SetPageUptodate(page);
1272 page_cache_release(page);
1277 cifs_readpage(struct file *file, struct page *page)
1279 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1285 if (file->private_data == NULL) {
1290 cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
1292 rc = cifs_readpage_worker(file,page,&offset);
1300 /* We do not want to update the file size from server for inodes
1301 open for write - to avoid races with writepage extending
1302 the file - in the future we could consider allowing
1303 refreshing the inode only on increases in the file size
1304 but this is tricky to do without racing with writebehind
1305 page caching in the current Linux kernel design */
1307 int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
1309 struct list_head *tmp;
1310 struct list_head *tmp1;
1311 struct cifsFileInfo *open_file = NULL;
1314 if(cifsInode == NULL)
1317 read_lock(&GlobalSMBSeslock);
1318 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
1319 open_file = list_entry(tmp,struct cifsFileInfo, flist);
1320 if(open_file == NULL)
1322 if(open_file->closePend)
1324 /* We check if file is open for writing,
1325 BB we could supplement this with a check to see if file size
1326 changes have been flushed to server - ie inode metadata dirty */
1327 if((open_file->pfile) &&
1328 ((open_file->pfile->f_flags & O_RDWR) ||
1329 (open_file->pfile->f_flags & O_WRONLY))) {
1333 if(tmp->next == NULL) {
1334 cFYI(1,("File instance %p removed",tmp));
1338 read_unlock(&GlobalSMBSeslock);
1344 fill_in_inode(struct inode *tmp_inode,
1345 FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
1347 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1348 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
1350 pfindData->ExtFileAttributes =
1351 le32_to_cpu(pfindData->ExtFileAttributes);
1352 pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
1353 pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
1354 cifsInfo->cifsAttrs = pfindData->ExtFileAttributes;
1355 cifsInfo->time = jiffies;
1357 /* Linux can not store file creation time unfortunately so ignore it */
1358 tmp_inode->i_atime =
1359 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1360 tmp_inode->i_mtime =
1361 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
1362 tmp_inode->i_ctime =
1363 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
1364 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
1365 /* 2767 perms - indicate mandatory locking */
1366 /* BB fill in uid and gid here? with help from winbind?
1367 or retrieve from NTFS stream extended attribute */
1368 if(atomic_read(&cifsInfo->inUse) == 0) {
1369 tmp_inode->i_uid = cifs_sb->mnt_uid;
1370 tmp_inode->i_gid = cifs_sb->mnt_gid;
1371 /* set default mode. will override for dirs below */
1372 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
1376 ("CIFS FFIRST: Attributes came in as 0x%x",
1377 pfindData->ExtFileAttributes));
1378 if (pfindData->ExtFileAttributes & ATTR_REPARSE) {
1379 *pobject_type = DT_LNK;
1380 /* BB can this and S_IFREG or S_IFDIR be set as in Windows? */
1381 tmp_inode->i_mode |= S_IFLNK;
1382 } else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) {
1383 *pobject_type = DT_DIR;
1384 /* override default perms since we do not lock dirs */
1385 if(atomic_read(&cifsInfo->inUse) == 0) {
1386 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
1388 tmp_inode->i_mode |= S_IFDIR;
1390 *pobject_type = DT_REG;
1391 tmp_inode->i_mode |= S_IFREG;
1392 if(pfindData->ExtFileAttributes & ATTR_READONLY)
1393 tmp_inode->i_mode &= ~(S_IWUGO);
1395 }/* could add code here - to validate if device or weird share type? */
1397 /* can not fill in nlink here as in qpathinfo version and Unx search */
1398 if(atomic_read(&cifsInfo->inUse) == 0) {
1399 atomic_set(&cifsInfo->inUse,1);
1402 if(is_size_safe_to_change(cifsInfo)) {
1403 /* can not safely change the file size here if the
1404 client is writing to it due to potential races */
1405 i_size_write(tmp_inode,pfindData->EndOfFile);
1407 /* 512 bytes (2**9) is the fake blocksize that must be used */
1408 /* for this calculation, even though the reported blocksize is larger */
1409 tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9;
1412 if (pfindData->AllocationSize < pfindData->EndOfFile)
1413 cFYI(1, ("Possible sparse file: allocation size less than end of file "));
1415 ("File Size %ld and blocks %ld and blocksize %ld",
1416 (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
1417 tmp_inode->i_blksize));
1418 if (S_ISREG(tmp_inode->i_mode)) {
1419 cFYI(1, (" File inode "));
1420 tmp_inode->i_op = &cifs_file_inode_ops;
1421 tmp_inode->i_fop = &cifs_file_ops;
1422 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1423 } else if (S_ISDIR(tmp_inode->i_mode)) {
1424 cFYI(1, (" Directory inode"));
1425 tmp_inode->i_op = &cifs_dir_inode_ops;
1426 tmp_inode->i_fop = &cifs_dir_ops;
1427 } else if (S_ISLNK(tmp_inode->i_mode)) {
1428 cFYI(1, (" Symbolic Link inode "));
1429 tmp_inode->i_op = &cifs_symlink_inode_ops;
1431 cFYI(1, (" Init special inode "));
1432 init_special_inode(tmp_inode, tmp_inode->i_mode,
1438 unix_fill_in_inode(struct inode *tmp_inode,
1439 FILE_UNIX_INFO * pfindData, int *pobject_type)
1441 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1442 cifsInfo->time = jiffies;
1443 atomic_inc(&cifsInfo->inUse);
1445 tmp_inode->i_atime =
1446 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1447 tmp_inode->i_mtime =
1448 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
1449 tmp_inode->i_ctime =
1450 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
1452 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
1453 pfindData->Type = le32_to_cpu(pfindData->Type);
1454 if (pfindData->Type == UNIX_FILE) {
1455 *pobject_type = DT_REG;
1456 tmp_inode->i_mode |= S_IFREG;
1457 } else if (pfindData->Type == UNIX_SYMLINK) {
1458 *pobject_type = DT_LNK;
1459 tmp_inode->i_mode |= S_IFLNK;
1460 } else if (pfindData->Type == UNIX_DIR) {
1461 *pobject_type = DT_DIR;
1462 tmp_inode->i_mode |= S_IFDIR;
1463 } else if (pfindData->Type == UNIX_CHARDEV) {
1464 *pobject_type = DT_CHR;
1465 tmp_inode->i_mode |= S_IFCHR;
1466 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1467 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1468 } else if (pfindData->Type == UNIX_BLOCKDEV) {
1469 *pobject_type = DT_BLK;
1470 tmp_inode->i_mode |= S_IFBLK;
1471 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1472 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1473 } else if (pfindData->Type == UNIX_FIFO) {
1474 *pobject_type = DT_FIFO;
1475 tmp_inode->i_mode |= S_IFIFO;
1476 } else if (pfindData->Type == UNIX_SOCKET) {
1477 *pobject_type = DT_SOCK;
1478 tmp_inode->i_mode |= S_IFSOCK;
1481 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
1482 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
1483 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
1485 pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes);
1487 if(is_size_safe_to_change(cifsInfo)) {
1488 /* can not safely change the file size here if the
1489 client is writing to it due to potential races */
1490 pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
1491 i_size_write(tmp_inode,pfindData->EndOfFile);
1493 /* 512 bytes (2**9) is the fake blocksize that must be used */
1494 /* for this calculation, not the real blocksize */
1495 tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9;
1498 if (S_ISREG(tmp_inode->i_mode)) {
1499 cFYI(1, ("File inode"));
1500 tmp_inode->i_op = &cifs_file_inode_ops;
1501 tmp_inode->i_fop = &cifs_file_ops;
1502 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1503 } else if (S_ISDIR(tmp_inode->i_mode)) {
1504 cFYI(1, ("Directory inode"));
1505 tmp_inode->i_op = &cifs_dir_inode_ops;
1506 tmp_inode->i_fop = &cifs_dir_ops;
1507 } else if (S_ISLNK(tmp_inode->i_mode)) {
1508 cFYI(1, ("Symbolic Link inode"));
1509 tmp_inode->i_op = &cifs_symlink_inode_ops;
1510 /* tmp_inode->i_fop = *//* do not need to set to anything */
1512 cFYI(1, ("Special inode"));
1513 init_special_inode(tmp_inode, tmp_inode->i_mode,
1519 construct_dentry(struct qstr *qstring, struct file *file,
1520 struct inode **ptmp_inode, struct dentry **pnew_dentry)
1522 struct dentry *tmp_dentry;
1523 struct cifs_sb_info *cifs_sb;
1524 struct cifsTconInfo *pTcon;
1526 cFYI(1, ("For %s ", qstring->name));
1527 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1528 pTcon = cifs_sb->tcon;
1530 qstring->hash = full_name_hash(qstring->name, qstring->len);
1531 tmp_dentry = d_lookup(file->f_dentry, qstring);
1533 cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
1534 *ptmp_inode = tmp_dentry->d_inode;
1535 /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
1536 if(*ptmp_inode == NULL) {
1537 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1538 if(*ptmp_inode == NULL)
1540 d_instantiate(tmp_dentry, *ptmp_inode);
1541 insert_inode_hash(*ptmp_inode);
1544 tmp_dentry = d_alloc(file->f_dentry, qstring);
1545 if(tmp_dentry == NULL) {
1546 cERROR(1,("Failed allocating dentry"));
1551 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1552 tmp_dentry->d_op = &cifs_dentry_ops;
1553 if(*ptmp_inode == NULL)
1555 d_instantiate(tmp_dentry, *ptmp_inode);
1556 d_rehash(tmp_dentry);
1557 insert_inode_hash(*ptmp_inode);
1560 tmp_dentry->d_time = jiffies;
1561 *pnew_dentry = tmp_dentry;
1564 static void reset_resume_key(struct file * dir_file,
1565 unsigned char * filename,
1566 unsigned int len,int Unicode,struct nls_table * nls_tab) {
1567 struct cifsFileInfo *cifsFile;
1569 cifsFile = (struct cifsFileInfo *)dir_file->private_data;
1570 if(cifsFile == NULL)
1572 if(cifsFile->search_resume_name) {
1573 kfree(cifsFile->search_resume_name);
1578 cifsFile->resume_name_length = len;
1580 cifsFile->search_resume_name =
1581 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1583 if(cifsFile->search_resume_name == NULL) {
1584 cERROR(1,("failed new resume key allocate, length %d",
1585 cifsFile->resume_name_length));
1589 cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
1590 filename, len, nls_tab);
1592 memcpy(cifsFile->search_resume_name, filename,
1593 cifsFile->resume_name_length);
1594 cFYI(1,("Reset resume key to: %s with len %d",filename,len));
1601 cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
1602 struct file *file, filldir_t filldir, void *direntry)
1604 struct inode *tmp_inode;
1605 struct dentry *tmp_dentry;
1608 pqstring->name = pfindData->FileName;
1609 pqstring->len = pfindData->FileNameLength;
1611 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1612 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1615 fill_in_inode(tmp_inode, pfindData, &object_type);
1616 rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
1617 tmp_inode->i_ino, object_type);
1619 /* due to readdir error we need to recalculate resume
1620 key so next readdir will restart on right entry */
1621 cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
1628 cifs_filldir_unix(struct qstr *pqstring,
1629 FILE_UNIX_INFO * pUnixFindData, struct file *file,
1630 filldir_t filldir, void *direntry)
1632 struct inode *tmp_inode;
1633 struct dentry *tmp_dentry;
1634 int object_type, rc;
1636 pqstring->name = pUnixFindData->FileName;
1637 pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
1639 construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1640 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1644 unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
1645 rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
1646 file->f_pos, tmp_inode->i_ino, object_type);
1648 /* due to readdir error we need to recalculate resume
1649 key so next readdir will restart on right entry */
1650 cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
1657 cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1661 int Unicode = FALSE;
1662 int UnixSearch = FALSE;
1663 unsigned int bufsize, i;
1665 struct cifs_sb_info *cifs_sb;
1666 struct cifsTconInfo *pTcon;
1667 struct cifsFileInfo *cifsFile = NULL;
1668 char *full_path = NULL;
1670 struct qstr qstring;
1671 T2_FFIRST_RSP_PARMS findParms;
1672 T2_FNEXT_RSP_PARMS findNextParms;
1673 FILE_DIRECTORY_INFO *pfindData;
1674 FILE_DIRECTORY_INFO *lastFindData;
1675 FILE_UNIX_INFO *pfindDataUnix;
1679 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1680 pTcon = cifs_sb->tcon;
1681 bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
1682 if(bufsize > CIFS_MAX_MSGSIZE) {
1686 data = kmalloc(bufsize, GFP_KERNEL);
1687 pfindData = (FILE_DIRECTORY_INFO *) data;
1689 if(file->f_dentry == NULL) {
1693 down(&file->f_dentry->d_sb->s_vfs_rename_sem);
1694 full_path = build_wildcard_path_from_dentry(file->f_dentry);
1695 up(&file->f_dentry->d_sb->s_vfs_rename_sem);
1698 cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
1700 switch ((int) file->f_pos) {
1702 if (filldir(direntry, ".", 1, file->f_pos,
1703 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
1704 cERROR(1, ("Filldir for current dir failed "));
1710 if (filldir(direntry, "..", 2, file->f_pos,
1711 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
1712 cERROR(1, ("Filldir for parent dir failed "));
1718 if (file->private_data != NULL) {
1720 (struct cifsFileInfo *) file->private_data;
1721 if (cifsFile->endOfSearch) {
1722 if(cifsFile->emptyDir) {
1723 cFYI(1, ("End of search, empty dir"));
1728 cifsFile->invalidHandle = TRUE;
1729 CIFSFindClose(xid, pTcon, cifsFile->netfid);
1731 if(cifsFile->search_resume_name) {
1732 kfree(cifsFile->search_resume_name);
1733 cifsFile->search_resume_name = NULL;
1736 rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
1737 &findParms, cifs_sb->local_nls,
1738 &Unicode, &UnixSearch);
1739 cFYI(1, ("Count: %d End: %d ", findParms.SearchCount,
1740 findParms.EndofSearch));
1743 searchHandle = findParms.SearchHandle;
1744 if(file->private_data == NULL)
1745 file->private_data =
1746 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
1747 if (file->private_data) {
1748 memset(file->private_data, 0,
1749 sizeof (struct cifsFileInfo));
1751 (struct cifsFileInfo *) file->private_data;
1752 cifsFile->netfid = searchHandle;
1753 cifsFile->invalidHandle = FALSE;
1754 init_MUTEX(&cifsFile->fh_sem);
1760 renew_parental_timestamps(file->f_dentry);
1762 (FILE_DIRECTORY_INFO *) ((char *) pfindData +
1763 findParms.LastNameOffset);
1764 if((char *)lastFindData > (char *)pfindData + bufsize) {
1765 cFYI(1,("last search entry past end of packet"));
1769 /* Offset of resume key same for levels 257 and 514 */
1770 cifsFile->resume_key = lastFindData->FileIndex;
1771 if(UnixSearch == FALSE) {
1772 cifsFile->resume_name_length =
1773 le32_to_cpu(lastFindData->FileNameLength);
1774 if(cifsFile->resume_name_length > bufsize - 64) {
1775 cFYI(1,("Illegal resume file name length %d",
1776 cifsFile->resume_name_length));
1780 cifsFile->search_resume_name =
1781 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1782 cFYI(1,("Last file: %s with name %d bytes long",
1783 lastFindData->FileName,
1784 cifsFile->resume_name_length));
1785 memcpy(cifsFile->search_resume_name,
1786 lastFindData->FileName,
1787 cifsFile->resume_name_length);
1789 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1790 if (Unicode == TRUE) {
1791 for(i=0;(pfindDataUnix->FileName[i]
1792 | pfindDataUnix->FileName[i+1]);
1797 cifsFile->resume_name_length = i + 2;
1799 cifsFile->resume_name_length =
1800 strnlen(pfindDataUnix->FileName,
1803 if(cifsFile->resume_name_length > bufsize - 64) {
1804 cFYI(1,("Illegal resume file name length %d",
1805 cifsFile->resume_name_length));
1809 cifsFile->search_resume_name =
1810 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1811 cFYI(1,("Last file: %s with name %d bytes long",
1812 pfindDataUnix->FileName,
1813 cifsFile->resume_name_length));
1814 memcpy(cifsFile->search_resume_name,
1815 pfindDataUnix->FileName,
1816 cifsFile->resume_name_length);
1818 for (i = 2; i < (unsigned int)findParms.SearchCount + 2; i++) {
1819 if (UnixSearch == FALSE) {
1820 pfindData->FileNameLength =
1821 le32_to_cpu(pfindData->FileNameLength);
1822 if (Unicode == TRUE)
1823 pfindData->FileNameLength =
1825 (pfindData->FileName,
1827 pfindData->FileName,
1829 FileNameLength) / 2,
1830 cifs_sb->local_nls);
1831 qstring.len = pfindData->FileNameLength;
1832 if (((qstring.len != 1)
1833 || (pfindData->FileName[0] != '.'))
1834 && ((qstring.len != 2)
1838 FileName[1] != '.'))) {
1839 if(cifs_filldir(&qstring,
1843 /* do not end search if
1844 kernel not ready to take
1845 remaining entries yet */
1846 reset_resume_key(file, pfindData->FileName,qstring.len,
1847 Unicode, cifs_sb->local_nls);
1848 findParms.EndofSearch = 0;
1853 } else { /* UnixSearch */
1855 (FILE_UNIX_INFO *) pfindData;
1856 if (Unicode == TRUE)
1859 (pfindDataUnix->FileName,
1861 pfindDataUnix->FileName,
1863 cifs_sb->local_nls);
1866 strnlen(pfindDataUnix->
1869 if (((qstring.len != 1)
1871 FileName[0] != '.'))
1872 && ((qstring.len != 2)
1876 FileName[1] != '.'))) {
1877 if(cifs_filldir_unix(&qstring,
1882 /* do not end search if
1883 kernel not ready to take
1884 remaining entries yet */
1885 findParms.EndofSearch = 0;
1886 reset_resume_key(file, pfindDataUnix->FileName,
1887 qstring.len,Unicode,cifs_sb->local_nls);
1893 /* works also for Unix ff struct since first field of both */
1895 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1896 + le32_to_cpu(pfindData->NextEntryOffset));
1897 /* BB also should check to make sure that pointer is not beyond the end of the SMB */
1898 /* if(pfindData > lastFindData) rc = -EIO; break; */
1899 } /* end for loop */
1900 if ((findParms.EndofSearch != 0) && cifsFile) {
1901 cifsFile->endOfSearch = TRUE;
1902 if(findParms.SearchCount == 2)
1903 cifsFile->emptyDir = TRUE;
1907 cifsFile->endOfSearch = TRUE;
1908 /* unless parent directory gone do not return error */
1913 if (file->private_data == NULL) {
1916 ("Readdir on closed srch, pos = %lld",
1919 cifsFile = (struct cifsFileInfo *) file->private_data;
1920 if (cifsFile->endOfSearch) {
1922 cFYI(1, ("End of search "));
1925 searchHandle = cifsFile->netfid;
1926 rc = CIFSFindNext(xid, pTcon, pfindData,
1927 &findNextParms, searchHandle,
1928 cifsFile->search_resume_name,
1929 cifsFile->resume_name_length,
1930 cifsFile->resume_key,
1931 &Unicode, &UnixSearch);
1932 cFYI(1,("Count: %d End: %d ",
1933 findNextParms.SearchCount,
1934 findNextParms.EndofSearch));
1935 if ((rc == 0) && (findNextParms.SearchCount != 0)) {
1936 /* BB save off resume key, key name and name length */
1938 (FILE_DIRECTORY_INFO *) ((char *) pfindData
1939 + findNextParms.LastNameOffset);
1940 if((char *)lastFindData > (char *)pfindData + bufsize) {
1941 cFYI(1,("last search entry past end of packet"));
1945 /* Offset of resume key same for levels 257 and 514 */
1946 cifsFile->resume_key = lastFindData->FileIndex;
1948 if(UnixSearch == FALSE) {
1949 cifsFile->resume_name_length =
1950 le32_to_cpu(lastFindData->FileNameLength);
1951 if(cifsFile->resume_name_length > bufsize - 64) {
1952 cFYI(1,("Illegal resume file name length %d",
1953 cifsFile->resume_name_length));
1957 /* Free the memory allocated by previous findfirst
1958 or findnext call - we can not reuse the memory since
1959 the resume name may not be same string length */
1960 if(cifsFile->search_resume_name)
1961 kfree(cifsFile->search_resume_name);
1962 cifsFile->search_resume_name =
1963 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1964 cFYI(1,("Last file: %s with name %d bytes long",
1965 lastFindData->FileName,
1966 cifsFile->resume_name_length));
1967 memcpy(cifsFile->search_resume_name,
1968 lastFindData->FileName,
1969 cifsFile->resume_name_length);
1971 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
1972 if (Unicode == TRUE) {
1973 for(i=0;(pfindDataUnix->FileName[i]
1974 | pfindDataUnix->FileName[i+1]);
1979 cifsFile->resume_name_length = i + 2;
1981 cifsFile->resume_name_length =
1982 strnlen(pfindDataUnix->
1986 if(cifsFile->resume_name_length > bufsize - 64) {
1987 cFYI(1,("Illegal resume file name length %d",
1988 cifsFile->resume_name_length));
1992 /* Free the memory allocated by previous findfirst
1993 or findnext call - we can not reuse the memory since
1994 the resume name may not be same string length */
1995 if(cifsFile->search_resume_name)
1996 kfree(cifsFile->search_resume_name);
1997 cifsFile->search_resume_name =
1998 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1999 cFYI(1,("fnext last file: %s with name %d bytes long",
2000 pfindDataUnix->FileName,
2001 cifsFile->resume_name_length));
2002 memcpy(cifsFile->search_resume_name,
2003 pfindDataUnix->FileName,
2004 cifsFile->resume_name_length);
2007 for (i = 0; i < findNextParms.SearchCount; i++) {
2008 pfindData->FileNameLength =
2009 le32_to_cpu(pfindData->
2011 if (UnixSearch == FALSE) {
2012 if (Unicode == TRUE)
2013 pfindData->FileNameLength =
2015 (pfindData->FileName,
2017 pfindData->FileName,
2018 (pfindData->FileNameLength)/ 2,
2019 cifs_sb->local_nls);
2021 pfindData->FileNameLength;
2022 if (((qstring.len != 1)
2023 || (pfindData->FileName[0] != '.'))
2024 && ((qstring.len != 2)
2025 || (pfindData->FileName[0] != '.')
2026 || (pfindData->FileName[1] !=
2033 /* do not end search if
2034 kernel not ready to take
2035 remaining entries yet */
2036 findNextParms.EndofSearch = 0;
2037 reset_resume_key(file, pfindData->FileName,qstring.len,
2038 Unicode,cifs_sb->local_nls);
2043 } else { /* UnixSearch */
2047 if (Unicode == TRUE)
2050 (pfindDataUnix->FileName,
2052 pfindDataUnix->FileName,
2054 cifs_sb->local_nls);
2061 if (((qstring.len != 1)
2063 FileName[0] != '.'))
2064 && ((qstring.len != 2)
2070 if(cifs_filldir_unix
2075 /* do not end search if
2076 kernel not ready to take
2077 remaining entries yet */
2078 findNextParms.EndofSearch = 0;
2079 reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
2080 Unicode,cifs_sb->local_nls);
2086 pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData +
2087 le32_to_cpu(pfindData->NextEntryOffset));
2088 /* works also for Unix find struct since first field of both */
2089 /* BB also should check to ensure pointer not beyond end of SMB */
2090 } /* end for loop */
2091 if (findNextParms.EndofSearch != 0) {
2092 cifsFile->endOfSearch = TRUE;
2095 cifsFile->endOfSearch = TRUE;
2096 rc = 0; /* unless parent directory disappeared - do not
2097 return error here (eg Access Denied or no more files) */
2109 int cifs_prepare_write(struct file *file, struct page *page,
2110 unsigned from, unsigned to)
2113 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
2114 cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
2115 if (!PageUptodate(page)) {
2116 /* if (to - from != PAGE_CACHE_SIZE) {
2117 void *kaddr = kmap_atomic(page, KM_USER0);
2118 memset(kaddr, 0, from);
2119 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
2120 flush_dcache_page(page);
2121 kunmap_atomic(kaddr, KM_USER0);
2123 /* If we are writing a full page it will be up to date,
2124 no need to read from the server */
2125 if((to==PAGE_CACHE_SIZE) && (from == 0))
2126 SetPageUptodate(page);
2128 /* might as well read a page, it is fast enough */
2129 if((file->f_flags & O_ACCMODE) != O_WRONLY) {
2130 rc = cifs_readpage_worker(file,page,&offset);
2132 /* should we try using another
2133 file handle if there is one - how would we lock it
2134 to prevent close of that handle racing with this read? */
2135 /* In any case this will be written out by commit_write */
2139 /* BB should we pass any errors back? e.g. if we do not have read access to the file */
2144 struct address_space_operations cifs_addr_ops = {
2145 .readpage = cifs_readpage,
2146 .readpages = cifs_readpages,
2147 .writepage = cifs_writepage,
2148 .prepare_write = cifs_prepare_write,
2149 .commit_write = cifs_commit_write,
2150 .set_page_dirty = __set_page_dirty_nobuffers,
2151 /* .sync_page = cifs_sync_page, */