diff options
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 129 |
1 files changed, 35 insertions, 94 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 2d3275bedb55..b570530f97bf 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -48,7 +48,7 @@ static inline struct cifsFileInfo *cifs_init_private( | |||
48 | private_data->netfid = netfid; | 48 | private_data->netfid = netfid; |
49 | private_data->pid = current->tgid; | 49 | private_data->pid = current->tgid; |
50 | init_MUTEX(&private_data->fh_sem); | 50 | init_MUTEX(&private_data->fh_sem); |
51 | init_MUTEX(&private_data->lock_sem); | 51 | mutex_init(&private_data->lock_mutex); |
52 | INIT_LIST_HEAD(&private_data->llist); | 52 | INIT_LIST_HEAD(&private_data->llist); |
53 | private_data->pfile = file; /* needed for writepage */ | 53 | private_data->pfile = file; /* needed for writepage */ |
54 | private_data->pInode = inode; | 54 | private_data->pInode = inode; |
@@ -338,8 +338,7 @@ static int cifs_relock_file(struct cifsFileInfo *cifsFile) | |||
338 | return rc; | 338 | return rc; |
339 | } | 339 | } |
340 | 340 | ||
341 | static int cifs_reopen_file(struct inode *inode, struct file *file, | 341 | static int cifs_reopen_file(struct file *file, int can_flush) |
342 | int can_flush) | ||
343 | { | 342 | { |
344 | int rc = -EACCES; | 343 | int rc = -EACCES; |
345 | int xid, oplock; | 344 | int xid, oplock; |
@@ -347,13 +346,12 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
347 | struct cifsTconInfo *pTcon; | 346 | struct cifsTconInfo *pTcon; |
348 | struct cifsFileInfo *pCifsFile; | 347 | struct cifsFileInfo *pCifsFile; |
349 | struct cifsInodeInfo *pCifsInode; | 348 | struct cifsInodeInfo *pCifsInode; |
349 | struct inode * inode; | ||
350 | char *full_path = NULL; | 350 | char *full_path = NULL; |
351 | int desiredAccess; | 351 | int desiredAccess; |
352 | int disposition = FILE_OPEN; | 352 | int disposition = FILE_OPEN; |
353 | __u16 netfid; | 353 | __u16 netfid; |
354 | 354 | ||
355 | if (inode == NULL) | ||
356 | return -EBADF; | ||
357 | if (file->private_data) { | 355 | if (file->private_data) { |
358 | pCifsFile = (struct cifsFileInfo *)file->private_data; | 356 | pCifsFile = (struct cifsFileInfo *)file->private_data; |
359 | } else | 357 | } else |
@@ -368,25 +366,37 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
368 | } | 366 | } |
369 | 367 | ||
370 | if (file->f_path.dentry == NULL) { | 368 | if (file->f_path.dentry == NULL) { |
371 | up(&pCifsFile->fh_sem); | 369 | cERROR(1, ("no valid name if dentry freed")); |
372 | cFYI(1, ("failed file reopen, no valid name if dentry freed")); | 370 | dump_stack(); |
373 | FreeXid(xid); | 371 | rc = -EBADF; |
374 | return -EBADF; | 372 | goto reopen_error_exit; |
375 | } | 373 | } |
374 | |||
375 | inode = file->f_path.dentry->d_inode; | ||
376 | if(inode == NULL) { | ||
377 | cERROR(1, ("inode not valid")); | ||
378 | dump_stack(); | ||
379 | rc = -EBADF; | ||
380 | goto reopen_error_exit; | ||
381 | } | ||
382 | |||
376 | cifs_sb = CIFS_SB(inode->i_sb); | 383 | cifs_sb = CIFS_SB(inode->i_sb); |
377 | pTcon = cifs_sb->tcon; | 384 | pTcon = cifs_sb->tcon; |
385 | |||
378 | /* can not grab rename sem here because various ops, including | 386 | /* can not grab rename sem here because various ops, including |
379 | those that already have the rename sem can end up causing writepage | 387 | those that already have the rename sem can end up causing writepage |
380 | to get called and if the server was down that means we end up here, | 388 | to get called and if the server was down that means we end up here, |
381 | and we can never tell if the caller already has the rename_sem */ | 389 | and we can never tell if the caller already has the rename_sem */ |
382 | full_path = build_path_from_dentry(file->f_path.dentry); | 390 | full_path = build_path_from_dentry(file->f_path.dentry); |
383 | if (full_path == NULL) { | 391 | if (full_path == NULL) { |
392 | rc = -ENOMEM; | ||
393 | reopen_error_exit: | ||
384 | up(&pCifsFile->fh_sem); | 394 | up(&pCifsFile->fh_sem); |
385 | FreeXid(xid); | 395 | FreeXid(xid); |
386 | return -ENOMEM; | 396 | return rc; |
387 | } | 397 | } |
388 | 398 | ||
389 | cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", | 399 | cFYI(1, ("inode = 0x%p file flags 0x%x for %s", |
390 | inode, file->f_flags,full_path)); | 400 | inode, file->f_flags,full_path)); |
391 | desiredAccess = cifs_convert_flags(file->f_flags); | 401 | desiredAccess = cifs_convert_flags(file->f_flags); |
392 | 402 | ||
@@ -401,13 +411,6 @@ static int cifs_reopen_file(struct inode *inode, struct file *file, | |||
401 | and server version of file size can be stale. If we knew for sure | 411 | and server version of file size can be stale. If we knew for sure |
402 | that inode was not dirty locally we could do this */ | 412 | that inode was not dirty locally we could do this */ |
403 | 413 | ||
404 | /* buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | ||
405 | if (buf == 0) { | ||
406 | up(&pCifsFile->fh_sem); | ||
407 | kfree(full_path); | ||
408 | FreeXid(xid); | ||
409 | return -ENOMEM; | ||
410 | } */ | ||
411 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, | 414 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, |
412 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | 415 | CREATE_NOT_DIR, &netfid, &oplock, NULL, |
413 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 416 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
@@ -508,12 +511,12 @@ int cifs_close(struct inode *inode, struct file *file) | |||
508 | 511 | ||
509 | /* Delete any outstanding lock records. | 512 | /* Delete any outstanding lock records. |
510 | We'll lose them when the file is closed anyway. */ | 513 | We'll lose them when the file is closed anyway. */ |
511 | down(&pSMBFile->lock_sem); | 514 | mutex_lock(&pSMBFile->lock_mutex); |
512 | list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { | 515 | list_for_each_entry_safe(li, tmp, &pSMBFile->llist, llist) { |
513 | list_del(&li->llist); | 516 | list_del(&li->llist); |
514 | kfree(li); | 517 | kfree(li); |
515 | } | 518 | } |
516 | up(&pSMBFile->lock_sem); | 519 | mutex_unlock(&pSMBFile->lock_mutex); |
517 | 520 | ||
518 | write_lock(&GlobalSMBSeslock); | 521 | write_lock(&GlobalSMBSeslock); |
519 | list_del(&pSMBFile->flist); | 522 | list_del(&pSMBFile->flist); |
@@ -598,9 +601,9 @@ static int store_file_lock(struct cifsFileInfo *fid, __u64 len, | |||
598 | li->offset = offset; | 601 | li->offset = offset; |
599 | li->length = len; | 602 | li->length = len; |
600 | li->type = lockType; | 603 | li->type = lockType; |
601 | down(&fid->lock_sem); | 604 | mutex_lock(&fid->lock_mutex); |
602 | list_add(&li->llist, &fid->llist); | 605 | list_add(&li->llist, &fid->llist); |
603 | up(&fid->lock_sem); | 606 | mutex_unlock(&fid->lock_mutex); |
604 | return 0; | 607 | return 0; |
605 | } | 608 | } |
606 | 609 | ||
@@ -757,7 +760,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
757 | struct cifsLockInfo *li, *tmp; | 760 | struct cifsLockInfo *li, *tmp; |
758 | 761 | ||
759 | rc = 0; | 762 | rc = 0; |
760 | down(&fid->lock_sem); | 763 | mutex_lock(&fid->lock_mutex); |
761 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 764 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { |
762 | if (pfLock->fl_start <= li->offset && | 765 | if (pfLock->fl_start <= li->offset && |
763 | length >= li->length) { | 766 | length >= li->length) { |
@@ -771,7 +774,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
771 | kfree(li); | 774 | kfree(li); |
772 | } | 775 | } |
773 | } | 776 | } |
774 | up(&fid->lock_sem); | 777 | mutex_unlock(&fid->lock_mutex); |
775 | } | 778 | } |
776 | } | 779 | } |
777 | 780 | ||
@@ -792,12 +795,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
792 | int xid, long_op; | 795 | int xid, long_op; |
793 | struct cifsFileInfo *open_file; | 796 | struct cifsFileInfo *open_file; |
794 | 797 | ||
795 | if (file->f_path.dentry == NULL) | ||
796 | return -EBADF; | ||
797 | |||
798 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 798 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
799 | if (cifs_sb == NULL) | ||
800 | return -EBADF; | ||
801 | 799 | ||
802 | pTcon = cifs_sb->tcon; | 800 | pTcon = cifs_sb->tcon; |
803 | 801 | ||
@@ -807,14 +805,9 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
807 | 805 | ||
808 | if (file->private_data == NULL) | 806 | if (file->private_data == NULL) |
809 | return -EBADF; | 807 | return -EBADF; |
810 | else | 808 | open_file = (struct cifsFileInfo *) file->private_data; |
811 | open_file = (struct cifsFileInfo *) file->private_data; | ||
812 | 809 | ||
813 | xid = GetXid(); | 810 | xid = GetXid(); |
814 | if (file->f_path.dentry->d_inode == NULL) { | ||
815 | FreeXid(xid); | ||
816 | return -EBADF; | ||
817 | } | ||
818 | 811 | ||
819 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 812 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
820 | long_op = 2; /* writes past end of file can take a long time */ | 813 | long_op = 2; /* writes past end of file can take a long time */ |
@@ -841,17 +834,11 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
841 | return -EBADF; | 834 | return -EBADF; |
842 | } | 835 | } |
843 | if (open_file->invalidHandle) { | 836 | if (open_file->invalidHandle) { |
844 | if ((file->f_path.dentry == NULL) || | ||
845 | (file->f_path.dentry->d_inode == NULL)) { | ||
846 | FreeXid(xid); | ||
847 | return total_written; | ||
848 | } | ||
849 | /* we could deadlock if we called | 837 | /* we could deadlock if we called |
850 | filemap_fdatawait from here so tell | 838 | filemap_fdatawait from here so tell |
851 | reopen_file not to flush data to server | 839 | reopen_file not to flush data to server |
852 | now */ | 840 | now */ |
853 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 841 | rc = cifs_reopen_file(file, FALSE); |
854 | file, FALSE); | ||
855 | if (rc != 0) | 842 | if (rc != 0) |
856 | break; | 843 | break; |
857 | } | 844 | } |
@@ -908,12 +895,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
908 | int xid, long_op; | 895 | int xid, long_op; |
909 | struct cifsFileInfo *open_file; | 896 | struct cifsFileInfo *open_file; |
910 | 897 | ||
911 | if (file->f_path.dentry == NULL) | ||
912 | return -EBADF; | ||
913 | |||
914 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 898 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
915 | if (cifs_sb == NULL) | ||
916 | return -EBADF; | ||
917 | 899 | ||
918 | pTcon = cifs_sb->tcon; | 900 | pTcon = cifs_sb->tcon; |
919 | 901 | ||
@@ -922,14 +904,9 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
922 | 904 | ||
923 | if (file->private_data == NULL) | 905 | if (file->private_data == NULL) |
924 | return -EBADF; | 906 | return -EBADF; |
925 | else | 907 | open_file = (struct cifsFileInfo *)file->private_data; |
926 | open_file = (struct cifsFileInfo *)file->private_data; | ||
927 | 908 | ||
928 | xid = GetXid(); | 909 | xid = GetXid(); |
929 | if (file->f_path.dentry->d_inode == NULL) { | ||
930 | FreeXid(xid); | ||
931 | return -EBADF; | ||
932 | } | ||
933 | 910 | ||
934 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 911 | if (*poffset > file->f_path.dentry->d_inode->i_size) |
935 | long_op = 2; /* writes past end of file can take a long time */ | 912 | long_op = 2; /* writes past end of file can take a long time */ |
@@ -957,17 +934,11 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
957 | return -EBADF; | 934 | return -EBADF; |
958 | } | 935 | } |
959 | if (open_file->invalidHandle) { | 936 | if (open_file->invalidHandle) { |
960 | if ((file->f_path.dentry == NULL) || | ||
961 | (file->f_path.dentry->d_inode == NULL)) { | ||
962 | FreeXid(xid); | ||
963 | return total_written; | ||
964 | } | ||
965 | /* we could deadlock if we called | 937 | /* we could deadlock if we called |
966 | filemap_fdatawait from here so tell | 938 | filemap_fdatawait from here so tell |
967 | reopen_file not to flush data to | 939 | reopen_file not to flush data to |
968 | server now */ | 940 | server now */ |
969 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 941 | rc = cifs_reopen_file(file, FALSE); |
970 | file, FALSE); | ||
971 | if (rc != 0) | 942 | if (rc != 0) |
972 | break; | 943 | break; |
973 | } | 944 | } |
@@ -1056,8 +1027,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1056 | read_unlock(&GlobalSMBSeslock); | 1027 | read_unlock(&GlobalSMBSeslock); |
1057 | if((open_file->invalidHandle) && | 1028 | if((open_file->invalidHandle) && |
1058 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { | 1029 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { |
1059 | rc = cifs_reopen_file(&cifs_inode->vfs_inode, | 1030 | rc = cifs_reopen_file(open_file->pfile, FALSE); |
1060 | open_file->pfile, FALSE); | ||
1061 | /* if it fails, try another handle - might be */ | 1031 | /* if it fails, try another handle - might be */ |
1062 | /* dangerous to hold up writepages with retry */ | 1032 | /* dangerous to hold up writepages with retry */ |
1063 | if(rc) { | 1033 | if(rc) { |
@@ -1404,32 +1374,6 @@ static int cifs_commit_write(struct file *file, struct page *page, | |||
1404 | spin_lock(&inode->i_lock); | 1374 | spin_lock(&inode->i_lock); |
1405 | if (position > inode->i_size) { | 1375 | if (position > inode->i_size) { |
1406 | i_size_write(inode, position); | 1376 | i_size_write(inode, position); |
1407 | /* if (file->private_data == NULL) { | ||
1408 | rc = -EBADF; | ||
1409 | } else { | ||
1410 | open_file = (struct cifsFileInfo *)file->private_data; | ||
1411 | cifs_sb = CIFS_SB(inode->i_sb); | ||
1412 | rc = -EAGAIN; | ||
1413 | while (rc == -EAGAIN) { | ||
1414 | if ((open_file->invalidHandle) && | ||
1415 | (!open_file->closePend)) { | ||
1416 | rc = cifs_reopen_file( | ||
1417 | file->f_path.dentry->d_inode, file); | ||
1418 | if (rc != 0) | ||
1419 | break; | ||
1420 | } | ||
1421 | if (!open_file->closePend) { | ||
1422 | rc = CIFSSMBSetFileSize(xid, | ||
1423 | cifs_sb->tcon, position, | ||
1424 | open_file->netfid, | ||
1425 | open_file->pid, FALSE); | ||
1426 | } else { | ||
1427 | rc = -EBADF; | ||
1428 | break; | ||
1429 | } | ||
1430 | } | ||
1431 | cFYI(1, (" SetEOF (commit write) rc = %d", rc)); | ||
1432 | } */ | ||
1433 | } | 1377 | } |
1434 | spin_unlock(&inode->i_lock); | 1378 | spin_unlock(&inode->i_lock); |
1435 | if (!PageUptodate(page)) { | 1379 | if (!PageUptodate(page)) { |
@@ -1573,8 +1517,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1573 | int buf_type = CIFS_NO_BUFFER; | 1517 | int buf_type = CIFS_NO_BUFFER; |
1574 | if ((open_file->invalidHandle) && | 1518 | if ((open_file->invalidHandle) && |
1575 | (!open_file->closePend)) { | 1519 | (!open_file->closePend)) { |
1576 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1520 | rc = cifs_reopen_file(file, TRUE); |
1577 | file, TRUE); | ||
1578 | if (rc != 0) | 1521 | if (rc != 0) |
1579 | break; | 1522 | break; |
1580 | } | 1523 | } |
@@ -1660,8 +1603,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1660 | while (rc == -EAGAIN) { | 1603 | while (rc == -EAGAIN) { |
1661 | if ((open_file->invalidHandle) && | 1604 | if ((open_file->invalidHandle) && |
1662 | (!open_file->closePend)) { | 1605 | (!open_file->closePend)) { |
1663 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1606 | rc = cifs_reopen_file(file, TRUE); |
1664 | file, TRUE); | ||
1665 | if (rc != 0) | 1607 | if (rc != 0) |
1666 | break; | 1608 | break; |
1667 | } | 1609 | } |
@@ -1817,8 +1759,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1817 | while (rc == -EAGAIN) { | 1759 | while (rc == -EAGAIN) { |
1818 | if ((open_file->invalidHandle) && | 1760 | if ((open_file->invalidHandle) && |
1819 | (!open_file->closePend)) { | 1761 | (!open_file->closePend)) { |
1820 | rc = cifs_reopen_file(file->f_path.dentry->d_inode, | 1762 | rc = cifs_reopen_file(file, TRUE); |
1821 | file, TRUE); | ||
1822 | if (rc != 0) | 1763 | if (rc != 0) |
1823 | break; | 1764 | break; |
1824 | } | 1765 | } |