Blame view
fs/affs/inode.c
10.6 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 11 12 |
/* * linux/fs/affs/inode.c * * (c) 1996 Hans-Joachim Widmaier - Rewritten * * (C) 1993 Ray Burr - Modified for Amiga FFS filesystem. * * (C) 1992 Eric Youngdale Modified for ISO9660 filesystem. * * (C) 1991 Linus Torvalds - minix filesystem */ |
e8edc6e03 Detach sched.h fr... |
13 |
#include <linux/sched.h> |
5b825c3af sched/headers: Pr... |
14 |
#include <linux/cred.h> |
5a0e3ad6a include cleanup: ... |
15 |
#include <linux/gfp.h> |
1da177e4c Linux-2.6.12-rc2 |
16 |
#include "affs.h" |
210f85596 iget: stop AFFS f... |
17 |
struct inode *affs_iget(struct super_block *sb, unsigned long ino) |
1da177e4c Linux-2.6.12-rc2 |
18 |
{ |
1da177e4c Linux-2.6.12-rc2 |
19 20 |
struct affs_sb_info *sbi = AFFS_SB(sb); struct buffer_head *bh; |
1da177e4c Linux-2.6.12-rc2 |
21 |
struct affs_tail *tail; |
210f85596 iget: stop AFFS f... |
22 |
struct inode *inode; |
1da177e4c Linux-2.6.12-rc2 |
23 24 25 26 |
u32 block; u32 size; u32 prot; u16 id; |
210f85596 iget: stop AFFS f... |
27 28 29 30 31 |
inode = iget_locked(sb, ino); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; |
9606d9aa8 fs/affs: pr_debug... |
32 33 |
pr_debug("affs_iget(%lu) ", inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 42 43 44 45 46 |
block = inode->i_ino; bh = affs_bread(sb, block); if (!bh) { affs_warning(sb, "read_inode", "Cannot read block %d", block); goto bad_inode; } if (affs_checksum_block(sb, bh) || be32_to_cpu(AFFS_HEAD(bh)->ptype) != T_SHORT) { affs_warning(sb,"read_inode", "Checksum or type (ptype=%d) error on inode %d", AFFS_HEAD(bh)->ptype, block); goto bad_inode; } |
1da177e4c Linux-2.6.12-rc2 |
47 48 49 50 |
tail = AFFS_TAIL(sb, bh); prot = be32_to_cpu(tail->protect); inode->i_size = 0; |
bfe868486 filesystems: add ... |
51 |
set_nlink(inode, 1); |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 |
inode->i_mode = 0; AFFS_I(inode)->i_extcnt = 1; AFFS_I(inode)->i_ext_last = ~1; AFFS_I(inode)->i_protect = prot; |
dca3c3365 [PATCH] fix reser... |
56 |
atomic_set(&AFFS_I(inode)->i_opencnt, 0); |
1da177e4c Linux-2.6.12-rc2 |
57 58 59 60 61 62 63 64 65 66 |
AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; AFFS_I(inode)->i_lc_shift = 0; AFFS_I(inode)->i_lc_mask = 0; AFFS_I(inode)->i_ac = NULL; AFFS_I(inode)->i_ext_bh = NULL; AFFS_I(inode)->mmu_private = 0; AFFS_I(inode)->i_lastalloc = 0; AFFS_I(inode)->i_pa_cnt = 0; |
79bda4d51 fs/affs: use affs... |
67 |
if (affs_test_opt(sbi->s_flags, SF_SETMODE)) |
1da177e4c Linux-2.6.12-rc2 |
68 69 |
inode->i_mode = sbi->s_mode; else |
c16182085 fs/affs: add pref... |
70 |
inode->i_mode = affs_prot_to_mode(prot); |
1da177e4c Linux-2.6.12-rc2 |
71 72 |
id = be16_to_cpu(tail->uid); |
79bda4d51 fs/affs: use affs... |
73 |
if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETUID)) |
1da177e4c Linux-2.6.12-rc2 |
74 |
inode->i_uid = sbi->s_uid; |
79bda4d51 fs/affs: use affs... |
75 |
else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS)) |
8fed10be0 userns: Convert a... |
76 |
i_uid_write(inode, 0); |
1da177e4c Linux-2.6.12-rc2 |
77 |
else |
8fed10be0 userns: Convert a... |
78 |
i_uid_write(inode, id); |
1da177e4c Linux-2.6.12-rc2 |
79 80 |
id = be16_to_cpu(tail->gid); |
79bda4d51 fs/affs: use affs... |
81 |
if (id == 0 || affs_test_opt(sbi->s_flags, SF_SETGID)) |
1da177e4c Linux-2.6.12-rc2 |
82 |
inode->i_gid = sbi->s_gid; |
79bda4d51 fs/affs: use affs... |
83 |
else if (id == 0xFFFF && affs_test_opt(sbi->s_flags, SF_MUFS)) |
8fed10be0 userns: Convert a... |
84 |
i_gid_write(inode, 0); |
1da177e4c Linux-2.6.12-rc2 |
85 |
else |
8fed10be0 userns: Convert a... |
86 |
i_gid_write(inode, id); |
1da177e4c Linux-2.6.12-rc2 |
87 88 89 90 91 |
switch (be32_to_cpu(tail->stype)) { case ST_ROOT: inode->i_uid = sbi->s_uid; inode->i_gid = sbi->s_gid; |
df561f668 treewide: Use fal... |
92 |
fallthrough; |
1da177e4c Linux-2.6.12-rc2 |
93 94 |
case ST_USERDIR: if (be32_to_cpu(tail->stype) == ST_USERDIR || |
79bda4d51 fs/affs: use affs... |
95 |
affs_test_opt(sbi->s_flags, SF_SETMODE)) { |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 100 101 102 103 104 |
if (inode->i_mode & S_IRUSR) inode->i_mode |= S_IXUSR; if (inode->i_mode & S_IRGRP) inode->i_mode |= S_IXGRP; if (inode->i_mode & S_IROTH) inode->i_mode |= S_IXOTH; inode->i_mode |= S_IFDIR; } else inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR; |
1da177e4c Linux-2.6.12-rc2 |
105 106 107 108 109 110 111 112 113 114 115 |
/* Maybe it should be controlled by mount parameter? */ //inode->i_mode |= S_ISVTX; inode->i_op = &affs_dir_inode_operations; inode->i_fop = &affs_dir_operations; break; case ST_LINKDIR: #if 0 affs_warning(sb, "read_inode", "inode is LINKDIR"); goto bad_inode; #else inode->i_mode |= S_IFDIR; |
c765d4790 affs: do not zero... |
116 |
/* ... and leave ->i_op and ->i_fop pointing to empty */ |
1da177e4c Linux-2.6.12-rc2 |
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
break; #endif case ST_LINKFILE: affs_warning(sb, "read_inode", "inode is LINKFILE"); goto bad_inode; case ST_FILE: size = be32_to_cpu(tail->size); inode->i_mode |= S_IFREG; AFFS_I(inode)->mmu_private = inode->i_size = size; if (inode->i_size) { AFFS_I(inode)->i_blkcnt = (size - 1) / sbi->s_data_blksize + 1; AFFS_I(inode)->i_extcnt = (AFFS_I(inode)->i_blkcnt - 1) / sbi->s_hashsize + 1; } if (tail->link_chain) |
bfe868486 filesystems: add ... |
133 |
set_nlink(inode, 2); |
79bda4d51 fs/affs: use affs... |
134 |
inode->i_mapping->a_ops = affs_test_opt(sbi->s_flags, SF_OFS) ? |
a0016ff28 fs/affs: use AFFS... |
135 |
&affs_aops_ofs : &affs_aops; |
1da177e4c Linux-2.6.12-rc2 |
136 137 138 139 |
inode->i_op = &affs_file_inode_operations; inode->i_fop = &affs_file_operations; break; case ST_SOFTLINK: |
f1bf90724 fs/affs: bugfix: ... |
140 |
inode->i_size = strlen((char *)AFFS_HEAD(bh)->table); |
1da177e4c Linux-2.6.12-rc2 |
141 |
inode->i_mode |= S_IFLNK; |
21fc61c73 don't put symlink... |
142 |
inode_nohighmem(inode); |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 146 147 148 |
inode->i_op = &affs_symlink_inode_operations; inode->i_data.a_ops = &affs_symlink_aops; break; } inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec |
487b25bc4 fs: affs: Initial... |
149 |
= (be32_to_cpu(tail->change.days) * 86400LL + |
1da177e4c Linux-2.6.12-rc2 |
150 151 |
be32_to_cpu(tail->change.mins) * 60 + be32_to_cpu(tail->change.ticks) / 50 + |
487b25bc4 fs: affs: Initial... |
152 |
AFFS_EPOCH_DELTA) + |
1da177e4c Linux-2.6.12-rc2 |
153 154 155 |
sys_tz.tz_minuteswest * 60; inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0; affs_brelse(bh); |
210f85596 iget: stop AFFS f... |
156 157 |
unlock_new_inode(inode); return inode; |
1da177e4c Linux-2.6.12-rc2 |
158 159 |
bad_inode: |
1da177e4c Linux-2.6.12-rc2 |
160 |
affs_brelse(bh); |
210f85596 iget: stop AFFS f... |
161 162 |
iget_failed(inode); return ERR_PTR(-EIO); |
1da177e4c Linux-2.6.12-rc2 |
163 164 165 |
} int |
a9185b41a pass writeback_co... |
166 |
affs_write_inode(struct inode *inode, struct writeback_control *wbc) |
1da177e4c Linux-2.6.12-rc2 |
167 168 169 170 171 172 |
{ struct super_block *sb = inode->i_sb; struct buffer_head *bh; struct affs_tail *tail; uid_t uid; gid_t gid; |
9606d9aa8 fs/affs: pr_debug... |
173 174 |
pr_debug("write_inode(%lu) ", inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 179 180 181 182 183 184 185 |
if (!inode->i_nlink) // possibly free block return 0; bh = affs_bread(sb, inode->i_ino); if (!bh) { affs_error(sb,"write_inode","Cannot read block %lu",inode->i_ino); return -EIO; } tail = AFFS_TAIL(sb, bh); if (tail->stype == cpu_to_be32(ST_ROOT)) { |
c16182085 fs/affs: add pref... |
186 187 |
affs_secs_to_datestamp(inode->i_mtime.tv_sec, &AFFS_ROOT_TAIL(sb, bh)->root_change); |
1da177e4c Linux-2.6.12-rc2 |
188 189 190 |
} else { tail->protect = cpu_to_be32(AFFS_I(inode)->i_protect); tail->size = cpu_to_be32(inode->i_size); |
c16182085 fs/affs: add pref... |
191 |
affs_secs_to_datestamp(inode->i_mtime.tv_sec, &tail->change); |
1da177e4c Linux-2.6.12-rc2 |
192 |
if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) { |
8fed10be0 userns: Convert a... |
193 194 |
uid = i_uid_read(inode); gid = i_gid_read(inode); |
79bda4d51 fs/affs: use affs... |
195 |
if (affs_test_opt(AFFS_SB(sb)->s_flags, SF_MUFS)) { |
8fed10be0 userns: Convert a... |
196 197 198 199 |
if (uid == 0 || uid == 0xFFFF) uid = uid ^ ~0; if (gid == 0 || gid == 0xFFFF) gid = gid ^ ~0; |
1da177e4c Linux-2.6.12-rc2 |
200 |
} |
79bda4d51 fs/affs: use affs... |
201 |
if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETUID)) |
1da177e4c Linux-2.6.12-rc2 |
202 |
tail->uid = cpu_to_be16(uid); |
79bda4d51 fs/affs: use affs... |
203 |
if (!affs_test_opt(AFFS_SB(sb)->s_flags, SF_SETGID)) |
1da177e4c Linux-2.6.12-rc2 |
204 205 206 207 208 209 210 211 212 213 214 215 216 |
tail->gid = cpu_to_be16(gid); } } affs_fix_checksum(sb, bh); mark_buffer_dirty_inode(bh, inode); affs_brelse(bh); affs_free_prealloc(inode); return 0; } int affs_notify_change(struct dentry *dentry, struct iattr *attr) { |
2b0143b5c VFS: normal files... |
217 |
struct inode *inode = d_inode(dentry); |
1da177e4c Linux-2.6.12-rc2 |
218 |
int error; |
9606d9aa8 fs/affs: pr_debug... |
219 220 |
pr_debug("notify_change(%lu,0x%x) ", inode->i_ino, attr->ia_valid); |
1da177e4c Linux-2.6.12-rc2 |
221 |
|
31051c85b fs: Give dentry t... |
222 |
error = setattr_prepare(dentry, attr); |
1da177e4c Linux-2.6.12-rc2 |
223 224 |
if (error) goto out; |
a0016ff28 fs/affs: use AFFS... |
225 |
if (((attr->ia_valid & ATTR_UID) && |
79bda4d51 fs/affs: use affs... |
226 |
affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETUID)) || |
a0016ff28 fs/affs: use AFFS... |
227 |
((attr->ia_valid & ATTR_GID) && |
79bda4d51 fs/affs: use affs... |
228 |
affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_SETGID)) || |
1da177e4c Linux-2.6.12-rc2 |
229 |
((attr->ia_valid & ATTR_MODE) && |
a0016ff28 fs/affs: use AFFS... |
230 231 |
(AFFS_SB(inode->i_sb)->s_flags & (AFFS_MOUNT_SF_SETMODE | AFFS_MOUNT_SF_IMMUTABLE)))) { |
79bda4d51 fs/affs: use affs... |
232 |
if (!affs_test_opt(AFFS_SB(inode->i_sb)->s_flags, SF_QUIET)) |
1da177e4c Linux-2.6.12-rc2 |
233 234 235 |
error = -EPERM; goto out; } |
1025774ce remove inode_setattr |
236 237 |
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { |
1dc1834f4 affs: drop vmtrun... |
238 |
error = inode_newsize_ok(inode, attr->ia_size); |
1025774ce remove inode_setattr |
239 240 |
if (error) return error; |
1dc1834f4 affs: drop vmtrun... |
241 242 243 |
truncate_setsize(inode, attr->ia_size); affs_truncate(inode); |
1025774ce remove inode_setattr |
244 245 246 247 248 249 |
} setattr_copy(inode, attr); mark_inode_dirty(inode); if (attr->ia_valid & ATTR_MODE) |
c16182085 fs/affs: add pref... |
250 |
affs_mode_to_prot(inode); |
1da177e4c Linux-2.6.12-rc2 |
251 252 253 254 255 |
out: return error; } void |
f053ddde7 switch affs to ->... |
256 |
affs_evict_inode(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
257 |
{ |
dca3c3365 [PATCH] fix reser... |
258 |
unsigned long cache_page; |
9606d9aa8 fs/affs: pr_debug... |
259 260 261 |
pr_debug("evict_inode(ino=%lu, nlink=%u) ", inode->i_ino, inode->i_nlink); |
91b0abe36 mm + fs: store sh... |
262 |
truncate_inode_pages_final(&inode->i_data); |
1da177e4c Linux-2.6.12-rc2 |
263 |
|
f053ddde7 switch affs to ->... |
264 265 266 267 |
if (!inode->i_nlink) { inode->i_size = 0; affs_truncate(inode); } |
dca3c3365 [PATCH] fix reser... |
268 |
|
f053ddde7 switch affs to ->... |
269 |
invalidate_inode_buffers(inode); |
dbd5768f8 vfs: Rename end_w... |
270 |
clear_inode(inode); |
dca3c3365 [PATCH] fix reser... |
271 272 |
affs_free_prealloc(inode); cache_page = (unsigned long)AFFS_I(inode)->i_lc; |
1da177e4c Linux-2.6.12-rc2 |
273 |
if (cache_page) { |
9606d9aa8 fs/affs: pr_debug... |
274 275 |
pr_debug("freeing ext cache "); |
1da177e4c Linux-2.6.12-rc2 |
276 277 278 279 280 281 282 |
AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_ac = NULL; free_page(cache_page); } affs_brelse(AFFS_I(inode)->i_ext_bh); AFFS_I(inode)->i_ext_last = ~1; AFFS_I(inode)->i_ext_bh = NULL; |
f053ddde7 switch affs to ->... |
283 284 285 |
if (!inode->i_nlink) affs_free_block(inode->i_sb, inode->i_ino); |
1da177e4c Linux-2.6.12-rc2 |
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
} struct inode * affs_new_inode(struct inode *dir) { struct super_block *sb = dir->i_sb; struct inode *inode; u32 block; struct buffer_head *bh; if (!(inode = new_inode(sb))) goto err_inode; if (!(block = affs_alloc_block(dir, dir->i_ino))) goto err_block; bh = affs_getzeroblk(sb, block); if (!bh) goto err_bh; mark_buffer_dirty_inode(bh, inode); affs_brelse(bh); |
215599815 CRED: Wrap task c... |
307 308 |
inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
309 |
inode->i_ino = block; |
bfe868486 filesystems: add ... |
310 |
set_nlink(inode, 1); |
02027d42c fs: Replace CURRE... |
311 |
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); |
dca3c3365 [PATCH] fix reser... |
312 |
atomic_set(&AFFS_I(inode)->i_opencnt, 0); |
1da177e4c Linux-2.6.12-rc2 |
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
AFFS_I(inode)->i_blkcnt = 0; AFFS_I(inode)->i_lc = NULL; AFFS_I(inode)->i_lc_size = 0; AFFS_I(inode)->i_lc_shift = 0; AFFS_I(inode)->i_lc_mask = 0; AFFS_I(inode)->i_ac = NULL; AFFS_I(inode)->i_ext_bh = NULL; AFFS_I(inode)->mmu_private = 0; AFFS_I(inode)->i_protect = 0; AFFS_I(inode)->i_lastalloc = 0; AFFS_I(inode)->i_pa_cnt = 0; AFFS_I(inode)->i_extcnt = 1; AFFS_I(inode)->i_ext_last = ~1; insert_inode_hash(inode); return inode; err_bh: affs_free_block(sb, block); err_block: iput(inode); err_inode: return NULL; } /* * Add an entry to a directory. Create the header block * and insert it into the hash table. */ int affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type) { struct super_block *sb = dir->i_sb; struct buffer_head *inode_bh = NULL; |
78f444f67 fs/affs/inode.c: ... |
349 |
struct buffer_head *bh; |
1da177e4c Linux-2.6.12-rc2 |
350 351 |
u32 block = 0; int retval; |
08fe100d9 fs/affs: fix cast... |
352 353 354 |
pr_debug("%s(dir=%lu, inode=%lu, \"%pd\", type=%d) ", __func__, dir->i_ino, inode->i_ino, dentry, type); |
1da177e4c Linux-2.6.12-rc2 |
355 356 357 358 359 360 361 362 363 364 |
retval = -EIO; bh = affs_bread(sb, inode->i_ino); if (!bh) goto done; affs_lock_link(inode); switch (type) { case ST_LINKFILE: case ST_LINKDIR: |
1da177e4c Linux-2.6.12-rc2 |
365 366 367 368 369 |
retval = -ENOSPC; block = affs_alloc_block(dir, dir->i_ino); if (!block) goto err; retval = -EIO; |
dca3c3365 [PATCH] fix reser... |
370 |
inode_bh = bh; |
1da177e4c Linux-2.6.12-rc2 |
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
bh = affs_getzeroblk(sb, block); if (!bh) goto err; break; default: break; } AFFS_HEAD(bh)->ptype = cpu_to_be32(T_SHORT); AFFS_HEAD(bh)->key = cpu_to_be32(bh->b_blocknr); affs_copy_name(AFFS_TAIL(sb, bh)->name, dentry); AFFS_TAIL(sb, bh)->stype = cpu_to_be32(type); AFFS_TAIL(sb, bh)->parent = cpu_to_be32(dir->i_ino); if (inode_bh) { __be32 chain; chain = AFFS_TAIL(sb, inode_bh)->link_chain; AFFS_TAIL(sb, bh)->original = cpu_to_be32(inode->i_ino); AFFS_TAIL(sb, bh)->link_chain = chain; AFFS_TAIL(sb, inode_bh)->link_chain = cpu_to_be32(block); affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain)); mark_buffer_dirty_inode(inode_bh, inode); |
bfe868486 filesystems: add ... |
393 |
set_nlink(inode, 2); |
7de9c6ee3 new helper: ihold() |
394 |
ihold(inode); |
1da177e4c Linux-2.6.12-rc2 |
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
} affs_fix_checksum(sb, bh); mark_buffer_dirty_inode(bh, inode); dentry->d_fsdata = (void *)(long)bh->b_blocknr; affs_lock_dir(dir); retval = affs_insert_hash(dir, bh); mark_buffer_dirty_inode(bh, inode); affs_unlock_dir(dir); affs_unlock_link(inode); d_instantiate(dentry, inode); done: affs_brelse(inode_bh); affs_brelse(bh); return retval; err: if (block) affs_free_block(sb, block); affs_unlock_link(inode); goto done; } |