aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/dir.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index a71df0206f6f..5b1274699b08 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1225,6 +1225,12 @@ static int fuse_direntplus_link(struct file *file,
1225 if (name.name[1] == '.' && name.len == 2) 1225 if (name.name[1] == '.' && name.len == 2)
1226 return 0; 1226 return 0;
1227 } 1227 }
1228
1229 if (invalid_nodeid(o->nodeid))
1230 return -EIO;
1231 if (!fuse_valid_type(o->attr.mode))
1232 return -EIO;
1233
1228 fc = get_fuse_conn(dir); 1234 fc = get_fuse_conn(dir);
1229 1235
1230 name.hash = full_name_hash(name.name, name.len); 1236 name.hash = full_name_hash(name.name, name.len);
@@ -1233,10 +1239,14 @@ static int fuse_direntplus_link(struct file *file,
1233 inode = dentry->d_inode; 1239 inode = dentry->d_inode;
1234 if (!inode) { 1240 if (!inode) {
1235 d_drop(dentry); 1241 d_drop(dentry);
1236 } else if (get_node_id(inode) != o->nodeid) { 1242 } else if (get_node_id(inode) != o->nodeid ||
1243 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
1237 err = d_invalidate(dentry); 1244 err = d_invalidate(dentry);
1238 if (err) 1245 if (err)
1239 goto out; 1246 goto out;
1247 } else if (is_bad_inode(inode)) {
1248 err = -EIO;
1249 goto out;
1240 } else { 1250 } else {
1241 struct fuse_inode *fi; 1251 struct fuse_inode *fi;
1242 fi = get_fuse_inode(inode); 1252 fi = get_fuse_inode(inode);