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"
38 extern int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir); /* BB removeme BB */
41 cifs_open(struct inode *inode, struct file *file)
45 struct cifs_sb_info *cifs_sb;
46 struct cifsTconInfo *pTcon;
47 struct cifsFileInfo *pCifsFile;
48 struct cifsInodeInfo *pCifsInode;
49 struct list_head * tmp;
50 char *full_path = NULL;
51 int desiredAccess = 0x20197;
54 FILE_ALL_INFO * buf = NULL;
58 cifs_sb = CIFS_SB(inode->i_sb);
59 pTcon = cifs_sb->tcon;
61 if (file->f_flags & O_CREAT) {
62 /* search inode for this file and fill in file->private_data = */
63 pCifsInode = CIFS_I(file->f_dentry->d_inode);
64 read_lock(&GlobalSMBSeslock);
65 list_for_each(tmp, &pCifsInode->openFileList) {
66 pCifsFile = list_entry(tmp,struct cifsFileInfo, flist);
67 if((pCifsFile->pfile == NULL)&& (pCifsFile->pid == current->tgid)){
68 /* mode set in cifs_create */
69 pCifsFile->pfile = file; /* needed for writepage */
70 file->private_data = pCifsFile;
74 read_unlock(&GlobalSMBSeslock);
75 if(file->private_data != NULL) {
80 if(file->f_flags & O_EXCL)
81 cERROR(1,("could not find file instance for new file %p ",file));
85 down(&inode->i_sb->s_vfs_rename_sem);
86 full_path = build_path_from_dentry(file->f_dentry);
87 up(&inode->i_sb->s_vfs_rename_sem);
88 if(full_path == NULL) {
93 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
94 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
95 desiredAccess = GENERIC_READ;
96 else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
97 desiredAccess = GENERIC_WRITE;
98 else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
99 /* GENERIC_ALL is too much permission to request */
100 /* can cause unnecessary access denied on create */
101 /* desiredAccess = GENERIC_ALL; */
102 desiredAccess = GENERIC_READ | GENERIC_WRITE;
105 /*********************************************************************
106 * open flag mapping table:
108 * POSIX Flag CIFS Disposition
109 * ---------- ----------------
110 * O_CREAT FILE_OPEN_IF
111 * O_CREAT | O_EXCL FILE_CREATE
112 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
113 * O_TRUNC FILE_OVERWRITE
114 * none of the above FILE_OPEN
116 * Note that there is not a direct match between disposition
117 * FILE_SUPERSEDE (ie create whether or not file exists although
118 * O_CREAT | O_TRUNC is similar but truncates the existing
119 * file rather than creating a new file as FILE_SUPERSEDE does
120 * (which uses the attributes / metadata passed in on open call)
122 *? O_SYNC is a reasonable match to CIFS writethrough flag
123 *? and the read write flags match reasonably. O_LARGEFILE
124 *? is irrelevant because largefile support is always used
125 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
126 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
127 *********************************************************************/
129 if((file->f_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
130 disposition = FILE_CREATE;
131 else if((file->f_flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
132 disposition = FILE_OVERWRITE_IF;
133 else if((file->f_flags & O_CREAT) == O_CREAT)
134 disposition = FILE_OPEN_IF;
136 disposition = FILE_OPEN;
143 /* BB pass O_SYNC flag through on file attributes .. BB */
145 /* Also refresh inode by passing in file_info buf returned by SMBOpen
146 and calling get_inode_info with returned buf (at least
147 helps non-Unix server case */
149 /* BB we can not do this if this is the second open of a file
150 and the first handle has writebehind data, we might be
151 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
152 buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
159 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
160 CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls);
162 cFYI(1, ("cifs_open returned 0x%x ", rc));
163 cFYI(1, ("oplock: %d ", oplock));
166 kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
167 if (file->private_data) {
168 memset(file->private_data, 0, sizeof(struct cifsFileInfo));
169 pCifsFile = (struct cifsFileInfo *) file->private_data;
170 pCifsFile->netfid = netfid;
171 pCifsFile->pid = current->tgid;
172 init_MUTEX(&pCifsFile->fh_sem);
173 pCifsFile->pfile = file; /* needed for writepage */
174 pCifsFile->pInode = inode;
175 pCifsFile->invalidHandle = FALSE;
176 pCifsFile->closePend = FALSE;
177 write_lock(&file->f_owner.lock);
178 write_lock(&GlobalSMBSeslock);
179 list_add(&pCifsFile->tlist,&pTcon->openFileList);
180 pCifsInode = CIFS_I(file->f_dentry->d_inode);
182 /* want handles we can use to read with first */
183 /* in the list so we do not have to walk the */
184 /* list to search for one in prepare_write */
185 if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
186 list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList);
188 list_add(&pCifsFile->flist,&pCifsInode->openFileList);
190 write_unlock(&GlobalSMBSeslock);
191 write_unlock(&file->f_owner.lock);
192 if(pCifsInode->clientCanCacheRead) {
193 /* we have the inode open somewhere else
194 no need to discard cache data */
197 /* BB need same check in cifs_create too? */
199 /* if not oplocked, invalidate inode pages if mtime
200 or file size changed */
201 struct timespec temp;
202 temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
203 if(timespec_equal(&file->f_dentry->d_inode->i_mtime,&temp) &&
204 (file->f_dentry->d_inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) {
205 cFYI(1,("inode unchanged on server"));
207 if(file->f_dentry->d_inode->i_mapping) {
208 /* BB no need to lock inode until after invalidate*/
209 /* since namei code should already have it locked?*/
210 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
211 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
213 cFYI(1,("invalidating remote inode since open detected it changed"));
214 invalidate_remote_inode(file->f_dentry->d_inode);
218 if (pTcon->ses->capabilities & CAP_UNIX)
219 rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
220 full_path, inode->i_sb,xid);
222 rc = cifs_get_inode_info(&file->f_dentry->d_inode,
223 full_path, buf, inode->i_sb,xid);
225 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
226 pCifsInode->clientCanCacheAll = TRUE;
227 pCifsInode->clientCanCacheRead = TRUE;
228 cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
229 } else if((oplock & 0xF) == OPLOCK_READ)
230 pCifsInode->clientCanCacheRead = TRUE;
232 write_unlock(&GlobalSMBSeslock);
233 write_unlock(&file->f_owner.lock);
235 if(oplock & CIFS_CREATE_ACTION) {
236 /* time to set mode which we can not set earlier due
237 to problems creating new read-only files */
238 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
239 CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
244 else {/* BB implement via Windows security descriptors */
245 /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
246 /* in the meantime could set r/o dos attribute when perms are eg:
261 /* Try to reaquire byte range locks that were released when session */
262 /* to server was lost */
263 static int cifs_relock_file(struct cifsFileInfo * cifsFile)
267 /* BB list all locks open on this file and relock */
272 static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush)
276 struct cifs_sb_info *cifs_sb;
277 struct cifsTconInfo *pTcon;
278 struct cifsFileInfo *pCifsFile;
279 struct cifsInodeInfo *pCifsInode;
280 char *full_path = NULL;
281 int desiredAccess = 0x20197;
282 int disposition = FILE_OPEN;
287 if (file->private_data) {
288 pCifsFile = (struct cifsFileInfo *) file->private_data;
293 down(&pCifsFile->fh_sem);
294 if(pCifsFile->invalidHandle == FALSE) {
295 up(&pCifsFile->fh_sem);
300 if(file->f_dentry == NULL) {
301 up(&pCifsFile->fh_sem);
302 cFYI(1,("failed file reopen, no valid name if dentry freed"));
306 cifs_sb = CIFS_SB(inode->i_sb);
307 pTcon = cifs_sb->tcon;
308 /* can not grab rename sem here because various ops, including
309 those that already have the rename sem can end up causing writepage
310 to get called and if the server was down that means we end up here,
311 and we can never tell if the caller already has the rename_sem */
312 full_path = build_path_from_dentry(file->f_dentry);
313 if(full_path == NULL) {
314 up(&pCifsFile->fh_sem);
319 cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
320 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
321 desiredAccess = GENERIC_READ;
322 else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
323 desiredAccess = GENERIC_WRITE;
324 else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
325 /* GENERIC_ALL is too much permission to request */
326 /* can cause unnecessary access denied on create */
327 /* desiredAccess = GENERIC_ALL; */
328 desiredAccess = GENERIC_READ | GENERIC_WRITE;
337 /* Can not refresh inode by passing in file_info buf to be returned
338 by SMBOpen and then calling get_inode_info with returned buf
339 since file might have write behind data that needs to be flushed
340 and server version of file size can be stale. If we
341 knew for sure that inode was not dirty locally we could do this */
343 /* buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
345 up(&pCifsFile->fh_sem);
351 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
352 CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
354 up(&pCifsFile->fh_sem);
355 cFYI(1, ("cifs_open returned 0x%x ", rc));
356 cFYI(1, ("oplock: %d ", oplock));
358 pCifsFile->netfid = netfid;
359 pCifsFile->invalidHandle = FALSE;
360 up(&pCifsFile->fh_sem);
361 pCifsInode = CIFS_I(inode);
364 filemap_fdatawrite(inode->i_mapping);
365 filemap_fdatawait(inode->i_mapping);
366 /* temporarily disable caching while we
367 go to server to get inode info */
368 pCifsInode->clientCanCacheAll = FALSE;
369 pCifsInode->clientCanCacheRead = FALSE;
370 if (pTcon->ses->capabilities & CAP_UNIX)
371 rc = cifs_get_inode_info_unix(&inode,
372 full_path, inode->i_sb,xid);
374 rc = cifs_get_inode_info(&inode,
375 full_path, NULL, inode->i_sb,xid);
376 } /* else we are writing out data to server already
377 and could deadlock if we tried to flush data, and
378 since we do not know if we have data that would
379 invalidate the current end of file on the server
380 we can not go to the server to get the new
382 if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
383 pCifsInode->clientCanCacheAll = TRUE;
384 pCifsInode->clientCanCacheRead = TRUE;
385 cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
386 } else if((oplock & 0xF) == OPLOCK_READ) {
387 pCifsInode->clientCanCacheRead = TRUE;
388 pCifsInode->clientCanCacheAll = FALSE;
390 pCifsInode->clientCanCacheRead = FALSE;
391 pCifsInode->clientCanCacheAll = FALSE;
393 cifs_relock_file(pCifsFile);
404 cifs_close(struct inode *inode, struct file *file)
408 struct cifs_sb_info *cifs_sb;
409 struct cifsTconInfo *pTcon;
410 struct cifsFileInfo *pSMBFile =
411 (struct cifsFileInfo *) file->private_data;
415 cifs_sb = CIFS_SB(inode->i_sb);
416 pTcon = cifs_sb->tcon;
418 pSMBFile->closePend = TRUE;
419 write_lock(&file->f_owner.lock);
421 /* no sense reconnecting to close a file that is
423 if (pTcon->tidStatus != CifsNeedReconnect) {
424 write_unlock(&file->f_owner.lock);
425 rc = CIFSSMBClose(xid,pTcon,pSMBFile->netfid);
426 write_lock(&file->f_owner.lock);
429 list_del(&pSMBFile->flist);
430 list_del(&pSMBFile->tlist);
431 write_unlock(&file->f_owner.lock);
432 if(pSMBFile->search_resume_name)
433 kfree(pSMBFile->search_resume_name);
434 kfree(file->private_data);
435 file->private_data = NULL;
439 if(list_empty(&(CIFS_I(inode)->openFileList))) {
440 cFYI(1,("closing last open instance for inode %p",inode));
441 /* if the file is not open we do not know if we can cache
442 info on this inode, much less write behind and read ahead */
443 CIFS_I(inode)->clientCanCacheRead = FALSE;
444 CIFS_I(inode)->clientCanCacheAll = FALSE;
446 if((rc ==0) && CIFS_I(inode)->write_behind_rc)
447 rc = CIFS_I(inode)->write_behind_rc;
453 cifs_closedir(struct inode *inode, struct file *file)
457 struct cifsFileInfo *pCFileStruct =
458 (struct cifsFileInfo *) file->private_data;
461 cFYI(1, ("Closedir inode = 0x%p with ", inode));
466 struct cifsTconInfo *pTcon;
467 struct cifs_sb_info * cifs_sb = CIFS_SB(file->f_dentry->d_sb);
469 pTcon = cifs_sb->tcon;
471 cFYI(1, ("Freeing private data in close dir"));
472 if(pCFileStruct->srch_inf.endOfSearch == FALSE) {
473 pCFileStruct->invalidHandle = TRUE;
474 rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
475 cFYI(1,("Closing uncompleted readdir with rc %d",rc));
476 /* not much we can do if it fails anywway, ignore rc */
479 ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
481 cFYI(1,("freeing smb buf in srch struct in closedir")); /* BB removeme BB */
482 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
483 cifs_buf_release(ptmp);
485 ptmp = pCFileStruct->search_resume_name;
487 cFYI(1,("freeing resume name in closedir")); /* BB removeme BB */
488 pCFileStruct->search_resume_name = NULL;
491 kfree(file->private_data);
492 file->private_data = NULL;
494 /* BB can we lock the filestruct while this is going on? */
500 cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
503 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
507 int wait_flag = FALSE;
508 struct cifs_sb_info *cifs_sb;
509 struct cifsTconInfo *pTcon;
510 length = 1 + pfLock->fl_end - pfLock->fl_start;
517 ("Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld",
518 cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
521 if (pfLock->fl_flags & FL_POSIX)
523 if (pfLock->fl_flags & FL_FLOCK)
525 if (pfLock->fl_flags & FL_SLEEP) {
526 cFYI(1, ("Blocking lock "));
529 if (pfLock->fl_flags & FL_ACCESS)
530 cFYI(1, ("Process suspended by mandatory locking - not implemented yet "));
531 if (pfLock->fl_flags & FL_LEASE)
532 cFYI(1, ("Lease on file - not implemented yet"));
533 if (pfLock->fl_flags & (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
534 cFYI(1, ("Unknown lock flags 0x%x",pfLock->fl_flags));
536 if (pfLock->fl_type == F_WRLCK) {
537 cFYI(1, ("F_WRLCK "));
539 } else if (pfLock->fl_type == F_UNLCK) {
540 cFYI(1, ("F_UNLCK "));
542 } else if (pfLock->fl_type == F_RDLCK) {
543 cFYI(1, ("F_RDLCK "));
544 lockType |= LOCKING_ANDX_SHARED_LOCK;
546 } else if (pfLock->fl_type == F_EXLCK) {
547 cFYI(1, ("F_EXLCK "));
549 } else if (pfLock->fl_type == F_SHLCK) {
550 cFYI(1, ("F_SHLCK "));
551 lockType |= LOCKING_ANDX_SHARED_LOCK;
554 cFYI(1, ("Unknown type of lock "));
556 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
557 pTcon = cifs_sb->tcon;
559 if (file->private_data == NULL) {
565 rc = CIFSSMBLock(xid, pTcon,
566 ((struct cifsFileInfo *) file->
567 private_data)->netfid,
569 pfLock->fl_start, 0, 1, lockType,
572 rc = CIFSSMBLock(xid, pTcon,
573 ((struct cifsFileInfo *) file->
574 private_data)->netfid,
576 pfLock->fl_start, 1 /* numUnlock */ ,
577 0 /* numLock */ , lockType,
579 pfLock->fl_type = F_UNLCK;
582 ("Error unlocking previously locked range %d during test of lock ",
587 /* if rc == ERR_SHARING_VIOLATION ? */
588 rc = 0; /* do not change lock type to unlock since range in use */
595 rc = CIFSSMBLock(xid, pTcon,
596 ((struct cifsFileInfo *) file->private_data)->
598 pfLock->fl_start, numUnlock, numLock, lockType,
600 if (rc == 0 && (pfLock->fl_flags & FL_POSIX))
601 posix_lock_file_wait(file, pfLock);
607 cifs_user_write(struct file * file, const char __user * write_data,
608 size_t write_size, loff_t * poffset)
611 unsigned int bytes_written = 0;
612 unsigned int total_written;
613 struct cifs_sb_info *cifs_sb;
614 struct cifsTconInfo *pTcon;
616 struct cifsFileInfo * open_file;
618 if(file->f_dentry == NULL)
621 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
622 if(cifs_sb == NULL) {
625 pTcon = cifs_sb->tcon;
628 (" write %d bytes to offset %lld of %s", write_size,
629 *poffset, file->f_dentry->d_name.name)); */
631 if (file->private_data == NULL) {
634 open_file = (struct cifsFileInfo *) file->private_data;
638 if(file->f_dentry->d_inode == NULL) {
643 if (*poffset > file->f_dentry->d_inode->i_size)
644 long_op = 2; /* writes past end of file can take a long time */
648 for (total_written = 0; write_size > total_written;
649 total_written += bytes_written) {
651 while(rc == -EAGAIN) {
652 if(file->private_data == NULL) {
653 /* file has been closed on us */
655 /* if we have gotten here we have written some data
656 and blocked, and the file has been freed on us
657 while we blocked so return what we managed to write */
658 return total_written;
660 if(open_file->closePend) {
663 return total_written;
667 if (open_file->invalidHandle) {
668 if((file->f_dentry == NULL) ||
669 (file->f_dentry->d_inode == NULL)) {
671 return total_written;
673 /* we could deadlock if we called
674 filemap_fdatawait from here so tell
675 reopen_file not to flush data to server now */
676 rc = cifs_reopen_file(file->f_dentry->d_inode,
682 rc = CIFSSMBWrite(xid, pTcon,
684 write_size - total_written, *poffset,
686 NULL, write_data + total_written, long_op);
688 if (rc || (bytes_written == 0)) {
696 *poffset += bytes_written;
697 long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
700 #ifdef CONFIG_CIFS_STATS
701 if(total_written > 0) {
702 atomic_inc(&pTcon->num_writes);
703 spin_lock(&pTcon->stat_lock);
704 pTcon->bytes_written += total_written;
705 spin_unlock(&pTcon->stat_lock);
709 /* since the write may have blocked check these pointers again */
711 if(file->f_dentry->d_inode) {
712 file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
714 if (total_written > 0) {
715 if (*poffset > file->f_dentry->d_inode->i_size)
716 i_size_write(file->f_dentry->d_inode, *poffset);
718 mark_inode_dirty_sync(file->f_dentry->d_inode);
722 return total_written;
726 cifs_write(struct file * file, const char *write_data,
727 size_t write_size, loff_t * poffset)
730 unsigned int bytes_written = 0;
731 unsigned int total_written;
732 struct cifs_sb_info *cifs_sb;
733 struct cifsTconInfo *pTcon;
735 struct cifsFileInfo * open_file;
737 if(file->f_dentry == NULL)
740 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
741 if(cifs_sb == NULL) {
744 pTcon = cifs_sb->tcon;
747 (" write %d bytes to offset %lld of %s", write_size,
748 *poffset, file->f_dentry->d_name.name)); */
750 if (file->private_data == NULL) {
753 open_file = (struct cifsFileInfo *) file->private_data;
757 if(file->f_dentry->d_inode == NULL) {
762 if (*poffset > file->f_dentry->d_inode->i_size)
763 long_op = 2; /* writes past end of file can take a long time */
767 for (total_written = 0; write_size > total_written;
768 total_written += bytes_written) {
770 while(rc == -EAGAIN) {
771 if(file->private_data == NULL) {
772 /* file has been closed on us */
774 /* if we have gotten here we have written some data
775 and blocked, and the file has been freed on us
776 while we blocked so return what we managed to write */
777 return total_written;
779 if(open_file->closePend) {
782 return total_written;
786 if (open_file->invalidHandle) {
787 if((file->f_dentry == NULL) ||
788 (file->f_dentry->d_inode == NULL)) {
790 return total_written;
792 /* we could deadlock if we called
793 filemap_fdatawait from here so tell
794 reopen_file not to flush data to server now */
795 rc = cifs_reopen_file(file->f_dentry->d_inode,
801 rc = CIFSSMBWrite(xid, pTcon,
803 write_size - total_written, *poffset,
805 write_data + total_written, NULL, long_op);
807 if (rc || (bytes_written == 0)) {
815 *poffset += bytes_written;
816 long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
819 #ifdef CONFIG_CIFS_STATS
820 if(total_written > 0) {
821 atomic_inc(&pTcon->num_writes);
822 spin_lock(&pTcon->stat_lock);
823 pTcon->bytes_written += total_written;
824 spin_unlock(&pTcon->stat_lock);
828 /* since the write may have blocked check these pointers again */
830 if(file->f_dentry->d_inode) {
831 file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
833 if (total_written > 0) {
834 if (*poffset > file->f_dentry->d_inode->i_size)
835 i_size_write(file->f_dentry->d_inode, *poffset);
837 mark_inode_dirty_sync(file->f_dentry->d_inode);
841 return total_written;
845 cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
847 struct address_space *mapping = page->mapping;
848 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
851 int bytes_written = 0;
852 struct cifs_sb_info *cifs_sb;
853 struct cifsTconInfo *pTcon;
855 struct cifsInodeInfo *cifsInode;
856 struct cifsFileInfo *open_file = NULL;
857 struct list_head *tmp;
858 struct list_head *tmp1;
862 } else if(!mapping->host) {
866 inode = page->mapping->host;
867 cifs_sb = CIFS_SB(inode->i_sb);
868 pTcon = cifs_sb->tcon;
870 offset += (loff_t)from;
871 write_data = kmap(page);
874 if((to > PAGE_CACHE_SIZE) || (from > to)) {
879 /* racing with truncate? */
880 if(offset > mapping->host->i_size) {
882 return 0; /* don't care */
885 /* check to make sure that we are not extending the file */
886 if(mapping->host->i_size - offset < (loff_t)to)
887 to = (unsigned)(mapping->host->i_size - offset);
890 cifsInode = CIFS_I(mapping->host);
891 read_lock(&GlobalSMBSeslock);
892 /* BB we should start at the end */
893 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
894 open_file = list_entry(tmp,struct cifsFileInfo, flist);
895 if(open_file->closePend)
897 /* We check if file is open for writing first */
898 if((open_file->pfile) &&
899 ((open_file->pfile->f_flags & O_RDWR) ||
900 (open_file->pfile->f_flags & O_WRONLY))) {
901 read_unlock(&GlobalSMBSeslock);
902 bytes_written = cifs_write(open_file->pfile, write_data,
904 read_lock(&GlobalSMBSeslock);
905 /* Does mm or vfs already set times? */
906 inode->i_atime = inode->i_mtime = CURRENT_TIME;
907 if ((bytes_written > 0) && (offset)) {
909 } else if(bytes_written < 0) {
911 /* have seen a case in which
912 kernel seemed to have closed/freed a file
913 even with writes active so we might as well
914 see if there are other file structs to try
915 for the same inode before giving up */
920 break; /* now that we found a valid file handle
921 and tried to write to it we are done, no
922 sense continuing to loop looking for another */
924 if(tmp->next == NULL) {
925 cFYI(1,("File instance %p removed",tmp));
929 read_unlock(&GlobalSMBSeslock);
930 if(open_file == NULL) {
931 cFYI(1,("No writeable filehandles for inode"));
941 cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
947 /* call 16K write then Setpageuptodate */
954 cifs_writepage(struct page* page, struct writeback_control *wbc)
960 /* BB add check for wbc flags */
961 page_cache_get(page);
962 if (!PageUptodate(page)) {
963 cFYI(1,("ppw - page not up to date"));
966 rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
967 SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
969 page_cache_release(page);
975 cifs_commit_write(struct file *file, struct page *page, unsigned offset,
980 struct inode *inode = page->mapping->host;
981 loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
985 cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
986 if (position > inode->i_size){
987 i_size_write(inode, position);
988 /*if (file->private_data == NULL) {
991 open_file = (struct cifsFileInfo *)file->private_data;
992 cifs_sb = CIFS_SB(inode->i_sb);
994 while(rc == -EAGAIN) {
995 if((open_file->invalidHandle) &&
996 (!open_file->closePend)) {
997 rc = cifs_reopen_file(file->f_dentry->d_inode,file);
1001 if(!open_file->closePend) {
1002 rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon,
1003 position, open_file->netfid,
1004 open_file->pid,FALSE);
1010 cFYI(1,(" SetEOF (commit write) rc = %d",rc));
1013 if (!PageUptodate(page)) {
1014 position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
1015 /* can not rely on (or let) writepage write this data */
1017 cFYI(1,("Illegal offsets, can not copy from %d to %d",
1022 /* this is probably better than directly calling
1023 partialpage_write since in this function
1024 the file handle is known which we might as well
1026 /* BB check if anything else missing out of ppw */
1027 /* such as updating last write time */
1028 page_data = kmap(page);
1029 rc = cifs_write(file, page_data+offset,to-offset,
1033 /* else if rc < 0 should we set writebehind rc? */
1036 set_page_dirty(page);
1044 cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
1048 struct inode * inode = file->f_dentry->d_inode;
1052 cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
1053 dentry->d_name.name, datasync));
1055 rc = filemap_fdatawrite(inode->i_mapping);
1057 CIFS_I(inode)->write_behind_rc = 0;
1063 cifs_sync_page(struct page *page)
1065 struct address_space *mapping;
1066 struct inode *inode;
1067 unsigned long index = page->index;
1068 unsigned int rpages = 0;
1071 cFYI(1,("sync page %p",page));
1072 mapping = page->mapping;
1075 inode = mapping->host;
1079 /* fill in rpages then
1080 result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */
1082 /* cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
1090 * As file closes, flush all cached write data for this inode checking
1091 * for write behind errors.
1094 int cifs_flush(struct file *file)
1096 struct inode * inode = file->f_dentry->d_inode;
1099 /* Rather than do the steps manually: */
1100 /* lock the inode for writing */
1101 /* loop through pages looking for write behind data (dirty pages) */
1102 /* coalesce into contiguous 16K (or smaller) chunks to write to server */
1103 /* send to server (prefer in parallel) */
1104 /* deal with writebehind errors */
1105 /* unlock inode for writing */
1106 /* filemapfdatawrite appears easier for the time being */
1108 rc = filemap_fdatawrite(inode->i_mapping);
1109 if(rc == 0) /* reset wb rc if we were able to write out dirty pages */
1110 CIFS_I(inode)->write_behind_rc = 0;
1112 cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
1119 cifs_user_read(struct file * file, char __user *read_data, size_t read_size,
1123 unsigned int bytes_read = 0;
1124 unsigned int total_read = 0;
1125 unsigned int current_read_size;
1126 struct cifs_sb_info *cifs_sb;
1127 struct cifsTconInfo *pTcon;
1129 struct cifsFileInfo * open_file;
1130 char * smb_read_data;
1131 char __user * current_offset;
1132 struct smb_com_read_rsp * pSMBr;
1135 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1136 pTcon = cifs_sb->tcon;
1138 if (file->private_data == NULL) {
1142 open_file = (struct cifsFileInfo *)file->private_data;
1144 if((file->f_flags & O_ACCMODE) == O_WRONLY) {
1145 cFYI(1,("attempting read on write only file instance"));
1148 for (total_read = 0,current_offset=read_data; read_size > total_read;
1149 total_read += bytes_read,current_offset+=bytes_read) {
1150 current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
1152 smb_read_data = NULL;
1153 while(rc == -EAGAIN) {
1154 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1155 rc = cifs_reopen_file(file->f_dentry->d_inode,
1161 rc = CIFSSMBRead(xid, pTcon,
1163 current_read_size, *poffset,
1164 &bytes_read, &smb_read_data);
1166 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1167 copy_to_user(current_offset,smb_read_data + 4/* RFC1001 hdr*/
1168 + le16_to_cpu(pSMBr->DataOffset), bytes_read);
1170 cifs_buf_release(smb_read_data);
1171 smb_read_data = NULL;
1174 if (rc || (bytes_read == 0)) {
1182 #ifdef CONFIG_CIFS_STATS
1183 atomic_inc(&pTcon->num_reads);
1184 spin_lock(&pTcon->stat_lock);
1185 pTcon->bytes_read += total_read;
1186 spin_unlock(&pTcon->stat_lock);
1188 *poffset += bytes_read;
1196 cifs_read(struct file * file, char *read_data, size_t read_size,
1200 unsigned int bytes_read = 0;
1201 unsigned int total_read;
1202 unsigned int current_read_size;
1203 struct cifs_sb_info *cifs_sb;
1204 struct cifsTconInfo *pTcon;
1206 char * current_offset;
1207 struct cifsFileInfo * open_file;
1210 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1211 pTcon = cifs_sb->tcon;
1213 if (file->private_data == NULL) {
1217 open_file = (struct cifsFileInfo *)file->private_data;
1219 if((file->f_flags & O_ACCMODE) == O_WRONLY) {
1220 cFYI(1,("attempting read on write only file instance"));
1223 for (total_read = 0,current_offset=read_data; read_size > total_read;
1224 total_read += bytes_read,current_offset+=bytes_read) {
1225 current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
1227 while(rc == -EAGAIN) {
1228 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1229 rc = cifs_reopen_file(file->f_dentry->d_inode,
1235 rc = CIFSSMBRead(xid, pTcon,
1237 current_read_size, *poffset,
1238 &bytes_read, ¤t_offset);
1240 if (rc || (bytes_read == 0)) {
1248 #ifdef CONFIG_CIFS_STATS
1249 atomic_inc(&pTcon->num_reads);
1250 spin_lock(&pTcon->stat_lock);
1251 pTcon->bytes_read += total_read;
1252 spin_unlock(&pTcon->stat_lock);
1254 *poffset += bytes_read;
1261 int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
1263 struct dentry * dentry = file->f_dentry;
1266 #ifdef CIFS_EXPERIMENTAL /* BB fixme reenable when cifs_read_wrapper fixed */
1268 struct cifs_sb_info *cifs_sb;
1269 cifs_sb = CIFS_SB(sb);
1270 if(cifs_sb != NULL) {
1271 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
1275 #endif /* CIFS_EXPERIMENTAL */
1278 rc = cifs_revalidate(dentry);
1280 cFYI(1,("Validation prior to mmap failed, error=%d", rc));
1284 rc = generic_file_mmap(file, vma);
1289 static void cifs_copy_cache_pages(struct address_space *mapping,
1290 struct list_head *pages, int bytes_read,
1291 char *data,struct pagevec * plru_pvec)
1296 while (bytes_read > 0) {
1297 if(list_empty(pages))
1300 page = list_entry(pages->prev, struct page, lru);
1301 list_del(&page->lru);
1303 if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
1304 page_cache_release(page);
1305 cFYI(1,("Add page cache failed"));
1309 target = kmap_atomic(page,KM_USER0);
1311 if(PAGE_CACHE_SIZE > bytes_read) {
1312 memcpy(target,data,bytes_read);
1313 /* zero the tail end of this partial page */
1314 memset(target+bytes_read,0,PAGE_CACHE_SIZE-bytes_read);
1317 memcpy(target,data,PAGE_CACHE_SIZE);
1318 bytes_read -= PAGE_CACHE_SIZE;
1320 kunmap_atomic(target,KM_USER0);
1322 flush_dcache_page(page);
1323 SetPageUptodate(page);
1325 if (!pagevec_add(plru_pvec, page))
1326 __pagevec_lru_add(plru_pvec);
1327 data += PAGE_CACHE_SIZE;
1334 cifs_readpages(struct file *file, struct address_space *mapping,
1335 struct list_head *page_list, unsigned num_pages)
1341 struct cifs_sb_info *cifs_sb;
1342 struct cifsTconInfo *pTcon;
1344 unsigned int read_size,i;
1345 char * smb_read_data = NULL;
1346 struct smb_com_read_rsp * pSMBr;
1347 struct pagevec lru_pvec;
1348 struct cifsFileInfo * open_file;
1351 if (file->private_data == NULL) {
1355 open_file = (struct cifsFileInfo *)file->private_data;
1356 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1357 pTcon = cifs_sb->tcon;
1359 pagevec_init(&lru_pvec, 0);
1361 for(i = 0;i<num_pages;) {
1362 unsigned contig_pages;
1363 struct page * tmp_page;
1364 unsigned long expected_index;
1366 if(list_empty(page_list)) {
1369 page = list_entry(page_list->prev, struct page, lru);
1370 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1372 /* count adjacent pages that we will read into */
1374 expected_index = list_entry(page_list->prev,struct page,lru)->index;
1375 list_for_each_entry_reverse(tmp_page,page_list,lru) {
1376 if(tmp_page->index == expected_index) {
1383 if(contig_pages + i > num_pages) {
1384 contig_pages = num_pages - i;
1387 /* for reads over a certain size could initiate async read ahead */
1389 read_size = contig_pages * PAGE_CACHE_SIZE;
1390 /* Read size needs to be in multiples of one page */
1391 read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
1394 while(rc == -EAGAIN) {
1395 if ((open_file->invalidHandle) && (!open_file->closePend)) {
1396 rc = cifs_reopen_file(file->f_dentry->d_inode,
1402 rc = CIFSSMBRead(xid, pTcon,
1405 &bytes_read, &smb_read_data);
1406 /* BB need to check return code here */
1409 cifs_buf_release(smb_read_data);
1410 smb_read_data = NULL;
1414 if ((rc < 0) || (smb_read_data == NULL)) {
1415 cFYI(1,("Read error in readpages: %d",rc));
1416 /* clean up remaing pages off list */
1417 while (!list_empty(page_list) && (i < num_pages)) {
1418 page = list_entry(page_list->prev, struct page, lru);
1419 list_del(&page->lru);
1420 page_cache_release(page);
1423 } else if (bytes_read > 0) {
1424 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
1425 cifs_copy_cache_pages(mapping, page_list, bytes_read,
1426 smb_read_data + 4 /* RFC1001 hdr */ +
1427 le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
1429 i += bytes_read >> PAGE_CACHE_SHIFT;
1430 #ifdef CONFIG_CIFS_STATS
1431 atomic_inc(&pTcon->num_reads);
1432 spin_lock(&pTcon->stat_lock);
1433 pTcon->bytes_read += bytes_read;
1434 spin_unlock(&pTcon->stat_lock);
1436 if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
1437 i++; /* account for partial page */
1439 /* server copy of file can have smaller size than client */
1440 /* BB do we need to verify this common case ? this case is ok -
1441 if we are at server EOF we will hit it on next read */
1443 /* while(!list_empty(page_list) && (i < num_pages)) {
1444 page = list_entry(page_list->prev,struct page, list);
1445 list_del(&page->list);
1446 page_cache_release(page);
1451 cFYI(1,("No bytes read (%d) at offset %lld . Cleaning remaining pages from readahead list",bytes_read,offset));
1452 /* BB turn off caching and do new lookup on file size at server? */
1453 while (!list_empty(page_list) && (i < num_pages)) {
1454 page = list_entry(page_list->prev, struct page, lru);
1455 list_del(&page->lru);
1456 page_cache_release(page); /* BB removeme - replace with zero of page? */
1461 cifs_buf_release(smb_read_data);
1462 smb_read_data = NULL;
1467 pagevec_lru_add(&lru_pvec);
1469 /* need to free smb_read_data buf before exit */
1471 cifs_buf_release(smb_read_data);
1472 smb_read_data = NULL;
1479 static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
1484 page_cache_get(page);
1485 read_data = kmap(page);
1486 /* for reads over a certain size could initiate async read ahead */
1488 rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
1493 cFYI(1,("Bytes read %d ",rc));
1496 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
1498 if(PAGE_CACHE_SIZE > rc) {
1499 memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
1501 flush_dcache_page(page);
1502 SetPageUptodate(page);
1507 page_cache_release(page);
1512 cifs_readpage(struct file *file, struct page *page)
1514 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
1520 if (file->private_data == NULL) {
1525 cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
1527 rc = cifs_readpage_worker(file,page,&offset);
1535 /* We do not want to update the file size from server for inodes
1536 open for write - to avoid races with writepage extending
1537 the file - in the future we could consider allowing
1538 refreshing the inode only on increases in the file size
1539 but this is tricky to do without racing with writebehind
1540 page caching in the current Linux kernel design */
1542 int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
1544 struct list_head *tmp;
1545 struct list_head *tmp1;
1546 struct cifsFileInfo *open_file = NULL;
1549 if(cifsInode == NULL)
1552 read_lock(&GlobalSMBSeslock);
1553 list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
1554 open_file = list_entry(tmp,struct cifsFileInfo, flist);
1555 if(open_file == NULL)
1557 if(open_file->closePend)
1559 /* We check if file is open for writing,
1560 BB we could supplement this with a check to see if file size
1561 changes have been flushed to server - ie inode metadata dirty */
1562 if((open_file->pfile) &&
1563 ((open_file->pfile->f_flags & O_RDWR) ||
1564 (open_file->pfile->f_flags & O_WRONLY))) {
1568 if(tmp->next == NULL) {
1569 cFYI(1,("File instance %p removed",tmp));
1573 read_unlock(&GlobalSMBSeslock);
1579 fill_in_inode(struct inode *tmp_inode,
1580 FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
1582 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1583 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
1584 __u32 attr = le32_to_cpu(pfindData->ExtFileAttributes);
1585 __u64 allocation_size = le64_to_cpu(pfindData->AllocationSize);
1586 __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
1588 cifsInfo->cifsAttrs = attr;
1589 cifsInfo->time = jiffies;
1591 /* Linux can not store file creation time unfortunately so ignore it */
1592 tmp_inode->i_atime =
1593 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1594 tmp_inode->i_mtime =
1595 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
1596 tmp_inode->i_ctime =
1597 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
1598 /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
1599 /* 2767 perms - indicate mandatory locking */
1600 /* BB fill in uid and gid here? with help from winbind?
1601 or retrieve from NTFS stream extended attribute */
1602 if(atomic_read(&cifsInfo->inUse) == 0) {
1603 tmp_inode->i_uid = cifs_sb->mnt_uid;
1604 tmp_inode->i_gid = cifs_sb->mnt_gid;
1605 /* set default mode. will override for dirs below */
1606 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
1610 ("CIFS FFIRST: Attributes came in as 0x%x",
1612 if (attr & ATTR_DIRECTORY) {
1613 *pobject_type = DT_DIR;
1614 /* override default perms since we do not lock dirs */
1615 if(atomic_read(&cifsInfo->inUse) == 0) {
1616 tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
1618 tmp_inode->i_mode |= S_IFDIR;
1619 /* we no longer mark these because we could not follow them */
1620 /* } else if (attr & ATTR_REPARSE) {
1621 *pobject_type = DT_LNK;
1622 tmp_inode->i_mode |= S_IFLNK;*/
1624 *pobject_type = DT_REG;
1625 tmp_inode->i_mode |= S_IFREG;
1626 if(attr & ATTR_READONLY)
1627 tmp_inode->i_mode &= ~(S_IWUGO);
1628 }/* could add code here - to validate if device or weird share type? */
1630 /* can not fill in nlink here as in qpathinfo version and Unx search */
1631 if(atomic_read(&cifsInfo->inUse) == 0) {
1632 atomic_set(&cifsInfo->inUse,1);
1635 if(is_size_safe_to_change(cifsInfo)) {
1636 /* can not safely change the file size here if the
1637 client is writing to it due to potential races */
1638 i_size_write(tmp_inode,end_of_file);
1640 /* 512 bytes (2**9) is the fake blocksize that must be used */
1641 /* for this calculation, even though the reported blocksize is larger */
1642 tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9;
1645 if (allocation_size < end_of_file)
1646 cFYI(1, ("Possible sparse file: allocation size less than end of file "));
1648 ("File Size %ld and blocks %ld and blocksize %ld",
1649 (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
1650 tmp_inode->i_blksize));
1651 if (S_ISREG(tmp_inode->i_mode)) {
1652 cFYI(1, (" File inode "));
1653 tmp_inode->i_op = &cifs_file_inode_ops;
1654 tmp_inode->i_fop = &cifs_file_ops;
1655 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1656 } else if (S_ISDIR(tmp_inode->i_mode)) {
1657 cFYI(1, (" Directory inode"));
1658 tmp_inode->i_op = &cifs_dir_inode_ops;
1659 tmp_inode->i_fop = &cifs_dir_ops;
1660 } else if (S_ISLNK(tmp_inode->i_mode)) {
1661 cFYI(1, (" Symbolic Link inode "));
1662 tmp_inode->i_op = &cifs_symlink_inode_ops;
1664 cFYI(1, (" Init special inode "));
1665 init_special_inode(tmp_inode, tmp_inode->i_mode,
1671 unix_fill_in_inode(struct inode *tmp_inode,
1672 FILE_UNIX_INFO * pfindData, int *pobject_type)
1674 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1675 __u32 type = le32_to_cpu(pfindData->Type);
1676 __u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes);
1677 __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile);
1678 cifsInfo->time = jiffies;
1679 atomic_inc(&cifsInfo->inUse);
1681 tmp_inode->i_atime =
1682 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
1683 tmp_inode->i_mtime =
1684 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
1685 tmp_inode->i_ctime =
1686 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
1688 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
1689 if (type == UNIX_FILE) {
1690 *pobject_type = DT_REG;
1691 tmp_inode->i_mode |= S_IFREG;
1692 } else if (type == UNIX_SYMLINK) {
1693 *pobject_type = DT_LNK;
1694 tmp_inode->i_mode |= S_IFLNK;
1695 } else if (type == UNIX_DIR) {
1696 *pobject_type = DT_DIR;
1697 tmp_inode->i_mode |= S_IFDIR;
1698 } else if (type == UNIX_CHARDEV) {
1699 *pobject_type = DT_CHR;
1700 tmp_inode->i_mode |= S_IFCHR;
1701 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1702 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1703 } else if (type == UNIX_BLOCKDEV) {
1704 *pobject_type = DT_BLK;
1705 tmp_inode->i_mode |= S_IFBLK;
1706 tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
1707 le64_to_cpu(pfindData->DevMinor) & MINORMASK);
1708 } else if (type == UNIX_FIFO) {
1709 *pobject_type = DT_FIFO;
1710 tmp_inode->i_mode |= S_IFIFO;
1711 } else if (type == UNIX_SOCKET) {
1712 *pobject_type = DT_SOCK;
1713 tmp_inode->i_mode |= S_IFSOCK;
1716 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
1717 tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
1718 tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
1721 if(is_size_safe_to_change(cifsInfo)) {
1722 /* can not safely change the file size here if the
1723 client is writing to it due to potential races */
1724 i_size_write(tmp_inode,end_of_file);
1726 /* 512 bytes (2**9) is the fake blocksize that must be used */
1727 /* for this calculation, not the real blocksize */
1728 tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
1731 if (S_ISREG(tmp_inode->i_mode)) {
1732 cFYI(1, ("File inode"));
1733 tmp_inode->i_op = &cifs_file_inode_ops;
1734 tmp_inode->i_fop = &cifs_file_ops;
1735 tmp_inode->i_data.a_ops = &cifs_addr_ops;
1736 } else if (S_ISDIR(tmp_inode->i_mode)) {
1737 cFYI(1, ("Directory inode"));
1738 tmp_inode->i_op = &cifs_dir_inode_ops;
1739 tmp_inode->i_fop = &cifs_dir_ops;
1740 } else if (S_ISLNK(tmp_inode->i_mode)) {
1741 cFYI(1, ("Symbolic Link inode"));
1742 tmp_inode->i_op = &cifs_symlink_inode_ops;
1743 /* tmp_inode->i_fop = *//* do not need to set to anything */
1745 cFYI(1, ("Special inode"));
1746 init_special_inode(tmp_inode, tmp_inode->i_mode,
1751 /* Returns one if new inode created (which therefore needs to be hashed) */
1752 /* Might check in the future if inode number changed so we can rehash inode */
1754 construct_dentry(struct qstr *qstring, struct file *file,
1755 struct inode **ptmp_inode, struct dentry **pnew_dentry)
1757 struct dentry *tmp_dentry;
1758 struct cifs_sb_info *cifs_sb;
1759 struct cifsTconInfo *pTcon;
1762 cFYI(1, ("For %s ", qstring->name));
1763 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1764 pTcon = cifs_sb->tcon;
1766 qstring->hash = full_name_hash(qstring->name, qstring->len);
1767 tmp_dentry = d_lookup(file->f_dentry, qstring);
1769 cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
1770 *ptmp_inode = tmp_dentry->d_inode;
1771 /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
1772 if(*ptmp_inode == NULL) {
1773 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1774 if(*ptmp_inode == NULL)
1777 d_instantiate(tmp_dentry, *ptmp_inode);
1780 tmp_dentry = d_alloc(file->f_dentry, qstring);
1781 if(tmp_dentry == NULL) {
1782 cERROR(1,("Failed allocating dentry"));
1787 *ptmp_inode = new_inode(file->f_dentry->d_sb);
1788 tmp_dentry->d_op = &cifs_dentry_ops;
1789 if(*ptmp_inode == NULL)
1792 d_instantiate(tmp_dentry, *ptmp_inode);
1793 d_rehash(tmp_dentry);
1796 tmp_dentry->d_time = jiffies;
1797 *pnew_dentry = tmp_dentry;
1801 static void reset_resume_key(struct file * dir_file,
1802 unsigned char * filename,
1803 unsigned int len,int Unicode,struct nls_table * nls_tab) {
1804 struct cifsFileInfo *cifsFile;
1806 cifsFile = (struct cifsFileInfo *)dir_file->private_data;
1807 if(cifsFile == NULL)
1809 if(cifsFile->search_resume_name) {
1810 kfree(cifsFile->search_resume_name);
1815 cifsFile->resume_name_length = len;
1817 cifsFile->search_resume_name =
1818 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
1820 if(cifsFile->search_resume_name == NULL) {
1821 cERROR(1,("failed new resume key allocate, length %d",
1822 cifsFile->resume_name_length));
1826 cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
1827 filename, len, nls_tab);
1829 memcpy(cifsFile->search_resume_name, filename,
1830 cifsFile->resume_name_length);
1831 cFYI(1,("Reset resume key to: %s with len %d",filename,len));
1838 cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
1839 struct file *file, filldir_t filldir, void *direntry)
1841 struct inode *tmp_inode;
1842 struct dentry *tmp_dentry;
1845 pqstring->name = pfindData->FileName;
1846 /* pqstring->len is already set by caller */
1848 rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1849 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1852 fill_in_inode(tmp_inode, pfindData, &object_type);
1854 /* We have no reliable way to get inode numbers
1855 from servers w/o Unix extensions yet so we can not set
1856 i_ino from pfindData yet */
1858 /* new inode created, let us hash it */
1859 insert_inode_hash(tmp_inode);
1860 } /* else if inode number changed do we rehash it? */
1861 rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
1862 tmp_inode->i_ino, object_type);
1864 /* due to readdir error we need to recalculate resume
1865 key so next readdir will restart on right entry */
1866 cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
1873 cifs_filldir_unix(struct qstr *pqstring,
1874 FILE_UNIX_INFO * pUnixFindData, struct file *file,
1875 filldir_t filldir, void *direntry)
1877 struct inode *tmp_inode;
1878 struct dentry *tmp_dentry;
1879 int object_type, rc;
1881 pqstring->name = pUnixFindData->FileName;
1882 pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
1884 rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
1885 if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
1889 struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
1891 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
1893 (unsigned long)pUnixFindData->UniqueId;
1895 insert_inode_hash(tmp_inode);
1896 } /* else if i_ino has changed should we rehash it? */
1897 unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
1898 rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
1899 file->f_pos, tmp_inode->i_ino, object_type);
1901 /* due to readdir error we need to recalculate resume
1902 key so next readdir will restart on right entry */
1903 cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
1910 cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1914 int Unicode = FALSE;
1915 int UnixSearch = FALSE;
1916 unsigned int bufsize, i;
1918 struct cifs_sb_info *cifs_sb;
1919 struct cifsTconInfo *pTcon;
1920 struct cifsFileInfo *cifsFile = NULL;
1921 char *full_path = NULL;
1923 struct qstr qstring;
1924 T2_FFIRST_RSP_PARMS findParms;
1925 T2_FNEXT_RSP_PARMS findNextParms;
1926 FILE_DIRECTORY_INFO *pfindData;
1927 FILE_DIRECTORY_INFO *lastFindData;
1928 FILE_UNIX_INFO *pfindDataUnix;
1931 /* BB removeme begin */
1933 return cifs_readdir2(file,direntry,filldir);
1934 /* BB removeme end */
1939 if(file->f_dentry == NULL) {
1944 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
1945 pTcon = cifs_sb->tcon;
1946 bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
1947 if(bufsize > CIFSMaxBufSize) {
1952 data = kmalloc(bufsize, GFP_KERNEL);
1953 pfindData = (FILE_DIRECTORY_INFO *) data;
1959 down(&file->f_dentry->d_sb->s_vfs_rename_sem);
1960 full_path = build_wildcard_path_from_dentry(file->f_dentry);
1961 up(&file->f_dentry->d_sb->s_vfs_rename_sem);
1963 if(full_path == NULL) {
1968 cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
1970 switch ((int) file->f_pos) {
1972 if (filldir(direntry, ".", 1, file->f_pos,
1973 file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
1974 cERROR(1, ("Filldir for current dir failed "));
1980 if (filldir(direntry, "..", 2, file->f_pos,
1981 file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
1982 cERROR(1, ("Filldir for parent dir failed "));
1988 if (file->private_data != NULL) {
1990 (struct cifsFileInfo *) file->private_data;
1991 if (cifsFile->srch_inf.endOfSearch) {
1992 if(cifsFile->srch_inf.emptyDir) {
1993 cFYI(1, ("End of search, empty dir"));
1998 cifsFile->invalidHandle = TRUE;
1999 CIFSFindClose(xid, pTcon, cifsFile->netfid);
2001 if(cifsFile->search_resume_name) {
2002 kfree(cifsFile->search_resume_name);
2003 cifsFile->search_resume_name = NULL;
2006 rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
2007 &findParms, cifs_sb->local_nls,
2008 &Unicode, &UnixSearch);
2009 cFYI(1, ("Count: %d End: %d ",
2010 le16_to_cpu(findParms.SearchCount),
2011 le16_to_cpu(findParms.EndofSearch)));
2014 __u16 count = le16_to_cpu(findParms.SearchCount);
2015 searchHandle = findParms.SearchHandle;
2016 if(file->private_data == NULL)
2017 file->private_data =
2018 kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
2019 if (file->private_data) {
2020 memset(file->private_data, 0,
2021 sizeof (struct cifsFileInfo));
2023 (struct cifsFileInfo *) file->private_data;
2024 cifsFile->netfid = searchHandle;
2025 cifsFile->invalidHandle = FALSE;
2026 init_MUTEX(&cifsFile->fh_sem);
2032 renew_parental_timestamps(file->f_dentry);
2034 (FILE_DIRECTORY_INFO *) ((char *) pfindData +
2035 le16_to_cpu(findParms.LastNameOffset));
2036 if((char *)lastFindData > (char *)pfindData + bufsize) {
2037 cFYI(1,("last search entry past end of packet"));
2041 /* Offset of resume key same for levels 257 and 514 */
2042 cifsFile->srch_inf.resume_key = lastFindData->FileIndex;
2043 if(UnixSearch == FALSE) {
2044 cifsFile->resume_name_length =
2045 le32_to_cpu(lastFindData->FileNameLength);
2046 if(cifsFile->resume_name_length > bufsize - 64) {
2047 cFYI(1,("Illegal resume file name length %d",
2048 cifsFile->resume_name_length));
2052 cifsFile->search_resume_name =
2053 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
2054 cFYI(1,("Last file: %s with name %d bytes long",
2055 lastFindData->FileName,
2056 cifsFile->resume_name_length));
2057 if(cifsFile->search_resume_name == NULL) {
2061 memcpy(cifsFile->search_resume_name,
2062 lastFindData->FileName,
2063 cifsFile->resume_name_length);
2065 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
2066 if (Unicode == TRUE) {
2067 for(i=0;(pfindDataUnix->FileName[i]
2068 | pfindDataUnix->FileName[i+1]);
2073 cifsFile->resume_name_length = i + 2;
2075 cifsFile->resume_name_length =
2076 strnlen(pfindDataUnix->FileName,
2079 if(cifsFile->resume_name_length > bufsize - 64) {
2080 cFYI(1,("Illegal resume file name length %d",
2081 cifsFile->resume_name_length));
2085 cifsFile->search_resume_name =
2086 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
2087 cFYI(1,("Last file: %s with name %d bytes long",
2088 pfindDataUnix->FileName,
2089 cifsFile->resume_name_length));
2090 if(cifsFile->search_resume_name == NULL) {
2094 memcpy(cifsFile->search_resume_name,
2095 pfindDataUnix->FileName,
2096 cifsFile->resume_name_length);
2098 for (i = 2; i < count + 2; i++) {
2099 if (UnixSearch == FALSE) {
2100 __u32 len = le32_to_cpu(pfindData->FileNameLength);
2101 if (Unicode == TRUE)
2104 (pfindData->FileName,
2106 pfindData->FileName,
2108 cifs_sb->local_nls);
2111 || (pfindData->FileName[0] != '.'))
2116 FileName[1] != '.'))) {
2117 if(cifs_filldir(&qstring,
2121 /* do not end search if
2122 kernel not ready to take
2123 remaining entries yet */
2124 reset_resume_key(file, pfindData->FileName,qstring.len,
2125 Unicode, cifs_sb->local_nls);
2126 findParms.EndofSearch = 0;
2131 } else { /* UnixSearch */
2133 (FILE_UNIX_INFO *) pfindData;
2134 if (Unicode == TRUE)
2137 (pfindDataUnix->FileName,
2139 pfindDataUnix->FileName,
2141 cifs_sb->local_nls);
2144 strnlen(pfindDataUnix->
2147 if (((qstring.len != 1)
2149 FileName[0] != '.'))
2150 && ((qstring.len != 2)
2154 FileName[1] != '.'))) {
2155 if(cifs_filldir_unix(&qstring,
2160 /* do not end search if
2161 kernel not ready to take
2162 remaining entries yet */
2163 findParms.EndofSearch = 0;
2164 reset_resume_key(file, pfindDataUnix->FileName,
2165 qstring.len,Unicode,cifs_sb->local_nls);
2171 /* works also for Unix ff struct since first field of both */
2173 (FILE_DIRECTORY_INFO *) ((char *) pfindData
2174 + le32_to_cpu(pfindData->NextEntryOffset));
2175 /* BB also should check to make sure that pointer is not beyond the end of the SMB */
2176 /* if(pfindData > lastFindData) rc = -EIO; break; */
2177 } /* end for loop */
2178 if ((findParms.EndofSearch != 0) && cifsFile) {
2179 cifsFile->srch_inf.endOfSearch = TRUE;
2180 if(findParms.SearchCount == cpu_to_le16(2))
2181 cifsFile->srch_inf.emptyDir = TRUE;
2185 cifsFile->srch_inf.endOfSearch = TRUE;
2186 /* unless parent directory gone do not return error */
2191 if (file->private_data == NULL) {
2194 ("Readdir on closed srch, pos = %lld",
2197 cifsFile = (struct cifsFileInfo *) file->private_data;
2198 if (cifsFile->srch_inf.endOfSearch) {
2200 cFYI(1, ("End of search "));
2203 searchHandle = cifsFile->netfid;
2204 rc = CIFSFindNext(xid, pTcon, pfindData,
2205 &findNextParms, searchHandle,
2206 cifsFile->search_resume_name,
2207 cifsFile->resume_name_length,
2208 cifsFile->srch_inf.resume_key,
2209 &Unicode, &UnixSearch);
2210 cFYI(1,("Count: %d End: %d ",
2211 le16_to_cpu(findNextParms.SearchCount),
2212 le16_to_cpu(findNextParms.EndofSearch)));
2213 if ((rc == 0) && (findNextParms.SearchCount != 0)) {
2214 /* BB save off resume key, key name and name length */
2215 __u16 count = le16_to_cpu(findNextParms.SearchCount);
2217 (FILE_DIRECTORY_INFO *) ((char *) pfindData
2218 + le16_to_cpu(findNextParms.LastNameOffset));
2219 if((char *)lastFindData > (char *)pfindData + bufsize) {
2220 cFYI(1,("last search entry past end of packet"));
2224 /* Offset of resume key same for levels 257 and 514 */
2225 cifsFile->srch_inf.resume_key = lastFindData->FileIndex;
2227 if(UnixSearch == FALSE) {
2228 cifsFile->resume_name_length =
2229 le32_to_cpu(lastFindData->FileNameLength);
2230 if(cifsFile->resume_name_length > bufsize - 64) {
2231 cFYI(1,("Illegal resume file name length %d",
2232 cifsFile->resume_name_length));
2236 /* Free the memory allocated by previous findfirst
2237 or findnext call - we can not reuse the memory since
2238 the resume name may not be same string length */
2239 if(cifsFile->search_resume_name)
2240 kfree(cifsFile->search_resume_name);
2241 cifsFile->search_resume_name =
2242 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
2243 cFYI(1,("Last file: %s with name %d bytes long",
2244 lastFindData->FileName,
2245 cifsFile->resume_name_length));
2246 if(cifsFile->search_resume_name == NULL) {
2251 memcpy(cifsFile->search_resume_name,
2252 lastFindData->FileName,
2253 cifsFile->resume_name_length);
2255 pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
2256 if (Unicode == TRUE) {
2257 for(i=0;(pfindDataUnix->FileName[i]
2258 | pfindDataUnix->FileName[i+1]);
2263 cifsFile->resume_name_length = i + 2;
2265 cifsFile->resume_name_length =
2266 strnlen(pfindDataUnix->
2270 if(cifsFile->resume_name_length > bufsize - 64) {
2271 cFYI(1,("Illegal resume file name length %d",
2272 cifsFile->resume_name_length));
2276 /* Free the memory allocated by previous findfirst
2277 or findnext call - we can not reuse the memory since
2278 the resume name may not be same string length */
2279 if(cifsFile->search_resume_name)
2280 kfree(cifsFile->search_resume_name);
2281 cifsFile->search_resume_name =
2282 kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
2283 cFYI(1,("fnext last file: %s with name %d bytes long",
2284 pfindDataUnix->FileName,
2285 cifsFile->resume_name_length));
2286 if(cifsFile->search_resume_name == NULL) {
2290 memcpy(cifsFile->search_resume_name,
2291 pfindDataUnix->FileName,
2292 cifsFile->resume_name_length);
2295 for (i = 0; i < count; i++) {
2296 __u32 len = le32_to_cpu(pfindData->
2298 if (UnixSearch == FALSE) {
2299 if (Unicode == TRUE)
2302 (pfindData->FileName,
2304 pfindData->FileName,
2306 cifs_sb->local_nls);
2309 || (pfindData->FileName[0] != '.'))
2311 || (pfindData->FileName[0] != '.')
2312 || (pfindData->FileName[1] !=
2319 /* do not end search if
2320 kernel not ready to take
2321 remaining entries yet */
2322 findNextParms.EndofSearch = 0;
2323 reset_resume_key(file, pfindData->FileName,qstring.len,
2324 Unicode,cifs_sb->local_nls);
2329 } else { /* UnixSearch */
2333 if (Unicode == TRUE)
2336 (pfindDataUnix->FileName,
2338 pfindDataUnix->FileName,
2340 cifs_sb->local_nls);
2347 if (((qstring.len != 1)
2349 FileName[0] != '.'))
2350 && ((qstring.len != 2)
2356 if(cifs_filldir_unix
2361 /* do not end search if
2362 kernel not ready to take
2363 remaining entries yet */
2364 findNextParms.EndofSearch = 0;
2365 reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
2366 Unicode,cifs_sb->local_nls);
2372 pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData +
2373 le32_to_cpu(pfindData->NextEntryOffset));
2374 /* works also for Unix find struct since first field of both */
2375 /* BB also should check to ensure pointer not beyond end of SMB */
2376 } /* end for loop */
2377 if (findNextParms.EndofSearch != 0) {
2378 cifsFile->srch_inf.endOfSearch = TRUE;
2381 cifsFile->srch_inf.endOfSearch = TRUE;
2382 rc = 0; /* unless parent directory disappeared - do not
2383 return error here (eg Access Denied or no more files) */
2395 int cifs_prepare_write(struct file *file, struct page *page,
2396 unsigned from, unsigned to)
2399 loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
2400 cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
2401 if (!PageUptodate(page)) {
2402 /* if (to - from != PAGE_CACHE_SIZE) {
2403 void *kaddr = kmap_atomic(page, KM_USER0);
2404 memset(kaddr, 0, from);
2405 memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
2406 flush_dcache_page(page);
2407 kunmap_atomic(kaddr, KM_USER0);
2409 /* If we are writing a full page it will be up to date,
2410 no need to read from the server */
2411 if((to==PAGE_CACHE_SIZE) && (from == 0))
2412 SetPageUptodate(page);
2414 /* might as well read a page, it is fast enough */
2415 if((file->f_flags & O_ACCMODE) != O_WRONLY) {
2416 rc = cifs_readpage_worker(file,page,&offset);
2418 /* should we try using another
2419 file handle if there is one - how would we lock it
2420 to prevent close of that handle racing with this read? */
2421 /* In any case this will be written out by commit_write */
2425 /* BB should we pass any errors back? e.g. if we do not have read access to the file */
2430 struct address_space_operations cifs_addr_ops = {
2431 .readpage = cifs_readpage,
2432 .readpages = cifs_readpages,
2433 .writepage = cifs_writepage,
2434 .prepare_write = cifs_prepare_write,
2435 .commit_write = cifs_commit_write,
2436 .set_page_dirty = __set_page_dirty_nobuffers,
2437 /* .sync_page = cifs_sync_page, */