Thu Jul 18 09:01:20 2013 UTC ()
One more explicit error log, and two bug fixes
1) with recent FUSE, when lookup returns a null ino, it means ENOENT
2) odd corner case that caused a bug on dd if=test of=test conv=notrunc
   This caused the file to be open first ro, then rw. A logic bug in
   perfuse_node_open caused it to skip the second operation, whereas
   it should open for writing, and store the write FH without touching
   the read FH.


(manu)
diff -r1.60 -r1.61 src/lib/libperfuse/ops.c

cvs diff -r1.60 -r1.61 src/lib/libperfuse/ops.c (expand / switch to unified diff)

--- src/lib/libperfuse/ops.c 2012/11/03 15:43:20 1.60
+++ src/lib/libperfuse/ops.c 2013/07/18 09:01:20 1.61
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ops.c,v 1.60 2012/11/03 15:43:20 manu Exp $ */ 1/* $NetBSD: ops.c,v 1.61 2013/07/18 09:01:20 manu Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. 4 * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved.
5 *  5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 *  14 *
@@ -1359,30 +1359,49 @@ perfuse_node_open(struct puffs_usermount @@ -1359,30 +1359,49 @@ perfuse_node_open(struct puffs_usermount
1359 * - O_TRUNC may be used if mount option atomic_o_trunc is used XXX 1359 * - O_TRUNC may be used if mount option atomic_o_trunc is used XXX
1360 * 1360 *
1361 * O_APPEND makes no sense since FUSE always sends 1361 * O_APPEND makes no sense since FUSE always sends
1362 * the file offset for write operations. If the  1362 * the file offset for write operations. If the
1363 * filesystem uses pwrite(), O_APPEND would cause 1363 * filesystem uses pwrite(), O_APPEND would cause
1364 * the offset to be ignored and cause file corruption. 1364 * the offset to be ignored and cause file corruption.
1365 */ 1365 */
1366 mode &= ~(O_CREAT|O_EXCL|O_APPEND); 1366 mode &= ~(O_CREAT|O_EXCL|O_APPEND);
1367 1367
1368 /* 1368 /*
1369 * Do not open twice, and do not reopen for reading 1369 * Do not open twice, and do not reopen for reading
1370 * if we already have write handle. 1370 * if we already have write handle.
1371 */ 1371 */
1372 if (((mode & FREAD) && (pnd->pnd_flags & PND_RFH)) || 1372 switch (mode & (FREAD|FWRITE)) {
1373 ((mode & FREAD) && (pnd->pnd_flags & PND_WFH)) || 1373 case FREAD:
1374 ((mode & FWRITE) && (pnd->pnd_flags & PND_WFH))) 1374 if (pnd->pnd_flags & (PND_RFH|PND_WFH))
1375 goto out; 1375 goto out;
 1376 break;
 1377 case FWRITE:
 1378 if (pnd->pnd_flags & PND_WFH)
 1379 goto out;
 1380 break;
 1381 case FREAD|FWRITE:
 1382 if (pnd->pnd_flags & PND_WFH)
 1383 goto out;
 1384
 1385 /*
 1386 * Corner case: if already open for reading (PND_RFH)
 1387 * and re-opening FREAD|FWRITE, we need to reopen,
 1388 * but only for writing. Note the change on mode
 1389 * will only affect perfuse_new_fh()
 1390 */
 1391 if (pnd->pnd_flags & PND_RFH)
 1392 mode &= ~FREAD;
 1393 break;
 1394 }
1376  1395
1377 /* 1396 /*
1378 * Queue open on a node so that we do not open 1397 * Queue open on a node so that we do not open
1379 * twice. This would be better with read and 1398 * twice. This would be better with read and
1380 * write distinguished. 1399 * write distinguished.
1381 */ 1400 */
1382 while (pnd->pnd_flags & PND_INOPEN) 1401 while (pnd->pnd_flags & PND_INOPEN)
1383 requeue_request(pu, opc, PCQ_OPEN); 1402 requeue_request(pu, opc, PCQ_OPEN);
1384 pnd->pnd_flags |= PND_INOPEN; 1403 pnd->pnd_flags |= PND_INOPEN;
1385 1404
1386 /* 1405 /*
1387 * Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE 1406 * Convert PUFFS mode to FUSE mode: convert FREAD/FWRITE
1388 * to O_RDONLY/O_WRONLY while perserving the other options. 1407 * to O_RDONLY/O_WRONLY while perserving the other options.
@@ -2713,28 +2732,28 @@ perfuse_node_reclaim(struct puffs_usermo @@ -2713,28 +2732,28 @@ perfuse_node_reclaim(struct puffs_usermo
2713 * reclaim cancel? 2732 * reclaim cancel?
2714 */ 2733 */
2715 if (pnd->pnd_puffs_nlookup > nlookup) { 2734 if (pnd->pnd_puffs_nlookup > nlookup) {
2716 pnd->pnd_flags &= ~PND_RECLAIMED; 2735 pnd->pnd_flags &= ~PND_RECLAIMED;
2717 perfuse_node_cache(ps, opc); 2736 perfuse_node_cache(ps, opc);
2718 node_rele(opc); 2737 node_rele(opc);
2719 return 0; 2738 return 0;
2720 } 2739 }
2721 2740
2722 2741
2723#ifdef PERFUSE_DEBUG 2742#ifdef PERFUSE_DEBUG
2724 if ((pnd->pnd_flags & PND_OPEN) || 2743 if ((pnd->pnd_flags & PND_OPEN) ||
2725 !TAILQ_EMPTY(&pnd->pnd_pcq)) 2744 !TAILQ_EMPTY(&pnd->pnd_pcq))
2726 DERRX(EX_SOFTWARE, "%s: opc = %p: still open", 2745 DERRX(EX_SOFTWARE, "%s: opc = %p \"%s\": still open",
2727 __func__, opc); 2746 __func__, opc, pnd->pnd_name);
2728 2747
2729 if ((pnd->pnd_flags & PND_BUSY) || 2748 if ((pnd->pnd_flags & PND_BUSY) ||
2730 !TAILQ_EMPTY(&pnd->pnd_pcq)) 2749 !TAILQ_EMPTY(&pnd->pnd_pcq))
2731 DERRX(EX_SOFTWARE, "%s: opc = %p: queued operations", 2750 DERRX(EX_SOFTWARE, "%s: opc = %p: queued operations",
2732 __func__, opc); 2751 __func__, opc);
2733 2752
2734 if (pnd->pnd_inxchg != 0) 2753 if (pnd->pnd_inxchg != 0)
2735 DERRX(EX_SOFTWARE, "%s: opc = %p: ongoing operations", 2754 DERRX(EX_SOFTWARE, "%s: opc = %p: ongoing operations",
2736 __func__, opc); 2755 __func__, opc);
2737#endif 2756#endif
2738 2757
2739 /* 2758 /*
2740 * Send the FORGET message 2759 * Send the FORGET message