aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/inode.c47
-rw-r--r--fs/cifs/readdir.c31
2 files changed, 56 insertions, 22 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 93dd705577bc..ffc7305841b3 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -41,7 +41,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
41 char *tmp_path; 41 char *tmp_path;
42 42
43 pTcon = cifs_sb->tcon; 43 pTcon = cifs_sb->tcon;
44 cFYI(1, (" Getting info on %s ", search_path)); 44 cFYI(1, ("Getting info on %s ", search_path));
45 /* could have done a find first instead but this returns more info */ 45 /* could have done a find first instead but this returns more info */
46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, 46 rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 47 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -111,6 +111,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
111 inode->i_ctime = 111 inode->i_ctime =
112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange)); 112 cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
113 inode->i_mode = le64_to_cpu(findData.Permissions); 113 inode->i_mode = le64_to_cpu(findData.Permissions);
114 /* since we set the inode type below we need to mask off
115 to avoid strange results if bits set above */
116 inode->i_mode &= ~S_IFMT;
114 if (type == UNIX_FILE) { 117 if (type == UNIX_FILE) {
115 inode->i_mode |= S_IFREG; 118 inode->i_mode |= S_IFREG;
116 } else if (type == UNIX_SYMLINK) { 119 } else if (type == UNIX_SYMLINK) {
@@ -129,6 +132,10 @@ int cifs_get_inode_info_unix(struct inode **pinode,
129 inode->i_mode |= S_IFIFO; 132 inode->i_mode |= S_IFIFO;
130 } else if (type == UNIX_SOCKET) { 133 } else if (type == UNIX_SOCKET) {
131 inode->i_mode |= S_IFSOCK; 134 inode->i_mode |= S_IFSOCK;
135 } else {
136 /* safest to call it a file if we do not know */
137 inode->i_mode |= S_IFREG;
138 cFYI(1,("unknown type %d",type));
132 } 139 }
133 inode->i_uid = le64_to_cpu(findData.Uid); 140 inode->i_uid = le64_to_cpu(findData.Uid);
134 inode->i_gid = le64_to_cpu(findData.Gid); 141 inode->i_gid = le64_to_cpu(findData.Gid);
@@ -228,20 +235,19 @@ static int decode_sfu_inode(struct inode * inode, __u64 size,
228 8 /* length */, 0 /* offset */, 235 8 /* length */, 0 /* offset */,
229 &bytes_read, &pbuf); 236 &bytes_read, &pbuf);
230 if((rc == 0) && (bytes_read == 8)) { 237 if((rc == 0) && (bytes_read == 8)) {
231 cERROR(1,("intx %s" ,pbuf));
232 if(memcmp("IntxBLK", pbuf, 8) == 0) { 238 if(memcmp("IntxBLK", pbuf, 8) == 0) {
233 cFYI(1,("Block device")); 239 cFYI(1,("Block device"));
234 inode->i_mode = S_IFBLK; 240 inode->i_mode |= S_IFBLK;
235 } else if(memcmp("IntxCHR", pbuf, 8) == 0) { 241 } else if(memcmp("IntxCHR", pbuf, 8) == 0) {
236 cFYI(1,("Char device")); 242 cFYI(1,("Char device"));
237 inode->i_mode = S_IFCHR; 243 inode->i_mode |= S_IFCHR;
238 } else if(memcmp("IntxLNK", pbuf, 7) == 0) { 244 } else if(memcmp("IntxLNK", pbuf, 7) == 0) {
239 cFYI(1,("Symlink")); 245 cFYI(1,("Symlink"));
240 inode->i_mode = S_IFLNK; 246 inode->i_mode |= S_IFLNK;
241 } else 247 }
242 inode->i_mode = S_IFREG; /* then it is a file */ 248 } else {
243 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 249 inode->i_mode |= S_IFREG; /* then it is a file */
244 250 rc = -EOPNOTSUPP; /* or some unknown SFU type */
245 } 251 }
246 252
247 CIFSSMBClose(xid, pTcon, netfid); 253 CIFSSMBClose(xid, pTcon, netfid);
@@ -261,6 +267,7 @@ static int get_sfu_uid_mode(struct inode * inode,
261 const unsigned char *path, 267 const unsigned char *path,
262 struct cifs_sb_info *cifs_sb, int xid) 268 struct cifs_sb_info *cifs_sb, int xid)
263{ 269{
270#ifdef CONFIG_CIFS_XATTR
264 ssize_t rc; 271 ssize_t rc;
265 char ea_value[4]; 272 char ea_value[4];
266 __u32 mode; 273 __u32 mode;
@@ -272,12 +279,17 @@ static int get_sfu_uid_mode(struct inode * inode,
272 return (int)rc; 279 return (int)rc;
273 else if (rc > 3) { 280 else if (rc > 3) {
274 mode = le32_to_cpu(*((__le32 *)ea_value)); 281 mode = le32_to_cpu(*((__le32 *)ea_value));
282 cFYI(1,("special bits 0%o org mode 0%o", mode, inode->i_mode));
275 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 283 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode;
276 cFYI(1,("special mode bits 0%o", mode)); 284 cFYI(1,("special mode bits 0%o", mode));
277 return 0; 285 return 0;
278 } else { 286 } else {
279 return 0; 287 return 0;
280 } 288 }
289#else
290 return -EOPNOTSUPP;
291#endif
292
281 293
282} 294}
283 295
@@ -394,9 +406,9 @@ int cifs_get_inode_info(struct inode **pinode,
394 inode = *pinode; 406 inode = *pinode;
395 cifsInfo = CIFS_I(inode); 407 cifsInfo = CIFS_I(inode);
396 cifsInfo->cifsAttrs = attr; 408 cifsInfo->cifsAttrs = attr;
397 cFYI(1, (" Old time %ld ", cifsInfo->time)); 409 cFYI(1, ("Old time %ld ", cifsInfo->time));
398 cifsInfo->time = jiffies; 410 cifsInfo->time = jiffies;
399 cFYI(1, (" New time %ld ", cifsInfo->time)); 411 cFYI(1, ("New time %ld ", cifsInfo->time));
400 412
401 /* blksize needs to be multiple of two. So safer to default to 413 /* blksize needs to be multiple of two. So safer to default to
402 blksize and blkbits set in superblock so 2**blkbits and blksize 414 blksize and blkbits set in superblock so 2**blkbits and blksize
@@ -410,13 +422,15 @@ int cifs_get_inode_info(struct inode **pinode,
410 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); 422 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
411 inode->i_ctime = 423 inode->i_ctime =
412 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); 424 cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
413 cFYI(0, (" Attributes came in as 0x%x ", attr)); 425 cFYI(0, ("Attributes came in as 0x%x ", attr));
414 426
415 /* set default mode. will override for dirs below */ 427 /* set default mode. will override for dirs below */
416 if (atomic_read(&cifsInfo->inUse) == 0) 428 if (atomic_read(&cifsInfo->inUse) == 0)
417 /* new inode, can safely set these fields */ 429 /* new inode, can safely set these fields */
418 inode->i_mode = cifs_sb->mnt_file_mode; 430 inode->i_mode = cifs_sb->mnt_file_mode;
419 431 else /* since we set the inode type below we need to mask off
432 to avoid strange results if type changes and both get orred in */
433 inode->i_mode &= ~S_IFMT;
420/* if (attr & ATTR_REPARSE) */ 434/* if (attr & ATTR_REPARSE) */
421 /* We no longer handle these as symlinks because we could not 435 /* We no longer handle these as symlinks because we could not
422 follow them due to the absolute path with drive letter */ 436 follow them due to the absolute path with drive letter */
@@ -440,6 +454,7 @@ int cifs_get_inode_info(struct inode **pinode,
440 cifs_sb, xid)) { 454 cifs_sb, xid)) {
441 cFYI(1,("Unrecognized sfu inode type")); 455 cFYI(1,("Unrecognized sfu inode type"));
442 } 456 }
457 cFYI(1,("sfu mode 0%o",inode->i_mode));
443 } else { 458 } else {
444 inode->i_mode |= S_IFREG; 459 inode->i_mode |= S_IFREG;
445 /* treat the dos attribute of read-only as read-only 460 /* treat the dos attribute of read-only as read-only
@@ -535,7 +550,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
535 struct cifsInodeInfo *cifsInode; 550 struct cifsInodeInfo *cifsInode;
536 FILE_BASIC_INFO *pinfo_buf; 551 FILE_BASIC_INFO *pinfo_buf;
537 552
538 cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); 553 cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode));
539 554
540 xid = GetXid(); 555 xid = GetXid();
541 556
@@ -755,7 +770,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
755 char *full_path = NULL; 770 char *full_path = NULL;
756 struct cifsInodeInfo *cifsInode; 771 struct cifsInodeInfo *cifsInode;
757 772
758 cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); 773 cFYI(1, ("cifs_rmdir, inode = 0x%p with ", inode));
759 774
760 xid = GetXid(); 775 xid = GetXid();
761 776
@@ -1074,7 +1089,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1074 1089
1075 xid = GetXid(); 1090 xid = GetXid();
1076 1091
1077 cFYI(1, (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1092 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
1078 direntry->d_name.name, attrs->ia_valid)); 1093 direntry->d_name.name, attrs->ia_valid));
1079 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); 1094 cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
1080 pTcon = cifs_sb->tcon; 1095 pTcon = cifs_sb->tcon;
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 9b7e0ff9584b..9bdaaecae36f 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -142,6 +142,11 @@ static void fill_in_inode(struct inode *tmp_inode,
142 tmp_inode->i_gid = cifs_sb->mnt_gid; 142 tmp_inode->i_gid = cifs_sb->mnt_gid;
143 /* set default mode. will override for dirs below */ 143 /* set default mode. will override for dirs below */
144 tmp_inode->i_mode = cifs_sb->mnt_file_mode; 144 tmp_inode->i_mode = cifs_sb->mnt_file_mode;
145 } else {
146 /* mask off the type bits since it gets set
147 below and we do not want to get two type
148 bits set */
149 tmp_inode->i_mode &= ~S_IFMT;
145 } 150 }
146 151
147 if (attr & ATTR_DIRECTORY) { 152 if (attr & ATTR_DIRECTORY) {
@@ -152,12 +157,18 @@ static void fill_in_inode(struct inode *tmp_inode,
152 } 157 }
153 tmp_inode->i_mode |= S_IFDIR; 158 tmp_inode->i_mode |= S_IFDIR;
154 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 159 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
155 (attr & ATTR_SYSTEM) && (end_of_file == 0)) { 160 (attr & ATTR_SYSTEM)) {
156 *pobject_type = DT_FIFO; 161 if (end_of_file == 0) {
157 tmp_inode->i_mode |= S_IFIFO; 162 *pobject_type = DT_FIFO;
158/* BB Finish for SFU style symlinks and devies */ 163 tmp_inode->i_mode |= S_IFIFO;
159/* } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && 164 } else {
160 (attr & ATTR_SYSTEM) && ) { */ 165 /* rather than get the type here, we mark the
166 inode as needing revalidate and get the real type
167 (blk vs chr vs. symlink) later ie in lookup */
168 *pobject_type = DT_REG;
169 tmp_inode->i_mode |= S_IFREG;
170 cifsInfo->time = 0;
171 }
161/* we no longer mark these because we could not follow them */ 172/* we no longer mark these because we could not follow them */
162/* } else if (attr & ATTR_REPARSE) { 173/* } else if (attr & ATTR_REPARSE) {
163 *pobject_type = DT_LNK; 174 *pobject_type = DT_LNK;
@@ -264,6 +275,9 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
264 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); 275 cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
265 276
266 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 277 tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
278 /* since we set the inode type below we need to mask off type
279 to avoid strange results if bits above were corrupt */
280 tmp_inode->i_mode &= ~S_IFMT;
267 if (type == UNIX_FILE) { 281 if (type == UNIX_FILE) {
268 *pobject_type = DT_REG; 282 *pobject_type = DT_REG;
269 tmp_inode->i_mode |= S_IFREG; 283 tmp_inode->i_mode |= S_IFREG;
@@ -289,6 +303,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode,
289 } else if (type == UNIX_SOCKET) { 303 } else if (type == UNIX_SOCKET) {
290 *pobject_type = DT_SOCK; 304 *pobject_type = DT_SOCK;
291 tmp_inode->i_mode |= S_IFSOCK; 305 tmp_inode->i_mode |= S_IFSOCK;
306 } else {
307 /* safest to just call it a file */
308 *pobject_type = DT_REG;
309 tmp_inode->i_mode |= S_IFREG;
310 cFYI(1,("unknown inode type %d",type));
292 } 311 }
293 312
294 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 313 tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);