|
|
1.1 root 1: #include "param.h"
2: #include "systm.h"
3: #include "namei.h"
4: #include "resourcevar.h"
5: #include "kernel.h"
6: #include "file.h"
7: #include "stat.h"
8: #include "buf.h"
9: #include "proc.h"
10: #include "conf.h"
11: #include "mount.h"
12: #include "vnode.h"
13: #include "specdev.h"
14: #include "fifo.h"
15: #include "malloc.h"
16: #include "dir.h"
17:
18: #include "iso.h"
19: #include "isofs_node.h"
20:
21: /*
22: * Open called.
23: *
24: * Nothing to do.
25: */
26: /* ARGSUSED */
27: isofs_open(vp, mode, cred, p)
28: struct vnode *vp;
29: int mode;
30: struct ucred *cred;
31: struct proc *p;
32: {
33: return (0);
34: }
35:
36: /*
37: * Close called
38: *
39: * Update the times on the inode on writeable file systems.
40: */
41: /* ARGSUSED */
42: isofs_close(vp, fflag, cred, p)
43: struct vnode *vp;
44: int fflag;
45: struct ucred *cred;
46: struct proc *p;
47: {
48: return (0);
49: }
50:
51: /*
52: * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
53: * The mode is shifted to select the owner/group/other fields. The
54: * super user is granted all permissions.
55: */
56: isofs_access(vp, mode, cred, p)
57: struct vnode *vp;
58: register int mode;
59: struct ucred *cred;
60: struct proc *p;
61: {
62: return (0);
63: }
64:
65: /* ARGSUSED */
66: isofs_getattr(vp, vap, cred, p)
67: struct vnode *vp;
68: register struct vattr *vap;
69: struct ucred *cred;
70: struct proc *p;
71: {
72: register struct iso_node *ip = VTOI(vp);
73: int year, month, day, hour ,minute, second, tz;
74: int crtime, days;
75: int i;
76:
77: year = ip->iso_time[0] - 70;
78: month = ip->iso_time[1];
79: day = ip->iso_time[2];
80: hour = ip->iso_time[3];
81: minute = ip->iso_time[4];
82: second = ip->iso_time[5];
83: tz = ip->iso_time[6];
84:
85: if (year < 0) {
86: crtime = 0;
87: } else {
88: int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
89: days = year * 365;
90: if (year > 2)
91: days += (year+2) / 4;
92: for (i = 1; i < month; i++)
93: days += monlen[i-1];
94: if (((year+2) % 4) == 0 && month > 2)
95: days++;
96: days += day - 1;
97: crtime = ((((days * 24) + hour) * 60 + minute) * 60)
98: + second;
99:
100: /* sign extend */
101: if (tz & 0x80)
102: tz |= (-1 << 8);
103:
104: /* timezone offset is unreliable on some disks */
105: if (-48 <= tz && tz <= 52)
106: crtime += tz * 15 * 60;
107: }
108:
109: vap->va_fsid = ip->i_dev;
110: vap->va_fileid = ip->i_number;
111: vap->va_mode = VREAD|VEXEC;
112: vap->va_mode |= (vap->va_mode >> 3) | (vap->va_mode >> 6);
113: if (vp->v_type == VDIR)
114: vap->va_nlink = 2;
115: else
116: vap->va_nlink = 1;
117: vap->va_uid = 0;
118: vap->va_gid = 0;
119: vap->va_rdev = 0;
120: vap->va_size = ip->i_size;
121: vap->va_size_rsv = 0;
122: vap->va_atime.tv_sec = crtime;
123: vap->va_atime.tv_usec = 0;
124: vap->va_mtime.tv_sec = crtime;
125: vap->va_mtime.tv_usec = 0;
126: vap->va_ctime.tv_sec = crtime;
127: vap->va_ctime.tv_usec = 0;
128: vap->va_flags = 0;
129: vap->va_gen = 1;
130: vap->va_blocksize = ip->i_mnt->logical_block_size;
131: vap->va_bytes = ip->i_size;
132: vap->va_bytes_rsv = 0;
133: vap->va_type = vp->v_type;
134: return (0);
135: }
136:
137: /*
138: * Vnode op for reading.
139: */
140: /* ARGSUSED */
141: isofs_read(vp, uio, ioflag, cred)
142: struct vnode *vp;
143: register struct uio *uio;
144: int ioflag;
145: struct ucred *cred;
146: {
147: register struct iso_node *ip = VTOI(vp);
148: register struct iso_mnt *imp;
149: struct buf *bp;
150: daddr_t lbn, bn, rablock;
151: int size, diff, error = 0;
152: long n, on, type;
153:
154: #ifdef DIAGNOSTICx
155: if (uio->uio_rw != UIO_READ)
156: panic("isofs_read mode");
157: type = ip->i_mode & IFMT;
158: if (type != IFDIR && type != IFREG && type != IFLNK)
159: panic("isofs_read type");
160: #endif
161: if (uio->uio_resid == 0)
162: return (0);
163: if (uio->uio_offset < 0)
164: return (EINVAL);
165: ip->i_flag |= IACC;
166: imp = ip->i_mnt;
167: do {
168: lbn = iso_lblkno(imp, uio->uio_offset);
169: on = iso_blkoff(imp, uio->uio_offset);
170: n = MIN((unsigned)(imp->im_bsize - on), uio->uio_resid);
171: diff = ip->i_size - uio->uio_offset;
172: if (diff <= 0)
173: return (0);
174: if (diff < n)
175: n = diff;
176: size = iso_blksize(imp, ip, lbn);
177: rablock = lbn + 1;
178: if (vp->v_lastr + 1 == lbn &&
179: iso_lblktosize(imp, rablock) < ip->i_size)
180: error = breada(ITOV(ip), lbn, size, rablock,
181: iso_blksize(imp, ip, rablock), NOCRED, &bp);
182: else
183: error = bread(ITOV(ip), lbn, size, NOCRED, &bp);
184: vp->v_lastr = lbn;
185: n = MIN(n, size - bp->b_resid);
186: if (error) {
187: brelse(bp);
188: return (error);
189: }
190:
191: error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
192: if (n + on == imp->im_bsize || uio->uio_offset == ip->i_size)
193: bp->b_flags |= B_AGE;
194: brelse(bp);
195: } while (error == 0 && uio->uio_resid > 0 && n != 0);
196: return (error);
197: }
198:
199: /* ARGSUSED */
200: isofs_ioctl(vp, com, data, fflag, cred, p)
201: struct vnode *vp;
202: int com;
203: caddr_t data;
204: int fflag;
205: struct ucred *cred;
206: struct proc *p;
207: {
208: return (ENOTTY);
209: }
210:
211: /* ARGSUSED */
212: isofs_select(vp, which, fflags, cred, p)
213: struct vnode *vp;
214: int which, fflags;
215: struct ucred *cred;
216: struct proc *p;
217: {
218:
219: /*
220: * We should really check to see if I/O is possible.
221: */
222: return (1);
223: }
224:
225: /*
226: * Mmap a file
227: *
228: * NB Currently unsupported.
229: */
230: /* ARGSUSED */
231: isofs_mmap(vp, fflags, cred, p)
232: struct vnode *vp;
233: int fflags;
234: struct ucred *cred;
235: struct proc *p;
236: {
237:
238: return (EINVAL);
239: }
240:
241: /*
242: * Seek on a file
243: *
244: * Nothing to do, so just return.
245: */
246: /* ARGSUSED */
247: isofs_seek(vp, oldoff, newoff, cred)
248: struct vnode *vp;
249: off_t oldoff, newoff;
250: struct ucred *cred;
251: {
252:
253: return (0);
254: }
255:
256: /*
257: * Vnode op for readdir
258: */
259: isofs_readdir(vp, uio, cred, eofflagp)
260: struct vnode *vp;
261: register struct uio *uio;
262: struct ucred *cred;
263: int *eofflagp;
264: {
265: struct dirent dirent;
266: int iso_offset;
267: int entryoffsetinblock;
268: int error = 0;
269: int endsearch;
270: struct iso_directory_record *ep;
271: int reclen;
272: struct iso_mnt *imp;
273: struct iso_node *ip;
274: struct buf *bp = NULL;
275: int i;
276: int end_flag = 0;
277:
278: ip = VTOI (vp);
279: imp = ip->i_mnt;
280:
281: iso_offset = uio->uio_offset;
282:
283: entryoffsetinblock = iso_blkoff(imp, iso_offset);
284: if (entryoffsetinblock != 0) {
285: if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp))
286: return (error);
287: }
288:
289: endsearch = ip->i_size;
290:
291: while (iso_offset < endsearch && uio->uio_resid > 0) {
292: /*
293: * If offset is on a block boundary,
294: * read the next directory block.
295: * Release previous if it exists.
296: */
297:
298: if (iso_blkoff(imp, iso_offset) == 0) {
299: if (bp != NULL)
300: brelse(bp);
301: if (error = iso_blkatoff(ip, iso_offset,
302: (char **)0, &bp))
303: return (error);
304: entryoffsetinblock = 0;
305: }
306: /*
307: * Get pointer to next entry.
308: */
309:
310: ep = (struct iso_directory_record *)
311: (bp->b_un.b_addr + entryoffsetinblock);
312:
313: reclen = isonum_711 (ep->length);
314: if (reclen == 0) {
315: /* skip to next block, if any */
316: iso_offset = roundup (iso_offset,
317: imp->logical_block_size);
318: continue;
319: }
320:
321: if (reclen < sizeof (struct iso_directory_record))
322: /* illegal entry, stop */
323: break;
324:
325: if (entryoffsetinblock + reclen >= imp->logical_block_size)
326: /* illegal directory, so stop looking */
327: break;
328:
329: dirent.d_fileno = isonum_733 (ep->extent);
330: dirent.d_namlen = isonum_711 (ep->name_len);
331:
332: if (reclen < sizeof (struct iso_directory_record)
333: + dirent.d_namlen)
334: /* illegal entry, stop */
335: break;
336:
337: /*bcopy (ep->name, dirent.d_name, dirent.d_namlen);*/
338: isofntrans(ep->name, dirent.d_namlen,
339: dirent.d_name, &dirent.d_namlen);
340: if (dirent.d_namlen == 1) {
341: switch (dirent.d_name[0]) {
342: case 0:
343: dirent.d_name[0] = '.';
344: break;
345: case 1:
346: dirent.d_name[0] = '.';
347: dirent.d_name[1] = '.';
348: dirent.d_namlen = 2;
349: }
350: }
351: dirent.d_name[dirent.d_namlen] = 0;
352: dirent.d_reclen = DIRSIZ (&dirent);
353:
354: if (uio->uio_resid < dirent.d_reclen)
355: break;
356:
357: if (error = uiomove (&dirent, dirent.d_reclen, uio))
358: break;
359:
360: iso_offset += reclen;
361: entryoffsetinblock += reclen;
362: }
363:
364: if (bp)
365: brelse (bp);
366:
367: if (end_flag || (VTOI(vp)->i_size - iso_offset) <= 0)
368: *eofflagp = 1;
369: else
370: *eofflagp = 0;
371:
372: uio->uio_offset = iso_offset;
373:
374: return (error);
375: }
376:
377: /*
378: * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
379: * done. If a buffer has been saved in anticipation of a CREATE, delete it.
380: */
381: /* ARGSUSED */
382: isofs_abortop(ndp)
383: struct nameidata *ndp;
384: {
385:
386: if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
387: FREE(ndp->ni_pnbuf, M_NAMEI);
388: return (0);
389: }
390:
391: /*
392: * Lock an inode.
393: */
394: isofs_lock(vp)
395: struct vnode *vp;
396: {
397: register struct iso_node *ip = VTOI(vp);
398:
399: ISO_ILOCK(ip);
400: return (0);
401: }
402:
403: /*
404: * Unlock an inode.
405: */
406: isofs_unlock(vp)
407: struct vnode *vp;
408: {
409: register struct iso_node *ip = VTOI(vp);
410:
411: if (!(ip->i_flag & ILOCKED))
412: panic("isofs_unlock NOT LOCKED");
413: ISO_IUNLOCK(ip);
414: return (0);
415: }
416:
417: /*
418: * Check for a locked inode.
419: */
420: isofs_islocked(vp)
421: struct vnode *vp;
422: {
423:
424: if (VTOI(vp)->i_flag & ILOCKED)
425: return (1);
426: return (0);
427: }
428:
429: /*
430: * Calculate the logical to physical mapping if not done already,
431: * then call the device strategy routine.
432: */
433:
434: isofs_strategy(bp)
435: register struct buf *bp;
436: {
437: register struct iso_node *ip = VTOI(bp->b_vp);
438: struct vnode *vp;
439: int error;
440:
441: if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
442: panic("isofs_strategy: spec");
443: if (bp->b_blkno == bp->b_lblkno) {
444: if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno))
445: return (error);
446: if ((long)bp->b_blkno == -1)
447: clrbuf(bp);
448: }
449: if ((long)bp->b_blkno == -1) {
450: biodone(bp);
451: return (0);
452: }
453: vp = ip->i_devvp;
454: bp->b_dev = vp->v_rdev;
455: (*(vp->v_op->vop_strategy))(bp);
456: return (0);
457: }
458:
459: /*
460: * Print out the contents of an inode.
461: */
462: isofs_print(vp)
463: struct vnode *vp;
464: {
465: printf ("isoprint\n");
466: }
467:
468: extern int enodev ();
469:
470: /*
471: * Global vfs data structures for isofs
472: */
473: struct vnodeops isofs_vnodeops = {
474: isofs_lookup, /* lookup */
475: (void *)enodev, /* create */
476: (void *)enodev, /* mknod */
477: isofs_open, /* open */
478: isofs_close, /* close */
479: isofs_access, /* access */
480: isofs_getattr, /* getattr */
481: (void *)enodev, /* setattr */
482: isofs_read, /* read */
483: (void *)enodev, /* write */
484: isofs_ioctl, /* ioctl */
485: isofs_select, /* select */
486: isofs_mmap, /* mmap */
487: (void *)nullop, /* fsync */
488: isofs_seek, /* seek */
489: (void *)enodev, /* remove */
490: (void *)enodev, /* link */
491: (void *)enodev, /* rename */
492: (void *)enodev, /* mkdir */
493: (void *)enodev, /* rmdir */
494: (void *)enodev, /* symlink */
495: isofs_readdir, /* readdir */
496: (void *)enodev, /* readlink */
497: isofs_abortop, /* abortop */
498: isofs_inactive, /* inactive */
499: isofs_reclaim, /* reclaim */
500: isofs_lock, /* lock */
501: isofs_unlock, /* unlock */
502: (void *)enodev, /* bmap */
503: isofs_strategy, /* strategy */
504: isofs_print, /* print */
505: isofs_islocked, /* islocked */
506: (void *)enodev, /* advlock */
507: };
508:
509:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.