Page MenuHomeFreeBSD

D56494.id175817.diff
No OneTemporary

D56494.id175817.diff

diff --git a/sys/fs/p9fs/p9fs_subr.c b/sys/fs/p9fs/p9fs_subr.c
--- a/sys/fs/p9fs/p9fs_subr.c
+++ b/sys/fs/p9fs/p9fs_subr.c
@@ -275,16 +275,20 @@
{
/*
* Return TRUE for an exact match. For OREAD and OWRITE, allow
- * existing ORDWR fids to match. Only check the low two bits
- * of mode.
+ * existing ORDWR fids to match.
*
- * TODO: figure out if this is correct for O_APPEND
+ * We mask both the requested mode and the existing fid's mode
+ * with 3 (0b11) to isolate the base access intent (O_RDONLY,
+ * O_WRONLY, or O_RDWR). This prevents extended open flags like
+ * O_EXCL or O_APPEND from causing a mismatch when we are merely
+ * looking for an appropriately privileged open descriptor.
*/
int fid_mode = fid->mode & 3;
- if (fid_mode == mode)
+ int req_mode = mode & 3;
+ if (fid_mode == req_mode)
return (TRUE);
if (fid_mode == P9PROTO_ORDWR)
- return (mode == P9PROTO_OREAD || mode == P9PROTO_OWRITE);
+ return (req_mode == P9PROTO_OREAD || req_mode == P9PROTO_OWRITE);
return (FALSE);
}
diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c
--- a/sys/fs/p9fs/p9fs_vnops.c
+++ b/sys/fs/p9fs/p9fs_vnops.c
@@ -419,7 +419,7 @@
* the name and perm specified under the parent dir. If this succeeds (an entry
* is created for the new file on the server), we create our metadata for this
* file (vnode, p9fs node calling vget). Once we are done, we clunk the open
- * fid of the parent directory.
+ * fid of the parent directory if it was not retained.
*/
static int
create_common(struct p9fs_node *dnp, struct componentname *cnp,
@@ -473,6 +473,28 @@
dnp, newfid, vpp, cnp->cn_nameptr);
if (error != 0)
goto out;
+
+ if (ofid != NULL) {
+ struct p9fs_node *np = P9FS_VTON(*vpp);
+ ofid->v_opens = 0;
+ /*
+ * The 9P file creation request natively opens
+ * the file as part of the create operation and
+ * gives us a writable file handle (ofid).
+ * We retain this open descriptor by adding it
+ * to the VOFID list of the new vnode. This
+ * guarantees that a subsequent VOP_OPEN call
+ * does not need to send a redundant TOPEN
+ * request. This is particularly important
+ * because if a file was requested to be created
+ * with 000 permissions, the host will reject
+ * subsequent TOPEN requests due to insufficient
+ * permissions, which would cause an overall
+ * open() failure.
+ */
+ p9fs_fid_add(np, ofid, VOFID);
+ ofid = NULL; /* prevent closing handle below */
+ }
} else {
/* Not found return NOENTRY.*/
goto out;

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 11:44 AM (1 m, 52 s ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31766659
Default Alt Text
D56494.id175817.diff (2 KB)

Event Timeline