aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-09-27 23:35:57 -0400
committerSteve French <sfrench@us.ibm.com>2006-09-27 23:35:57 -0400
commit1bd5bbcb6531776a8f73e2cc6287fc4dd542e1c7 (patch)
tree7c41514f13224d6292a1bb90636f44c3c027b2e8
parent0889a9441d98af7951c5377647413d79c84c9efa (diff)
[CIFS] Legacy time handling for Win9x and OS/2 part 1
Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/cifssmb.c10
-rw-r--r--fs/cifs/inode.c7
-rw-r--r--fs/cifs/link.c6
-rw-r--r--fs/cifs/netmisc.c51
-rw-r--r--fs/cifs/readdir.c7
6 files changed, 80 insertions, 4 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index b35c55c3c8bb..2fbc982aa13d 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
80extern void DeleteOplockQEntry(struct oplock_q_entry *); 80extern void DeleteOplockQEntry(struct oplock_q_entry *);
81extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); 81extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
82extern u64 cifs_UnixTimeToNT(struct timespec); 82extern u64 cifs_UnixTimeToNT(struct timespec);
83extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
84extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
85
83extern int cifs_get_inode_info(struct inode **pinode, 86extern int cifs_get_inode_info(struct inode **pinode,
84 const unsigned char *search_path, 87 const unsigned char *search_path,
85 FILE_ALL_INFO * pfile_info, 88 FILE_ALL_INFO * pfile_info,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 075d8fb3d376..2851d6e0d823 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2856,7 +2856,6 @@ qsec_out:
2856 return rc; 2856 return rc;
2857} 2857}
2858 2858
2859
2860/* Legacy Query Path Information call for lookup to old servers such 2859/* Legacy Query Path Information call for lookup to old servers such
2861 as Win9x/WinME */ 2860 as Win9x/WinME */
2862int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 2861int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -2898,7 +2897,16 @@ QInfRetry:
2898 if (rc) { 2897 if (rc) {
2899 cFYI(1, ("Send error in QueryInfo = %d", rc)); 2898 cFYI(1, ("Send error in QueryInfo = %d", rc));
2900 } else if (pFinfo) { /* decode response */ 2899 } else if (pFinfo) { /* decode response */
2900 struct timespec ts;
2901 __u32 time = le32_to_cpu(pSMBr->last_write_time);
2902 /* BB FIXME - add time zone adjustment BB */
2901 memset(pFinfo, 0, sizeof(FILE_ALL_INFO)); 2903 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
2904 ts.tv_nsec = 0;
2905 ts.tv_sec = time;
2906 /* decode time fields */
2907 pFinfo->ChangeTime = cifs_UnixTimeToNT(ts);
2908 pFinfo->LastWriteTime = pFinfo->ChangeTime;
2909 pFinfo->LastAccessTime = 0;
2902 pFinfo->AllocationSize = 2910 pFinfo->AllocationSize =
2903 cpu_to_le64(le32_to_cpu(pSMBr->size)); 2911 cpu_to_le64(le32_to_cpu(pSMBr->size));
2904 pFinfo->EndOfFile = pFinfo->AllocationSize; 2912 pFinfo->EndOfFile = pFinfo->AllocationSize;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b88147c1dc27..06dbce3a1815 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -432,8 +432,11 @@ int cifs_get_inode_info(struct inode **pinode,
432 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 432 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
433 433
434 /* Linux can not store file creation time so ignore it */ 434 /* Linux can not store file creation time so ignore it */
435 inode->i_atime = 435 if(pfindData->LastAccessTime)
436 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); 436 inode->i_atime = cifs_NTtimeToUnix
437 (le64_to_cpu(pfindData->LastAccessTime));
438 else /* do not need to use current_fs_time - time not stored */
439 inode->i_atime = CURRENT_TIME;
437 inode->i_mtime = 440 inode->i_mtime =
438 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 441 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
439 inode->i_ctime = 442 inode->i_ctime =
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index a57f5d6e6213..0bee8b7e521a 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
254 tmpbuffer, 254 tmpbuffer,
255 len - 1, 255 len - 1,
256 cifs_sb->local_nls); 256 cifs_sb->local_nls);
257 else { 257 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
258 cERROR(1,("SFU style symlinks not implemented yet"));
259 /* add open and read as in fs/cifs/inode.c */
260
261 } else {
258 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 262 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
259 OPEN_REPARSE_POINT,&fid, &oplock, NULL, 263 OPEN_REPARSE_POINT,&fid, &oplock, NULL,
260 cifs_sb->local_nls, 264 cifs_sb->local_nls,
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index ce87550e918f..fa5124d9af19 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -909,3 +909,54 @@ cifs_UnixTimeToNT(struct timespec t)
909 /* Convert to 100ns intervals and then add the NTFS time offset. */ 909 /* Convert to 100ns intervals and then add the NTFS time offset. */
910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; 910 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
911} 911}
912
913static int total_days_of_prev_months[] =
914{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
915
916
917__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
918{
919 return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
920}
921struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
922{
923 __u8 dt[2];
924 __u8 tm[2];
925 struct timespec ts;
926 int sec,min, days, month, year;
927 struct timespec removeme; /* BB removeme BB */
928/* SMB_TIME * st = (SMB_TIME *)&time;*/
929
930 cFYI(1,("date %d time %d",date, time));
931
932 dt[0] = date & 0xFF;
933 dt[1] = (date & 0xFF00) >> 8;
934 tm[0] = time & 0xFF;
935 tm[1] = (time & 0xFF00) >> 8;
936
937 sec = tm[0] & 0x1F;
938 sec = 2 * sec;
939 min = ((tm[0] >>5)&0xFF) + ((tm[1] & 0x7)<<3);
940
941 sec += (min * 60);
942 sec += 60 * 60 * ((tm[1] >> 3) &0xFF) /* hours */;
943 days = (dt[0] & 0x1F) - 1;
944 month = ((dt[0] >> 5) & 0xFF) + ((dt[1] & 0x1) <<3);
945 if(month > 12)
946 cERROR(1,("illegal month %d in date", month));
947 month -= 1;
948 days += total_days_of_prev_months[month];
949 days += 3653; /* account for difference in days between 1980 and 1970 */
950 year = (dt[1]>>1) & 0xFF;
951 days += year * 365;
952 days += (year/4); /* leap year */
953 /* adjust for leap year where we are still before leap day */
954 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
955 sec += 24 * 60 * 60 * days;
956
957 removeme = CURRENT_TIME; /* BB removeme BB */
958 ts.tv_sec = sec;
959
960 ts.tv_nsec = 0;
961 return ts;
962}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9aeb58a7d369..71e86c38e632 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -135,12 +135,19 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
135 tmp_inode->i_ctime = 135 tmp_inode->i_ctime =
136 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 136 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
137 } else { /* legacy, OS2 and DOS style */ 137 } else { /* legacy, OS2 and DOS style */
138/* struct timespec ts;*/
138 FIND_FILE_STANDARD_INFO * pfindData = 139 FIND_FILE_STANDARD_INFO * pfindData =
139 (FIND_FILE_STANDARD_INFO *)buf; 140 (FIND_FILE_STANDARD_INFO *)buf;
140 141
142/* ts = cnvrtDosUnixTm(
143 le16_to_cpu(pfindData->LastWriteDate),
144 le16_to_cpu(pfindData->LastWriteTime));*/
141 attr = le16_to_cpu(pfindData->Attributes); 145 attr = le16_to_cpu(pfindData->Attributes);
142 allocation_size = le32_to_cpu(pfindData->AllocationSize); 146 allocation_size = le32_to_cpu(pfindData->AllocationSize);
143 end_of_file = le32_to_cpu(pfindData->DataSize); 147 end_of_file = le32_to_cpu(pfindData->DataSize);
148 /* do not need to use current_fs_time helper function since
149 time not stored for this case so atime can not "go backwards"
150 by pulling newer older from disk when inode refrenshed */
144 tmp_inode->i_atime = CURRENT_TIME; 151 tmp_inode->i_atime = CURRENT_TIME;
145 /* tmp_inode->i_mtime = BB FIXME - add dos time handling 152 /* tmp_inode->i_mtime = BB FIXME - add dos time handling
146 tmp_inode->i_ctime = 0; BB FIXME */ 153 tmp_inode->i_ctime = 0; BB FIXME */