diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 287 |
1 files changed, 146 insertions, 141 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 94d5b49049df..e13592afca9c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * fs/cifs/file.c | 2 | * fs/cifs/file.c |
3 | * | 3 | * |
4 | * vfs operations that deal with files | 4 | * vfs operations that deal with files |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2002,2003 | 6 | * Copyright (C) International Business Machines Corp., 2002,2007 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * Jeremy Allison (jra@samba.org) | 8 | * Jeremy Allison (jra@samba.org) |
9 | * | 9 | * |
@@ -45,7 +45,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
45 | { | 45 | { |
46 | memset(private_data, 0, sizeof(struct cifsFileInfo)); | 46 | memset(private_data, 0, sizeof(struct cifsFileInfo)); |
47 | private_data->netfid = netfid; | 47 | private_data->netfid = netfid; |
48 | private_data->pid = current->tgid; | 48 | private_data->pid = current->tgid; |
49 | init_MUTEX(&private_data->fh_sem); | 49 | init_MUTEX(&private_data->fh_sem); |
50 | mutex_init(&private_data->lock_mutex); | 50 | mutex_init(&private_data->lock_mutex); |
51 | INIT_LIST_HEAD(&private_data->llist); | 51 | INIT_LIST_HEAD(&private_data->llist); |
@@ -57,7 +57,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
57 | does not tell us which handle the write is for so there can | 57 | does not tell us which handle the write is for so there can |
58 | be a close (overlapping with write) of the filehandle that | 58 | be a close (overlapping with write) of the filehandle that |
59 | cifs_writepages chose to use */ | 59 | cifs_writepages chose to use */ |
60 | atomic_set(&private_data->wrtPending,0); | 60 | atomic_set(&private_data->wrtPending, 0); |
61 | 61 | ||
62 | return private_data; | 62 | return private_data; |
63 | } | 63 | } |
@@ -105,7 +105,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
105 | in the list so we do not have to walk the | 105 | in the list so we do not have to walk the |
106 | list to search for one in prepare_write */ | 106 | list to search for one in prepare_write */ |
107 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { | 107 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) { |
108 | list_add_tail(&pCifsFile->flist, | 108 | list_add_tail(&pCifsFile->flist, |
109 | &pCifsInode->openFileList); | 109 | &pCifsInode->openFileList); |
110 | } else { | 110 | } else { |
111 | list_add(&pCifsFile->flist, | 111 | list_add(&pCifsFile->flist, |
@@ -138,7 +138,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
138 | } | 138 | } |
139 | 139 | ||
140 | client_can_cache: | 140 | client_can_cache: |
141 | if (pTcon->ses->capabilities & CAP_UNIX) | 141 | if (pTcon->unix_ext) |
142 | rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, | 142 | rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, |
143 | full_path, inode->i_sb, xid); | 143 | full_path, inode->i_sb, xid); |
144 | else | 144 | else |
@@ -189,7 +189,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
189 | 189 | ||
190 | /* needed for writepage */ | 190 | /* needed for writepage */ |
191 | pCifsFile->pfile = file; | 191 | pCifsFile->pfile = file; |
192 | 192 | ||
193 | file->private_data = pCifsFile; | 193 | file->private_data = pCifsFile; |
194 | break; | 194 | break; |
195 | } | 195 | } |
@@ -212,15 +212,15 @@ int cifs_open(struct inode *inode, struct file *file) | |||
212 | return -ENOMEM; | 212 | return -ENOMEM; |
213 | } | 213 | } |
214 | 214 | ||
215 | cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", | 215 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", |
216 | inode, file->f_flags, full_path)); | 216 | inode, file->f_flags, full_path)); |
217 | desiredAccess = cifs_convert_flags(file->f_flags); | 217 | desiredAccess = cifs_convert_flags(file->f_flags); |
218 | 218 | ||
219 | /********************************************************************* | 219 | /********************************************************************* |
220 | * open flag mapping table: | 220 | * open flag mapping table: |
221 | * | 221 | * |
222 | * POSIX Flag CIFS Disposition | 222 | * POSIX Flag CIFS Disposition |
223 | * ---------- ---------------- | 223 | * ---------- ---------------- |
224 | * O_CREAT FILE_OPEN_IF | 224 | * O_CREAT FILE_OPEN_IF |
225 | * O_CREAT | O_EXCL FILE_CREATE | 225 | * O_CREAT | O_EXCL FILE_CREATE |
226 | * O_CREAT | O_TRUNC FILE_OVERWRITE_IF | 226 | * O_CREAT | O_TRUNC FILE_OVERWRITE_IF |
@@ -228,12 +228,12 @@ int cifs_open(struct inode *inode, struct file *file) | |||
228 | * none of the above FILE_OPEN | 228 | * none of the above FILE_OPEN |
229 | * | 229 | * |
230 | * Note that there is not a direct match between disposition | 230 | * Note that there is not a direct match between disposition |
231 | * FILE_SUPERSEDE (ie create whether or not file exists although | 231 | * FILE_SUPERSEDE (ie create whether or not file exists although |
232 | * O_CREAT | O_TRUNC is similar but truncates the existing | 232 | * O_CREAT | O_TRUNC is similar but truncates the existing |
233 | * file rather than creating a new file as FILE_SUPERSEDE does | 233 | * file rather than creating a new file as FILE_SUPERSEDE does |
234 | * (which uses the attributes / metadata passed in on open call) | 234 | * (which uses the attributes / metadata passed in on open call) |
235 | *? | 235 | *? |
236 | *? O_SYNC is a reasonable match to CIFS writethrough flag | 236 | *? O_SYNC is a reasonable match to CIFS writethrough flag |
237 | *? and the read write flags match reasonably. O_LARGEFILE | 237 | *? and the read write flags match reasonably. O_LARGEFILE |
238 | *? is irrelevant because largefile support is always used | 238 | *? is irrelevant because largefile support is always used |
239 | *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, | 239 | *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY, |
@@ -253,8 +253,8 @@ int cifs_open(struct inode *inode, struct file *file) | |||
253 | and calling get_inode_info with returned buf (at least helps | 253 | and calling get_inode_info with returned buf (at least helps |
254 | non-Unix server case) */ | 254 | non-Unix server case) */ |
255 | 255 | ||
256 | /* BB we can not do this if this is the second open of a file | 256 | /* BB we can not do this if this is the second open of a file |
257 | and the first handle has writebehind data, we might be | 257 | and the first handle has writebehind data, we might be |
258 | able to simply do a filemap_fdatawrite/filemap_fdatawait first */ | 258 | able to simply do a filemap_fdatawrite/filemap_fdatawait first */ |
259 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 259 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
260 | if (!buf) { | 260 | if (!buf) { |
@@ -263,7 +263,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
263 | } | 263 | } |
264 | 264 | ||
265 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) | 265 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
266 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 266 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
267 | desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, | 267 | desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf, |
268 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags | 268 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags |
269 | & CIFS_MOUNT_MAP_SPECIAL_CHR); | 269 | & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -300,15 +300,15 @@ int cifs_open(struct inode *inode, struct file *file) | |||
300 | write_unlock(&GlobalSMBSeslock); | 300 | write_unlock(&GlobalSMBSeslock); |
301 | } | 301 | } |
302 | 302 | ||
303 | if (oplock & CIFS_CREATE_ACTION) { | 303 | if (oplock & CIFS_CREATE_ACTION) { |
304 | /* time to set mode which we can not set earlier due to | 304 | /* time to set mode which we can not set earlier due to |
305 | problems creating new read-only files */ | 305 | problems creating new read-only files */ |
306 | if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) { | 306 | if (pTcon->unix_ext) { |
307 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 307 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
308 | inode->i_mode, | 308 | inode->i_mode, |
309 | (__u64)-1, (__u64)-1, 0 /* dev */, | 309 | (__u64)-1, (__u64)-1, 0 /* dev */, |
310 | cifs_sb->local_nls, | 310 | cifs_sb->local_nls, |
311 | cifs_sb->mnt_cifs_flags & | 311 | cifs_sb->mnt_cifs_flags & |
312 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 312 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
313 | } else { | 313 | } else { |
314 | /* BB implement via Windows security descriptors eg | 314 | /* BB implement via Windows security descriptors eg |
@@ -345,7 +345,7 @@ static int cifs_reopen_file(struct file *file, int can_flush) | |||
345 | struct cifsTconInfo *pTcon; | 345 | struct cifsTconInfo *pTcon; |
346 | struct cifsFileInfo *pCifsFile; | 346 | struct cifsFileInfo *pCifsFile; |
347 | struct cifsInodeInfo *pCifsInode; | 347 | struct cifsInodeInfo *pCifsInode; |
348 | struct inode * inode; | 348 | struct inode *inode; |
349 | char *full_path = NULL; | 349 | char *full_path = NULL; |
350 | int desiredAccess; | 350 | int desiredAccess; |
351 | int disposition = FILE_OPEN; | 351 | int disposition = FILE_OPEN; |
@@ -372,13 +372,13 @@ static int cifs_reopen_file(struct file *file, int can_flush) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | inode = file->f_path.dentry->d_inode; | 374 | inode = file->f_path.dentry->d_inode; |
375 | if(inode == NULL) { | 375 | if (inode == NULL) { |
376 | cERROR(1, ("inode not valid")); | 376 | cERROR(1, ("inode not valid")); |
377 | dump_stack(); | 377 | dump_stack(); |
378 | rc = -EBADF; | 378 | rc = -EBADF; |
379 | goto reopen_error_exit; | 379 | goto reopen_error_exit; |
380 | } | 380 | } |
381 | 381 | ||
382 | cifs_sb = CIFS_SB(inode->i_sb); | 382 | cifs_sb = CIFS_SB(inode->i_sb); |
383 | pTcon = cifs_sb->tcon; | 383 | pTcon = cifs_sb->tcon; |
384 | 384 | ||
@@ -396,7 +396,7 @@ reopen_error_exit: | |||
396 | } | 396 | } |
397 | 397 | ||
398 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", | 398 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", |
399 | inode, file->f_flags,full_path)); | 399 | inode, file->f_flags, full_path)); |
400 | desiredAccess = cifs_convert_flags(file->f_flags); | 400 | desiredAccess = cifs_convert_flags(file->f_flags); |
401 | 401 | ||
402 | if (oplockEnabled) | 402 | if (oplockEnabled) |
@@ -405,14 +405,14 @@ reopen_error_exit: | |||
405 | oplock = FALSE; | 405 | oplock = FALSE; |
406 | 406 | ||
407 | /* Can not refresh inode by passing in file_info buf to be returned | 407 | /* Can not refresh inode by passing in file_info buf to be returned |
408 | by SMBOpen and then calling get_inode_info with returned buf | 408 | by SMBOpen and then calling get_inode_info with returned buf |
409 | since file might have write behind data that needs to be flushed | 409 | since file might have write behind data that needs to be flushed |
410 | and server version of file size can be stale. If we knew for sure | 410 | and server version of file size can be stale. If we knew for sure |
411 | that inode was not dirty locally we could do this */ | 411 | that inode was not dirty locally we could do this */ |
412 | 412 | ||
413 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 413 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
414 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 414 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
415 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 415 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
416 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 416 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
417 | if (rc) { | 417 | if (rc) { |
418 | up(&pCifsFile->fh_sem); | 418 | up(&pCifsFile->fh_sem); |
@@ -430,7 +430,7 @@ reopen_error_exit: | |||
430 | go to server to get inode info */ | 430 | go to server to get inode info */ |
431 | pCifsInode->clientCanCacheAll = FALSE; | 431 | pCifsInode->clientCanCacheAll = FALSE; |
432 | pCifsInode->clientCanCacheRead = FALSE; | 432 | pCifsInode->clientCanCacheRead = FALSE; |
433 | if (pTcon->ses->capabilities & CAP_UNIX) | 433 | if (pTcon->unix_ext) |
434 | rc = cifs_get_inode_info_unix(&inode, | 434 | rc = cifs_get_inode_info_unix(&inode, |
435 | full_path, inode->i_sb, xid); | 435 | full_path, inode->i_sb, xid); |
436 | else | 436 | else |
@@ -486,23 +486,24 @@ int cifs_close(struct inode *inode, struct file *file) | |||
486 | already closed */ | 486 | already closed */ |
487 | if (pTcon->tidStatus != CifsNeedReconnect) { | 487 | if (pTcon->tidStatus != CifsNeedReconnect) { |
488 | int timeout = 2; | 488 | int timeout = 2; |
489 | while((atomic_read(&pSMBFile->wrtPending) != 0) | 489 | while ((atomic_read(&pSMBFile->wrtPending) != 0) |
490 | && (timeout < 1000) ) { | 490 | && (timeout < 1000) ) { |
491 | /* Give write a better chance to get to | 491 | /* Give write a better chance to get to |
492 | server ahead of the close. We do not | 492 | server ahead of the close. We do not |
493 | want to add a wait_q here as it would | 493 | want to add a wait_q here as it would |
494 | increase the memory utilization as | 494 | increase the memory utilization as |
495 | the struct would be in each open file, | 495 | the struct would be in each open file, |
496 | but this should give enough time to | 496 | but this should give enough time to |
497 | clear the socket */ | 497 | clear the socket */ |
498 | #ifdef CONFIG_CIFS_DEBUG2 | 498 | #ifdef CONFIG_CIFS_DEBUG2 |
499 | cFYI(1,("close delay, write pending")); | 499 | cFYI(1, ("close delay, write pending")); |
500 | #endif /* DEBUG2 */ | 500 | #endif /* DEBUG2 */ |
501 | msleep(timeout); | 501 | msleep(timeout); |
502 | timeout *= 4; | 502 | timeout *= 4; |
503 | } | 503 | } |
504 | if(atomic_read(&pSMBFile->wrtPending)) | 504 | if (atomic_read(&pSMBFile->wrtPending)) |
505 | cERROR(1,("close with pending writes")); | 505 | cERROR(1, |
506 | ("close with pending writes")); | ||
506 | rc = CIFSSMBClose(xid, pTcon, | 507 | rc = CIFSSMBClose(xid, pTcon, |
507 | pSMBFile->netfid); | 508 | pSMBFile->netfid); |
508 | } | 509 | } |
@@ -534,7 +535,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
534 | CIFS_I(inode)->clientCanCacheRead = FALSE; | 535 | CIFS_I(inode)->clientCanCacheRead = FALSE; |
535 | CIFS_I(inode)->clientCanCacheAll = FALSE; | 536 | CIFS_I(inode)->clientCanCacheAll = FALSE; |
536 | } | 537 | } |
537 | if ((rc ==0) && CIFS_I(inode)->write_behind_rc) | 538 | if ((rc == 0) && CIFS_I(inode)->write_behind_rc) |
538 | rc = CIFS_I(inode)->write_behind_rc; | 539 | rc = CIFS_I(inode)->write_behind_rc; |
539 | FreeXid(xid); | 540 | FreeXid(xid); |
540 | return rc; | 541 | return rc; |
@@ -554,7 +555,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
554 | 555 | ||
555 | if (pCFileStruct) { | 556 | if (pCFileStruct) { |
556 | struct cifsTconInfo *pTcon; | 557 | struct cifsTconInfo *pTcon; |
557 | struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 558 | struct cifs_sb_info *cifs_sb = |
559 | CIFS_SB(file->f_path.dentry->d_sb); | ||
558 | 560 | ||
559 | pTcon = cifs_sb->tcon; | 561 | pTcon = cifs_sb->tcon; |
560 | 562 | ||
@@ -572,7 +574,7 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
572 | if (ptmp) { | 574 | if (ptmp) { |
573 | cFYI(1, ("closedir free smb buf in srch struct")); | 575 | cFYI(1, ("closedir free smb buf in srch struct")); |
574 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; | 576 | pCFileStruct->srch_inf.ntwrk_buf_start = NULL; |
575 | if(pCFileStruct->srch_inf.smallBuf) | 577 | if (pCFileStruct->srch_inf.smallBuf) |
576 | cifs_small_buf_release(ptmp); | 578 | cifs_small_buf_release(ptmp); |
577 | else | 579 | else |
578 | cifs_buf_release(ptmp); | 580 | cifs_buf_release(ptmp); |
@@ -594,7 +596,8 @@ int cifs_closedir(struct inode *inode, struct file *file) | |||
594 | static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | 596 | static int store_file_lock(struct cifsFileInfo *fid, __u64 len, |
595 | __u64 offset, __u8 lockType) | 597 | __u64 offset, __u8 lockType) |
596 | { | 598 | { |
597 | struct cifsLockInfo *li = kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); | 599 | struct cifsLockInfo *li = |
600 | kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); | ||
598 | if (li == NULL) | 601 | if (li == NULL) |
599 | return -ENOMEM; | 602 | return -ENOMEM; |
600 | li->offset = offset; | 603 | li->offset = offset; |
@@ -625,8 +628,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
625 | 628 | ||
626 | cFYI(1, ("Lock parm: 0x%x flockflags: " | 629 | cFYI(1, ("Lock parm: 0x%x flockflags: " |
627 | "0x%x flocktype: 0x%x start: %lld end: %lld", | 630 | "0x%x flocktype: 0x%x start: %lld end: %lld", |
628 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, | 631 | cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, |
629 | pfLock->fl_end)); | 632 | pfLock->fl_end)); |
630 | 633 | ||
631 | if (pfLock->fl_flags & FL_POSIX) | 634 | if (pfLock->fl_flags & FL_POSIX) |
632 | cFYI(1, ("Posix")); | 635 | cFYI(1, ("Posix")); |
@@ -641,7 +644,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
641 | "not implemented yet")); | 644 | "not implemented yet")); |
642 | if (pfLock->fl_flags & FL_LEASE) | 645 | if (pfLock->fl_flags & FL_LEASE) |
643 | cFYI(1, ("Lease on file - not implemented yet")); | 646 | cFYI(1, ("Lease on file - not implemented yet")); |
644 | if (pfLock->fl_flags & | 647 | if (pfLock->fl_flags & |
645 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) | 648 | (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) |
646 | cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); | 649 | cFYI(1, ("Unknown lock flags 0x%x", pfLock->fl_flags)); |
647 | 650 | ||
@@ -683,9 +686,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
683 | account for negative length which we can not accept over the | 686 | account for negative length which we can not accept over the |
684 | wire */ | 687 | wire */ |
685 | if (IS_GETLK(cmd)) { | 688 | if (IS_GETLK(cmd)) { |
686 | if(posix_locking) { | 689 | if (posix_locking) { |
687 | int posix_lock_type; | 690 | int posix_lock_type; |
688 | if(lockType & LOCKING_ANDX_SHARED_LOCK) | 691 | if (lockType & LOCKING_ANDX_SHARED_LOCK) |
689 | posix_lock_type = CIFS_RDLCK; | 692 | posix_lock_type = CIFS_RDLCK; |
690 | else | 693 | else |
691 | posix_lock_type = CIFS_WRLCK; | 694 | posix_lock_type = CIFS_WRLCK; |
@@ -700,7 +703,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
700 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 703 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, |
701 | 0, 1, lockType, 0 /* wait flag */ ); | 704 | 0, 1, lockType, 0 /* wait flag */ ); |
702 | if (rc == 0) { | 705 | if (rc == 0) { |
703 | rc = CIFSSMBLock(xid, pTcon, netfid, length, | 706 | rc = CIFSSMBLock(xid, pTcon, netfid, length, |
704 | pfLock->fl_start, 1 /* numUnlock */ , | 707 | pfLock->fl_start, 1 /* numUnlock */ , |
705 | 0 /* numLock */ , lockType, | 708 | 0 /* numLock */ , lockType, |
706 | 0 /* wait flag */ ); | 709 | 0 /* wait flag */ ); |
@@ -729,22 +732,24 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
729 | 732 | ||
730 | if (posix_locking) { | 733 | if (posix_locking) { |
731 | int posix_lock_type; | 734 | int posix_lock_type; |
732 | if(lockType & LOCKING_ANDX_SHARED_LOCK) | 735 | if (lockType & LOCKING_ANDX_SHARED_LOCK) |
733 | posix_lock_type = CIFS_RDLCK; | 736 | posix_lock_type = CIFS_RDLCK; |
734 | else | 737 | else |
735 | posix_lock_type = CIFS_WRLCK; | 738 | posix_lock_type = CIFS_WRLCK; |
736 | 739 | ||
737 | if(numUnlock == 1) | 740 | if (numUnlock == 1) |
738 | posix_lock_type = CIFS_UNLCK; | 741 | posix_lock_type = CIFS_UNLCK; |
739 | 742 | ||
740 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | 743 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, |
741 | length, pfLock, | 744 | length, pfLock, |
742 | posix_lock_type, wait_flag); | 745 | posix_lock_type, wait_flag); |
743 | } else { | 746 | } else { |
744 | struct cifsFileInfo *fid = (struct cifsFileInfo *)file->private_data; | 747 | struct cifsFileInfo *fid = |
748 | (struct cifsFileInfo *)file->private_data; | ||
745 | 749 | ||
746 | if (numLock) { | 750 | if (numLock) { |
747 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 751 | rc = CIFSSMBLock(xid, pTcon, netfid, length, |
752 | pfLock->fl_start, | ||
748 | 0, numLock, lockType, wait_flag); | 753 | 0, numLock, lockType, wait_flag); |
749 | 754 | ||
750 | if (rc == 0) { | 755 | if (rc == 0) { |
@@ -763,7 +768,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
763 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 768 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { |
764 | if (pfLock->fl_start <= li->offset && | 769 | if (pfLock->fl_start <= li->offset && |
765 | length >= li->length) { | 770 | length >= li->length) { |
766 | stored_rc = CIFSSMBLock(xid, pTcon, netfid, | 771 | stored_rc = CIFSSMBLock(xid, pTcon, |
772 | netfid, | ||
767 | li->length, li->offset, | 773 | li->length, li->offset, |
768 | 1, 0, li->type, FALSE); | 774 | 1, 0, li->type, FALSE); |
769 | if (stored_rc) | 775 | if (stored_rc) |
@@ -805,7 +811,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
805 | if (file->private_data == NULL) | 811 | if (file->private_data == NULL) |
806 | return -EBADF; | 812 | return -EBADF; |
807 | open_file = (struct cifsFileInfo *) file->private_data; | 813 | open_file = (struct cifsFileInfo *) file->private_data; |
808 | 814 | ||
809 | xid = GetXid(); | 815 | xid = GetXid(); |
810 | 816 | ||
811 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 817 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
@@ -824,7 +830,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
824 | and blocked, and the file has been freed on us while | 830 | and blocked, and the file has been freed on us while |
825 | we blocked so return what we managed to write */ | 831 | we blocked so return what we managed to write */ |
826 | return total_written; | 832 | return total_written; |
827 | } | 833 | } |
828 | if (open_file->closePend) { | 834 | if (open_file->closePend) { |
829 | FreeXid(xid); | 835 | FreeXid(xid); |
830 | if (total_written) | 836 | if (total_written) |
@@ -867,8 +873,8 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
867 | /* since the write may have blocked check these pointers again */ | 873 | /* since the write may have blocked check these pointers again */ |
868 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { | 874 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { |
869 | struct inode *inode = file->f_path.dentry->d_inode; | 875 | struct inode *inode = file->f_path.dentry->d_inode; |
870 | /* Do not update local mtime - server will set its actual value on write | 876 | /* Do not update local mtime - server will set its actual value on write |
871 | * inode->i_ctime = inode->i_mtime = | 877 | * inode->i_ctime = inode->i_mtime = |
872 | * current_fs_time(inode->i_sb);*/ | 878 | * current_fs_time(inode->i_sb);*/ |
873 | if (total_written > 0) { | 879 | if (total_written > 0) { |
874 | spin_lock(&inode->i_lock); | 880 | spin_lock(&inode->i_lock); |
@@ -877,7 +883,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
877 | *poffset); | 883 | *poffset); |
878 | spin_unlock(&inode->i_lock); | 884 | spin_unlock(&inode->i_lock); |
879 | } | 885 | } |
880 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); | 886 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); |
881 | } | 887 | } |
882 | FreeXid(xid); | 888 | FreeXid(xid); |
883 | return total_written; | 889 | return total_written; |
@@ -898,13 +904,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
898 | 904 | ||
899 | pTcon = cifs_sb->tcon; | 905 | pTcon = cifs_sb->tcon; |
900 | 906 | ||
901 | cFYI(1,("write %zd bytes to offset %lld of %s", write_size, | 907 | cFYI(1, ("write %zd bytes to offset %lld of %s", write_size, |
902 | *poffset, file->f_path.dentry->d_name.name)); | 908 | *poffset, file->f_path.dentry->d_name.name)); |
903 | 909 | ||
904 | if (file->private_data == NULL) | 910 | if (file->private_data == NULL) |
905 | return -EBADF; | 911 | return -EBADF; |
906 | open_file = (struct cifsFileInfo *)file->private_data; | 912 | open_file = (struct cifsFileInfo *)file->private_data; |
907 | 913 | ||
908 | xid = GetXid(); | 914 | xid = GetXid(); |
909 | 915 | ||
910 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 916 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
@@ -921,10 +927,10 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
921 | FreeXid(xid); | 927 | FreeXid(xid); |
922 | /* if we have gotten here we have written some data | 928 | /* if we have gotten here we have written some data |
923 | and blocked, and the file has been freed on us | 929 | and blocked, and the file has been freed on us |
924 | while we blocked so return what we managed to | 930 | while we blocked so return what we managed to |
925 | write */ | 931 | write */ |
926 | return total_written; | 932 | return total_written; |
927 | } | 933 | } |
928 | if (open_file->closePend) { | 934 | if (open_file->closePend) { |
929 | FreeXid(xid); | 935 | FreeXid(xid); |
930 | if (total_written) | 936 | if (total_written) |
@@ -935,14 +941,14 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
935 | if (open_file->invalidHandle) { | 941 | if (open_file->invalidHandle) { |
936 | /* we could deadlock if we called | 942 | /* we could deadlock if we called |
937 | filemap_fdatawait from here so tell | 943 | filemap_fdatawait from here so tell |
938 | reopen_file not to flush data to | 944 | reopen_file not to flush data to |
939 | server now */ | 945 | server now */ |
940 | rc = cifs_reopen_file(file, FALSE); | 946 | rc = cifs_reopen_file(file, FALSE); |
941 | if (rc != 0) | 947 | if (rc != 0) |
942 | break; | 948 | break; |
943 | } | 949 | } |
944 | if(experimEnabled || (pTcon->ses->server && | 950 | if (experimEnabled || (pTcon->ses->server && |
945 | ((pTcon->ses->server->secMode & | 951 | ((pTcon->ses->server->secMode & |
946 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 952 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
947 | == 0))) { | 953 | == 0))) { |
948 | struct kvec iov[2]; | 954 | struct kvec iov[2]; |
@@ -976,7 +982,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
976 | } | 982 | } |
977 | } else | 983 | } else |
978 | *poffset += bytes_written; | 984 | *poffset += bytes_written; |
979 | long_op = FALSE; /* subsequent writes fast - | 985 | long_op = FALSE; /* subsequent writes fast - |
980 | 15 seconds is plenty */ | 986 | 15 seconds is plenty */ |
981 | } | 987 | } |
982 | 988 | ||
@@ -1009,8 +1015,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1009 | the VFS or MM) should not happen but we had reports of on oops (due to | 1015 | the VFS or MM) should not happen but we had reports of on oops (due to |
1010 | it being zero) during stress testcases so we need to check for it */ | 1016 | it being zero) during stress testcases so we need to check for it */ |
1011 | 1017 | ||
1012 | if(cifs_inode == NULL) { | 1018 | if (cifs_inode == NULL) { |
1013 | cERROR(1,("Null inode passed to cifs_writeable_file")); | 1019 | cERROR(1, ("Null inode passed to cifs_writeable_file")); |
1014 | dump_stack(); | 1020 | dump_stack(); |
1015 | return NULL; | 1021 | return NULL; |
1016 | } | 1022 | } |
@@ -1024,13 +1030,14 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1024 | (open_file->pfile->f_flags & O_WRONLY))) { | 1030 | (open_file->pfile->f_flags & O_WRONLY))) { |
1025 | atomic_inc(&open_file->wrtPending); | 1031 | atomic_inc(&open_file->wrtPending); |
1026 | read_unlock(&GlobalSMBSeslock); | 1032 | read_unlock(&GlobalSMBSeslock); |
1027 | if((open_file->invalidHandle) && | 1033 | if ((open_file->invalidHandle) && |
1028 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { | 1034 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { |
1029 | rc = cifs_reopen_file(open_file->pfile, FALSE); | 1035 | rc = cifs_reopen_file(open_file->pfile, FALSE); |
1030 | /* if it fails, try another handle - might be */ | 1036 | /* if it fails, try another handle - might be */ |
1031 | /* dangerous to hold up writepages with retry */ | 1037 | /* dangerous to hold up writepages with retry */ |
1032 | if(rc) { | 1038 | if (rc) { |
1033 | cFYI(1,("failed on reopen file in wp")); | 1039 | cFYI(1, |
1040 | ("failed on reopen file in wp")); | ||
1034 | read_lock(&GlobalSMBSeslock); | 1041 | read_lock(&GlobalSMBSeslock); |
1035 | /* can not use this handle, no write | 1042 | /* can not use this handle, no write |
1036 | pending on this one after all */ | 1043 | pending on this one after all */ |
@@ -1082,7 +1089,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) | |||
1082 | 1089 | ||
1083 | /* check to make sure that we are not extending the file */ | 1090 | /* check to make sure that we are not extending the file */ |
1084 | if (mapping->host->i_size - offset < (loff_t)to) | 1091 | if (mapping->host->i_size - offset < (loff_t)to) |
1085 | to = (unsigned)(mapping->host->i_size - offset); | 1092 | to = (unsigned)(mapping->host->i_size - offset); |
1086 | 1093 | ||
1087 | open_file = find_writable_file(CIFS_I(mapping->host)); | 1094 | open_file = find_writable_file(CIFS_I(mapping->host)); |
1088 | if (open_file) { | 1095 | if (open_file) { |
@@ -1116,8 +1123,8 @@ static int cifs_writepages(struct address_space *mapping, | |||
1116 | int done = 0; | 1123 | int done = 0; |
1117 | pgoff_t end; | 1124 | pgoff_t end; |
1118 | pgoff_t index; | 1125 | pgoff_t index; |
1119 | int range_whole = 0; | 1126 | int range_whole = 0; |
1120 | struct kvec * iov; | 1127 | struct kvec *iov; |
1121 | int len; | 1128 | int len; |
1122 | int n_iov = 0; | 1129 | int n_iov = 0; |
1123 | pgoff_t next; | 1130 | pgoff_t next; |
@@ -1131,7 +1138,7 @@ static int cifs_writepages(struct address_space *mapping, | |||
1131 | int xid; | 1138 | int xid; |
1132 | 1139 | ||
1133 | cifs_sb = CIFS_SB(mapping->host->i_sb); | 1140 | cifs_sb = CIFS_SB(mapping->host->i_sb); |
1134 | 1141 | ||
1135 | /* | 1142 | /* |
1136 | * If wsize is smaller that the page cache size, default to writing | 1143 | * If wsize is smaller that the page cache size, default to writing |
1137 | * one page at a time via cifs_writepage | 1144 | * one page at a time via cifs_writepage |
@@ -1139,14 +1146,14 @@ static int cifs_writepages(struct address_space *mapping, | |||
1139 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) | 1146 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) |
1140 | return generic_writepages(mapping, wbc); | 1147 | return generic_writepages(mapping, wbc); |
1141 | 1148 | ||
1142 | if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) | 1149 | if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) |
1143 | if(cifs_sb->tcon->ses->server->secMode & | 1150 | if (cifs_sb->tcon->ses->server->secMode & |
1144 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 1151 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
1145 | if(!experimEnabled) | 1152 | if (!experimEnabled) |
1146 | return generic_writepages(mapping, wbc); | 1153 | return generic_writepages(mapping, wbc); |
1147 | 1154 | ||
1148 | iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); | 1155 | iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); |
1149 | if(iov == NULL) | 1156 | if (iov == NULL) |
1150 | return generic_writepages(mapping, wbc); | 1157 | return generic_writepages(mapping, wbc); |
1151 | 1158 | ||
1152 | 1159 | ||
@@ -1279,7 +1286,7 @@ retry: | |||
1279 | 1); | 1286 | 1); |
1280 | atomic_dec(&open_file->wrtPending); | 1287 | atomic_dec(&open_file->wrtPending); |
1281 | if (rc || bytes_written < bytes_to_write) { | 1288 | if (rc || bytes_written < bytes_to_write) { |
1282 | cERROR(1,("Write2 ret %d, written = %d", | 1289 | cERROR(1, ("Write2 ret %d, wrote %d", |
1283 | rc, bytes_written)); | 1290 | rc, bytes_written)); |
1284 | /* BB what if continued retry is | 1291 | /* BB what if continued retry is |
1285 | requested via mount flags? */ | 1292 | requested via mount flags? */ |
@@ -1295,8 +1302,8 @@ retry: | |||
1295 | success rc but too little data written? */ | 1302 | success rc but too little data written? */ |
1296 | /* BB investigate retry logic on temporary | 1303 | /* BB investigate retry logic on temporary |
1297 | server crash cases and how recovery works | 1304 | server crash cases and how recovery works |
1298 | when page marked as error */ | 1305 | when page marked as error */ |
1299 | if(rc) | 1306 | if (rc) |
1300 | SetPageError(page); | 1307 | SetPageError(page); |
1301 | kunmap(page); | 1308 | kunmap(page); |
1302 | unlock_page(page); | 1309 | unlock_page(page); |
@@ -1326,7 +1333,7 @@ retry: | |||
1326 | return rc; | 1333 | return rc; |
1327 | } | 1334 | } |
1328 | 1335 | ||
1329 | static int cifs_writepage(struct page* page, struct writeback_control *wbc) | 1336 | static int cifs_writepage(struct page *page, struct writeback_control *wbc) |
1330 | { | 1337 | { |
1331 | int rc = -EFAULT; | 1338 | int rc = -EFAULT; |
1332 | int xid; | 1339 | int xid; |
@@ -1334,7 +1341,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc) | |||
1334 | xid = GetXid(); | 1341 | xid = GetXid(); |
1335 | /* BB add check for wbc flags */ | 1342 | /* BB add check for wbc flags */ |
1336 | page_cache_get(page); | 1343 | page_cache_get(page); |
1337 | if (!PageUptodate(page)) { | 1344 | if (!PageUptodate(page)) { |
1338 | cFYI(1, ("ppw - page not up to date")); | 1345 | cFYI(1, ("ppw - page not up to date")); |
1339 | } | 1346 | } |
1340 | 1347 | ||
@@ -1348,7 +1355,7 @@ static int cifs_writepage(struct page* page, struct writeback_control *wbc) | |||
1348 | * Just unlocking the page will cause the radix tree tag-bits | 1355 | * Just unlocking the page will cause the radix tree tag-bits |
1349 | * to fail to update with the state of the page correctly. | 1356 | * to fail to update with the state of the page correctly. |
1350 | */ | 1357 | */ |
1351 | set_page_writeback(page); | 1358 | set_page_writeback(page); |
1352 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); | 1359 | rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE); |
1353 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ | 1360 | SetPageUptodate(page); /* BB add check for error and Clearuptodate? */ |
1354 | unlock_page(page); | 1361 | unlock_page(page); |
@@ -1368,7 +1375,7 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1368 | char *page_data; | 1375 | char *page_data; |
1369 | 1376 | ||
1370 | xid = GetXid(); | 1377 | xid = GetXid(); |
1371 | cFYI(1, ("commit write for page %p up to position %lld for %d", | 1378 | cFYI(1, ("commit write for page %p up to position %lld for %d", |
1372 | page, position, to)); | 1379 | page, position, to)); |
1373 | spin_lock(&inode->i_lock); | 1380 | spin_lock(&inode->i_lock); |
1374 | if (position > inode->i_size) { | 1381 | if (position > inode->i_size) { |
@@ -1396,7 +1403,7 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1396 | rc = 0; | 1403 | rc = 0; |
1397 | /* else if (rc < 0) should we set writebehind rc? */ | 1404 | /* else if (rc < 0) should we set writebehind rc? */ |
1398 | kunmap(page); | 1405 | kunmap(page); |
1399 | } else { | 1406 | } else { |
1400 | set_page_dirty(page); | 1407 | set_page_dirty(page); |
1401 | } | 1408 | } |
1402 | 1409 | ||
@@ -1412,9 +1419,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1412 | 1419 | ||
1413 | xid = GetXid(); | 1420 | xid = GetXid(); |
1414 | 1421 | ||
1415 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", | 1422 | cFYI(1, ("Sync file - name: %s datasync: 0x%x", |
1416 | dentry->d_name.name, datasync)); | 1423 | dentry->d_name.name, datasync)); |
1417 | 1424 | ||
1418 | rc = filemap_fdatawrite(inode->i_mapping); | 1425 | rc = filemap_fdatawrite(inode->i_mapping); |
1419 | if (rc == 0) | 1426 | if (rc == 0) |
1420 | CIFS_I(inode)->write_behind_rc = 0; | 1427 | CIFS_I(inode)->write_behind_rc = 0; |
@@ -1438,7 +1445,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1438 | if (!inode) | 1445 | if (!inode) |
1439 | return; */ | 1446 | return; */ |
1440 | 1447 | ||
1441 | /* fill in rpages then | 1448 | /* fill in rpages then |
1442 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ | 1449 | result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */ |
1443 | 1450 | ||
1444 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); | 1451 | /* cFYI(1, ("rpages is %d for sync page of Index %ld", rpages, index)); |
@@ -1456,7 +1463,7 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
1456 | */ | 1463 | */ |
1457 | int cifs_flush(struct file *file, fl_owner_t id) | 1464 | int cifs_flush(struct file *file, fl_owner_t id) |
1458 | { | 1465 | { |
1459 | struct inode * inode = file->f_path.dentry->d_inode; | 1466 | struct inode *inode = file->f_path.dentry->d_inode; |
1460 | int rc = 0; | 1467 | int rc = 0; |
1461 | 1468 | ||
1462 | /* Rather than do the steps manually: | 1469 | /* Rather than do the steps manually: |
@@ -1471,8 +1478,8 @@ int cifs_flush(struct file *file, fl_owner_t id) | |||
1471 | rc = filemap_fdatawrite(inode->i_mapping); | 1478 | rc = filemap_fdatawrite(inode->i_mapping); |
1472 | if (!rc) /* reset wb rc if we were able to write out dirty pages */ | 1479 | if (!rc) /* reset wb rc if we were able to write out dirty pages */ |
1473 | CIFS_I(inode)->write_behind_rc = 0; | 1480 | CIFS_I(inode)->write_behind_rc = 0; |
1474 | 1481 | ||
1475 | cFYI(1, ("Flush inode %p file %p rc %d",inode,file,rc)); | 1482 | cFYI(1, ("Flush inode %p file %p rc %d", inode, file, rc)); |
1476 | 1483 | ||
1477 | return rc; | 1484 | return rc; |
1478 | } | 1485 | } |
@@ -1508,13 +1515,13 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1508 | for (total_read = 0, current_offset = read_data; | 1515 | for (total_read = 0, current_offset = read_data; |
1509 | read_size > total_read; | 1516 | read_size > total_read; |
1510 | total_read += bytes_read, current_offset += bytes_read) { | 1517 | total_read += bytes_read, current_offset += bytes_read) { |
1511 | current_read_size = min_t(const int, read_size - total_read, | 1518 | current_read_size = min_t(const int, read_size - total_read, |
1512 | cifs_sb->rsize); | 1519 | cifs_sb->rsize); |
1513 | rc = -EAGAIN; | 1520 | rc = -EAGAIN; |
1514 | smb_read_data = NULL; | 1521 | smb_read_data = NULL; |
1515 | while (rc == -EAGAIN) { | 1522 | while (rc == -EAGAIN) { |
1516 | int buf_type = CIFS_NO_BUFFER; | 1523 | int buf_type = CIFS_NO_BUFFER; |
1517 | if ((open_file->invalidHandle) && | 1524 | if ((open_file->invalidHandle) && |
1518 | (!open_file->closePend)) { | 1525 | (!open_file->closePend)) { |
1519 | rc = cifs_reopen_file(file, TRUE); | 1526 | rc = cifs_reopen_file(file, TRUE); |
1520 | if (rc != 0) | 1527 | if (rc != 0) |
@@ -1535,9 +1542,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1535 | rc = -EFAULT; | 1542 | rc = -EFAULT; |
1536 | } | 1543 | } |
1537 | 1544 | ||
1538 | if(buf_type == CIFS_SMALL_BUFFER) | 1545 | if (buf_type == CIFS_SMALL_BUFFER) |
1539 | cifs_small_buf_release(smb_read_data); | 1546 | cifs_small_buf_release(smb_read_data); |
1540 | else if(buf_type == CIFS_LARGE_BUFFER) | 1547 | else if (buf_type == CIFS_LARGE_BUFFER) |
1541 | cifs_buf_release(smb_read_data); | 1548 | cifs_buf_release(smb_read_data); |
1542 | smb_read_data = NULL; | 1549 | smb_read_data = NULL; |
1543 | } | 1550 | } |
@@ -1586,21 +1593,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1586 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | 1593 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) |
1587 | cFYI(1, ("attempting read on write only file instance")); | 1594 | cFYI(1, ("attempting read on write only file instance")); |
1588 | 1595 | ||
1589 | for (total_read = 0, current_offset = read_data; | 1596 | for (total_read = 0, current_offset = read_data; |
1590 | read_size > total_read; | 1597 | read_size > total_read; |
1591 | total_read += bytes_read, current_offset += bytes_read) { | 1598 | total_read += bytes_read, current_offset += bytes_read) { |
1592 | current_read_size = min_t(const int, read_size - total_read, | 1599 | current_read_size = min_t(const int, read_size - total_read, |
1593 | cifs_sb->rsize); | 1600 | cifs_sb->rsize); |
1594 | /* For windows me and 9x we do not want to request more | 1601 | /* For windows me and 9x we do not want to request more |
1595 | than it negotiated since it will refuse the read then */ | 1602 | than it negotiated since it will refuse the read then */ |
1596 | if((pTcon->ses) && | 1603 | if ((pTcon->ses) && |
1597 | !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { | 1604 | !(pTcon->ses->capabilities & CAP_LARGE_FILES)) { |
1598 | current_read_size = min_t(const int, current_read_size, | 1605 | current_read_size = min_t(const int, current_read_size, |
1599 | pTcon->ses->server->maxBuf - 128); | 1606 | pTcon->ses->server->maxBuf - 128); |
1600 | } | 1607 | } |
1601 | rc = -EAGAIN; | 1608 | rc = -EAGAIN; |
1602 | while (rc == -EAGAIN) { | 1609 | while (rc == -EAGAIN) { |
1603 | if ((open_file->invalidHandle) && | 1610 | if ((open_file->invalidHandle) && |
1604 | (!open_file->closePend)) { | 1611 | (!open_file->closePend)) { |
1605 | rc = cifs_reopen_file(file, TRUE); | 1612 | rc = cifs_reopen_file(file, TRUE); |
1606 | if (rc != 0) | 1613 | if (rc != 0) |
@@ -1646,7 +1653,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
1646 | } | 1653 | } |
1647 | 1654 | ||
1648 | 1655 | ||
1649 | static void cifs_copy_cache_pages(struct address_space *mapping, | 1656 | static void cifs_copy_cache_pages(struct address_space *mapping, |
1650 | struct list_head *pages, int bytes_read, char *data, | 1657 | struct list_head *pages, int bytes_read, char *data, |
1651 | struct pagevec *plru_pvec) | 1658 | struct pagevec *plru_pvec) |
1652 | { | 1659 | { |
@@ -1669,12 +1676,12 @@ static void cifs_copy_cache_pages(struct address_space *mapping, | |||
1669 | continue; | 1676 | continue; |
1670 | } | 1677 | } |
1671 | 1678 | ||
1672 | target = kmap_atomic(page,KM_USER0); | 1679 | target = kmap_atomic(page, KM_USER0); |
1673 | 1680 | ||
1674 | if (PAGE_CACHE_SIZE > bytes_read) { | 1681 | if (PAGE_CACHE_SIZE > bytes_read) { |
1675 | memcpy(target, data, bytes_read); | 1682 | memcpy(target, data, bytes_read); |
1676 | /* zero the tail end of this partial page */ | 1683 | /* zero the tail end of this partial page */ |
1677 | memset(target + bytes_read, 0, | 1684 | memset(target + bytes_read, 0, |
1678 | PAGE_CACHE_SIZE - bytes_read); | 1685 | PAGE_CACHE_SIZE - bytes_read); |
1679 | bytes_read = 0; | 1686 | bytes_read = 0; |
1680 | } else { | 1687 | } else { |
@@ -1703,7 +1710,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1703 | struct cifs_sb_info *cifs_sb; | 1710 | struct cifs_sb_info *cifs_sb; |
1704 | struct cifsTconInfo *pTcon; | 1711 | struct cifsTconInfo *pTcon; |
1705 | int bytes_read = 0; | 1712 | int bytes_read = 0; |
1706 | unsigned int read_size,i; | 1713 | unsigned int read_size, i; |
1707 | char *smb_read_data = NULL; | 1714 | char *smb_read_data = NULL; |
1708 | struct smb_com_read_rsp *pSMBr; | 1715 | struct smb_com_read_rsp *pSMBr; |
1709 | struct pagevec lru_pvec; | 1716 | struct pagevec lru_pvec; |
@@ -1720,7 +1727,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1720 | pTcon = cifs_sb->tcon; | 1727 | pTcon = cifs_sb->tcon; |
1721 | 1728 | ||
1722 | pagevec_init(&lru_pvec, 0); | 1729 | pagevec_init(&lru_pvec, 0); |
1723 | 1730 | #ifdef CONFIG_CIFS_DEBUG2 | |
1731 | cFYI(1, ("rpages: num pages %d", num_pages)); | ||
1732 | #endif | ||
1724 | for (i = 0; i < num_pages; ) { | 1733 | for (i = 0; i < num_pages; ) { |
1725 | unsigned contig_pages; | 1734 | unsigned contig_pages; |
1726 | struct page *tmp_page; | 1735 | struct page *tmp_page; |
@@ -1734,14 +1743,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1734 | 1743 | ||
1735 | /* count adjacent pages that we will read into */ | 1744 | /* count adjacent pages that we will read into */ |
1736 | contig_pages = 0; | 1745 | contig_pages = 0; |
1737 | expected_index = | 1746 | expected_index = |
1738 | list_entry(page_list->prev, struct page, lru)->index; | 1747 | list_entry(page_list->prev, struct page, lru)->index; |
1739 | list_for_each_entry_reverse(tmp_page,page_list,lru) { | 1748 | list_for_each_entry_reverse(tmp_page, page_list, lru) { |
1740 | if (tmp_page->index == expected_index) { | 1749 | if (tmp_page->index == expected_index) { |
1741 | contig_pages++; | 1750 | contig_pages++; |
1742 | expected_index++; | 1751 | expected_index++; |
1743 | } else | 1752 | } else |
1744 | break; | 1753 | break; |
1745 | } | 1754 | } |
1746 | if (contig_pages + i > num_pages) | 1755 | if (contig_pages + i > num_pages) |
1747 | contig_pages = num_pages - i; | 1756 | contig_pages = num_pages - i; |
@@ -1753,10 +1762,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1753 | /* Read size needs to be in multiples of one page */ | 1762 | /* Read size needs to be in multiples of one page */ |
1754 | read_size = min_t(const unsigned int, read_size, | 1763 | read_size = min_t(const unsigned int, read_size, |
1755 | cifs_sb->rsize & PAGE_CACHE_MASK); | 1764 | cifs_sb->rsize & PAGE_CACHE_MASK); |
1756 | 1765 | #ifdef CONFIG_CIFS_DEBUG2 | |
1766 | cFYI(1, ("rpages: read size 0x%x contiguous pages %d", | ||
1767 | read_size, contig_pages)); | ||
1768 | #endif | ||
1757 | rc = -EAGAIN; | 1769 | rc = -EAGAIN; |
1758 | while (rc == -EAGAIN) { | 1770 | while (rc == -EAGAIN) { |
1759 | if ((open_file->invalidHandle) && | 1771 | if ((open_file->invalidHandle) && |
1760 | (!open_file->closePend)) { | 1772 | (!open_file->closePend)) { |
1761 | rc = cifs_reopen_file(file, TRUE); | 1773 | rc = cifs_reopen_file(file, TRUE); |
1762 | if (rc != 0) | 1774 | if (rc != 0) |
@@ -1769,11 +1781,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1769 | &bytes_read, &smb_read_data, | 1781 | &bytes_read, &smb_read_data, |
1770 | &buf_type); | 1782 | &buf_type); |
1771 | /* BB more RC checks ? */ | 1783 | /* BB more RC checks ? */ |
1772 | if (rc== -EAGAIN) { | 1784 | if (rc == -EAGAIN) { |
1773 | if (smb_read_data) { | 1785 | if (smb_read_data) { |
1774 | if(buf_type == CIFS_SMALL_BUFFER) | 1786 | if (buf_type == CIFS_SMALL_BUFFER) |
1775 | cifs_small_buf_release(smb_read_data); | 1787 | cifs_small_buf_release(smb_read_data); |
1776 | else if(buf_type == CIFS_LARGE_BUFFER) | 1788 | else if (buf_type == CIFS_LARGE_BUFFER) |
1777 | cifs_buf_release(smb_read_data); | 1789 | cifs_buf_release(smb_read_data); |
1778 | smb_read_data = NULL; | 1790 | smb_read_data = NULL; |
1779 | } | 1791 | } |
@@ -1794,10 +1806,10 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1794 | if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { | 1806 | if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { |
1795 | i++; /* account for partial page */ | 1807 | i++; /* account for partial page */ |
1796 | 1808 | ||
1797 | /* server copy of file can have smaller size | 1809 | /* server copy of file can have smaller size |
1798 | than client */ | 1810 | than client */ |
1799 | /* BB do we need to verify this common case ? | 1811 | /* BB do we need to verify this common case ? |
1800 | this case is ok - if we are at server EOF | 1812 | this case is ok - if we are at server EOF |
1801 | we will hit it on next read */ | 1813 | we will hit it on next read */ |
1802 | 1814 | ||
1803 | /* break; */ | 1815 | /* break; */ |
@@ -1806,14 +1818,14 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1806 | cFYI(1, ("No bytes read (%d) at offset %lld . " | 1818 | cFYI(1, ("No bytes read (%d) at offset %lld . " |
1807 | "Cleaning remaining pages from readahead list", | 1819 | "Cleaning remaining pages from readahead list", |
1808 | bytes_read, offset)); | 1820 | bytes_read, offset)); |
1809 | /* BB turn off caching and do new lookup on | 1821 | /* BB turn off caching and do new lookup on |
1810 | file size at server? */ | 1822 | file size at server? */ |
1811 | break; | 1823 | break; |
1812 | } | 1824 | } |
1813 | if (smb_read_data) { | 1825 | if (smb_read_data) { |
1814 | if(buf_type == CIFS_SMALL_BUFFER) | 1826 | if (buf_type == CIFS_SMALL_BUFFER) |
1815 | cifs_small_buf_release(smb_read_data); | 1827 | cifs_small_buf_release(smb_read_data); |
1816 | else if(buf_type == CIFS_LARGE_BUFFER) | 1828 | else if (buf_type == CIFS_LARGE_BUFFER) |
1817 | cifs_buf_release(smb_read_data); | 1829 | cifs_buf_release(smb_read_data); |
1818 | smb_read_data = NULL; | 1830 | smb_read_data = NULL; |
1819 | } | 1831 | } |
@@ -1824,12 +1836,12 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1824 | 1836 | ||
1825 | /* need to free smb_read_data buf before exit */ | 1837 | /* need to free smb_read_data buf before exit */ |
1826 | if (smb_read_data) { | 1838 | if (smb_read_data) { |
1827 | if(buf_type == CIFS_SMALL_BUFFER) | 1839 | if (buf_type == CIFS_SMALL_BUFFER) |
1828 | cifs_small_buf_release(smb_read_data); | 1840 | cifs_small_buf_release(smb_read_data); |
1829 | else if(buf_type == CIFS_LARGE_BUFFER) | 1841 | else if (buf_type == CIFS_LARGE_BUFFER) |
1830 | cifs_buf_release(smb_read_data); | 1842 | cifs_buf_release(smb_read_data); |
1831 | smb_read_data = NULL; | 1843 | smb_read_data = NULL; |
1832 | } | 1844 | } |
1833 | 1845 | ||
1834 | FreeXid(xid); | 1846 | FreeXid(xid); |
1835 | return rc; | 1847 | return rc; |
@@ -1844,26 +1856,26 @@ static int cifs_readpage_worker(struct file *file, struct page *page, | |||
1844 | page_cache_get(page); | 1856 | page_cache_get(page); |
1845 | read_data = kmap(page); | 1857 | read_data = kmap(page); |
1846 | /* for reads over a certain size could initiate async read ahead */ | 1858 | /* for reads over a certain size could initiate async read ahead */ |
1847 | 1859 | ||
1848 | rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); | 1860 | rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset); |
1849 | 1861 | ||
1850 | if (rc < 0) | 1862 | if (rc < 0) |
1851 | goto io_error; | 1863 | goto io_error; |
1852 | else | 1864 | else |
1853 | cFYI(1, ("Bytes read %d",rc)); | 1865 | cFYI(1, ("Bytes read %d", rc)); |
1854 | 1866 | ||
1855 | file->f_path.dentry->d_inode->i_atime = | 1867 | file->f_path.dentry->d_inode->i_atime = |
1856 | current_fs_time(file->f_path.dentry->d_inode->i_sb); | 1868 | current_fs_time(file->f_path.dentry->d_inode->i_sb); |
1857 | 1869 | ||
1858 | if (PAGE_CACHE_SIZE > rc) | 1870 | if (PAGE_CACHE_SIZE > rc) |
1859 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); | 1871 | memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); |
1860 | 1872 | ||
1861 | flush_dcache_page(page); | 1873 | flush_dcache_page(page); |
1862 | SetPageUptodate(page); | 1874 | SetPageUptodate(page); |
1863 | rc = 0; | 1875 | rc = 0; |
1864 | 1876 | ||
1865 | io_error: | 1877 | io_error: |
1866 | kunmap(page); | 1878 | kunmap(page); |
1867 | page_cache_release(page); | 1879 | page_cache_release(page); |
1868 | return rc; | 1880 | return rc; |
1869 | } | 1881 | } |
@@ -1881,7 +1893,7 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
1881 | return -EBADF; | 1893 | return -EBADF; |
1882 | } | 1894 | } |
1883 | 1895 | ||
1884 | cFYI(1, ("readpage %p at offset %d 0x%x\n", | 1896 | cFYI(1, ("readpage %p at offset %d 0x%x\n", |
1885 | page, (int)offset, (int)offset)); | 1897 | page, (int)offset, (int)offset)); |
1886 | 1898 | ||
1887 | rc = cifs_readpage_worker(file, page, &offset); | 1899 | rc = cifs_readpage_worker(file, page, &offset); |
@@ -1895,7 +1907,7 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
1895 | /* We do not want to update the file size from server for inodes | 1907 | /* We do not want to update the file size from server for inodes |
1896 | open for write - to avoid races with writepage extending | 1908 | open for write - to avoid races with writepage extending |
1897 | the file - in the future we could consider allowing | 1909 | the file - in the future we could consider allowing |
1898 | refreshing the inode only on increases in the file size | 1910 | refreshing the inode only on increases in the file size |
1899 | but this is tricky to do without racing with writebehind | 1911 | but this is tricky to do without racing with writebehind |
1900 | page caching in the current Linux kernel design */ | 1912 | page caching in the current Linux kernel design */ |
1901 | int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | 1913 | int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) |
@@ -1904,8 +1916,8 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | |||
1904 | 1916 | ||
1905 | if (cifsInode) | 1917 | if (cifsInode) |
1906 | open_file = find_writable_file(cifsInode); | 1918 | open_file = find_writable_file(cifsInode); |
1907 | 1919 | ||
1908 | if(open_file) { | 1920 | if (open_file) { |
1909 | struct cifs_sb_info *cifs_sb; | 1921 | struct cifs_sb_info *cifs_sb; |
1910 | 1922 | ||
1911 | /* there is not actually a write pending so let | 1923 | /* there is not actually a write pending so let |
@@ -1915,12 +1927,12 @@ int is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file) | |||
1915 | 1927 | ||
1916 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); | 1928 | cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb); |
1917 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { | 1929 | if ( cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO ) { |
1918 | /* since no page cache to corrupt on directio | 1930 | /* since no page cache to corrupt on directio |
1919 | we can change size safely */ | 1931 | we can change size safely */ |
1920 | return 1; | 1932 | return 1; |
1921 | } | 1933 | } |
1922 | 1934 | ||
1923 | if(i_size_read(&cifsInode->vfs_inode) < end_of_file) | 1935 | if (i_size_read(&cifsInode->vfs_inode) < end_of_file) |
1924 | return 1; | 1936 | return 1; |
1925 | 1937 | ||
1926 | return 0; | 1938 | return 0; |
@@ -1935,7 +1947,7 @@ static int cifs_prepare_write(struct file *file, struct page *page, | |||
1935 | loff_t i_size; | 1947 | loff_t i_size; |
1936 | loff_t offset; | 1948 | loff_t offset; |
1937 | 1949 | ||
1938 | cFYI(1, ("prepare write for page %p from %d to %d",page,from,to)); | 1950 | cFYI(1, ("prepare write for page %p from %d to %d", page, from, to)); |
1939 | if (PageUptodate(page)) | 1951 | if (PageUptodate(page)) |
1940 | return 0; | 1952 | return 0; |
1941 | 1953 | ||
@@ -1955,14 +1967,7 @@ static int cifs_prepare_write(struct file *file, struct page *page, | |||
1955 | * We don't need to read data beyond the end of the file. | 1967 | * We don't need to read data beyond the end of the file. |
1956 | * zero it, and set the page uptodate | 1968 | * zero it, and set the page uptodate |
1957 | */ | 1969 | */ |
1958 | void *kaddr = kmap_atomic(page, KM_USER0); | 1970 | simple_prepare_write(file, page, from, to); |
1959 | |||
1960 | if (from) | ||
1961 | memset(kaddr, 0, from); | ||
1962 | if (to < PAGE_CACHE_SIZE) | ||
1963 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); | ||
1964 | flush_dcache_page(page); | ||
1965 | kunmap_atomic(kaddr, KM_USER0); | ||
1966 | SetPageUptodate(page); | 1971 | SetPageUptodate(page); |
1967 | } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { | 1972 | } else if ((file->f_flags & O_ACCMODE) != O_WRONLY) { |
1968 | /* might as well read a page, it is fast enough */ | 1973 | /* might as well read a page, it is fast enough */ |
@@ -1974,8 +1979,8 @@ static int cifs_prepare_write(struct file *file, struct page *page, | |||
1974 | this will be written out by commit_write so is fine */ | 1979 | this will be written out by commit_write so is fine */ |
1975 | } | 1980 | } |
1976 | 1981 | ||
1977 | /* we do not need to pass errors back | 1982 | /* we do not need to pass errors back |
1978 | e.g. if we do not have read access to the file | 1983 | e.g. if we do not have read access to the file |
1979 | because cifs_commit_write will do the right thing. -- shaggy */ | 1984 | because cifs_commit_write will do the right thing. -- shaggy */ |
1980 | 1985 | ||
1981 | return 0; | 1986 | return 0; |