ffs_vget moves to ffs_vfsops.c; add parameter declarations;
[unix-history] / usr / src / sys / ufs / ffs / ffs_vfsops.c
CommitLineData
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 *
cb09ceb4 7 * @(#)ffs_vfsops.c 7.70 (Berkeley) %G%
da7c5cc6 8 */
71e4e98b 9
ab9f4fb0
KB
10#include <sys/param.h>
11#include <sys/systm.h>
12#include <sys/namei.h>
13#include <sys/proc.h>
14#include <sys/kernel.h>
15#include <sys/vnode.h>
16#include <sys/specdev.h>
17#include <sys/mount.h>
18#include <sys/buf.h>
19#include <sys/file.h>
20#include <sys/disklabel.h>
21#include <sys/ioctl.h>
22#include <sys/errno.h>
23#include <sys/malloc.h>
609e7cfa
MK
24#include "ioctl.h"
25#include "disklabel.h"
26#include "stat.h"
71e4e98b 27
ab9f4fb0
KB
28#include <ufs/ufs/quota.h>
29#include <ufs/ufs/ufsmount.h>
30#include <ufs/ufs/inode.h>
31#include <ufs/ufs/ufs_extern.h>
32
33#include <ufs/ffs/fs.h>
34#include <ufs/ffs/ffs_extern.h>
35
06445aba 36int ffs_sbupdate __P((struct ufsmount *, int));
c6f5111d 37
7188ac27 38struct vfsops ufs_vfsops = {
ab9f4fb0 39 ffs_mount,
5bf9d21f 40 ufs_start,
ab9f4fb0 41 ffs_unmount,
a9013e03 42 ffs_root,
8dc876c1 43 ufs_quotactl,
ab9f4fb0
KB
44 ffs_statfs,
45 ffs_sync,
a9013e03
KM
46 ffs_fhtovp,
47 ffs_vptofh,
ab9f4fb0 48 ffs_init,
7188ac27
KM
49};
50
7188ac27 51/*
4ac55ebc 52 * Called by main() when ufs is going to be mounted as root.
7188ac27 53 *
d48157d5 54 * Name is updated by mount(8) after booting.
7188ac27 55 */
8a4911ca 56#define ROOTNAME "root_device"
7188ac27 57
ab9f4fb0 58ffs_mountroot()
71e4e98b 59{
7188ac27 60 extern struct vnode *rootvp;
ab9f4fb0
KB
61 register struct fs *fs;
62 register struct mount *mp;
0eb6f54a 63 struct proc *p = curproc; /* XXX */
7188ac27 64 struct ufsmount *ump;
7188ac27
KM
65 u_int size;
66 int error;
71e4e98b 67
4ac55ebc 68 mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
ea301039 69 bzero((char *)mp, (u_long)sizeof(struct mount));
82161bc8
KM
70 mp->mnt_op = &ufs_vfsops;
71 mp->mnt_flag = MNT_RDONLY;
ab9f4fb0
KB
72 if (error = ffs_mountfs(rootvp, mp, p)) {
73 free(mp, M_MOUNT);
7188ac27 74 return (error);
71e4e98b 75 }
d48157d5 76 if (error = vfs_lock(mp)) {
ab9f4fb0
KB
77 (void)ffs_unmount(mp, 0, p);
78 free(mp, M_MOUNT);
7188ac27 79 return (error);
6d07f4cd 80 }
d48157d5 81 rootfs = mp;
82161bc8
KM
82 mp->mnt_next = mp;
83 mp->mnt_prev = mp;
84 mp->mnt_vnodecovered = NULLVP;
7188ac27
KM
85 ump = VFSTOUFS(mp);
86 fs = ump->um_fs;
d45de50d 87 bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
7188ac27 88 fs->fs_fsmnt[0] = '/';
82161bc8
KM
89 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
90 MNAMELEN);
91 (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
92 &size);
93 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
ab9f4fb0 94 (void)ffs_statfs(mp, &mp->mnt_stat, p);
7188ac27
KM
95 vfs_unlock(mp);
96 inittodr(fs->fs_time);
97 return (0);
98}
99
100/*
101 * VFS Operations.
102 *
103 * mount system call
104 */
06445aba 105int
ab9f4fb0 106ffs_mount(mp, path, data, ndp, p)
d45de50d 107 register struct mount *mp;
7188ac27
KM
108 char *path;
109 caddr_t data;
110 struct nameidata *ndp;
0eb6f54a 111 struct proc *p;
7188ac27
KM
112{
113 struct vnode *devvp;
114 struct ufs_args args;
115 struct ufsmount *ump;
116 register struct fs *fs;
117 u_int size;
118 int error;
119
120 if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
121 return (error);
190244fb
MK
122 /*
123 * If updating, check whether changing from read-only to
124 * read/write; if there is no device name, that's all we do.
125 */
126 if (mp->mnt_flag & MNT_UPDATE) {
d48157d5
KM
127 ump = VFSTOUFS(mp);
128 fs = ump->um_fs;
82161bc8 129 if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
d48157d5 130 fs->fs_ronly = 0;
c906fba1
KM
131 if (args.fspec == 0) {
132 /*
133 * Process export requests.
134 */
135 if (args.exflags & MNT_EXPORTED) {
cb09ceb4 136 if (error = ufs_hang_addrlist(mp, &args))
c906fba1
KM
137 return (error);
138 mp->mnt_flag |= MNT_EXPORTED;
139 }
140 if (args.exflags & MNT_DELEXPORT) {
cb09ceb4 141 ufs_free_addrlist(ump);
c906fba1
KM
142 mp->mnt_flag &=
143 ~(MNT_EXPORTED | MNT_DEFEXPORTED);
144 }
3b931949 145 return (0);
c906fba1 146 }
190244fb
MK
147 }
148 /*
149 * Not an update, or updating the name: look up the name
150 * and verify that it refers to a sensible block device.
151 */
995e59df
KM
152 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
153 if (error = namei(ndp))
190244fb
MK
154 return (error);
155 devvp = ndp->ni_vp;
ab9f4fb0 156
190244fb
MK
157 if (devvp->v_type != VBLK) {
158 vrele(devvp);
159 return (ENOTBLK);
160 }
161 if (major(devvp->v_rdev) >= nblkdev) {
162 vrele(devvp);
163 return (ENXIO);
164 }
165 if ((mp->mnt_flag & MNT_UPDATE) == 0)
ab9f4fb0 166 error = ffs_mountfs(devvp, mp, p);
190244fb 167 else {
d48157d5
KM
168 if (devvp != ump->um_devvp)
169 error = EINVAL; /* needs translation */
2a7dbb09
KM
170 else
171 vrele(devvp);
d48157d5 172 }
7188ac27
KM
173 if (error) {
174 vrele(devvp);
175 return (error);
27d00e76 176 }
7188ac27
KM
177 ump = VFSTOUFS(mp);
178 fs = ump->um_fs;
179 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
180 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
82161bc8
KM
181 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
182 MNAMELEN);
183 (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
184 &size);
185 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
ab9f4fb0 186 (void)ffs_statfs(mp, &mp->mnt_stat, p);
7188ac27 187 return (0);
71e4e98b
SL
188}
189
7188ac27
KM
190/*
191 * Common code for mount and mountroot
192 */
ab9f4fb0
KB
193int
194ffs_mountfs(devvp, mp, p)
1182ae61 195 register struct vnode *devvp;
7188ac27 196 struct mount *mp;
0eb6f54a 197 struct proc *p;
71e4e98b 198{
9342689a
JH
199 USES_VOP_CLOSE;
200 USES_VOP_IOCTL;
201 USES_VOP_OPEN;
6b50a7c5
KM
202 register struct ufsmount *ump;
203 struct buf *bp;
71e4e98b 204 register struct fs *fs;
7188ac27 205 dev_t dev = devvp->v_rdev;
ec67a3ce
MK
206 struct partinfo dpart;
207 int havepart = 0, blks;
27d00e76 208 caddr_t base, space;
7188ac27
KM
209 int havepart = 0, blks;
210 int error, i, size;
6b50a7c5 211 int ronly;
1c26e003 212 extern struct vnode *rootvp;
71e4e98b 213
0eb6f54a 214 if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p))
7188ac27 215 return (error);
0eb6f54a 216 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
609e7cfa 217 size = DEV_BSIZE;
0eb6f54a 218 else {
ec67a3ce
MK
219 havepart = 1;
220 size = dpart.disklab->d_secsize;
7188ac27 221 }
6b50a7c5
KM
222
223 bp = NULL;
224 ump = NULL;
8dc876c1 225 if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp))
71e4e98b 226 goto out;
e018935f 227 fs = bp->b_un.b_fs;
8dc876c1 228 error = EINVAL; /* XXX needs translation */
1c281610
MK
229 goto out;
230 }
ab9f4fb0 231 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
7bff53ea 232 bzero((caddr_t)ump, sizeof *ump);
b1ca3fbf 233 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
5adcb337 234 M_WAITOK);
7188ac27 235 bcopy((caddr_t)bp->b_un.b_addr, (caddr_t)ump->um_fs,
71e4e98b 236 (u_int)fs->fs_sbsize);
5d96a9ad
KM
237 if (fs->fs_sbsize < SBSIZE)
238 bp->b_flags |= B_INVAL;
e018935f
MK
239 brelse(bp);
240 bp = NULL;
7188ac27
KM
241 fs = ump->um_fs;
242 fs->fs_ronly = ronly;
71e4e98b
SL
243 if (ronly == 0)
244 fs->fs_fmod = 1;
609e7cfa
MK
245 if (havepart) {
246 dpart.part->p_fstype = FS_BSDFFS;
247 dpart.part->p_fsize = fs->fs_fsize;
248 dpart.part->p_frag = fs->fs_frag;
42ff4c2e 249 dpart.part->p_cpg = fs->fs_cpg;
609e7cfa 250 }
ec67a3ce
MK
251#ifdef SECSIZE
252 /*
253 * If we have a disk label, force per-partition
254 * filesystem information to be correct
255 * and set correct current fsbtodb shift.
256 */
257#endif SECSIZE
258 if (havepart) {
259 dpart.part->p_fstype = FS_BSDFFS;
260 dpart.part->p_fsize = fs->fs_fsize;
261 dpart.part->p_frag = fs->fs_frag;
262#ifdef SECSIZE
263#ifdef tahoe
264 /*
265 * Save the original fsbtodb shift to restore on updates.
266 * (Console doesn't understand fsbtodb changes.)
267 */
268 fs->fs_sparecon[0] = fs->fs_fsbtodb;
269#endif
270 i = fs->fs_fsize / size;
271 for (fs->fs_fsbtodb = 0; i > 1; i >>= 1)
272 fs->fs_fsbtodb++;
273#endif SECSIZE
274 fs->fs_dbsize = size;
275 }
71e4e98b 276 blks = howmany(fs->fs_cssize, fs->fs_fsize);
b1ca3fbf 277 base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT,
5adcb337 278 M_WAITOK);
71e4e98b
SL
279 for (i = 0; i < blks; i += fs->fs_frag) {
280 size = fs->fs_bsize;
281 if (i + fs->fs_frag > blks)
282 size = (blks - i) * fs->fs_fsize;
ec67a3ce
MK
283#ifdef SECSIZE
284 tp = bread(dev, fsbtodb(fs, fs->fs_csaddr + i), size,
285 fs->fs_dbsize);
286#else SECSIZE
a937f856
KM
287 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
288 NOCRED, &bp);
7188ac27 289 if (error) {
b1ca3fbf 290 free(base, M_UFSMNT);
71e4e98b
SL
291 goto out;
292 }
e018935f 293 bcopy((caddr_t)bp->b_un.b_addr, space, (u_int)size);
60f9c9e3 294 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space;
71e4e98b 295 space += size;
e018935f
MK
296 brelse(bp);
297 bp = NULL;
71e4e98b 298 }
82161bc8
KM
299 mp->mnt_data = (qaddr_t)ump;
300 mp->mnt_stat.f_fsid.val[0] = (long)dev;
301 mp->mnt_stat.f_fsid.val[1] = MOUNT_UFS;
ea301039 302 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
82161bc8 303 mp->mnt_flag |= MNT_LOCAL;
7188ac27
KM
304 ump->um_mountp = mp;
305 ump->um_dev = dev;
306 ump->um_devvp = devvp;
8dc876c1
KM
307 for (i = 0; i < MAXQUOTAS; i++)
308 ump->um_quotas[i] = NULLVP;
0f93ba7b 309 devvp->v_specflags |= SI_MOUNTEDON;
7188ac27 310
94354803
KM
311 /* Sanity checks for old file systems. XXX */
312 fs->fs_npsect = MAX(fs->fs_npsect, fs->fs_nsect); /* XXX */
313 fs->fs_interleave = MAX(fs->fs_interleave, 1); /* XXX */
2af59000
KM
314 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
315 fs->fs_nrpos = 8; /* XXX */
4605fb61
KM
316 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
317 quad_t sizepb = fs->fs_bsize; /* XXX */
318 /* XXX */
319 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
320 for (i = 0; i < NIADDR; i++) { /* XXX */
321 sizepb *= NINDIR(fs); /* XXX */
322 fs->fs_maxfilesize += sizepb; /* XXX */
323 } /* XXX */
324 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
325 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
326 } /* XXX */
609e7cfa 327
7188ac27 328 return (0);
71e4e98b 329out:
c86c9b6e
KM
330 if (bp)
331 brelse(bp);
3a328e36 332 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
8dc876c1 333 if (ump) {
b1ca3fbf 334 free(ump->um_fs, M_UFSMNT);
ab9f4fb0 335 free(ump, M_UFSMNT);
82161bc8 336 mp->mnt_data = (qaddr_t)0;
27d00e76 337 }
7188ac27 338 return (error);
71e4e98b
SL
339}
340
7188ac27
KM
341/*
342 * unmount system call
343 */
ab9f4fb0
KB
344int
345ffs_unmount(mp, mntflags, p)
7188ac27 346 struct mount *mp;
8dc876c1 347 int mntflags;
0eb6f54a 348 struct proc *p;
71e4e98b 349{
9342689a 350 USES_VOP_CLOSE;
ab9f4fb0 351 extern int doforce;
7188ac27 352 register struct ufsmount *ump;
71e4e98b 353 register struct fs *fs;
6b50a7c5 354 int i, error, flags, ronly;
71e4e98b 355
6b50a7c5 356 flags = 0;
87be6db2 357 if (mntflags & MNT_FORCE) {
d85a9d1b 358 if (!doforce || mp == rootfs)
87be6db2 359 return (EINVAL);
8dc876c1 360 flags |= FORCECLOSE;
87be6db2 361 }
7188ac27 362 ump = VFSTOUFS(mp);
ec67a3ce 363 return (error);
71e4e98b 364#ifdef QUOTA
82161bc8 365 if (mp->mnt_flag & MNT_QUOTA) {
8dc876c1 366 if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags))
6d943995 367 return (error);
8dc876c1
KM
368 for (i = 0; i < MAXQUOTAS; i++) {
369 if (ump->um_quotas[i] == NULLVP)
370 continue;
70a360ba 371 quotaoff(p, mp, i);
8dc876c1 372 }
6d943995 373 /*
8dc876c1
KM
374 * Here we fall through to vflush again to ensure
375 * that we have gotten rid of all the system vnodes.
6d943995 376 */
8dc876c1 377 }
71e4e98b 378#endif
8dc876c1 379 if (error = vflush(mp, NULLVP, flags))
6d943995 380 return (error);
7188ac27
KM
381 fs = ump->um_fs;
382 ronly = !fs->fs_ronly;
7188ac27
KM
383 * Get file system statistics.
384 */
ab9f4fb0
KB
385int
386ffs_statfs(mp, sbp, p)
7188ac27
KM
387 struct mount *mp;
388 register struct statfs *sbp;
0eb6f54a 389 struct proc *p;
7188ac27
KM
390{
391 register struct ufsmount *ump;
392 register struct fs *fs;
393
394 ump = VFSTOUFS(mp);
395 fs = ump->um_fs;
396 if (fs->fs_magic != FS_MAGIC)
ab9f4fb0 397 panic("ffs_statfs");
7188ac27 398 sbp->f_type = MOUNT_UFS;
06445aba
KM
399 sbp->f_bsize = fs->fs_fsize;
400 sbp->f_iosize = fs->fs_bsize;
7188ac27
KM
401 sbp->f_blocks = fs->fs_dsize;
402 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
403 fs->fs_cstotal.cs_nffree;
404 sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) -
405 (fs->fs_dsize - sbp->f_bfree);
5c41c19e 406 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
7188ac27 407 sbp->f_ffree = fs->fs_cstotal.cs_nifree;
82161bc8
KM
408 if (sbp != &mp->mnt_stat) {
409 bcopy((caddr_t)mp->mnt_stat.f_mntonname,
d45de50d 410 (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
82161bc8 411 bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
d45de50d
KM
412 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
413 }
7188ac27
KM
414 return (0);
415}
416
7188ac27
KM
417/*
418 * Go through the disk queues to initiate sandbagged IO;
419 * go through the inodes to write those that have been modified;
420 * initiate the writing of the super block if it has been modified.
8dc876c1
KM
421 *
422 * Note: we are always called with the filesystem marked `MPBUSY'.
7188ac27 423 */
ab9f4fb0 424int
6b50a7c5 425ffs_sync(mp, waitfor, cred, p)
71e4e98b 426 struct mount *mp;
7188ac27 427 int waitfor;
6b50a7c5
KM
428 struct ucred *cred;
429 struct proc *p;
71e4e98b 430{
9342689a 431 USES_VOP_ISLOCKED;
6b50a7c5 432 USES_VOP_FSYNC;
ab9f4fb0 433 extern int syncprt;
31593ba7 434 register struct vnode *vp;
7188ac27
KM
435 register struct inode *ip;
436 register struct ufsmount *ump = VFSTOUFS(mp);
437 register struct fs *fs;
812b91f3 438 int error, allerror = 0;
7188ac27
KM
439
440 if (syncprt)
ab9f4fb0 441 ufs_bufstats();
7188ac27 442 fs = ump->um_fs;
7188ac27
KM
443 /*
444 * Write back modified superblock.
445 * Consistency check that the superblock
446 * is still in the buffer cache.
447 */
448 if (fs->fs_fmod != 0) {
449 if (fs->fs_ronly != 0) { /* XXX */
450 printf("fs = %s\n", fs->fs_fsmnt);
451 panic("update: rofs mod");
452 }
453 fs->fs_fmod = 0;
454 fs->fs_time = time.tv_sec;
ab9f4fb0 455 allerror = ffs_sbupdate(ump, waitfor);
7188ac27
KM
456 }
457 /*
458 * Write back each (modified) inode.
459 */
25b5cf58 460loop:
a242f429
KM
461 for (vp = mp->mnt_mounth; vp; vp = vp->v_mountf) {
462 /*
463 * If the vnode that we are about to sync is no longer
464 * associated with this mount point, start over.
465 */
466 if (vp->v_mount != mp)
467 goto loop;
d85a9d1b
KM
468 if (VOP_ISLOCKED(vp))
469 continue;
31593ba7 470 ip = VTOI(vp);
25b5cf58
KM
471 if ((ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0 &&
472 vp->v_dirtyblkhd == NULL)
7188ac27 473 continue;
25b5cf58
KM
474 if (vget(vp))
475 goto loop;
6b50a7c5 476 if (error = VOP_FSYNC(vp, cred, waitfor, p))
812b91f3
KM
477 allerror = error;
478 vput(vp);
7188ac27 479 }
7188ac27 480 /*
5d96a9ad 481 * Force stale file system control information to be flushed.
7188ac27 482 */
6b50a7c5
KM
483 if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p))
484 allerror = error;
8dc876c1
KM
485#ifdef QUOTA
486 qsync(mp);
487#endif
812b91f3 488 return (allerror);
7188ac27
KM
489}
490
a9013e03
KM
491/*
492 * File handle to vnode
493 *
494 * Have to be really careful about stale file handles:
495 * - check that the inode number is valid
496 * - call ffs_vget() to get the locked inode
497 * - check for an unallocated inode (i_mode == 0)
a9013e03
KM
498 */
499int
6b50a7c5 500ffs_fhtovp(mp, fhp, vpp)
a9013e03
KM
501 register struct mount *mp;
502 struct fid *fhp;
503 struct vnode **vpp;
504{
9342689a 505 USES_VOP_VGET;
a9013e03
KM
506 register struct inode *ip;
507 register struct ufid *ufhp;
508 struct fs *fs;
509 struct vnode *nvp;
510 int error;
511
512 ufhp = (struct ufid *)fhp;
513 fs = VFSTOUFS(mp)->um_fs;
514 if (ufhp->ufid_ino < ROOTINO ||
515 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
516 return (EINVAL);
9342689a 517 if (error = FFS_VGET(mp, ufhp->ufid_ino, &nvp)) {
a9013e03
KM
518 *vpp = NULLVP;
519 return (error);
520 }
521 ip = VTOI(nvp);
6b50a7c5 522 if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) {
a9013e03
KM
523 ufs_iput(ip);
524 *vpp = NULLVP;
525 return (EINVAL);
526 }
a9013e03
KM
527 *vpp = nvp;
528 return (0);
529}
530
531/*
532 * Vnode pointer to File handle
533 */
534/* ARGSUSED */
535ffs_vptofh(vp, fhp)
536 struct vnode *vp;
537 struct fid *fhp;
538{
539 register struct inode *ip;
540 register struct ufid *ufhp;
541
542 ip = VTOI(vp);
543 ufhp = (struct ufid *)fhp;
544 ufhp->ufid_len = sizeof(struct ufid);
545 ufhp->ufid_ino = ip->i_number;
546 ufhp->ufid_gen = ip->i_gen;
547 return (0);
548}
549
7188ac27
KM
550/*
551 * Write a superblock and associated information back to disk.
552 */
06445aba 553int
ab9f4fb0 554ffs_sbupdate(mp, waitfor)
7188ac27
KM
555 struct ufsmount *mp;
556 int waitfor;
557{
558 register struct fs *fs = mp->um_fs;
71e4e98b
SL
559 register struct buf *bp;
560 int blks;
561 caddr_t space;
7188ac27 562 int i, size, error = 0;
71e4e98b 563
ec67a3ce
MK
564#ifdef SECSIZE
565 bp = getblk(mp->m_dev, (daddr_t)fsbtodb(fs, SBOFF / fs->fs_fsize),
566 (int)fs->fs_sbsize, fs->fs_dbsize);
567#else SECSIZE
7188ac27 568 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize);
ec67a3ce 569#endif SECSIZE
71e4e98b 570 bcopy((caddr_t)fs, bp->b_un.b_addr, (u_int)fs->fs_sbsize);
2af59000
KM
571 /* Restore compatibility to old file systems. XXX */
572 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
573 bp->b_un.b_fs->fs_nrpos = -1; /* XXX */
ec67a3ce
MK
574#ifdef SECSIZE
575#ifdef tahoe
576 /* restore standard fsbtodb shift */
577 bp->b_un.b_fs->fs_fsbtodb = fs->fs_sparecon[0];
578 bp->b_un.b_fs->fs_sparecon[0] = 0;
579#endif
580#endif SECSIZE
7188ac27
KM
581 if (waitfor == MNT_WAIT)
582 error = bwrite(bp);
583 else
584 bawrite(bp);
71e4e98b
SL
585 blks = howmany(fs->fs_cssize, fs->fs_fsize);
586 space = (caddr_t)fs->fs_csp[0];
587 for (i = 0; i < blks; i += fs->fs_frag) {
588 size = fs->fs_bsize;
589 if (i + fs->fs_frag > blks)
590 size = (blks - i) * fs->fs_fsize;
ec67a3ce
MK
591#ifdef SECSIZE
592 bp = getblk(mp->m_dev, fsbtodb(fs, fs->fs_csaddr + i), size,
593 fs->fs_dbsize);
594#else SECSIZE
7188ac27 595 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), size);
ec67a3ce 596#endif SECSIZE
71e4e98b
SL
597 bcopy(space, bp->b_un.b_addr, (u_int)size);
598 space += size;
7188ac27
KM
599 if (waitfor == MNT_WAIT)
600 error = bwrite(bp);
601 else
602 bawrite(bp);
71e4e98b 603 }
7188ac27 604 return (error);
71e4e98b 605}