aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/CHANGES5
-rw-r--r--fs/cifs/connect.c7
-rw-r--r--fs/cifs/file.c31
-rw-r--r--fs/cifs/inode.c24
-rw-r--r--fs/cifs/link.c33
-rw-r--r--fs/cifs/readdir.c9
-rw-r--r--fs/cifs/sess.c23
7 files changed, 81 insertions, 51 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 1eb9a2ec0a..0b3c37ef52 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,6 +1,11 @@
1Version 1.46 1Version 1.46
2------------ 2------------
3Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. 3Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps.
4Allow null user to be specified on mount ("username="). Do not return
5EINVAL on readdir when filldir fails due to overwritten blocksize
6(fixes FC problem). Return error in rename 2nd attempt retry (ie report
7if rename by handle also fails, after rename by path fails, we were
8not reporting whether the retry worked or not).
4 9
5Version 1.45 10Version 1.45
6------------ 11------------
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4093d53329..71f77914ce 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -822,10 +822,13 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
822 } else if (strnicmp(data, "nouser_xattr",12) == 0) { 822 } else if (strnicmp(data, "nouser_xattr",12) == 0) {
823 vol->no_xattr = 1; 823 vol->no_xattr = 1;
824 } else if (strnicmp(data, "user", 4) == 0) { 824 } else if (strnicmp(data, "user", 4) == 0) {
825 if (!value || !*value) { 825 if (!value) {
826 printk(KERN_WARNING 826 printk(KERN_WARNING
827 "CIFS: invalid or missing username\n"); 827 "CIFS: invalid or missing username\n");
828 return 1; /* needs_arg; */ 828 return 1; /* needs_arg; */
829 } else if(!*value) {
830 /* null user, ie anonymous, authentication */
831 vol->nullauth = 1;
829 } 832 }
830 if (strnlen(value, 200) < 200) { 833 if (strnlen(value, 200) < 200) {
831 vol->username = value; 834 vol->username = value;
@@ -1642,6 +1645,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1642 /* BB fixme parse for domain name here */ 1645 /* BB fixme parse for domain name here */
1643 cFYI(1, ("Username: %s ", volume_info.username)); 1646 cFYI(1, ("Username: %s ", volume_info.username));
1644 1647
1648 } else if (volume_info.nullauth) {
1649 cFYI(1,("null user"));
1645 } else { 1650 } else {
1646 cifserror("No username specified"); 1651 cifserror("No username specified");
1647 /* In userspace mount helper we can get user name from alternate 1652 /* In userspace mount helper we can get user name from alternate
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 976a691c5a..2436ed8fc8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -492,10 +492,14 @@ int cifs_close(struct inode *inode, struct file *file)
492 the struct would be in each open file, 492 the struct would be in each open file,
493 but this should give enough time to 493 but this should give enough time to
494 clear the socket */ 494 clear the socket */
495 cERROR(1,("close with pending writes")); 495#ifdef CONFIG_CIFS_DEBUG2
496 cFYI(1,("close delay, write pending"));
497#endif /* DEBUG2 */
496 msleep(timeout); 498 msleep(timeout);
497 timeout *= 4; 499 timeout *= 4;
498 } 500 }
501 if(atomic_read(&pSMBFile->wrtPending))
502 cERROR(1,("close with pending writes"));
499 rc = CIFSSMBClose(xid, pTcon, 503 rc = CIFSSMBClose(xid, pTcon,
500 pSMBFile->netfid); 504 pSMBFile->netfid);
501 } 505 }
@@ -1806,13 +1810,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1806 } 1810 }
1807 if ((rc < 0) || (smb_read_data == NULL)) { 1811 if ((rc < 0) || (smb_read_data == NULL)) {
1808 cFYI(1, ("Read error in readpages: %d", rc)); 1812 cFYI(1, ("Read error in readpages: %d", rc));
1809 /* clean up remaing pages off list */
1810 while (!list_empty(page_list) && (i < num_pages)) {
1811 page = list_entry(page_list->prev, struct page,
1812 lru);
1813 list_del(&page->lru);
1814 page_cache_release(page);
1815 }
1816 break; 1813 break;
1817 } else if (bytes_read > 0) { 1814 } else if (bytes_read > 0) {
1818 pSMBr = (struct smb_com_read_rsp *)smb_read_data; 1815 pSMBr = (struct smb_com_read_rsp *)smb_read_data;
@@ -1831,13 +1828,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1831 this case is ok - if we are at server EOF 1828 this case is ok - if we are at server EOF
1832 we will hit it on next read */ 1829 we will hit it on next read */
1833 1830
1834 /* while (!list_empty(page_list) && (i < num_pages)) { 1831 /* break; */
1835 page = list_entry(page_list->prev,
1836 struct page, list);
1837 list_del(&page->list);
1838 page_cache_release(page);
1839 }
1840 break; */
1841 } 1832 }
1842 } else { 1833 } else {
1843 cFYI(1, ("No bytes read (%d) at offset %lld . " 1834 cFYI(1, ("No bytes read (%d) at offset %lld . "
@@ -1845,14 +1836,6 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1845 bytes_read, offset)); 1836 bytes_read, offset));
1846 /* BB turn off caching and do new lookup on 1837 /* BB turn off caching and do new lookup on
1847 file size at server? */ 1838 file size at server? */
1848 while (!list_empty(page_list) && (i < num_pages)) {
1849 page = list_entry(page_list->prev, struct page,
1850 lru);
1851 list_del(&page->lru);
1852
1853 /* BB removeme - replace with zero of page? */
1854 page_cache_release(page);
1855 }
1856 break; 1839 break;
1857 } 1840 }
1858 if (smb_read_data) { 1841 if (smb_read_data) {
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 35d54bb086..c4fa91b8b6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -318,6 +318,7 @@ int cifs_get_inode_info(struct inode **pinode,
318 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 318 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
319 char *tmp_path; 319 char *tmp_path;
320 char *buf = NULL; 320 char *buf = NULL;
321 int adjustTZ = FALSE;
321 322
322 pTcon = cifs_sb->tcon; 323 pTcon = cifs_sb->tcon;
323 cFYI(1,("Getting info on %s", search_path)); 324 cFYI(1,("Getting info on %s", search_path));
@@ -348,6 +349,7 @@ int cifs_get_inode_info(struct inode **pinode,
348 pfindData, cifs_sb->local_nls, 349 pfindData, cifs_sb->local_nls,
349 cifs_sb->mnt_cifs_flags & 350 cifs_sb->mnt_cifs_flags &
350 CIFS_MOUNT_MAP_SPECIAL_CHR); 351 CIFS_MOUNT_MAP_SPECIAL_CHR);
352 adjustTZ = TRUE;
351 } 353 }
352 354
353 } 355 }
@@ -444,6 +446,10 @@ int cifs_get_inode_info(struct inode **pinode,
444 inode->i_ctime = 446 inode->i_ctime =
445 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 447 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
446 cFYI(0, ("Attributes came in as 0x%x", attr)); 448 cFYI(0, ("Attributes came in as 0x%x", attr));
449 if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
450 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
451 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
452 }
447 453
448 /* set default mode. will override for dirs below */ 454 /* set default mode. will override for dirs below */
449 if (atomic_read(&cifsInfo->inUse) == 0) 455 if (atomic_read(&cifsInfo->inUse) == 0)
@@ -885,10 +891,14 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
885 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); 891 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
886 if (info_buf_source != NULL) { 892 if (info_buf_source != NULL) {
887 info_buf_target = info_buf_source + 1; 893 info_buf_target = info_buf_source + 1;
888 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 894 if (pTcon->ses->capabilities & CAP_UNIX)
889 info_buf_source, cifs_sb_source->local_nls, 895 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
890 cifs_sb_source->mnt_cifs_flags & 896 info_buf_source,
891 CIFS_MOUNT_MAP_SPECIAL_CHR); 897 cifs_sb_source->local_nls,
898 cifs_sb_source->mnt_cifs_flags &
899 CIFS_MOUNT_MAP_SPECIAL_CHR);
900 /* else rc is still EEXIST so will fall through to
901 unlink the target and retry rename */
892 if (rc == 0) { 902 if (rc == 0) {
893 rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName, 903 rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
894 info_buf_target, 904 info_buf_target,
@@ -937,7 +947,7 @@ int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
937 cifs_sb_source->mnt_cifs_flags & 947 cifs_sb_source->mnt_cifs_flags &
938 CIFS_MOUNT_MAP_SPECIAL_CHR); 948 CIFS_MOUNT_MAP_SPECIAL_CHR);
939 if (rc==0) { 949 if (rc==0) {
940 CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName, 950 rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
941 cifs_sb_source->local_nls, 951 cifs_sb_source->local_nls,
942 cifs_sb_source->mnt_cifs_flags & 952 cifs_sb_source->mnt_cifs_flags &
943 CIFS_MOUNT_MAP_SPECIAL_CHR); 953 CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1085,8 +1095,10 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1085 struct kstat *stat) 1095 struct kstat *stat)
1086{ 1096{
1087 int err = cifs_revalidate(dentry); 1097 int err = cifs_revalidate(dentry);
1088 if (!err) 1098 if (!err) {
1089 generic_fillattr(dentry->d_inode, stat); 1099 generic_fillattr(dentry->d_inode, stat);
1100 stat->blksize = CIFS_MAX_MSGSIZE;
1101 }
1090 return err; 1102 return err;
1091} 1103}
1092 1104
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 0bee8b7e52..8e25996935 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -69,17 +69,30 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
69 rc = -EOPNOTSUPP; 69 rc = -EOPNOTSUPP;
70 } 70 }
71 71
72/* if (!rc) */ 72 d_drop(direntry); /* force new lookup from server of target */
73 { 73
74 /* renew_parental_timestamps(old_file); 74 /* if source file is cached (oplocked) revalidate will not go to server
75 inode->i_nlink++; 75 until the file is closed or oplock broken so update nlinks locally */
76 mark_inode_dirty(inode); 76 if(old_file->d_inode) {
77 d_instantiate(direntry, inode); */ 77 cifsInode = CIFS_I(old_file->d_inode);
78 /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ 78 if(rc == 0) {
79 old_file->d_inode->i_nlink++;
80 old_file->d_inode->i_ctime = CURRENT_TIME;
81 /* parent dir timestamps will update from srv
82 within a second, would it really be worth it
83 to set the parent dir cifs inode time to zero
84 to force revalidate (faster) for it too? */
85 }
86 /* if not oplocked will force revalidate to get info
87 on source file from srv */
88 cifsInode->time = 0;
89
90 /* Will update parent dir timestamps from srv within a second.
91 Would it really be worth it to set the parent dir (cifs
92 inode) time field to zero to force revalidate on parent
93 directory faster ie
94 CIFS_I(inode)->time = 0; */
79 } 95 }
80 d_drop(direntry); /* force new lookup from server */
81 cifsInode = CIFS_I(old_file->d_inode);
82 cifsInode->time = 0; /* will force revalidate to go get info when needed */
83 96
84cifs_hl_exit: 97cifs_hl_exit:
85 kfree(fromName); 98 kfree(fromName);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index b5b0a2a41b..ed18c3965f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -896,6 +896,10 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
896 tmp_inode->i_ino,obj_type); 896 tmp_inode->i_ino,obj_type);
897 if(rc) { 897 if(rc) {
898 cFYI(1,("filldir rc = %d",rc)); 898 cFYI(1,("filldir rc = %d",rc));
899 /* we can not return filldir errors to the caller
900 since they are "normal" when the stat blocksize
901 is too small - we return remapped error instead */
902 rc = -EOVERFLOW;
899 } 903 }
900 904
901 dput(tmp_dentry); 905 dput(tmp_dentry);
@@ -1074,6 +1078,11 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1074 we want to check for that here? */ 1078 we want to check for that here? */
1075 rc = cifs_filldir(current_entry, file, 1079 rc = cifs_filldir(current_entry, file,
1076 filldir, direntry, tmp_buf, max_len); 1080 filldir, direntry, tmp_buf, max_len);
1081 if(rc == -EOVERFLOW) {
1082 rc = 0;
1083 break;
1084 }
1085
1077 file->f_pos++; 1086 file->f_pos++;
1078 if(file->f_pos == 1087 if(file->f_pos ==
1079 cifsFile->srch_inf.index_of_last_entry) { 1088 cifsFile->srch_inf.index_of_last_entry) {
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index a8a083543b..bbdda99dce 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -90,7 +90,9 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
90 } */ 90 } */
91 /* copy user */ 91 /* copy user */
92 if(ses->userName == NULL) { 92 if(ses->userName == NULL) {
93 /* BB what about null user mounts - check that we do this BB */ 93 /* null user mount */
94 *bcc_ptr = 0;
95 *(bcc_ptr+1) = 0;
94 } else { /* 300 should be long enough for any conceivable user name */ 96 } else { /* 300 should be long enough for any conceivable user name */
95 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, 97 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
96 300, nls_cp); 98 300, nls_cp);
@@ -98,10 +100,13 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
98 bcc_ptr += 2 * bytes_ret; 100 bcc_ptr += 2 * bytes_ret;
99 bcc_ptr += 2; /* account for null termination */ 101 bcc_ptr += 2; /* account for null termination */
100 /* copy domain */ 102 /* copy domain */
101 if(ses->domainName == NULL) 103 if(ses->domainName == NULL) {
102 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, 104 /* Sending null domain better than using a bogus domain name (as
103 "CIFS_LINUX_DOM", 32, nls_cp); 105 we did briefly in 2.6.18) since server will use its default */
104 else 106 *bcc_ptr = 0;
107 *(bcc_ptr+1) = 0;
108 bytes_ret = 0;
109 } else
105 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 110 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
106 256, nls_cp); 111 256, nls_cp);
107 bcc_ptr += 2 * bytes_ret; 112 bcc_ptr += 2 * bytes_ret;
@@ -144,13 +149,11 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
144 149
145 /* copy domain */ 150 /* copy domain */
146 151
147 if(ses->domainName == NULL) { 152 if(ses->domainName != NULL) {
148 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
149 bcc_ptr += 14; /* strlen(CIFS_LINUX_DOM) */
150 } else {
151 strncpy(bcc_ptr, ses->domainName, 256); 153 strncpy(bcc_ptr, ses->domainName, 256);
152 bcc_ptr += strnlen(ses->domainName, 256); 154 bcc_ptr += strnlen(ses->domainName, 256);
153 } 155 } /* else we will send a null domain name
156 so the server will default to its own domain */
154 *bcc_ptr = 0; 157 *bcc_ptr = 0;
155 bcc_ptr++; 158 bcc_ptr++;
156 159