Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
cifs: when ATTR_READONLY is set, only clear write bits on non-directories
cifs: remove cifsInodeInfo->inUse counter
cifs: convert cifs_get_inode_info and non-posix readdir to use cifs_iget
[CIFS] update cifs version number
cifs: add and use CIFSSMBUnixSetFileInfo for setattr calls
cifs: make a separate function for filling out FILE_UNIX_BASIC_INFO
cifs: rename CIFSSMBUnixSetInfo to CIFSSMBUnixSetPathInfo
cifs: add pid of initiating process to spnego upcall info
cifs: fix regression with O_EXCL creates and optimize away lookup
cifs: add new cifs_iget function and convert unix codepath to use it

+704 -914
+5 -1
fs/cifs/CHANGES
··· 5 on by default if server supports it). Add forceuid and forcegid 6 mount options (so that when negotiating unix extensions specifying 7 which uid mounted does not immediately force the server's reported 8 - uids to be overridden). Add support for scope moutn parm. 9 10 Version 1.58 11 ------------
··· 5 on by default if server supports it). Add forceuid and forcegid 6 mount options (so that when negotiating unix extensions specifying 7 which uid mounted does not immediately force the server's reported 8 + uids to be overridden). Add support for scope mount parm. Improve 9 + hard link detection to use same inode for both. Do not set 10 + read-only dos attribute on directories (for chmod) since Windows 11 + explorer special cases this attribute bit for directories for 12 + a different purpose. 13 14 Version 1.58 15 ------------
+8 -1
fs/cifs/cifs_spnego.c
··· 86 /* strlen of ";user=" */ 87 #define USER_KEY_LEN 6 88 89 /* get a key struct with a SPNEGO security blob, suitable for session setup */ 90 struct key * 91 cifs_get_spnego_key(struct cifsSesInfo *sesInfo) ··· 106 IP_KEY_LEN + INET6_ADDRSTRLEN + 107 MAX_MECH_STR_LEN + 108 UID_KEY_LEN + (sizeof(uid_t) * 2) + 109 - USER_KEY_LEN + strlen(sesInfo->userName) + 1; 110 111 spnego_key = ERR_PTR(-ENOMEM); 112 description = kzalloc(desc_len, GFP_KERNEL); ··· 144 145 dp = description + strlen(description); 146 sprintf(dp, ";user=%s", sesInfo->userName); 147 148 cFYI(1, ("key description = %s", description)); 149 spnego_key = request_key(&cifs_spnego_key_type, description, "");
··· 86 /* strlen of ";user=" */ 87 #define USER_KEY_LEN 6 88 89 + /* strlen of ";pid=0x" */ 90 + #define PID_KEY_LEN 7 91 + 92 /* get a key struct with a SPNEGO security blob, suitable for session setup */ 93 struct key * 94 cifs_get_spnego_key(struct cifsSesInfo *sesInfo) ··· 103 IP_KEY_LEN + INET6_ADDRSTRLEN + 104 MAX_MECH_STR_LEN + 105 UID_KEY_LEN + (sizeof(uid_t) * 2) + 106 + USER_KEY_LEN + strlen(sesInfo->userName) + 107 + PID_KEY_LEN + (sizeof(pid_t) * 2) + 1; 108 109 spnego_key = ERR_PTR(-ENOMEM); 110 description = kzalloc(desc_len, GFP_KERNEL); ··· 140 141 dp = description + strlen(description); 142 sprintf(dp, ";user=%s", sesInfo->userName); 143 + 144 + dp = description + strlen(description); 145 + sprintf(dp, ";pid=0x%x", current->pid); 146 147 cFYI(1, ("key description = %s", description)); 148 spnego_key = request_key(&cifs_spnego_key_type, description, "");
+13 -13
fs/cifs/cifsacl.c
··· 327 328 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 329 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, 330 - struct inode *inode) 331 { 332 int i; 333 int num_aces = 0; ··· 340 if (!pdacl) { 341 /* no DACL in the security descriptor, set 342 all the permissions for user/group/other */ 343 - inode->i_mode |= S_IRWXUGO; 344 return; 345 } 346 ··· 357 /* reset rwx permissions for user/group/other. 358 Also, if num_aces is 0 i.e. DACL has no ACEs, 359 user/group/other have no permissions */ 360 - inode->i_mode &= ~(S_IRWXUGO); 361 362 acl_base = (char *)pdacl; 363 acl_size = sizeof(struct cifs_acl); ··· 379 if (compare_sids(&(ppace[i]->sid), pownersid)) 380 access_flags_to_mode(ppace[i]->access_req, 381 ppace[i]->type, 382 - &(inode->i_mode), 383 &user_mask); 384 if (compare_sids(&(ppace[i]->sid), pgrpsid)) 385 access_flags_to_mode(ppace[i]->access_req, 386 ppace[i]->type, 387 - &(inode->i_mode), 388 &group_mask); 389 if (compare_sids(&(ppace[i]->sid), &sid_everyone)) 390 access_flags_to_mode(ppace[i]->access_req, 391 ppace[i]->type, 392 - &(inode->i_mode), 393 &other_mask); 394 395 /* memcpy((void *)(&(cifscred->aces[i])), ··· 464 465 /* Convert CIFS ACL to POSIX form */ 466 static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, 467 - struct inode *inode) 468 { 469 int rc; 470 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; ··· 472 char *end_of_acl = ((char *)pntsd) + acl_len; 473 __u32 dacloffset; 474 475 - if ((inode == NULL) || (pntsd == NULL)) 476 return -EIO; 477 478 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ··· 497 498 if (dacloffset) 499 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, 500 - group_sid_ptr, inode); 501 else 502 cFYI(1, ("no ACL")); /* BB grant all or default perms? */ 503 ··· 507 sizeof(struct cifs_sid)); 508 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, 509 sizeof(struct cifs_sid)); */ 510 - 511 512 return 0; 513 } ··· 670 } 671 672 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ 673 - void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, 674 - const char *path, const __u16 *pfid) 675 { 676 struct cifs_ntsd *pntsd = NULL; 677 u32 acllen = 0; ··· 687 688 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ 689 if (pntsd) 690 - rc = parse_sec_desc(pntsd, acllen, inode); 691 if (rc) 692 cFYI(1, ("parse sec desc failed rc = %d", rc)); 693
··· 327 328 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 329 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, 330 + struct cifs_fattr *fattr) 331 { 332 int i; 333 int num_aces = 0; ··· 340 if (!pdacl) { 341 /* no DACL in the security descriptor, set 342 all the permissions for user/group/other */ 343 + fattr->cf_mode |= S_IRWXUGO; 344 return; 345 } 346 ··· 357 /* reset rwx permissions for user/group/other. 358 Also, if num_aces is 0 i.e. DACL has no ACEs, 359 user/group/other have no permissions */ 360 + fattr->cf_mode &= ~(S_IRWXUGO); 361 362 acl_base = (char *)pdacl; 363 acl_size = sizeof(struct cifs_acl); ··· 379 if (compare_sids(&(ppace[i]->sid), pownersid)) 380 access_flags_to_mode(ppace[i]->access_req, 381 ppace[i]->type, 382 + &fattr->cf_mode, 383 &user_mask); 384 if (compare_sids(&(ppace[i]->sid), pgrpsid)) 385 access_flags_to_mode(ppace[i]->access_req, 386 ppace[i]->type, 387 + &fattr->cf_mode, 388 &group_mask); 389 if (compare_sids(&(ppace[i]->sid), &sid_everyone)) 390 access_flags_to_mode(ppace[i]->access_req, 391 ppace[i]->type, 392 + &fattr->cf_mode, 393 &other_mask); 394 395 /* memcpy((void *)(&(cifscred->aces[i])), ··· 464 465 /* Convert CIFS ACL to POSIX form */ 466 static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, 467 + struct cifs_fattr *fattr) 468 { 469 int rc; 470 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; ··· 472 char *end_of_acl = ((char *)pntsd) + acl_len; 473 __u32 dacloffset; 474 475 + if (pntsd == NULL) 476 return -EIO; 477 478 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + ··· 497 498 if (dacloffset) 499 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, 500 + group_sid_ptr, fattr); 501 else 502 cFYI(1, ("no ACL")); /* BB grant all or default perms? */ 503 ··· 507 sizeof(struct cifs_sid)); 508 memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, 509 sizeof(struct cifs_sid)); */ 510 511 return 0; 512 } ··· 671 } 672 673 /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ 674 + void 675 + cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 676 + struct inode *inode, const char *path, const __u16 *pfid) 677 { 678 struct cifs_ntsd *pntsd = NULL; 679 u32 acllen = 0; ··· 687 688 /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ 689 if (pntsd) 690 + rc = parse_sec_desc(pntsd, acllen, fattr); 691 if (rc) 692 cFYI(1, ("parse sec desc failed rc = %d", rc)); 693
-1
fs/cifs/cifsfs.c
··· 308 if (!cifs_inode) 309 return NULL; 310 cifs_inode->cifsAttrs = 0x20; /* default */ 311 - atomic_set(&cifs_inode->inUse, 0); 312 cifs_inode->time = 0; 313 cifs_inode->write_behind_rc = 0; 314 /* Until the file is open and we have gotten oplock
··· 308 if (!cifs_inode) 309 return NULL; 310 cifs_inode->cifsAttrs = 0x20; /* default */ 311 cifs_inode->time = 0; 312 cifs_inode->write_behind_rc = 0; 313 /* Until the file is open and we have gotten oplock
+14 -1
fs/cifs/cifsfs.h
··· 24 25 #define ROOT_I 2 26 27 extern struct file_system_type cifs_fs_type; 28 extern const struct address_space_operations cifs_addr_ops; 29 extern const struct address_space_operations cifs_addr_ops_smallbuf; ··· 113 extern const struct export_operations cifs_export_ops; 114 #endif /* EXPERIMENTAL */ 115 116 - #define CIFS_VERSION "1.59" 117 #endif /* _CIFSFS_H */
··· 24 25 #define ROOT_I 2 26 27 + /* 28 + * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down 29 + * so that it will fit. 30 + */ 31 + static inline ino_t 32 + cifs_uniqueid_to_ino_t(u64 fileid) 33 + { 34 + ino_t ino = (ino_t) fileid; 35 + if (sizeof(ino_t) < sizeof(u64)) 36 + ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8; 37 + return ino; 38 + } 39 + 40 extern struct file_system_type cifs_fs_type; 41 extern const struct address_space_operations cifs_addr_ops; 42 extern const struct address_space_operations cifs_addr_ops_smallbuf; ··· 100 extern const struct export_operations cifs_export_ops; 101 #endif /* EXPERIMENTAL */ 102 103 + #define CIFS_VERSION "1.60" 104 #endif /* _CIFSFS_H */
+27 -1
fs/cifs/cifsglob.h
··· 364 struct list_head openFileList; 365 int write_behind_rc; 366 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 367 - atomic_t inUse; /* num concurrent users (local openers cifs) of file*/ 368 unsigned long time; /* jiffies of last update/check of inode */ 369 bool clientCanCacheRead:1; /* read oplock */ 370 bool clientCanCacheAll:1; /* read and writebehind oplock */ 371 bool oplockPending:1; 372 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 373 u64 server_eof; /* current file size on server */ 374 struct inode vfs_inode; 375 }; 376 ··· 470 int ref_flag; 471 char *path_name; 472 char *node_name; 473 }; 474 475 static inline void free_dfs_info_param(struct dfs_info3_param *param)
··· 364 struct list_head openFileList; 365 int write_behind_rc; 366 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 367 unsigned long time; /* jiffies of last update/check of inode */ 368 bool clientCanCacheRead:1; /* read oplock */ 369 bool clientCanCacheAll:1; /* read and writebehind oplock */ 370 bool oplockPending:1; 371 bool delete_pending:1; /* DELETE_ON_CLOSE is set */ 372 u64 server_eof; /* current file size on server */ 373 + u64 uniqueid; /* server inode number */ 374 struct inode vfs_inode; 375 }; 376 ··· 470 int ref_flag; 471 char *path_name; 472 char *node_name; 473 + }; 474 + 475 + /* 476 + * common struct for holding inode info when searching for or updating an 477 + * inode with new info 478 + */ 479 + 480 + #define CIFS_FATTR_DFS_REFERRAL 0x1 481 + #define CIFS_FATTR_DELETE_PENDING 0x2 482 + #define CIFS_FATTR_NEED_REVAL 0x4 483 + 484 + struct cifs_fattr { 485 + u32 cf_flags; 486 + u32 cf_cifsattrs; 487 + u64 cf_uniqueid; 488 + u64 cf_eof; 489 + u64 cf_bytes; 490 + uid_t cf_uid; 491 + gid_t cf_gid; 492 + umode_t cf_mode; 493 + dev_t cf_rdev; 494 + unsigned int cf_nlink; 495 + unsigned int cf_dtype; 496 + struct timespec cf_atime; 497 + struct timespec cf_mtime; 498 + struct timespec cf_ctime; 499 }; 500 501 static inline void free_dfs_info_param(struct dfs_info3_param *param)
+1 -13
fs/cifs/cifspdu.h
··· 2328 typedef struct { 2329 __le32 NextEntryOffset; 2330 __u32 ResumeKey; /* as with FileIndex - no need to convert */ 2331 - __le64 EndOfFile; 2332 - __le64 NumOfBytes; 2333 - __le64 LastStatusChange; /*SNIA specs DCE time for the 3 time fields */ 2334 - __le64 LastAccessTime; 2335 - __le64 LastModificationTime; 2336 - __le64 Uid; 2337 - __le64 Gid; 2338 - __le32 Type; 2339 - __le64 DevMajor; 2340 - __le64 DevMinor; 2341 - __le64 UniqueId; 2342 - __le64 Permissions; 2343 - __le64 Nlinks; 2344 char FileName[1]; 2345 } __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */ 2346
··· 2328 typedef struct { 2329 __le32 NextEntryOffset; 2330 __u32 ResumeKey; /* as with FileIndex - no need to convert */ 2331 + FILE_UNIX_BASIC_INFO basic; 2332 char FileName[1]; 2333 } __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */ 2334
+15 -6
fs/cifs/cifsproto.h
··· 98 extern int cifs_posix_open(char *full_path, struct inode **pinode, 99 struct super_block *sb, int mode, int oflags, 100 int *poplock, __u16 *pnetfid, int xid); 101 - extern void posix_fill_in_inode(struct inode *tmp_inode, 102 - FILE_UNIX_BASIC_INFO *pData, int isNewInode); 103 - extern struct inode *cifs_new_inode(struct super_block *sb, __u64 *inum); 104 extern int cifs_get_inode_info(struct inode **pinode, 105 const unsigned char *search_path, 106 FILE_ALL_INFO *pfile_info, ··· 112 extern int cifs_get_inode_info_unix(struct inode **pinode, 113 const unsigned char *search_path, 114 struct super_block *sb, int xid); 115 - extern void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, 116 - const char *path, const __u16 *pfid); 117 extern int mode_to_acl(struct inode *inode, const char *path, __u64); 118 119 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, ··· 220 dev_t device; 221 }; 222 223 - extern int CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *pTcon, 224 char *fileName, 225 const struct cifs_unix_set_info_args *args, 226 const struct nls_table *nls_codepage,
··· 98 extern int cifs_posix_open(char *full_path, struct inode **pinode, 99 struct super_block *sb, int mode, int oflags, 100 int *poplock, __u16 *pnetfid, int xid); 101 + extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, 102 + FILE_UNIX_BASIC_INFO *info, 103 + struct cifs_sb_info *cifs_sb); 104 + extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr); 105 + extern struct inode *cifs_iget(struct super_block *sb, 106 + struct cifs_fattr *fattr); 107 + 108 extern int cifs_get_inode_info(struct inode **pinode, 109 const unsigned char *search_path, 110 FILE_ALL_INFO *pfile_info, ··· 108 extern int cifs_get_inode_info_unix(struct inode **pinode, 109 const unsigned char *search_path, 110 struct super_block *sb, int xid); 111 + extern void cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, 112 + struct cifs_fattr *fattr, struct inode *inode, 113 + const char *path, const __u16 *pfid); 114 extern int mode_to_acl(struct inode *inode, const char *path, __u64); 115 116 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, ··· 215 dev_t device; 216 }; 217 218 + extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 219 + const struct cifs_unix_set_info_args *args, 220 + u16 fid, u32 pid_of_opener); 221 + 222 + extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon, 223 char *fileName, 224 const struct cifs_unix_set_info_args *args, 225 const struct nls_table *nls_codepage,
+108 -35
fs/cifs/cifssmb.c
··· 5074 } 5075 #endif /* temporarily unneeded SetAttr legacy function */ 5076 5077 int 5078 - CIFSSMBUnixSetInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, 5079 - const struct cifs_unix_set_info_args *args, 5080 - const struct nls_table *nls_codepage, int remap) 5081 { 5082 TRANSACTION2_SPI_REQ *pSMB = NULL; 5083 TRANSACTION2_SPI_RSP *pSMBr = NULL; ··· 5190 int bytes_returned = 0; 5191 FILE_UNIX_BASIC_INFO *data_offset; 5192 __u16 params, param_offset, offset, count, byte_count; 5193 - __u64 mode = args->mode; 5194 5195 cFYI(1, ("In SetUID/GID/Mode")); 5196 setPermsRetry: ··· 5240 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5241 pSMB->Reserved4 = 0; 5242 pSMB->hdr.smb_buf_length += byte_count; 5243 - /* Samba server ignores set of file size to zero due to bugs in some 5244 - older clients, but we should be precise - we use SetFileSize to 5245 - set file size and do not want to truncate file size to zero 5246 - accidently as happened on one Samba server beta by putting 5247 - zero instead of -1 here */ 5248 - data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5249 - data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5250 - data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5251 - data_offset->LastAccessTime = cpu_to_le64(args->atime); 5252 - data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5253 - data_offset->Uid = cpu_to_le64(args->uid); 5254 - data_offset->Gid = cpu_to_le64(args->gid); 5255 - /* better to leave device as zero when it is */ 5256 - data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5257 - data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5258 - data_offset->Permissions = cpu_to_le64(mode); 5259 5260 - if (S_ISREG(mode)) 5261 - data_offset->Type = cpu_to_le32(UNIX_FILE); 5262 - else if (S_ISDIR(mode)) 5263 - data_offset->Type = cpu_to_le32(UNIX_DIR); 5264 - else if (S_ISLNK(mode)) 5265 - data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5266 - else if (S_ISCHR(mode)) 5267 - data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5268 - else if (S_ISBLK(mode)) 5269 - data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5270 - else if (S_ISFIFO(mode)) 5271 - data_offset->Type = cpu_to_le32(UNIX_FIFO); 5272 - else if (S_ISSOCK(mode)) 5273 - data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5274 - 5275 5276 pSMB->ByteCount = cpu_to_le16(byte_count); 5277 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
··· 5074 } 5075 #endif /* temporarily unneeded SetAttr legacy function */ 5076 5077 + static void 5078 + cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset, 5079 + const struct cifs_unix_set_info_args *args) 5080 + { 5081 + u64 mode = args->mode; 5082 + 5083 + /* 5084 + * Samba server ignores set of file size to zero due to bugs in some 5085 + * older clients, but we should be precise - we use SetFileSize to 5086 + * set file size and do not want to truncate file size to zero 5087 + * accidently as happened on one Samba server beta by putting 5088 + * zero instead of -1 here 5089 + */ 5090 + data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64); 5091 + data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64); 5092 + data_offset->LastStatusChange = cpu_to_le64(args->ctime); 5093 + data_offset->LastAccessTime = cpu_to_le64(args->atime); 5094 + data_offset->LastModificationTime = cpu_to_le64(args->mtime); 5095 + data_offset->Uid = cpu_to_le64(args->uid); 5096 + data_offset->Gid = cpu_to_le64(args->gid); 5097 + /* better to leave device as zero when it is */ 5098 + data_offset->DevMajor = cpu_to_le64(MAJOR(args->device)); 5099 + data_offset->DevMinor = cpu_to_le64(MINOR(args->device)); 5100 + data_offset->Permissions = cpu_to_le64(mode); 5101 + 5102 + if (S_ISREG(mode)) 5103 + data_offset->Type = cpu_to_le32(UNIX_FILE); 5104 + else if (S_ISDIR(mode)) 5105 + data_offset->Type = cpu_to_le32(UNIX_DIR); 5106 + else if (S_ISLNK(mode)) 5107 + data_offset->Type = cpu_to_le32(UNIX_SYMLINK); 5108 + else if (S_ISCHR(mode)) 5109 + data_offset->Type = cpu_to_le32(UNIX_CHARDEV); 5110 + else if (S_ISBLK(mode)) 5111 + data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV); 5112 + else if (S_ISFIFO(mode)) 5113 + data_offset->Type = cpu_to_le32(UNIX_FIFO); 5114 + else if (S_ISSOCK(mode)) 5115 + data_offset->Type = cpu_to_le32(UNIX_SOCKET); 5116 + } 5117 + 5118 int 5119 + CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 5120 + const struct cifs_unix_set_info_args *args, 5121 + u16 fid, u32 pid_of_opener) 5122 + { 5123 + struct smb_com_transaction2_sfi_req *pSMB = NULL; 5124 + FILE_UNIX_BASIC_INFO *data_offset; 5125 + int rc = 0; 5126 + u16 params, param_offset, offset, byte_count, count; 5127 + 5128 + cFYI(1, ("Set Unix Info (via SetFileInfo)")); 5129 + rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB); 5130 + 5131 + if (rc) 5132 + return rc; 5133 + 5134 + pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); 5135 + pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16)); 5136 + 5137 + params = 6; 5138 + pSMB->MaxSetupCount = 0; 5139 + pSMB->Reserved = 0; 5140 + pSMB->Flags = 0; 5141 + pSMB->Timeout = 0; 5142 + pSMB->Reserved2 = 0; 5143 + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; 5144 + offset = param_offset + params; 5145 + 5146 + data_offset = (FILE_UNIX_BASIC_INFO *) 5147 + ((char *)(&pSMB->hdr.Protocol) + offset); 5148 + count = sizeof(FILE_UNIX_BASIC_INFO); 5149 + 5150 + pSMB->MaxParameterCount = cpu_to_le16(2); 5151 + /* BB find max SMB PDU from sess */ 5152 + pSMB->MaxDataCount = cpu_to_le16(1000); 5153 + pSMB->SetupCount = 1; 5154 + pSMB->Reserved3 = 0; 5155 + pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); 5156 + byte_count = 3 /* pad */ + params + count; 5157 + pSMB->DataCount = cpu_to_le16(count); 5158 + pSMB->ParameterCount = cpu_to_le16(params); 5159 + pSMB->TotalDataCount = pSMB->DataCount; 5160 + pSMB->TotalParameterCount = pSMB->ParameterCount; 5161 + pSMB->ParameterOffset = cpu_to_le16(param_offset); 5162 + pSMB->DataOffset = cpu_to_le16(offset); 5163 + pSMB->Fid = fid; 5164 + pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5165 + pSMB->Reserved4 = 0; 5166 + pSMB->hdr.smb_buf_length += byte_count; 5167 + pSMB->ByteCount = cpu_to_le16(byte_count); 5168 + 5169 + cifs_fill_unix_set_info(data_offset, args); 5170 + 5171 + rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0); 5172 + if (rc) 5173 + cFYI(1, ("Send error in Set Time (SetFileInfo) = %d", rc)); 5174 + 5175 + /* Note: On -EAGAIN error only caller can retry on handle based calls 5176 + since file handle passed in no longer valid */ 5177 + 5178 + return rc; 5179 + } 5180 + 5181 + int 5182 + CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, 5183 + const struct cifs_unix_set_info_args *args, 5184 + const struct nls_table *nls_codepage, int remap) 5185 { 5186 TRANSACTION2_SPI_REQ *pSMB = NULL; 5187 TRANSACTION2_SPI_RSP *pSMBr = NULL; ··· 5086 int bytes_returned = 0; 5087 FILE_UNIX_BASIC_INFO *data_offset; 5088 __u16 params, param_offset, offset, count, byte_count; 5089 5090 cFYI(1, ("In SetUID/GID/Mode")); 5091 setPermsRetry: ··· 5137 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC); 5138 pSMB->Reserved4 = 0; 5139 pSMB->hdr.smb_buf_length += byte_count; 5140 5141 + cifs_fill_unix_set_info(data_offset, args); 5142 5143 pSMB->ByteCount = cpu_to_le16(byte_count); 5144 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+28 -18
fs/cifs/dir.c
··· 188 FILE_UNIX_BASIC_INFO *presp_data; 189 __u32 posix_flags = 0; 190 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 191 192 cFYI(1, ("posix open %s", full_path)); 193 ··· 237 if (presp_data->Type == cpu_to_le32(-1)) 238 goto posix_open_ret; /* open ok, caller does qpathinfo */ 239 240 - /* get new inode and set it up */ 241 if (!pinode) 242 goto posix_open_ret; /* caller does not need info */ 243 244 if (*pinode == NULL) { 245 - __u64 unique_id = le64_to_cpu(presp_data->UniqueId); 246 - *pinode = cifs_new_inode(sb, &unique_id); 247 } 248 - /* else an inode was passed in. Update its info, don't create one */ 249 - 250 - /* We do not need to close the file if new_inode fails since 251 - the caller will retry qpathinfo as long as inode is null */ 252 - if (*pinode == NULL) 253 - goto posix_open_ret; 254 - 255 - posix_fill_in_inode(*pinode, presp_data, 1); 256 257 cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); 258 ··· 425 args.uid = NO_CHANGE_64; 426 args.gid = NO_CHANGE_64; 427 } 428 - CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, 429 - cifs_sb->local_nls, 430 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 431 } else { 432 /* BB implement mode setting via Windows security 433 descriptors e.g. */ ··· 516 args.uid = NO_CHANGE_64; 517 args.gid = NO_CHANGE_64; 518 } 519 - rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, 520 - &args, cifs_sb->local_nls, 521 - cifs_sb->mnt_cifs_flags & 522 - CIFS_MOUNT_MAP_SPECIAL_CHR); 523 524 if (!rc) { 525 rc = cifs_get_inode_info_unix(&newinode, full_path, ··· 642 FreeXid(xid); 643 return ERR_PTR(-EINVAL); 644 } 645 } 646 647 /* can not grab the rename sem here since it would
··· 188 FILE_UNIX_BASIC_INFO *presp_data; 189 __u32 posix_flags = 0; 190 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 191 + struct cifs_fattr fattr; 192 193 cFYI(1, ("posix open %s", full_path)); 194 ··· 236 if (presp_data->Type == cpu_to_le32(-1)) 237 goto posix_open_ret; /* open ok, caller does qpathinfo */ 238 239 if (!pinode) 240 goto posix_open_ret; /* caller does not need info */ 241 242 + cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb); 243 + 244 + /* get new inode and set it up */ 245 if (*pinode == NULL) { 246 + *pinode = cifs_iget(sb, &fattr); 247 + if (!*pinode) { 248 + rc = -ENOMEM; 249 + goto posix_open_ret; 250 + } 251 + } else { 252 + cifs_fattr_to_inode(*pinode, &fattr); 253 } 254 255 cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only); 256 ··· 425 args.uid = NO_CHANGE_64; 426 args.gid = NO_CHANGE_64; 427 } 428 + CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 429 + cifs_sb->local_nls, 430 + cifs_sb->mnt_cifs_flags & 431 + CIFS_MOUNT_MAP_SPECIAL_CHR); 432 } else { 433 /* BB implement mode setting via Windows security 434 descriptors e.g. */ ··· 515 args.uid = NO_CHANGE_64; 516 args.gid = NO_CHANGE_64; 517 } 518 + rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, 519 + cifs_sb->local_nls, 520 + cifs_sb->mnt_cifs_flags & 521 + CIFS_MOUNT_MAP_SPECIAL_CHR); 522 523 if (!rc) { 524 rc = cifs_get_inode_info_unix(&newinode, full_path, ··· 641 FreeXid(xid); 642 return ERR_PTR(-EINVAL); 643 } 644 + } 645 + 646 + /* 647 + * O_EXCL: optimize away the lookup, but don't hash the dentry. Let 648 + * the VFS handle the create. 649 + */ 650 + if (nd->flags & LOOKUP_EXCL) { 651 + d_instantiate(direntry, NULL); 652 + return 0; 653 } 654 655 /* can not grab the rename sem here since it would
+3 -3
fs/cifs/file.c
··· 448 .mtime = NO_CHANGE_64, 449 .device = 0, 450 }; 451 - CIFSSMBUnixSetInfo(xid, tcon, full_path, &args, 452 - cifs_sb->local_nls, 453 - cifs_sb->mnt_cifs_flags & 454 CIFS_MOUNT_MAP_SPECIAL_CHR); 455 } 456 }
··· 448 .mtime = NO_CHANGE_64, 449 .device = 0, 450 }; 451 + CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 452 + cifs_sb->local_nls, 453 + cifs_sb->mnt_cifs_flags & 454 CIFS_MOUNT_MAP_SPECIAL_CHR); 455 } 456 }
+358 -440
fs/cifs/inode.c
··· 77 } 78 } 79 80 - static void cifs_unix_info_to_inode(struct inode *inode, 81 - FILE_UNIX_BASIC_INFO *info, int force_uid_gid) 82 { 83 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 84 - struct cifsInodeInfo *cifsInfo = CIFS_I(inode); 85 - __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); 86 - __u64 end_of_file = le64_to_cpu(info->EndOfFile); 87 88 - inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime); 89 - inode->i_mtime = 90 - cifs_NTtimeToUnix(info->LastModificationTime); 91 - inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange); 92 - inode->i_mode = le64_to_cpu(info->Permissions); 93 94 /* 95 - * Since we set the inode type below we need to mask off 96 - * to avoid strange results if bits set above. 97 */ 98 - inode->i_mode &= ~S_IFMT; 99 - switch (le32_to_cpu(info->Type)) { 100 - case UNIX_FILE: 101 - inode->i_mode |= S_IFREG; 102 - break; 103 - case UNIX_SYMLINK: 104 - inode->i_mode |= S_IFLNK; 105 - break; 106 - case UNIX_DIR: 107 - inode->i_mode |= S_IFDIR; 108 - break; 109 - case UNIX_CHARDEV: 110 - inode->i_mode |= S_IFCHR; 111 - inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 112 - le64_to_cpu(info->DevMinor) & MINORMASK); 113 - break; 114 - case UNIX_BLOCKDEV: 115 - inode->i_mode |= S_IFBLK; 116 - inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 117 - le64_to_cpu(info->DevMinor) & MINORMASK); 118 - break; 119 - case UNIX_FIFO: 120 - inode->i_mode |= S_IFIFO; 121 - break; 122 - case UNIX_SOCKET: 123 - inode->i_mode |= S_IFSOCK; 124 - break; 125 - default: 126 - /* safest to call it a file if we do not know */ 127 - inode->i_mode |= S_IFREG; 128 - cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); 129 - break; 130 - } 131 - 132 - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) && 133 - !force_uid_gid) 134 - inode->i_uid = cifs_sb->mnt_uid; 135 - else 136 - inode->i_uid = le64_to_cpu(info->Uid); 137 - 138 - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) && 139 - !force_uid_gid) 140 - inode->i_gid = cifs_sb->mnt_gid; 141 - else 142 - inode->i_gid = le64_to_cpu(info->Gid); 143 - 144 - inode->i_nlink = le64_to_cpu(info->Nlinks); 145 - 146 - cifsInfo->server_eof = end_of_file; 147 spin_lock(&inode->i_lock); 148 - if (is_size_safe_to_change(cifsInfo, end_of_file)) { 149 - /* 150 - * We can not safely change the file size here if the client 151 - * is writing to it due to potential races. 152 - */ 153 - i_size_write(inode, end_of_file); 154 155 /* 156 * i_blocks is not related to (i_size / i_blksize), 157 * but instead 512 byte (2**9) size is required for 158 * calculating num blocks. 159 */ 160 - inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; 161 } 162 spin_unlock(&inode->i_lock); 163 } 164 165 166 /* 167 - * Needed to setup inode data for the directory which is the 168 - * junction to the new submount (ie to setup the fake directory 169 - * which represents a DFS referral) 170 - */ 171 - static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, 172 - struct super_block *sb) 173 - { 174 - struct inode *pinode = NULL; 175 - 176 - memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO)); 177 - 178 - /* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); 179 - __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0); 180 - __u64 UniqueId = 0; */ 181 - pfnd_dat->LastStatusChange = 182 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 183 - pfnd_dat->LastAccessTime = 184 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 185 - pfnd_dat->LastModificationTime = 186 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 187 - pfnd_dat->Type = cpu_to_le32(UNIX_DIR); 188 - pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU); 189 - pfnd_dat->Nlinks = cpu_to_le64(2); 190 - if (sb->s_root) 191 - pinode = sb->s_root->d_inode; 192 - if (pinode == NULL) 193 - return; 194 - 195 - /* fill in default values for the remaining based on root 196 - inode since we can not query the server for this inode info */ 197 - pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev)); 198 - pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev)); 199 - pfnd_dat->Uid = cpu_to_le64(pinode->i_uid); 200 - pfnd_dat->Gid = cpu_to_le64(pinode->i_gid); 201 - } 202 - 203 - /** 204 - * cifs_new inode - create new inode, initialize, and hash it 205 - * @sb - pointer to superblock 206 - * @inum - if valid pointer and serverino is enabled, replace i_ino with val 207 * 208 - * Create a new inode, initialize it for CIFS and hash it. Returns the new 209 - * inode or NULL if one couldn't be allocated. 210 - * 211 - * If the share isn't mounted with "serverino" or inum is a NULL pointer then 212 - * we'll just use the inode number assigned by new_inode(). Note that this can 213 - * mean i_ino collisions since the i_ino assigned by new_inode is not 214 - * guaranteed to be unique. 215 */ 216 - struct inode * 217 - cifs_new_inode(struct super_block *sb, __u64 *inum) 218 { 219 - struct inode *inode; 220 221 - inode = new_inode(sb); 222 - if (inode == NULL) 223 - return NULL; 224 225 - /* 226 - * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we 227 - * stop passing inum as ptr. Are there sanity checks we can use to 228 - * ensure that the server is really filling in that field? Also, 229 - * if serverino is disabled, perhaps we should be using iunique()? 230 - */ 231 - if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) 232 - inode->i_ino = (unsigned long) *inum; 233 - 234 - /* 235 - * must set this here instead of cifs_alloc_inode since VFS will 236 - * clobber i_flags 237 - */ 238 - if (sb->s_flags & MS_NOATIME) 239 - inode->i_flags |= S_NOATIME | S_NOCMTIME; 240 - 241 - insert_inode_hash(inode); 242 - 243 - return inode; 244 } 245 246 int cifs_get_inode_info_unix(struct inode **pinode, 247 - const unsigned char *full_path, struct super_block *sb, int xid) 248 { 249 - int rc = 0; 250 FILE_UNIX_BASIC_INFO find_data; 251 - struct cifsTconInfo *pTcon; 252 - struct inode *inode; 253 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 254 - bool is_dfs_referral = false; 255 - struct cifsInodeInfo *cifsInfo; 256 - __u64 num_of_bytes; 257 - __u64 end_of_file; 258 259 - pTcon = cifs_sb->tcon; 260 cFYI(1, ("Getting info on %s", full_path)); 261 262 /* could have done a find first instead but this returns more info */ 263 - rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data, 264 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 265 CIFS_MOUNT_MAP_SPECIAL_CHR); 266 - if (rc == -EREMOTE && !is_dfs_referral) { 267 - is_dfs_referral = true; 268 - cFYI(DBG2, ("DFS ref")); 269 - /* for DFS, server does not give us real inode data */ 270 - fill_fake_finddataunix(&find_data, sb); 271 rc = 0; 272 - } else if (rc) 273 - goto cgiiu_exit; 274 - 275 - num_of_bytes = le64_to_cpu(find_data.NumOfBytes); 276 - end_of_file = le64_to_cpu(find_data.EndOfFile); 277 - 278 - /* get new inode */ 279 - if (*pinode == NULL) { 280 - __u64 unique_id = le64_to_cpu(find_data.UniqueId); 281 - *pinode = cifs_new_inode(sb, &unique_id); 282 - if (*pinode == NULL) { 283 - rc = -ENOMEM; 284 - goto cgiiu_exit; 285 - } 286 } 287 288 - inode = *pinode; 289 - cifsInfo = CIFS_I(inode); 290 291 - cFYI(1, ("Old time %ld", cifsInfo->time)); 292 - cifsInfo->time = jiffies; 293 - cFYI(1, ("New time %ld", cifsInfo->time)); 294 - /* this is ok to set on every inode revalidate */ 295 - atomic_set(&cifsInfo->inUse, 1); 296 - 297 - cifs_unix_info_to_inode(inode, &find_data, 0); 298 - 299 - if (num_of_bytes < end_of_file) 300 - cFYI(1, ("allocation size less than end of file")); 301 - cFYI(1, ("Size %ld and blocks %llu", 302 - (unsigned long) inode->i_size, 303 - (unsigned long long)inode->i_blocks)); 304 - 305 - cifs_set_ops(inode, is_dfs_referral); 306 - cgiiu_exit: 307 return rc; 308 } 309 310 - static int decode_sfu_inode(struct inode *inode, __u64 size, 311 - const unsigned char *path, 312 - struct cifs_sb_info *cifs_sb, int xid) 313 { 314 int rc; 315 int oplock = 0; ··· 284 285 pbuf = buf; 286 287 - if (size == 0) { 288 - inode->i_mode |= S_IFIFO; 289 return 0; 290 - } else if (size < 8) { 291 return -EINVAL; /* EOPNOTSUPP? */ 292 } 293 ··· 304 if (rc == 0) { 305 int buf_type = CIFS_NO_BUFFER; 306 /* Read header */ 307 - rc = CIFSSMBRead(xid, pTcon, 308 - netfid, 309 24 /* length */, 0 /* offset */, 310 &bytes_read, &pbuf, &buf_type); 311 if ((rc == 0) && (bytes_read >= 8)) { 312 if (memcmp("IntxBLK", pbuf, 8) == 0) { 313 cFYI(1, ("Block device")); 314 - inode->i_mode |= S_IFBLK; 315 if (bytes_read == 24) { 316 /* we have enough to decode dev num */ 317 __u64 mjr; /* major */ 318 __u64 mnr; /* minor */ 319 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 320 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 321 - inode->i_rdev = MKDEV(mjr, mnr); 322 } 323 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 324 cFYI(1, ("Char device")); 325 - inode->i_mode |= S_IFCHR; 326 if (bytes_read == 24) { 327 /* we have enough to decode dev num */ 328 __u64 mjr; /* major */ 329 __u64 mnr; /* minor */ 330 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 331 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 332 - inode->i_rdev = MKDEV(mjr, mnr); 333 } 334 } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 335 cFYI(1, ("Symlink")); 336 - inode->i_mode |= S_IFLNK; 337 } else { 338 - inode->i_mode |= S_IFREG; /* file? */ 339 rc = -EOPNOTSUPP; 340 } 341 } else { 342 - inode->i_mode |= S_IFREG; /* then it is a file */ 343 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 344 } 345 CIFSSMBClose(xid, pTcon, netfid); ··· 353 354 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 355 356 - static int get_sfu_mode(struct inode *inode, 357 - const unsigned char *path, 358 - struct cifs_sb_info *cifs_sb, int xid) 359 { 360 #ifdef CONFIG_CIFS_XATTR 361 ssize_t rc; ··· 367 __u32 mode; 368 369 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 370 - ea_value, 4 /* size of buf */, cifs_sb->local_nls, 371 - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 372 if (rc < 0) 373 return (int)rc; 374 else if (rc > 3) { 375 mode = le32_to_cpu(*((__le32 *)ea_value)); 376 - inode->i_mode &= ~SFBITS_MASK; 377 - cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode)); 378 - inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 379 cFYI(1, ("special mode bits 0%o", mode)); 380 - return 0; 381 - } else { 382 - return 0; 383 } 384 #else 385 return -EOPNOTSUPP; 386 #endif 387 } 388 389 - /* 390 - * Needed to setup inode data for the directory which is the 391 - * junction to the new submount (ie to setup the fake directory 392 - * which represents a DFS referral) 393 - */ 394 - static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat, 395 - struct super_block *sb) 396 { 397 - memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO)); 398 399 - /* __le64 pfnd_dat->AllocationSize = cpu_to_le64(0); 400 - __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); 401 - __u8 pfnd_dat->DeletePending = 0; 402 - __u8 pfnd_data->Directory = 0; 403 - __le32 pfnd_dat->EASize = 0; 404 - __u64 pfnd_dat->IndexNumber = 0; 405 - __u64 pfnd_dat->IndexNumber1 = 0; */ 406 - pfnd_dat->CreationTime = 407 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 408 - pfnd_dat->LastAccessTime = 409 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 410 - pfnd_dat->LastWriteTime = 411 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 412 - pfnd_dat->ChangeTime = 413 - cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 414 - pfnd_dat->Attributes = cpu_to_le32(ATTR_DIRECTORY); 415 - pfnd_dat->NumberOfLinks = cpu_to_le32(2); 416 } 417 418 int cifs_get_inode_info(struct inode **pinode, 419 const unsigned char *full_path, FILE_ALL_INFO *pfindData, 420 struct super_block *sb, int xid, const __u16 *pfid) 421 { 422 - int rc = 0; 423 - __u32 attr; 424 - struct cifsInodeInfo *cifsInfo; 425 struct cifsTconInfo *pTcon; 426 - struct inode *inode; 427 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 428 char *buf = NULL; 429 bool adjustTZ = false; 430 - bool is_dfs_referral = false; 431 - umode_t default_mode; 432 433 pTcon = cifs_sb->tcon; 434 cFYI(1, ("Getting info on %s", full_path)); ··· 475 adjustTZ = true; 476 } 477 } 478 - /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 479 - if (rc == -EREMOTE) { 480 - is_dfs_referral = true; 481 - fill_fake_finddata(pfindData, sb); 482 rc = 0; 483 - } else if (rc) 484 goto cgii_exit; 485 486 - attr = le32_to_cpu(pfindData->Attributes); 487 - 488 - /* get new inode */ 489 if (*pinode == NULL) { 490 - __u64 inode_num; 491 - __u64 *pinum = &inode_num; 492 - 493 - /* Is an i_ino of zero legal? Can we use that to check 494 - if the server supports returning inode numbers? Are 495 - there other sanity checks we can use to ensure that 496 - the server is really filling in that field? */ 497 - 498 - /* We can not use the IndexNumber field by default from 499 - Windows or Samba (in ALL_INFO buf) but we can request 500 - it explicitly. It may not be unique presumably if 501 - the server has multiple devices mounted under one share */ 502 - 503 - /* There may be higher info levels that work but are 504 - there Windows server or network appliances for which 505 - IndexNumber field is not guaranteed unique? */ 506 - 507 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 508 int rc1 = 0; 509 510 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 511 - full_path, pinum, 512 cifs_sb->local_nls, 513 cifs_sb->mnt_cifs_flags & 514 CIFS_MOUNT_MAP_SPECIAL_CHR); 515 if (rc1) { 516 - cFYI(1, ("GetSrvInodeNum rc %d", rc1)); 517 - pinum = NULL; 518 /* BB EOPNOSUPP disable SERVER_INUM? */ 519 } 520 } else { 521 - pinum = NULL; 522 } 523 - 524 - *pinode = cifs_new_inode(sb, pinum); 525 - if (*pinode == NULL) { 526 - rc = -ENOMEM; 527 - goto cgii_exit; 528 - } 529 - } 530 - inode = *pinode; 531 - cifsInfo = CIFS_I(inode); 532 - cifsInfo->cifsAttrs = attr; 533 - cifsInfo->delete_pending = pfindData->DeletePending ? true : false; 534 - cFYI(1, ("Old time %ld", cifsInfo->time)); 535 - cifsInfo->time = jiffies; 536 - cFYI(1, ("New time %ld", cifsInfo->time)); 537 - 538 - /* blksize needs to be multiple of two. So safer to default to 539 - blksize and blkbits set in superblock so 2**blkbits and blksize 540 - will match rather than setting to: 541 - (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/ 542 - 543 - /* Linux can not store file creation time so ignore it */ 544 - if (pfindData->LastAccessTime) 545 - inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime); 546 - else /* do not need to use current_fs_time - time not stored */ 547 - inode->i_atime = CURRENT_TIME; 548 - inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime); 549 - inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime); 550 - cFYI(DBG2, ("Attributes came in as 0x%x", attr)); 551 - if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { 552 - inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; 553 - inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; 554 - } 555 - 556 - /* get default inode mode */ 557 - if (attr & ATTR_DIRECTORY) 558 - default_mode = cifs_sb->mnt_dir_mode; 559 - else 560 - default_mode = cifs_sb->mnt_file_mode; 561 - 562 - /* set permission bits */ 563 - if (atomic_read(&cifsInfo->inUse) == 0 || 564 - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) 565 - inode->i_mode = default_mode; 566 - else { 567 - /* just reenable write bits if !ATTR_READONLY */ 568 - if ((inode->i_mode & S_IWUGO) == 0 && 569 - (attr & ATTR_READONLY) == 0) 570 - inode->i_mode |= (S_IWUGO & default_mode); 571 - 572 - inode->i_mode &= ~S_IFMT; 573 - } 574 - /* clear write bits if ATTR_READONLY is set */ 575 - if (attr & ATTR_READONLY) 576 - inode->i_mode &= ~S_IWUGO; 577 - 578 - /* set inode type */ 579 - if ((attr & ATTR_SYSTEM) && 580 - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { 581 - /* no need to fix endianness on 0 */ 582 - if (pfindData->EndOfFile == 0) 583 - inode->i_mode |= S_IFIFO; 584 - else if (decode_sfu_inode(inode, 585 - le64_to_cpu(pfindData->EndOfFile), 586 - full_path, cifs_sb, xid)) 587 - cFYI(1, ("unknown SFU file type\n")); 588 } else { 589 - if (attr & ATTR_DIRECTORY) 590 - inode->i_mode |= S_IFDIR; 591 - else 592 - inode->i_mode |= S_IFREG; 593 } 594 595 - cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile); 596 - spin_lock(&inode->i_lock); 597 - if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) { 598 - /* can not safely shrink the file size here if the 599 - client is writing to it due to potential races */ 600 - i_size_write(inode, cifsInfo->server_eof); 601 - 602 - /* 512 bytes (2**9) is the fake blocksize that must be 603 - used for this calculation */ 604 - inode->i_blocks = (512 - 1 + le64_to_cpu( 605 - pfindData->AllocationSize)) >> 9; 606 } 607 - spin_unlock(&inode->i_lock); 608 609 - inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks); 610 - 611 - /* BB fill in uid and gid here? with help from winbind? 612 - or retrieve from NTFS stream extended attribute */ 613 #ifdef CONFIG_CIFS_EXPERIMENTAL 614 /* fill in 0777 bits from ACL */ 615 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 616 cFYI(1, ("Getting mode bits from ACL")); 617 - acl_to_uid_mode(cifs_sb, inode, full_path, pfid); 618 } 619 #endif 620 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 621 - /* fill in remaining high mode bits e.g. SUID, VTX */ 622 - get_sfu_mode(inode, full_path, cifs_sb, xid); 623 - } else if (atomic_read(&cifsInfo->inUse) == 0) { 624 - inode->i_uid = cifs_sb->mnt_uid; 625 - inode->i_gid = cifs_sb->mnt_gid; 626 - /* set so we do not keep refreshing these fields with 627 - bad data after user has changed them in memory */ 628 - atomic_set(&cifsInfo->inUse, 1); 629 } 630 - 631 - cifs_set_ops(inode, is_dfs_referral); 632 - 633 - 634 - 635 636 cgii_exit: 637 kfree(buf); ··· 602 return full_path; 603 } 604 605 /* gets root inode */ 606 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 607 { 608 int xid; 609 struct cifs_sb_info *cifs_sb; 610 - struct inode *inode; 611 long rc; 612 char *full_path; 613 614 - inode = iget_locked(sb, ino); 615 - if (!inode) 616 - return ERR_PTR(-ENOMEM); 617 - if (!(inode->i_state & I_NEW)) 618 - return inode; 619 - 620 - cifs_sb = CIFS_SB(inode->i_sb); 621 full_path = cifs_build_path_to_root(cifs_sb); 622 if (full_path == NULL) 623 return ERR_PTR(-ENOMEM); 624 625 xid = GetXid(); 626 if (cifs_sb->tcon->unix_ext) 627 - rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, 628 - xid); 629 else 630 - rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb, 631 xid, NULL); 632 if (rc && cifs_sb->tcon->ipc) { 633 cFYI(1, ("ipc connection - fake read inode")); 634 inode->i_mode |= S_IFDIR; ··· 689 return ERR_PTR(rc); 690 } 691 692 - unlock_new_inode(inode); 693 694 kfree(full_path); 695 /* can not call macro FreeXid here since in a void func ··· 1014 return rc; 1015 } 1016 1017 - void posix_fill_in_inode(struct inode *tmp_inode, 1018 - FILE_UNIX_BASIC_INFO *pData, int isNewInode) 1019 - { 1020 - struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); 1021 - loff_t local_size; 1022 - struct timespec local_mtime; 1023 - 1024 - cifsInfo->time = jiffies; 1025 - atomic_inc(&cifsInfo->inUse); 1026 - 1027 - /* save mtime and size */ 1028 - local_mtime = tmp_inode->i_mtime; 1029 - local_size = tmp_inode->i_size; 1030 - 1031 - cifs_unix_info_to_inode(tmp_inode, pData, 1); 1032 - cifs_set_ops(tmp_inode, false); 1033 - 1034 - if (!S_ISREG(tmp_inode->i_mode)) 1035 - return; 1036 - 1037 - /* 1038 - * No sense invalidating pages for new inode 1039 - * since we we have not started caching 1040 - * readahead file data yet. 1041 - */ 1042 - if (isNewInode) 1043 - return; 1044 - 1045 - if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 1046 - (local_size == tmp_inode->i_size)) { 1047 - cFYI(1, ("inode exists but unchanged")); 1048 - } else { 1049 - /* file may have changed on server */ 1050 - cFYI(1, ("invalidate inode, readdir detected change")); 1051 - invalidate_remote_inode(tmp_inode); 1052 - } 1053 - } 1054 - 1055 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 1056 { 1057 int rc = 0, tmprc; ··· 1022 struct cifsTconInfo *pTcon; 1023 char *full_path = NULL; 1024 struct inode *newinode = NULL; 1025 1026 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode)); 1027 ··· 1062 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1063 d_drop(direntry); 1064 } else { 1065 - __u64 unique_id; 1066 if (pInfo->Type == cpu_to_le32(-1)) { 1067 /* no return info, go query for it */ 1068 kfree(pInfo); ··· 1075 else 1076 direntry->d_op = &cifs_dentry_ops; 1077 1078 - unique_id = le64_to_cpu(pInfo->UniqueId); 1079 - newinode = cifs_new_inode(inode->i_sb, &unique_id); 1080 - if (newinode == NULL) { 1081 kfree(pInfo); 1082 goto mkdir_get_info; 1083 } 1084 1085 - newinode->i_nlink = 2; 1086 d_instantiate(direntry, newinode); 1087 1088 - /* we already checked in POSIXCreate whether 1089 - frame was long enough */ 1090 - posix_fill_in_inode(direntry->d_inode, 1091 - pInfo, 1 /* NewInode */); 1092 #ifdef CONFIG_CIFS_DEBUG2 1093 cFYI(1, ("instantiated dentry %p %s to inode %p", 1094 direntry, direntry->d_name.name, newinode)); ··· 1146 args.uid = NO_CHANGE_64; 1147 args.gid = NO_CHANGE_64; 1148 } 1149 - CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args, 1150 - cifs_sb->local_nls, 1151 - cifs_sb->mnt_cifs_flags & 1152 - CIFS_MOUNT_MAP_SPECIAL_CHR); 1153 } else { 1154 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && 1155 (mode & S_IWUGO) == 0) { ··· 1530 if (!err) { 1531 generic_fillattr(dentry->d_inode, stat); 1532 stat->blksize = CIFS_MAX_MSGSIZE; 1533 } 1534 return err; 1535 } ··· 1695 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1696 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1697 struct cifs_unix_set_info_args *args = NULL; 1698 1699 cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x", 1700 direntry->d_name.name, attrs->ia_valid)); ··· 1782 args->ctime = NO_CHANGE_64; 1783 1784 args->device = 0; 1785 - rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, args, 1786 - cifs_sb->local_nls, 1787 - cifs_sb->mnt_cifs_flags & 1788 - CIFS_MOUNT_MAP_SPECIAL_CHR); 1789 1790 if (!rc) 1791 rc = inode_setattr(inode, attrs);
··· 77 } 78 } 79 80 + /* populate an inode with info from a cifs_fattr struct */ 81 + void 82 + cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) 83 { 84 + struct cifsInodeInfo *cifs_i = CIFS_I(inode); 85 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 86 + unsigned long oldtime = cifs_i->time; 87 88 + inode->i_atime = fattr->cf_atime; 89 + inode->i_mtime = fattr->cf_mtime; 90 + inode->i_ctime = fattr->cf_ctime; 91 + inode->i_rdev = fattr->cf_rdev; 92 + inode->i_nlink = fattr->cf_nlink; 93 + inode->i_uid = fattr->cf_uid; 94 + inode->i_gid = fattr->cf_gid; 95 + 96 + /* if dynperm is set, don't clobber existing mode */ 97 + if (inode->i_state & I_NEW || 98 + !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) 99 + inode->i_mode = fattr->cf_mode; 100 + 101 + cifs_i->cifsAttrs = fattr->cf_cifsattrs; 102 + cifs_i->uniqueid = fattr->cf_uniqueid; 103 + 104 + if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) 105 + cifs_i->time = 0; 106 + else 107 + cifs_i->time = jiffies; 108 + 109 + cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode, 110 + oldtime, cifs_i->time)); 111 + 112 + cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING; 113 114 /* 115 + * Can't safely change the file size here if the client is writing to 116 + * it due to potential races. 117 */ 118 spin_lock(&inode->i_lock); 119 + if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) { 120 + i_size_write(inode, fattr->cf_eof); 121 122 /* 123 * i_blocks is not related to (i_size / i_blksize), 124 * but instead 512 byte (2**9) size is required for 125 * calculating num blocks. 126 */ 127 + inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9; 128 } 129 spin_unlock(&inode->i_lock); 130 + 131 + cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL); 132 } 133 134 + /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */ 135 + void 136 + cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, 137 + struct cifs_sb_info *cifs_sb) 138 + { 139 + memset(fattr, 0, sizeof(*fattr)); 140 + fattr->cf_uniqueid = le64_to_cpu(info->UniqueId); 141 + fattr->cf_bytes = le64_to_cpu(info->NumOfBytes); 142 + fattr->cf_eof = le64_to_cpu(info->EndOfFile); 143 + 144 + fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 145 + fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime); 146 + fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange); 147 + fattr->cf_mode = le64_to_cpu(info->Permissions); 148 + 149 + /* 150 + * Since we set the inode type below we need to mask off 151 + * to avoid strange results if bits set above. 152 + */ 153 + fattr->cf_mode &= ~S_IFMT; 154 + switch (le32_to_cpu(info->Type)) { 155 + case UNIX_FILE: 156 + fattr->cf_mode |= S_IFREG; 157 + fattr->cf_dtype = DT_REG; 158 + break; 159 + case UNIX_SYMLINK: 160 + fattr->cf_mode |= S_IFLNK; 161 + fattr->cf_dtype = DT_LNK; 162 + break; 163 + case UNIX_DIR: 164 + fattr->cf_mode |= S_IFDIR; 165 + fattr->cf_dtype = DT_DIR; 166 + break; 167 + case UNIX_CHARDEV: 168 + fattr->cf_mode |= S_IFCHR; 169 + fattr->cf_dtype = DT_CHR; 170 + fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), 171 + le64_to_cpu(info->DevMinor) & MINORMASK); 172 + break; 173 + case UNIX_BLOCKDEV: 174 + fattr->cf_mode |= S_IFBLK; 175 + fattr->cf_dtype = DT_BLK; 176 + fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), 177 + le64_to_cpu(info->DevMinor) & MINORMASK); 178 + break; 179 + case UNIX_FIFO: 180 + fattr->cf_mode |= S_IFIFO; 181 + fattr->cf_dtype = DT_FIFO; 182 + break; 183 + case UNIX_SOCKET: 184 + fattr->cf_mode |= S_IFSOCK; 185 + fattr->cf_dtype = DT_SOCK; 186 + break; 187 + default: 188 + /* safest to call it a file if we do not know */ 189 + fattr->cf_mode |= S_IFREG; 190 + fattr->cf_dtype = DT_REG; 191 + cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); 192 + break; 193 + } 194 + 195 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 196 + fattr->cf_uid = cifs_sb->mnt_uid; 197 + else 198 + fattr->cf_uid = le64_to_cpu(info->Uid); 199 + 200 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) 201 + fattr->cf_gid = cifs_sb->mnt_gid; 202 + else 203 + fattr->cf_gid = le64_to_cpu(info->Gid); 204 + 205 + fattr->cf_nlink = le64_to_cpu(info->Nlinks); 206 + } 207 208 /* 209 + * Fill a cifs_fattr struct with fake inode info. 210 * 211 + * Needed to setup cifs_fattr data for the directory which is the 212 + * junction to the new submount (ie to setup the fake directory 213 + * which represents a DFS referral). 214 */ 215 + void 216 + cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) 217 { 218 + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 219 220 + cFYI(1, ("creating fake fattr for DFS referral")); 221 222 + memset(fattr, 0, sizeof(*fattr)); 223 + fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; 224 + fattr->cf_uid = cifs_sb->mnt_uid; 225 + fattr->cf_gid = cifs_sb->mnt_gid; 226 + fattr->cf_atime = CURRENT_TIME; 227 + fattr->cf_ctime = CURRENT_TIME; 228 + fattr->cf_mtime = CURRENT_TIME; 229 + fattr->cf_nlink = 2; 230 + fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; 231 } 232 233 int cifs_get_inode_info_unix(struct inode **pinode, 234 + const unsigned char *full_path, 235 + struct super_block *sb, int xid) 236 { 237 + int rc; 238 FILE_UNIX_BASIC_INFO find_data; 239 + struct cifs_fattr fattr; 240 + struct cifsTconInfo *tcon; 241 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 242 243 + tcon = cifs_sb->tcon; 244 cFYI(1, ("Getting info on %s", full_path)); 245 246 /* could have done a find first instead but this returns more info */ 247 + rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, 248 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 249 CIFS_MOUNT_MAP_SPECIAL_CHR); 250 + 251 + if (!rc) { 252 + cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); 253 + } else if (rc == -EREMOTE) { 254 + cifs_create_dfs_fattr(&fattr, sb); 255 rc = 0; 256 + } else { 257 + return rc; 258 } 259 260 + if (*pinode == NULL) { 261 + /* get new inode */ 262 + *pinode = cifs_iget(sb, &fattr); 263 + if (!*pinode) 264 + rc = -ENOMEM; 265 + } else { 266 + /* we already have inode, update it */ 267 + cifs_fattr_to_inode(*pinode, &fattr); 268 + } 269 270 return rc; 271 } 272 273 + static int 274 + cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, 275 + struct cifs_sb_info *cifs_sb, int xid) 276 { 277 int rc; 278 int oplock = 0; ··· 321 322 pbuf = buf; 323 324 + fattr->cf_mode &= ~S_IFMT; 325 + 326 + if (fattr->cf_eof == 0) { 327 + fattr->cf_mode |= S_IFIFO; 328 + fattr->cf_dtype = DT_FIFO; 329 return 0; 330 + } else if (fattr->cf_eof < 8) { 331 + fattr->cf_mode |= S_IFREG; 332 + fattr->cf_dtype = DT_REG; 333 return -EINVAL; /* EOPNOTSUPP? */ 334 } 335 ··· 336 if (rc == 0) { 337 int buf_type = CIFS_NO_BUFFER; 338 /* Read header */ 339 + rc = CIFSSMBRead(xid, pTcon, netfid, 340 24 /* length */, 0 /* offset */, 341 &bytes_read, &pbuf, &buf_type); 342 if ((rc == 0) && (bytes_read >= 8)) { 343 if (memcmp("IntxBLK", pbuf, 8) == 0) { 344 cFYI(1, ("Block device")); 345 + fattr->cf_mode |= S_IFBLK; 346 + fattr->cf_dtype = DT_BLK; 347 if (bytes_read == 24) { 348 /* we have enough to decode dev num */ 349 __u64 mjr; /* major */ 350 __u64 mnr; /* minor */ 351 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 352 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 353 + fattr->cf_rdev = MKDEV(mjr, mnr); 354 } 355 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 356 cFYI(1, ("Char device")); 357 + fattr->cf_mode |= S_IFCHR; 358 + fattr->cf_dtype = DT_CHR; 359 if (bytes_read == 24) { 360 /* we have enough to decode dev num */ 361 __u64 mjr; /* major */ 362 __u64 mnr; /* minor */ 363 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 364 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 365 + fattr->cf_rdev = MKDEV(mjr, mnr); 366 } 367 } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 368 cFYI(1, ("Symlink")); 369 + fattr->cf_mode |= S_IFLNK; 370 + fattr->cf_dtype = DT_LNK; 371 } else { 372 + fattr->cf_mode |= S_IFREG; /* file? */ 373 + fattr->cf_dtype = DT_REG; 374 rc = -EOPNOTSUPP; 375 } 376 } else { 377 + fattr->cf_mode |= S_IFREG; /* then it is a file */ 378 + fattr->cf_dtype = DT_REG; 379 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 380 } 381 CIFSSMBClose(xid, pTcon, netfid); ··· 381 382 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 383 384 + /* 385 + * Fetch mode bits as provided by SFU. 386 + * 387 + * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ? 388 + */ 389 + static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, 390 + struct cifs_sb_info *cifs_sb, int xid) 391 { 392 #ifdef CONFIG_CIFS_XATTR 393 ssize_t rc; ··· 391 __u32 mode; 392 393 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 394 + ea_value, 4 /* size of buf */, cifs_sb->local_nls, 395 + cifs_sb->mnt_cifs_flags & 396 + CIFS_MOUNT_MAP_SPECIAL_CHR); 397 if (rc < 0) 398 return (int)rc; 399 else if (rc > 3) { 400 mode = le32_to_cpu(*((__le32 *)ea_value)); 401 + fattr->cf_mode &= ~SFBITS_MASK; 402 + cFYI(1, ("special bits 0%o org mode 0%o", mode, 403 + fattr->cf_mode)); 404 + fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode; 405 cFYI(1, ("special mode bits 0%o", mode)); 406 } 407 + 408 + return 0; 409 #else 410 return -EOPNOTSUPP; 411 #endif 412 } 413 414 + /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ 415 + void 416 + cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, 417 + struct cifs_sb_info *cifs_sb, bool adjust_tz) 418 { 419 + memset(fattr, 0, sizeof(*fattr)); 420 + fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); 421 + if (info->DeletePending) 422 + fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING; 423 424 + if (info->LastAccessTime) 425 + fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 426 + else 427 + fattr->cf_atime = CURRENT_TIME; 428 + 429 + fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); 430 + fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); 431 + 432 + if (adjust_tz) { 433 + fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; 434 + fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj; 435 + } 436 + 437 + fattr->cf_eof = le64_to_cpu(info->EndOfFile); 438 + fattr->cf_bytes = le64_to_cpu(info->AllocationSize); 439 + 440 + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { 441 + fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; 442 + fattr->cf_dtype = DT_DIR; 443 + } else { 444 + fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; 445 + fattr->cf_dtype = DT_REG; 446 + 447 + /* clear write bits if ATTR_READONLY is set */ 448 + if (fattr->cf_cifsattrs & ATTR_READONLY) 449 + fattr->cf_mode &= ~(S_IWUGO); 450 + } 451 + 452 + fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); 453 + 454 + fattr->cf_uid = cifs_sb->mnt_uid; 455 + fattr->cf_gid = cifs_sb->mnt_gid; 456 } 457 458 int cifs_get_inode_info(struct inode **pinode, 459 const unsigned char *full_path, FILE_ALL_INFO *pfindData, 460 struct super_block *sb, int xid, const __u16 *pfid) 461 { 462 + int rc = 0, tmprc; 463 struct cifsTconInfo *pTcon; 464 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 465 char *buf = NULL; 466 bool adjustTZ = false; 467 + struct cifs_fattr fattr; 468 469 pTcon = cifs_sb->tcon; 470 cFYI(1, ("Getting info on %s", full_path)); ··· 487 adjustTZ = true; 488 } 489 } 490 + 491 + if (!rc) { 492 + cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData, 493 + cifs_sb, adjustTZ); 494 + } else if (rc == -EREMOTE) { 495 + cifs_create_dfs_fattr(&fattr, sb); 496 rc = 0; 497 + } else { 498 goto cgii_exit; 499 + } 500 501 + /* 502 + * If an inode wasn't passed in, then get the inode number 503 + * 504 + * Is an i_ino of zero legal? Can we use that to check if the server 505 + * supports returning inode numbers? Are there other sanity checks we 506 + * can use to ensure that the server is really filling in that field? 507 + * 508 + * We can not use the IndexNumber field by default from Windows or 509 + * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA 510 + * CIFS spec claims that this value is unique within the scope of a 511 + * share, and the windows docs hint that it's actually unique 512 + * per-machine. 513 + * 514 + * There may be higher info levels that work but are there Windows 515 + * server or network appliances for which IndexNumber field is not 516 + * guaranteed unique? 517 + */ 518 if (*pinode == NULL) { 519 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 520 int rc1 = 0; 521 522 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 523 + full_path, &fattr.cf_uniqueid, 524 cifs_sb->local_nls, 525 cifs_sb->mnt_cifs_flags & 526 CIFS_MOUNT_MAP_SPECIAL_CHR); 527 if (rc1) { 528 /* BB EOPNOSUPP disable SERVER_INUM? */ 529 + cFYI(1, ("GetSrvInodeNum rc %d", rc1)); 530 + fattr.cf_uniqueid = iunique(sb, ROOT_I); 531 } 532 } else { 533 + fattr.cf_uniqueid = iunique(sb, ROOT_I); 534 } 535 } else { 536 + fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid; 537 } 538 539 + /* query for SFU type info if supported and needed */ 540 + if (fattr.cf_cifsattrs & ATTR_SYSTEM && 541 + cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 542 + tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid); 543 + if (tmprc) 544 + cFYI(1, ("cifs_sfu_type failed: %d", tmprc)); 545 } 546 547 #ifdef CONFIG_CIFS_EXPERIMENTAL 548 /* fill in 0777 bits from ACL */ 549 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 550 cFYI(1, ("Getting mode bits from ACL")); 551 + cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid); 552 } 553 #endif 554 + 555 + /* fill in remaining high mode bits e.g. SUID, VTX */ 556 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) 557 + cifs_sfu_mode(&fattr, full_path, cifs_sb, xid); 558 + 559 + if (!*pinode) { 560 + *pinode = cifs_iget(sb, &fattr); 561 + if (!*pinode) 562 + rc = -ENOMEM; 563 + } else { 564 + cifs_fattr_to_inode(*pinode, &fattr); 565 } 566 567 cgii_exit: 568 kfree(buf); ··· 695 return full_path; 696 } 697 698 + static int 699 + cifs_find_inode(struct inode *inode, void *opaque) 700 + { 701 + struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; 702 + 703 + if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) 704 + return 0; 705 + 706 + return 1; 707 + } 708 + 709 + static int 710 + cifs_init_inode(struct inode *inode, void *opaque) 711 + { 712 + struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; 713 + 714 + CIFS_I(inode)->uniqueid = fattr->cf_uniqueid; 715 + return 0; 716 + } 717 + 718 + /* Given fattrs, get a corresponding inode */ 719 + struct inode * 720 + cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) 721 + { 722 + unsigned long hash; 723 + struct inode *inode; 724 + 725 + cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid)); 726 + 727 + /* hash down to 32-bits on 32-bit arch */ 728 + hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); 729 + 730 + inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); 731 + 732 + /* we have fattrs in hand, update the inode */ 733 + if (inode) { 734 + cifs_fattr_to_inode(inode, fattr); 735 + if (sb->s_flags & MS_NOATIME) 736 + inode->i_flags |= S_NOATIME | S_NOCMTIME; 737 + if (inode->i_state & I_NEW) { 738 + inode->i_ino = hash; 739 + unlock_new_inode(inode); 740 + } 741 + } 742 + 743 + return inode; 744 + } 745 + 746 /* gets root inode */ 747 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 748 { 749 int xid; 750 struct cifs_sb_info *cifs_sb; 751 + struct inode *inode = NULL; 752 long rc; 753 char *full_path; 754 755 + cifs_sb = CIFS_SB(sb); 756 full_path = cifs_build_path_to_root(cifs_sb); 757 if (full_path == NULL) 758 return ERR_PTR(-ENOMEM); 759 760 xid = GetXid(); 761 if (cifs_sb->tcon->unix_ext) 762 + rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 763 else 764 + rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 765 xid, NULL); 766 + 767 + if (!inode) 768 + return ERR_PTR(-ENOMEM); 769 + 770 if (rc && cifs_sb->tcon->ipc) { 771 cFYI(1, ("ipc connection - fake read inode")); 772 inode->i_mode |= S_IFDIR; ··· 737 return ERR_PTR(rc); 738 } 739 740 741 kfree(full_path); 742 /* can not call macro FreeXid here since in a void func ··· 1063 return rc; 1064 } 1065 1066 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 1067 { 1068 int rc = 0, tmprc; ··· 1109 struct cifsTconInfo *pTcon; 1110 char *full_path = NULL; 1111 struct inode *newinode = NULL; 1112 + struct cifs_fattr fattr; 1113 1114 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode)); 1115 ··· 1148 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1149 d_drop(direntry); 1150 } else { 1151 if (pInfo->Type == cpu_to_le32(-1)) { 1152 /* no return info, go query for it */ 1153 kfree(pInfo); ··· 1162 else 1163 direntry->d_op = &cifs_dentry_ops; 1164 1165 + cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); 1166 + newinode = cifs_iget(inode->i_sb, &fattr); 1167 + if (!newinode) { 1168 kfree(pInfo); 1169 goto mkdir_get_info; 1170 } 1171 1172 d_instantiate(direntry, newinode); 1173 1174 #ifdef CONFIG_CIFS_DEBUG2 1175 cFYI(1, ("instantiated dentry %p %s to inode %p", 1176 direntry, direntry->d_name.name, newinode)); ··· 1238 args.uid = NO_CHANGE_64; 1239 args.gid = NO_CHANGE_64; 1240 } 1241 + CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, 1242 + cifs_sb->local_nls, 1243 + cifs_sb->mnt_cifs_flags & 1244 + CIFS_MOUNT_MAP_SPECIAL_CHR); 1245 } else { 1246 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && 1247 (mode & S_IWUGO) == 0) { ··· 1622 if (!err) { 1623 generic_fillattr(dentry->d_inode, stat); 1624 stat->blksize = CIFS_MAX_MSGSIZE; 1625 + stat->ino = CIFS_I(dentry->d_inode)->uniqueid; 1626 } 1627 return err; 1628 } ··· 1786 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1787 struct cifsTconInfo *pTcon = cifs_sb->tcon; 1788 struct cifs_unix_set_info_args *args = NULL; 1789 + struct cifsFileInfo *open_file; 1790 1791 cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x", 1792 direntry->d_name.name, attrs->ia_valid)); ··· 1872 args->ctime = NO_CHANGE_64; 1873 1874 args->device = 0; 1875 + open_file = find_writable_file(cifsInode); 1876 + if (open_file) { 1877 + u16 nfid = open_file->netfid; 1878 + u32 npid = open_file->pid; 1879 + rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); 1880 + atomic_dec(&open_file->wrtPending); 1881 + } else { 1882 + rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, 1883 + cifs_sb->local_nls, 1884 + cifs_sb->mnt_cifs_flags & 1885 + CIFS_MOUNT_MAP_SPECIAL_CHR); 1886 + } 1887 1888 if (!rc) 1889 rc = inode_setattr(inode, attrs);
+124 -381
fs/cifs/readdir.c
··· 63 } 64 #endif /* DEBUG2 */ 65 66 - /* Returns 1 if new inode created, 2 if both dentry and inode were */ 67 - /* Might check in the future if inode number changed so we can rehash inode */ 68 - static int 69 - construct_dentry(struct qstr *qstring, struct file *file, 70 - struct inode **ptmp_inode, struct dentry **pnew_dentry, 71 - __u64 *inum) 72 { 73 - struct dentry *tmp_dentry = NULL; 74 - struct super_block *sb = file->f_path.dentry->d_sb; 75 - int rc = 0; 76 77 - cFYI(1, ("For %s", qstring->name)); 78 79 - qstring->hash = full_name_hash(qstring->name, qstring->len); 80 - tmp_dentry = d_lookup(file->f_path.dentry, qstring); 81 - if (tmp_dentry) { 82 - /* BB: overwrite old name? i.e. tmp_dentry->d_name and 83 - * tmp_dentry->d_name.len?? 84 - */ 85 - cFYI(0, ("existing dentry with inode 0x%p", 86 - tmp_dentry->d_inode)); 87 - *ptmp_inode = tmp_dentry->d_inode; 88 - if (*ptmp_inode == NULL) { 89 - *ptmp_inode = cifs_new_inode(sb, inum); 90 - if (*ptmp_inode == NULL) 91 - return rc; 92 - rc = 1; 93 - } 94 - } else { 95 - tmp_dentry = d_alloc(file->f_path.dentry, qstring); 96 - if (tmp_dentry == NULL) { 97 - cERROR(1, ("Failed allocating dentry")); 98 - *ptmp_inode = NULL; 99 - return rc; 100 - } 101 - 102 - if (CIFS_SB(sb)->tcon->nocase) 103 - tmp_dentry->d_op = &cifs_ci_dentry_ops; 104 - else 105 - tmp_dentry->d_op = &cifs_dentry_ops; 106 - 107 - *ptmp_inode = cifs_new_inode(sb, inum); 108 - if (*ptmp_inode == NULL) 109 - return rc; 110 - rc = 2; 111 } 112 113 - tmp_dentry->d_time = jiffies; 114 - *pnew_dentry = tmp_dentry; 115 - return rc; 116 } 117 118 - static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, 119 - char *buf, unsigned int *pobject_type, int isNewInode) 120 { 121 - loff_t local_size; 122 - struct timespec local_mtime; 123 124 - struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); 125 - struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); 126 - __u32 attr; 127 - __u64 allocation_size; 128 - __u64 end_of_file; 129 - umode_t default_mode; 130 - 131 - /* save mtime and size */ 132 - local_mtime = tmp_inode->i_mtime; 133 - local_size = tmp_inode->i_size; 134 - 135 - if (new_buf_type) { 136 - FILE_DIRECTORY_INFO *pfindData = (FILE_DIRECTORY_INFO *)buf; 137 - 138 - attr = le32_to_cpu(pfindData->ExtFileAttributes); 139 - allocation_size = le64_to_cpu(pfindData->AllocationSize); 140 - end_of_file = le64_to_cpu(pfindData->EndOfFile); 141 - tmp_inode->i_atime = 142 - cifs_NTtimeToUnix(pfindData->LastAccessTime); 143 - tmp_inode->i_mtime = 144 - cifs_NTtimeToUnix(pfindData->LastWriteTime); 145 - tmp_inode->i_ctime = 146 - cifs_NTtimeToUnix(pfindData->ChangeTime); 147 - } else { /* legacy, OS2 and DOS style */ 148 - int offset = cifs_sb->tcon->ses->server->timeAdj; 149 - FIND_FILE_STANDARD_INFO *pfindData = 150 - (FIND_FILE_STANDARD_INFO *)buf; 151 - 152 - tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate, 153 - pfindData->LastWriteTime, 154 - offset); 155 - tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate, 156 - pfindData->LastAccessTime, 157 - offset); 158 - tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate, 159 - pfindData->LastWriteTime, 160 - offset); 161 - attr = le16_to_cpu(pfindData->Attributes); 162 - allocation_size = le32_to_cpu(pfindData->AllocationSize); 163 - end_of_file = le32_to_cpu(pfindData->DataSize); 164 } 165 166 - /* Linux can not store file creation time unfortunately so ignore it */ 167 168 - cifsInfo->cifsAttrs = attr; 169 - #ifdef CONFIG_CIFS_EXPERIMENTAL 170 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 171 - /* get more accurate mode via ACL - so force inode refresh */ 172 - cifsInfo->time = 0; 173 - } else 174 - #endif /* CONFIG_CIFS_EXPERIMENTAL */ 175 - cifsInfo->time = jiffies; 176 - 177 - /* treat dos attribute of read-only as read-only mode bit e.g. 555? */ 178 - /* 2767 perms - indicate mandatory locking */ 179 - /* BB fill in uid and gid here? with help from winbind? 180 - or retrieve from NTFS stream extended attribute */ 181 - if (atomic_read(&cifsInfo->inUse) == 0) { 182 - tmp_inode->i_uid = cifs_sb->mnt_uid; 183 - tmp_inode->i_gid = cifs_sb->mnt_gid; 184 - } 185 - 186 - if (attr & ATTR_DIRECTORY) 187 - default_mode = cifs_sb->mnt_dir_mode; 188 - else 189 - default_mode = cifs_sb->mnt_file_mode; 190 - 191 - /* set initial permissions */ 192 - if ((atomic_read(&cifsInfo->inUse) == 0) || 193 - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) 194 - tmp_inode->i_mode = default_mode; 195 - else { 196 - /* just reenable write bits if !ATTR_READONLY */ 197 - if ((tmp_inode->i_mode & S_IWUGO) == 0 && 198 - (attr & ATTR_READONLY) == 0) 199 - tmp_inode->i_mode |= (S_IWUGO & default_mode); 200 - 201 - tmp_inode->i_mode &= ~S_IFMT; 202 - } 203 - 204 - /* clear write bits if ATTR_READONLY is set */ 205 - if (attr & ATTR_READONLY) 206 - tmp_inode->i_mode &= ~S_IWUGO; 207 - 208 - /* set inode type */ 209 - if ((attr & ATTR_SYSTEM) && 210 - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { 211 - if (end_of_file == 0) { 212 - tmp_inode->i_mode |= S_IFIFO; 213 - *pobject_type = DT_FIFO; 214 } else { 215 /* 216 - * trying to get the type can be slow, so just call 217 - * this a regular file for now, and mark for reval 218 */ 219 - tmp_inode->i_mode |= S_IFREG; 220 - *pobject_type = DT_REG; 221 - cifsInfo->time = 0; 222 } 223 - } else { 224 - if (attr & ATTR_DIRECTORY) { 225 - tmp_inode->i_mode |= S_IFDIR; 226 - *pobject_type = DT_DIR; 227 - } else { 228 - tmp_inode->i_mode |= S_IFREG; 229 - *pobject_type = DT_REG; 230 - } 231 - } 232 - 233 - /* can not fill in nlink here as in qpathinfo version and Unx search */ 234 - if (atomic_read(&cifsInfo->inUse) == 0) 235 - atomic_set(&cifsInfo->inUse, 1); 236 - 237 - cifsInfo->server_eof = end_of_file; 238 - spin_lock(&tmp_inode->i_lock); 239 - if (is_size_safe_to_change(cifsInfo, end_of_file)) { 240 - /* can not safely change the file size here if the 241 - client is writing to it due to potential races */ 242 - i_size_write(tmp_inode, end_of_file); 243 - 244 - /* 512 bytes (2**9) is the fake blocksize that must be used */ 245 - /* for this calculation, even though the reported blocksize is larger */ 246 - tmp_inode->i_blocks = (512 - 1 + allocation_size) >> 9; 247 - } 248 - spin_unlock(&tmp_inode->i_lock); 249 - 250 - if (allocation_size < end_of_file) 251 - cFYI(1, ("May be sparse file, allocation less than file size")); 252 - cFYI(1, ("File Size %ld and blocks %llu", 253 - (unsigned long)tmp_inode->i_size, 254 - (unsigned long long)tmp_inode->i_blocks)); 255 - if (S_ISREG(tmp_inode->i_mode)) { 256 - cFYI(1, ("File inode")); 257 - tmp_inode->i_op = &cifs_file_inode_ops; 258 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 259 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 260 - tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 261 - else 262 - tmp_inode->i_fop = &cifs_file_direct_ops; 263 - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 264 - tmp_inode->i_fop = &cifs_file_nobrl_ops; 265 - else 266 - tmp_inode->i_fop = &cifs_file_ops; 267 - 268 - if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 269 - (cifs_sb->tcon->ses->server->maxBuf < 270 - PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 271 - tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 272 - else 273 - tmp_inode->i_data.a_ops = &cifs_addr_ops; 274 - 275 - if (isNewInode) 276 - return; /* No sense invalidating pages for new inode 277 - since have not started caching readahead file 278 - data yet */ 279 - 280 - if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 281 - (local_size == tmp_inode->i_size)) { 282 - cFYI(1, ("inode exists but unchanged")); 283 - } else { 284 - /* file may have changed on server */ 285 - cFYI(1, ("invalidate inode, readdir detected change")); 286 - invalidate_remote_inode(tmp_inode); 287 - } 288 - } else if (S_ISDIR(tmp_inode->i_mode)) { 289 - cFYI(1, ("Directory inode")); 290 - tmp_inode->i_op = &cifs_dir_inode_ops; 291 - tmp_inode->i_fop = &cifs_dir_ops; 292 - } else if (S_ISLNK(tmp_inode->i_mode)) { 293 - cFYI(1, ("Symbolic Link inode")); 294 - tmp_inode->i_op = &cifs_symlink_inode_ops; 295 - } else { 296 - cFYI(1, ("Init special inode")); 297 - init_special_inode(tmp_inode, tmp_inode->i_mode, 298 - tmp_inode->i_rdev); 299 } 300 } 301 302 - static void unix_fill_in_inode(struct inode *tmp_inode, 303 - FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode) 304 { 305 - loff_t local_size; 306 - struct timespec local_mtime; 307 308 - struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode); 309 - struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); 310 311 - __u32 type = le32_to_cpu(pfindData->Type); 312 - __u64 num_of_bytes = le64_to_cpu(pfindData->NumOfBytes); 313 - __u64 end_of_file = le64_to_cpu(pfindData->EndOfFile); 314 - cifsInfo->time = jiffies; 315 - atomic_inc(&cifsInfo->inUse); 316 317 - /* save mtime and size */ 318 - local_mtime = tmp_inode->i_mtime; 319 - local_size = tmp_inode->i_size; 320 321 - tmp_inode->i_atime = 322 - cifs_NTtimeToUnix(pfindData->LastAccessTime); 323 - tmp_inode->i_mtime = 324 - cifs_NTtimeToUnix(pfindData->LastModificationTime); 325 - tmp_inode->i_ctime = 326 - cifs_NTtimeToUnix(pfindData->LastStatusChange); 327 328 - tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); 329 - /* since we set the inode type below we need to mask off type 330 - to avoid strange results if bits above were corrupt */ 331 - tmp_inode->i_mode &= ~S_IFMT; 332 - if (type == UNIX_FILE) { 333 - *pobject_type = DT_REG; 334 - tmp_inode->i_mode |= S_IFREG; 335 - } else if (type == UNIX_SYMLINK) { 336 - *pobject_type = DT_LNK; 337 - tmp_inode->i_mode |= S_IFLNK; 338 - } else if (type == UNIX_DIR) { 339 - *pobject_type = DT_DIR; 340 - tmp_inode->i_mode |= S_IFDIR; 341 - } else if (type == UNIX_CHARDEV) { 342 - *pobject_type = DT_CHR; 343 - tmp_inode->i_mode |= S_IFCHR; 344 - tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor), 345 - le64_to_cpu(pfindData->DevMinor) & MINORMASK); 346 - } else if (type == UNIX_BLOCKDEV) { 347 - *pobject_type = DT_BLK; 348 - tmp_inode->i_mode |= S_IFBLK; 349 - tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor), 350 - le64_to_cpu(pfindData->DevMinor) & MINORMASK); 351 - } else if (type == UNIX_FIFO) { 352 - *pobject_type = DT_FIFO; 353 - tmp_inode->i_mode |= S_IFIFO; 354 - } else if (type == UNIX_SOCKET) { 355 - *pobject_type = DT_SOCK; 356 - tmp_inode->i_mode |= S_IFSOCK; 357 - } else { 358 - /* safest to just call it a file */ 359 - *pobject_type = DT_REG; 360 - tmp_inode->i_mode |= S_IFREG; 361 - cFYI(1, ("unknown inode type %d", type)); 362 - } 363 - 364 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) 365 - tmp_inode->i_uid = cifs_sb->mnt_uid; 366 - else 367 - tmp_inode->i_uid = le64_to_cpu(pfindData->Uid); 368 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) 369 - tmp_inode->i_gid = cifs_sb->mnt_gid; 370 - else 371 - tmp_inode->i_gid = le64_to_cpu(pfindData->Gid); 372 - tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks); 373 - 374 - cifsInfo->server_eof = end_of_file; 375 - spin_lock(&tmp_inode->i_lock); 376 - if (is_size_safe_to_change(cifsInfo, end_of_file)) { 377 - /* can not safely change the file size here if the 378 - client is writing to it due to potential races */ 379 - i_size_write(tmp_inode, end_of_file); 380 - 381 - /* 512 bytes (2**9) is the fake blocksize that must be used */ 382 - /* for this calculation, not the real blocksize */ 383 - tmp_inode->i_blocks = (512 - 1 + num_of_bytes) >> 9; 384 - } 385 - spin_unlock(&tmp_inode->i_lock); 386 - 387 - if (S_ISREG(tmp_inode->i_mode)) { 388 - cFYI(1, ("File inode")); 389 - tmp_inode->i_op = &cifs_file_inode_ops; 390 - 391 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 392 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 393 - tmp_inode->i_fop = &cifs_file_direct_nobrl_ops; 394 - else 395 - tmp_inode->i_fop = &cifs_file_direct_ops; 396 - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) 397 - tmp_inode->i_fop = &cifs_file_nobrl_ops; 398 - else 399 - tmp_inode->i_fop = &cifs_file_ops; 400 - 401 - if ((cifs_sb->tcon) && (cifs_sb->tcon->ses) && 402 - (cifs_sb->tcon->ses->server->maxBuf < 403 - PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)) 404 - tmp_inode->i_data.a_ops = &cifs_addr_ops_smallbuf; 405 - else 406 - tmp_inode->i_data.a_ops = &cifs_addr_ops; 407 - 408 - if (isNewInode) 409 - return; /* No sense invalidating pages for new inode 410 - since we have not started caching readahead 411 - file data for it yet */ 412 - 413 - if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) && 414 - (local_size == tmp_inode->i_size)) { 415 - cFYI(1, ("inode exists but unchanged")); 416 - } else { 417 - /* file may have changed on server */ 418 - cFYI(1, ("invalidate inode, readdir detected change")); 419 - invalidate_remote_inode(tmp_inode); 420 - } 421 - } else if (S_ISDIR(tmp_inode->i_mode)) { 422 - cFYI(1, ("Directory inode")); 423 - tmp_inode->i_op = &cifs_dir_inode_ops; 424 - tmp_inode->i_fop = &cifs_dir_ops; 425 - } else if (S_ISLNK(tmp_inode->i_mode)) { 426 - cFYI(1, ("Symbolic Link inode")); 427 - tmp_inode->i_op = &cifs_symlink_inode_ops; 428 - /* tmp_inode->i_fop = *//* do not need to set to anything */ 429 - } else { 430 - cFYI(1, ("Special inode")); 431 - init_special_inode(tmp_inode, tmp_inode->i_mode, 432 - tmp_inode->i_rdev); 433 - } 434 } 435 436 /* BB eventually need to add the following helper function to ··· 621 len = strnlen(filename, PATH_MAX); 622 } 623 624 - *pinum = le64_to_cpu(pFindData->UniqueId); 625 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 626 FILE_DIRECTORY_INFO *pFindData = 627 (FILE_DIRECTORY_INFO *)current_entry; ··· 681 int rc = 0; 682 struct qstr qstring; 683 struct cifsFileInfo *pCifsF; 684 - unsigned int obj_type; 685 - __u64 inum; 686 struct cifs_sb_info *cifs_sb; 687 - struct inode *tmp_inode; 688 struct dentry *tmp_dentry; 689 690 /* get filename and len into qstring */ 691 /* get dentry */ ··· 704 if (rc != 0) 705 return 0; 706 707 - cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 708 709 qstring.name = scratch_buf; 710 rc = cifs_get_name_from_search_buf(&qstring, pfindEntry, 711 pCifsF->srch_inf.info_level, 712 pCifsF->srch_inf.unicode, cifs_sb, 713 - max_len, 714 - &inum /* returned */); 715 716 if (rc) 717 return rc; 718 719 - /* only these two infolevels return valid inode numbers */ 720 - if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || 721 - pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) 722 - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 723 - &inum); 724 - else 725 - rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, 726 - NULL); 727 - 728 - if ((tmp_inode == NULL) || (tmp_dentry == NULL)) 729 - return -ENOMEM; 730 - 731 - /* we pass in rc below, indicating whether it is a new inode, 732 - so we can figure out whether to invalidate the inode cached 733 - data if the file has changed */ 734 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 735 - unix_fill_in_inode(tmp_inode, 736 - (FILE_UNIX_INFO *)pfindEntry, 737 - &obj_type, rc); 738 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 739 - fill_in_inode(tmp_inode, 0 /* old level 1 buffer type */, 740 - pfindEntry, &obj_type, rc); 741 else 742 - fill_in_inode(tmp_inode, 1 /* NT */, pfindEntry, &obj_type, rc); 743 744 - if (rc) /* new inode - needs to be tied to dentry */ { 745 - d_instantiate(tmp_dentry, tmp_inode); 746 - if (rc == 2) 747 - d_rehash(tmp_dentry); 748 - } 749 750 751 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, 752 - tmp_inode->i_ino, obj_type); 753 if (rc) { 754 cFYI(1, ("filldir rc = %d", rc)); 755 - /* we can not return filldir errors to the caller 756 - since they are "normal" when the stat blocksize 757 - is too small - we return remapped error instead */ 758 rc = -EOVERFLOW; 759 } 760 - 761 dput(tmp_dentry); 762 return rc; 763 }
··· 63 } 64 #endif /* DEBUG2 */ 65 66 + /* 67 + * Find the dentry that matches "name". If there isn't one, create one. If it's 68 + * a negative dentry or the uniqueid changed, then drop it and recreate it. 69 + */ 70 + static struct dentry * 71 + cifs_readdir_lookup(struct dentry *parent, struct qstr *name, 72 + struct cifs_fattr *fattr) 73 { 74 + struct dentry *dentry, *alias; 75 + struct inode *inode; 76 + struct super_block *sb = parent->d_inode->i_sb; 77 78 + cFYI(1, ("For %s", name->name)); 79 80 + dentry = d_lookup(parent, name); 81 + if (dentry) { 82 + /* FIXME: check for inode number changes? */ 83 + if (dentry->d_inode != NULL) 84 + return dentry; 85 + d_drop(dentry); 86 + dput(dentry); 87 } 88 89 + dentry = d_alloc(parent, name); 90 + if (dentry == NULL) 91 + return NULL; 92 + 93 + inode = cifs_iget(sb, fattr); 94 + if (!inode) { 95 + dput(dentry); 96 + return NULL; 97 + } 98 + 99 + if (CIFS_SB(sb)->tcon->nocase) 100 + dentry->d_op = &cifs_ci_dentry_ops; 101 + else 102 + dentry->d_op = &cifs_dentry_ops; 103 + 104 + alias = d_materialise_unique(dentry, inode); 105 + if (alias != NULL) { 106 + dput(dentry); 107 + if (IS_ERR(alias)) 108 + return NULL; 109 + dentry = alias; 110 + } 111 + 112 + return dentry; 113 } 114 115 + static void 116 + cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) 117 { 118 + fattr->cf_uid = cifs_sb->mnt_uid; 119 + fattr->cf_gid = cifs_sb->mnt_gid; 120 121 + if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { 122 + fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; 123 + fattr->cf_dtype = DT_DIR; 124 + } else { 125 + fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; 126 + fattr->cf_dtype = DT_REG; 127 } 128 129 + if (fattr->cf_cifsattrs & ATTR_READONLY) 130 + fattr->cf_mode &= ~S_IWUGO; 131 132 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && 133 + fattr->cf_cifsattrs & ATTR_SYSTEM) { 134 + if (fattr->cf_eof == 0) { 135 + fattr->cf_mode &= ~S_IFMT; 136 + fattr->cf_mode |= S_IFIFO; 137 + fattr->cf_dtype = DT_FIFO; 138 } else { 139 /* 140 + * trying to get the type and mode via SFU can be slow, 141 + * so just call those regular files for now, and mark 142 + * for reval 143 */ 144 + fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; 145 } 146 } 147 } 148 149 + void 150 + cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, 151 + struct cifs_sb_info *cifs_sb) 152 { 153 + memset(fattr, 0, sizeof(*fattr)); 154 + fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); 155 + fattr->cf_eof = le64_to_cpu(info->EndOfFile); 156 + fattr->cf_bytes = le64_to_cpu(info->AllocationSize); 157 + fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 158 + fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); 159 + fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); 160 161 + cifs_fill_common_info(fattr, cifs_sb); 162 + } 163 164 + void 165 + cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, 166 + struct cifs_sb_info *cifs_sb) 167 + { 168 + int offset = cifs_sb->tcon->ses->server->timeAdj; 169 170 + memset(fattr, 0, sizeof(*fattr)); 171 + fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, 172 + info->LastAccessTime, offset); 173 + fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate, 174 + info->LastWriteTime, offset); 175 + fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate, 176 + info->LastWriteTime, offset); 177 178 + fattr->cf_cifsattrs = le16_to_cpu(info->Attributes); 179 + fattr->cf_bytes = le32_to_cpu(info->AllocationSize); 180 + fattr->cf_eof = le32_to_cpu(info->DataSize); 181 182 + cifs_fill_common_info(fattr, cifs_sb); 183 } 184 185 /* BB eventually need to add the following helper function to ··· 872 len = strnlen(filename, PATH_MAX); 873 } 874 875 + *pinum = le64_to_cpu(pFindData->basic.UniqueId); 876 } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { 877 FILE_DIRECTORY_INFO *pFindData = 878 (FILE_DIRECTORY_INFO *)current_entry; ··· 932 int rc = 0; 933 struct qstr qstring; 934 struct cifsFileInfo *pCifsF; 935 + u64 inum; 936 + ino_t ino; 937 + struct super_block *sb; 938 struct cifs_sb_info *cifs_sb; 939 struct dentry *tmp_dentry; 940 + struct cifs_fattr fattr; 941 942 /* get filename and len into qstring */ 943 /* get dentry */ ··· 954 if (rc != 0) 955 return 0; 956 957 + sb = file->f_path.dentry->d_sb; 958 + cifs_sb = CIFS_SB(sb); 959 960 qstring.name = scratch_buf; 961 rc = cifs_get_name_from_search_buf(&qstring, pfindEntry, 962 pCifsF->srch_inf.info_level, 963 pCifsF->srch_inf.unicode, cifs_sb, 964 + max_len, &inum /* returned */); 965 966 if (rc) 967 return rc; 968 969 if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX) 970 + cifs_unix_basic_to_fattr(&fattr, 971 + &((FILE_UNIX_INFO *) pfindEntry)->basic, 972 + cifs_sb); 973 else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) 974 + cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *) 975 + pfindEntry, cifs_sb); 976 else 977 + cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) 978 + pfindEntry, cifs_sb); 979 980 + /* FIXME: make _to_fattr functions fill this out */ 981 + if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) 982 + fattr.cf_uniqueid = inum; 983 + else 984 + fattr.cf_uniqueid = iunique(sb, ROOT_I); 985 986 + ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 987 + tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); 988 989 rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, 990 + ino, fattr.cf_dtype); 991 + 992 + /* 993 + * we can not return filldir errors to the caller since they are 994 + * "normal" when the stat blocksize is too small - we return remapped 995 + * error instead 996 + * 997 + * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above 998 + * case already. Why should we be clobbering other errors from it? 999 + */ 1000 if (rc) { 1001 cFYI(1, ("filldir rc = %d", rc)); 1002 rc = -EOVERFLOW; 1003 } 1004 dput(tmp_dentry); 1005 return rc; 1006 }