From 1bd5bbcb6531776a8f73e2cc6287fc4dd542e1c7 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Sep 2006 03:35:57 +0000 Subject: [CIFS] Legacy time handling for Win9x and OS/2 part 1 Signed-off-by: Steve French --- fs/cifs/readdir.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'fs/cifs/readdir.c') 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, tmp_inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); } else { /* legacy, OS2 and DOS style */ +/* struct timespec ts;*/ FIND_FILE_STANDARD_INFO * pfindData = (FIND_FILE_STANDARD_INFO *)buf; +/* ts = cnvrtDosUnixTm( + le16_to_cpu(pfindData->LastWriteDate), + le16_to_cpu(pfindData->LastWriteTime));*/ attr = le16_to_cpu(pfindData->Attributes); allocation_size = le32_to_cpu(pfindData->AllocationSize); end_of_file = le32_to_cpu(pfindData->DataSize); + /* do not need to use current_fs_time helper function since + time not stored for this case so atime can not "go backwards" + by pulling newer older from disk when inode refrenshed */ tmp_inode->i_atime = CURRENT_TIME; /* tmp_inode->i_mtime = BB FIXME - add dos time handling tmp_inode->i_ctime = 0; BB FIXME */ -- cgit v1.2.3 From 203cf2fc13a5db1fb202c294948fa9cb43bf69fa Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 1 Oct 2006 19:59:41 +0000 Subject: [CIFS] Fix readdir of large directories for backlevel servers (were not setting all of resume key) Signed-off-by: Steve French --- fs/cifs/readdir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/cifs/readdir.c') diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 71e86c38e632..b0e5db10664c 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -946,6 +946,7 @@ static int cifs_save_resume_key(const char *current_entry, filename = &pFindData->FileName[0]; /* one byte length, no name conversion */ len = (unsigned int)pFindData->FileNameLength; + cifsFile->srch_inf.resume_key = pFindData->ResumeKey; } else { cFYI(1,("Unknown findfirst level %d",level)); return -EINVAL; -- cgit v1.2.3 From 268f3be177ce93791da38facc34126b5038cd851 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 6 Oct 2006 21:47:09 +0000 Subject: [CIFS] readdir (ffirst) enablement of accurate timestamps from legacy servers Signed-off-by: Steve French --- fs/cifs/netmisc.c | 39 ++++++++++++++++++--------------------- fs/cifs/readdir.c | 18 +++++++++--------- 2 files changed, 27 insertions(+), 30 deletions(-) (limited to 'fs/cifs/readdir.c') diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index fa5124d9af19..3d86b31cf2e4 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -918,45 +918,42 @@ __le64 cnvrtDosCifsTm(__u16 date, __u16 time) { return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); } + struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) { - __u8 dt[2]; - __u8 tm[2]; struct timespec ts; - int sec,min, days, month, year; - struct timespec removeme; /* BB removeme BB */ -/* SMB_TIME * st = (SMB_TIME *)&time;*/ + int sec, min, days, month, year; + SMB_TIME * st = (SMB_TIME *)&time; + SMB_DATE * sd = (SMB_DATE *)&date; cFYI(1,("date %d time %d",date, time)); - dt[0] = date & 0xFF; - dt[1] = (date & 0xFF00) >> 8; - tm[0] = time & 0xFF; - tm[1] = (time & 0xFF00) >> 8; - - sec = tm[0] & 0x1F; - sec = 2 * sec; - min = ((tm[0] >>5)&0xFF) + ((tm[1] & 0x7)<<3); - + sec = 2 * st->TwoSeconds; + min = st->Minutes; + if((sec > 59) || (min > 59)) + cERROR(1,("illegal time min %d sec %d", min, sec)); sec += (min * 60); - sec += 60 * 60 * ((tm[1] >> 3) &0xFF) /* hours */; - days = (dt[0] & 0x1F) - 1; - month = ((dt[0] >> 5) & 0xFF) + ((dt[1] & 0x1) <<3); - if(month > 12) - cERROR(1,("illegal month %d in date", month)); + sec += 60 * 60 * st->Hours; + if(st->Hours > 24) + cERROR(1,("illegal hours %d",st->Hours)); + days = sd->Day; + month = sd->Month; + if((days > 31) || (month > 12)) + cERROR(1,("illegal date, month %d day: %d", month, days)); month -= 1; days += total_days_of_prev_months[month]; days += 3653; /* account for difference in days between 1980 and 1970 */ - year = (dt[1]>>1) & 0xFF; + year = sd->Year; days += year * 365; days += (year/4); /* leap year */ /* adjust for leap year where we are still before leap day */ days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); sec += 24 * 60 * 60 * days; - removeme = CURRENT_TIME; /* BB removeme BB */ ts.tv_sec = sec; + /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ + ts.tv_nsec = 0; return ts; } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index b0e5db10664c..81e7b2e5fb4d 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -139,19 +139,19 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, FIND_FILE_STANDARD_INFO * pfindData = (FIND_FILE_STANDARD_INFO *)buf; -/* ts = cnvrtDosUnixTm( + tmp_inode->i_mtime = cnvrtDosUnixTm( le16_to_cpu(pfindData->LastWriteDate), - le16_to_cpu(pfindData->LastWriteTime));*/ + le16_to_cpu(pfindData->LastWriteTime)); + tmp_inode->i_atime = cnvrtDosUnixTm( + le16_to_cpu(pfindData->LastAccessDate), + le16_to_cpu(pfindData->LastAccessTime)); + tmp_inode->i_ctime = cnvrtDosUnixTm( + le16_to_cpu(pfindData->LastWriteDate), + le16_to_cpu(pfindData->LastWriteTime)); + attr = le16_to_cpu(pfindData->Attributes); allocation_size = le32_to_cpu(pfindData->AllocationSize); end_of_file = le32_to_cpu(pfindData->DataSize); - /* do not need to use current_fs_time helper function since - time not stored for this case so atime can not "go backwards" - by pulling newer older from disk when inode refrenshed */ - tmp_inode->i_atime = CURRENT_TIME; - /* tmp_inode->i_mtime = BB FIXME - add dos time handling - tmp_inode->i_ctime = 0; BB FIXME */ - } /* Linux can not store file creation time unfortunately so ignore it */ -- cgit v1.2.3 From 533f90af6d90b9e4859a158565385d1d84a79f75 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 12 Oct 2006 00:02:32 +0000 Subject: [CIFS] Fix old DOS time conversion to handle timezone Signed-off-by: Steve French --- fs/cifs/netmisc.c | 2 +- fs/cifs/readdir.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'fs/cifs/readdir.c') diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 3adbd128e08e..992e80edc720 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -942,7 +942,7 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) cERROR(1,("illegal date, month %d day: %d", month, days)); month -= 1; days += total_days_of_prev_months[month]; - days += 3653; /* account for difference in days between 1980 and 1970 */ + days += 3652; /* account for difference in days between 1980 and 1970 */ year = sd->Year; days += year * 365; days += (year/4); /* leap year */ diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 81e7b2e5fb4d..80e6ebd440a8 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -106,6 +106,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file, return rc; } +static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) +{ + if((tcon) && (tcon->ses) && (tcon->ses->server)) { + inode->i_ctime.tv_sec += tcon->ses->server.timeAdj; + inode->i_mtime.tv_sec += tcon->ses->server.timeAdj; + inode->i_atime.tv_sec += tcon->ses->server.timeAdj; + } + return; +} + + static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, char * buf, int *pobject_type, int isNewInode) { @@ -148,7 +159,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, tmp_inode->i_ctime = cnvrtDosUnixTm( le16_to_cpu(pfindData->LastWriteDate), le16_to_cpu(pfindData->LastWriteTime)); - + AdjustForTZ(cifs_sb->tcon, tmp_inode); attr = le16_to_cpu(pfindData->Attributes); allocation_size = le32_to_cpu(pfindData->AllocationSize); end_of_file = le32_to_cpu(pfindData->DataSize); -- cgit v1.2.3 From ddae957da48cc381c1472a8909905e1818e4afdd Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 12 Oct 2006 01:23:29 +0000 Subject: [CIFS] fix typo in previous patch Signed-off-by: Steve French --- fs/cifs/readdir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs/cifs/readdir.c') diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 80e6ebd440a8..acbabc09543f 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -109,9 +109,9 @@ static int construct_dentry(struct qstr *qstring, struct file *file, static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode) { if((tcon) && (tcon->ses) && (tcon->ses->server)) { - inode->i_ctime.tv_sec += tcon->ses->server.timeAdj; - inode->i_mtime.tv_sec += tcon->ses->server.timeAdj; - inode->i_atime.tv_sec += tcon->ses->server.timeAdj; + inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; + inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; + inode->i_atime.tv_sec += tcon->ses->server->timeAdj; } return; } -- cgit v1.2.3