Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
190244fb | 2 | * Copyright (c) 1989, 1991 The Regents of the University of California. |
7188ac27 | 3 | * All rights reserved. |
da7c5cc6 | 4 | * |
b702c21d | 5 | * %sccs.include.redist.c% |
7188ac27 | 6 | * |
0b4d6502 | 7 | * @(#)lfs_vfsops.c 7.57 (Berkeley) %G% |
da7c5cc6 | 8 | */ |
71e4e98b | 9 | |
94368568 JB |
10 | #include "param.h" |
11 | #include "systm.h" | |
c6f5111d | 12 | #include "namei.h" |
8dc876c1 | 13 | #include "proc.h" |
7188ac27 | 14 | #include "kernel.h" |
7188ac27 | 15 | #include "vnode.h" |
0f93ba7b | 16 | #include "specdev.h" |
94368568 | 17 | #include "mount.h" |
7188ac27 | 18 | #include "buf.h" |
94368568 | 19 | #include "file.h" |
ec67a3ce | 20 | #include "disklabel.h" |
7188ac27 KM |
21 | #include "ioctl.h" |
22 | #include "errno.h" | |
4def0c5e | 23 | #include "malloc.h" |
609e7cfa MK |
24 | #include "ioctl.h" |
25 | #include "disklabel.h" | |
26 | #include "stat.h" | |
71e4e98b | 27 | |
0b4d6502 KB |
28 | #include "../ufs/quota.h" |
29 | #include "../ufs/inode.h" | |
30 | #include "../ufs/ufsmount.h" | |
31 | #include "lfs.h" | |
32 | #include "lfs_extern.h" | |
c6f5111d | 33 | |
0b4d6502 KB |
34 | static int lfs_mountfs |
35 | __P((struct vnode *, struct mount *, struct proc *)); | |
36 | static int sbupdate __P((struct ufsmount *, int)); | |
37 | ||
38 | struct vfsops lfs_vfsops = { | |
39 | lfs_mount, | |
5bf9d21f | 40 | ufs_start, |
0b4d6502 KB |
41 | lfs_unmount, |
42 | lfs_root, | |
8dc876c1 | 43 | ufs_quotactl, |
0b4d6502 KB |
44 | lfs_statfs, |
45 | lfs_sync, | |
46 | lfs_fhtovp, | |
de0d8667 | 47 | ufs_vptofh, |
0b4d6502 | 48 | lfs_init |
7188ac27 KM |
49 | }; |
50 | ||
d85a9d1b KM |
51 | /* |
52 | * Flag to allow forcible unmounting. | |
53 | */ | |
0b4d6502 | 54 | extern int doforce; /* LFS */ |
7188ac27 | 55 | |
0b4d6502 | 56 | lfs_mountroot() |
71e4e98b | 57 | { |
0b4d6502 KB |
58 | /* LFS IMPLEMENT -- lfs_mountroot */ |
59 | panic("lfs_mountroot"); | |
7188ac27 KM |
60 | } |
61 | ||
62 | /* | |
63 | * VFS Operations. | |
64 | * | |
65 | * mount system call | |
66 | */ | |
0b4d6502 | 67 | lfs_mount(mp, path, data, ndp, p) |
d45de50d | 68 | register struct mount *mp; |
7188ac27 KM |
69 | char *path; |
70 | caddr_t data; | |
71 | struct nameidata *ndp; | |
0eb6f54a | 72 | struct proc *p; |
7188ac27 KM |
73 | { |
74 | struct vnode *devvp; | |
75 | struct ufs_args args; | |
76 | struct ufsmount *ump; | |
0b4d6502 | 77 | register LFS *fs; /* LFS */ |
7188ac27 KM |
78 | u_int size; |
79 | int error; | |
80 | ||
0b4d6502 | 81 | printf("lfs_mount\n"); |
7188ac27 KM |
82 | if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) |
83 | return (error); | |
3b931949 KM |
84 | /* |
85 | * Process export requests. | |
86 | */ | |
82161bc8 KM |
87 | if ((args.exflags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) { |
88 | if (args.exflags & MNT_EXPORTED) | |
89 | mp->mnt_flag |= MNT_EXPORTED; | |
3b931949 | 90 | else |
82161bc8 KM |
91 | mp->mnt_flag &= ~MNT_EXPORTED; |
92 | if (args.exflags & MNT_EXRDONLY) | |
93 | mp->mnt_flag |= MNT_EXRDONLY; | |
3b931949 | 94 | else |
82161bc8 KM |
95 | mp->mnt_flag &= ~MNT_EXRDONLY; |
96 | mp->mnt_exroot = args.exroot; | |
3b931949 | 97 | } |
190244fb MK |
98 | /* |
99 | * If updating, check whether changing from read-only to | |
100 | * read/write; if there is no device name, that's all we do. | |
101 | */ | |
102 | if (mp->mnt_flag & MNT_UPDATE) { | |
d48157d5 | 103 | ump = VFSTOUFS(mp); |
0b4d6502 | 104 | #ifdef NOTLFS /* LFS */ |
d48157d5 | 105 | fs = ump->um_fs; |
82161bc8 | 106 | if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) |
d48157d5 | 107 | fs->fs_ronly = 0; |
0b4d6502 KB |
108 | #else |
109 | fs = ump->um_lfs; | |
110 | if (fs->lfs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0) | |
111 | fs->lfs_ronly = 0; | |
112 | #endif | |
3b931949 KM |
113 | if (args.fspec == 0) |
114 | return (0); | |
190244fb MK |
115 | } |
116 | /* | |
117 | * Not an update, or updating the name: look up the name | |
118 | * and verify that it refers to a sensible block device. | |
119 | */ | |
120 | ndp->ni_nameiop = LOOKUP | FOLLOW; | |
121 | ndp->ni_segflg = UIO_USERSPACE; | |
122 | ndp->ni_dirp = args.fspec; | |
123 | if (error = namei(ndp, p)) | |
124 | return (error); | |
125 | devvp = ndp->ni_vp; | |
126 | if (devvp->v_type != VBLK) { | |
127 | vrele(devvp); | |
128 | return (ENOTBLK); | |
129 | } | |
130 | if (major(devvp->v_rdev) >= nblkdev) { | |
131 | vrele(devvp); | |
132 | return (ENXIO); | |
133 | } | |
134 | if ((mp->mnt_flag & MNT_UPDATE) == 0) | |
0b4d6502 | 135 | error = lfs_mountfs(devvp, mp, p); /* LFS */ |
190244fb | 136 | else { |
d48157d5 KM |
137 | if (devvp != ump->um_devvp) |
138 | error = EINVAL; /* needs translation */ | |
2a7dbb09 KM |
139 | else |
140 | vrele(devvp); | |
d48157d5 | 141 | } |
7188ac27 KM |
142 | if (error) { |
143 | vrele(devvp); | |
144 | return (error); | |
27d00e76 | 145 | } |
7188ac27 | 146 | ump = VFSTOUFS(mp); |
0b4d6502 KB |
147 | fs = ump->um_lfs; /* LFS */ |
148 | #ifdef NOTLFS /* LFS */ | |
7188ac27 KM |
149 | (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); |
150 | bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); | |
82161bc8 KM |
151 | bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, |
152 | MNAMELEN); | |
153 | (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, | |
154 | &size); | |
155 | bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); | |
0eb6f54a | 156 | (void) ufs_statfs(mp, &mp->mnt_stat, p); |
0b4d6502 KB |
157 | #else |
158 | (void)copyinstr(path, fs->lfs_fsmnt, sizeof(fs->lfs_fsmnt) - 1, &size); | |
159 | bzero(fs->lfs_fsmnt + size, sizeof(fs->lfs_fsmnt) - size); | |
160 | bcopy((caddr_t)fs->lfs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, | |
161 | MNAMELEN); | |
162 | (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, | |
163 | &size); | |
164 | bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); | |
165 | (void) lfs_statfs(mp, &mp->mnt_stat, p); | |
166 | #endif | |
7188ac27 | 167 | return (0); |
71e4e98b SL |
168 | } |
169 | ||
7188ac27 KM |
170 | /* |
171 | * Common code for mount and mountroot | |
0b4d6502 | 172 | * LFS specific |
7188ac27 | 173 | */ |
0b4d6502 KB |
174 | static int |
175 | lfs_mountfs(devvp, mp, p) | |
1182ae61 | 176 | register struct vnode *devvp; |
7188ac27 | 177 | struct mount *mp; |
0eb6f54a | 178 | struct proc *p; |
71e4e98b | 179 | { |
1c26e003 | 180 | extern struct vnode *rootvp; |
0b4d6502 KB |
181 | register LFS *fs; |
182 | register struct ufsmount *ump; | |
183 | struct inode *ip; | |
184 | struct vnode *vp; | |
185 | struct buf *bp; | |
186 | struct partinfo dpart; | |
187 | daddr_t seg_addr; | |
188 | dev_t dev; | |
189 | int error, i, ronly, size; | |
71e4e98b | 190 | |
0eb6f54a | 191 | if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p)) |
7188ac27 | 192 | return (error); |
0b4d6502 | 193 | |
0eb6f54a | 194 | if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) |
609e7cfa | 195 | size = DEV_BSIZE; |
0eb6f54a | 196 | else { |
ec67a3ce | 197 | size = dpart.disklab->d_secsize; |
0b4d6502 KB |
198 | #ifdef NEVER_USED |
199 | dpart.part->p_fstype = FS_LFS; | |
200 | dpart.part->p_fsize = fs->lfs_fsize; /* frag size */ | |
201 | dpart.part->p_frag = fs->lfs_frag; /* frags per block */ | |
202 | dpart.part->p_cpg = fs->lfs_segshift; /* segment shift */ | |
203 | #endif | |
7188ac27 | 204 | } |
0b4d6502 KB |
205 | |
206 | /* Don't free random space on error. */ | |
207 | bp = NULL; | |
208 | ump = NULL; | |
209 | ||
210 | /* Read in the superblock. */ | |
211 | if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, NOCRED, &bp)) | |
71e4e98b | 212 | goto out; |
8dc876c1 | 213 | error = EINVAL; /* XXX needs translation */ |
1c281610 MK |
214 | goto out; |
215 | } | |
0b4d6502 KB |
216 | #ifdef DEBUG |
217 | dump_super(fs); | |
218 | #endif | |
219 | ||
220 | /* Allocate the mount structure, copy the superblock into it. */ | |
8dc876c1 | 221 | ump = (struct ufsmount *)malloc(sizeof *ump, M_UFSMNT, M_WAITOK); |
0b4d6502 KB |
222 | ump->um_lfs = malloc(sizeof(LFS), M_SUPERBLK, M_WAITOK); |
223 | bcopy(bp->b_un.b_addr, ump->um_lfs, sizeof(LFS)); | |
224 | if (sizeof(LFS) < LFS_SBPAD) /* XXX why? */ | |
5d96a9ad | 225 | bp->b_flags |= B_INVAL; |
e018935f MK |
226 | brelse(bp); |
227 | bp = NULL; | |
0b4d6502 KB |
228 | |
229 | /* Set the file system readonly/modify bits. */ | |
230 | fs = ump->um_lfs; | |
231 | fs->lfs_ronly = ronly; | |
71e4e98b | 232 | if (ronly == 0) |
0b4d6502 KB |
233 | fs->lfs_fmod = 1; |
234 | ||
235 | /* Initialize the mount structure. */ | |
236 | dev = devvp->v_rdev; | |
82161bc8 KM |
237 | mp->mnt_data = (qaddr_t)ump; |
238 | mp->mnt_stat.f_fsid.val[0] = (long)dev; | |
0b4d6502 | 239 | mp->mnt_stat.f_fsid.val[1] = MOUNT_LFS; |
82161bc8 | 240 | mp->mnt_flag |= MNT_LOCAL; |
7188ac27 KM |
241 | ump->um_mountp = mp; |
242 | ump->um_dev = dev; | |
243 | ump->um_devvp = devvp; | |
8dc876c1 KM |
244 | for (i = 0; i < MAXQUOTAS; i++) |
245 | ump->um_quotas[i] = NULLVP; | |
7188ac27 | 246 | |
0b4d6502 KB |
247 | /* Read the ifile disk inode and store it in a vnode. */ |
248 | error = bread(devvp, fs->lfs_idaddr, fs->lfs_bsize, NOCRED, &bp); | |
249 | if (error) | |
250 | goto out; | |
251 | error = lfs_vcreate(mp, LFS_IFILE_INUM, &vp); | |
252 | if (error) | |
253 | goto out; | |
254 | ip = VTOI(vp); | |
255 | ||
256 | /* The ifile inode is stored in the superblock. */ | |
257 | fs->lfs_ivnode = vp; | |
258 | ||
259 | /* Copy the on-disk inode into place. */ | |
260 | ip->i_din = *lfs_ifind(fs, LFS_IFILE_INUM, bp->b_un.b_dino); | |
261 | brelse(bp); | |
262 | ||
263 | /* Initialize the associated vnode */ | |
264 | vp->v_type = IFTOVT(ip->i_mode); | |
265 | ||
266 | /* | |
267 | * Read in the segusage table. | |
268 | * | |
269 | * Since we always explicitly write the segusage table at a checkpoint, | |
270 | * we're assuming that it is continguous on disk. | |
271 | */ | |
272 | seg_addr = ip->i_din.di_db[0]; | |
273 | size = fs->lfs_segtabsz << fs->lfs_bshift; | |
274 | fs->lfs_segtab = malloc(size, M_SUPERBLK, M_WAITOK); | |
275 | error = bread(devvp, seg_addr, size, NOCRED, &bp); | |
276 | if (error) { | |
277 | free(fs->lfs_segtab, M_SUPERBLK); | |
278 | goto out; | |
279 | } | |
280 | bcopy((caddr_t)bp->b_un.b_addr, fs->lfs_segtab, size); | |
281 | brelse(bp); | |
282 | devvp->v_specflags |= SI_MOUNTEDON; | |
283 | VREF(ip->i_devvp); | |
609e7cfa | 284 | |
7188ac27 | 285 | return (0); |
71e4e98b | 286 | out: |
c86c9b6e KM |
287 | if (bp) |
288 | brelse(bp); | |
0b4d6502 | 289 | (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); |
8dc876c1 | 290 | if (ump) { |
0b4d6502 | 291 | free((caddr_t)ump->um_lfs, M_SUPERBLK); |
8dc876c1 | 292 | free((caddr_t)ump, M_UFSMNT); |
82161bc8 | 293 | mp->mnt_data = (qaddr_t)0; |
27d00e76 | 294 | } |
7188ac27 | 295 | return (error); |
71e4e98b SL |
296 | } |
297 | ||
7188ac27 KM |
298 | /* |
299 | * unmount system call | |
300 | */ | |
0b4d6502 | 301 | lfs_unmount(mp, mntflags, p) |
7188ac27 | 302 | struct mount *mp; |
8dc876c1 | 303 | int mntflags; |
0eb6f54a | 304 | struct proc *p; |
71e4e98b | 305 | { |
7188ac27 | 306 | register struct ufsmount *ump; |
0b4d6502 | 307 | register struct lfs *fs; /* LFS */ |
8dc876c1 | 308 | int i, error, ronly, flags = 0; |
71e4e98b | 309 | |
0b4d6502 | 310 | printf("lfs_unmount\n"); |
87be6db2 | 311 | if (mntflags & MNT_FORCE) { |
d85a9d1b | 312 | if (!doforce || mp == rootfs) |
87be6db2 | 313 | return (EINVAL); |
8dc876c1 | 314 | flags |= FORCECLOSE; |
87be6db2 | 315 | } |
5d96a9ad KM |
316 | mntflushbuf(mp, 0); |
317 | if (mntinvalbuf(mp)) | |
318 | return (EBUSY); | |
7188ac27 | 319 | ump = VFSTOUFS(mp); |
ec67a3ce | 320 | return (error); |
71e4e98b | 321 | #ifdef QUOTA |
82161bc8 | 322 | if (mp->mnt_flag & MNT_QUOTA) { |
8dc876c1 | 323 | if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) |
6d943995 | 324 | return (error); |
8dc876c1 KM |
325 | for (i = 0; i < MAXQUOTAS; i++) { |
326 | if (ump->um_quotas[i] == NULLVP) | |
327 | continue; | |
70a360ba | 328 | quotaoff(p, mp, i); |
8dc876c1 | 329 | } |
6d943995 | 330 | /* |
8dc876c1 KM |
331 | * Here we fall through to vflush again to ensure |
332 | * that we have gotten rid of all the system vnodes. | |
6d943995 | 333 | */ |
8dc876c1 | 334 | } |
71e4e98b | 335 | #endif |
8dc876c1 | 336 | if (error = vflush(mp, NULLVP, flags)) |
6d943995 | 337 | return (error); |
0b4d6502 | 338 | #ifdef NOTLFS /* LFS */ |
7188ac27 KM |
339 | fs = ump->um_fs; |
340 | ronly = !fs->fs_ronly; | |
0b4d6502 KB |
341 | #else |
342 | fs = ump->um_lfs; | |
343 | ronly = !fs->lfs_ronly; | |
344 | #endif | |
7188ac27 KM |
345 | * Return root of a filesystem |
346 | */ | |
0b4d6502 | 347 | lfs_root(mp, vpp) |
7188ac27 KM |
348 | struct mount *mp; |
349 | struct vnode **vpp; | |
350 | { | |
31593ba7 KM |
351 | register struct inode *ip; |
352 | struct inode *nip; | |
353 | struct vnode tvp; | |
7188ac27 KM |
354 | int error; |
355 | ||
0b4d6502 | 356 | printf("lfs_root\n"); |
31593ba7 KM |
357 | tvp.v_mount = mp; |
358 | ip = VTOI(&tvp); | |
359 | ip->i_vnode = &tvp; | |
360 | ip->i_dev = VFSTOUFS(mp)->um_dev; | |
0b4d6502 | 361 | error = lfs_iget(ip, (ino_t)ROOTINO, &nip); /* LFS */ |
7188ac27 KM |
362 | if (error) |
363 | return (error); | |
31593ba7 | 364 | *vpp = ITOV(nip); |
7188ac27 KM |
365 | return (0); |
366 | } | |
367 | ||
368 | /* | |
369 | * Get file system statistics. | |
370 | */ | |
0b4d6502 | 371 | lfs_statfs(mp, sbp, p) |
7188ac27 KM |
372 | struct mount *mp; |
373 | register struct statfs *sbp; | |
0eb6f54a | 374 | struct proc *p; |
7188ac27 | 375 | { |
0b4d6502 | 376 | register LFS *fs; |
7188ac27 | 377 | register struct ufsmount *ump; |
7188ac27 | 378 | |
0b4d6502 | 379 | printf("lfs_statfs\n"); |
7188ac27 | 380 | ump = VFSTOUFS(mp); |
0b4d6502 | 381 | #ifdef NOTLFS /* LFS */ |
7188ac27 KM |
382 | fs = ump->um_fs; |
383 | if (fs->fs_magic != FS_MAGIC) | |
384 | panic("ufs_statfs"); | |
385 | sbp->f_type = MOUNT_UFS; | |
7188ac27 KM |
386 | sbp->f_fsize = fs->fs_fsize; |
387 | sbp->f_bsize = fs->fs_bsize; | |
388 | sbp->f_blocks = fs->fs_dsize; | |
389 | sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + | |
390 | fs->fs_cstotal.cs_nffree; | |
391 | sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) - | |
392 | (fs->fs_dsize - sbp->f_bfree); | |
5c41c19e | 393 | sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; |
7188ac27 | 394 | sbp->f_ffree = fs->fs_cstotal.cs_nifree; |
0b4d6502 KB |
395 | #else |
396 | fs = ump->um_lfs; | |
397 | if (fs->lfs_magic != LFS_MAGIC) | |
398 | panic("lfs_statfs: magic"); | |
399 | sbp->f_type = MOUNT_LFS; | |
400 | sbp->f_fsize = fs->lfs_bsize; | |
401 | sbp->f_bsize = fs->lfs_bsize; | |
402 | sbp->f_blocks = fs->lfs_dsize; | |
403 | sbp->f_bfree = fs->lfs_bfree; | |
404 | sbp->f_bavail = (fs->lfs_dsize * (100 - fs->lfs_minfree) / 100) - | |
405 | (fs->lfs_dsize - sbp->f_bfree); | |
406 | sbp->f_files = fs->lfs_nfiles; | |
407 | sbp->f_ffree = fs->lfs_bfree * INOPB(fs); | |
408 | #endif | |
82161bc8 KM |
409 | if (sbp != &mp->mnt_stat) { |
410 | bcopy((caddr_t)mp->mnt_stat.f_mntonname, | |
d45de50d | 411 | (caddr_t)&sbp->f_mntonname[0], MNAMELEN); |
82161bc8 | 412 | bcopy((caddr_t)mp->mnt_stat.f_mntfromname, |
d45de50d KM |
413 | (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); |
414 | } | |
7188ac27 KM |
415 | return (0); |
416 | } | |
417 | ||
0b4d6502 | 418 | extern int syncprt; /* LFS */ |
7188ac27 KM |
419 | |
420 | /* | |
421 | * Go through the disk queues to initiate sandbagged IO; | |
422 | * go through the inodes to write those that have been modified; | |
423 | * initiate the writing of the super block if it has been modified. | |
8dc876c1 KM |
424 | * |
425 | * Note: we are always called with the filesystem marked `MPBUSY'. | |
7188ac27 | 426 | */ |
0b4d6502 | 427 | lfs_sync(mp, waitfor) |
71e4e98b | 428 | struct mount *mp; |
7188ac27 | 429 | int waitfor; |
71e4e98b | 430 | { |
31593ba7 | 431 | register struct vnode *vp; |
7188ac27 KM |
432 | register struct inode *ip; |
433 | register struct ufsmount *ump = VFSTOUFS(mp); | |
434 | register struct fs *fs; | |
812b91f3 | 435 | int error, allerror = 0; |
7188ac27 | 436 | |
0b4d6502 | 437 | printf("lfs_sync\n"); |
7188ac27 KM |
438 | if (syncprt) |
439 | bufstats(); | |
0b4d6502 | 440 | #ifdef NOTLFS /* LFS */ |
7188ac27 | 441 | fs = ump->um_fs; |
7188ac27 KM |
442 | /* |
443 | * Write back modified superblock. | |
444 | * Consistency check that the superblock | |
445 | * is still in the buffer cache. | |
446 | */ | |
447 | if (fs->fs_fmod != 0) { | |
448 | if (fs->fs_ronly != 0) { /* XXX */ | |
449 | printf("fs = %s\n", fs->fs_fsmnt); | |
450 | panic("update: rofs mod"); | |
451 | } | |
452 | fs->fs_fmod = 0; | |
453 | fs->fs_time = time.tv_sec; | |
881f1b87 | 454 | allerror = sbupdate(ump, waitfor); |
7188ac27 | 455 | } |
0b4d6502 KB |
456 | #else |
457 | #ifdef DEBUG | |
458 | return (0); | |
459 | #else | |
460 | /* LFS IMPLEMENT -- read only access, super-block update */ | |
461 | panic("lfs_sync not implemented"); */ | |
462 | #endif | |
463 | #endif | |
7188ac27 KM |
464 | /* |
465 | * Write back each (modified) inode. | |
466 | */ | |
25b5cf58 | 467 | loop: |
a242f429 KM |
468 | for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) { |
469 | /* | |
470 | * If the vnode that we are about to sync is no longer | |
471 | * associated with this mount point, start over. | |
472 | */ | |
473 | if (vp->v_mount != mp) | |
474 | goto loop; | |
d85a9d1b KM |
475 | if (VOP_ISLOCKED(vp)) |
476 | continue; | |
31593ba7 | 477 | ip = VTOI(vp); |
25b5cf58 KM |
478 | if ((ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0 && |
479 | vp->v_dirtyblkhd == NULL) | |
7188ac27 | 480 | continue; |
25b5cf58 KM |
481 | if (vget(vp)) |
482 | goto loop; | |
483 | if (vp->v_dirtyblkhd) | |
484 | vflushbuf(vp, 0); | |
485 | if ((ip->i_flag & (IMOD|IACC|IUPD|ICHG)) && | |
0b4d6502 | 486 | (error = lfs_iupdat(ip, &time, &time, 0))) /* LFS */ |
812b91f3 KM |
487 | allerror = error; |
488 | vput(vp); | |
7188ac27 | 489 | } |
7188ac27 | 490 | /* |
5d96a9ad | 491 | * Force stale file system control information to be flushed. |
7188ac27 | 492 | */ |
5d96a9ad | 493 | vflushbuf(ump->um_devvp, waitfor == MNT_WAIT ? B_SYNC : 0); |
8dc876c1 KM |
494 | #ifdef QUOTA |
495 | qsync(mp); | |
496 | #endif | |
812b91f3 | 497 | return (allerror); |
7188ac27 KM |
498 | } |
499 | ||
0b4d6502 | 500 | static int |
7188ac27 KM |
501 | sbupdate(mp, waitfor) |
502 | struct ufsmount *mp; | |
503 | int waitfor; | |
504 | { | |
0b4d6502 KB |
505 | /* LFS IMPLEMENT -- sbupdate */ |
506 | panic("sbupdate not implemented"); | |
7188ac27 KM |
507 | } |
508 | ||
509 | /* | |
510 | * File handle to vnode | |
113c35f2 KM |
511 | * |
512 | * Have to be really careful about stale file handles: | |
513 | * - check that the inode number is in range | |
514 | * - call iget() to get the locked inode | |
515 | * - check for an unallocated inode (i_mode == 0) | |
516 | * - check that the generation number matches | |
7188ac27 | 517 | */ |
0b4d6502 | 518 | lfs_fhtovp(mp, fhp, vpp) |
113c35f2 | 519 | register struct mount *mp; |
7188ac27 KM |
520 | struct fid *fhp; |
521 | struct vnode **vpp; | |
522 | { | |
523 | register struct ufid *ufhp; | |
0b4d6502 | 524 | register struct lfs *fs; /* LFS */ |
31593ba7 | 525 | register struct inode *ip; |
0b4d6502 KB |
526 | IFILE *ifp; |
527 | struct buf *bp; | |
31593ba7 KM |
528 | struct inode *nip; |
529 | struct vnode tvp; | |
7188ac27 KM |
530 | int error; |
531 | ||
532 | ufhp = (struct ufid *)fhp; | |
0b4d6502 | 533 | #ifdef NOTLFS /* LFS */ |
113c35f2 KM |
534 | fs = VFSTOUFS(mp)->um_fs; |
535 | if (ufhp->ufid_ino < ROOTINO || | |
536 | ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) { | |
82161bc8 | 537 | *vpp = NULLVP; |
113c35f2 KM |
538 | return (EINVAL); |
539 | } | |
0b4d6502 KB |
540 | #else |
541 | fs = VFSTOUFS(mp)->um_lfs; | |
542 | if (ufhp->ufid_ino < ROOTINO) { | |
543 | *vpp = NULLVP; | |
544 | return (EINVAL); | |
545 | } | |
546 | #endif | |
31593ba7 KM |
547 | tvp.v_mount = mp; |
548 | ip = VTOI(&tvp); | |
549 | ip->i_vnode = &tvp; | |
550 | ip->i_dev = VFSTOUFS(mp)->um_dev; | |
0b4d6502 | 551 | if (error = lfs_iget(ip, ufhp->ufid_ino, &nip)) { /* LFS */ |
82161bc8 | 552 | *vpp = NULLVP; |
7188ac27 KM |
553 | return (error); |
554 | } | |
31593ba7 | 555 | ip = nip; |
113c35f2 KM |
556 | if (ip->i_mode == 0) { |
557 | iput(ip); | |
82161bc8 | 558 | *vpp = NULLVP; |
113c35f2 KM |
559 | return (EINVAL); |
560 | } | |
7188ac27 KM |
561 | if (ip->i_gen != ufhp->ufid_gen) { |
562 | iput(ip); | |
82161bc8 | 563 | *vpp = NULLVP; |
7188ac27 KM |
564 | return (EINVAL); |
565 | } | |
566 | *vpp = ITOV(ip); | |
567 | return (0); | |
568 | } |