fix
authorMiklos Szeredi <miklos@szeredi.hu>
Wed, 7 Dec 2005 12:57:59 +0000 (12:57 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Wed, 7 Dec 2005 12:57:59 +0000 (12:57 +0000)
ChangeLog
kernel/dir.c
kernel/file.c

index 637ca23f2a44ca047b78f53c7b145d6815678182..86a4365d9f5b0e33d401bb4269a80a23a6a3fb7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-12-07  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Return EIO for file operations (read, write, fsync, flush) on
+       open files whose inode has become "bad".  Inodes will be marked
+       "bad" if their type changes.  Bug report by Csaba Henk
+
 2005-12-06  Miklos Szeredi <miklos@szeredi.hu>
 
        * Use bigger request buffer size.  write() did not work on archs
index 3258d42c977fad0a12d1a8006e9ef5461213992f..8c161b6a133768951f8bdb31ae2494e476c7196a 100644 (file)
@@ -837,7 +837,12 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
        struct page *page;
        struct inode *inode = file->f_dentry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_request(fc);
+       struct fuse_req *req;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
+       req = fuse_get_request(fc);
        if (!req)
                return -EINTR;
 
index 2365d2e1604b964593f09c2b80adb24b7b6865fa..0a625a23602c2616cb7fc997693f1f5dcdb6538a 100644 (file)
@@ -177,6 +177,9 @@ static int fuse_flush(struct file *file)
        struct fuse_flush_in inarg;
        int err;
 
+       if (is_bad_inode(inode))
+               return -EIO;
+
        if (fc->no_flush)
                return 0;
 
@@ -213,6 +216,9 @@ int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
        struct fuse_fsync_in inarg;
        int err;
 
+       if (is_bad_inode(inode))
+               return -EIO;
+
        if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
                return 0;
 
@@ -286,8 +292,15 @@ static int fuse_readpage(struct file *file, struct page *page)
 {
        struct inode *inode = page->mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_request(fc);
-       int err = -EINTR;
+       struct fuse_req *req;
+       int err;
+
+       err = -EIO;
+       if (is_bad_inode(inode))
+               goto out;
+
+       err = -EINTR;
+       req = fuse_get_request(fc);
        if (!req)
                goto out;
 
@@ -359,6 +372,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_readpages_data data;
        int err;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
        data.file = file;
        data.inode = inode;
        data.req = fuse_get_request(fc);
@@ -518,6 +535,9 @@ static int fuse_commit_write(struct file *file, struct page *page,
        loff_t pos = page_offset(page) + offset;
        struct fuse_req *req;
 
+       if (is_bad_inode(inode))
+               return -EIO;
+
        if (count > fc->max_write)
                return -EIO;
 
@@ -593,7 +613,12 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
        size_t nmax = write ? fc->max_write : fc->max_read;
        loff_t pos = *ppos;
        ssize_t res = 0;
-       struct fuse_req *req = fuse_get_request(fc);
+       struct fuse_req *req;
+
+       if (is_bad_inode(inode))
+               return -EIO;
+
+       req = fuse_get_request(fc);
        if (!req)
                return -EINTR;
 
@@ -666,6 +691,9 @@ static ssize_t fuse_file_read(struct file *file, char __user *buf,
        struct inode *inode = file->f_dentry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
 
+       if (is_bad_inode(file))
+               return -EIO;
+
        if (fc->flags & FUSE_LARGE_READ) {
                int res;
                down(&inode->i_sem);