From: Christoph Hellwig <hch@lst.de>
To: linux-fsdevel@vger.kernel.org
Subject: hfsplus: create correct initial catalog entries for device files
Date: Tue, 12 Oct 2010 15:58:32 +0200 [thread overview]
Message-ID: <20101012135832.GH26867@lst.de> (raw)
In-Reply-To: <20101012135634.GA26867@lst.de>
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>
Index: linux-2.6/fs/hfsplus/catalog.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/catalog.c 2010-10-11 20:02:16.780274444 +0200
+++ linux-2.6/fs/hfsplus/catalog.c 2010-10-11 20:02:40.577253560 +0200
@@ -67,7 +67,7 @@ static void hfsplus_cat_build_key_uni(hf
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)
perms->rootflags |= HFSPLUS_FLG_IMMUTABLE;
@@ -77,10 +77,18 @@ static void hfsplus_set_perms(struct ino
perms->rootflags |= HFSPLUS_FLG_APPEND;
else
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->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_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode)
@@ -99,7 +107,7 @@ static int hfsplus_cat_build_record(hfsp
folder->content_mod_date =
folder->attribute_mod_date =
folder->access_date = hfsp_now2mt();
- hfsplus_set_perms(inode, &folder->permissions);
+ hfsplus_cat_set_perms(inode, &folder->permissions);
if (inode == sbi->hidden_dir)
/* invisible and namelocked */
folder->user_info.frFlags = cpu_to_be16(0x5000);
@@ -118,7 +126,7 @@ static int hfsplus_cat_build_record(hfsp
file->attribute_mod_date =
file->access_date = hfsp_now2mt();
if (cnid == inode->i_ino) {
- hfsplus_set_perms(inode, &file->permissions);
+ hfsplus_cat_set_perms(inode, &file->permissions);
if (S_ISLNK(inode->i_mode)) {
file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE);
file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR);
Index: linux-2.6/fs/hfsplus/dir.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/dir.c 2010-10-11 20:01:06.023253839 +0200
+++ linux-2.6/fs/hfsplus/dir.c 2010-10-11 20:02:40.578254049 +0200
@@ -418,6 +418,9 @@ static int hfsplus_mknod(struct inode *d
if (!inode)
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);
if (res) {
inode->i_nlink = 0;
@@ -426,9 +429,6 @@ static int hfsplus_mknod(struct inode *d
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);
mark_inode_dirty(inode);
out:
Index: linux-2.6/fs/hfsplus/hfsplus_fs.h
===================================================================
--- linux-2.6.orig/fs/hfsplus/hfsplus_fs.h 2010-10-11 20:02:16.780274444 +0200
+++ linux-2.6/fs/hfsplus/hfsplus_fs.h 2010-10-11 20:02:40.584331783 +0200
@@ -326,6 +326,7 @@ int hfsplus_create_cat(u32, struct inode
int hfsplus_delete_cat(u32, struct inode *, struct qstr *);
int hfsplus_rename_cat(u32, struct inode *, struct qstr *,
struct inode *, struct qstr *);
+void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms);
/* dir.c */
extern const struct inode_operations hfsplus_dir_inode_operations;
Index: linux-2.6/fs/hfsplus/inode.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/inode.c 2010-10-11 20:02:16.786004155 +0200
+++ linux-2.6/fs/hfsplus/inode.c 2010-10-11 20:02:40.590255236 +0200
@@ -252,29 +252,6 @@ static void hfsplus_get_perms(struct ino
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)
{
if (HFSPLUS_IS_RSRC(inode))
@@ -578,7 +555,7 @@ int hfsplus_cat_write_inode(struct inode
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_folder));
/* 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->content_mod_date = hfsp_ut2mt(inode->i_mtime);
folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime);
@@ -600,7 +577,7 @@ int hfsplus_cat_write_inode(struct inode
hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file));
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)
file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED);
else
next prev parent reply other threads:[~2010-10-12 13:58 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-12 13:56 hfsplus updates Christoph Hellwig
2010-10-12 13:56 ` hfsplus: fix oops on mount with corrupted btree extent records Christoph Hellwig
2010-10-12 13:57 ` hfs_bnode_find() can fail, resulting in hfs_bnode_split() breakage Christoph Hellwig
2010-10-12 13:57 ` hfsplus: handle more on-disk corruptions without oopsing Christoph Hellwig
2010-10-12 13:57 ` hfsplus: validate btree flags Christoph Hellwig
2010-10-12 13:58 ` hfsplus: fix link corruption Christoph Hellwig
2010-10-12 13:58 ` hfsplus: remove superflous rootflags field in hfsplus_inode_info Christoph Hellwig
2010-10-12 13:58 ` Christoph Hellwig [this message]
2010-10-12 13:58 ` hfsplus: remove the unused hfsplus_kmap/hfsplus_kunmap helpers Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101012135832.GH26867@lst.de \
--to=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.