aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@tuxera.com>2010-09-30 23:45:20 -0400
committerChristoph Hellwig <hch@lst.de>2010-09-30 23:45:20 -0400
commit84adede31267af37141da2b2b04293c5ea8af7ae (patch)
tree41c1a3e28fab11baca330232bacbff3085afde82 /fs/hfsplus
parent7ac9fb9c2a50963b699b3548e6f00698c1554dc6 (diff)
hfsplus: use atomic bitops for the superblock flags
The flags in the HFS+-specific superlock do get modified during runtime, use atomic bitops to make the modifications SMP safe. Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs/hfsplus')
-rw-r--r--fs/hfsplus/btree.c4
-rw-r--r--fs/hfsplus/hfsplus_fs.h10
-rw-r--r--fs/hfsplus/options.c8
-rw-r--r--fs/hfsplus/super.c10
-rw-r--r--fs/hfsplus/unicode.c12
-rw-r--r--fs/hfsplus/wrapper.c14
6 files changed, 30 insertions, 28 deletions
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index f75cf222b8b4..27504f57a485 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -61,12 +61,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
61 if (id == HFSPLUS_EXT_CNID) { 61 if (id == HFSPLUS_EXT_CNID) {
62 tree->keycmp = hfsplus_ext_cmp_key; 62 tree->keycmp = hfsplus_ext_cmp_key;
63 } else if (id == HFSPLUS_CAT_CNID) { 63 } else if (id == HFSPLUS_CAT_CNID) {
64 if ((HFSPLUS_SB(sb)->flags & HFSPLUS_SB_HFSX) && 64 if (test_bit(HFSPLUS_SB_HFSX, &HFSPLUS_SB(sb)->flags) &&
65 (head->key_type == HFSPLUS_KEY_BINARY)) 65 (head->key_type == HFSPLUS_KEY_BINARY))
66 tree->keycmp = hfsplus_cat_bin_cmp_key; 66 tree->keycmp = hfsplus_cat_bin_cmp_key;
67 else { 67 else {
68 tree->keycmp = hfsplus_cat_case_cmp_key; 68 tree->keycmp = hfsplus_cat_case_cmp_key;
69 HFSPLUS_SB(sb)->flags |= HFSPLUS_SB_CASEFOLD; 69 set_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
70 } 70 }
71 } else { 71 } else {
72 printk(KERN_ERR "hfs: unknown B*Tree requested\n"); 72 printk(KERN_ERR "hfs: unknown B*Tree requested\n");
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 08865ed70f00..c521d44f0747 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -150,11 +150,11 @@ struct hfsplus_sb_info {
150 unsigned long flags; 150 unsigned long flags;
151}; 151};
152 152
153#define HFSPLUS_SB_WRITEBACKUP 0x0001 153#define HFSPLUS_SB_WRITEBACKUP 0
154#define HFSPLUS_SB_NODECOMPOSE 0x0002 154#define HFSPLUS_SB_NODECOMPOSE 1
155#define HFSPLUS_SB_FORCE 0x0004 155#define HFSPLUS_SB_FORCE 2
156#define HFSPLUS_SB_HFSX 0x0008 156#define HFSPLUS_SB_HFSX 3
157#define HFSPLUS_SB_CASEFOLD 0x0010 157#define HFSPLUS_SB_CASEFOLD 4
158 158
159 159
160struct hfsplus_inode_info { 160struct hfsplus_inode_info {
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index f2598aef206e..f9ab276a4d8d 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -143,13 +143,13 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
143 kfree(p); 143 kfree(p);
144 break; 144 break;
145 case opt_decompose: 145 case opt_decompose:
146 sbi->flags &= ~HFSPLUS_SB_NODECOMPOSE; 146 clear_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
147 break; 147 break;
148 case opt_nodecompose: 148 case opt_nodecompose:
149 sbi->flags |= HFSPLUS_SB_NODECOMPOSE; 149 set_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags);
150 break; 150 break;
151 case opt_force: 151 case opt_force:
152 sbi->flags |= HFSPLUS_SB_FORCE; 152 set_bit(HFSPLUS_SB_FORCE, &sbi->flags);
153 break; 153 break;
154 default: 154 default:
155 return 0; 155 return 0;
@@ -184,7 +184,7 @@ int hfsplus_show_options(struct seq_file *seq, struct vfsmount *mnt)
184 seq_printf(seq, ",session=%u", sbi->session); 184 seq_printf(seq, ",session=%u", sbi->session);
185 if (sbi->nls) 185 if (sbi->nls)
186 seq_printf(seq, ",nls=%s", sbi->nls->charset); 186 seq_printf(seq, ",nls=%s", sbi->nls->charset);
187 if (sbi->flags & HFSPLUS_SB_NODECOMPOSE) 187 if (test_bit(HFSPLUS_SB_NODECOMPOSE, &sbi->flags))
188 seq_printf(seq, ",nodecompose"); 188 seq_printf(seq, ",nodecompose");
189 return 0; 189 return 0;
190} 190}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index b766c170e4d8..9a88d7536103 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -119,7 +119,7 @@ static int hfsplus_system_write_inode(struct inode *inode)
119 } 119 }
120 120
121 if (fork->total_size != cpu_to_be64(inode->i_size)) { 121 if (fork->total_size != cpu_to_be64(inode->i_size)) {
122 sbi->flags |= HFSPLUS_SB_WRITEBACKUP; 122 set_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags);
123 inode->i_sb->s_dirt = 1; 123 inode->i_sb->s_dirt = 1;
124 } 124 }
125 hfsplus_inode_write_fork(inode, fork); 125 hfsplus_inode_write_fork(inode, fork);
@@ -170,7 +170,7 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
170 vhdr->file_count = cpu_to_be32(sbi->file_count); 170 vhdr->file_count = cpu_to_be32(sbi->file_count);
171 171
172 mark_buffer_dirty(sbi->s_vhbh); 172 mark_buffer_dirty(sbi->s_vhbh);
173 if (sbi->flags & HFSPLUS_SB_WRITEBACKUP) { 173 if (test_and_clear_bit(HFSPLUS_SB_WRITEBACKUP, &sbi->flags)) {
174 if (sbi->sect_count) { 174 if (sbi->sect_count) {
175 struct buffer_head *bh; 175 struct buffer_head *bh;
176 u32 block, offset; 176 u32 block, offset;
@@ -192,7 +192,6 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
192 printk(KERN_WARNING "hfs: backup not found!\n"); 192 printk(KERN_WARNING "hfs: backup not found!\n");
193 } 193 }
194 } 194 }
195 sbi->flags &= ~HFSPLUS_SB_WRITEBACKUP;
196 } 195 }
197 mutex_unlock(&sbi->alloc_mutex); 196 mutex_unlock(&sbi->alloc_mutex);
198 mutex_unlock(&sbi->vh_mutex); 197 mutex_unlock(&sbi->vh_mutex);
@@ -276,7 +275,7 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
276 "running fsck.hfsplus is recommended. leaving read-only.\n"); 275 "running fsck.hfsplus is recommended. leaving read-only.\n");
277 sb->s_flags |= MS_RDONLY; 276 sb->s_flags |= MS_RDONLY;
278 *flags |= MS_RDONLY; 277 *flags |= MS_RDONLY;
279 } else if (sbi.flags & HFSPLUS_SB_FORCE) { 278 } else if (test_bit(HFSPLUS_SB_FORCE, &sbi.flags)) {
280 /* nothing */ 279 /* nothing */
281 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { 280 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
282 printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n"); 281 printk(KERN_WARNING "hfs: filesystem is marked locked, leaving read-only.\n");
@@ -376,7 +375,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
376 printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, " 375 printk(KERN_WARNING "hfs: Filesystem was not cleanly unmounted, "
377 "running fsck.hfsplus is recommended. mounting read-only.\n"); 376 "running fsck.hfsplus is recommended. mounting read-only.\n");
378 sb->s_flags |= MS_RDONLY; 377 sb->s_flags |= MS_RDONLY;
379 } else if (sbi->flags & HFSPLUS_SB_FORCE) { 378 } else if (test_and_clear_bit(HFSPLUS_SB_FORCE, &sbi->flags)) {
380 /* nothing */ 379 /* nothing */
381 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { 380 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
382 printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n"); 381 printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n");
@@ -386,7 +385,6 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
386 "use the force option at your own risk, mounting read-only.\n"); 385 "use the force option at your own risk, mounting read-only.\n");
387 sb->s_flags |= MS_RDONLY; 386 sb->s_flags |= MS_RDONLY;
388 } 387 }
389 sbi->flags &= ~HFSPLUS_SB_FORCE;
390 388
391 /* Load metadata objects (B*Trees) */ 389 /* Load metadata objects (B*Trees) */
392 sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); 390 sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index a15fcffce74f..b66d67de882c 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -132,7 +132,7 @@ int hfsplus_uni2asc(struct super_block *sb, const struct hfsplus_unistr *ustr, c
132 ustrlen = be16_to_cpu(ustr->length); 132 ustrlen = be16_to_cpu(ustr->length);
133 len = *len_p; 133 len = *len_p;
134 ce1 = NULL; 134 ce1 = NULL;
135 compose = !(HFSPLUS_SB(sb)->flags & HFSPLUS_SB_NODECOMPOSE); 135 compose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
136 136
137 while (ustrlen > 0) { 137 while (ustrlen > 0) {
138 c0 = be16_to_cpu(*ip++); 138 c0 = be16_to_cpu(*ip++);
@@ -293,7 +293,7 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
293 u16 *dstr, outlen = 0; 293 u16 *dstr, outlen = 0;
294 wchar_t c; 294 wchar_t c;
295 295
296 decompose = !(HFSPLUS_SB(sb)->flags & HFSPLUS_SB_NODECOMPOSE); 296 decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
297 while (outlen < HFSPLUS_MAX_STRLEN && len > 0) { 297 while (outlen < HFSPLUS_MAX_STRLEN && len > 0) {
298 size = asc2unichar(sb, astr, len, &c); 298 size = asc2unichar(sb, astr, len, &c);
299 299
@@ -330,8 +330,8 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)
330 wchar_t c; 330 wchar_t c;
331 u16 c2; 331 u16 c2;
332 332
333 casefold = (HFSPLUS_SB(sb)->flags & HFSPLUS_SB_CASEFOLD); 333 casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
334 decompose = !(HFSPLUS_SB(sb)->flags & HFSPLUS_SB_NODECOMPOSE); 334 decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
335 hash = init_name_hash(); 335 hash = init_name_hash();
336 astr = str->name; 336 astr = str->name;
337 len = str->len; 337 len = str->len;
@@ -373,8 +373,8 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *
373 u16 c1, c2; 373 u16 c1, c2;
374 wchar_t c; 374 wchar_t c;
375 375
376 casefold = (HFSPLUS_SB(sb)->flags & HFSPLUS_SB_CASEFOLD); 376 casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
377 decompose = !(HFSPLUS_SB(sb)->flags & HFSPLUS_SB_NODECOMPOSE); 377 decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
378 astr1 = s1->name; 378 astr1 = s1->name;
379 len1 = s1->len; 379 len1 = s1->len;
380 astr2 = s2->name; 380 astr2 = s2->name;
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c
index c89e198e8a2a..8972c20b3216 100644
--- a/fs/hfsplus/wrapper.c
+++ b/fs/hfsplus/wrapper.c
@@ -123,7 +123,7 @@ int hfsplus_read_wrapper(struct super_block *sb)
123 if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG)) 123 if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
124 break; 124 break;
125 if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) { 125 if (vhdr->signature == cpu_to_be16(HFSPLUS_VOLHEAD_SIGX)) {
126 sbi->flags |= HFSPLUS_SB_HFSX; 126 set_bit(HFSPLUS_SB_HFSX, &sbi->flags);
127 break; 127 break;
128 } 128 }
129 brelse(bh); 129 brelse(bh);
@@ -169,10 +169,14 @@ int hfsplus_read_wrapper(struct super_block *sb)
169 return -EIO; 169 return -EIO;
170 170
171 /* should still be the same... */ 171 /* should still be the same... */
172 if (vhdr->signature != (sbi->flags & HFSPLUS_SB_HFSX ? 172 if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) {
173 cpu_to_be16(HFSPLUS_VOLHEAD_SIGX) : 173 if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIGX))
174 cpu_to_be16(HFSPLUS_VOLHEAD_SIG))) 174 goto error;
175 goto error; 175 } else {
176 if (vhdr->signature != cpu_to_be16(HFSPLUS_VOLHEAD_SIG))
177 goto error;
178 }
179
176 sbi->s_vhbh = bh; 180 sbi->s_vhbh = bh;
177 sbi->s_vhdr = vhdr; 181 sbi->s_vhdr = vhdr;
178 182