namei.c (47e4937a4a7ca4184fd282791dfee76c6799966a) | namei.c (8d8a09b093d7073465c824f74caf315c073d3875) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 * http://www.huawei.com/ 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 */ 7#include "xattr.h" 8 --- 50 unchanged lines hidden (view full) --- 59 60 while (head <= back) { 61 const int mid = head + (back - head) / 2; 62 const int nameoff = nameoff_from_disk(de[mid].nameoff, 63 dirblksize); 64 unsigned int matched = min(startprfx, endprfx); 65 struct erofs_qstr dname = { 66 .name = data + nameoff, | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 * http://www.huawei.com/ 5 * Created by Gao Xiang <gaoxiang25@huawei.com> 6 */ 7#include "xattr.h" 8 --- 50 unchanged lines hidden (view full) --- 59 60 while (head <= back) { 61 const int mid = head + (back - head) / 2; 62 const int nameoff = nameoff_from_disk(de[mid].nameoff, 63 dirblksize); 64 unsigned int matched = min(startprfx, endprfx); 65 struct erofs_qstr dname = { 66 .name = data + nameoff, |
67 .end = unlikely(mid >= ndirents - 1) ? | 67 .end = mid >= ndirents - 1 ? |
68 data + dirblksize : 69 data + nameoff_from_disk(de[mid + 1].nameoff, 70 dirblksize) 71 }; 72 73 /* string comparison without already matched prefix */ 74 int ret = dirnamecmp(name, &dname, &matched); 75 | 68 data + dirblksize : 69 data + nameoff_from_disk(de[mid + 1].nameoff, 70 dirblksize) 71 }; 72 73 /* string comparison without already matched prefix */ 74 int ret = dirnamecmp(name, &dname, &matched); 75 |
76 if (unlikely(!ret)) { | 76 if (!ret) { |
77 return de + mid; 78 } else if (ret > 0) { 79 head = mid + 1; 80 startprfx = matched; 81 } else { 82 back = mid - 1; 83 endprfx = matched; 84 } --- 23 unchanged lines hidden (view full) --- 108 struct erofs_dirent *de = kmap_atomic(page); 109 const int nameoff = nameoff_from_disk(de->nameoff, 110 EROFS_BLKSIZ); 111 const int ndirents = nameoff / sizeof(*de); 112 int diff; 113 unsigned int matched; 114 struct erofs_qstr dname; 115 | 77 return de + mid; 78 } else if (ret > 0) { 79 head = mid + 1; 80 startprfx = matched; 81 } else { 82 back = mid - 1; 83 endprfx = matched; 84 } --- 23 unchanged lines hidden (view full) --- 108 struct erofs_dirent *de = kmap_atomic(page); 109 const int nameoff = nameoff_from_disk(de->nameoff, 110 EROFS_BLKSIZ); 111 const int ndirents = nameoff / sizeof(*de); 112 int diff; 113 unsigned int matched; 114 struct erofs_qstr dname; 115 |
116 if (unlikely(!ndirents)) { | 116 if (!ndirents) { |
117 kunmap_atomic(de); 118 put_page(page); 119 errln("corrupted dir block %d @ nid %llu", 120 mid, EROFS_V(dir)->nid); 121 DBG_BUGON(1); 122 page = ERR_PTR(-EFSCORRUPTED); 123 goto out; 124 } --- 7 unchanged lines hidden (view full) --- 132 dname.end = (u8 *)de + 133 nameoff_from_disk(de[1].nameoff, 134 EROFS_BLKSIZ); 135 136 /* string comparison without already matched prefix */ 137 diff = dirnamecmp(name, &dname, &matched); 138 kunmap_atomic(de); 139 | 117 kunmap_atomic(de); 118 put_page(page); 119 errln("corrupted dir block %d @ nid %llu", 120 mid, EROFS_V(dir)->nid); 121 DBG_BUGON(1); 122 page = ERR_PTR(-EFSCORRUPTED); 123 goto out; 124 } --- 7 unchanged lines hidden (view full) --- 132 dname.end = (u8 *)de + 133 nameoff_from_disk(de[1].nameoff, 134 EROFS_BLKSIZ); 135 136 /* string comparison without already matched prefix */ 137 diff = dirnamecmp(name, &dname, &matched); 138 kunmap_atomic(de); 139 |
140 if (unlikely(!diff)) { | 140 if (!diff) { |
141 *_ndirents = 0; 142 goto out; 143 } else if (diff > 0) { 144 head = mid + 1; 145 startprfx = matched; 146 147 if (!IS_ERR(candidate)) 148 put_page(candidate); --- 20 unchanged lines hidden (view full) --- 169 erofs_nid_t *nid, unsigned int *d_type) 170{ 171 int ndirents; 172 struct page *page; 173 void *data; 174 struct erofs_dirent *de; 175 struct erofs_qstr qn; 176 | 141 *_ndirents = 0; 142 goto out; 143 } else if (diff > 0) { 144 head = mid + 1; 145 startprfx = matched; 146 147 if (!IS_ERR(candidate)) 148 put_page(candidate); --- 20 unchanged lines hidden (view full) --- 169 erofs_nid_t *nid, unsigned int *d_type) 170{ 171 int ndirents; 172 struct page *page; 173 void *data; 174 struct erofs_dirent *de; 175 struct erofs_qstr qn; 176 |
177 if (unlikely(!dir->i_size)) | 177 if (!dir->i_size) |
178 return -ENOENT; 179 180 qn.name = name->name; 181 qn.end = name->name + name->len; 182 183 ndirents = 0; 184 page = find_target_block_classic(dir, &qn, &ndirents); 185 --- 30 unchanged lines hidden (view full) --- 216 217 DBG_BUGON(!d_really_is_negative(dentry)); 218 /* dentry must be unhashed in lookup, no need to worry about */ 219 DBG_BUGON(!d_unhashed(dentry)); 220 221 trace_erofs_lookup(dir, dentry, flags); 222 223 /* file name exceeds fs limit */ | 178 return -ENOENT; 179 180 qn.name = name->name; 181 qn.end = name->name + name->len; 182 183 ndirents = 0; 184 page = find_target_block_classic(dir, &qn, &ndirents); 185 --- 30 unchanged lines hidden (view full) --- 216 217 DBG_BUGON(!d_really_is_negative(dentry)); 218 /* dentry must be unhashed in lookup, no need to worry about */ 219 DBG_BUGON(!d_unhashed(dentry)); 220 221 trace_erofs_lookup(dir, dentry, flags); 222 223 /* file name exceeds fs limit */ |
224 if (unlikely(dentry->d_name.len > EROFS_NAME_LEN)) | 224 if (dentry->d_name.len > EROFS_NAME_LEN) |
225 return ERR_PTR(-ENAMETOOLONG); 226 227 /* false uninitialized warnings on gcc 4.8.x */ 228 err = erofs_namei(dir, &dentry->d_name, &nid, &d_type); 229 230 if (err == -ENOENT) { 231 /* negative dentry */ 232 inode = NULL; | 225 return ERR_PTR(-ENAMETOOLONG); 226 227 /* false uninitialized warnings on gcc 4.8.x */ 228 err = erofs_namei(dir, &dentry->d_name, &nid, &d_type); 229 230 if (err == -ENOENT) { 231 /* negative dentry */ 232 inode = NULL; |
233 } else if (unlikely(err)) { | 233 } else if (err) { |
234 inode = ERR_PTR(err); 235 } else { 236 debugln("%s, %s (nid %llu) found, d_type %u", __func__, 237 dentry->d_name.name, nid, d_type); 238 inode = erofs_iget(dir->i_sb, nid, d_type == FT_DIR); 239 } 240 return d_splice_alias(inode, dentry); 241} 242 243const struct inode_operations erofs_dir_iops = { 244 .lookup = erofs_lookup, 245 .getattr = erofs_getattr, 246#ifdef CONFIG_EROFS_FS_XATTR 247 .listxattr = erofs_listxattr, 248#endif 249 .get_acl = erofs_get_acl, 250}; 251 | 234 inode = ERR_PTR(err); 235 } else { 236 debugln("%s, %s (nid %llu) found, d_type %u", __func__, 237 dentry->d_name.name, nid, d_type); 238 inode = erofs_iget(dir->i_sb, nid, d_type == FT_DIR); 239 } 240 return d_splice_alias(inode, dentry); 241} 242 243const struct inode_operations erofs_dir_iops = { 244 .lookup = erofs_lookup, 245 .getattr = erofs_getattr, 246#ifdef CONFIG_EROFS_FS_XATTR 247 .listxattr = erofs_listxattr, 248#endif 249 .get_acl = erofs_get_acl, 250}; 251 |