aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-18 03:03:58 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:52 -0400
commit8d3af7f333cba7dfc37bad3a8366d50c493201f3 (patch)
tree3e9c0ab36d2b078364ecec71b538878d4ef583fd /fs/fuse/dir.c
parent568f8f5ec5f1ac70850e27bc31eacaecaf9fb548 (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.c37
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
17static bool fuse_use_readdirplus(struct inode *dir, struct file *filp) 17static 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
1167static int parse_dirfile(char *buf, size_t nbytes, struct file *file, 1167static 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
1286static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, 1284static 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
1329static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) 1326static 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 = {
1886static const struct file_operations fuse_dir_operations = { 1883static 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,