aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfs
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/hfs
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'fs/hfs')
-rw-r--r--fs/hfs/bfind.c4
-rw-r--r--fs/hfs/btree.c2
-rw-r--r--fs/hfs/btree.h2
-rw-r--r--fs/hfs/dir.c52
-rw-r--r--fs/hfs/hfs_fs.h21
-rw-r--r--fs/hfs/inode.c4
-rw-r--r--fs/hfs/mdb.c4
-rw-r--r--fs/hfs/string.c17
-rw-r--r--fs/hfs/super.c28
-rw-r--r--fs/hfs/sysdep.c7
10 files changed, 55 insertions, 86 deletions
diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c
index 4129cdb3f0d8..571abe97b42a 100644
--- a/fs/hfs/bfind.c
+++ b/fs/hfs/bfind.c
@@ -23,7 +23,7 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd)
23 fd->search_key = ptr; 23 fd->search_key = ptr;
24 fd->key = ptr + tree->max_key_len + 2; 24 fd->key = ptr + tree->max_key_len + 2;
25 dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0)); 25 dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", tree->cnid, __builtin_return_address(0));
26 down(&tree->tree_lock); 26 mutex_lock(&tree->tree_lock);
27 return 0; 27 return 0;
28} 28}
29 29
@@ -32,7 +32,7 @@ void hfs_find_exit(struct hfs_find_data *fd)
32 hfs_bnode_put(fd->bnode); 32 hfs_bnode_put(fd->bnode);
33 kfree(fd->search_key); 33 kfree(fd->search_key);
34 dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0)); 34 dprint(DBG_BNODE_REFS, "find_exit: %d (%p)\n", fd->tree->cnid, __builtin_return_address(0));
35 up(&fd->tree->tree_lock); 35 mutex_unlock(&fd->tree->tree_lock);
36 fd->tree = NULL; 36 fd->tree = NULL;
37} 37}
38 38
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
index 38a0a9917d7f..3ebc437736fe 100644
--- a/fs/hfs/btree.c
+++ b/fs/hfs/btree.c
@@ -27,7 +27,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke
27 if (!tree) 27 if (!tree)
28 return NULL; 28 return NULL;
29 29
30 init_MUTEX(&tree->tree_lock); 30 mutex_init(&tree->tree_lock);
31 spin_lock_init(&tree->hash_lock); 31 spin_lock_init(&tree->hash_lock);
32 /* Set the correct compare function */ 32 /* Set the correct compare function */
33 tree->sb = sb; 33 tree->sb = sb;
diff --git a/fs/hfs/btree.h b/fs/hfs/btree.h
index cc51905ac21d..2a1d712f85dc 100644
--- a/fs/hfs/btree.h
+++ b/fs/hfs/btree.h
@@ -33,7 +33,7 @@ struct hfs_btree {
33 unsigned int depth; 33 unsigned int depth;
34 34
35 //unsigned int map1_size, map_size; 35 //unsigned int map1_size, map_size;
36 struct semaphore tree_lock; 36 struct mutex tree_lock;
37 37
38 unsigned int pages_per_bnode; 38 unsigned int pages_per_bnode;
39 spinlock_t hash_lock; 39 spinlock_t hash_lock;
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index 2b3b8611b41b..b4d70b13be92 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -25,8 +25,6 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry,
25 struct inode *inode = NULL; 25 struct inode *inode = NULL;
26 int res; 26 int res;
27 27
28 dentry->d_op = &hfs_dentry_operations;
29
30 hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); 28 hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
31 hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); 29 hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name);
32 res = hfs_brec_read(&fd, &rec, sizeof(rec)); 30 res = hfs_brec_read(&fd, &rec, sizeof(rec));
@@ -240,46 +238,22 @@ static int hfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
240} 238}
241 239
242/* 240/*
243 * hfs_unlink() 241 * hfs_remove()
244 * 242 *
245 * This is the unlink() entry in the inode_operations structure for 243 * This serves as both unlink() and rmdir() in the inode_operations
246 * regular HFS directories. The purpose is to delete an existing 244 * structure for regular HFS directories. The purpose is to delete
247 * file, given the inode for the parent directory and the name 245 * an existing child, given the inode for the parent directory and
248 * (and its length) of the existing file. 246 * the name (and its length) of the existing directory.
249 */
250static int hfs_unlink(struct inode *dir, struct dentry *dentry)
251{
252 struct inode *inode;
253 int res;
254
255 inode = dentry->d_inode;
256 res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
257 if (res)
258 return res;
259
260 drop_nlink(inode);
261 hfs_delete_inode(inode);
262 inode->i_ctime = CURRENT_TIME_SEC;
263 mark_inode_dirty(inode);
264
265 return res;
266}
267
268/*
269 * hfs_rmdir()
270 * 247 *
271 * This is the rmdir() entry in the inode_operations structure for 248 * HFS does not have hardlinks, so both rmdir and unlink set the
272 * regular HFS directories. The purpose is to delete an existing 249 * link count to 0. The only difference is the emptiness check.
273 * directory, given the inode for the parent directory and the name
274 * (and its length) of the existing directory.
275 */ 250 */
276static int hfs_rmdir(struct inode *dir, struct dentry *dentry) 251static int hfs_remove(struct inode *dir, struct dentry *dentry)
277{ 252{
278 struct inode *inode; 253 struct inode *inode = dentry->d_inode;
279 int res; 254 int res;
280 255
281 inode = dentry->d_inode; 256 if (S_ISDIR(inode->i_mode) && inode->i_size != 2)
282 if (inode->i_size != 2)
283 return -ENOTEMPTY; 257 return -ENOTEMPTY;
284 res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name); 258 res = hfs_cat_delete(inode->i_ino, dir, &dentry->d_name);
285 if (res) 259 if (res)
@@ -309,7 +283,7 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,
309 283
310 /* Unlink destination if it already exists */ 284 /* Unlink destination if it already exists */
311 if (new_dentry->d_inode) { 285 if (new_dentry->d_inode) {
312 res = hfs_unlink(new_dir, new_dentry); 286 res = hfs_remove(new_dir, new_dentry);
313 if (res) 287 if (res)
314 return res; 288 return res;
315 } 289 }
@@ -334,9 +308,9 @@ const struct file_operations hfs_dir_operations = {
334const struct inode_operations hfs_dir_inode_operations = { 308const struct inode_operations hfs_dir_inode_operations = {
335 .create = hfs_create, 309 .create = hfs_create,
336 .lookup = hfs_lookup, 310 .lookup = hfs_lookup,
337 .unlink = hfs_unlink, 311 .unlink = hfs_remove,
338 .mkdir = hfs_mkdir, 312 .mkdir = hfs_mkdir,
339 .rmdir = hfs_rmdir, 313 .rmdir = hfs_remove,
340 .rename = hfs_rename, 314 .rename = hfs_rename,
341 .setattr = hfs_inode_setattr, 315 .setattr = hfs_inode_setattr,
342}; 316};
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index 4f55651aaa51..ad97c2d58287 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -147,8 +147,6 @@ struct hfs_sb_info {
147 u16 blockoffset; 147 u16 blockoffset;
148 148
149 int fs_div; 149 int fs_div;
150
151 struct hlist_head rsrc_inodes;
152}; 150};
153 151
154#define HFS_FLG_BITMAP_DIRTY 0 152#define HFS_FLG_BITMAP_DIRTY 0
@@ -215,10 +213,14 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
215/* string.c */ 213/* string.c */
216extern const struct dentry_operations hfs_dentry_operations; 214extern const struct dentry_operations hfs_dentry_operations;
217 215
218extern int hfs_hash_dentry(struct dentry *, struct qstr *); 216extern int hfs_hash_dentry(const struct dentry *, const struct inode *,
217 struct qstr *);
219extern int hfs_strcmp(const unsigned char *, unsigned int, 218extern int hfs_strcmp(const unsigned char *, unsigned int,
220 const unsigned char *, unsigned int); 219 const unsigned char *, unsigned int);
221extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); 220extern int hfs_compare_dentry(const struct dentry *parent,
221 const struct inode *pinode,
222 const struct dentry *dentry, const struct inode *inode,
223 unsigned int len, const char *str, const struct qstr *name);
222 224
223/* trans.c */ 225/* trans.c */
224extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *); 226extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *);
@@ -254,17 +256,6 @@ static inline void hfs_bitmap_dirty(struct super_block *sb)
254 sb->s_dirt = 1; 256 sb->s_dirt = 1;
255} 257}
256 258
257static inline void hfs_buffer_sync(struct buffer_head *bh)
258{
259 while (buffer_locked(bh)) {
260 wait_on_buffer(bh);
261 }
262 if (buffer_dirty(bh)) {
263 ll_rw_block(WRITE, 1, &bh);
264 wait_on_buffer(bh);
265 }
266}
267
268#define sb_bread512(sb, sec, data) ({ \ 259#define sb_bread512(sb, sec, data) ({ \
269 struct buffer_head *__bh; \ 260 struct buffer_head *__bh; \
270 sector_t __block; \ 261 sector_t __block; \
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 397b7adc7ce6..fff16c968e67 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -150,7 +150,6 @@ static int hfs_writepages(struct address_space *mapping,
150const struct address_space_operations hfs_btree_aops = { 150const struct address_space_operations hfs_btree_aops = {
151 .readpage = hfs_readpage, 151 .readpage = hfs_readpage,
152 .writepage = hfs_writepage, 152 .writepage = hfs_writepage,
153 .sync_page = block_sync_page,
154 .write_begin = hfs_write_begin, 153 .write_begin = hfs_write_begin,
155 .write_end = generic_write_end, 154 .write_end = generic_write_end,
156 .bmap = hfs_bmap, 155 .bmap = hfs_bmap,
@@ -160,7 +159,6 @@ const struct address_space_operations hfs_btree_aops = {
160const struct address_space_operations hfs_aops = { 159const struct address_space_operations hfs_aops = {
161 .readpage = hfs_readpage, 160 .readpage = hfs_readpage,
162 .writepage = hfs_writepage, 161 .writepage = hfs_writepage,
163 .sync_page = block_sync_page,
164 .write_begin = hfs_write_begin, 162 .write_begin = hfs_write_begin,
165 .write_end = generic_write_end, 163 .write_end = generic_write_end,
166 .bmap = hfs_bmap, 164 .bmap = hfs_bmap,
@@ -524,7 +522,7 @@ static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,
524 HFS_I(inode)->rsrc_inode = dir; 522 HFS_I(inode)->rsrc_inode = dir;
525 HFS_I(dir)->rsrc_inode = inode; 523 HFS_I(dir)->rsrc_inode = inode;
526 igrab(dir); 524 igrab(dir);
527 hlist_add_head(&inode->i_hash, &HFS_SB(dir->i_sb)->rsrc_inodes); 525 hlist_add_fake(&inode->i_hash);
528 mark_inode_dirty(inode); 526 mark_inode_dirty(inode);
529out: 527out:
530 d_add(dentry, inode); 528 d_add(dentry, inode);
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c
index 86428f5ac991..1563d5ce5764 100644
--- a/fs/hfs/mdb.c
+++ b/fs/hfs/mdb.c
@@ -220,7 +220,7 @@ int hfs_mdb_get(struct super_block *sb)
220 mdb->drLsMod = hfs_mtime(); 220 mdb->drLsMod = hfs_mtime();
221 221
222 mark_buffer_dirty(HFS_SB(sb)->mdb_bh); 222 mark_buffer_dirty(HFS_SB(sb)->mdb_bh);
223 hfs_buffer_sync(HFS_SB(sb)->mdb_bh); 223 sync_dirty_buffer(HFS_SB(sb)->mdb_bh);
224 } 224 }
225 225
226 return 0; 226 return 0;
@@ -287,7 +287,7 @@ void hfs_mdb_commit(struct super_block *sb)
287 HFS_SB(sb)->alt_mdb->drAtrb |= cpu_to_be16(HFS_SB_ATTRIB_UNMNT); 287 HFS_SB(sb)->alt_mdb->drAtrb |= cpu_to_be16(HFS_SB_ATTRIB_UNMNT);
288 HFS_SB(sb)->alt_mdb->drAtrb &= cpu_to_be16(~HFS_SB_ATTRIB_INCNSTNT); 288 HFS_SB(sb)->alt_mdb->drAtrb &= cpu_to_be16(~HFS_SB_ATTRIB_INCNSTNT);
289 mark_buffer_dirty(HFS_SB(sb)->alt_mdb_bh); 289 mark_buffer_dirty(HFS_SB(sb)->alt_mdb_bh);
290 hfs_buffer_sync(HFS_SB(sb)->alt_mdb_bh); 290 sync_dirty_buffer(HFS_SB(sb)->alt_mdb_bh);
291 } 291 }
292 292
293 if (test_and_clear_bit(HFS_FLG_BITMAP_DIRTY, &HFS_SB(sb)->flags)) { 293 if (test_and_clear_bit(HFS_FLG_BITMAP_DIRTY, &HFS_SB(sb)->flags)) {
diff --git a/fs/hfs/string.c b/fs/hfs/string.c
index 927a5af79428..495a976a3cc9 100644
--- a/fs/hfs/string.c
+++ b/fs/hfs/string.c
@@ -51,7 +51,8 @@ static unsigned char caseorder[256] = {
51/* 51/*
52 * Hash a string to an integer in a case-independent way 52 * Hash a string to an integer in a case-independent way
53 */ 53 */
54int hfs_hash_dentry(struct dentry *dentry, struct qstr *this) 54int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
55 struct qstr *this)
55{ 56{
56 const unsigned char *name = this->name; 57 const unsigned char *name = this->name;
57 unsigned int hash, len = this->len; 58 unsigned int hash, len = this->len;
@@ -92,21 +93,21 @@ int hfs_strcmp(const unsigned char *s1, unsigned int len1,
92 * Test for equality of two strings in the HFS filename character ordering. 93 * Test for equality of two strings in the HFS filename character ordering.
93 * return 1 on failure and 0 on success 94 * return 1 on failure and 0 on success
94 */ 95 */
95int hfs_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) 96int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode,
97 const struct dentry *dentry, const struct inode *inode,
98 unsigned int len, const char *str, const struct qstr *name)
96{ 99{
97 const unsigned char *n1, *n2; 100 const unsigned char *n1, *n2;
98 int len;
99 101
100 len = s1->len;
101 if (len >= HFS_NAMELEN) { 102 if (len >= HFS_NAMELEN) {
102 if (s2->len < HFS_NAMELEN) 103 if (name->len < HFS_NAMELEN)
103 return 1; 104 return 1;
104 len = HFS_NAMELEN; 105 len = HFS_NAMELEN;
105 } else if (len != s2->len) 106 } else if (len != name->len)
106 return 1; 107 return 1;
107 108
108 n1 = s1->name; 109 n1 = str;
109 n2 = s2->name; 110 n2 = name->name;
110 while (len--) { 111 while (len--) {
111 if (caseorder[*n1++] != caseorder[*n2++]) 112 if (caseorder[*n1++] != caseorder[*n2++])
112 return 1; 113 return 1;
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 34235d4bf08b..1b55f704fb22 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -20,7 +20,6 @@
20#include <linux/parser.h> 20#include <linux/parser.h>
21#include <linux/seq_file.h> 21#include <linux/seq_file.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/smp_lock.h>
24#include <linux/vfs.h> 23#include <linux/vfs.h>
25 24
26#include "hfs_fs.h" 25#include "hfs_fs.h"
@@ -79,15 +78,11 @@ static int hfs_sync_fs(struct super_block *sb, int wait)
79 */ 78 */
80static void hfs_put_super(struct super_block *sb) 79static void hfs_put_super(struct super_block *sb)
81{ 80{
82 lock_kernel();
83
84 if (sb->s_dirt) 81 if (sb->s_dirt)
85 hfs_write_super(sb); 82 hfs_write_super(sb);
86 hfs_mdb_close(sb); 83 hfs_mdb_close(sb);
87 /* release the MDB's resources */ 84 /* release the MDB's resources */
88 hfs_mdb_put(sb); 85 hfs_mdb_put(sb);
89
90 unlock_kernel();
91} 86}
92 87
93/* 88/*
@@ -172,11 +167,18 @@ static struct inode *hfs_alloc_inode(struct super_block *sb)
172 return i ? &i->vfs_inode : NULL; 167 return i ? &i->vfs_inode : NULL;
173} 168}
174 169
175static void hfs_destroy_inode(struct inode *inode) 170static void hfs_i_callback(struct rcu_head *head)
176{ 171{
172 struct inode *inode = container_of(head, struct inode, i_rcu);
173 INIT_LIST_HEAD(&inode->i_dentry);
177 kmem_cache_free(hfs_inode_cachep, HFS_I(inode)); 174 kmem_cache_free(hfs_inode_cachep, HFS_I(inode));
178} 175}
179 176
177static void hfs_destroy_inode(struct inode *inode)
178{
179 call_rcu(&inode->i_rcu, hfs_i_callback);
180}
181
180static const struct super_operations hfs_super_operations = { 182static const struct super_operations hfs_super_operations = {
181 .alloc_inode = hfs_alloc_inode, 183 .alloc_inode = hfs_alloc_inode,
182 .destroy_inode = hfs_destroy_inode, 184 .destroy_inode = hfs_destroy_inode,
@@ -385,8 +387,8 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
385 sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL); 387 sbi = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL);
386 if (!sbi) 388 if (!sbi)
387 return -ENOMEM; 389 return -ENOMEM;
390
388 sb->s_fs_info = sbi; 391 sb->s_fs_info = sbi;
389 INIT_HLIST_HEAD(&sbi->rsrc_inodes);
390 392
391 res = -EINVAL; 393 res = -EINVAL;
392 if (!parse_options((char *)data, sbi)) { 394 if (!parse_options((char *)data, sbi)) {
@@ -427,13 +429,12 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent)
427 if (!root_inode) 429 if (!root_inode)
428 goto bail_no_root; 430 goto bail_no_root;
429 431
432 sb->s_d_op = &hfs_dentry_operations;
430 res = -ENOMEM; 433 res = -ENOMEM;
431 sb->s_root = d_alloc_root(root_inode); 434 sb->s_root = d_alloc_root(root_inode);
432 if (!sb->s_root) 435 if (!sb->s_root)
433 goto bail_iput; 436 goto bail_iput;
434 437
435 sb->s_root->d_op = &hfs_dentry_operations;
436
437 /* everything's okay */ 438 /* everything's okay */
438 return 0; 439 return 0;
439 440
@@ -446,17 +447,16 @@ bail:
446 return res; 447 return res;
447} 448}
448 449
449static int hfs_get_sb(struct file_system_type *fs_type, 450static struct dentry *hfs_mount(struct file_system_type *fs_type,
450 int flags, const char *dev_name, void *data, 451 int flags, const char *dev_name, void *data)
451 struct vfsmount *mnt)
452{ 452{
453 return get_sb_bdev(fs_type, flags, dev_name, data, hfs_fill_super, mnt); 453 return mount_bdev(fs_type, flags, dev_name, data, hfs_fill_super);
454} 454}
455 455
456static struct file_system_type hfs_fs_type = { 456static struct file_system_type hfs_fs_type = {
457 .owner = THIS_MODULE, 457 .owner = THIS_MODULE,
458 .name = "hfs", 458 .name = "hfs",
459 .get_sb = hfs_get_sb, 459 .mount = hfs_mount,
460 .kill_sb = kill_block_super, 460 .kill_sb = kill_block_super,
461 .fs_flags = FS_REQUIRES_DEV, 461 .fs_flags = FS_REQUIRES_DEV,
462}; 462};
diff --git a/fs/hfs/sysdep.c b/fs/hfs/sysdep.c
index 7478f5c219aa..19cf291eb91f 100644
--- a/fs/hfs/sysdep.c
+++ b/fs/hfs/sysdep.c
@@ -8,15 +8,20 @@
8 * This file contains the code to do various system dependent things. 8 * This file contains the code to do various system dependent things.
9 */ 9 */
10 10
11#include <linux/namei.h>
11#include "hfs_fs.h" 12#include "hfs_fs.h"
12 13
13/* dentry case-handling: just lowercase everything */ 14/* dentry case-handling: just lowercase everything */
14 15
15static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) 16static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd)
16{ 17{
17 struct inode *inode = dentry->d_inode; 18 struct inode *inode;
18 int diff; 19 int diff;
19 20
21 if (nd->flags & LOOKUP_RCU)
22 return -ECHILD;
23
24 inode = dentry->d_inode;
20 if(!inode) 25 if(!inode)
21 return 1; 26 return 1;
22 27