[CIFS] Legacy time handling for Win9x and OS/2 part 1
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
0889a9441d
commit
1bd5bbcb65
6 changed files with 80 additions and 4 deletions
|
@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
|
||||||
extern void DeleteOplockQEntry(struct oplock_q_entry *);
|
extern void DeleteOplockQEntry(struct oplock_q_entry *);
|
||||||
extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
|
extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
|
||||||
extern u64 cifs_UnixTimeToNT(struct timespec);
|
extern u64 cifs_UnixTimeToNT(struct timespec);
|
||||||
|
extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
|
||||||
|
extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
|
||||||
|
|
||||||
extern int cifs_get_inode_info(struct inode **pinode,
|
extern int cifs_get_inode_info(struct inode **pinode,
|
||||||
const unsigned char *search_path,
|
const unsigned char *search_path,
|
||||||
FILE_ALL_INFO * pfile_info,
|
FILE_ALL_INFO * pfile_info,
|
||||||
|
|
|
@ -2856,7 +2856,6 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Legacy Query Path Information call for lookup to old servers such
|
/* Legacy Query Path Information call for lookup to old servers such
|
||||||
as Win9x/WinME */
|
as Win9x/WinME */
|
||||||
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||||
|
@ -2898,7 +2897,16 @@ int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, ("Send error in QueryInfo = %d", rc));
|
cFYI(1, ("Send error in QueryInfo = %d", rc));
|
||||||
} else if (pFinfo) { /* decode response */
|
} else if (pFinfo) { /* decode response */
|
||||||
|
struct timespec ts;
|
||||||
|
__u32 time = le32_to_cpu(pSMBr->last_write_time);
|
||||||
|
/* BB FIXME - add time zone adjustment BB */
|
||||||
memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
|
memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
ts.tv_sec = time;
|
||||||
|
/* decode time fields */
|
||||||
|
pFinfo->ChangeTime = cifs_UnixTimeToNT(ts);
|
||||||
|
pFinfo->LastWriteTime = pFinfo->ChangeTime;
|
||||||
|
pFinfo->LastAccessTime = 0;
|
||||||
pFinfo->AllocationSize =
|
pFinfo->AllocationSize =
|
||||||
cpu_to_le64(le32_to_cpu(pSMBr->size));
|
cpu_to_le64(le32_to_cpu(pSMBr->size));
|
||||||
pFinfo->EndOfFile = pFinfo->AllocationSize;
|
pFinfo->EndOfFile = pFinfo->AllocationSize;
|
||||||
|
|
|
@ -432,8 +432,11 @@ int cifs_get_inode_info(struct inode **pinode,
|
||||||
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
|
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
|
||||||
|
|
||||||
/* Linux can not store file creation time so ignore it */
|
/* Linux can not store file creation time so ignore it */
|
||||||
inode->i_atime =
|
if(pfindData->LastAccessTime)
|
||||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
|
inode->i_atime = cifs_NTtimeToUnix
|
||||||
|
(le64_to_cpu(pfindData->LastAccessTime));
|
||||||
|
else /* do not need to use current_fs_time - time not stored */
|
||||||
|
inode->i_atime = CURRENT_TIME;
|
||||||
inode->i_mtime =
|
inode->i_mtime =
|
||||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
|
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
|
||||||
inode->i_ctime =
|
inode->i_ctime =
|
||||||
|
|
|
@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
|
||||||
tmpbuffer,
|
tmpbuffer,
|
||||||
len - 1,
|
len - 1,
|
||||||
cifs_sb->local_nls);
|
cifs_sb->local_nls);
|
||||||
else {
|
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
|
||||||
|
cERROR(1,("SFU style symlinks not implemented yet"));
|
||||||
|
/* add open and read as in fs/cifs/inode.c */
|
||||||
|
|
||||||
|
} else {
|
||||||
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
|
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
|
||||||
OPEN_REPARSE_POINT,&fid, &oplock, NULL,
|
OPEN_REPARSE_POINT,&fid, &oplock, NULL,
|
||||||
cifs_sb->local_nls,
|
cifs_sb->local_nls,
|
||||||
|
|
|
@ -909,3 +909,54 @@ cifs_UnixTimeToNT(struct timespec t)
|
||||||
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
/* Convert to 100ns intervals and then add the NTFS time offset. */
|
||||||
return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
|
return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int total_days_of_prev_months[] =
|
||||||
|
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||||
|
|
||||||
|
|
||||||
|
__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;*/
|
||||||
|
|
||||||
|
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 += (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));
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
ts.tv_nsec = 0;
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
|
@ -135,12 +135,19 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
|
||||||
tmp_inode->i_ctime =
|
tmp_inode->i_ctime =
|
||||||
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
|
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
|
||||||
} else { /* legacy, OS2 and DOS style */
|
} else { /* legacy, OS2 and DOS style */
|
||||||
|
/* struct timespec ts;*/
|
||||||
FIND_FILE_STANDARD_INFO * pfindData =
|
FIND_FILE_STANDARD_INFO * pfindData =
|
||||||
(FIND_FILE_STANDARD_INFO *)buf;
|
(FIND_FILE_STANDARD_INFO *)buf;
|
||||||
|
|
||||||
|
/* ts = cnvrtDosUnixTm(
|
||||||
|
le16_to_cpu(pfindData->LastWriteDate),
|
||||||
|
le16_to_cpu(pfindData->LastWriteTime));*/
|
||||||
attr = le16_to_cpu(pfindData->Attributes);
|
attr = le16_to_cpu(pfindData->Attributes);
|
||||||
allocation_size = le32_to_cpu(pfindData->AllocationSize);
|
allocation_size = le32_to_cpu(pfindData->AllocationSize);
|
||||||
end_of_file = le32_to_cpu(pfindData->DataSize);
|
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_atime = CURRENT_TIME;
|
||||||
/* tmp_inode->i_mtime = BB FIXME - add dos time handling
|
/* tmp_inode->i_mtime = BB FIXME - add dos time handling
|
||||||
tmp_inode->i_ctime = 0; BB FIXME */
|
tmp_inode->i_ctime = 0; BB FIXME */
|
||||||
|
|
Loading…
Reference in a new issue