diff options
| -rw-r--r-- | fs/gfs2/dir.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 26ca3361a8bc..6b48d7c268b2 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
| @@ -1231,6 +1231,25 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
| 1231 | return 0; | 1231 | return 0; |
| 1232 | } | 1232 | } |
| 1233 | 1233 | ||
| 1234 | static void *gfs2_alloc_sort_buffer(unsigned size) | ||
| 1235 | { | ||
| 1236 | void *ptr = NULL; | ||
| 1237 | |||
| 1238 | if (size < KMALLOC_MAX_SIZE) | ||
| 1239 | ptr = kmalloc(size, GFP_NOFS | __GFP_NOWARN); | ||
| 1240 | if (!ptr) | ||
| 1241 | ptr = __vmalloc(size, GFP_NOFS, PAGE_KERNEL); | ||
| 1242 | return ptr; | ||
| 1243 | } | ||
| 1244 | |||
| 1245 | static void gfs2_free_sort_buffer(void *ptr) | ||
| 1246 | { | ||
| 1247 | if (is_vmalloc_addr(ptr)) | ||
| 1248 | vfree(ptr); | ||
| 1249 | else | ||
| 1250 | kfree(ptr); | ||
| 1251 | } | ||
| 1252 | |||
| 1234 | static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | 1253 | static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, |
| 1235 | filldir_t filldir, int *copied, unsigned *depth, | 1254 | filldir_t filldir, int *copied, unsigned *depth, |
| 1236 | u64 leaf_no) | 1255 | u64 leaf_no) |
| @@ -1271,7 +1290,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
| 1271 | * 99 is the maximum number of entries that can fit in a single | 1290 | * 99 is the maximum number of entries that can fit in a single |
| 1272 | * leaf block. | 1291 | * leaf block. |
| 1273 | */ | 1292 | */ |
| 1274 | larr = vmalloc((leaves + entries + 99) * sizeof(void *)); | 1293 | larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *)); |
| 1275 | if (!larr) | 1294 | if (!larr) |
| 1276 | goto out; | 1295 | goto out; |
| 1277 | darr = (const struct gfs2_dirent **)(larr + leaves); | 1296 | darr = (const struct gfs2_dirent **)(larr + leaves); |
| @@ -1282,7 +1301,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
| 1282 | do { | 1301 | do { |
| 1283 | error = get_leaf(ip, lfn, &bh); | 1302 | error = get_leaf(ip, lfn, &bh); |
| 1284 | if (error) | 1303 | if (error) |
| 1285 | goto out_kfree; | 1304 | goto out_free; |
| 1286 | lf = (struct gfs2_leaf *)bh->b_data; | 1305 | lf = (struct gfs2_leaf *)bh->b_data; |
| 1287 | lfn = be64_to_cpu(lf->lf_next); | 1306 | lfn = be64_to_cpu(lf->lf_next); |
| 1288 | if (lf->lf_entries) { | 1307 | if (lf->lf_entries) { |
| @@ -1291,7 +1310,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
| 1291 | gfs2_dirent_gather, NULL, &g); | 1310 | gfs2_dirent_gather, NULL, &g); |
| 1292 | error = PTR_ERR(dent); | 1311 | error = PTR_ERR(dent); |
| 1293 | if (IS_ERR(dent)) | 1312 | if (IS_ERR(dent)) |
| 1294 | goto out_kfree; | 1313 | goto out_free; |
| 1295 | if (entries2 != g.offset) { | 1314 | if (entries2 != g.offset) { |
| 1296 | fs_warn(sdp, "Number of entries corrupt in dir " | 1315 | fs_warn(sdp, "Number of entries corrupt in dir " |
| 1297 | "leaf %llu, entries2 (%u) != " | 1316 | "leaf %llu, entries2 (%u) != " |
| @@ -1300,7 +1319,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
| 1300 | entries2, g.offset); | 1319 | entries2, g.offset); |
| 1301 | 1320 | ||
| 1302 | error = -EIO; | 1321 | error = -EIO; |
| 1303 | goto out_kfree; | 1322 | goto out_free; |
| 1304 | } | 1323 | } |
| 1305 | error = 0; | 1324 | error = 0; |
| 1306 | larr[leaf++] = bh; | 1325 | larr[leaf++] = bh; |
| @@ -1312,10 +1331,10 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
| 1312 | BUG_ON(entries2 != entries); | 1331 | BUG_ON(entries2 != entries); |
| 1313 | error = do_filldir_main(ip, offset, opaque, filldir, darr, | 1332 | error = do_filldir_main(ip, offset, opaque, filldir, darr, |
| 1314 | entries, copied); | 1333 | entries, copied); |
| 1315 | out_kfree: | 1334 | out_free: |
| 1316 | for(i = 0; i < leaf; i++) | 1335 | for(i = 0; i < leaf; i++) |
| 1317 | brelse(larr[i]); | 1336 | brelse(larr[i]); |
| 1318 | vfree(larr); | 1337 | gfs2_free_sort_buffer(larr); |
| 1319 | out: | 1338 | out: |
| 1320 | return error; | 1339 | return error; |
| 1321 | } | 1340 | } |
