diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ecryptfs/inode.c | 4 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 3 | ||||
-rw-r--r-- | fs/hugetlbfs/inode.c | 15 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 2 | ||||
-rw-r--r-- | fs/nfs/super.c | 110 | ||||
-rw-r--r-- | fs/udf/balloc.c | 10 | ||||
-rw-r--r-- | fs/udf/super.c | 26 |
7 files changed, 103 insertions, 67 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5d40ad1..131954b 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -357,10 +357,6 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); goto out; } - if (special_file(lower_inode->i_mode)) { - ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); - goto out; - } if (!nd) { ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" "as we *think* we are about to unlink\n"); diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index e4ab7bc..fd3f94d 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -834,7 +834,8 @@ static void ecryptfs_sync_page(struct page *page) ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n"); return; } - lower_page->mapping->a_ops->sync_page(lower_page); + if (lower_page->mapping->a_ops->sync_page) + lower_page->mapping->a_ops->sync_page(lower_page); ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", lower_page->index); unlock_page(lower_page); diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index c848a19..950c2fb 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -82,14 +82,19 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) int ret; /* - * vma alignment has already been checked by prepare_hugepage_range. - * If you add any error returns here, do so after setting VM_HUGETLB, - * so is_vm_hugetlb_page tests below unmap_region go the right way - * when do_mmap_pgoff unwinds (may be important on powerpc and ia64). + * vma address alignment (but not the pgoff alignment) has + * already been checked by prepare_hugepage_range. If you add + * any error returns here, do so after setting VM_HUGETLB, so + * is_vm_hugetlb_page tests below unmap_region go the right + * way when do_mmap_pgoff unwinds (may be important on powerpc + * and ia64). */ vma->vm_flags |= VM_HUGETLB | VM_RESERVED; vma->vm_ops = &hugetlb_vm_ops; + if (vma->vm_pgoff & ~(HPAGE_MASK >> PAGE_SHIFT)) + return -EINVAL; + vma_len = (loff_t)(vma->vm_end - vma->vm_start); mutex_lock(&inode->i_mutex); @@ -132,7 +137,7 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, return -ENOMEM; if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) + if (prepare_hugepage_range(addr, len)) return -EINVAL; return addr; } diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 1d3b7a9..8bc727b 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -627,7 +627,7 @@ unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, struct inode *inode = OFNI_EDONI_2SFFJ(f); struct page *pg; - pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, + pg = read_cache_page_async(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode); if (IS_ERR(pg)) return (void *)pg; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index b2a851c..4613900 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1303,34 +1303,6 @@ static void nfs_clone_super(struct super_block *sb, nfs_initialise_sb(sb); } -static int nfs_set_super(struct super_block *s, void *_server) -{ - struct nfs_server *server = _server; - int ret; - - s->s_fs_info = server; - ret = set_anon_super(s, server); - if (ret == 0) - server->s_dev = s->s_dev; - return ret; -} - -static int nfs_compare_super(struct super_block *sb, void *data) -{ - struct nfs_server *server = data, *old = NFS_SB(sb); - - if (memcmp(&old->nfs_client->cl_addr, - &server->nfs_client->cl_addr, - sizeof(old->nfs_client->cl_addr)) != 0) - return 0; - /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */ - if (old->flags & NFS_MOUNT_UNSHARED) - return 0; - if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) - return 0; - return 1; -} - #define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS) static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags) @@ -1359,9 +1331,46 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n goto Ebusy; if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor) goto Ebusy; - return 0; + return 1; Ebusy: - return -EBUSY; + return 0; +} + +struct nfs_sb_mountdata { + struct nfs_server *server; + int mntflags; +}; + +static int nfs_set_super(struct super_block *s, void *data) +{ + struct nfs_sb_mountdata *sb_mntdata = data; + struct nfs_server *server = sb_mntdata->server; + int ret; + + s->s_flags = sb_mntdata->mntflags; + s->s_fs_info = server; + ret = set_anon_super(s, server); + if (ret == 0) + server->s_dev = s->s_dev; + return ret; +} + +static int nfs_compare_super(struct super_block *sb, void *data) +{ + struct nfs_sb_mountdata *sb_mntdata = data; + struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb); + int mntflags = sb_mntdata->mntflags; + + if (memcmp(&old->nfs_client->cl_addr, + &server->nfs_client->cl_addr, + sizeof(old->nfs_client->cl_addr)) != 0) + return 0; + /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */ + if (old->flags & NFS_MOUNT_UNSHARED) + return 0; + if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0) + return 0; + return nfs_compare_mount_options(sb, server, mntflags); } static int nfs_get_sb(struct file_system_type *fs_type, @@ -1373,6 +1382,9 @@ static int nfs_get_sb(struct file_system_type *fs_type, struct nfs_mount_data *data = raw_data; struct dentry *mntroot; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; /* Validate the mount data */ @@ -1386,28 +1398,25 @@ static int nfs_get_sb(struct file_system_type *fs_type, error = PTR_ERR(server); goto out; } + sb_mntdata.server = server; if (server->flags & NFS_MOUNT_UNSHARED) compare_super = NULL; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(fs_type, compare_super, nfs_set_super, server); + s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; } if (s->s_fs_info != server) { - error = nfs_compare_mount_options(s, server, flags); nfs_free_server(server); server = NULL; - if (error < 0) - goto error_splat_super; } if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs_fill_super(s, data); } @@ -1460,6 +1469,9 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, struct nfs_server *server; struct dentry *mntroot; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs_xdev_get_sb()\n"); @@ -1470,28 +1482,25 @@ static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; if (server->flags & NFS_MOUNT_UNSHARED) compare_super = NULL; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; } if (s->s_fs_info != server) { - error = nfs_compare_mount_options(s, server, flags); nfs_free_server(server); server = NULL; - if (error < 0) - goto error_splat_super; } if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs_clone_super(s, data->sb); } @@ -1729,6 +1738,9 @@ static int nfs4_get_sb(struct file_system_type *fs_type, struct dentry *mntroot; char *mntpath = NULL, *hostname = NULL, *ip_addr = NULL; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; /* Validate the mount data */ @@ -1744,12 +1756,13 @@ static int nfs4_get_sb(struct file_system_type *fs_type, error = PTR_ERR(server); goto out; } + sb_mntdata.server = server; if (server->flags & NFS4_MOUNT_UNSHARED) compare_super = NULL; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(fs_type, compare_super, nfs_set_super, server); + s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_free; @@ -1762,7 +1775,6 @@ static int nfs4_get_sb(struct file_system_type *fs_type, if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_fill_super(s); } @@ -1816,6 +1828,9 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, struct nfs_server *server; struct dentry *mntroot; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs4_xdev_get_sb()\n"); @@ -1826,12 +1841,13 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; if (server->flags & NFS4_MOUNT_UNSHARED) compare_super = NULL; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -1844,7 +1860,6 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags, if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_clone_super(s, data->sb); } @@ -1887,6 +1902,9 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, struct dentry *mntroot; struct nfs_fh mntfh; int (*compare_super)(struct super_block *, void *) = nfs_compare_super; + struct nfs_sb_mountdata sb_mntdata = { + .mntflags = flags, + }; int error; dprintk("--> nfs4_referral_get_sb()\n"); @@ -1897,12 +1915,13 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, error = PTR_ERR(server); goto out_err_noserver; } + sb_mntdata.server = server; if (server->flags & NFS4_MOUNT_UNSHARED) compare_super = NULL; /* Get a superblock - note that we may end up sharing one that already exists */ - s = sget(&nfs_fs_type, compare_super, nfs_set_super, server); + s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata); if (IS_ERR(s)) { error = PTR_ERR(s); goto out_err_nosb; @@ -1915,7 +1934,6 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags, if (!s->s_root) { /* initial superblock/root creation */ - s->s_flags = flags; nfs4_fill_super(s); } diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 276f720..87e87dc 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -540,26 +540,24 @@ static void udf_table_free_blocks(struct super_block *sb, if (epos.offset + adsize > sb->s_blocksize) { loffset = epos.offset; aed->lengthAllocDescs = cpu_to_le32(adsize); - sptr = UDF_I_DATA(inode) + epos.offset - - udf_file_entry_alloc_offset(inode) + - UDF_I_LENEATTR(inode) - adsize; + sptr = UDF_I_DATA(table) + epos.offset - adsize; dptr = epos.bh->b_data + sizeof(struct allocExtDesc); memcpy(dptr, sptr, adsize); epos.offset = sizeof(struct allocExtDesc) + adsize; } else { loffset = epos.offset + adsize; aed->lengthAllocDescs = cpu_to_le32(0); - sptr = oepos.bh->b_data + epos.offset; - epos.offset = sizeof(struct allocExtDesc); - if (oepos.bh) { + sptr = oepos.bh->b_data + epos.offset; aed = (struct allocExtDesc *)oepos.bh->b_data; aed->lengthAllocDescs = cpu_to_le32(le32_to_cpu(aed->lengthAllocDescs) + adsize); } else { + sptr = UDF_I_DATA(table) + epos.offset; UDF_I_LENALLOC(table) += adsize; mark_inode_dirty(table); } + epos.offset = sizeof(struct allocExtDesc); } if (UDF_SB_UDFREV(sb) >= 0x0200) udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, diff --git a/fs/udf/super.c b/fs/udf/super.c index 382be7b..c68a6e7 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -89,7 +89,7 @@ static int udf_find_fileset(struct super_block *, kernel_lb_addr *, static void udf_load_pvoldesc(struct super_block *, struct buffer_head *); static void udf_load_fileset(struct super_block *, struct buffer_head *, kernel_lb_addr *); -static void udf_load_partdesc(struct super_block *, struct buffer_head *); +static int udf_load_partdesc(struct super_block *, struct buffer_head *); static void udf_open_lvid(struct super_block *); static void udf_close_lvid(struct super_block *); static unsigned int udf_count_free(struct super_block *); @@ -877,7 +877,7 @@ static void udf_load_fileset(struct super_block *sb, struct buffer_head *bh, root->logicalBlockNum, root->partitionReferenceNum); } -static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) +static int udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) { struct partitionDesc *p; int i; @@ -912,6 +912,11 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table = udf_iget(sb, loc); + if (!UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table) { + udf_debug("cannot load unallocSpaceTable (part %d)\n", + i); + return 1; + } UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_UNALLOC_TABLE; udf_debug("unallocSpaceTable (part %d) @ %ld\n", i, UDF_SB_PARTMAPS(sb)[i].s_uspace.s_table->i_ino); @@ -938,6 +943,11 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table = udf_iget(sb, loc); + if (!UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table) { + udf_debug("cannot load freedSpaceTable (part %d)\n", + i); + return 1; + } UDF_SB_PARTFLAGS(sb,i) |= UDF_PART_FLAG_FREED_TABLE; udf_debug("freedSpaceTable (part %d) @ %ld\n", i, UDF_SB_PARTMAPS(sb)[i].s_fspace.s_table->i_ino); @@ -966,6 +976,7 @@ static void udf_load_partdesc(struct super_block *sb, struct buffer_head *bh) le16_to_cpu(p->partitionNumber), i, UDF_SB_PARTTYPE(sb,i), UDF_SB_PARTROOT(sb,i), UDF_SB_PARTLEN(sb,i)); } + return 0; } static int udf_load_logicalvol(struct super_block *sb, struct buffer_head *bh, @@ -1177,12 +1188,19 @@ static int udf_process_sequence(struct super_block *sb, long block, long lastblo udf_load_logicalvol(sb, bh, fileset); } else if (i == VDS_POS_PARTITION_DESC) { struct buffer_head *bh2 = NULL; - udf_load_partdesc(sb, bh); + if (udf_load_partdesc(sb, bh)) { + brelse(bh); + return 1; + } for (j = vds[i].block + 1; j < vds[VDS_POS_TERMINATING_DESC].block; j++) { bh2 = udf_read_tagged(sb, j, j, &ident); gd = (struct generic_desc *)bh2->b_data; if (ident == TAG_IDENT_PD) - udf_load_partdesc(sb, bh2); + if (udf_load_partdesc(sb, bh2)) { + brelse(bh); + brelse(bh2); + return 1; + } brelse(bh2); } } |