/*
* Calculate the time in jiffies until a dentry/attributes are valid
*/
-static inline unsigned long time_to_jiffies(unsigned long sec,
- unsigned long nsec)
+static unsigned long time_to_jiffies(unsigned long sec, unsigned long nsec)
{
struct timespec ts = {sec, nsec};
return jiffies + timespec_to_jiffies(&ts);
return 0;
}
-static inline int invalid_nodeid(u64 nodeid)
+static int invalid_nodeid(u64 nodeid)
{
return !nodeid || nodeid == FUSE_ROOT_ID;
}
.d_revalidate = fuse_dentry_revalidate,
};
+static int valid_mode(int m)
+{
+ return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
+ S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
+}
+
static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
struct nameidata *nd)
{
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
- if (!err && outarg.nodeid && invalid_nodeid(outarg.nodeid))
+ if (!err && ((outarg.nodeid && invalid_nodeid(outarg.nodeid)) ||
+ !valid_mode(outarg.attr.mode)))
err = -EIO;
if (!err && outarg.nodeid) {
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
fuse_put_request(fc, req);
return err;
}
- if (invalid_nodeid(outarg.nodeid)) {
- fuse_put_request(fc, req);
- return -EIO;
- }
+ err = -EIO;
+ if (invalid_nodeid(outarg.nodeid))
+ goto out_put_request;
+
+ if ((outarg.attr.mode ^ mode) & S_IFMT)
+ goto out_put_request;
+
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr);
if (!inode) {
}
fuse_put_request(fc, req);
- /* Don't allow userspace to do really stupid things... */
- if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
+ if (dir_alias(inode)) {
iput(inode);
return -EIO;
}
fuse_change_timeout(entry, &outarg);
fuse_invalidate_attr(dir);
return 0;
+
+ out_put_request:
+ fuse_put_request(fc, req);
+ return err;
}
static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
return 0;
}
-static inline size_t fuse_send_readdir(struct fuse_req *req, struct file *file,
- struct inode *inode, loff_t pos,
- size_t count)
-{
- return fuse_send_read_common(req, file, inode, pos, count, 1);
-}
-
static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
{
int err;
}
req->num_pages = 1;
req->pages[0] = page;
- nbytes = fuse_send_readdir(req, file, inode, file->f_pos, PAGE_SIZE);
+ fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
+ request_send(fc, req);
+ nbytes = req->out.args[0].size;
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err)