Blame view
fs/hfsplus/inode.c
16.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 |
/* * linux/fs/hfsplus/inode.c * * Copyright (C) 2001 * Brad Boyer (flar@allandria.com) * (C) 2003 Ardis Technologies <roman@ardistech.com> * * Inode handling routines */ |
34a2d313c hfsplus: flush di... |
10 |
#include <linux/blkdev.h> |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
#include <linux/mm.h> #include <linux/fs.h> #include <linux/pagemap.h> |
1da177e4c Linux-2.6.12-rc2 |
14 |
#include <linux/mpage.h> |
e8edc6e03 Detach sched.h fr... |
15 |
#include <linux/sched.h> |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 20 21 |
#include "hfsplus_fs.h" #include "hfsplus_raw.h" static int hfsplus_readpage(struct file *file, struct page *page) { |
1da177e4c Linux-2.6.12-rc2 |
22 23 24 25 26 |
return block_read_full_page(page, hfsplus_get_block); } static int hfsplus_writepage(struct page *page, struct writeback_control *wbc) { |
1da177e4c Linux-2.6.12-rc2 |
27 28 |
return block_write_full_page(page, hfsplus_get_block, wbc); } |
7c0efc627 hfsplus: convert ... |
29 30 31 |
static int hfsplus_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata) |
1da177e4c Linux-2.6.12-rc2 |
32 |
{ |
282dc1788 get rid of cont_w... |
33 |
int ret; |
7c0efc627 hfsplus: convert ... |
34 |
*pagep = NULL; |
282dc1788 get rid of cont_w... |
35 |
ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
7c0efc627 hfsplus: convert ... |
36 |
hfsplus_get_block, |
6af502de2 hfsplus: fix HFSP... |
37 |
&HFSPLUS_I(mapping->host)->phys_size); |
282dc1788 get rid of cont_w... |
38 39 40 41 42 43 44 |
if (unlikely(ret)) { loff_t isize = mapping->host->i_size; if (pos + len > isize) vmtruncate(mapping->host, isize); } return ret; |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 49 50 |
} static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block) { return generic_block_bmap(mapping, block, hfsplus_get_block); } |
27496a8c6 [PATCH] gfp_t: fs/* |
51 |
static int hfsplus_releasepage(struct page *page, gfp_t mask) |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 56 57 58 59 60 61 |
{ struct inode *inode = page->mapping->host; struct super_block *sb = inode->i_sb; struct hfs_btree *tree; struct hfs_bnode *node; u32 nidx; int i, res = 1; switch (inode->i_ino) { case HFSPLUS_EXT_CNID: |
dd73a01a3 hfsplus: fix HFSP... |
62 |
tree = HFSPLUS_SB(sb)->ext_tree; |
1da177e4c Linux-2.6.12-rc2 |
63 64 |
break; case HFSPLUS_CAT_CNID: |
dd73a01a3 hfsplus: fix HFSP... |
65 |
tree = HFSPLUS_SB(sb)->cat_tree; |
1da177e4c Linux-2.6.12-rc2 |
66 67 |
break; case HFSPLUS_ATTR_CNID: |
dd73a01a3 hfsplus: fix HFSP... |
68 |
tree = HFSPLUS_SB(sb)->attr_tree; |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 72 73 |
break; default: BUG(); return 0; } |
706322496 Fix hfsplus oops ... |
74 75 |
if (!tree) return 0; |
1da177e4c Linux-2.6.12-rc2 |
76 |
if (tree->node_size >= PAGE_CACHE_SIZE) { |
2753cc281 hfsplus: over 80 ... |
77 78 |
nidx = page->index >> (tree->node_size_shift - PAGE_CACHE_SHIFT); |
1da177e4c Linux-2.6.12-rc2 |
79 80 81 82 83 84 85 86 87 88 89 90 |
spin_lock(&tree->hash_lock); node = hfs_bnode_findhash(tree, nidx); if (!node) ; else if (atomic_read(&node->refcnt)) res = 0; if (res && node) { hfs_bnode_unhash(node); hfs_bnode_free(node); } spin_unlock(&tree->hash_lock); } else { |
2753cc281 hfsplus: over 80 ... |
91 92 |
nidx = page->index << (PAGE_CACHE_SHIFT - tree->node_size_shift); |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
i = 1 << (PAGE_CACHE_SHIFT - tree->node_size_shift); spin_lock(&tree->hash_lock); do { node = hfs_bnode_findhash(tree, nidx++); if (!node) continue; if (atomic_read(&node->refcnt)) { res = 0; break; } hfs_bnode_unhash(node); hfs_bnode_free(node); } while (--i && nidx < tree->node_count); spin_unlock(&tree->hash_lock); } |
1da177e4c Linux-2.6.12-rc2 |
108 109 |
return res ? try_to_free_buffers(page) : 0; } |
1da177e4c Linux-2.6.12-rc2 |
110 111 112 113 |
static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs) { struct file *file = iocb->ki_filp; |
f44ea0310 [PATCH] struct pa... |
114 |
struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host; |
eafdc7d19 sort out blockdev... |
115 |
ssize_t ret; |
1da177e4c Linux-2.6.12-rc2 |
116 |
|
aacfc19c6 fs: simplify the ... |
117 118 |
ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs, hfsplus_get_block); |
eafdc7d19 sort out blockdev... |
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
/* * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ if (unlikely((rw & WRITE) && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = offset + iov_length(iov, nr_segs); if (end > isize) vmtruncate(inode, isize); } return ret; |
1da177e4c Linux-2.6.12-rc2 |
133 134 135 136 137 138 139 |
} static int hfsplus_writepages(struct address_space *mapping, struct writeback_control *wbc) { return mpage_writepages(mapping, wbc, hfsplus_get_block); } |
f5e54d6e5 [PATCH] mark addr... |
140 |
const struct address_space_operations hfsplus_btree_aops = { |
1da177e4c Linux-2.6.12-rc2 |
141 142 |
.readpage = hfsplus_readpage, .writepage = hfsplus_writepage, |
7c0efc627 hfsplus: convert ... |
143 144 |
.write_begin = hfsplus_write_begin, .write_end = generic_write_end, |
1da177e4c Linux-2.6.12-rc2 |
145 146 147 |
.bmap = hfsplus_bmap, .releasepage = hfsplus_releasepage, }; |
f5e54d6e5 [PATCH] mark addr... |
148 |
const struct address_space_operations hfsplus_aops = { |
1da177e4c Linux-2.6.12-rc2 |
149 150 |
.readpage = hfsplus_readpage, .writepage = hfsplus_writepage, |
7c0efc627 hfsplus: convert ... |
151 152 |
.write_begin = hfsplus_write_begin, .write_end = generic_write_end, |
1da177e4c Linux-2.6.12-rc2 |
153 154 155 156 |
.bmap = hfsplus_bmap, .direct_IO = hfsplus_direct_IO, .writepages = hfsplus_writepages, }; |
e16404ed0 constify dentry_o... |
157 |
const struct dentry_operations hfsplus_dentry_operations = { |
d45bce8fa HFS+: add custom ... |
158 159 160 |
.d_hash = hfsplus_hash_dentry, .d_compare = hfsplus_compare_dentry, }; |
2753cc281 hfsplus: over 80 ... |
161 162 |
static struct dentry *hfsplus_file_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
1da177e4c Linux-2.6.12-rc2 |
163 164 165 166 |
{ struct hfs_find_data fd; struct super_block *sb = dir->i_sb; struct inode *inode = NULL; |
6af502de2 hfsplus: fix HFSP... |
167 |
struct hfsplus_inode_info *hip; |
1da177e4c Linux-2.6.12-rc2 |
168 169 170 171 |
int err; if (HFSPLUS_IS_RSRC(dir) || strcmp(dentry->d_name.name, "rsrc")) goto out; |
6af502de2 hfsplus: fix HFSP... |
172 |
inode = HFSPLUS_I(dir)->rsrc_inode; |
1da177e4c Linux-2.6.12-rc2 |
173 174 175 176 177 178 |
if (inode) goto out; inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); |
6af502de2 hfsplus: fix HFSP... |
179 |
hip = HFSPLUS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
180 |
inode->i_ino = dir->i_ino; |
6af502de2 hfsplus: fix HFSP... |
181 182 |
INIT_LIST_HEAD(&hip->open_dir_list); mutex_init(&hip->extents_lock); |
b33b7921d hfsplus: split up... |
183 184 185 |
hip->extent_state = 0; hip->flags = 0; set_bit(HFSPLUS_I_RSRC, &hip->flags); |
1da177e4c Linux-2.6.12-rc2 |
186 |
|
5bd9d99d1 hfsplus: add erro... |
187 188 189 190 191 192 193 |
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); if (!err) { err = hfsplus_find_cat(sb, dir->i_ino, &fd); if (!err) err = hfsplus_cat_read_inode(inode, &fd); hfs_find_exit(&fd); } |
1da177e4c Linux-2.6.12-rc2 |
194 195 196 197 |
if (err) { iput(inode); return ERR_PTR(err); } |
6af502de2 hfsplus: fix HFSP... |
198 199 |
hip->rsrc_inode = dir; HFSPLUS_I(dir)->rsrc_inode = inode; |
1da177e4c Linux-2.6.12-rc2 |
200 |
igrab(dir); |
58a818f53 hfsplus: remove t... |
201 202 203 204 205 206 207 |
/* * __mark_inode_dirty expects inodes to be hashed. Since we don't * want resource fork inodes in the regular inode space, we make them * appear hashed, but do not put on any lists. hlist_del() * will work fine and require no locking. */ |
756acc2d6 list.h: new helpe... |
208 |
hlist_add_fake(&inode->i_hash); |
58a818f53 hfsplus: remove t... |
209 |
|
1da177e4c Linux-2.6.12-rc2 |
210 |
mark_inode_dirty(inode); |
1da177e4c Linux-2.6.12-rc2 |
211 212 213 214 |
out: d_add(dentry, inode); return NULL; } |
2753cc281 hfsplus: over 80 ... |
215 216 |
static void hfsplus_get_perms(struct inode *inode, struct hfsplus_perm *perms, int dir) |
1da177e4c Linux-2.6.12-rc2 |
217 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
218 |
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
219 220 221 222 223 224 |
u16 mode; mode = be16_to_cpu(perms->mode); inode->i_uid = be32_to_cpu(perms->owner); if (!inode->i_uid && !mode) |
dd73a01a3 hfsplus: fix HFSP... |
225 |
inode->i_uid = sbi->uid; |
1da177e4c Linux-2.6.12-rc2 |
226 227 228 |
inode->i_gid = be32_to_cpu(perms->group); if (!inode->i_gid && !mode) |
dd73a01a3 hfsplus: fix HFSP... |
229 |
inode->i_gid = sbi->gid; |
1da177e4c Linux-2.6.12-rc2 |
230 231 |
if (dir) { |
dd73a01a3 hfsplus: fix HFSP... |
232 |
mode = mode ? (mode & S_IALLUGO) : (S_IRWXUGO & ~(sbi->umask)); |
1da177e4c Linux-2.6.12-rc2 |
233 234 |
mode |= S_IFDIR; } else if (!mode) |
dd73a01a3 hfsplus: fix HFSP... |
235 |
mode = S_IFREG | ((S_IRUGO|S_IWUGO) & ~(sbi->umask)); |
1da177e4c Linux-2.6.12-rc2 |
236 |
inode->i_mode = mode; |
6af502de2 hfsplus: fix HFSP... |
237 |
HFSPLUS_I(inode)->userflags = perms->userflags; |
1da177e4c Linux-2.6.12-rc2 |
238 239 240 241 242 243 244 245 246 |
if (perms->rootflags & HFSPLUS_FLG_IMMUTABLE) inode->i_flags |= S_IMMUTABLE; else inode->i_flags &= ~S_IMMUTABLE; if (perms->rootflags & HFSPLUS_FLG_APPEND) inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; } |
1da177e4c Linux-2.6.12-rc2 |
247 248 249 |
static int hfsplus_file_open(struct inode *inode, struct file *file) { if (HFSPLUS_IS_RSRC(inode)) |
6af502de2 hfsplus: fix HFSP... |
250 |
inode = HFSPLUS_I(inode)->rsrc_inode; |
6e7152944 hfsplus: missing ... |
251 252 |
if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) return -EOVERFLOW; |
6af502de2 hfsplus: fix HFSP... |
253 |
atomic_inc(&HFSPLUS_I(inode)->opencnt); |
1da177e4c Linux-2.6.12-rc2 |
254 255 256 257 258 259 260 261 |
return 0; } static int hfsplus_file_release(struct inode *inode, struct file *file) { struct super_block *sb = inode->i_sb; if (HFSPLUS_IS_RSRC(inode)) |
6af502de2 hfsplus: fix HFSP... |
262 263 |
inode = HFSPLUS_I(inode)->rsrc_inode; if (atomic_dec_and_test(&HFSPLUS_I(inode)->opencnt)) { |
1b1dcc1b5 [PATCH] mutex sub... |
264 |
mutex_lock(&inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
265 266 |
hfsplus_file_truncate(inode); if (inode->i_flags & S_DEAD) { |
dd73a01a3 hfsplus: fix HFSP... |
267 268 |
hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb)->hidden_dir, NULL); |
1da177e4c Linux-2.6.12-rc2 |
269 270 |
hfsplus_delete_inode(inode); } |
1b1dcc1b5 [PATCH] mutex sub... |
271 |
mutex_unlock(&inode->i_mutex); |
1da177e4c Linux-2.6.12-rc2 |
272 273 274 |
} return 0; } |
d39aae9ec add missing setat... |
275 276 277 278 279 280 281 282 |
static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; int error; error = inode_change_ok(inode, attr); if (error) return error; |
1025774ce remove inode_setattr |
283 284 285 |
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { |
562c72aa5 fs: move inode_di... |
286 |
inode_dio_wait(inode); |
1025774ce remove inode_setattr |
287 288 289 290 291 292 293 294 |
error = vmtruncate(inode, attr->ia_size); if (error) return error; } setattr_copy(inode, attr); mark_inode_dirty(inode); return 0; |
d39aae9ec add missing setat... |
295 |
} |
02c24a821 fs: push i_mutex ... |
296 297 |
int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
b5fc510c4 get rid of file_f... |
298 |
{ |
281469766 hfsplus: simplify... |
299 |
struct inode *inode = file->f_mapping->host; |
e34947056 hfsplus: optimize... |
300 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
281469766 hfsplus: simplify... |
301 |
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); |
e34947056 hfsplus: optimize... |
302 |
int error = 0, error2; |
b5fc510c4 get rid of file_f... |
303 |
|
02c24a821 fs: push i_mutex ... |
304 305 306 307 |
error = filemap_write_and_wait_range(inode->i_mapping, start, end); if (error) return error; mutex_lock(&inode->i_mutex); |
281469766 hfsplus: simplify... |
308 309 310 311 312 313 314 315 |
/* * Sync inode metadata into the catalog and extent trees. */ sync_inode_metadata(inode, 1); /* * And explicitly write out the btrees. */ |
e34947056 hfsplus: optimize... |
316 317 318 319 |
if (test_and_clear_bit(HFSPLUS_I_CAT_DIRTY, &hip->flags)) error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); if (test_and_clear_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags)) { |
2753cc281 hfsplus: over 80 ... |
320 321 |
error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); |
e34947056 hfsplus: optimize... |
322 323 324 325 326 327 328 329 330 |
if (!error) error = error2; } if (test_and_clear_bit(HFSPLUS_I_ALLOC_DIRTY, &hip->flags)) { error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); if (!error) error = error2; } |
34a2d313c hfsplus: flush di... |
331 332 |
if (!test_bit(HFSPLUS_SB_NOBARRIER, &sbi->flags)) blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL); |
02c24a821 fs: push i_mutex ... |
333 |
mutex_unlock(&inode->i_mutex); |
281469766 hfsplus: simplify... |
334 |
return error; |
b5fc510c4 get rid of file_f... |
335 |
} |
92e1d5be9 [PATCH] mark stru... |
336 |
static const struct inode_operations hfsplus_file_inode_operations = { |
1da177e4c Linux-2.6.12-rc2 |
337 338 |
.lookup = hfsplus_file_lookup, .truncate = hfsplus_file_truncate, |
d39aae9ec add missing setat... |
339 |
.setattr = hfsplus_setattr, |
1da177e4c Linux-2.6.12-rc2 |
340 341 342 343 |
.setxattr = hfsplus_setxattr, .getxattr = hfsplus_getxattr, .listxattr = hfsplus_listxattr, }; |
4b6f5d20b [PATCH] Make most... |
344 |
static const struct file_operations hfsplus_file_operations = { |
20b7643d8 hfsplus: spaces/i... |
345 |
.llseek = generic_file_llseek, |
543ade1fc [PATCH] Streamlin... |
346 347 348 349 |
.read = do_sync_read, .aio_read = generic_file_aio_read, .write = do_sync_write, .aio_write = generic_file_aio_write, |
1da177e4c Linux-2.6.12-rc2 |
350 |
.mmap = generic_file_mmap, |
5ffc4ef45 sendfile: remove ... |
351 |
.splice_read = generic_file_splice_read, |
b5fc510c4 get rid of file_f... |
352 |
.fsync = hfsplus_file_fsync, |
1da177e4c Linux-2.6.12-rc2 |
353 354 |
.open = hfsplus_file_open, .release = hfsplus_file_release, |
7cc4bcc6f hfsplus: Push dow... |
355 |
.unlocked_ioctl = hfsplus_ioctl, |
1da177e4c Linux-2.6.12-rc2 |
356 |
}; |
c47da7985 hfsplus: propagat... |
357 |
struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
358 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
359 |
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
360 |
struct inode *inode = new_inode(sb); |
6af502de2 hfsplus: fix HFSP... |
361 |
struct hfsplus_inode_info *hip; |
dd73a01a3 hfsplus: fix HFSP... |
362 |
|
1da177e4c Linux-2.6.12-rc2 |
363 364 |
if (!inode) return NULL; |
dd73a01a3 hfsplus: fix HFSP... |
365 |
inode->i_ino = sbi->next_cnid++; |
1da177e4c Linux-2.6.12-rc2 |
366 |
inode->i_mode = mode; |
4ac8489a7 CRED: Wrap task c... |
367 368 |
inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); |
bfe868486 filesystems: add ... |
369 |
set_nlink(inode, 1); |
1da177e4c Linux-2.6.12-rc2 |
370 |
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
6af502de2 hfsplus: fix HFSP... |
371 372 373 374 375 |
hip = HFSPLUS_I(inode); INIT_LIST_HEAD(&hip->open_dir_list); mutex_init(&hip->extents_lock); atomic_set(&hip->opencnt, 0); |
b33b7921d hfsplus: split up... |
376 |
hip->extent_state = 0; |
6af502de2 hfsplus: fix HFSP... |
377 378 379 380 381 382 383 384 385 386 |
hip->flags = 0; memset(hip->first_extents, 0, sizeof(hfsplus_extent_rec)); memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); hip->alloc_blocks = 0; hip->first_blocks = 0; hip->cached_start = 0; hip->cached_blocks = 0; hip->phys_size = 0; hip->fs_blocks = 0; hip->rsrc_inode = NULL; |
1da177e4c Linux-2.6.12-rc2 |
387 388 |
if (S_ISDIR(inode->i_mode)) { inode->i_size = 2; |
dd73a01a3 hfsplus: fix HFSP... |
389 |
sbi->folder_count++; |
1da177e4c Linux-2.6.12-rc2 |
390 391 392 |
inode->i_op = &hfsplus_dir_inode_operations; inode->i_fop = &hfsplus_dir_operations; } else if (S_ISREG(inode->i_mode)) { |
dd73a01a3 hfsplus: fix HFSP... |
393 |
sbi->file_count++; |
1da177e4c Linux-2.6.12-rc2 |
394 395 396 |
inode->i_op = &hfsplus_file_inode_operations; inode->i_fop = &hfsplus_file_operations; inode->i_mapping->a_ops = &hfsplus_aops; |
6af502de2 hfsplus: fix HFSP... |
397 |
hip->clump_blocks = sbi->data_clump_blocks; |
1da177e4c Linux-2.6.12-rc2 |
398 |
} else if (S_ISLNK(inode->i_mode)) { |
dd73a01a3 hfsplus: fix HFSP... |
399 |
sbi->file_count++; |
1da177e4c Linux-2.6.12-rc2 |
400 401 |
inode->i_op = &page_symlink_inode_operations; inode->i_mapping->a_ops = &hfsplus_aops; |
6af502de2 hfsplus: fix HFSP... |
402 |
hip->clump_blocks = 1; |
1da177e4c Linux-2.6.12-rc2 |
403 |
} else |
dd73a01a3 hfsplus: fix HFSP... |
404 |
sbi->file_count++; |
1da177e4c Linux-2.6.12-rc2 |
405 406 407 408 409 410 411 412 413 414 415 416 |
insert_inode_hash(inode); mark_inode_dirty(inode); sb->s_dirt = 1; return inode; } void hfsplus_delete_inode(struct inode *inode) { struct super_block *sb = inode->i_sb; if (S_ISDIR(inode->i_mode)) { |
dd73a01a3 hfsplus: fix HFSP... |
417 |
HFSPLUS_SB(sb)->folder_count--; |
1da177e4c Linux-2.6.12-rc2 |
418 419 420 |
sb->s_dirt = 1; return; } |
dd73a01a3 hfsplus: fix HFSP... |
421 |
HFSPLUS_SB(sb)->file_count--; |
1da177e4c Linux-2.6.12-rc2 |
422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
if (S_ISREG(inode->i_mode)) { if (!inode->i_nlink) { inode->i_size = 0; hfsplus_file_truncate(inode); } } else if (S_ISLNK(inode->i_mode)) { inode->i_size = 0; hfsplus_file_truncate(inode); } sb->s_dirt = 1; } void hfsplus_inode_read_fork(struct inode *inode, struct hfsplus_fork_raw *fork) { struct super_block *sb = inode->i_sb; |
dd73a01a3 hfsplus: fix HFSP... |
437 |
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); |
6af502de2 hfsplus: fix HFSP... |
438 |
struct hfsplus_inode_info *hip = HFSPLUS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
439 440 |
u32 count; int i; |
6af502de2 hfsplus: fix HFSP... |
441 |
memcpy(&hip->first_extents, &fork->extents, sizeof(hfsplus_extent_rec)); |
1da177e4c Linux-2.6.12-rc2 |
442 443 |
for (count = 0, i = 0; i < 8; i++) count += be32_to_cpu(fork->extents[i].block_count); |
6af502de2 hfsplus: fix HFSP... |
444 445 446 447 448 449 450 451 452 453 454 |
hip->first_blocks = count; memset(hip->cached_extents, 0, sizeof(hfsplus_extent_rec)); hip->cached_start = 0; hip->cached_blocks = 0; hip->alloc_blocks = be32_to_cpu(fork->total_blocks); hip->phys_size = inode->i_size = be64_to_cpu(fork->total_size); hip->fs_blocks = (inode->i_size + sb->s_blocksize - 1) >> sb->s_blocksize_bits; inode_set_bytes(inode, hip->fs_blocks << sb->s_blocksize_bits); hip->clump_blocks = |
dd73a01a3 hfsplus: fix HFSP... |
455 |
be32_to_cpu(fork->clump_size) >> sbi->alloc_blksz_shift; |
6af502de2 hfsplus: fix HFSP... |
456 457 |
if (!hip->clump_blocks) { hip->clump_blocks = HFSPLUS_IS_RSRC(inode) ? |
dd73a01a3 hfsplus: fix HFSP... |
458 459 460 |
sbi->rsrc_clump_blocks : sbi->data_clump_blocks; } |
1da177e4c Linux-2.6.12-rc2 |
461 |
} |
2753cc281 hfsplus: over 80 ... |
462 463 |
void hfsplus_inode_write_fork(struct inode *inode, struct hfsplus_fork_raw *fork) |
1da177e4c Linux-2.6.12-rc2 |
464 |
{ |
6af502de2 hfsplus: fix HFSP... |
465 |
memcpy(&fork->extents, &HFSPLUS_I(inode)->first_extents, |
1da177e4c Linux-2.6.12-rc2 |
466 467 |
sizeof(hfsplus_extent_rec)); fork->total_size = cpu_to_be64(inode->i_size); |
6af502de2 hfsplus: fix HFSP... |
468 |
fork->total_blocks = cpu_to_be32(HFSPLUS_I(inode)->alloc_blocks); |
1da177e4c Linux-2.6.12-rc2 |
469 470 471 472 473 474 475 476 477 |
} int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) { hfsplus_cat_entry entry; int res = 0; u16 type; type = hfs_bnode_read_u16(fd->bnode, fd->entryoffset); |
f6089ff87 hfsplus: fix link... |
478 |
HFSPLUS_I(inode)->linkid = 0; |
1da177e4c Linux-2.6.12-rc2 |
479 480 481 482 483 484 485 486 |
if (type == HFSPLUS_FOLDER) { struct hfsplus_cat_folder *folder = &entry.folder; if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) /* panic? */; hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, sizeof(struct hfsplus_cat_folder)); hfsplus_get_perms(inode, &folder->permissions, 1); |
bfe868486 filesystems: add ... |
487 |
set_nlink(inode, 1); |
1da177e4c Linux-2.6.12-rc2 |
488 489 490 |
inode->i_size = 2 + be32_to_cpu(folder->valence); inode->i_atime = hfsp_mt2ut(folder->access_date); inode->i_mtime = hfsp_mt2ut(folder->content_mod_date); |
9a4cad95c [PATCH] hfs: set ... |
491 |
inode->i_ctime = hfsp_mt2ut(folder->attribute_mod_date); |
6af502de2 hfsplus: fix HFSP... |
492 493 |
HFSPLUS_I(inode)->create_date = folder->create_date; HFSPLUS_I(inode)->fs_blocks = 0; |
1da177e4c Linux-2.6.12-rc2 |
494 495 496 497 498 499 500 501 502 |
inode->i_op = &hfsplus_dir_inode_operations; inode->i_fop = &hfsplus_dir_operations; } else if (type == HFSPLUS_FILE) { struct hfsplus_cat_file *file = &entry.file; if (fd->entrylength < sizeof(struct hfsplus_cat_file)) /* panic? */; hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, sizeof(struct hfsplus_cat_file)); |
b33b7921d hfsplus: split up... |
503 504 |
hfsplus_inode_read_fork(inode, HFSPLUS_IS_RSRC(inode) ? &file->rsrc_fork : &file->data_fork); |
1da177e4c Linux-2.6.12-rc2 |
505 |
hfsplus_get_perms(inode, &file->permissions, 0); |
bfe868486 filesystems: add ... |
506 |
set_nlink(inode, 1); |
1da177e4c Linux-2.6.12-rc2 |
507 508 |
if (S_ISREG(inode->i_mode)) { if (file->permissions.dev) |
bfe868486 filesystems: add ... |
509 510 |
set_nlink(inode, be32_to_cpu(file->permissions.dev)); |
1da177e4c Linux-2.6.12-rc2 |
511 512 513 514 515 516 517 518 519 520 521 522 |
inode->i_op = &hfsplus_file_inode_operations; inode->i_fop = &hfsplus_file_operations; inode->i_mapping->a_ops = &hfsplus_aops; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &page_symlink_inode_operations; inode->i_mapping->a_ops = &hfsplus_aops; } else { init_special_inode(inode, inode->i_mode, be32_to_cpu(file->permissions.dev)); } inode->i_atime = hfsp_mt2ut(file->access_date); inode->i_mtime = hfsp_mt2ut(file->content_mod_date); |
9a4cad95c [PATCH] hfs: set ... |
523 |
inode->i_ctime = hfsp_mt2ut(file->attribute_mod_date); |
6af502de2 hfsplus: fix HFSP... |
524 |
HFSPLUS_I(inode)->create_date = file->create_date; |
1da177e4c Linux-2.6.12-rc2 |
525 |
} else { |
634725a92 [PATCH] hfs: clea... |
526 527 |
printk(KERN_ERR "hfs: bad catalog entry used to create inode "); |
1da177e4c Linux-2.6.12-rc2 |
528 529 530 531 532 533 534 535 536 537 538 539 |
res = -EIO; } return res; } int hfsplus_cat_write_inode(struct inode *inode) { struct inode *main_inode = inode; struct hfs_find_data fd; hfsplus_cat_entry entry; if (HFSPLUS_IS_RSRC(inode)) |
6af502de2 hfsplus: fix HFSP... |
540 |
main_inode = HFSPLUS_I(inode)->rsrc_inode; |
1da177e4c Linux-2.6.12-rc2 |
541 542 543 |
if (!main_inode->i_nlink) return 0; |
dd73a01a3 hfsplus: fix HFSP... |
544 |
if (hfs_find_init(HFSPLUS_SB(main_inode->i_sb)->cat_tree, &fd)) |
1da177e4c Linux-2.6.12-rc2 |
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
/* panic? */ return -EIO; if (hfsplus_find_cat(main_inode->i_sb, main_inode->i_ino, &fd)) /* panic? */ goto out; if (S_ISDIR(main_inode->i_mode)) { struct hfsplus_cat_folder *folder = &entry.folder; if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) /* panic? */; hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_folder)); /* simple node checks? */ |
90e616905 hfsplus: create c... |
560 |
hfsplus_cat_set_perms(inode, &folder->permissions); |
1da177e4c Linux-2.6.12-rc2 |
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
folder->access_date = hfsp_ut2mt(inode->i_atime); folder->content_mod_date = hfsp_ut2mt(inode->i_mtime); folder->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); folder->valence = cpu_to_be32(inode->i_size - 2); hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_folder)); } else if (HFSPLUS_IS_RSRC(inode)) { struct hfsplus_cat_file *file = &entry.file; hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); hfsplus_inode_write_fork(inode, &file->rsrc_fork); hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); } else { struct hfsplus_cat_file *file = &entry.file; if (fd.entrylength < sizeof(struct hfsplus_cat_file)) /* panic? */; hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); hfsplus_inode_write_fork(inode, &file->data_fork); |
90e616905 hfsplus: create c... |
582 |
hfsplus_cat_set_perms(inode, &file->permissions); |
2753cc281 hfsplus: over 80 ... |
583 584 585 |
if (HFSPLUS_FLG_IMMUTABLE & (file->permissions.rootflags | file->permissions.userflags)) |
1da177e4c Linux-2.6.12-rc2 |
586 587 588 589 590 591 592 593 594 |
file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); else file->flags &= cpu_to_be16(~HFSPLUS_FILE_LOCKED); file->access_date = hfsp_ut2mt(inode->i_atime); file->content_mod_date = hfsp_ut2mt(inode->i_mtime); file->attribute_mod_date = hfsp_ut2mt(inode->i_ctime); hfs_bnode_write(fd.bnode, &entry, fd.entryoffset, sizeof(struct hfsplus_cat_file)); } |
e34947056 hfsplus: optimize... |
595 596 |
set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); |
1da177e4c Linux-2.6.12-rc2 |
597 598 599 600 |
out: hfs_find_exit(&fd); return 0; } |