Loading fs/hfsplus/dir.c +35 −19 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (HFSPLUS_IS_RSRC(inode)) return -EPERM; mutex_lock(&sbi->vh_mutex); if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) { for (;;) { get_random_bytes(&id, sizeof(cnid)); Loading @@ -263,7 +264,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (!res) break; if (res != -EEXIST) return res; goto out; } HFSPLUS_I(inode)->dev = id; cnid = sbi->next_cnid++; Loading @@ -271,13 +272,13 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode); if (res) /* panic? */ return res; goto out; sbi->file_count++; } cnid = sbi->next_cnid++; res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode); if (res) return res; goto out; inc_nlink(inode); hfsplus_instantiate(dst_dentry, inode, cnid); Loading @@ -286,8 +287,9 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, mark_inode_dirty(inode); sbi->file_count++; dst_dir->i_sb->s_dirt = 1; return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) Loading @@ -302,6 +304,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) if (HFSPLUS_IS_RSRC(inode)) return -EPERM; mutex_lock(&sbi->vh_mutex); cnid = (u32)(unsigned long)dentry->d_fsdata; if (inode->i_ino == cnid && atomic_read(&HFSPLUS_I(inode)->opencnt)) { Loading @@ -312,11 +315,11 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) sbi->hidden_dir, &str); if (!res) inode->i_flags |= S_DEAD; return res; goto out; } res = hfsplus_delete_cat(cnid, dir, &dentry->d_name); if (res) return res; goto out; if (inode->i_nlink > 0) drop_nlink(inode); Loading @@ -339,37 +342,44 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) sbi->file_count--; inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) { struct inode *inode; struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode = dentry->d_inode; int res; inode = dentry->d_inode; if (inode->i_size != 2) return -ENOTEMPTY; mutex_lock(&sbi->vh_mutex); res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); if (res) return res; goto out; clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfsplus_delete_inode(inode); mark_inode_dirty(inode); return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; int res; int res = -ENOSPC; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); if (!inode) return -ENOSPC; goto out; res = page_symlink(inode, symname, strlen(symname) + 1); if (res) Loading @@ -381,31 +391,35 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; goto out; out_err: inode->i_nlink = 0; hfsplus_delete_inode(inode); iput(inode); out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; int res; int res = -ENOSPC; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, mode); if (!inode) return -ENOSPC; goto out; res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (res) { inode->i_nlink = 0; hfsplus_delete_inode(inode); iput(inode); return res; goto out; } if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) Loading @@ -413,7 +427,9 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_create(struct inode *dir, struct dentry *dentry, int mode, Loading fs/hfsplus/hfsplus_fs.h +8 −5 Original line number Diff line number Diff line Loading @@ -116,23 +116,26 @@ struct hfsplus_sb_info { struct inode *hidden_dir; struct nls_table *nls; /* synchronize block allocations */ struct mutex alloc_mutex; /* Runtime variables */ u32 blockoffset; u32 sect_count; int fs_shift; /* Stuff in host order from Vol Header */ /* immutable data from the volume header */ u32 alloc_blksz; int alloc_blksz_shift; u32 total_blocks; u32 data_clump_blocks, rsrc_clump_blocks; /* mutable data from the volume header, protected by alloc_mutex */ u32 free_blocks; struct mutex alloc_mutex; /* mutable data from the volume header, protected by vh_mutex */ u32 next_cnid; u32 file_count; u32 folder_count; u32 data_clump_blocks, rsrc_clump_blocks; struct mutex vh_mutex; /* Config options */ u32 creator; Loading fs/hfsplus/super.c +7 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) dprint(DBG_SUPER, "hfsplus_write_super\n"); mutex_lock(&sbi->vh_mutex); mutex_lock(&sbi->alloc_mutex); sb->s_dirt = 0; Loading Loading @@ -194,6 +195,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) sbi->flags &= ~HFSPLUS_SB_WRITEBACKUP; } mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->vh_mutex); return 0; } Loading Loading @@ -319,6 +321,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; mutex_init(&sbi->alloc_mutex); mutex_init(&sbi->vh_mutex); hfsplus_fill_defaults(sbi); if (!hfsplus_parse_options(data, sbi)) { printk(KERN_ERR "hfs: unable to parse mount options\n"); Loading Loading @@ -453,9 +456,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) if (!sbi->hidden_dir) { printk(KERN_DEBUG "hfs: create hidden dir...\n"); mutex_lock(&sbi->vh_mutex); sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode, &str, sbi->hidden_dir); mutex_unlock(&sbi->vh_mutex); mark_inode_dirty(sbi->hidden_dir); } out: Loading Loading
fs/hfsplus/dir.c +35 −19 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (HFSPLUS_IS_RSRC(inode)) return -EPERM; mutex_lock(&sbi->vh_mutex); if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) { for (;;) { get_random_bytes(&id, sizeof(cnid)); Loading @@ -263,7 +264,7 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, if (!res) break; if (res != -EEXIST) return res; goto out; } HFSPLUS_I(inode)->dev = id; cnid = sbi->next_cnid++; Loading @@ -271,13 +272,13 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, res = hfsplus_create_cat(cnid, src_dir, &src_dentry->d_name, inode); if (res) /* panic? */ return res; goto out; sbi->file_count++; } cnid = sbi->next_cnid++; res = hfsplus_create_cat(cnid, dst_dir, &dst_dentry->d_name, inode); if (res) return res; goto out; inc_nlink(inode); hfsplus_instantiate(dst_dentry, inode, cnid); Loading @@ -286,8 +287,9 @@ static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir, mark_inode_dirty(inode); sbi->file_count++; dst_dir->i_sb->s_dirt = 1; return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) Loading @@ -302,6 +304,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) if (HFSPLUS_IS_RSRC(inode)) return -EPERM; mutex_lock(&sbi->vh_mutex); cnid = (u32)(unsigned long)dentry->d_fsdata; if (inode->i_ino == cnid && atomic_read(&HFSPLUS_I(inode)->opencnt)) { Loading @@ -312,11 +315,11 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) sbi->hidden_dir, &str); if (!res) inode->i_flags |= S_DEAD; return res; goto out; } res = hfsplus_delete_cat(cnid, dir, &dentry->d_name); if (res) return res; goto out; if (inode->i_nlink > 0) drop_nlink(inode); Loading @@ -339,37 +342,44 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) sbi->file_count--; inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry) { struct inode *inode; struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode = dentry->d_inode; int res; inode = dentry->d_inode; if (inode->i_size != 2) return -ENOTEMPTY; mutex_lock(&sbi->vh_mutex); res = hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); if (res) return res; goto out; clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; hfsplus_delete_inode(inode); mark_inode_dirty(inode); return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; int res; int res = -ENOSPC; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO); if (!inode) return -ENOSPC; goto out; res = page_symlink(inode, symname, strlen(symname) + 1); if (res) Loading @@ -381,31 +391,35 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry, hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; goto out; out_err: inode->i_nlink = 0; hfsplus_delete_inode(inode); iput(inode); out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); struct inode *inode; int res; int res = -ENOSPC; mutex_lock(&sbi->vh_mutex); inode = hfsplus_new_inode(dir->i_sb, mode); if (!inode) return -ENOSPC; goto out; res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); if (res) { inode->i_nlink = 0; hfsplus_delete_inode(inode); iput(inode); return res; goto out; } if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) Loading @@ -413,7 +427,9 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, hfsplus_instantiate(dentry, inode, inode->i_ino); mark_inode_dirty(inode); return 0; out: mutex_unlock(&sbi->vh_mutex); return res; } static int hfsplus_create(struct inode *dir, struct dentry *dentry, int mode, Loading
fs/hfsplus/hfsplus_fs.h +8 −5 Original line number Diff line number Diff line Loading @@ -116,23 +116,26 @@ struct hfsplus_sb_info { struct inode *hidden_dir; struct nls_table *nls; /* synchronize block allocations */ struct mutex alloc_mutex; /* Runtime variables */ u32 blockoffset; u32 sect_count; int fs_shift; /* Stuff in host order from Vol Header */ /* immutable data from the volume header */ u32 alloc_blksz; int alloc_blksz_shift; u32 total_blocks; u32 data_clump_blocks, rsrc_clump_blocks; /* mutable data from the volume header, protected by alloc_mutex */ u32 free_blocks; struct mutex alloc_mutex; /* mutable data from the volume header, protected by vh_mutex */ u32 next_cnid; u32 file_count; u32 folder_count; u32 data_clump_blocks, rsrc_clump_blocks; struct mutex vh_mutex; /* Config options */ u32 creator; Loading
fs/hfsplus/super.c +7 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) dprint(DBG_SUPER, "hfsplus_write_super\n"); mutex_lock(&sbi->vh_mutex); mutex_lock(&sbi->alloc_mutex); sb->s_dirt = 0; Loading Loading @@ -194,6 +195,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait) sbi->flags &= ~HFSPLUS_SB_WRITEBACKUP; } mutex_unlock(&sbi->alloc_mutex); mutex_unlock(&sbi->vh_mutex); return 0; } Loading Loading @@ -319,6 +321,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) sb->s_fs_info = sbi; mutex_init(&sbi->alloc_mutex); mutex_init(&sbi->vh_mutex); hfsplus_fill_defaults(sbi); if (!hfsplus_parse_options(data, sbi)) { printk(KERN_ERR "hfs: unable to parse mount options\n"); Loading Loading @@ -453,9 +456,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) if (!sbi->hidden_dir) { printk(KERN_DEBUG "hfs: create hidden dir...\n"); mutex_lock(&sbi->vh_mutex); sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR); hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode, &str, sbi->hidden_dir); mutex_unlock(&sbi->vh_mutex); mark_inode_dirty(sbi->hidden_dir); } out: Loading