[PATCH] Fix bugs in analog tv i2c-helper chipset drivers
[linux-2.6/history.git] / fs / affs / inode.c
blob37aca8f801fd9cf0fe060d4ec9637e0bd01a81ce
1 /*
2 * linux/fs/affs/inode.c
4 * (c) 1996 Hans-Joachim Widmaier - Rewritten
6 * (C) 1993 Ray Burr - Modified for Amiga FFS filesystem.
8 * (C) 1992 Eric Youngdale Modified for ISO9660 filesystem.
10 * (C) 1991 Linus Torvalds - minix filesystem
13 #include <asm/div64.h>
14 #include <linux/errno.h>
15 #include <linux/fs.h>
16 #include <linux/slab.h>
17 #include <linux/stat.h>
18 #include <linux/time.h>
19 #include <linux/affs_fs.h>
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/string.h>
23 #include <linux/genhd.h>
24 #include <linux/amigaffs.h>
25 #include <linux/major.h>
26 #include <linux/blkdev.h>
27 #include <linux/init.h>
28 #include <linux/smp_lock.h>
29 #include <linux/buffer_head.h>
30 #include <asm/system.h>
31 #include <asm/uaccess.h>
32 #include <linux/module.h>
34 extern struct inode_operations affs_symlink_inode_operations;
35 extern struct timezone sys_tz;
37 void
38 affs_read_inode(struct inode *inode)
40 struct super_block *sb = inode->i_sb;
41 struct affs_sb_info *sbi = AFFS_SB(sb);
42 struct buffer_head *bh;
43 struct affs_head *head;
44 struct affs_tail *tail;
45 u32 block;
46 u32 size;
47 u32 prot;
48 u16 id;
50 pr_debug("AFFS: read_inode(%lu)\n",inode->i_ino);
52 block = inode->i_ino;
53 bh = affs_bread(sb, block);
54 if (!bh) {
55 affs_warning(sb, "read_inode", "Cannot read block %d", block);
56 goto bad_inode;
58 if (affs_checksum_block(sb, bh) || be32_to_cpu(AFFS_HEAD(bh)->ptype) != T_SHORT) {
59 affs_warning(sb,"read_inode",
60 "Checksum or type (ptype=%d) error on inode %d",
61 AFFS_HEAD(bh)->ptype, block);
62 goto bad_inode;
65 head = AFFS_HEAD(bh);
66 tail = AFFS_TAIL(sb, bh);
67 prot = be32_to_cpu(tail->protect);
69 inode->i_size = 0;
70 inode->i_nlink = 1;
71 inode->i_mode = 0;
72 AFFS_I(inode)->i_extcnt = 1;
73 AFFS_I(inode)->i_ext_last = ~1;
74 AFFS_I(inode)->i_protect = prot;
75 AFFS_I(inode)->i_opencnt = 0;
76 AFFS_I(inode)->i_blkcnt = 0;
77 AFFS_I(inode)->i_lc = NULL;
78 AFFS_I(inode)->i_lc_size = 0;
79 AFFS_I(inode)->i_lc_shift = 0;
80 AFFS_I(inode)->i_lc_mask = 0;
81 AFFS_I(inode)->i_ac = NULL;
82 AFFS_I(inode)->i_ext_bh = NULL;
83 AFFS_I(inode)->mmu_private = 0;
84 AFFS_I(inode)->i_lastalloc = 0;
85 AFFS_I(inode)->i_pa_cnt = 0;
87 if (sbi->s_flags & SF_SETMODE)
88 inode->i_mode = sbi->s_mode;
89 else
90 inode->i_mode = prot_to_mode(prot);
92 id = be16_to_cpu(tail->uid);
93 if (id == 0 || sbi->s_flags & SF_SETUID)
94 inode->i_uid = sbi->s_uid;
95 else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
96 inode->i_uid = 0;
97 else
98 inode->i_uid = id;
100 id = be16_to_cpu(tail->gid);
101 if (id == 0 || sbi->s_flags & SF_SETGID)
102 inode->i_gid = sbi->s_gid;
103 else if (id == 0xFFFF && sbi->s_flags & SF_MUFS)
104 inode->i_gid = 0;
105 else
106 inode->i_gid = id;
108 switch (be32_to_cpu(tail->stype)) {
109 case ST_ROOT:
110 inode->i_uid = sbi->s_uid;
111 inode->i_gid = sbi->s_gid;
112 /* fall through */
113 case ST_USERDIR:
114 if (be32_to_cpu(tail->stype) == ST_USERDIR ||
115 sbi->s_flags & SF_SETMODE) {
116 if (inode->i_mode & S_IRUSR)
117 inode->i_mode |= S_IXUSR;
118 if (inode->i_mode & S_IRGRP)
119 inode->i_mode |= S_IXGRP;
120 if (inode->i_mode & S_IROTH)
121 inode->i_mode |= S_IXOTH;
122 inode->i_mode |= S_IFDIR;
123 } else
124 inode->i_mode = S_IRUGO | S_IXUGO | S_IWUSR | S_IFDIR;
125 if (tail->link_chain)
126 inode->i_nlink = 2;
127 /* Maybe it should be controlled by mount parameter? */
128 //inode->i_mode |= S_ISVTX;
129 inode->i_op = &affs_dir_inode_operations;
130 inode->i_fop = &affs_dir_operations;
131 break;
132 case ST_LINKDIR:
133 #if 0
134 affs_warning(sb, "read_inode", "inode is LINKDIR");
135 goto bad_inode;
136 #else
137 inode->i_mode |= S_IFDIR;
138 inode->i_op = NULL;
139 inode->i_fop = NULL;
140 break;
141 #endif
142 case ST_LINKFILE:
143 affs_warning(sb, "read_inode", "inode is LINKFILE");
144 goto bad_inode;
145 case ST_FILE:
146 size = be32_to_cpu(tail->size);
147 inode->i_mode |= S_IFREG;
148 AFFS_I(inode)->mmu_private = inode->i_size = size;
149 if (inode->i_size) {
150 AFFS_I(inode)->i_blkcnt = (size - 1) /
151 sbi->s_data_blksize + 1;
152 AFFS_I(inode)->i_extcnt = (AFFS_I(inode)->i_blkcnt - 1) /
153 sbi->s_hashsize + 1;
155 if (tail->link_chain)
156 inode->i_nlink = 2;
157 inode->i_mapping->a_ops = (sbi->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
158 inode->i_op = &affs_file_inode_operations;
159 inode->i_fop = &affs_file_operations;
160 break;
161 case ST_SOFTLINK:
162 inode->i_mode |= S_IFLNK;
163 inode->i_op = &affs_symlink_inode_operations;
164 inode->i_data.a_ops = &affs_symlink_aops;
165 break;
168 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec
169 = (be32_to_cpu(tail->change.days) * (24 * 60 * 60) +
170 be32_to_cpu(tail->change.mins) * 60 +
171 be32_to_cpu(tail->change.ticks) / 50 +
172 ((8 * 365 + 2) * 24 * 60 * 60)) +
173 sys_tz.tz_minuteswest * 60;
174 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
175 affs_brelse(bh);
176 return;
178 bad_inode:
179 make_bad_inode(inode);
180 affs_brelse(bh);
181 return;
184 void
185 affs_write_inode(struct inode *inode, int unused)
187 struct super_block *sb = inode->i_sb;
188 struct buffer_head *bh;
189 struct affs_tail *tail;
190 uid_t uid;
191 gid_t gid;
193 pr_debug("AFFS: write_inode(%lu)\n",inode->i_ino);
195 if (!inode->i_nlink)
196 // possibly free block
197 return;
198 bh = affs_bread(sb, inode->i_ino);
199 if (!bh) {
200 affs_error(sb,"write_inode","Cannot read block %lu",inode->i_ino);
201 return;
203 tail = AFFS_TAIL(sb, bh);
204 if (tail->stype == be32_to_cpu(ST_ROOT)) {
205 secs_to_datestamp(inode->i_mtime.tv_sec,&AFFS_ROOT_TAIL(sb, bh)->root_change);
206 } else {
207 tail->protect = cpu_to_be32(AFFS_I(inode)->i_protect);
208 tail->size = cpu_to_be32(inode->i_size);
209 secs_to_datestamp(inode->i_mtime.tv_sec,&tail->change);
210 if (!(inode->i_ino == AFFS_SB(sb)->s_root_block)) {
211 uid = inode->i_uid;
212 gid = inode->i_gid;
213 if (AFFS_SB(sb)->s_flags & SF_MUFS) {
214 if (inode->i_uid == 0 || inode->i_uid == 0xFFFF)
215 uid = inode->i_uid ^ ~0;
216 if (inode->i_gid == 0 || inode->i_gid == 0xFFFF)
217 gid = inode->i_gid ^ ~0;
219 if (!(AFFS_SB(sb)->s_flags & SF_SETUID))
220 tail->uid = cpu_to_be16(uid);
221 if (!(AFFS_SB(sb)->s_flags & SF_SETGID))
222 tail->gid = cpu_to_be16(gid);
225 affs_fix_checksum(sb, bh);
226 mark_buffer_dirty_inode(bh, inode);
227 affs_brelse(bh);
228 affs_free_prealloc(inode);
232 affs_notify_change(struct dentry *dentry, struct iattr *attr)
234 struct inode *inode = dentry->d_inode;
235 int error;
237 pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
239 error = inode_change_ok(inode,attr);
240 if (error)
241 goto out;
243 if (((attr->ia_valid & ATTR_UID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETUID)) ||
244 ((attr->ia_valid & ATTR_GID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETGID)) ||
245 ((attr->ia_valid & ATTR_MODE) &&
246 (AFFS_SB(inode->i_sb)->s_flags & (SF_SETMODE | SF_IMMUTABLE)))) {
247 if (!(AFFS_SB(inode->i_sb)->s_flags & SF_QUIET))
248 error = -EPERM;
249 goto out;
252 inode_setattr(inode, attr);
253 if (!error && (attr->ia_valid & ATTR_MODE))
254 mode_to_prot(inode);
255 out:
256 return error;
259 void
260 affs_put_inode(struct inode *inode)
262 pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
263 affs_free_prealloc(inode);
264 if (atomic_read(&inode->i_count) == 1) {
265 down(&inode->i_sem);
266 if (inode->i_size != AFFS_I(inode)->mmu_private)
267 affs_truncate(inode);
268 up(&inode->i_sem);
272 void
273 affs_delete_inode(struct inode *inode)
275 pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
276 inode->i_size = 0;
277 if (S_ISREG(inode->i_mode))
278 affs_truncate(inode);
279 clear_inode(inode);
280 affs_free_block(inode->i_sb, inode->i_ino);
283 void
284 affs_clear_inode(struct inode *inode)
286 unsigned long cache_page = (unsigned long) AFFS_I(inode)->i_lc;
288 pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
289 if (cache_page) {
290 pr_debug("AFFS: freeing ext cache\n");
291 AFFS_I(inode)->i_lc = NULL;
292 AFFS_I(inode)->i_ac = NULL;
293 free_page(cache_page);
295 affs_brelse(AFFS_I(inode)->i_ext_bh);
296 AFFS_I(inode)->i_ext_last = ~1;
297 AFFS_I(inode)->i_ext_bh = NULL;
300 struct inode *
301 affs_new_inode(struct inode *dir)
303 struct super_block *sb = dir->i_sb;
304 struct inode *inode;
305 u32 block;
306 struct buffer_head *bh;
308 if (!(inode = new_inode(sb)))
309 goto err_inode;
311 if (!(block = affs_alloc_block(dir, dir->i_ino)))
312 goto err_block;
314 bh = affs_getzeroblk(sb, block);
315 if (!bh)
316 goto err_bh;
317 mark_buffer_dirty_inode(bh, inode);
318 affs_brelse(bh);
320 inode->i_uid = current->fsuid;
321 inode->i_gid = current->fsgid;
322 inode->i_ino = block;
323 inode->i_nlink = 1;
324 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
325 AFFS_I(inode)->i_opencnt = 0;
326 AFFS_I(inode)->i_blkcnt = 0;
327 AFFS_I(inode)->i_lc = NULL;
328 AFFS_I(inode)->i_lc_size = 0;
329 AFFS_I(inode)->i_lc_shift = 0;
330 AFFS_I(inode)->i_lc_mask = 0;
331 AFFS_I(inode)->i_ac = NULL;
332 AFFS_I(inode)->i_ext_bh = NULL;
333 AFFS_I(inode)->mmu_private = 0;
334 AFFS_I(inode)->i_protect = 0;
335 AFFS_I(inode)->i_lastalloc = 0;
336 AFFS_I(inode)->i_pa_cnt = 0;
337 AFFS_I(inode)->i_extcnt = 1;
338 AFFS_I(inode)->i_ext_last = ~1;
340 insert_inode_hash(inode);
342 return inode;
344 err_bh:
345 affs_free_block(sb, block);
346 err_block:
347 iput(inode);
348 err_inode:
349 return NULL;
353 * Add an entry to a directory. Create the header block
354 * and insert it into the hash table.
358 affs_add_entry(struct inode *dir, struct inode *inode, struct dentry *dentry, s32 type)
360 struct super_block *sb = dir->i_sb;
361 struct buffer_head *inode_bh = NULL;
362 struct buffer_head *bh = NULL;
363 u32 block = 0;
364 int retval;
366 pr_debug("AFFS: add_entry(dir=%u, inode=%u, \"%*s\", type=%d)\n", (u32)dir->i_ino,
367 (u32)inode->i_ino, (int)dentry->d_name.len, dentry->d_name.name, type);
369 retval = -EIO;
370 bh = affs_bread(sb, inode->i_ino);
371 if (!bh)
372 goto done;
374 affs_lock_link(inode);
375 switch (type) {
376 case ST_LINKFILE:
377 case ST_LINKDIR:
378 inode_bh = bh;
379 retval = -ENOSPC;
380 block = affs_alloc_block(dir, dir->i_ino);
381 if (!block)
382 goto err;
383 retval = -EIO;
384 bh = affs_getzeroblk(sb, block);
385 if (!bh)
386 goto err;
387 break;
388 default:
389 break;
392 AFFS_HEAD(bh)->ptype = cpu_to_be32(T_SHORT);
393 AFFS_HEAD(bh)->key = cpu_to_be32(bh->b_blocknr);
394 affs_copy_name(AFFS_TAIL(sb, bh)->name, dentry);
395 AFFS_TAIL(sb, bh)->stype = cpu_to_be32(type);
396 AFFS_TAIL(sb, bh)->parent = cpu_to_be32(dir->i_ino);
398 if (inode_bh) {
399 u32 chain;
400 chain = AFFS_TAIL(sb, inode_bh)->link_chain;
401 AFFS_TAIL(sb, bh)->original = cpu_to_be32(inode->i_ino);
402 AFFS_TAIL(sb, bh)->link_chain = chain;
403 AFFS_TAIL(sb, inode_bh)->link_chain = cpu_to_be32(block);
404 affs_adjust_checksum(inode_bh, block - be32_to_cpu(chain));
405 mark_buffer_dirty_inode(inode_bh, inode);
406 inode->i_nlink = 2;
407 atomic_inc(&inode->i_count);
409 affs_fix_checksum(sb, bh);
410 mark_buffer_dirty_inode(bh, inode);
411 dentry->d_fsdata = (void *)(long)bh->b_blocknr;
413 affs_lock_dir(dir);
414 retval = affs_insert_hash(dir, bh);
415 mark_buffer_dirty_inode(bh, inode);
416 affs_unlock_dir(dir);
417 affs_unlock_link(inode);
419 d_instantiate(dentry, inode);
420 done:
421 affs_brelse(inode_bh);
422 affs_brelse(bh);
423 return retval;
424 err:
425 if (block)
426 affs_free_block(sb, block);
427 affs_unlock_link(inode);
428 goto done;
430 MODULE_LICENSE("GPL");