-2004-11-10 Miklos Szeredi <miklos@szeredi.hu>
+2004-11-11 Miklos Szeredi <miklos@szeredi.hu>
* Check kernel interface version in fusermount to prevent
strangeness in case of mismatch.
+ * Fix potential race between umount and fuse_invalidate
+
+ * Check superblock of proc file in addition to inode number
+
2004-11-10 Miklos Szeredi <miklos@szeredi.hu>
* Released 2.1-pre0
switch (uh.opcode) {
case FUSE_INVALIDATE:
- err = fuse_invalidate(fc, &uh);
+ down(&fc->sb_sem);
+ err = -ENODEV;
+ if (fc->sb)
+ err = fuse_invalidate(fc, &uh);
+ up(&fc->sb_sem);
break;
default:
INIT_LIST_HEAD(&fc->processing);
INIT_LIST_HEAD(&fc->unused_list);
sema_init(&fc->unused_sem, MAX_OUTSTANDING);
+ sema_init(&fc->sb_sem, 1);
for (i = 0; i < MAX_OUTSTANDING; i++) {
struct fuse_req *req = fuse_request_alloc();
if (!req) {
/** Controls the maximum number of outstanding requests */
struct semaphore unused_sem;
+ /** Semaphore protecting the super block from going away */
+ struct semaphore sb_sem;
+
/** The list of unused requests */
struct list_head unused_list;
{
struct fuse_conn *fc = SB_FC(sb);
+ down(&fc->sb_sem);
spin_lock(&fuse_lock);
fc->sb = NULL;
+ up(&fc->sb_sem);
fc->uid = 0;
fc->flags = 0;
/* Flush all readers on this fs */
struct inode *ino;
ino = file->f_dentry->d_inode;
- if (!ino || !proc_fuse_dev || proc_fuse_dev->low_ino != ino->i_ino) {
+ if (!ino || !proc_fuse_dev || proc_mnt->mnt_sb != ino->i_sb ||
+ proc_fuse_dev->low_ino != ino->i_ino) {
printk("FUSE: bad communication file descriptor\n");
return NULL;
}
return 0;
err:
+ down(&fc->sb_sem);
spin_lock(&fuse_lock);
fc->sb = NULL;
+ up(&fc->sb_sem);
fuse_release_conn(fc);
spin_unlock(&fuse_lock);
SB_FC(sb) = NULL;