diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-16 14:14:48 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:35 -0400 |
commit | d81a8ef59802d2d8908466d631573a3644c313d5 (patch) | |
tree | 108b4b58e1c518aaa073e375abcf2bbafb34cbf2 | |
parent | 75811d4fdaad3ac6fd27ec36773541ef6bbc104a (diff) |
[readdir] convert gfs2
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/gfs2/dir.c | 56 | ||||
-rw-r--r-- | fs/gfs2/dir.h | 4 | ||||
-rw-r--r-- | fs/gfs2/export.c | 6 | ||||
-rw-r--r-- | fs/gfs2/file.c | 23 |
4 files changed, 38 insertions, 51 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index b631c9043460..e0449c10286a 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -1212,9 +1212,7 @@ static int compare_dents(const void *a, const void *b) | |||
1212 | /** | 1212 | /** |
1213 | * do_filldir_main - read out directory entries | 1213 | * do_filldir_main - read out directory entries |
1214 | * @dip: The GFS2 inode | 1214 | * @dip: The GFS2 inode |
1215 | * @offset: The offset in the file to read from | 1215 | * @ctx: what to feed the entries to |
1216 | * @opaque: opaque data to pass to filldir | ||
1217 | * @filldir: The function to pass entries to | ||
1218 | * @darr: an array of struct gfs2_dirent pointers to read | 1216 | * @darr: an array of struct gfs2_dirent pointers to read |
1219 | * @entries: the number of entries in darr | 1217 | * @entries: the number of entries in darr |
1220 | * @copied: pointer to int that's non-zero if a entry has been copied out | 1218 | * @copied: pointer to int that's non-zero if a entry has been copied out |
@@ -1224,11 +1222,10 @@ static int compare_dents(const void *a, const void *b) | |||
1224 | * the possibility that they will fall into different readdir buffers or | 1222 | * the possibility that they will fall into different readdir buffers or |
1225 | * that someone will want to seek to that location. | 1223 | * that someone will want to seek to that location. |
1226 | * | 1224 | * |
1227 | * Returns: errno, >0 on exception from filldir | 1225 | * Returns: errno, >0 if the actor tells you to stop |
1228 | */ | 1226 | */ |
1229 | 1227 | ||
1230 | static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | 1228 | static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx, |
1231 | void *opaque, filldir_t filldir, | ||
1232 | const struct gfs2_dirent **darr, u32 entries, | 1229 | const struct gfs2_dirent **darr, u32 entries, |
1233 | int *copied) | 1230 | int *copied) |
1234 | { | 1231 | { |
@@ -1236,7 +1233,6 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1236 | u64 off, off_next; | 1233 | u64 off, off_next; |
1237 | unsigned int x, y; | 1234 | unsigned int x, y; |
1238 | int run = 0; | 1235 | int run = 0; |
1239 | int error = 0; | ||
1240 | 1236 | ||
1241 | sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL); | 1237 | sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL); |
1242 | 1238 | ||
@@ -1253,9 +1249,9 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1253 | off_next = be32_to_cpu(dent_next->de_hash); | 1249 | off_next = be32_to_cpu(dent_next->de_hash); |
1254 | off_next = gfs2_disk_hash2offset(off_next); | 1250 | off_next = gfs2_disk_hash2offset(off_next); |
1255 | 1251 | ||
1256 | if (off < *offset) | 1252 | if (off < ctx->pos) |
1257 | continue; | 1253 | continue; |
1258 | *offset = off; | 1254 | ctx->pos = off; |
1259 | 1255 | ||
1260 | if (off_next == off) { | 1256 | if (off_next == off) { |
1261 | if (*copied && !run) | 1257 | if (*copied && !run) |
@@ -1264,26 +1260,25 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1264 | } else | 1260 | } else |
1265 | run = 0; | 1261 | run = 0; |
1266 | } else { | 1262 | } else { |
1267 | if (off < *offset) | 1263 | if (off < ctx->pos) |
1268 | continue; | 1264 | continue; |
1269 | *offset = off; | 1265 | ctx->pos = off; |
1270 | } | 1266 | } |
1271 | 1267 | ||
1272 | error = filldir(opaque, (const char *)(dent + 1), | 1268 | if (!dir_emit(ctx, (const char *)(dent + 1), |
1273 | be16_to_cpu(dent->de_name_len), | 1269 | be16_to_cpu(dent->de_name_len), |
1274 | off, be64_to_cpu(dent->de_inum.no_addr), | 1270 | be64_to_cpu(dent->de_inum.no_addr), |
1275 | be16_to_cpu(dent->de_type)); | 1271 | be16_to_cpu(dent->de_type))) |
1276 | if (error) | ||
1277 | return 1; | 1272 | return 1; |
1278 | 1273 | ||
1279 | *copied = 1; | 1274 | *copied = 1; |
1280 | } | 1275 | } |
1281 | 1276 | ||
1282 | /* Increment the *offset by one, so the next time we come into the | 1277 | /* Increment the ctx->pos by one, so the next time we come into the |
1283 | do_filldir fxn, we get the next entry instead of the last one in the | 1278 | do_filldir fxn, we get the next entry instead of the last one in the |
1284 | current leaf */ | 1279 | current leaf */ |
1285 | 1280 | ||
1286 | (*offset)++; | 1281 | ctx->pos++; |
1287 | 1282 | ||
1288 | return 0; | 1283 | return 0; |
1289 | } | 1284 | } |
@@ -1307,8 +1302,8 @@ static void gfs2_free_sort_buffer(void *ptr) | |||
1307 | kfree(ptr); | 1302 | kfree(ptr); |
1308 | } | 1303 | } |
1309 | 1304 | ||
1310 | static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | 1305 | static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, |
1311 | filldir_t filldir, int *copied, unsigned *depth, | 1306 | int *copied, unsigned *depth, |
1312 | u64 leaf_no) | 1307 | u64 leaf_no) |
1313 | { | 1308 | { |
1314 | struct gfs2_inode *ip = GFS2_I(inode); | 1309 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -1386,8 +1381,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, | |||
1386 | } while(lfn); | 1381 | } while(lfn); |
1387 | 1382 | ||
1388 | BUG_ON(entries2 != entries); | 1383 | BUG_ON(entries2 != entries); |
1389 | error = do_filldir_main(ip, offset, opaque, filldir, darr, | 1384 | error = do_filldir_main(ip, ctx, darr, entries, copied); |
1390 | entries, copied); | ||
1391 | out_free: | 1385 | out_free: |
1392 | for(i = 0; i < leaf; i++) | 1386 | for(i = 0; i < leaf; i++) |
1393 | brelse(larr[i]); | 1387 | brelse(larr[i]); |
@@ -1446,15 +1440,13 @@ static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index, | |||
1446 | /** | 1440 | /** |
1447 | * dir_e_read - Reads the entries from a directory into a filldir buffer | 1441 | * dir_e_read - Reads the entries from a directory into a filldir buffer |
1448 | * @dip: dinode pointer | 1442 | * @dip: dinode pointer |
1449 | * @offset: the hash of the last entry read shifted to the right once | 1443 | * @ctx: actor to feed the entries to |
1450 | * @opaque: buffer for the filldir function to fill | ||
1451 | * @filldir: points to the filldir function to use | ||
1452 | * | 1444 | * |
1453 | * Returns: errno | 1445 | * Returns: errno |
1454 | */ | 1446 | */ |
1455 | 1447 | ||
1456 | static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | 1448 | static int dir_e_read(struct inode *inode, struct dir_context *ctx, |
1457 | filldir_t filldir, struct file_ra_state *f_ra) | 1449 | struct file_ra_state *f_ra) |
1458 | { | 1450 | { |
1459 | struct gfs2_inode *dip = GFS2_I(inode); | 1451 | struct gfs2_inode *dip = GFS2_I(inode); |
1460 | u32 hsize, len = 0; | 1452 | u32 hsize, len = 0; |
@@ -1465,7 +1457,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1465 | unsigned depth = 0; | 1457 | unsigned depth = 0; |
1466 | 1458 | ||
1467 | hsize = 1 << dip->i_depth; | 1459 | hsize = 1 << dip->i_depth; |
1468 | hash = gfs2_dir_offset2hash(*offset); | 1460 | hash = gfs2_dir_offset2hash(ctx->pos); |
1469 | index = hash >> (32 - dip->i_depth); | 1461 | index = hash >> (32 - dip->i_depth); |
1470 | 1462 | ||
1471 | if (dip->i_hash_cache == NULL) | 1463 | if (dip->i_hash_cache == NULL) |
@@ -1477,7 +1469,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1477 | gfs2_dir_readahead(inode, hsize, index, f_ra); | 1469 | gfs2_dir_readahead(inode, hsize, index, f_ra); |
1478 | 1470 | ||
1479 | while (index < hsize) { | 1471 | while (index < hsize) { |
1480 | error = gfs2_dir_read_leaf(inode, offset, opaque, filldir, | 1472 | error = gfs2_dir_read_leaf(inode, ctx, |
1481 | &copied, &depth, | 1473 | &copied, &depth, |
1482 | be64_to_cpu(lp[index])); | 1474 | be64_to_cpu(lp[index])); |
1483 | if (error) | 1475 | if (error) |
@@ -1492,8 +1484,8 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1492 | return error; | 1484 | return error; |
1493 | } | 1485 | } |
1494 | 1486 | ||
1495 | int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | 1487 | int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, |
1496 | filldir_t filldir, struct file_ra_state *f_ra) | 1488 | struct file_ra_state *f_ra) |
1497 | { | 1489 | { |
1498 | struct gfs2_inode *dip = GFS2_I(inode); | 1490 | struct gfs2_inode *dip = GFS2_I(inode); |
1499 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1491 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -1507,7 +1499,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1507 | return 0; | 1499 | return 0; |
1508 | 1500 | ||
1509 | if (dip->i_diskflags & GFS2_DIF_EXHASH) | 1501 | if (dip->i_diskflags & GFS2_DIF_EXHASH) |
1510 | return dir_e_read(inode, offset, opaque, filldir, f_ra); | 1502 | return dir_e_read(inode, ctx, f_ra); |
1511 | 1503 | ||
1512 | if (!gfs2_is_stuffed(dip)) { | 1504 | if (!gfs2_is_stuffed(dip)) { |
1513 | gfs2_consist_inode(dip); | 1505 | gfs2_consist_inode(dip); |
@@ -1539,7 +1531,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1539 | error = -EIO; | 1531 | error = -EIO; |
1540 | goto out; | 1532 | goto out; |
1541 | } | 1533 | } |
1542 | error = do_filldir_main(dip, offset, opaque, filldir, darr, | 1534 | error = do_filldir_main(dip, ctx, darr, |
1543 | dip->i_entries, &copied); | 1535 | dip->i_entries, &copied); |
1544 | out: | 1536 | out: |
1545 | kfree(darr); | 1537 | kfree(darr); |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 98c960beab35..ba9000bc1397 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -24,8 +24,8 @@ extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename, | |||
24 | extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 24 | extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
25 | const struct gfs2_inode *ip); | 25 | const struct gfs2_inode *ip); |
26 | extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry); | 26 | extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry); |
27 | extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | 27 | extern int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, |
28 | filldir_t filldir, struct file_ra_state *f_ra); | 28 | struct file_ra_state *f_ra); |
29 | extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 29 | extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
30 | const struct gfs2_inode *nip, unsigned int new_type); | 30 | const struct gfs2_inode *nip, unsigned int new_type); |
31 | 31 | ||
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index 9973df4ff565..aed4003486d6 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
@@ -64,6 +64,7 @@ static int gfs2_encode_fh(struct inode *inode, __u32 *p, int *len, | |||
64 | } | 64 | } |
65 | 65 | ||
66 | struct get_name_filldir { | 66 | struct get_name_filldir { |
67 | struct dir_context ctx; | ||
67 | struct gfs2_inum_host inum; | 68 | struct gfs2_inum_host inum; |
68 | char *name; | 69 | char *name; |
69 | }; | 70 | }; |
@@ -90,7 +91,6 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
90 | struct gfs2_inode *dip, *ip; | 91 | struct gfs2_inode *dip, *ip; |
91 | struct get_name_filldir gnfd; | 92 | struct get_name_filldir gnfd; |
92 | struct gfs2_holder gh; | 93 | struct gfs2_holder gh; |
93 | u64 offset = 0; | ||
94 | int error; | 94 | int error; |
95 | struct file_ra_state f_ra = { .start = 0 }; | 95 | struct file_ra_state f_ra = { .start = 0 }; |
96 | 96 | ||
@@ -107,12 +107,14 @@ static int gfs2_get_name(struct dentry *parent, char *name, | |||
107 | gnfd.inum.no_addr = ip->i_no_addr; | 107 | gnfd.inum.no_addr = ip->i_no_addr; |
108 | gnfd.inum.no_formal_ino = ip->i_no_formal_ino; | 108 | gnfd.inum.no_formal_ino = ip->i_no_formal_ino; |
109 | gnfd.name = name; | 109 | gnfd.name = name; |
110 | gnfd.ctx.actor = get_name_filldir; | ||
111 | gnfd.ctx.pos = 0; | ||
110 | 112 | ||
111 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); | 113 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); |
112 | if (error) | 114 | if (error) |
113 | return error; | 115 | return error; |
114 | 116 | ||
115 | error = gfs2_dir_read(dir, &offset, &gnfd, get_name_filldir, &f_ra); | 117 | error = gfs2_dir_read(dir, &gnfd.ctx, &f_ra); |
116 | 118 | ||
117 | gfs2_glock_dq_uninit(&gh); | 119 | gfs2_glock_dq_uninit(&gh); |
118 | 120 | ||
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index ad0dc38d87ab..b3333371aebb 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -82,35 +82,28 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int whence) | |||
82 | } | 82 | } |
83 | 83 | ||
84 | /** | 84 | /** |
85 | * gfs2_readdir - Read directory entries from a directory | 85 | * gfs2_readdir - Iterator for a directory |
86 | * @file: The directory to read from | 86 | * @file: The directory to read from |
87 | * @dirent: Buffer for dirents | 87 | * @ctx: What to feed directory entries to |
88 | * @filldir: Function used to do the copying | ||
89 | * | 88 | * |
90 | * Returns: errno | 89 | * Returns: errno |
91 | */ | 90 | */ |
92 | 91 | ||
93 | static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) | 92 | static int gfs2_readdir(struct file *file, struct dir_context *ctx) |
94 | { | 93 | { |
95 | struct inode *dir = file->f_mapping->host; | 94 | struct inode *dir = file->f_mapping->host; |
96 | struct gfs2_inode *dip = GFS2_I(dir); | 95 | struct gfs2_inode *dip = GFS2_I(dir); |
97 | struct gfs2_holder d_gh; | 96 | struct gfs2_holder d_gh; |
98 | u64 offset = file->f_pos; | ||
99 | int error; | 97 | int error; |
100 | 98 | ||
101 | gfs2_holder_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); | 99 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
102 | error = gfs2_glock_nq(&d_gh); | 100 | if (error) |
103 | if (error) { | ||
104 | gfs2_holder_uninit(&d_gh); | ||
105 | return error; | 101 | return error; |
106 | } | ||
107 | 102 | ||
108 | error = gfs2_dir_read(dir, &offset, dirent, filldir, &file->f_ra); | 103 | error = gfs2_dir_read(dir, ctx, &file->f_ra); |
109 | 104 | ||
110 | gfs2_glock_dq_uninit(&d_gh); | 105 | gfs2_glock_dq_uninit(&d_gh); |
111 | 106 | ||
112 | file->f_pos = offset; | ||
113 | |||
114 | return error; | 107 | return error; |
115 | } | 108 | } |
116 | 109 | ||
@@ -1048,7 +1041,7 @@ const struct file_operations gfs2_file_fops = { | |||
1048 | }; | 1041 | }; |
1049 | 1042 | ||
1050 | const struct file_operations gfs2_dir_fops = { | 1043 | const struct file_operations gfs2_dir_fops = { |
1051 | .readdir = gfs2_readdir, | 1044 | .iterate = gfs2_readdir, |
1052 | .unlocked_ioctl = gfs2_ioctl, | 1045 | .unlocked_ioctl = gfs2_ioctl, |
1053 | .open = gfs2_open, | 1046 | .open = gfs2_open, |
1054 | .release = gfs2_release, | 1047 | .release = gfs2_release, |
@@ -1078,7 +1071,7 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
1078 | }; | 1071 | }; |
1079 | 1072 | ||
1080 | const struct file_operations gfs2_dir_fops_nolock = { | 1073 | const struct file_operations gfs2_dir_fops_nolock = { |
1081 | .readdir = gfs2_readdir, | 1074 | .iterate = gfs2_readdir, |
1082 | .unlocked_ioctl = gfs2_ioctl, | 1075 | .unlocked_ioctl = gfs2_ioctl, |
1083 | .open = gfs2_open, | 1076 | .open = gfs2_open, |
1084 | .release = gfs2_release, | 1077 | .release = gfs2_release, |