From: Christoph Hellwig <hch@lst.de>
To: viro@zeniv.linux.org.uk, zippel@linux-m68k.org
Cc: linux-fsdevel@vger.kernel.org
Subject: [PATCH 9/14] hfsplus: add per-superblock lock for volume header updates
Date: Fri, 1 Oct 2010 09:26:55 +0200 [thread overview]
Message-ID: <20101001072655.GI27055@lst.de> (raw)
In-Reply-To: <20101001072500.GA26972@lst.de>
Lock updates to the mutal fields in the volume header, and document the
locing in the hfsplus_sb_info structure.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Index: linux-2.6/fs/hfsplus/hfsplus_fs.h
===================================================================
--- linux-2.6.orig/fs/hfsplus/hfsplus_fs.h 2010-09-30 12:07:34.800782662 +0200
+++ linux-2.6/fs/hfsplus/hfsplus_fs.h 2010-09-30 12:07:35.632782662 +0200
@@ -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;
Index: linux-2.6/fs/hfsplus/dir.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/dir.c 2010-09-30 12:07:30.825782662 +0200
+++ linux-2.6/fs/hfsplus/dir.c 2010-09-30 12:07:35.634782662 +0200
@@ -251,6 +251,7 @@ static int hfsplus_link(struct dentry *s
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));
@@ -263,7 +264,7 @@ static int hfsplus_link(struct dentry *s
if (!res)
break;
if (res != -EEXIST)
- return res;
+ goto out;
}
HFSPLUS_I(inode)->dev = id;
cnid = sbi->next_cnid++;
@@ -271,13 +272,13 @@ static int hfsplus_link(struct dentry *s
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);
@@ -286,8 +287,9 @@ static int hfsplus_link(struct dentry *s
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)
@@ -302,6 +304,7 @@ static int hfsplus_unlink(struct inode *
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)) {
@@ -312,11 +315,11 @@ static int hfsplus_unlink(struct inode *
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);
@@ -339,37 +342,44 @@ static int hfsplus_unlink(struct inode *
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)
@@ -381,31 +391,35 @@ static int hfsplus_symlink(struct inode
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))
@@ -413,7 +427,9 @@ static int hfsplus_mknod(struct inode *d
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,
Index: linux-2.6/fs/hfsplus/super.c
===================================================================
--- linux-2.6.orig/fs/hfsplus/super.c 2010-09-30 12:07:34.803782662 +0200
+++ linux-2.6/fs/hfsplus/super.c 2010-09-30 12:07:35.639782662 +0200
@@ -160,6 +160,7 @@ int hfsplus_sync_fs(struct super_block *
dprint(DBG_SUPER, "hfsplus_write_super\n");
+ mutex_lock(&sbi->vh_mutex);
mutex_lock(&sbi->alloc_mutex);
sb->s_dirt = 0;
@@ -194,6 +195,7 @@ int hfsplus_sync_fs(struct super_block *
sbi->flags &= ~HFSPLUS_SB_WRITEBACKUP;
}
mutex_unlock(&sbi->alloc_mutex);
+ mutex_unlock(&sbi->vh_mutex);
return 0;
}
@@ -319,6 +321,7 @@ static int hfsplus_fill_super(struct sup
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");
@@ -453,9 +456,13 @@ static int hfsplus_fill_super(struct sup
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:
next prev parent reply other threads:[~2010-10-01 7:27 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-01 7:25 [PATCH 0/14] more hfsplus updates Christoph Hellwig
2010-10-01 7:25 ` [PATCH 1/14] hfsplus: fix HFSPLUS_SB calling convention Christoph Hellwig
2010-10-01 7:25 ` [PATCH 2/14] hfsplus: fix HFSPLUS_I " Christoph Hellwig
2010-10-01 7:25 ` [PATCH 3/14] hfsplus: clean up hfsplus_iget Christoph Hellwig
2010-10-01 7:26 ` [PATCH 4/14] hfsplus: clean up hfsplus_write_inode Christoph Hellwig
2010-10-01 7:26 ` [PATCH 5/14] hfsplus: merge mknod/mkdir/creat Christoph Hellwig
2010-10-01 7:26 ` [PATCH 6/14] hfsplus: fix error handling in hfsplus_symlink Christoph Hellwig
2010-10-01 7:26 ` [PATCH 7/14] hfsplus: do not cache and write next_alloc Christoph Hellwig
2010-10-01 7:26 ` [PATCH 8/14] hfsplus: remove the rsrc_inodes list Christoph Hellwig
2010-10-01 7:26 ` Christoph Hellwig [this message]
2010-10-01 7:27 ` [PATCH 10/14] hfsplus: use atomic bitops for the superblock flags Christoph Hellwig
2010-10-01 7:27 ` [PATCH 11/14] hfsplus: protect readdir against removals from open_dir_list Christoph Hellwig
2010-10-01 7:27 ` [PATCH 12/14] hfsplus: add missing extent locking in hfsplus_write_inode Christoph Hellwig
2010-10-01 7:27 ` [PATCH 13/14] hfsplus: convert tree_lock to mutex Christoph Hellwig
2010-10-01 7:28 ` [PATCH 14/14] hfsplus: fix rename over directories Christoph Hellwig
2010-10-01 14:06 ` [PATCH 0/14] more hfsplus updates Christoph Hellwig
2010-10-01 14:16 ` Christoph Hellwig
2010-10-02 4:09 ` Stephen Rothwell
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=20101001072655.GI27055@lst.de \
--to=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=zippel@linux-m68k.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.