aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-11-17 19:59:21 -0500
committerSteve French <sfrench@us.ibm.com>2005-11-17 19:59:21 -0500
commit9e294f1c4d4a5fc0068fcb21f5809ff6e88e49bc (patch)
tree955f905c13f9d8d21c3e0c90f37849ff6170febd /fs/cifs
parent0f2b27c438cb593717dde8ee0fc05e0874eabbb6 (diff)
[CIFS] Recognize properly symlinks and char/blk devices (not just
FIFOs) created by SFU (part 2 of 2). Thanks to Martin Koeppe for useful analysis. Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/inode.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index ba9eae56d011..93dd705577bc 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -228,9 +228,20 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
228 8 /* length */, 0 /* offset */, 228 8 /* length */, 0 /* offset */,
229 &bytes_read, &pbuf); 229 &bytes_read, &pbuf);
230 if((rc == 0) && (bytes_read == 8)) { 230 if((rc == 0) && (bytes_read == 8)) {
231 /* if memcmp(IntxCHR\000, pbuf, 8) 231 cERROR(1,("intx %s" ,pbuf));
232 else if memcmp(IntxBLK\000, pbuf, 8) 232 if(memcmp("IntxBLK", pbuf, 8) == 0) {
233 else if memcmp(IntxLNK\001, pbuf, 8) */ 233 cFYI(1,("Block device"));
234 inode->i_mode = S_IFBLK;
235 } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
236 cFYI(1,("Char device"));
237 inode->i_mode = S_IFCHR;
238 } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
239 cFYI(1,("Symlink"));
240 inode->i_mode = S_IFLNK;
241 } else
242 inode->i_mode = S_IFREG; /* then it is a file */
243 rc = -EOPNOTSUPP; /* or some unknown SFU type */
244
234 } 245 }
235 246
236 CIFSSMBClose(xid, pTcon, netfid); 247 CIFSSMBClose(xid, pTcon, netfid);
@@ -244,6 +255,32 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
244 255
245} 256}
246 257
258#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
259
260static int get_sfu_uid_mode(struct inode * inode,
261 const unsigned char *path,
262 struct cifs_sb_info *cifs_sb, int xid)
263{
264 ssize_t rc;
265 char ea_value[4];
266 __u32 mode;
267
268 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
269 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
270 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
271 if(rc < 0)
272 return (int)rc;
273 else if (rc > 3) {
274 mode = le32_to_cpu(*((__le32 *)ea_value));
275 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
276 cFYI(1,("special mode bits 0%o", mode));
277 return 0;
278 } else {
279 return 0;
280 }
281
282}
283
247int cifs_get_inode_info(struct inode **pinode, 284int cifs_get_inode_info(struct inode **pinode,
248 const unsigned char *search_path, FILE_ALL_INFO *pfindData, 285 const unsigned char *search_path, FILE_ALL_INFO *pfindData,
249 struct super_block *sb, int xid) 286 struct super_block *sb, int xid)
@@ -427,7 +464,10 @@ int cifs_get_inode_info(struct inode **pinode,
427 464
428 /* BB fill in uid and gid here? with help from winbind? 465 /* BB fill in uid and gid here? with help from winbind?
429 or retrieve from NTFS stream extended attribute */ 466 or retrieve from NTFS stream extended attribute */
430 if (atomic_read(&cifsInfo->inUse) == 0) { 467 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
468 /* fill in uid, gid, mode from server ACL */
469 get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
470 } else if (atomic_read(&cifsInfo->inUse) == 0) {
431 inode->i_uid = cifs_sb->mnt_uid; 471 inode->i_uid = cifs_sb->mnt_uid;
432 inode->i_gid = cifs_sb->mnt_gid; 472 inode->i_gid = cifs_sb->mnt_gid;
433 /* set so we do not keep refreshing these fields with 473 /* set so we do not keep refreshing these fields with