dir.c (c2132c1bc73d9a279cec148f74ea709c960b3d89) dir.c (4582a4ab2a0e7218449fb2e895d0aae9ea753c94)
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/file.h>
13#include <linux/sched.h>
14#include <linux/namei.h>
15#include <linux/slab.h>
16
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/file.h>
13#include <linux/sched.h>
14#include <linux/namei.h>
15#include <linux/slab.h>
16
17static bool fuse_use_readdirplus(struct inode *dir, struct file *filp)
18{
19 struct fuse_conn *fc = get_fuse_conn(dir);
20 struct fuse_inode *fi = get_fuse_inode(dir);
21
22 if (!fc->do_readdirplus)
23 return false;
24 if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
25 return true;
26 if (filp->f_pos == 0)
27 return true;
28 return false;
29}
30
31static void fuse_advise_use_readdirplus(struct inode *dir)
32{
33 struct fuse_inode *fi = get_fuse_inode(dir);
34
35 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
36}
37
17#if BITS_PER_LONG >= 64
18static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
19{
20 entry->d_time = time;
21}
22
23static inline u64 fuse_dentry_time(struct dentry *entry)
24{

--- 189 unchanged lines hidden (view full) ---

214 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
215 return 0;
216
217 fuse_change_attributes(inode, &outarg.attr,
218 entry_attr_timeout(&outarg),
219 attr_version);
220 fuse_change_entry_timeout(entry, &outarg);
221 }
38#if BITS_PER_LONG >= 64
39static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
40{
41 entry->d_time = time;
42}
43
44static inline u64 fuse_dentry_time(struct dentry *entry)
45{

--- 189 unchanged lines hidden (view full) ---

235 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
236 return 0;
237
238 fuse_change_attributes(inode, &outarg.attr,
239 entry_attr_timeout(&outarg),
240 attr_version);
241 fuse_change_entry_timeout(entry, &outarg);
242 }
243 fuse_advise_use_readdirplus(inode);
222 return 1;
223}
224
225static int invalid_nodeid(u64 nodeid)
226{
227 return !nodeid || nodeid == FUSE_ROOT_ID;
228}
229

--- 120 unchanged lines hidden (view full) ---

350 }
351
352 entry = newent ? newent : entry;
353 if (outarg_valid)
354 fuse_change_entry_timeout(entry, &outarg);
355 else
356 fuse_invalidate_entry_cache(entry);
357
244 return 1;
245}
246
247static int invalid_nodeid(u64 nodeid)
248{
249 return !nodeid || nodeid == FUSE_ROOT_ID;
250}
251

--- 120 unchanged lines hidden (view full) ---

372 }
373
374 entry = newent ? newent : entry;
375 if (outarg_valid)
376 fuse_change_entry_timeout(entry, &outarg);
377 else
378 fuse_invalidate_entry_cache(entry);
379
380 fuse_advise_use_readdirplus(dir);
358 return newent;
359
360 out_iput:
361 iput(inode);
362 out_err:
363 return ERR_PTR(err);
364}
365

--- 919 unchanged lines hidden (view full) ---

1285 fuse_force_forget(file, direntplus->entry_out.nodeid);
1286 }
1287
1288 return 0;
1289}
1290
1291static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
1292{
381 return newent;
382
383 out_iput:
384 iput(inode);
385 out_err:
386 return ERR_PTR(err);
387}
388

--- 919 unchanged lines hidden (view full) ---

1308 fuse_force_forget(file, direntplus->entry_out.nodeid);
1309 }
1310
1311 return 0;
1312}
1313
1314static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
1315{
1293 int err;
1316 int plus, err;
1294 size_t nbytes;
1295 struct page *page;
1296 struct inode *inode = file->f_path.dentry->d_inode;
1297 struct fuse_conn *fc = get_fuse_conn(inode);
1298 struct fuse_req *req;
1299 u64 attr_version = 0;
1300
1301 if (is_bad_inode(inode))
1302 return -EIO;
1303
1304 req = fuse_get_req(fc, 1);
1305 if (IS_ERR(req))
1306 return PTR_ERR(req);
1307
1308 page = alloc_page(GFP_KERNEL);
1309 if (!page) {
1310 fuse_put_request(fc, req);
1311 return -ENOMEM;
1312 }
1317 size_t nbytes;
1318 struct page *page;
1319 struct inode *inode = file->f_path.dentry->d_inode;
1320 struct fuse_conn *fc = get_fuse_conn(inode);
1321 struct fuse_req *req;
1322 u64 attr_version = 0;
1323
1324 if (is_bad_inode(inode))
1325 return -EIO;
1326
1327 req = fuse_get_req(fc, 1);
1328 if (IS_ERR(req))
1329 return PTR_ERR(req);
1330
1331 page = alloc_page(GFP_KERNEL);
1332 if (!page) {
1333 fuse_put_request(fc, req);
1334 return -ENOMEM;
1335 }
1336
1337 plus = fuse_use_readdirplus(inode, file);
1313 req->out.argpages = 1;
1314 req->num_pages = 1;
1315 req->pages[0] = page;
1316 req->page_descs[0].length = PAGE_SIZE;
1338 req->out.argpages = 1;
1339 req->num_pages = 1;
1340 req->pages[0] = page;
1341 req->page_descs[0].length = PAGE_SIZE;
1317 if (fc->do_readdirplus) {
1342 if (plus) {
1318 attr_version = fuse_get_attr_version(fc);
1319 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
1320 FUSE_READDIRPLUS);
1321 } else {
1322 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
1323 FUSE_READDIR);
1324 }
1325 fuse_request_send(fc, req);
1326 nbytes = req->out.args[0].size;
1327 err = req->out.h.error;
1328 fuse_put_request(fc, req);
1329 if (!err) {
1343 attr_version = fuse_get_attr_version(fc);
1344 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
1345 FUSE_READDIRPLUS);
1346 } else {
1347 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
1348 FUSE_READDIR);
1349 }
1350 fuse_request_send(fc, req);
1351 nbytes = req->out.args[0].size;
1352 err = req->out.h.error;
1353 fuse_put_request(fc, req);
1354 if (!err) {
1330 if (fc->do_readdirplus) {
1355 if (plus) {
1331 err = parse_dirplusfile(page_address(page), nbytes,
1332 file, dstbuf, filldir,
1333 attr_version);
1334 } else {
1335 err = parse_dirfile(page_address(page), nbytes, file,
1336 dstbuf, filldir);
1337 }
1338 }

--- 554 unchanged lines hidden ---
1356 err = parse_dirplusfile(page_address(page), nbytes,
1357 file, dstbuf, filldir,
1358 attr_version);
1359 } else {
1360 err = parse_dirfile(page_address(page), nbytes, file,
1361 dstbuf, filldir);
1362 }
1363 }

--- 554 unchanged lines hidden ---