Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 97147
b: refs/heads/master
c: 0e4bbde
h: refs/heads/master
i:
  97145: 83036bc
  97143: 1b4d9aa
v: v3
  • Loading branch information
Steve French committed May 20, 2008
1 parent af8b6fd commit d2f95ca
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 89562b777c50d100d1694db7b1b023279839b9ae
refs/heads/master: 0e4bbde94fdc33f5b3d793166b21bf768ca3e098
1 change: 1 addition & 0 deletions trunk/fs/cifs/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Miklos Szeredi
Kazeon team for various fixes especially for 2.4 version.
Asser Ferno (Change Notify support)
Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
Igor Mammedov (DFS support)

Test case and Bug Report contributors
-------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/cifs/CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Version 1.53
------------
DFS support added (Microsoft Distributed File System client support needed
for referrals which enable a hierarchical name space among servers).

Version 1.52
------------
Expand Down
15 changes: 8 additions & 7 deletions trunk/fs/cifs/TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Version 1.52 January 3, 2008
Version 1.53 May 20, 2008

A Partial List of Missing Features
==================================
Expand All @@ -20,20 +20,21 @@ d) Cleanup now unneeded SessSetup code in
fs/cifs/connect.c and add back in NTLMSSP code if any servers
need it

e) ms-dfs and ms-dfs host name resolution cleanup

f) fix NTLMv2 signing when two mounts with different users to same
e) fix NTLMv2 signing when two mounts with different users to same
server.

g) Directory entry caching relies on a 1 second timer, rather than
f) Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started)

h) quota support (needs minor kernel change since quota calls
g) quota support (needs minor kernel change since quota calls
to make it to network filesystems or deviceless filesystems)

i) investigate sync behavior (including syncpage) and check
h) investigate sync behavior (including syncpage) and check
for proper behavior of intr/nointr

i) improve support for very old servers (OS/2 and Win9x for example)
Including support for changing the time remotely (utimes command).

j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
extra copy in/out of the socket buffers in some cases.

Expand Down
117 changes: 74 additions & 43 deletions trunk/fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,77 +161,108 @@ static void cifs_unix_info_to_inode(struct inode *inode,
spin_unlock(&inode->i_lock);
}

static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
struct super_block *sb)
{
struct inode *pinode = NULL;

memset(pfnd_dat, sizeof(FILE_UNIX_BASIC_INFO), 0);

/* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
__le64 pfnd_dat->NumOfBytes = cpu_to_le64(0);
__u64 UniqueId = 0; */
pfnd_dat->LastStatusChange =
cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
pfnd_dat->LastAccessTime =
cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
pfnd_dat->LastModificationTime =
cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
pfnd_dat->Type = cpu_to_le32(UNIX_DIR);
pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU);
pfnd_dat->Nlinks = cpu_to_le64(2);
if (sb->s_root)
pinode = sb->s_root->d_inode;
if (pinode == NULL)
return;

/* fill in default values for the remaining based on root
inode since we can not query the server for this inode info */
pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
}

int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *full_path, struct super_block *sb, int xid)
{
int rc = 0;
FILE_UNIX_BASIC_INFO findData;
FILE_UNIX_BASIC_INFO find_data;
struct cifsTconInfo *pTcon;
struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
bool is_dfs_referral = false;
struct cifsInodeInfo *cifsInfo;
__u64 num_of_bytes;
__u64 end_of_file;

pTcon = cifs_sb->tcon;
cFYI(1, ("Getting info on %s", full_path));

try_again_CIFSSMBUnixQPathInfo:
/* could have done a find first instead but this returns more info */
rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData,
rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
/* dump_mem("\nUnixQPathInfo return data", &findData,
sizeof(findData)); */
if (rc) {
if (rc == -EREMOTE && !is_dfs_referral) {
is_dfs_referral = true;
goto try_again_CIFSSMBUnixQPathInfo;
cERROR(1, ("DFS ref")); /* BB removeme BB */
/* for DFS, server does not give us real inode data */
fill_fake_finddataunix(&find_data, sb);
rc = 0;
}
goto cgiiu_exit;
} else {
struct cifsInodeInfo *cifsInfo;
__u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
__u64 end_of_file = le64_to_cpu(findData.EndOfFile);
}
num_of_bytes = le64_to_cpu(find_data.NumOfBytes);
end_of_file = le64_to_cpu(find_data.EndOfFile);

/* get new inode */
/* get new inode */
if (*pinode == NULL) {
*pinode = new_inode(sb);
if (*pinode == NULL) {
*pinode = new_inode(sb);
if (*pinode == NULL) {
rc = -ENOMEM;
goto cgiiu_exit;
}
/* Is an i_ino of zero legal? */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
(*pinode)->i_ino =
(unsigned long)findData.UniqueId;
} /* note ino incremented to unique num in new_inode */
if (sb->s_flags & MS_NOATIME)
(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;

insert_inode_hash(*pinode);
rc = -ENOMEM;
goto cgiiu_exit;
}
/* Is an i_ino of zero legal? */
/* note ino incremented to unique num in new_inode */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
(*pinode)->i_ino = (unsigned long)find_data.UniqueId;

inode = *pinode;
cifsInfo = CIFS_I(inode);
if (sb->s_flags & MS_NOATIME)
(*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;

cFYI(1, ("Old time %ld", cifsInfo->time));
cifsInfo->time = jiffies;
cFYI(1, ("New time %ld", cifsInfo->time));
/* this is ok to set on every inode revalidate */
atomic_set(&cifsInfo->inUse, 1);
insert_inode_hash(*pinode);
}

cifs_unix_info_to_inode(inode, &findData, 0);
inode = *pinode;
cifsInfo = CIFS_I(inode);

cFYI(1, ("Old time %ld", cifsInfo->time));
cifsInfo->time = jiffies;
cFYI(1, ("New time %ld", cifsInfo->time));
/* this is ok to set on every inode revalidate */
atomic_set(&cifsInfo->inUse, 1);

if (num_of_bytes < end_of_file)
cFYI(1, ("allocation size less than end of file"));
cFYI(1, ("Size %ld and blocks %llu",
(unsigned long) inode->i_size,
(unsigned long long)inode->i_blocks));
cifs_unix_info_to_inode(inode, &find_data, 0);

cifs_set_ops(inode, is_dfs_referral);
}
if (num_of_bytes < end_of_file)
cFYI(1, ("allocation size less than end of file"));
cFYI(1, ("Size %ld and blocks %llu",
(unsigned long) inode->i_size,
(unsigned long long)inode->i_blocks));

cifs_set_ops(inode, is_dfs_referral);
cgiiu_exit:
return rc;
}
Expand Down

0 comments on commit d2f95ca

Please sign in to comment.