aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@tuxera.com>2010-10-14 09:54:39 -0400
committerChristoph Hellwig <hch@lst.de>2010-10-14 09:54:39 -0400
commit90e616905a423126805186cb5754e10a704b30c8 (patch)
treef3b142b0414462ae9f267689c965d91c784760d4 /fs
parent722c55d13e7296cc62ed8a38f926a915ff32e4ea (diff)
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: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/hfsplus/catalog.c16
-rw-r--r--fs/hfsplus/dir.c6
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/inode.c27
4 files changed, 18 insertions, 32 deletions
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index bbcf5a27b5d3..8af45fc5b051 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -67,7 +67,7 @@ static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent,
67 key->key_len = cpu_to_be16(6 + ustrlen); 67 key->key_len = cpu_to_be16(6 + ustrlen);
68} 68}
69 69
70static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) 70void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms)
71{ 71{
72 if (inode->i_flags & S_IMMUTABLE) 72 if (inode->i_flags & S_IMMUTABLE)
73 perms->rootflags |= HFSPLUS_FLG_IMMUTABLE; 73 perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
@@ -77,10 +77,18 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
77 perms->rootflags |= HFSPLUS_FLG_APPEND; 77 perms->rootflags |= HFSPLUS_FLG_APPEND;
78 else 78 else
79 perms->rootflags &= ~HFSPLUS_FLG_APPEND; 79 perms->rootflags &= ~HFSPLUS_FLG_APPEND;
80 HFSPLUS_I(inode)->userflags = perms->userflags; 80
81 perms->userflags = HFSPLUS_I(inode)->userflags;
81 perms->mode = cpu_to_be16(inode->i_mode); 82 perms->mode = cpu_to_be16(inode->i_mode);
82 perms->owner = cpu_to_be32(inode->i_uid); 83 perms->owner = cpu_to_be32(inode->i_uid);
83 perms->group = cpu_to_be32(inode->i_gid); 84 perms->group = cpu_to_be32(inode->i_gid);
85
86 if (S_ISREG(inode->i_mode))
87 perms->dev = cpu_to_be32(inode->i_nlink);
88 else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
89 perms->dev = cpu_to_be32(inode->i_rdev);
90 else
91 perms->dev = 0;
84} 92}
85 93
86static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode) 94static 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 folder->content_mod_date = 107 folder->content_mod_date =
100 folder->attribute_mod_date = 108 folder->attribute_mod_date =
101 folder->access_date = hfsp_now2mt(); 109 folder->access_date = hfsp_now2mt();
102 hfsplus_set_perms(inode, &folder->permissions); 110 hfsplus_cat_set_perms(inode, &folder->permissions);
103 if (inode == sbi->hidden_dir) 111 if (inode == sbi->hidden_dir)
104 /* invisible and namelocked */ 112 /* invisible and namelocked */
105 folder->user_info.frFlags = cpu_to_be16(0x5000); 113 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 file->attribute_mod_date = 126 file->attribute_mod_date =
119 file->access_date = hfsp_now2mt(); 127 file->access_date = hfsp_now2mt();
120 if (cnid == inode->i_ino) { 128 if (cnid == inode->i_ino) {
121 hfsplus_set_perms(inode, &file->permissions); 129 hfsplus_cat_set_perms(inode, &file->permissions);
122 if (S_ISLNK(inode->i_mode)) { 130 if (S_ISLNK(inode->i_mode)) {
123 file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE); 131 file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE);
124 file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR); 132 file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR);
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index c05c8776e836..d236d85ec9d7 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -418,6 +418,9 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
418 if (!inode) 418 if (!inode)
419 goto out; 419 goto out;
420 420
421 if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode))
422 init_special_inode(inode, mode, rdev);
423
421 res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); 424 res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode);
422 if (res) { 425 if (res) {
423 inode->i_nlink = 0; 426 inode->i_nlink = 0;
@@ -426,9 +429,6 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
426 goto out; 429 goto out;
427 } 430 }
428 431
429 if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode))
430 init_special_inode(inode, mode, rdev);
431
432 hfsplus_instantiate(dentry, inode, inode->i_ino); 432 hfsplus_instantiate(dentry, inode, inode->i_ino);
433 mark_inode_dirty(inode); 433 mark_inode_dirty(inode);
434out: 434out:
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 0d77844a00e8..d77dfd22ea00 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -326,6 +326,7 @@ int hfsplus_create_cat(u32, struct inode *, struct qstr *, struct inode *);
326int hfsplus_delete_cat(u32, struct inode *, struct qstr *); 326int hfsplus_delete_cat(u32, struct inode *, struct qstr *);
327int hfsplus_rename_cat(u32, struct inode *, struct qstr *, 327int hfsplus_rename_cat(u32, struct inode *, struct qstr *,
328 struct inode *, struct qstr *); 328 struct inode *, struct qstr *);
329void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms);
329 330
330/* dir.c */ 331/* dir.c */
331extern const struct inode_operations hfsplus_dir_inode_operations; 332extern const struct inode_operations hfsplus_dir_inode_operations;
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index df57ea1f3a71..78449280dae0 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -252,29 +252,6 @@ static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, i
252 inode->i_flags &= ~S_APPEND; 252 inode->i_flags &= ~S_APPEND;
253} 253}
254 254
255static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
256{
257 if (inode->i_flags & S_IMMUTABLE)
258 perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
259 else
260 perms->rootflags &= ~HFSPLUS_FLG_IMMUTABLE;
261 if (inode->i_flags & S_APPEND)
262 perms->rootflags |= HFSPLUS_FLG_APPEND;
263 else
264 perms->rootflags &= ~HFSPLUS_FLG_APPEND;
265 perms->userflags = HFSPLUS_I(inode)->userflags;
266 perms->mode = cpu_to_be16(inode->i_mode);
267 perms->owner = cpu_to_be32(inode->i_uid);
268 perms->group = cpu_to_be32(inode->i_gid);
269
270 if (S_ISREG(inode->i_mode))
271 perms->dev = cpu_to_be32(inode->i_nlink);
272 else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
273 perms->dev = cpu_to_be32(inode->i_rdev);
274 else
275 perms->dev = 0;
276}
277
278static int hfsplus_file_open(struct inode *inode, struct file *file) 255static int hfsplus_file_open(struct inode *inode, struct file *file)
279{ 256{
280 if (HFSPLUS_IS_RSRC(inode)) 257 if (HFSPLUS_IS_RSRC(inode))
@@ -578,7 +555,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
578 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, 555 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
579 sizeof(struct hfsplus_cat_folder)); 556 sizeof(struct hfsplus_cat_folder));
580 /* simple node checks? */ 557 /* simple node checks? */
581 hfsplus_set_perms(inode, &folder->permissions); 558 hfsplus_cat_set_perms(inode, &folder->permissions);
582 folder->access_date = hfsp_ut2mt(inode->i_atime); 559 folder->access_date = hfsp_ut2mt(inode->i_atime);
583 folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); 560 folder->content_mod_date = hfsp_ut2mt(inode->i_mtime);
584 folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); 561 folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
@@ -600,7 +577,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
600 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, 577 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
601 sizeof(struct hfsplus_cat_file)); 578 sizeof(struct hfsplus_cat_file));
602 hfsplus_inode_write_fork(inode, &file->data_fork); 579 hfsplus_inode_write_fork(inode, &file->data_fork);
603 hfsplus_set_perms(inode, &file->permissions); 580 hfsplus_cat_set_perms(inode, &file->permissions);
604 if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) 581 if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE)
605 file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); 582 file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
606 else 583 else