|
|
1.1 root 1: /*
2: * linux/fs/truncate.c
3: *
4: * (C) 1991 Linus Torvalds
5: */
6:
7: #include <linux/sched.h>
8: #include <linux/minix_fs.h>
9: #include <linux/tty.h>
10:
11: #include <errno.h>
12: #include <fcntl.h>
13: #include <sys/stat.h>
14:
15: static int minix_free_ind(int dev,int block)
16: {
17: struct buffer_head * bh;
18: unsigned short * p;
19: int i;
20: int block_busy;
21:
22: if (!block)
23: return 1;
24: block_busy = 0;
25: if (bh=bread(dev,block)) {
26: p = (unsigned short *) bh->b_data;
27: for (i=0;i<512;i++,p++)
28: if (*p)
29: if (minix_free_block(dev,*p)) {
30: *p = 0;
31: bh->b_dirt = 1;
32: } else
33: block_busy = 1;
34: brelse(bh);
35: }
36: if (block_busy)
37: return 0;
38: else
39: return minix_free_block(dev,block);
40: }
41:
42: static int minix_free_dind(int dev,int block)
43: {
44: struct buffer_head * bh;
45: unsigned short * p;
46: int i;
47: int block_busy;
48:
49: if (!block)
50: return 1;
51: block_busy = 0;
52: if (bh=bread(dev,block)) {
53: p = (unsigned short *) bh->b_data;
54: for (i=0;i<512;i++,p++)
55: if (*p)
56: if (minix_free_ind(dev,*p)) {
57: *p = 0;
58: bh->b_dirt = 1;
59: } else
60: block_busy = 1;
61: brelse(bh);
62: }
63: if (block_busy)
64: return 0;
65: else
66: return minix_free_block(dev,block);
67: }
68:
69: void minix_truncate(struct inode * inode)
70: {
71: int i;
72: int block_busy;
73:
74: if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
75: S_ISLNK(inode->i_mode)))
76: return;
77: repeat:
78: block_busy = 0;
79: for (i=0;i<7;i++)
80: if (inode->i_data[i]) {
81: if (minix_free_block(inode->i_dev,inode->i_data[i]))
82: inode->i_data[i]=0;
83: else
84: block_busy = 1;
85: }
86: if (minix_free_ind(inode->i_dev,inode->i_data[7]))
87: inode->i_data[7] = 0;
88: else
89: block_busy = 1;
90: if (minix_free_dind(inode->i_dev,inode->i_data[8]))
91: inode->i_data[8] = 0;
92: else
93: block_busy = 1;
94: inode->i_dirt = 1;
95: if (block_busy) {
96: current->counter = 0;
97: schedule();
98: goto repeat;
99: }
100: inode->i_size = 0;
101: inode->i_mtime = inode->i_ctime = CURRENT_TIME;
102: }
103:
104: /*
105: * Called when a inode is released. Note that this is different
106: * from minix_open: open gets called at every open, but release
107: * gets called only when /all/ the files are closed.
108: */
109: void minix_release(struct inode * inode, struct file * filp)
110: {
111: printk("minix_release not implemented\n");
112: }
113:
114: static int check_char_dev(struct inode * inode, struct file * filp)
115: {
116: struct tty_struct *tty;
117: int min, dev;
118:
119: dev = inode->i_rdev;
120: if (MAJOR(dev) == 4 || MAJOR(dev) == 5) {
121: if (MAJOR(dev) == 5)
122: min = current->tty;
123: else
124: min = MINOR(dev);
125: if (min < 0)
126: return -1;
127: if ((IS_A_PTY_MASTER(min)) && (inode->i_count>1))
128: return -1;
129: tty = TTY_TABLE(min);
130: if (!(filp->f_flags & O_NOCTTY) &&
131: current->leader &&
132: current->tty<0 &&
133: tty->session==0) {
134: current->tty = min;
135: tty->session= current->session;
136: tty->pgrp = current->pgrp;
137: }
138: }
139: return 0;
140: }
141:
142: /*
143: * Called every time a minix-file is opened
144: */
145: int minix_open(struct inode * inode, struct file * filp)
146: {
147: if (S_ISCHR(inode->i_mode)) {
148: if (check_char_dev(inode,filp))
149: return -EAGAIN;
150: } else if (S_ISBLK(inode->i_mode))
151: check_disk_change(inode->i_rdev);
152: filp->f_op = &minix_file_operations;
153: return 0;
154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.