diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-05-10 14:52:07 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2011-05-10 16:50:41 -0400 |
commit | 020abf03cd659388f94cb328e1e1df0656e0d7ff (patch) | |
tree | 40d05011708ad1b4a05928d167eb120420581aa6 /fs/hfs | |
parent | 0ff8fbc61727c926883eec381fbd3d32d1fab504 (diff) | |
parent | 693d92a1bbc9e42681c42ed190bd42b636ca876f (diff) |
Merge tag 'v2.6.39-rc7'
in order to pull in changes in drivers/media/dvb/firewire/ and
sound/firewire/.
Diffstat (limited to 'fs/hfs')
-rw-r--r-- | fs/hfs/dir.c | 52 | ||||
-rw-r--r-- | fs/hfs/hfs_fs.h | 8 | ||||
-rw-r--r-- | fs/hfs/inode.c | 2 | ||||
-rw-r--r-- | fs/hfs/string.c | 17 | ||||
-rw-r--r-- | fs/hfs/super.c | 12 | ||||
-rw-r--r-- | fs/hfs/sysdep.c | 7 |
6 files changed, 43 insertions, 55 deletions
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 | */ | ||
250 | static 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 | */ |
276 | static int hfs_rmdir(struct inode *dir, struct dentry *dentry) | 251 | static 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 = { | |||
334 | const struct inode_operations hfs_dir_inode_operations = { | 308 | const 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 c8cffb81e849..ad97c2d58287 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -213,10 +213,14 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); | |||
213 | /* string.c */ | 213 | /* string.c */ |
214 | extern const struct dentry_operations hfs_dentry_operations; | 214 | extern const struct dentry_operations hfs_dentry_operations; |
215 | 215 | ||
216 | extern int hfs_hash_dentry(struct dentry *, struct qstr *); | 216 | extern int hfs_hash_dentry(const struct dentry *, const struct inode *, |
217 | struct qstr *); | ||
217 | extern int hfs_strcmp(const unsigned char *, unsigned int, | 218 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
218 | const unsigned char *, unsigned int); | 219 | const unsigned char *, unsigned int); |
219 | extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); | 220 | extern 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); | ||
220 | 224 | ||
221 | /* trans.c */ | 225 | /* trans.c */ |
222 | extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *); | 226 | extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *); |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index dffb4e996643..fff16c968e67 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -150,7 +150,6 @@ static int hfs_writepages(struct address_space *mapping, | |||
150 | const struct address_space_operations hfs_btree_aops = { | 150 | const 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 = { | |||
160 | const struct address_space_operations hfs_aops = { | 159 | const 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, |
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 | */ |
54 | int hfs_hash_dentry(struct dentry *dentry, struct qstr *this) | 54 | int 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 | */ |
95 | int hfs_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) | 96 | int 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 4824c27cebb8..1b55f704fb22 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -167,11 +167,18 @@ static struct inode *hfs_alloc_inode(struct super_block *sb) | |||
167 | return i ? &i->vfs_inode : NULL; | 167 | return i ? &i->vfs_inode : NULL; |
168 | } | 168 | } |
169 | 169 | ||
170 | static void hfs_destroy_inode(struct inode *inode) | 170 | static void hfs_i_callback(struct rcu_head *head) |
171 | { | 171 | { |
172 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
173 | INIT_LIST_HEAD(&inode->i_dentry); | ||
172 | kmem_cache_free(hfs_inode_cachep, HFS_I(inode)); | 174 | kmem_cache_free(hfs_inode_cachep, HFS_I(inode)); |
173 | } | 175 | } |
174 | 176 | ||
177 | static void hfs_destroy_inode(struct inode *inode) | ||
178 | { | ||
179 | call_rcu(&inode->i_rcu, hfs_i_callback); | ||
180 | } | ||
181 | |||
175 | static const struct super_operations hfs_super_operations = { | 182 | static const struct super_operations hfs_super_operations = { |
176 | .alloc_inode = hfs_alloc_inode, | 183 | .alloc_inode = hfs_alloc_inode, |
177 | .destroy_inode = hfs_destroy_inode, | 184 | .destroy_inode = hfs_destroy_inode, |
@@ -422,13 +429,12 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
422 | if (!root_inode) | 429 | if (!root_inode) |
423 | goto bail_no_root; | 430 | goto bail_no_root; |
424 | 431 | ||
432 | sb->s_d_op = &hfs_dentry_operations; | ||
425 | res = -ENOMEM; | 433 | res = -ENOMEM; |
426 | sb->s_root = d_alloc_root(root_inode); | 434 | sb->s_root = d_alloc_root(root_inode); |
427 | if (!sb->s_root) | 435 | if (!sb->s_root) |
428 | goto bail_iput; | 436 | goto bail_iput; |
429 | 437 | ||
430 | sb->s_root->d_op = &hfs_dentry_operations; | ||
431 | |||
432 | /* everything's okay */ | 438 | /* everything's okay */ |
433 | return 0; | 439 | return 0; |
434 | 440 | ||
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 | ||
15 | static int hfs_revalidate_dentry(struct dentry *dentry, struct nameidata *nd) | 16 | static 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 | ||