diff options
author | Steve French <sfrench@us.ibm.com> | 2005-11-15 19:43:39 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-11-15 19:43:39 -0500 |
commit | d6e2f2a4c892e4d131ab4fa5d212546c47dd3c40 (patch) | |
tree | ce457134489d125f496247997f60fe1c5d2d3077 /fs/cifs | |
parent | 7b0a65f9923ffe7885a5473648baaa3a1a701726 (diff) |
[CIFS] Recognize properly symlinks and char/blk devices (not just FIFOs)
created by SFU (part 1 of 2).
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/CHANGES | 2 | ||||
-rw-r--r-- | fs/cifs/inode.c | 74 |
2 files changed, 66 insertions, 10 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index eab3750cf304..289e4079c96b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -3,6 +3,8 @@ Version 1.39 | |||
3 | Defer close of a file handle slightly if pending writes depend on that file handle | 3 | Defer close of a file handle slightly if pending writes depend on that file handle |
4 | (this reduces the EBADF bad file handle errors that can be logged under heavy | 4 | (this reduces the EBADF bad file handle errors that can be logged under heavy |
5 | stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 | 5 | stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 |
6 | Fix SFU style symlinks and mknod needed for servers which do not support the CIFS | ||
7 | Unix Extensions. | ||
6 | 8 | ||
7 | Version 1.38 | 9 | Version 1.38 |
8 | ------------ | 10 | ------------ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 941b247fceb0..ba9eae56d011 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -97,9 +97,9 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
97 | inode = *pinode; | 97 | inode = *pinode; |
98 | cifsInfo = CIFS_I(inode); | 98 | cifsInfo = CIFS_I(inode); |
99 | 99 | ||
100 | cFYI(1, (" Old time %ld ", cifsInfo->time)); | 100 | cFYI(1, ("Old time %ld ", cifsInfo->time)); |
101 | cifsInfo->time = jiffies; | 101 | cifsInfo->time = jiffies; |
102 | cFYI(1, (" New time %ld ", cifsInfo->time)); | 102 | cFYI(1, ("New time %ld ", cifsInfo->time)); |
103 | /* this is ok to set on every inode revalidate */ | 103 | /* this is ok to set on every inode revalidate */ |
104 | atomic_set(&cifsInfo->inUse,1); | 104 | atomic_set(&cifsInfo->inUse,1); |
105 | 105 | ||
@@ -195,6 +195,55 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
195 | return rc; | 195 | return rc; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int decode_sfu_inode(struct inode * inode, __u64 size, | ||
199 | const unsigned char *path, | ||
200 | struct cifs_sb_info *cifs_sb, int xid) | ||
201 | { | ||
202 | int rc; | ||
203 | int oplock = FALSE; | ||
204 | __u16 netfid; | ||
205 | struct cifsTconInfo *pTcon = cifs_sb->tcon; | ||
206 | char buf[8]; | ||
207 | unsigned int bytes_read; | ||
208 | char * pbuf; | ||
209 | |||
210 | pbuf = buf; | ||
211 | |||
212 | if(size == 0) { | ||
213 | inode->i_mode |= S_IFIFO; | ||
214 | return 0; | ||
215 | } else if (size < 8) { | ||
216 | return -EINVAL; /* EOPNOTSUPP? */ | ||
217 | } | ||
218 | |||
219 | rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ, | ||
220 | CREATE_NOT_DIR, &netfid, &oplock, NULL, | ||
221 | cifs_sb->local_nls, | ||
222 | cifs_sb->mnt_cifs_flags & | ||
223 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
224 | if (rc==0) { | ||
225 | /* Read header */ | ||
226 | rc = CIFSSMBRead(xid, pTcon, | ||
227 | netfid, | ||
228 | 8 /* length */, 0 /* offset */, | ||
229 | &bytes_read, &pbuf); | ||
230 | if((rc == 0) && (bytes_read == 8)) { | ||
231 | /* if memcmp(IntxCHR\000, pbuf, 8) | ||
232 | else if memcmp(IntxBLK\000, pbuf, 8) | ||
233 | else if memcmp(IntxLNK\001, pbuf, 8) */ | ||
234 | } | ||
235 | |||
236 | CIFSSMBClose(xid, pTcon, netfid); | ||
237 | |||
238 | |||
239 | /* inode->i_rdev = MKDEV(le64_to_cpu(DevMajor), | ||
240 | le64_to_cpu(DevMinor) & MINORMASK);*/ | ||
241 | /* inode->i_mode |= S_IFBLK; */ | ||
242 | } | ||
243 | return rc; | ||
244 | |||
245 | } | ||
246 | |||
198 | int cifs_get_inode_info(struct inode **pinode, | 247 | int cifs_get_inode_info(struct inode **pinode, |
199 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, | 248 | const unsigned char *search_path, FILE_ALL_INFO *pfindData, |
200 | struct super_block *sb, int xid) | 249 | struct super_block *sb, int xid) |
@@ -207,7 +256,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
207 | char *buf = NULL; | 256 | char *buf = NULL; |
208 | 257 | ||
209 | pTcon = cifs_sb->tcon; | 258 | pTcon = cifs_sb->tcon; |
210 | cFYI(1,("Getting info on %s ", search_path)); | 259 | cFYI(1,("Getting info on %s", search_path)); |
211 | 260 | ||
212 | if ((pfindData == NULL) && (*pinode != NULL)) { | 261 | if ((pfindData == NULL) && (*pinode != NULL)) { |
213 | if (CIFS_I(*pinode)->clientCanCacheRead) { | 262 | if (CIFS_I(*pinode)->clientCanCacheRead) { |
@@ -345,10 +394,15 @@ int cifs_get_inode_info(struct inode **pinode, | |||
345 | (pfindData->EndOfFile == 0)) { | 394 | (pfindData->EndOfFile == 0)) { |
346 | inode->i_mode = cifs_sb->mnt_file_mode; | 395 | inode->i_mode = cifs_sb->mnt_file_mode; |
347 | inode->i_mode |= S_IFIFO; | 396 | inode->i_mode |= S_IFIFO; |
348 | /* BB Finish for SFU style symlinks and devies */ | 397 | /* BB Finish for SFU style symlinks and devices */ |
349 | /* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && | 398 | } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && |
350 | (cifsInfo->cifsAttrs & ATTR_SYSTEM) && ) */ | 399 | (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { |
351 | 400 | if (decode_sfu_inode(inode, | |
401 | le64_to_cpu(pfindData->EndOfFile), | ||
402 | search_path, | ||
403 | cifs_sb, xid)) { | ||
404 | cFYI(1,("Unrecognized sfu inode type")); | ||
405 | } | ||
352 | } else { | 406 | } else { |
353 | inode->i_mode |= S_IFREG; | 407 | inode->i_mode |= S_IFREG; |
354 | /* treat the dos attribute of read-only as read-only | 408 | /* treat the dos attribute of read-only as read-only |
@@ -382,7 +436,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
382 | } | 436 | } |
383 | 437 | ||
384 | if (S_ISREG(inode->i_mode)) { | 438 | if (S_ISREG(inode->i_mode)) { |
385 | cFYI(1, (" File inode ")); | 439 | cFYI(1, ("File inode")); |
386 | inode->i_op = &cifs_file_inode_ops; | 440 | inode->i_op = &cifs_file_inode_ops; |
387 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { | 441 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { |
388 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 442 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
@@ -400,11 +454,11 @@ int cifs_get_inode_info(struct inode **pinode, | |||
400 | 4096 + MAX_CIFS_HDR_SIZE) | 454 | 4096 + MAX_CIFS_HDR_SIZE) |
401 | inode->i_data.a_ops->readpages = NULL; | 455 | inode->i_data.a_ops->readpages = NULL; |
402 | } else if (S_ISDIR(inode->i_mode)) { | 456 | } else if (S_ISDIR(inode->i_mode)) { |
403 | cFYI(1, (" Directory inode ")); | 457 | cFYI(1, ("Directory inode")); |
404 | inode->i_op = &cifs_dir_inode_ops; | 458 | inode->i_op = &cifs_dir_inode_ops; |
405 | inode->i_fop = &cifs_dir_ops; | 459 | inode->i_fop = &cifs_dir_ops; |
406 | } else if (S_ISLNK(inode->i_mode)) { | 460 | } else if (S_ISLNK(inode->i_mode)) { |
407 | cFYI(1, (" Symbolic Link inode ")); | 461 | cFYI(1, ("Symbolic Link inode")); |
408 | inode->i_op = &cifs_symlink_inode_ops; | 462 | inode->i_op = &cifs_symlink_inode_ops; |
409 | } else { | 463 | } else { |
410 | init_special_inode(inode, inode->i_mode, | 464 | init_special_inode(inode, inode->i_mode, |