diff options
Diffstat (limited to 'fs/cifs/readdir.c')
| -rw-r--r-- | fs/cifs/readdir.c | 58 |
1 files changed, 26 insertions, 32 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 9f51f9bf0292..c2c01ff4c32c 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -56,35 +56,34 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) | |||
| 56 | } | 56 | } |
| 57 | #endif /* DEBUG2 */ | 57 | #endif /* DEBUG2 */ |
| 58 | 58 | ||
| 59 | /* Returns one if new inode created (which therefore needs to be hashed) */ | 59 | /* Returns 1 if new inode created, 2 if both dentry and inode were */ |
| 60 | /* Might check in the future if inode number changed so we can rehash inode */ | 60 | /* Might check in the future if inode number changed so we can rehash inode */ |
| 61 | static int construct_dentry(struct qstr *qstring, struct file *file, | 61 | static int |
| 62 | struct inode **ptmp_inode, struct dentry **pnew_dentry) | 62 | construct_dentry(struct qstr *qstring, struct file *file, |
| 63 | struct inode **ptmp_inode, struct dentry **pnew_dentry, | ||
| 64 | __u64 *inum) | ||
| 63 | { | 65 | { |
| 64 | struct dentry *tmp_dentry; | 66 | struct dentry *tmp_dentry = NULL; |
| 65 | struct cifs_sb_info *cifs_sb; | 67 | struct super_block *sb = file->f_path.dentry->d_sb; |
| 66 | struct cifsTconInfo *pTcon; | ||
| 67 | int rc = 0; | 68 | int rc = 0; |
| 68 | 69 | ||
| 69 | cFYI(1, ("For %s", qstring->name)); | 70 | cFYI(1, ("For %s", qstring->name)); |
| 70 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | ||
| 71 | pTcon = cifs_sb->tcon; | ||
| 72 | 71 | ||
| 73 | qstring->hash = full_name_hash(qstring->name, qstring->len); | 72 | qstring->hash = full_name_hash(qstring->name, qstring->len); |
| 74 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); | 73 | tmp_dentry = d_lookup(file->f_path.dentry, qstring); |
| 75 | if (tmp_dentry) { | 74 | if (tmp_dentry) { |
| 75 | /* BB: overwrite old name? i.e. tmp_dentry->d_name and | ||
| 76 | * tmp_dentry->d_name.len?? | ||
| 77 | */ | ||
| 76 | cFYI(0, ("existing dentry with inode 0x%p", | 78 | cFYI(0, ("existing dentry with inode 0x%p", |
| 77 | tmp_dentry->d_inode)); | 79 | tmp_dentry->d_inode)); |
| 78 | *ptmp_inode = tmp_dentry->d_inode; | 80 | *ptmp_inode = tmp_dentry->d_inode; |
| 79 | /* BB overwrite old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len??*/ | ||
| 80 | if (*ptmp_inode == NULL) { | 81 | if (*ptmp_inode == NULL) { |
| 81 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); | 82 | *ptmp_inode = cifs_new_inode(sb, inum); |
| 82 | if (*ptmp_inode == NULL) | 83 | if (*ptmp_inode == NULL) |
| 83 | return rc; | 84 | return rc; |
| 84 | rc = 1; | 85 | rc = 1; |
| 85 | } | 86 | } |
| 86 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | ||
| 87 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 88 | } else { | 87 | } else { |
| 89 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); | 88 | tmp_dentry = d_alloc(file->f_path.dentry, qstring); |
| 90 | if (tmp_dentry == NULL) { | 89 | if (tmp_dentry == NULL) { |
| @@ -93,15 +92,14 @@ static int construct_dentry(struct qstr *qstring, struct file *file, | |||
| 93 | return rc; | 92 | return rc; |
| 94 | } | 93 | } |
| 95 | 94 | ||
| 96 | *ptmp_inode = new_inode(file->f_path.dentry->d_sb); | 95 | if (CIFS_SB(sb)->tcon->nocase) |
| 97 | if (pTcon->nocase) | ||
| 98 | tmp_dentry->d_op = &cifs_ci_dentry_ops; | 96 | tmp_dentry->d_op = &cifs_ci_dentry_ops; |
| 99 | else | 97 | else |
| 100 | tmp_dentry->d_op = &cifs_dentry_ops; | 98 | tmp_dentry->d_op = &cifs_dentry_ops; |
| 99 | |||
| 100 | *ptmp_inode = cifs_new_inode(sb, inum); | ||
| 101 | if (*ptmp_inode == NULL) | 101 | if (*ptmp_inode == NULL) |
| 102 | return rc; | 102 | return rc; |
| 103 | if (file->f_path.dentry->d_sb->s_flags & MS_NOATIME) | ||
| 104 | (*ptmp_inode)->i_flags |= S_NOATIME | S_NOCMTIME; | ||
| 105 | rc = 2; | 103 | rc = 2; |
| 106 | } | 104 | } |
| 107 | 105 | ||
| @@ -822,7 +820,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
| 822 | /* inode num, inode type and filename returned */ | 820 | /* inode num, inode type and filename returned */ |
| 823 | static int cifs_get_name_from_search_buf(struct qstr *pqst, | 821 | static int cifs_get_name_from_search_buf(struct qstr *pqst, |
| 824 | char *current_entry, __u16 level, unsigned int unicode, | 822 | char *current_entry, __u16 level, unsigned int unicode, |
| 825 | struct cifs_sb_info *cifs_sb, int max_len, ino_t *pinum) | 823 | struct cifs_sb_info *cifs_sb, int max_len, __u64 *pinum) |
| 826 | { | 824 | { |
| 827 | int rc = 0; | 825 | int rc = 0; |
| 828 | unsigned int len = 0; | 826 | unsigned int len = 0; |
| @@ -842,9 +840,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, | |||
| 842 | len = strnlen(filename, PATH_MAX); | 840 | len = strnlen(filename, PATH_MAX); |
| 843 | } | 841 | } |
| 844 | 842 | ||
| 845 | /* BB fixme - hash low and high 32 bits if not 64 bit arch BB */ | 843 | *pinum = pFindData->UniqueId; |
| 846 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | ||
| 847 | *pinum = pFindData->UniqueId; | ||
| 848 | } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { | 844 | } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) { |
| 849 | FILE_DIRECTORY_INFO *pFindData = | 845 | FILE_DIRECTORY_INFO *pFindData = |
| 850 | (FILE_DIRECTORY_INFO *)current_entry; | 846 | (FILE_DIRECTORY_INFO *)current_entry; |
| @@ -907,7 +903,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
| 907 | struct qstr qstring; | 903 | struct qstr qstring; |
| 908 | struct cifsFileInfo *pCifsF; | 904 | struct cifsFileInfo *pCifsF; |
| 909 | unsigned int obj_type; | 905 | unsigned int obj_type; |
| 910 | ino_t inum; | 906 | __u64 inum; |
| 911 | struct cifs_sb_info *cifs_sb; | 907 | struct cifs_sb_info *cifs_sb; |
| 912 | struct inode *tmp_inode; | 908 | struct inode *tmp_inode; |
| 913 | struct dentry *tmp_dentry; | 909 | struct dentry *tmp_dentry; |
| @@ -940,20 +936,18 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
| 940 | if (rc) | 936 | if (rc) |
| 941 | return rc; | 937 | return rc; |
| 942 | 938 | ||
| 943 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry); | 939 | /* only these two infolevels return valid inode numbers */ |
| 940 | if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX || | ||
| 941 | pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO) | ||
| 942 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, | ||
| 943 | &inum); | ||
| 944 | else | ||
| 945 | rc = construct_dentry(&qstring, file, &tmp_inode, &tmp_dentry, | ||
| 946 | NULL); | ||
| 947 | |||
| 944 | if ((tmp_inode == NULL) || (tmp_dentry == NULL)) | 948 | if ((tmp_inode == NULL) || (tmp_dentry == NULL)) |
| 945 | return -ENOMEM; | 949 | return -ENOMEM; |
| 946 | 950 | ||
| 947 | if (rc) { | ||
| 948 | /* inode created, we need to hash it with right inode number */ | ||
| 949 | if (inum != 0) { | ||
| 950 | /* BB fixme - hash the 2 32 quantities bits together if | ||
| 951 | * necessary BB */ | ||
| 952 | tmp_inode->i_ino = inum; | ||
| 953 | } | ||
| 954 | insert_inode_hash(tmp_inode); | ||
| 955 | } | ||
| 956 | |||
| 957 | /* we pass in rc below, indicating whether it is a new inode, | 951 | /* we pass in rc below, indicating whether it is a new inode, |
| 958 | so we can figure out whether to invalidate the inode cached | 952 | so we can figure out whether to invalidate the inode cached |
| 959 | data if the file has changed */ | 953 | data if the file has changed */ |
