提交 90e61690 编写于 作者: C Christoph Hellwig 提交者: Christoph Hellwig

hfsplus: create correct initial catalog entries for device files

Make sure the initial insertation of the catalog entry already contains
the device number by calling init_special_inode early and setting writing
out the dev field of the on-disk permission structure.  The latter is
facilitated by sharing the almost identical hfsplus_set_perms helpers
between initial catalog entry creating and ->write_inode.

Unless we crashed just after mknod this bug was harmless as the inode
is marked dirty at the end of hfsplus_mknod, and hfsplus_write_inode
will update the catalog entry to contain the correct value.
Signed-off-by: NChristoph Hellwig <hch@tuxera.com>
上级 722c55d1
...@@ -67,7 +67,7 @@ static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent, ...@@ -67,7 +67,7 @@ static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent,
key->key_len = cpu_to_be16(6 + ustrlen); key->key_len = cpu_to_be16(6 + ustrlen);
} }
static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms)
{ {
if (inode->i_flags & S_IMMUTABLE) if (inode->i_flags & S_IMMUTABLE)
perms->rootflags |= HFSPLUS_FLG_IMMUTABLE; perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
...@@ -77,10 +77,18 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) ...@@ -77,10 +77,18 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
perms->rootflags |= HFSPLUS_FLG_APPEND; perms->rootflags |= HFSPLUS_FLG_APPEND;
else else
perms->rootflags &= ~HFSPLUS_FLG_APPEND; perms->rootflags &= ~HFSPLUS_FLG_APPEND;
HFSPLUS_I(inode)->userflags = perms->userflags;
perms->userflags = HFSPLUS_I(inode)->userflags;
perms->mode = cpu_to_be16(inode->i_mode); perms->mode = cpu_to_be16(inode->i_mode);
perms->owner = cpu_to_be32(inode->i_uid); perms->owner = cpu_to_be32(inode->i_uid);
perms->group = cpu_to_be32(inode->i_gid); perms->group = cpu_to_be32(inode->i_gid);
if (S_ISREG(inode->i_mode))
perms->dev = cpu_to_be32(inode->i_nlink);
else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
perms->dev = cpu_to_be32(inode->i_rdev);
else
perms->dev = 0;
} }
static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode) static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode)
...@@ -99,7 +107,7 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i ...@@ -99,7 +107,7 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i
folder->content_mod_date = folder->content_mod_date =
folder->attribute_mod_date = folder->attribute_mod_date =
folder->access_date = hfsp_now2mt(); folder->access_date = hfsp_now2mt();
hfsplus_set_perms(inode, &folder->permissions); hfsplus_cat_set_perms(inode, &folder->permissions);
if (inode == sbi->hidden_dir) if (inode == sbi->hidden_dir)
/* invisible and namelocked */ /* invisible and namelocked */
folder->user_info.frFlags = cpu_to_be16(0x5000); folder->user_info.frFlags = cpu_to_be16(0x5000);
...@@ -118,7 +126,7 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i ...@@ -118,7 +126,7 @@ static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct i
file->attribute_mod_date = file->attribute_mod_date =
file->access_date = hfsp_now2mt(); file->access_date = hfsp_now2mt();
if (cnid == inode->i_ino) { if (cnid == inode->i_ino) {
hfsplus_set_perms(inode, &file->permissions); hfsplus_cat_set_perms(inode, &file->permissions);
if (S_ISLNK(inode->i_mode)) { if (S_ISLNK(inode->i_mode)) {
file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE); file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE);
file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR); file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR);
......
...@@ -418,6 +418,9 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, ...@@ -418,6 +418,9 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
if (!inode) if (!inode)
goto out; goto out;
if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode))
init_special_inode(inode, mode, rdev);
res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
if (res) { if (res) {
inode->i_nlink = 0; inode->i_nlink = 0;
...@@ -426,9 +429,6 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry, ...@@ -426,9 +429,6 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
goto out; goto out;
} }
if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode))
init_special_inode(inode, mode, rdev);
hfsplus_instantiate(dentry, inode, inode->i_ino); hfsplus_instantiate(dentry, inode, inode->i_ino);
mark_inode_dirty(inode); mark_inode_dirty(inode);
out: out:
......
...@@ -326,6 +326,7 @@ int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *); ...@@ -326,6 +326,7 @@ int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
int hfsplus_delete_cat(u32, struct inode *, struct qstr *); int hfsplus_delete_cat(u32, struct inode *, struct qstr *);
int hfsplus_rename_cat(u32, struct inode *, struct qstr *, int hfsplus_rename_cat(u32, struct inode *, struct qstr *,
struct inode *, struct qstr *); struct inode *, struct qstr *);
void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms);
/* dir.c */ /* dir.c */
extern const struct inode_operations hfsplus_dir_inode_operations; extern const struct inode_operations hfsplus_dir_inode_operations;
......
...@@ -252,29 +252,6 @@ static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, i ...@@ -252,29 +252,6 @@ static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, i
inode->i_flags &= ~S_APPEND; inode->i_flags &= ~S_APPEND;
} }
static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
{
if (inode->i_flags & S_IMMUTABLE)
perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
else
perms->rootflags &= ~HFSPLUS_FLG_IMMUTABLE;
if (inode->i_flags & S_APPEND)
perms->rootflags |= HFSPLUS_FLG_APPEND;
else
perms->rootflags &= ~HFSPLUS_FLG_APPEND;
perms->userflags = HFSPLUS_I(inode)->userflags;
perms->mode = cpu_to_be16(inode->i_mode);
perms->owner = cpu_to_be32(inode->i_uid);
perms->group = cpu_to_be32(inode->i_gid);
if (S_ISREG(inode->i_mode))
perms->dev = cpu_to_be32(inode->i_nlink);
else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
perms->dev = cpu_to_be32(inode->i_rdev);
else
perms->dev = 0;
}
static int hfsplus_file_open(struct inode *inode, struct file *file) static int hfsplus_file_open(struct inode *inode, struct file *file)
{ {
if (HFSPLUS_IS_RSRC(inode)) if (HFSPLUS_IS_RSRC(inode))
...@@ -578,7 +555,7 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -578,7 +555,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_folder)); sizeof(struct hfsplus_cat_folder));
/* simple node checks? */ /* simple node checks? */
hfsplus_set_perms(inode, &folder->permissions); hfsplus_cat_set_perms(inode, &folder->permissions);
folder->access_date = hfsp_ut2mt(inode->i_atime); folder->access_date = hfsp_ut2mt(inode->i_atime);
folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); folder->content_mod_date = hfsp_ut2mt(inode->i_mtime);
folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
...@@ -600,7 +577,7 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -600,7 +577,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file)); sizeof(struct hfsplus_cat_file));
hfsplus_inode_write_fork(inode, &file->data_fork); hfsplus_inode_write_fork(inode, &file->data_fork);
hfsplus_set_perms(inode, &file->permissions); hfsplus_cat_set_perms(inode, &file->permissions);
if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE)
file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
else else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册