[PATCH] Make most file operations structs in fs/ const
[deliverable/linux.git] / fs / fuse / dir.c
index 9a6075de961fb2eee09d84b7a42d373ebb2a0154..256355b80256f4525272f84788c8561207942389 100644 (file)
@@ -23,8 +23,7 @@
 /*
  * 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);
@@ -112,6 +111,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
 
                /* Doesn't hurt to "reset" the validity timeout */
                fuse_invalidate_entry_cache(entry);
+
+               /* For negative dentries, always do a fresh lookup */
                if (!inode)
                        return 0;
 
@@ -123,6 +124,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
                fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
                request_send(fc, req);
                err = req->out.h.error;
+               /* Zero nodeid is same as -ENOENT */
+               if (!err && !outarg.nodeid)
+                       err = -ENOENT;
                if (!err) {
                        struct fuse_inode *fi = get_fuse_inode(inode);
                        if (outarg.nodeid != get_node_id(inode)) {
@@ -157,7 +161,7 @@ static int dir_alias(struct inode *inode)
        return 0;
 }
 
-static inline int invalid_nodeid(u64 nodeid)
+static int invalid_nodeid(u64 nodeid)
 {
        return !nodeid || nodeid == FUSE_ROOT_ID;
 }
@@ -166,6 +170,12 @@ static struct dentry_operations fuse_dentry_operations = {
        .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)
 {
@@ -185,7 +195,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
        fuse_lookup_init(req, dir, entry, &outarg);
        request_send(fc, req);
        err = req->out.h.error;
-       if (!err && outarg.nodeid && invalid_nodeid(outarg.nodeid))
+       /* Zero nodeid is same as -ENOENT, but with valid timeout */
+       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,
@@ -236,10 +248,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        if (fc->no_create)
                goto out;
 
-       err = -ENAMETOOLONG;
-       if (entry->d_name.len > FUSE_NAME_MAX)
-               goto out;
-
        err = -EINTR;
        req = fuse_get_request(fc);
        if (!req)
@@ -332,10 +340,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                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) {
@@ -344,8 +355,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        }
        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;
        }
@@ -354,6 +364,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        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,
@@ -413,12 +427,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
 {
        struct fuse_conn *fc = get_fuse_conn(dir);
        unsigned len = strlen(link) + 1;
-       struct fuse_req *req;
-
-       if (len > FUSE_SYMLINK_MAX)
-               return -ENAMETOOLONG;
-
-       req = fuse_get_request(fc);
+       struct fuse_req *req = fuse_get_request(fc);
        if (!req)
                return -EINTR;
 
@@ -759,13 +768,6 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
        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;
@@ -789,7 +791,9 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
        }
        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)
@@ -988,9 +992,6 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
        struct fuse_setxattr_in inarg;
        int err;
 
-       if (size > FUSE_XATTR_SIZE_MAX)
-               return -E2BIG;
-
        if (fc->no_setxattr)
                return -EOPNOTSUPP;
 
@@ -1169,7 +1170,7 @@ static struct inode_operations fuse_dir_inode_operations = {
        .removexattr    = fuse_removexattr,
 };
 
-static struct file_operations fuse_dir_operations = {
+static const struct file_operations fuse_dir_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
        .readdir        = fuse_readdir,
This page took 0.027639 seconds and 5 git commands to generate.