diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/hfsplus/inode.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/hfsplus/inode.c')
-rw-r--r-- | fs/hfsplus/inode.c | 274 |
1 files changed, 147 insertions, 127 deletions
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index c5a979d62c65..b248a6cfcad9 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Inode handling routines | 8 | * Inode handling routines |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/blkdev.h> | ||
11 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
@@ -36,7 +37,7 @@ static int hfsplus_write_begin(struct file *file, struct address_space *mapping, | |||
36 | *pagep = NULL; | 37 | *pagep = NULL; |
37 | ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 38 | ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
38 | hfsplus_get_block, | 39 | hfsplus_get_block, |
39 | &HFSPLUS_I(mapping->host).phys_size); | 40 | &HFSPLUS_I(mapping->host)->phys_size); |
40 | if (unlikely(ret)) { | 41 | if (unlikely(ret)) { |
41 | loff_t isize = mapping->host->i_size; | 42 | loff_t isize = mapping->host->i_size; |
42 | if (pos + len > isize) | 43 | if (pos + len > isize) |
@@ -62,13 +63,13 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) | |||
62 | 63 | ||
63 | switch (inode->i_ino) { | 64 | switch (inode->i_ino) { |
64 | case HFSPLUS_EXT_CNID: | 65 | case HFSPLUS_EXT_CNID: |
65 | tree = HFSPLUS_SB(sb).ext_tree; | 66 | tree = HFSPLUS_SB(sb)->ext_tree; |
66 | break; | 67 | break; |
67 | case HFSPLUS_CAT_CNID: | 68 | case HFSPLUS_CAT_CNID: |
68 | tree = HFSPLUS_SB(sb).cat_tree; | 69 | tree = HFSPLUS_SB(sb)->cat_tree; |
69 | break; | 70 | break; |
70 | case HFSPLUS_ATTR_CNID: | 71 | case HFSPLUS_ATTR_CNID: |
71 | tree = HFSPLUS_SB(sb).attr_tree; | 72 | tree = HFSPLUS_SB(sb)->attr_tree; |
72 | break; | 73 | break; |
73 | default: | 74 | default: |
74 | BUG(); | 75 | BUG(); |
@@ -77,7 +78,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) | |||
77 | if (!tree) | 78 | if (!tree) |
78 | return 0; | 79 | return 0; |
79 | if (tree->node_size >= PAGE_CACHE_SIZE) { | 80 | if (tree->node_size >= PAGE_CACHE_SIZE) { |
80 | nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT); | 81 | nidx = page->index >> |
82 | (tree->node_size_shift - PAGE_CACHE_SHIFT); | ||
81 | spin_lock(&tree->hash_lock); | 83 | spin_lock(&tree->hash_lock); |
82 | node = hfs_bnode_findhash(tree, nidx); | 84 | node = hfs_bnode_findhash(tree, nidx); |
83 | if (!node) | 85 | if (!node) |
@@ -90,7 +92,8 @@ static int hfsplus_releasepage(struct page *page, gfp_t mask) | |||
90 | } | 92 | } |
91 | spin_unlock(&tree->hash_lock); | 93 | spin_unlock(&tree->hash_lock); |
92 | } else { | 94 | } else { |
93 | nidx = page->index << (PAGE_CACHE_SHIFT - tree->node_size_shift); | 95 | nidx = page->index << |
96 | (PAGE_CACHE_SHIFT - tree->node_size_shift); | ||
94 | i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift); | 97 | i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift); |
95 | spin_lock(&tree->hash_lock); | 98 | spin_lock(&tree->hash_lock); |
96 | do { | 99 | do { |
@@ -143,7 +146,6 @@ static int hfsplus_writepages(struct address_space *mapping, | |||
143 | const struct address_space_operations hfsplus_btree_aops = { | 146 | const struct address_space_operations hfsplus_btree_aops = { |
144 | .readpage = hfsplus_readpage, | 147 | .readpage = hfsplus_readpage, |
145 | .writepage = hfsplus_writepage, | 148 | .writepage = hfsplus_writepage, |
146 | .sync_page = block_sync_page, | ||
147 | .write_begin = hfsplus_write_begin, | 149 | .write_begin = hfsplus_write_begin, |
148 | .write_end = generic_write_end, | 150 | .write_end = generic_write_end, |
149 | .bmap = hfsplus_bmap, | 151 | .bmap = hfsplus_bmap, |
@@ -153,7 +155,6 @@ const struct address_space_operations hfsplus_btree_aops = { | |||
153 | const struct address_space_operations hfsplus_aops = { | 155 | const struct address_space_operations hfsplus_aops = { |
154 | .readpage = hfsplus_readpage, | 156 | .readpage = hfsplus_readpage, |
155 | .writepage = hfsplus_writepage, | 157 | .writepage = hfsplus_writepage, |
156 | .sync_page = block_sync_page, | ||
157 | .write_begin = hfsplus_write_begin, | 158 | .write_begin = hfsplus_write_begin, |
158 | .write_end = generic_write_end, | 159 | .write_end = generic_write_end, |
159 | .bmap = hfsplus_bmap, | 160 | .bmap = hfsplus_bmap, |
@@ -166,18 +167,19 @@ const struct dentry_operations hfsplus_dentry_operations = { | |||
166 | .d_compare = hfsplus_compare_dentry, | 167 | .d_compare = hfsplus_compare_dentry, |
167 | }; | 168 | }; |
168 | 169 | ||
169 | static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, | 170 | static struct dentry *hfsplus_file_lookup(struct inode *dir, |
170 | struct nameidata *nd) | 171 | struct dentry *dentry, struct nameidata *nd) |
171 | { | 172 | { |
172 | struct hfs_find_data fd; | 173 | struct hfs_find_data fd; |
173 | struct super_block *sb = dir->i_sb; | 174 | struct super_block *sb = dir->i_sb; |
174 | struct inode *inode = NULL; | 175 | struct inode *inode = NULL; |
176 | struct hfsplus_inode_info *hip; | ||
175 | int err; | 177 | int err; |
176 | 178 | ||
177 | if (HFSPLUS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc")) | 179 | if (HFSPLUS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc")) |
178 | goto out; | 180 | goto out; |
179 | 181 | ||
180 | inode = HFSPLUS_I(dir).rsrc_inode; | 182 | inode = HFSPLUS_I(dir)->rsrc_inode; |
181 | if (inode) | 183 | if (inode) |
182 | goto out; | 184 | goto out; |
183 | 185 | ||
@@ -185,12 +187,15 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent | |||
185 | if (!inode) | 187 | if (!inode) |
186 | return ERR_PTR(-ENOMEM); | 188 | return ERR_PTR(-ENOMEM); |
187 | 189 | ||
190 | hip = HFSPLUS_I(inode); | ||
188 | inode->i_ino = dir->i_ino; | 191 | inode->i_ino = dir->i_ino; |
189 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); | 192 | INIT_LIST_HEAD(&hip->open_dir_list); |
190 | mutex_init(&HFSPLUS_I(inode).extents_lock); | 193 | mutex_init(&hip->extents_lock); |
191 | HFSPLUS_I(inode).flags = HFSPLUS_FLG_RSRC; | 194 | hip->extent_state = 0; |
195 | hip->flags = 0; | ||
196 | set_bit(HFSPLUS_I_RSRC, &hip->flags); | ||
192 | 197 | ||
193 | hfs_find_init(HFSPLUS_SB(sb).cat_tree, &fd); | 198 | hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
194 | err = hfsplus_find_cat(sb, dir->i_ino, &fd); | 199 | err = hfsplus_find_cat(sb, dir->i_ino, &fd); |
195 | if (!err) | 200 | if (!err) |
196 | err = hfsplus_cat_read_inode(inode, &fd); | 201 | err = hfsplus_cat_read_inode(inode, &fd); |
@@ -199,42 +204,48 @@ static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dent | |||
199 | iput(inode); | 204 | iput(inode); |
200 | return ERR_PTR(err); | 205 | return ERR_PTR(err); |
201 | } | 206 | } |
202 | HFSPLUS_I(inode).rsrc_inode = dir; | 207 | hip->rsrc_inode = dir; |
203 | HFSPLUS_I(dir).rsrc_inode = inode; | 208 | HFSPLUS_I(dir)->rsrc_inode = inode; |
204 | igrab(dir); | 209 | igrab(dir); |
205 | hlist_add_head(&inode->i_hash, &HFSPLUS_SB(sb).rsrc_inodes); | 210 | |
211 | /* | ||
212 | * __mark_inode_dirty expects inodes to be hashed. Since we don't | ||
213 | * want resource fork inodes in the regular inode space, we make them | ||
214 | * appear hashed, but do not put on any lists. hlist_del() | ||
215 | * will work fine and require no locking. | ||
216 | */ | ||
217 | hlist_add_fake(&inode->i_hash); | ||
218 | |||
206 | mark_inode_dirty(inode); | 219 | mark_inode_dirty(inode); |
207 | out: | 220 | out: |
208 | d_add(dentry, inode); | 221 | d_add(dentry, inode); |
209 | return NULL; | 222 | return NULL; |
210 | } | 223 | } |
211 | 224 | ||
212 | static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, int dir) | 225 | static void hfsplus_get_perms(struct inode *inode, |
226 | struct hfsplus_perm *perms, int dir) | ||
213 | { | 227 | { |
214 | struct super_block *sb = inode->i_sb; | 228 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); |
215 | u16 mode; | 229 | u16 mode; |
216 | 230 | ||
217 | mode = be16_to_cpu(perms->mode); | 231 | mode = be16_to_cpu(perms->mode); |
218 | 232 | ||
219 | inode->i_uid = be32_to_cpu(perms->owner); | 233 | inode->i_uid = be32_to_cpu(perms->owner); |
220 | if (!inode->i_uid && !mode) | 234 | if (!inode->i_uid && !mode) |
221 | inode->i_uid = HFSPLUS_SB(sb).uid; | 235 | inode->i_uid = sbi->uid; |
222 | 236 | ||
223 | inode->i_gid = be32_to_cpu(perms->group); | 237 | inode->i_gid = be32_to_cpu(perms->group); |
224 | if (!inode->i_gid && !mode) | 238 | if (!inode->i_gid && !mode) |
225 | inode->i_gid = HFSPLUS_SB(sb).gid; | 239 | inode->i_gid = sbi->gid; |
226 | 240 | ||
227 | if (dir) { | 241 | if (dir) { |
228 | mode = mode ? (mode & S_IALLUGO) : | 242 | mode = mode ? (mode & S_IALLUGO) : (S_IRWXUGO & ~(sbi->umask)); |
229 | (S_IRWXUGO & ~(HFSPLUS_SB(sb).umask)); | ||
230 | mode |= S_IFDIR; | 243 | mode |= S_IFDIR; |
231 | } else if (!mode) | 244 | } else if (!mode) |
232 | mode = S_IFREG | ((S_IRUGO|S_IWUGO) & | 245 | mode = S_IFREG | ((S_IRUGO|S_IWUGO) & ~(sbi->umask)); |
233 | ~(HFSPLUS_SB(sb).umask)); | ||
234 | inode->i_mode = mode; | 246 | inode->i_mode = mode; |
235 | 247 | ||
236 | HFSPLUS_I(inode).rootflags = perms->rootflags; | 248 | HFSPLUS_I(inode)->userflags = perms->userflags; |
237 | HFSPLUS_I(inode).userflags = perms->userflags; | ||
238 | if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE) | 249 | if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE) |
239 | inode->i_flags |= S_IMMUTABLE; | 250 | inode->i_flags |= S_IMMUTABLE; |
240 | else | 251 | else |
@@ -245,30 +256,13 @@ static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, i | |||
245 | inode->i_flags &= ~S_APPEND; | 256 | inode->i_flags &= ~S_APPEND; |
246 | } | 257 | } |
247 | 258 | ||
248 | static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms) | ||
249 | { | ||
250 | if (inode->i_flags & S_IMMUTABLE) | ||
251 | perms->rootflags |= HFSPLUS_FLG_IMMUTABLE; | ||
252 | else | ||
253 | perms->rootflags &= ~HFSPLUS_FLG_IMMUTABLE; | ||
254 | if (inode->i_flags & S_APPEND) | ||
255 | perms->rootflags |= HFSPLUS_FLG_APPEND; | ||
256 | else | ||
257 | perms->rootflags &= ~HFSPLUS_FLG_APPEND; | ||
258 | perms->userflags = HFSPLUS_I(inode).userflags; | ||
259 | perms->mode = cpu_to_be16(inode->i_mode); | ||
260 | perms->owner = cpu_to_be32(inode->i_uid); | ||
261 | perms->group = cpu_to_be32(inode->i_gid); | ||
262 | perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); | ||
263 | } | ||
264 | |||
265 | static int hfsplus_file_open(struct inode *inode, struct file *file) | 259 | static int hfsplus_file_open(struct inode *inode, struct file *file) |
266 | { | 260 | { |
267 | if (HFSPLUS_IS_RSRC(inode)) | 261 | if (HFSPLUS_IS_RSRC(inode)) |
268 | inode = HFSPLUS_I(inode).rsrc_inode; | 262 | inode = HFSPLUS_I(inode)->rsrc_inode; |
269 | if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) | 263 | if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) |
270 | return -EOVERFLOW; | 264 | return -EOVERFLOW; |
271 | atomic_inc(&HFSPLUS_I(inode).opencnt); | 265 | atomic_inc(&HFSPLUS_I(inode)->opencnt); |
272 | return 0; | 266 | return 0; |
273 | } | 267 | } |
274 | 268 | ||
@@ -277,12 +271,13 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) | |||
277 | struct super_block *sb = inode->i_sb; | 271 | struct super_block *sb = inode->i_sb; |
278 | 272 | ||
279 | if (HFSPLUS_IS_RSRC(inode)) | 273 | if (HFSPLUS_IS_RSRC(inode)) |
280 | inode = HFSPLUS_I(inode).rsrc_inode; | 274 | inode = HFSPLUS_I(inode)->rsrc_inode; |
281 | if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { | 275 | if (atomic_dec_and_test(&HFSPLUS_I(inode)->opencnt)) { |
282 | mutex_lock(&inode->i_mutex); | 276 | mutex_lock(&inode->i_mutex); |
283 | hfsplus_file_truncate(inode); | 277 | hfsplus_file_truncate(inode); |
284 | if (inode->i_flags & S_DEAD) { | 278 | if (inode->i_flags & S_DEAD) { |
285 | hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); | 279 | hfsplus_delete_cat(inode->i_ino, |
280 | HFSPLUS_SB(sb)->hidden_dir, NULL); | ||
286 | hfsplus_delete_inode(inode); | 281 | hfsplus_delete_inode(inode); |
287 | } | 282 | } |
288 | mutex_unlock(&inode->i_mutex); | 283 | mutex_unlock(&inode->i_mutex); |
@@ -311,29 +306,41 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) | |||
311 | return 0; | 306 | return 0; |
312 | } | 307 | } |
313 | 308 | ||
314 | static int hfsplus_file_fsync(struct file *filp, int datasync) | 309 | int hfsplus_file_fsync(struct file *file, int datasync) |
315 | { | 310 | { |
316 | struct inode *inode = filp->f_mapping->host; | 311 | struct inode *inode = file->f_mapping->host; |
317 | struct super_block * sb; | 312 | struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
318 | int ret, err; | 313 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); |
319 | 314 | int error = 0, error2; | |
320 | /* sync the inode to buffers */ | 315 | |
321 | ret = write_inode_now(inode, 0); | 316 | /* |
322 | 317 | * Sync inode metadata into the catalog and extent trees. | |
323 | /* sync the superblock to buffers */ | 318 | */ |
324 | sb = inode->i_sb; | 319 | sync_inode_metadata(inode, 1); |
325 | if (sb->s_dirt) { | 320 | |
326 | if (!(sb->s_flags & MS_RDONLY)) | 321 | /* |
327 | hfsplus_sync_fs(sb, 1); | 322 | * And explicitly write out the btrees. |
328 | else | 323 | */ |
329 | sb->s_dirt = 0; | 324 | if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags)) |
325 | error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); | ||
326 | |||
327 | if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) { | ||
328 | error2 = | ||
329 | filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); | ||
330 | if (!error) | ||
331 | error = error2; | ||
330 | } | 332 | } |
331 | 333 | ||
332 | /* .. finally sync the buffers to disk */ | 334 | if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) { |
333 | err = sync_blockdev(sb->s_bdev); | 335 | error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); |
334 | if (!ret) | 336 | if (!error) |
335 | ret = err; | 337 | error = error2; |
336 | return ret; | 338 | } |
339 | |||
340 | if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) | ||
341 | blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); | ||
342 | |||
343 | return error; | ||
337 | } | 344 | } |
338 | 345 | ||
339 | static const struct inode_operations hfsplus_file_inode_operations = { | 346 | static const struct inode_operations hfsplus_file_inode_operations = { |
@@ -346,7 +353,7 @@ static const struct inode_operations hfsplus_file_inode_operations = { | |||
346 | }; | 353 | }; |
347 | 354 | ||
348 | static const struct file_operations hfsplus_file_operations = { | 355 | static const struct file_operations hfsplus_file_operations = { |
349 | .llseek = generic_file_llseek, | 356 | .llseek = generic_file_llseek, |
350 | .read = do_sync_read, | 357 | .read = do_sync_read, |
351 | .aio_read = generic_file_aio_read, | 358 | .aio_read = generic_file_aio_read, |
352 | .write = do_sync_write, | 359 | .write = do_sync_write, |
@@ -361,47 +368,53 @@ static const struct file_operations hfsplus_file_operations = { | |||
361 | 368 | ||
362 | struct inode *hfsplus_new_inode(struct super_block *sb, int mode) | 369 | struct inode *hfsplus_new_inode(struct super_block *sb, int mode) |
363 | { | 370 | { |
371 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | ||
364 | struct inode *inode = new_inode(sb); | 372 | struct inode *inode = new_inode(sb); |
373 | struct hfsplus_inode_info *hip; | ||
374 | |||
365 | if (!inode) | 375 | if (!inode) |
366 | return NULL; | 376 | return NULL; |
367 | 377 | ||
368 | inode->i_ino = HFSPLUS_SB(sb).next_cnid++; | 378 | inode->i_ino = sbi->next_cnid++; |
369 | inode->i_mode = mode; | 379 | inode->i_mode = mode; |
370 | inode->i_uid = current_fsuid(); | 380 | inode->i_uid = current_fsuid(); |
371 | inode->i_gid = current_fsgid(); | 381 | inode->i_gid = current_fsgid(); |
372 | inode->i_nlink = 1; | 382 | inode->i_nlink = 1; |
373 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 383 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
374 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); | 384 | |
375 | mutex_init(&HFSPLUS_I(inode).extents_lock); | 385 | hip = HFSPLUS_I(inode); |
376 | atomic_set(&HFSPLUS_I(inode).opencnt, 0); | 386 | INIT_LIST_HEAD(&hip->open_dir_list); |
377 | HFSPLUS_I(inode).flags = 0; | 387 | mutex_init(&hip->extents_lock); |
378 | memset(HFSPLUS_I(inode).first_extents, 0, sizeof(hfsplus_extent_rec)); | 388 | atomic_set(&hip->opencnt, 0); |
379 | memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec)); | 389 | hip->extent_state = 0; |
380 | HFSPLUS_I(inode).alloc_blocks = 0; | 390 | hip->flags = 0; |
381 | HFSPLUS_I(inode).first_blocks = 0; | 391 | memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); |
382 | HFSPLUS_I(inode).cached_start = 0; | 392 | memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); |
383 | HFSPLUS_I(inode).cached_blocks = 0; | 393 | hip->alloc_blocks = 0; |
384 | HFSPLUS_I(inode).phys_size = 0; | 394 | hip->first_blocks = 0; |
385 | HFSPLUS_I(inode).fs_blocks = 0; | 395 | hip->cached_start = 0; |
386 | HFSPLUS_I(inode).rsrc_inode = NULL; | 396 | hip->cached_blocks = 0; |
397 | hip->phys_size = 0; | ||
398 | hip->fs_blocks = 0; | ||
399 | hip->rsrc_inode = NULL; | ||
387 | if (S_ISDIR(inode->i_mode)) { | 400 | if (S_ISDIR(inode->i_mode)) { |
388 | inode->i_size = 2; | 401 | inode->i_size = 2; |
389 | HFSPLUS_SB(sb).folder_count++; | 402 | sbi->folder_count++; |
390 | inode->i_op = &hfsplus_dir_inode_operations; | 403 | inode->i_op = &hfsplus_dir_inode_operations; |
391 | inode->i_fop = &hfsplus_dir_operations; | 404 | inode->i_fop = &hfsplus_dir_operations; |
392 | } else if (S_ISREG(inode->i_mode)) { | 405 | } else if (S_ISREG(inode->i_mode)) { |
393 | HFSPLUS_SB(sb).file_count++; | 406 | sbi->file_count++; |
394 | inode->i_op = &hfsplus_file_inode_operations; | 407 | inode->i_op = &hfsplus_file_inode_operations; |
395 | inode->i_fop = &hfsplus_file_operations; | 408 | inode->i_fop = &hfsplus_file_operations; |
396 | inode->i_mapping->a_ops = &hfsplus_aops; | 409 | inode->i_mapping->a_ops = &hfsplus_aops; |
397 | HFSPLUS_I(inode).clump_blocks = HFSPLUS_SB(sb).data_clump_blocks; | 410 | hip->clump_blocks = sbi->data_clump_blocks; |
398 | } else if (S_ISLNK(inode->i_mode)) { | 411 | } else if (S_ISLNK(inode->i_mode)) { |
399 | HFSPLUS_SB(sb).file_count++; | 412 | sbi->file_count++; |
400 | inode->i_op = &page_symlink_inode_operations; | 413 | inode->i_op = &page_symlink_inode_operations; |
401 | inode->i_mapping->a_ops = &hfsplus_aops; | 414 | inode->i_mapping->a_ops = &hfsplus_aops; |
402 | HFSPLUS_I(inode).clump_blocks = 1; | 415 | hip->clump_blocks = 1; |
403 | } else | 416 | } else |
404 | HFSPLUS_SB(sb).file_count++; | 417 | sbi->file_count++; |
405 | insert_inode_hash(inode); | 418 | insert_inode_hash(inode); |
406 | mark_inode_dirty(inode); | 419 | mark_inode_dirty(inode); |
407 | sb->s_dirt = 1; | 420 | sb->s_dirt = 1; |
@@ -414,11 +427,11 @@ void hfsplus_delete_inode(struct inode *inode) | |||
414 | struct super_block *sb = inode->i_sb; | 427 | struct super_block *sb = inode->i_sb; |
415 | 428 | ||
416 | if (S_ISDIR(inode->i_mode)) { | 429 | if (S_ISDIR(inode->i_mode)) { |
417 | HFSPLUS_SB(sb).folder_count--; | 430 | HFSPLUS_SB(sb)->folder_count--; |
418 | sb->s_dirt = 1; | 431 | sb->s_dirt = 1; |
419 | return; | 432 | return; |
420 | } | 433 | } |
421 | HFSPLUS_SB(sb).file_count--; | 434 | HFSPLUS_SB(sb)->file_count--; |
422 | if (S_ISREG(inode->i_mode)) { | 435 | if (S_ISREG(inode->i_mode)) { |
423 | if (!inode->i_nlink) { | 436 | if (!inode->i_nlink) { |
424 | inode->i_size = 0; | 437 | inode->i_size = 0; |
@@ -434,34 +447,40 @@ void hfsplus_delete_inode(struct inode *inode) | |||
434 | void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) | 447 | void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) |
435 | { | 448 | { |
436 | struct super_block *sb = inode->i_sb; | 449 | struct super_block *sb = inode->i_sb; |
450 | struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); | ||
451 | struct hfsplus_inode_info *hip = HFSPLUS_I(inode); | ||
437 | u32 count; | 452 | u32 count; |
438 | int i; | 453 | int i; |
439 | 454 | ||
440 | memcpy(&HFSPLUS_I(inode).first_extents, &fork->extents, | 455 | memcpy(&hip->first_extents, &fork->extents, sizeof(hfsplus_extent_rec)); |
441 | sizeof(hfsplus_extent_rec)); | ||
442 | for (count = 0, i = 0; i < 8; i++) | 456 | for (count = 0, i = 0; i < 8; i++) |
443 | count += be32_to_cpu(fork->extents[i].block_count); | 457 | count += be32_to_cpu(fork->extents[i].block_count); |
444 | HFSPLUS_I(inode).first_blocks = count; | 458 | hip->first_blocks = count; |
445 | memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec)); | 459 | memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); |
446 | HFSPLUS_I(inode).cached_start = 0; | 460 | hip->cached_start = 0; |
447 | HFSPLUS_I(inode).cached_blocks = 0; | 461 | hip->cached_blocks = 0; |
448 | 462 | ||
449 | HFSPLUS_I(inode).alloc_blocks = be32_to_cpu(fork->total_blocks); | 463 | hip->alloc_blocks = be32_to_cpu(fork->total_blocks); |
450 | inode->i_size = HFSPLUS_I(inode).phys_size = be64_to_cpu(fork->total_size); | 464 | hip->phys_size = inode->i_size = be64_to_cpu(fork->total_size); |
451 | HFSPLUS_I(inode).fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; | 465 | hip->fs_blocks = |
452 | inode_set_bytes(inode, HFSPLUS_I(inode).fs_blocks << sb->s_blocksize_bits); | 466 | (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; |
453 | HFSPLUS_I(inode).clump_blocks = be32_to_cpu(fork->clump_size) >> HFSPLUS_SB(sb).alloc_blksz_shift; | 467 | inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits); |
454 | if (!HFSPLUS_I(inode).clump_blocks) | 468 | hip->clump_blocks = |
455 | HFSPLUS_I(inode).clump_blocks = HFSPLUS_IS_RSRC(inode) ? HFSPLUS_SB(sb).rsrc_clump_blocks : | 469 | be32_to_cpu(fork->clump_size) >> sbi->alloc_blksz_shift; |
456 | HFSPLUS_SB(sb).data_clump_blocks; | 470 | if (!hip->clump_blocks) { |
471 | hip->clump_blocks = HFSPLUS_IS_RSRC(inode) ? | ||
472 | sbi->rsrc_clump_blocks : | ||
473 | sbi->data_clump_blocks; | ||
474 | } | ||
457 | } | 475 | } |
458 | 476 | ||
459 | void hfsplus_inode_write_fork(struct inode *inode, struct hfsplus_fork_raw *fork) | 477 | void hfsplus_inode_write_fork(struct inode *inode, |
478 | struct hfsplus_fork_raw *fork) | ||
460 | { | 479 | { |
461 | memcpy(&fork->extents, &HFSPLUS_I(inode).first_extents, | 480 | memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents, |
462 | sizeof(hfsplus_extent_rec)); | 481 | sizeof(hfsplus_extent_rec)); |
463 | fork->total_size = cpu_to_be64(inode->i_size); | 482 | fork->total_size = cpu_to_be64(inode->i_size); |
464 | fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode).alloc_blocks); | 483 | fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode)->alloc_blocks); |
465 | } | 484 | } |
466 | 485 | ||
467 | int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | 486 | int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) |
@@ -472,7 +491,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
472 | 491 | ||
473 | type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset); | 492 | type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset); |
474 | 493 | ||
475 | HFSPLUS_I(inode).dev = 0; | 494 | HFSPLUS_I(inode)->linkid = 0; |
476 | if (type == HFSPLUS_FOLDER) { | 495 | if (type == HFSPLUS_FOLDER) { |
477 | struct hfsplus_cat_folder *folder = &entry.folder; | 496 | struct hfsplus_cat_folder *folder = &entry.folder; |
478 | 497 | ||
@@ -486,8 +505,8 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
486 | inode->i_atime = hfsp_mt2ut(folder->access_date); | 505 | inode->i_atime = hfsp_mt2ut(folder->access_date); |
487 | inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); | 506 | inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); |
488 | inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); | 507 | inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); |
489 | HFSPLUS_I(inode).create_date = folder->create_date; | 508 | HFSPLUS_I(inode)->create_date = folder->create_date; |
490 | HFSPLUS_I(inode).fs_blocks = 0; | 509 | HFSPLUS_I(inode)->fs_blocks = 0; |
491 | inode->i_op = &hfsplus_dir_inode_operations; | 510 | inode->i_op = &hfsplus_dir_inode_operations; |
492 | inode->i_fop = &hfsplus_dir_operations; | 511 | inode->i_fop = &hfsplus_dir_operations; |
493 | } else if (type == HFSPLUS_FILE) { | 512 | } else if (type == HFSPLUS_FILE) { |
@@ -498,13 +517,14 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
498 | hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, | 517 | hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
499 | sizeof(struct hfsplus_cat_file)); | 518 | sizeof(struct hfsplus_cat_file)); |
500 | 519 | ||
501 | hfsplus_inode_read_fork(inode, HFSPLUS_IS_DATA(inode) ? | 520 | hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? |
502 | &file->data_fork : &file->rsrc_fork); | 521 | &file->rsrc_fork : &file->data_fork); |
503 | hfsplus_get_perms(inode, &file->permissions, 0); | 522 | hfsplus_get_perms(inode, &file->permissions, 0); |
504 | inode->i_nlink = 1; | 523 | inode->i_nlink = 1; |
505 | if (S_ISREG(inode->i_mode)) { | 524 | if (S_ISREG(inode->i_mode)) { |
506 | if (file->permissions.dev) | 525 | if (file->permissions.dev) |
507 | inode->i_nlink = be32_to_cpu(file->permissions.dev); | 526 | inode->i_nlink = |
527 | be32_to_cpu(file->permissions.dev); | ||
508 | inode->i_op = &hfsplus_file_inode_operations; | 528 | inode->i_op = &hfsplus_file_inode_operations; |
509 | inode->i_fop = &hfsplus_file_operations; | 529 | inode->i_fop = &hfsplus_file_operations; |
510 | inode->i_mapping->a_ops = &hfsplus_aops; | 530 | inode->i_mapping->a_ops = &hfsplus_aops; |
@@ -518,7 +538,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) | |||
518 | inode->i_atime = hfsp_mt2ut(file->access_date); | 538 | inode->i_atime = hfsp_mt2ut(file->access_date); |
519 | inode->i_mtime = hfsp_mt2ut(file->content_mod_date); | 539 | inode->i_mtime = hfsp_mt2ut(file->content_mod_date); |
520 | inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); | 540 | inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); |
521 | HFSPLUS_I(inode).create_date = file->create_date; | 541 | HFSPLUS_I(inode)->create_date = file->create_date; |
522 | } else { | 542 | } else { |
523 | printk(KERN_ERR "hfs: bad catalog entry used to create inode\n"); | 543 | printk(KERN_ERR "hfs: bad catalog entry used to create inode\n"); |
524 | res = -EIO; | 544 | res = -EIO; |
@@ -533,12 +553,12 @@ int hfsplus_cat_write_inode(struct inode *inode) | |||
533 | hfsplus_cat_entry entry; | 553 | hfsplus_cat_entry entry; |
534 | 554 | ||
535 | if (HFSPLUS_IS_RSRC(inode)) | 555 | if (HFSPLUS_IS_RSRC(inode)) |
536 | main_inode = HFSPLUS_I(inode).rsrc_inode; | 556 | main_inode = HFSPLUS_I(inode)->rsrc_inode; |
537 | 557 | ||
538 | if (!main_inode->i_nlink) | 558 | if (!main_inode->i_nlink) |
539 | return 0; | 559 | return 0; |
540 | 560 | ||
541 | if (hfs_find_init(HFSPLUS_SB(main_inode->i_sb).cat_tree, &fd)) | 561 | if (hfs_find_init(HFSPLUS_SB(main_inode->i_sb)->cat_tree, &fd)) |
542 | /* panic? */ | 562 | /* panic? */ |
543 | return -EIO; | 563 | return -EIO; |
544 | 564 | ||
@@ -554,7 +574,7 @@ int hfsplus_cat_write_inode(struct inode *inode) | |||
554 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, | 574 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
555 | sizeof(struct hfsplus_cat_folder)); | 575 | sizeof(struct hfsplus_cat_folder)); |
556 | /* simple node checks? */ | 576 | /* simple node checks? */ |
557 | hfsplus_set_perms(inode, &folder->permissions); | 577 | hfsplus_cat_set_perms(inode, &folder->permissions); |
558 | folder->access_date = hfsp_ut2mt(inode->i_atime); | 578 | folder->access_date = hfsp_ut2mt(inode->i_atime); |
559 | folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); | 579 | folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); |
560 | folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); | 580 | folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); |
@@ -576,12 +596,10 @@ int hfsplus_cat_write_inode(struct inode *inode) | |||
576 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, | 596 | hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
577 | sizeof(struct hfsplus_cat_file)); | 597 | sizeof(struct hfsplus_cat_file)); |
578 | hfsplus_inode_write_fork(inode, &file->data_fork); | 598 | hfsplus_inode_write_fork(inode, &file->data_fork); |
579 | if (S_ISREG(inode->i_mode)) | 599 | hfsplus_cat_set_perms(inode, &file->permissions); |
580 | HFSPLUS_I(inode).dev = inode->i_nlink; | 600 | if (HFSPLUS_FLG_IMMUTABLE & |
581 | if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) | 601 | (file->permissions.rootflags | |
582 | HFSPLUS_I(inode).dev = kdev_t_to_nr(inode->i_rdev); | 602 | file->permissions.userflags)) |
583 | hfsplus_set_perms(inode, &file->permissions); | ||
584 | if ((file->permissions.rootflags | file->permissions.userflags) & HFSPLUS_FLG_IMMUTABLE) | ||
585 | file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); | 603 | file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); |
586 | else | 604 | else |
587 | file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED); | 605 | file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED); |
@@ -591,6 +609,8 @@ int hfsplus_cat_write_inode(struct inode *inode) | |||
591 | hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, | 609 | hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, |
592 | sizeof(struct hfsplus_cat_file)); | 610 | sizeof(struct hfsplus_cat_file)); |
593 | } | 611 | } |
612 | |||
613 | set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); | ||
594 | out: | 614 | out: |
595 | hfs_find_exit(&fd); | 615 | hfs_find_exit(&fd); |
596 | return 0; | 616 | return 0; |