Blame view
fs/hfsplus/catalog.c
13.5 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 |
/* * linux/fs/hfsplus/catalog.c * * Copyright (C) 2001 * Brad Boyer (flar@allandria.com) * (C) 2003 Ardis Technologies <roman@ardistech.com> * * Handling of catalog records */ |
1da177e4c Linux-2.6.12-rc2 |
11 12 13 |
#include "hfsplus_fs.h" #include "hfsplus_raw.h" |
2179d372d [PATCH] hfs: add ... |
14 15 |
int hfsplus_cat_case_cmp_key(const hfsplus_btree_key *k1, const hfsplus_btree_key *k2) |
1da177e4c Linux-2.6.12-rc2 |
16 17 18 19 20 21 22 |
{ __be32 k1p, k2p; k1p = k1->cat.parent; k2p = k2->cat.parent; if (k1p != k2p) return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1; |
2179d372d [PATCH] hfs: add ... |
23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
return hfsplus_strcasecmp(&k1->cat.name, &k2->cat.name); } int hfsplus_cat_bin_cmp_key(const hfsplus_btree_key *k1, const hfsplus_btree_key *k2) { __be32 k1p, k2p; k1p = k1->cat.parent; k2p = k2->cat.parent; if (k1p != k2p) return be32_to_cpu(k1p) < be32_to_cpu(k2p) ? -1 : 1; return hfsplus_strcmp(&k1->cat.name, &k2->cat.name); |
1da177e4c Linux-2.6.12-rc2 |
37 |
} |
89ac9b4d3 hfsplus: fix long... |
38 39 |
/* Generates key for catalog file/folders record. */ int hfsplus_cat_build_key(struct super_block *sb, |
b5cce521e qstr: constify in... |
40 |
hfsplus_btree_key *key, u32 parent, const struct qstr *str) |
1da177e4c Linux-2.6.12-rc2 |
41 |
{ |
89ac9b4d3 hfsplus: fix long... |
42 |
int len, err; |
1da177e4c Linux-2.6.12-rc2 |
43 44 |
key->cat.parent = cpu_to_be32(parent); |
89ac9b4d3 hfsplus: fix long... |
45 46 47 48 49 50 |
err = hfsplus_asc2uni(sb, &key->cat.name, HFSPLUS_MAX_STRLEN, str->name, str->len); if (unlikely(err < 0)) return err; len = be16_to_cpu(key->cat.name.length); |
1da177e4c Linux-2.6.12-rc2 |
51 |
key->key_len = cpu_to_be16(6 + 2 * len); |
89ac9b4d3 hfsplus: fix long... |
52 53 54 55 56 57 58 59 60 61 |
return 0; } /* Generates key for catalog thread record. */ void hfsplus_cat_build_key_with_cnid(struct super_block *sb, hfsplus_btree_key *key, u32 parent) { key->cat.parent = cpu_to_be32(parent); key->cat.name.length = 0; key->key_len = cpu_to_be16(6); |
1da177e4c Linux-2.6.12-rc2 |
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
} static void hfsplus_cat_build_key_uni(hfsplus_btree_key *key, u32 parent, struct hfsplus_unistr *name) { int ustrlen; ustrlen = be16_to_cpu(name->length); key->cat.parent = cpu_to_be32(parent); key->cat.name.length = cpu_to_be16(ustrlen); ustrlen *= 2; memcpy(key->cat.name.unicode, name->unicode, ustrlen); key->key_len = cpu_to_be16(6 + ustrlen); } |
90e616905 hfsplus: create c... |
76 |
void hfsplus_cat_set_perms(struct inode *inode, struct hfsplus_perm *perms) |
1da177e4c Linux-2.6.12-rc2 |
77 78 79 80 81 82 83 84 85 |
{ if (inode->i_flags & S_IMMUTABLE) perms->rootflags |= HFSPLUS_FLG_IMMUTABLE; else perms->rootflags &= ~HFSPLUS_FLG_IMMUTABLE; if (inode->i_flags & S_APPEND) perms->rootflags |= HFSPLUS_FLG_APPEND; else perms->rootflags &= ~HFSPLUS_FLG_APPEND; |
90e616905 hfsplus: create c... |
86 87 |
perms->userflags = HFSPLUS_I(inode)->userflags; |
1da177e4c Linux-2.6.12-rc2 |
88 |
perms->mode = cpu_to_be16(inode->i_mode); |
16525e3f1 userns: Convert h... |
89 90 |
perms->owner = cpu_to_be32(i_uid_read(inode)); perms->group = cpu_to_be32(i_gid_read(inode)); |
90e616905 hfsplus: create c... |
91 92 93 94 95 96 97 |
if (S_ISREG(inode->i_mode)) perms->dev = cpu_to_be32(inode->i_nlink); else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) perms->dev = cpu_to_be32(inode->i_rdev); else perms->dev = 0; |
1da177e4c Linux-2.6.12-rc2 |
98 |
} |
2753cc281 hfsplus: over 80 ... |
99 100 |
static int hfsplus_cat_build_record(hfsplus_cat_entry *entry, u32 cnid, struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
101 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
102 |
struct hfsplus_sb_info *sbi = HFSPLUS_SB(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
103 104 105 106 107 108 |
if (S_ISDIR(inode->i_mode)) { struct hfsplus_cat_folder *folder; folder = &entry->folder; memset(folder, 0, sizeof(*folder)); folder->type = cpu_to_be16(HFSPLUS_FOLDER); |
d7d673a59 hfsplus: add HFSX... |
109 110 |
if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) folder->flags |= cpu_to_be16(HFSPLUS_HAS_FOLDER_COUNT); |
1da177e4c Linux-2.6.12-rc2 |
111 |
folder->id = cpu_to_be32(inode->i_ino); |
6af502de2 hfsplus: fix HFSP... |
112 |
HFSPLUS_I(inode)->create_date = |
9a4cad95c [PATCH] hfs: set ... |
113 114 115 116 |
folder->create_date = folder->content_mod_date = folder->attribute_mod_date = folder->access_date = hfsp_now2mt(); |
90e616905 hfsplus: create c... |
117 |
hfsplus_cat_set_perms(inode, &folder->permissions); |
dd73a01a3 hfsplus: fix HFSP... |
118 |
if (inode == sbi->hidden_dir) |
1da177e4c Linux-2.6.12-rc2 |
119 120 121 122 123 124 125 126 127 128 129 |
/* invisible and namelocked */ folder->user_info.frFlags = cpu_to_be16(0x5000); return sizeof(*folder); } else { struct hfsplus_cat_file *file; file = &entry->file; memset(file, 0, sizeof(*file)); file->type = cpu_to_be16(HFSPLUS_FILE); file->flags = cpu_to_be16(HFSPLUS_FILE_THREAD_EXISTS); file->id = cpu_to_be32(cnid); |
6af502de2 hfsplus: fix HFSP... |
130 |
HFSPLUS_I(inode)->create_date = |
9a4cad95c [PATCH] hfs: set ... |
131 132 133 134 |
file->create_date = file->content_mod_date = file->attribute_mod_date = file->access_date = hfsp_now2mt(); |
1da177e4c Linux-2.6.12-rc2 |
135 |
if (cnid == inode->i_ino) { |
90e616905 hfsplus: create c... |
136 |
hfsplus_cat_set_perms(inode, &file->permissions); |
6b192832d [PATCH] hfs: set ... |
137 |
if (S_ISLNK(inode->i_mode)) { |
2753cc281 hfsplus: over 80 ... |
138 139 140 141 |
file->user_info.fdType = cpu_to_be32(HFSP_SYMLINK_TYPE); file->user_info.fdCreator = cpu_to_be32(HFSP_SYMLINK_CREATOR); |
6b192832d [PATCH] hfs: set ... |
142 |
} else { |
2753cc281 hfsplus: over 80 ... |
143 144 145 146 |
file->user_info.fdType = cpu_to_be32(sbi->type); file->user_info.fdCreator = cpu_to_be32(sbi->creator); |
6b192832d [PATCH] hfs: set ... |
147 |
} |
2753cc281 hfsplus: over 80 ... |
148 149 150 151 152 |
if (HFSPLUS_FLG_IMMUTABLE & (file->permissions.rootflags | file->permissions.userflags)) file->flags |= cpu_to_be16(HFSPLUS_FILE_LOCKED); |
1da177e4c Linux-2.6.12-rc2 |
153 |
} else { |
2753cc281 hfsplus: over 80 ... |
154 155 156 157 158 159 160 161 162 163 |
file->user_info.fdType = cpu_to_be32(HFSP_HARDLINK_TYPE); file->user_info.fdCreator = cpu_to_be32(HFSP_HFSPLUS_CREATOR); file->user_info.fdFlags = cpu_to_be16(0x100); file->create_date = HFSPLUS_I(sbi->hidden_dir)->create_date; file->permissions.dev = cpu_to_be32(HFSPLUS_I(inode)->linkid); |
1da177e4c Linux-2.6.12-rc2 |
164 165 166 167 168 169 170 |
} return sizeof(*file); } } static int hfsplus_fill_cat_thread(struct super_block *sb, hfsplus_cat_entry *entry, int type, |
b5cce521e qstr: constify in... |
171 |
u32 parentid, const struct qstr *str) |
1da177e4c Linux-2.6.12-rc2 |
172 |
{ |
89ac9b4d3 hfsplus: fix long... |
173 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
174 175 176 |
entry->type = cpu_to_be16(type); entry->thread.reserved = 0; entry->thread.parentID = cpu_to_be32(parentid); |
89ac9b4d3 hfsplus: fix long... |
177 |
err = hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN, |
324ef39a8 hfsplus: add supp... |
178 |
str->name, str->len); |
89ac9b4d3 hfsplus: fix long... |
179 180 |
if (unlikely(err < 0)) return err; |
1da177e4c Linux-2.6.12-rc2 |
181 182 183 184 185 186 187 188 189 190 |
return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2; } /* Try to get a catalog entry for given catalog id */ int hfsplus_find_cat(struct super_block *sb, u32 cnid, struct hfs_find_data *fd) { hfsplus_cat_entry tmp; int err; u16 type; |
89ac9b4d3 hfsplus: fix long... |
191 |
hfsplus_cat_build_key_with_cnid(sb, fd->search_key, cnid); |
1da177e4c Linux-2.6.12-rc2 |
192 193 194 195 196 197 |
err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry)); if (err) return err; type = be16_to_cpu(tmp.type); if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) { |
d61426732 hfs/hfsplus: conv... |
198 199 |
pr_err("found bad thread record in catalog "); |
1da177e4c Linux-2.6.12-rc2 |
200 201 |
return -EIO; } |
efc7ffcb4 hfsplus: fix Buff... |
202 |
if (be16_to_cpu(tmp.thread.nodeName.length) > 255) { |
d61426732 hfs/hfsplus: conv... |
203 204 |
pr_err("catalog name length corrupted "); |
efc7ffcb4 hfsplus: fix Buff... |
205 206 |
return -EIO; } |
2753cc281 hfsplus: over 80 ... |
207 208 209 |
hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID), &tmp.thread.nodeName); |
324ef39a8 hfsplus: add supp... |
210 |
return hfs_brec_find(fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
211 |
} |
d7d673a59 hfsplus: add HFSX... |
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
static void hfsplus_subfolders_inc(struct inode *dir) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { /* * Increment subfolder count. Note, the value is only meaningful * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set. */ HFSPLUS_I(dir)->subfolders++; } } static void hfsplus_subfolders_dec(struct inode *dir) { struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb); if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) { /* * Decrement subfolder count. Note, the value is only meaningful * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set. * * Check for zero. Some subfolders may have been created * by an implementation ignorant of this counter. */ if (HFSPLUS_I(dir)->subfolders) HFSPLUS_I(dir)->subfolders--; } } |
2753cc281 hfsplus: over 80 ... |
241 |
int hfsplus_create_cat(u32 cnid, struct inode *dir, |
b5cce521e qstr: constify in... |
242 |
const struct qstr *str, struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
243 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
244 |
struct super_block *sb = dir->i_sb; |
1da177e4c Linux-2.6.12-rc2 |
245 |
struct hfs_find_data fd; |
1da177e4c Linux-2.6.12-rc2 |
246 247 248 |
hfsplus_cat_entry entry; int entry_size; int err; |
c2b3e1f76 hfs/hfsplus: conv... |
249 250 |
hfs_dbg(CAT_MOD, "create_cat: %s,%u(%d) ", |
2753cc281 hfsplus: over 80 ... |
251 |
str->name, cnid, inode->i_nlink); |
5bd9d99d1 hfsplus: add erro... |
252 253 254 |
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
255 |
|
89ac9b4d3 hfsplus: fix long... |
256 |
hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
2753cc281 hfsplus: over 80 ... |
257 258 |
entry_size = hfsplus_fill_cat_thread(sb, &entry, S_ISDIR(inode->i_mode) ? |
1da177e4c Linux-2.6.12-rc2 |
259 |
HFSPLUS_FOLDER_THREAD : HFSPLUS_FILE_THREAD, |
2753cc281 hfsplus: over 80 ... |
260 |
dir->i_ino, str); |
89ac9b4d3 hfsplus: fix long... |
261 262 263 264 |
if (unlikely(entry_size < 0)) { err = entry_size; goto err2; } |
324ef39a8 hfsplus: add supp... |
265 |
err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
266 267 268 269 270 271 272 273 |
if (err != -ENOENT) { if (!err) err = -EEXIST; goto err2; } err = hfs_brec_insert(&fd, &entry, entry_size); if (err) goto err2; |
89ac9b4d3 hfsplus: fix long... |
274 275 276 |
err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); if (unlikely(err)) goto err1; |
1da177e4c Linux-2.6.12-rc2 |
277 |
entry_size = hfsplus_cat_build_record(&entry, cnid, inode); |
324ef39a8 hfsplus: add supp... |
278 |
err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
279 280 281 282 283 284 285 286 287 288 289 |
if (err != -ENOENT) { /* panic? */ if (!err) err = -EEXIST; goto err1; } err = hfs_brec_insert(&fd, &entry, entry_size); if (err) goto err1; dir->i_size++; |
d7d673a59 hfsplus: add HFSX... |
290 291 |
if (S_ISDIR(inode->i_mode)) hfsplus_subfolders_inc(dir); |
02027d42c fs: Replace CURRE... |
292 |
dir->i_mtime = dir->i_ctime = current_time(dir); |
e34947056 hfsplus: optimize... |
293 |
hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); |
1da177e4c Linux-2.6.12-rc2 |
294 295 296 297 |
hfs_find_exit(&fd); return 0; err1: |
89ac9b4d3 hfsplus: fix long... |
298 |
hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
324ef39a8 hfsplus: add supp... |
299 |
if (!hfs_brec_find(&fd, hfs_find_rec_by_key)) |
1da177e4c Linux-2.6.12-rc2 |
300 301 302 303 304 |
hfs_brec_remove(&fd); err2: hfs_find_exit(&fd); return err; } |
b5cce521e qstr: constify in... |
305 |
int hfsplus_delete_cat(u32 cnid, struct inode *dir, const struct qstr *str) |
1da177e4c Linux-2.6.12-rc2 |
306 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
307 |
struct super_block *sb = dir->i_sb; |
1da177e4c Linux-2.6.12-rc2 |
308 309 310 311 312 |
struct hfs_find_data fd; struct hfsplus_fork_raw fork; struct list_head *pos; int err, off; u16 type; |
c2b3e1f76 hfs/hfsplus: conv... |
313 314 |
hfs_dbg(CAT_MOD, "delete_cat: %s,%u ", str ? str->name : NULL, cnid); |
5bd9d99d1 hfsplus: add erro... |
315 316 317 |
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
318 319 320 |
if (!str) { int len; |
89ac9b4d3 hfsplus: fix long... |
321 |
hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
324ef39a8 hfsplus: add supp... |
322 |
err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
323 324 |
if (err) goto out; |
2753cc281 hfsplus: over 80 ... |
325 326 |
off = fd.entryoffset + offsetof(struct hfsplus_cat_thread, nodeName); |
1da177e4c Linux-2.6.12-rc2 |
327 |
fd.search_key->cat.parent = cpu_to_be32(dir->i_ino); |
2753cc281 hfsplus: over 80 ... |
328 329 |
hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.length, off, 2); |
1da177e4c Linux-2.6.12-rc2 |
330 |
len = be16_to_cpu(fd.search_key->cat.name.length) * 2; |
2753cc281 hfsplus: over 80 ... |
331 332 333 |
hfs_bnode_read(fd.bnode, &fd.search_key->cat.name.unicode, off + 2, len); |
1da177e4c Linux-2.6.12-rc2 |
334 |
fd.search_key->key_len = cpu_to_be16(6 + len); |
f01fa5fb3 hfsplus: add miss... |
335 |
} else { |
89ac9b4d3 hfsplus: fix long... |
336 337 338 |
err = hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, str); if (unlikely(err)) goto out; |
f01fa5fb3 hfsplus: add miss... |
339 |
} |
1da177e4c Linux-2.6.12-rc2 |
340 |
|
324ef39a8 hfsplus: add supp... |
341 |
err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
342 343 344 345 346 347 348 349 350 351 |
if (err) goto out; type = hfs_bnode_read_u16(fd.bnode, fd.entryoffset); if (type == HFSPLUS_FILE) { #if 0 off = fd.entryoffset + offsetof(hfsplus_cat_file, data_fork); hfs_bnode_read(fd.bnode, &fork, off, sizeof(fork)); hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_DATA); #endif |
2753cc281 hfsplus: over 80 ... |
352 353 |
off = fd.entryoffset + offsetof(struct hfsplus_cat_file, rsrc_fork); |
1da177e4c Linux-2.6.12-rc2 |
354 355 356 |
hfs_bnode_read(fd.bnode, &fork, off, sizeof(fork)); hfsplus_free_fork(sb, cnid, &fork, HFSPLUS_TYPE_RSRC); } |
323ee8fc5 hfsplus: switch t... |
357 358 |
/* we only need to take spinlock for exclusion with ->release() */ spin_lock(&HFSPLUS_I(dir)->open_dir_lock); |
6af502de2 hfsplus: fix HFSP... |
359 |
list_for_each(pos, &HFSPLUS_I(dir)->open_dir_list) { |
1da177e4c Linux-2.6.12-rc2 |
360 361 362 363 364 |
struct hfsplus_readdir_data *rd = list_entry(pos, struct hfsplus_readdir_data, list); if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0) rd->file->f_pos--; } |
323ee8fc5 hfsplus: switch t... |
365 |
spin_unlock(&HFSPLUS_I(dir)->open_dir_lock); |
1da177e4c Linux-2.6.12-rc2 |
366 367 368 369 |
err = hfs_brec_remove(&fd); if (err) goto out; |
89ac9b4d3 hfsplus: fix long... |
370 |
hfsplus_cat_build_key_with_cnid(sb, fd.search_key, cnid); |
324ef39a8 hfsplus: add supp... |
371 |
err = hfs_brec_find(&fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
372 373 374 375 376 377 378 379 |
if (err) goto out; err = hfs_brec_remove(&fd); if (err) goto out; dir->i_size--; |
d7d673a59 hfsplus: add HFSX... |
380 381 |
if (type == HFSPLUS_FOLDER) hfsplus_subfolders_dec(dir); |
02027d42c fs: Replace CURRE... |
382 |
dir->i_mtime = dir->i_ctime = current_time(dir); |
e34947056 hfsplus: optimize... |
383 |
hfsplus_mark_inode_dirty(dir, HFSPLUS_I_CAT_DIRTY); |
324ef39a8 hfsplus: add supp... |
384 385 386 387 388 |
if (type == HFSPLUS_FILE || type == HFSPLUS_FOLDER) { if (HFSPLUS_SB(sb)->attr_tree) hfsplus_delete_all_attrs(dir, cnid); } |
1da177e4c Linux-2.6.12-rc2 |
389 390 391 392 393 394 395 |
out: hfs_find_exit(&fd); return err; } int hfsplus_rename_cat(u32 cnid, |
b5cce521e qstr: constify in... |
396 397 |
struct inode *src_dir, const struct qstr *src_name, struct inode *dst_dir, const struct qstr *dst_name) |
1da177e4c Linux-2.6.12-rc2 |
398 |
{ |
dd73a01a3 hfsplus: fix HFSP... |
399 |
struct super_block *sb = src_dir->i_sb; |
1da177e4c Linux-2.6.12-rc2 |
400 401 402 |
struct hfs_find_data src_fd, dst_fd; hfsplus_cat_entry entry; int entry_size, type; |
5bd9d99d1 hfsplus: add erro... |
403 |
int err; |
1da177e4c Linux-2.6.12-rc2 |
404 |
|
c2b3e1f76 hfs/hfsplus: conv... |
405 406 |
hfs_dbg(CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s ", |
2753cc281 hfsplus: over 80 ... |
407 |
cnid, src_dir->i_ino, src_name->name, |
1da177e4c Linux-2.6.12-rc2 |
408 |
dst_dir->i_ino, dst_name->name); |
5bd9d99d1 hfsplus: add erro... |
409 410 411 |
err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &src_fd); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
412 413 414 |
dst_fd = src_fd; /* find the old dir entry and read the data */ |
89ac9b4d3 hfsplus: fix long... |
415 416 417 418 |
err = hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); if (unlikely(err)) goto out; |
324ef39a8 hfsplus: add supp... |
419 |
err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
420 421 |
if (err) goto out; |
6f24f8928 hfsplus: Fix pote... |
422 423 424 425 |
if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { err = -EIO; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
426 427 428 |
hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, src_fd.entrylength); |
d7d673a59 hfsplus: add HFSX... |
429 |
type = be16_to_cpu(entry.type); |
1da177e4c Linux-2.6.12-rc2 |
430 431 |
/* create new dir entry with the data from the old entry */ |
89ac9b4d3 hfsplus: fix long... |
432 433 434 435 |
err = hfsplus_cat_build_key(sb, dst_fd.search_key, dst_dir->i_ino, dst_name); if (unlikely(err)) goto out; |
324ef39a8 hfsplus: add supp... |
436 |
err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
437 438 439 440 441 442 443 444 445 446 |
if (err != -ENOENT) { if (!err) err = -EEXIST; goto out; } err = hfs_brec_insert(&dst_fd, &entry, src_fd.entrylength); if (err) goto out; dst_dir->i_size++; |
d7d673a59 hfsplus: add HFSX... |
447 448 |
if (type == HFSPLUS_FOLDER) hfsplus_subfolders_inc(dst_dir); |
02027d42c fs: Replace CURRE... |
449 |
dst_dir->i_mtime = dst_dir->i_ctime = current_time(dst_dir); |
1da177e4c Linux-2.6.12-rc2 |
450 451 |
/* finally remove the old entry */ |
89ac9b4d3 hfsplus: fix long... |
452 453 454 455 |
err = hfsplus_cat_build_key(sb, src_fd.search_key, src_dir->i_ino, src_name); if (unlikely(err)) goto out; |
324ef39a8 hfsplus: add supp... |
456 |
err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
457 458 459 460 461 462 |
if (err) goto out; err = hfs_brec_remove(&src_fd); if (err) goto out; src_dir->i_size--; |
d7d673a59 hfsplus: add HFSX... |
463 464 |
if (type == HFSPLUS_FOLDER) hfsplus_subfolders_dec(src_dir); |
02027d42c fs: Replace CURRE... |
465 |
src_dir->i_mtime = src_dir->i_ctime = current_time(src_dir); |
1da177e4c Linux-2.6.12-rc2 |
466 467 |
/* remove old thread entry */ |
89ac9b4d3 hfsplus: fix long... |
468 |
hfsplus_cat_build_key_with_cnid(sb, src_fd.search_key, cnid); |
324ef39a8 hfsplus: add supp... |
469 |
err = hfs_brec_find(&src_fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
470 471 472 473 474 475 476 477 |
if (err) goto out; type = hfs_bnode_read_u16(src_fd.bnode, src_fd.entryoffset); err = hfs_brec_remove(&src_fd); if (err) goto out; /* create new thread entry */ |
89ac9b4d3 hfsplus: fix long... |
478 |
hfsplus_cat_build_key_with_cnid(sb, dst_fd.search_key, cnid); |
2753cc281 hfsplus: over 80 ... |
479 480 |
entry_size = hfsplus_fill_cat_thread(sb, &entry, type, dst_dir->i_ino, dst_name); |
89ac9b4d3 hfsplus: fix long... |
481 482 483 484 |
if (unlikely(entry_size < 0)) { err = entry_size; goto out; } |
324ef39a8 hfsplus: add supp... |
485 |
err = hfs_brec_find(&dst_fd, hfs_find_rec_by_key); |
1da177e4c Linux-2.6.12-rc2 |
486 487 488 489 490 491 |
if (err != -ENOENT) { if (!err) err = -EEXIST; goto out; } err = hfs_brec_insert(&dst_fd, &entry, entry_size); |
e34947056 hfsplus: optimize... |
492 493 494 |
hfsplus_mark_inode_dirty(dst_dir, HFSPLUS_I_CAT_DIRTY); hfsplus_mark_inode_dirty(src_dir, HFSPLUS_I_CAT_DIRTY); |
1da177e4c Linux-2.6.12-rc2 |
495 496 497 498 499 |
out: hfs_bnode_put(dst_fd.bnode); hfs_find_exit(&src_fd); return err; } |