Deleted Added
full compact
dir.c (15699) dir.c (23675)
1/*
2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
1/*
2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char sccsid[] = "@(#)dir.c 8.1 (Berkeley) 6/5/93";
35static const char sccsid[] = "@(#)dir.c 8.8 (Berkeley) 4/28/95";
36#endif /* not lint */
37
38#include <sys/param.h>
39#include <sys/time.h>
36#endif /* not lint */
37
38#include <sys/param.h>
39#include <sys/time.h>
40
40#include <ufs/ufs/dinode.h>
41#include <ufs/ufs/dir.h>
42#include <ufs/ffs/fs.h>
43#include <stdio.h>
44#include <stdlib.h>
41#include <ufs/ufs/dinode.h>
42#include <ufs/ufs/dir.h>
43#include <ufs/ffs/fs.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <err.h>
45#include <string.h>
47#include <string.h>
48
46#include "fsck.h"
47
48char *lfname = "lost+found";
49int lfmode = 01777;
50struct dirtemplate emptydir = { 0, DIRBLKSIZ };
51struct dirtemplate dirhead = {
52 0, 12, DT_DIR, 1, ".",
53 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
54};
55struct odirtemplate odirhead = {
56 0, 12, 1, ".",
57 0, DIRBLKSIZ - 12, 2, ".."
58};
59
49#include "fsck.h"
50
51char *lfname = "lost+found";
52int lfmode = 01777;
53struct dirtemplate emptydir = { 0, DIRBLKSIZ };
54struct dirtemplate dirhead = {
55 0, 12, DT_DIR, 1, ".",
56 0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
57};
58struct odirtemplate odirhead = {
59 0, 12, 1, ".",
60 0, DIRBLKSIZ - 12, 2, ".."
61};
62
63static int chgino __P((struct inodesc *));
64static int dircheck __P((struct inodesc *, struct direct *));
65static int expanddir __P((struct dinode *dp, char *name));
66static void freedir __P((ino_t ino, ino_t parent));
67static struct direct *fsck_readdir __P((struct inodesc *));
68static struct bufarea *getdirblk __P((ufs_daddr_t blkno, long size));
69static int lftempname __P((char *bufp, ino_t ino));
70static int mkentry __P((struct inodesc *));
60
71
61static int chgino __P((struct inodesc *idesc));
62static int dircheck __P((struct inodesc *idesc, struct direct *dp));
63static int expanddir __P((struct dinode *dp, char *name));
64static void freedir __P((ino_t ino, ino_t parent));
65static struct direct * fsck_readdir __P((struct inodesc *idesc));
66static struct bufarea * getdirblk __P((daddr_t blkno, long size));
67static int lftempname __P((char *bufp, ino_t ino));
68static int mkentry __P((struct inodesc *idesc));
69
70/*
71 * Propagate connected state through the tree.
72 */
73void
74propagate()
75{
76 register struct inoinfo **inpp, *inp;
77 struct inoinfo **inpend;

--- 24 unchanged lines hidden (view full) ---

102{
103 register struct direct *dp;
104 register struct bufarea *bp;
105 int dsize, n;
106 long blksiz;
107 char dbuf[DIRBLKSIZ];
108
109 if (idesc->id_type != DATA)
72/*
73 * Propagate connected state through the tree.
74 */
75void
76propagate()
77{
78 register struct inoinfo **inpp, *inp;
79 struct inoinfo **inpend;

--- 24 unchanged lines hidden (view full) ---

104{
105 register struct direct *dp;
106 register struct bufarea *bp;
107 int dsize, n;
108 long blksiz;
109 char dbuf[DIRBLKSIZ];
110
111 if (idesc->id_type != DATA)
110 errexit("wrong type to dirscan %d\n", idesc->id_type);
112 errx(EEXIT, "wrong type to dirscan %d", idesc->id_type);
111 if (idesc->id_entryno == 0 &&
112 (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
113 idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
114 blksiz = idesc->id_numfrags * sblock.fs_fsize;
115 if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {
116 idesc->id_filesize -= blksiz;
117 return (SKIP);
118 }
119 idesc->id_loc = 0;
120 for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
121 dsize = dp->d_reclen;
113 if (idesc->id_entryno == 0 &&
114 (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
115 idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
116 blksiz = idesc->id_numfrags * sblock.fs_fsize;
117 if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {
118 idesc->id_filesize -= blksiz;
119 return (SKIP);
120 }
121 idesc->id_loc = 0;
122 for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
123 dsize = dp->d_reclen;
122 bcopy((char *)dp, dbuf, (size_t)dsize);
124 memmove(dbuf, dp, (size_t)dsize);
123# if (BYTE_ORDER == LITTLE_ENDIAN)
124 if (!newinofmt) {
125 struct direct *tdp = (struct direct *)dbuf;
126 u_char tmp;
127
128 tmp = tdp->d_namlen;
129 tdp->d_namlen = tdp->d_type;
130 tdp->d_type = tmp;

--- 8 unchanged lines hidden (view full) ---

139
140 tdp = (struct direct *)dbuf;
141 tmp = tdp->d_namlen;
142 tdp->d_namlen = tdp->d_type;
143 tdp->d_type = tmp;
144 }
145# endif
146 bp = getdirblk(idesc->id_blkno, blksiz);
125# if (BYTE_ORDER == LITTLE_ENDIAN)
126 if (!newinofmt) {
127 struct direct *tdp = (struct direct *)dbuf;
128 u_char tmp;
129
130 tmp = tdp->d_namlen;
131 tdp->d_namlen = tdp->d_type;
132 tdp->d_type = tmp;

--- 8 unchanged lines hidden (view full) ---

141
142 tdp = (struct direct *)dbuf;
143 tmp = tdp->d_namlen;
144 tdp->d_namlen = tdp->d_type;
145 tdp->d_type = tmp;
146 }
147# endif
148 bp = getdirblk(idesc->id_blkno, blksiz);
147 bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize,
149 memmove(bp->b_un.b_buf + idesc->id_loc - dsize, dbuf,
148 (size_t)dsize);
149 dirty(bp);
150 sbdirty();
151 }
152 if (n & STOP)
153 return (n);
154 }
155 return (idesc->id_filesize > 0 ? KEEPON : STOP);
156}
157
158/*
159 * get next entry in a directory.
160 */
150 (size_t)dsize);
151 dirty(bp);
152 sbdirty();
153 }
154 if (n & STOP)
155 return (n);
156 }
157 return (idesc->id_filesize > 0 ? KEEPON : STOP);
158}
159
160/*
161 * get next entry in a directory.
162 */
161struct direct *
163static struct direct *
162fsck_readdir(idesc)
163 register struct inodesc *idesc;
164{
165 register struct direct *dp, *ndp;
166 register struct bufarea *bp;
167 long size, blksiz, fix, dploc;
168
169 blksiz = idesc->id_numfrags * sblock.fs_fsize;
170 bp = getdirblk(idesc->id_blkno, blksiz);
171 if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 &&
172 idesc->id_loc < blksiz) {
173 dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
174 if (dircheck(idesc, dp))
175 goto dpok;
164fsck_readdir(idesc)
165 register struct inodesc *idesc;
166{
167 register struct direct *dp, *ndp;
168 register struct bufarea *bp;
169 long size, blksiz, fix, dploc;
170
171 blksiz = idesc->id_numfrags * sblock.fs_fsize;
172 bp = getdirblk(idesc->id_blkno, blksiz);
173 if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 &&
174 idesc->id_loc < blksiz) {
175 dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
176 if (dircheck(idesc, dp))
177 goto dpok;
178 if (idesc->id_fix == IGNORE)
179 return (0);
176 fix = dofix(idesc, "DIRECTORY CORRUPTED");
177 bp = getdirblk(idesc->id_blkno, blksiz);
178 dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
179 dp->d_reclen = DIRBLKSIZ;
180 dp->d_ino = 0;
181 dp->d_type = 0;
182 dp->d_namlen = 0;
183 dp->d_name[0] = '\0';

--- 13 unchanged lines hidden (view full) ---

197 if ((idesc->id_loc % DIRBLKSIZ) == 0)
198 return (dp);
199 ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
200 if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
201 dircheck(idesc, ndp) == 0) {
202 size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
203 idesc->id_loc += size;
204 idesc->id_filesize -= size;
180 fix = dofix(idesc, "DIRECTORY CORRUPTED");
181 bp = getdirblk(idesc->id_blkno, blksiz);
182 dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
183 dp->d_reclen = DIRBLKSIZ;
184 dp->d_ino = 0;
185 dp->d_type = 0;
186 dp->d_namlen = 0;
187 dp->d_name[0] = '\0';

--- 13 unchanged lines hidden (view full) ---

201 if ((idesc->id_loc % DIRBLKSIZ) == 0)
202 return (dp);
203 ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
204 if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
205 dircheck(idesc, ndp) == 0) {
206 size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
207 idesc->id_loc += size;
208 idesc->id_filesize -= size;
209 if (idesc->id_fix == IGNORE)
210 return (0);
205 fix = dofix(idesc, "DIRECTORY CORRUPTED");
206 bp = getdirblk(idesc->id_blkno, blksiz);
207 dp = (struct direct *)(bp->b_un.b_buf + dploc);
208 dp->d_reclen += size;
209 if (fix)
210 dirty(bp);
211 }
212 return (dp);
213}
214
215/*
216 * Verify that a directory entry is valid.
217 * This is a superset of the checks made in the kernel.
218 */
211 fix = dofix(idesc, "DIRECTORY CORRUPTED");
212 bp = getdirblk(idesc->id_blkno, blksiz);
213 dp = (struct direct *)(bp->b_un.b_buf + dploc);
214 dp->d_reclen += size;
215 if (fix)
216 dirty(bp);
217 }
218 return (dp);
219}
220
221/*
222 * Verify that a directory entry is valid.
223 * This is a superset of the checks made in the kernel.
224 */
219int
225static int
220dircheck(idesc, dp)
221 struct inodesc *idesc;
222 register struct direct *dp;
223{
224 register int size;
225 register char *cp;
226 u_char namlen, type;
227 int spaceleft;
228
226dircheck(idesc, dp)
227 struct inodesc *idesc;
228 register struct direct *dp;
229{
230 register int size;
231 register char *cp;
232 u_char namlen, type;
233 int spaceleft;
234
229 size = DIRSIZ(!newinofmt, dp);
230 spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
235 spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
236 if (dp->d_ino >= maxino ||
237 dp->d_reclen == 0 ||
238 dp->d_reclen > spaceleft ||
239 (dp->d_reclen & 0x3) != 0)
240 return (0);
241 if (dp->d_ino == 0)
242 return (1);
243 size = DIRSIZ(!newinofmt, dp);
231# if (BYTE_ORDER == LITTLE_ENDIAN)
232 if (!newinofmt) {
233 type = dp->d_namlen;
234 namlen = dp->d_type;
235 } else {
236 namlen = dp->d_namlen;
237 type = dp->d_type;
238 }
239# else
240 namlen = dp->d_namlen;
241 type = dp->d_type;
242# endif
244# if (BYTE_ORDER == LITTLE_ENDIAN)
245 if (!newinofmt) {
246 type = dp->d_namlen;
247 namlen = dp->d_type;
248 } else {
249 namlen = dp->d_namlen;
250 type = dp->d_type;
251 }
252# else
253 namlen = dp->d_namlen;
254 type = dp->d_type;
255# endif
243 if (dp->d_ino < maxino &&
244 dp->d_reclen != 0 &&
245 dp->d_reclen <= spaceleft &&
246 (dp->d_reclen & 0x3) == 0 &&
247 dp->d_reclen >= size &&
248 idesc->id_filesize >= size &&
249 namlen <= MAXNAMLEN &&
250 type <= 15) {
251 if (dp->d_ino == 0)
252 return (1);
253 for (cp = dp->d_name, size = 0; size < namlen; size++)
254 if (*cp == 0 || (*cp++ == '/'))
255 return (0);
256 if (*cp == 0)
257 return (1);
258 }
259 return (0);
256 if (dp->d_reclen < size ||
257 idesc->id_filesize < size ||
258 namlen > MAXNAMLEN ||
259 type > 15)
260 return (0);
261 for (cp = dp->d_name, size = 0; size < namlen; size++)
262 if (*cp == '\0' || (*cp++ == '/'))
263 return (0);
264 if (*cp != '\0')
265 return (0);
266 return (1);
260}
261
262void
263direrror(ino, errmesg)
264 ino_t ino;
265 char *errmesg;
266{
267

--- 22 unchanged lines hidden (view full) ---

290 (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf);
291 else
292 pfatal("NAME=%s\n", pathbuf);
293}
294
295void
296adjust(idesc, lcnt)
297 register struct inodesc *idesc;
267}
268
269void
270direrror(ino, errmesg)
271 ino_t ino;
272 char *errmesg;
273{
274

--- 22 unchanged lines hidden (view full) ---

297 (dp->di_mode & IFMT) == IFDIR ? "DIR" : "FILE", pathbuf);
298 else
299 pfatal("NAME=%s\n", pathbuf);
300}
301
302void
303adjust(idesc, lcnt)
304 register struct inodesc *idesc;
298 short lcnt;
305 int lcnt;
299{
300 register struct dinode *dp;
301
302 dp = ginode(idesc->id_number);
303 if (dp->di_nlink == lcnt) {
304 if (linkup(idesc->id_number, (ino_t)0) == 0)
305 clri(idesc, "UNREF", 0);
306 } else {

--- 11 unchanged lines hidden (view full) ---

318 }
319 if (preen || reply("ADJUST") == 1) {
320 dp->di_nlink -= lcnt;
321 inodirty();
322 }
323 }
324}
325
306{
307 register struct dinode *dp;
308
309 dp = ginode(idesc->id_number);
310 if (dp->di_nlink == lcnt) {
311 if (linkup(idesc->id_number, (ino_t)0) == 0)
312 clri(idesc, "UNREF", 0);
313 } else {

--- 11 unchanged lines hidden (view full) ---

325 }
326 if (preen || reply("ADJUST") == 1) {
327 dp->di_nlink -= lcnt;
328 inodirty();
329 }
330 }
331}
332
326int
333static int
327mkentry(idesc)
328 struct inodesc *idesc;
329{
330 register struct direct *dirp = idesc->id_dirp;
331 struct direct newent;
332 int newlen, oldlen;
333
334 newent.d_namlen = strlen(idesc->id_name);
335 newlen = DIRSIZ(0, &newent);
336 if (dirp->d_ino != 0)
337 oldlen = DIRSIZ(0, dirp);
338 else
339 oldlen = 0;
340 if (dirp->d_reclen - oldlen < newlen)
341 return (KEEPON);
342 newent.d_reclen = dirp->d_reclen - oldlen;
343 dirp->d_reclen = oldlen;
344 dirp = (struct direct *)(((char *)dirp) + oldlen);
345 dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
334mkentry(idesc)
335 struct inodesc *idesc;
336{
337 register struct direct *dirp = idesc->id_dirp;
338 struct direct newent;
339 int newlen, oldlen;
340
341 newent.d_namlen = strlen(idesc->id_name);
342 newlen = DIRSIZ(0, &newent);
343 if (dirp->d_ino != 0)
344 oldlen = DIRSIZ(0, dirp);
345 else
346 oldlen = 0;
347 if (dirp->d_reclen - oldlen < newlen)
348 return (KEEPON);
349 newent.d_reclen = dirp->d_reclen - oldlen;
350 dirp->d_reclen = oldlen;
351 dirp = (struct direct *)(((char *)dirp) + oldlen);
352 dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
346 if (newinofmt) {
347 dirp->d_type = typemap[idesc->id_parent];
348 dirp->d_namlen = newent.d_namlen;
349 } else {
350# if (BYTE_ORDER == LITTLE_ENDIAN)
351 dirp->d_type = newent.d_namlen;
352 dirp->d_namlen = 0;
353# else
354 dirp->d_type = 0;
355 dirp->d_namlen = newent.d_namlen;
356# endif
357 }
358 dirp->d_reclen = newent.d_reclen;
353 dirp->d_reclen = newent.d_reclen;
359 bcopy(idesc->id_name, dirp->d_name, (size_t)newent.d_namlen + 1);
354 if (newinofmt)
355 dirp->d_type = typemap[idesc->id_parent];
356 else
357 dirp->d_type = 0;
358 dirp->d_namlen = newent.d_namlen;
359 memmove(dirp->d_name, idesc->id_name, (size_t)newent.d_namlen + 1);
360# if (BYTE_ORDER == LITTLE_ENDIAN)
361 /*
362 * If the entry was split, dirscan() will only reverse the byte
363 * order of the original entry, and not the new one, before
364 * writing it back out. So, we reverse the byte order here if
365 * necessary.
366 */
367 if (oldlen != 0 && !newinofmt && !doinglevel2) {
368 u_char tmp;
369
370 tmp = dirp->d_namlen;
371 dirp->d_namlen = dirp->d_type;
372 dirp->d_type = tmp;
373 }
374# endif
360 return (ALTERED|STOP);
361}
362
375 return (ALTERED|STOP);
376}
377
363int
378static int
364chgino(idesc)
365 struct inodesc *idesc;
366{
367 register struct direct *dirp = idesc->id_dirp;
368
379chgino(idesc)
380 struct inodesc *idesc;
381{
382 register struct direct *dirp = idesc->id_dirp;
383
369 if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
384 if (memcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
370 return (KEEPON);
371 dirp->d_ino = idesc->id_parent;
372 if (newinofmt)
373 dirp->d_type = typemap[idesc->id_parent];
374 else
375 dirp->d_type = 0;
376 return (ALTERED|STOP);
377}

--- 4 unchanged lines hidden (view full) ---

382 ino_t parentdir;
383{
384 register struct dinode *dp;
385 int lostdir;
386 ino_t oldlfdir;
387 struct inodesc idesc;
388 char tempname[BUFSIZ];
389
385 return (KEEPON);
386 dirp->d_ino = idesc->id_parent;
387 if (newinofmt)
388 dirp->d_type = typemap[idesc->id_parent];
389 else
390 dirp->d_type = 0;
391 return (ALTERED|STOP);
392}

--- 4 unchanged lines hidden (view full) ---

397 ino_t parentdir;
398{
399 register struct dinode *dp;
400 int lostdir;
401 ino_t oldlfdir;
402 struct inodesc idesc;
403 char tempname[BUFSIZ];
404
390 bzero((char *)&idesc, sizeof(struct inodesc));
405 memset(&idesc, 0, sizeof(struct inodesc));
391 dp = ginode(orphan);
392 lostdir = (dp->di_mode & IFMT) == IFDIR;
393 pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
394 pinode(orphan);
395 if (preen && dp->di_size == 0)
396 return (0);
397 if (preen)
398 printf(" (RECONNECTED)\n");

--- 97 unchanged lines hidden (view full) ---

496int
497changeino(dir, name, newnum)
498 ino_t dir;
499 char *name;
500 ino_t newnum;
501{
502 struct inodesc idesc;
503
406 dp = ginode(orphan);
407 lostdir = (dp->di_mode & IFMT) == IFDIR;
408 pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
409 pinode(orphan);
410 if (preen && dp->di_size == 0)
411 return (0);
412 if (preen)
413 printf(" (RECONNECTED)\n");

--- 97 unchanged lines hidden (view full) ---

511int
512changeino(dir, name, newnum)
513 ino_t dir;
514 char *name;
515 ino_t newnum;
516{
517 struct inodesc idesc;
518
504 bzero((char *)&idesc, sizeof(struct inodesc));
519 memset(&idesc, 0, sizeof(struct inodesc));
505 idesc.id_type = DATA;
506 idesc.id_func = chgino;
507 idesc.id_number = dir;
508 idesc.id_fix = DONTKNOW;
509 idesc.id_name = name;
510 idesc.id_parent = newnum; /* new value for name */
511 return (ckinode(ginode(dir), &idesc));
512}

--- 8 unchanged lines hidden (view full) ---

521{
522 struct dinode *dp;
523 struct inodesc idesc;
524 char pathbuf[MAXPATHLEN + 1];
525
526 if (parent < ROOTINO || parent >= maxino ||
527 ino < ROOTINO || ino >= maxino)
528 return (0);
520 idesc.id_type = DATA;
521 idesc.id_func = chgino;
522 idesc.id_number = dir;
523 idesc.id_fix = DONTKNOW;
524 idesc.id_name = name;
525 idesc.id_parent = newnum; /* new value for name */
526 return (ckinode(ginode(dir), &idesc));
527}

--- 8 unchanged lines hidden (view full) ---

536{
537 struct dinode *dp;
538 struct inodesc idesc;
539 char pathbuf[MAXPATHLEN + 1];
540
541 if (parent < ROOTINO || parent >= maxino ||
542 ino < ROOTINO || ino >= maxino)
543 return (0);
529 bzero((char *)&idesc, sizeof(struct inodesc));
544 memset(&idesc, 0, sizeof(struct inodesc));
530 idesc.id_type = DATA;
531 idesc.id_func = mkentry;
532 idesc.id_number = parent;
533 idesc.id_parent = ino; /* this is the inode to enter */
534 idesc.id_fix = DONTKNOW;
535 idesc.id_name = name;
536 dp = ginode(parent);
537 if (dp->di_size % DIRBLKSIZ) {

--- 7 unchanged lines hidden (view full) ---

545 if (expanddir(dp, pathbuf) == 0)
546 return (0);
547 return (ckinode(dp, &idesc) & ALTERED);
548}
549
550/*
551 * Attempt to expand the size of a directory
552 */
545 idesc.id_type = DATA;
546 idesc.id_func = mkentry;
547 idesc.id_number = parent;
548 idesc.id_parent = ino; /* this is the inode to enter */
549 idesc.id_fix = DONTKNOW;
550 idesc.id_name = name;
551 dp = ginode(parent);
552 if (dp->di_size % DIRBLKSIZ) {

--- 7 unchanged lines hidden (view full) ---

560 if (expanddir(dp, pathbuf) == 0)
561 return (0);
562 return (ckinode(dp, &idesc) & ALTERED);
563}
564
565/*
566 * Attempt to expand the size of a directory
567 */
553int
568static int
554expanddir(dp, name)
555 register struct dinode *dp;
556 char *name;
557{
569expanddir(dp, name)
570 register struct dinode *dp;
571 char *name;
572{
558 daddr_t lastbn, newblk;
573 ufs_daddr_t lastbn, newblk;
559 register struct bufarea *bp;
560 char *cp, firstblk[DIRBLKSIZ];
561
562 lastbn = lblkno(&sblock, dp->di_size);
563 if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)
564 return (0);
565 if ((newblk = allocblk(sblock.fs_frag)) == 0)
566 return (0);
567 dp->di_db[lastbn + 1] = dp->di_db[lastbn];
568 dp->di_db[lastbn] = newblk;
569 dp->di_size += sblock.fs_bsize;
570 dp->di_blocks += btodb(sblock.fs_bsize);
571 bp = getdirblk(dp->di_db[lastbn + 1],
572 (long)dblksize(&sblock, dp, lastbn + 1));
573 if (bp->b_errs)
574 goto bad;
574 register struct bufarea *bp;
575 char *cp, firstblk[DIRBLKSIZ];
576
577 lastbn = lblkno(&sblock, dp->di_size);
578 if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)
579 return (0);
580 if ((newblk = allocblk(sblock.fs_frag)) == 0)
581 return (0);
582 dp->di_db[lastbn + 1] = dp->di_db[lastbn];
583 dp->di_db[lastbn] = newblk;
584 dp->di_size += sblock.fs_bsize;
585 dp->di_blocks += btodb(sblock.fs_bsize);
586 bp = getdirblk(dp->di_db[lastbn + 1],
587 (long)dblksize(&sblock, dp, lastbn + 1));
588 if (bp->b_errs)
589 goto bad;
575 bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
590 memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
576 bp = getdirblk(newblk, sblock.fs_bsize);
577 if (bp->b_errs)
578 goto bad;
591 bp = getdirblk(newblk, sblock.fs_bsize);
592 if (bp->b_errs)
593 goto bad;
579 bcopy(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
594 memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
580 for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
581 cp < &bp->b_un.b_buf[sblock.fs_bsize];
582 cp += DIRBLKSIZ)
595 for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
596 cp < &bp->b_un.b_buf[sblock.fs_bsize];
597 cp += DIRBLKSIZ)
583 bcopy((char *)&emptydir, cp, sizeof emptydir);
598 memmove(cp, &emptydir, sizeof emptydir);
584 dirty(bp);
585 bp = getdirblk(dp->di_db[lastbn + 1],
586 (long)dblksize(&sblock, dp, lastbn + 1));
587 if (bp->b_errs)
588 goto bad;
599 dirty(bp);
600 bp = getdirblk(dp->di_db[lastbn + 1],
601 (long)dblksize(&sblock, dp, lastbn + 1));
602 if (bp->b_errs)
603 goto bad;
589 bcopy((char *)&emptydir, bp->b_un.b_buf, sizeof emptydir);
604 memmove(bp->b_un.b_buf, &emptydir, sizeof emptydir);
590 pwarn("NO SPACE LEFT IN %s", name);
591 if (preen)
592 printf(" (EXPANDED)\n");
593 else if (reply("EXPAND") == 0)
594 goto bad;
595 dirty(bp);
596 inodirty();
597 return (1);

--- 28 unchanged lines hidden (view full) ---

626 dirp->dot_ino = ino;
627 dirp->dotdot_ino = parent;
628 dp = ginode(ino);
629 bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
630 if (bp->b_errs) {
631 freeino(ino);
632 return (0);
633 }
605 pwarn("NO SPACE LEFT IN %s", name);
606 if (preen)
607 printf(" (EXPANDED)\n");
608 else if (reply("EXPAND") == 0)
609 goto bad;
610 dirty(bp);
611 inodirty();
612 return (1);

--- 28 unchanged lines hidden (view full) ---

641 dirp->dot_ino = ino;
642 dirp->dotdot_ino = parent;
643 dp = ginode(ino);
644 bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
645 if (bp->b_errs) {
646 freeino(ino);
647 return (0);
648 }
634 bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate));
649 memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate));
635 for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
636 cp < &bp->b_un.b_buf[sblock.fs_fsize];
637 cp += DIRBLKSIZ)
650 for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
651 cp < &bp->b_un.b_buf[sblock.fs_fsize];
652 cp += DIRBLKSIZ)
638 bcopy((char *)&emptydir, cp, sizeof emptydir);
653 memmove(cp, &emptydir, sizeof emptydir);
639 dirty(bp);
640 dp->di_nlink = 2;
641 inodirty();
642 if (ino == ROOTINO) {
643 lncntp[ino] = dp->di_nlink;
644 cacheino(dp, ino);
645 return(ino);
646 }

--- 28 unchanged lines hidden (view full) ---

675 inodirty();
676 }
677 freeino(ino);
678}
679
680/*
681 * generate a temporary name for the lost+found directory.
682 */
654 dirty(bp);
655 dp->di_nlink = 2;
656 inodirty();
657 if (ino == ROOTINO) {
658 lncntp[ino] = dp->di_nlink;
659 cacheino(dp, ino);
660 return(ino);
661 }

--- 28 unchanged lines hidden (view full) ---

690 inodirty();
691 }
692 freeino(ino);
693}
694
695/*
696 * generate a temporary name for the lost+found directory.
697 */
683int
698static int
684lftempname(bufp, ino)
685 char *bufp;
686 ino_t ino;
687{
688 register ino_t in;
689 register char *cp;
690 int namlen;
691

--- 10 unchanged lines hidden (view full) ---

702 *cp = '#';
703 return (namlen);
704}
705
706/*
707 * Get a directory block.
708 * Insure that it is held until another is requested.
709 */
699lftempname(bufp, ino)
700 char *bufp;
701 ino_t ino;
702{
703 register ino_t in;
704 register char *cp;
705 int namlen;
706

--- 10 unchanged lines hidden (view full) ---

717 *cp = '#';
718 return (namlen);
719}
720
721/*
722 * Get a directory block.
723 * Insure that it is held until another is requested.
724 */
710struct bufarea *
725static struct bufarea *
711getdirblk(blkno, size)
726getdirblk(blkno, size)
712 daddr_t blkno;
727 ufs_daddr_t blkno;
713 long size;
714{
715
716 if (pdirbp != 0)
717 pdirbp->b_flags &= ~B_INUSE;
718 pdirbp = getdatablk(blkno, size);
719 return (pdirbp);
720}
728 long size;
729{
730
731 if (pdirbp != 0)
732 pdirbp->b_flags &= ~B_INUSE;
733 pdirbp = getdatablk(blkno, size);
734 return (pdirbp);
735}