summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-16 14:14:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:35 -0400
commitd81a8ef59802d2d8908466d631573a3644c313d5 (patch)
tree108b4b58e1c518aaa073e375abcf2bbafb34cbf2
parent75811d4fdaad3ac6fd27ec36773541ef6bbc104a (diff)
[readdir] convert gfs2
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/gfs2/dir.c56
-rw-r--r--fs/gfs2/dir.h4
-rw-r--r--fs/gfs2/export.c6
-rw-r--r--fs/gfs2/file.c23
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
1230static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, 1228static 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
1310static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque, 1305static 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);
1391out_free: 1385out_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
1456static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, 1448static 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
1495int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, 1487int 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);
1544out: 1536out:
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,
24extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename, 24extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
25 const struct gfs2_inode *ip); 25 const struct gfs2_inode *ip);
26extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry); 26extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
27extern int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, 27extern 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);
29extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 29extern 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
66struct get_name_filldir { 66struct 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
93static int gfs2_readdir(struct file *file, void *dirent, filldir_t filldir) 92static 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
1050const struct file_operations gfs2_dir_fops = { 1043const 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
1080const struct file_operations gfs2_dir_fops_nolock = { 1073const 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,