diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-18 03:03:58 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:52 -0400 |
commit | 8d3af7f333cba7dfc37bad3a8366d50c493201f3 (patch) | |
tree | 3e9c0ab36d2b078364ecec71b538878d4ef583fd /fs/fuse/dir.c | |
parent | 568f8f5ec5f1ac70850e27bc31eacaecaf9fb548 (diff) |
[readdir] convert fuse
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r-- | fs/fuse/dir.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index f3f783dc4f75..0eda52738ec4 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | 16 | ||
17 | static bool fuse_use_readdirplus(struct inode *dir, struct file *filp) | 17 | static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) |
18 | { | 18 | { |
19 | struct fuse_conn *fc = get_fuse_conn(dir); | 19 | struct fuse_conn *fc = get_fuse_conn(dir); |
20 | struct fuse_inode *fi = get_fuse_inode(dir); | 20 | struct fuse_inode *fi = get_fuse_inode(dir); |
@@ -25,7 +25,7 @@ static bool fuse_use_readdirplus(struct inode *dir, struct file *filp) | |||
25 | return true; | 25 | return true; |
26 | if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) | 26 | if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) |
27 | return true; | 27 | return true; |
28 | if (filp->f_pos == 0) | 28 | if (ctx->pos == 0) |
29 | return true; | 29 | return true; |
30 | return false; | 30 | return false; |
31 | } | 31 | } |
@@ -1165,25 +1165,23 @@ static int fuse_permission(struct inode *inode, int mask) | |||
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static int parse_dirfile(char *buf, size_t nbytes, struct file *file, | 1167 | static int parse_dirfile(char *buf, size_t nbytes, struct file *file, |
1168 | void *dstbuf, filldir_t filldir) | 1168 | struct dir_context *ctx) |
1169 | { | 1169 | { |
1170 | while (nbytes >= FUSE_NAME_OFFSET) { | 1170 | while (nbytes >= FUSE_NAME_OFFSET) { |
1171 | struct fuse_dirent *dirent = (struct fuse_dirent *) buf; | 1171 | struct fuse_dirent *dirent = (struct fuse_dirent *) buf; |
1172 | size_t reclen = FUSE_DIRENT_SIZE(dirent); | 1172 | size_t reclen = FUSE_DIRENT_SIZE(dirent); |
1173 | int over; | ||
1174 | if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) | 1173 | if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) |
1175 | return -EIO; | 1174 | return -EIO; |
1176 | if (reclen > nbytes) | 1175 | if (reclen > nbytes) |
1177 | break; | 1176 | break; |
1178 | 1177 | ||
1179 | over = filldir(dstbuf, dirent->name, dirent->namelen, | 1178 | if (!dir_emit(ctx, dirent->name, dirent->namelen, |
1180 | file->f_pos, dirent->ino, dirent->type); | 1179 | dirent->ino, dirent->type)) |
1181 | if (over) | ||
1182 | break; | 1180 | break; |
1183 | 1181 | ||
1184 | buf += reclen; | 1182 | buf += reclen; |
1185 | nbytes -= reclen; | 1183 | nbytes -= reclen; |
1186 | file->f_pos = dirent->off; | 1184 | ctx->pos = dirent->off; |
1187 | } | 1185 | } |
1188 | 1186 | ||
1189 | return 0; | 1187 | return 0; |
@@ -1284,7 +1282,7 @@ out: | |||
1284 | } | 1282 | } |
1285 | 1283 | ||
1286 | static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, | 1284 | static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, |
1287 | void *dstbuf, filldir_t filldir, u64 attr_version) | 1285 | struct dir_context *ctx, u64 attr_version) |
1288 | { | 1286 | { |
1289 | struct fuse_direntplus *direntplus; | 1287 | struct fuse_direntplus *direntplus; |
1290 | struct fuse_dirent *dirent; | 1288 | struct fuse_dirent *dirent; |
@@ -1309,10 +1307,9 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, | |||
1309 | we need to send a FORGET for each of those | 1307 | we need to send a FORGET for each of those |
1310 | which we did not link. | 1308 | which we did not link. |
1311 | */ | 1309 | */ |
1312 | over = filldir(dstbuf, dirent->name, dirent->namelen, | 1310 | over = !dir_emit(ctx, dirent->name, dirent->namelen, |
1313 | file->f_pos, dirent->ino, | 1311 | dirent->ino, dirent->type); |
1314 | dirent->type); | 1312 | ctx->pos = dirent->off; |
1315 | file->f_pos = dirent->off; | ||
1316 | } | 1313 | } |
1317 | 1314 | ||
1318 | buf += reclen; | 1315 | buf += reclen; |
@@ -1326,7 +1323,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, | |||
1326 | return 0; | 1323 | return 0; |
1327 | } | 1324 | } |
1328 | 1325 | ||
1329 | static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | 1326 | static int fuse_readdir(struct file *file, struct dir_context *ctx) |
1330 | { | 1327 | { |
1331 | int plus, err; | 1328 | int plus, err; |
1332 | size_t nbytes; | 1329 | size_t nbytes; |
@@ -1349,17 +1346,17 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
1349 | return -ENOMEM; | 1346 | return -ENOMEM; |
1350 | } | 1347 | } |
1351 | 1348 | ||
1352 | plus = fuse_use_readdirplus(inode, file); | 1349 | plus = fuse_use_readdirplus(inode, ctx); |
1353 | req->out.argpages = 1; | 1350 | req->out.argpages = 1; |
1354 | req->num_pages = 1; | 1351 | req->num_pages = 1; |
1355 | req->pages[0] = page; | 1352 | req->pages[0] = page; |
1356 | req->page_descs[0].length = PAGE_SIZE; | 1353 | req->page_descs[0].length = PAGE_SIZE; |
1357 | if (plus) { | 1354 | if (plus) { |
1358 | attr_version = fuse_get_attr_version(fc); | 1355 | attr_version = fuse_get_attr_version(fc); |
1359 | fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, | 1356 | fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, |
1360 | FUSE_READDIRPLUS); | 1357 | FUSE_READDIRPLUS); |
1361 | } else { | 1358 | } else { |
1362 | fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, | 1359 | fuse_read_fill(req, file, ctx->pos, PAGE_SIZE, |
1363 | FUSE_READDIR); | 1360 | FUSE_READDIR); |
1364 | } | 1361 | } |
1365 | fuse_request_send(fc, req); | 1362 | fuse_request_send(fc, req); |
@@ -1369,11 +1366,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) | |||
1369 | if (!err) { | 1366 | if (!err) { |
1370 | if (plus) { | 1367 | if (plus) { |
1371 | err = parse_dirplusfile(page_address(page), nbytes, | 1368 | err = parse_dirplusfile(page_address(page), nbytes, |
1372 | file, dstbuf, filldir, | 1369 | file, ctx, |
1373 | attr_version); | 1370 | attr_version); |
1374 | } else { | 1371 | } else { |
1375 | err = parse_dirfile(page_address(page), nbytes, file, | 1372 | err = parse_dirfile(page_address(page), nbytes, file, |
1376 | dstbuf, filldir); | 1373 | ctx); |
1377 | } | 1374 | } |
1378 | } | 1375 | } |
1379 | 1376 | ||
@@ -1886,7 +1883,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | |||
1886 | static const struct file_operations fuse_dir_operations = { | 1883 | static const struct file_operations fuse_dir_operations = { |
1887 | .llseek = generic_file_llseek, | 1884 | .llseek = generic_file_llseek, |
1888 | .read = generic_read_dir, | 1885 | .read = generic_read_dir, |
1889 | .readdir = fuse_readdir, | 1886 | .iterate = fuse_readdir, |
1890 | .open = fuse_dir_open, | 1887 | .open = fuse_dir_open, |
1891 | .release = fuse_dir_release, | 1888 | .release = fuse_dir_release, |
1892 | .fsync = fuse_dir_fsync, | 1889 | .fsync = fuse_dir_fsync, |