From 93c574365cf5926e1640f25d39f311fa9868e763 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Thu, 30 May 2013 17:53:56 -0500 Subject: [PATCH] namei: Create the IH_CREATE_INIT function Create a new function that combines calls to IH_CREATE and IH_INIT into one operation; the new function is called IH_CREATE_INIT. This allows a caller to create a file and then use it, without needing to open() the file twice. This is currently only implemented for the Unix namei backend; other backends result in effectively the same functionality (but can use the same API). Reviewed-on: http://gerrit.openafs.org/9969 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit aaa2584c0498037529a30c985ac8a437ec7d842c) Change-Id: I5018418cea63ba19ef0ef3bb047e3f9799a93293 Reviewed-on: http://gerrit.openafs.org/10177 Reviewed-by: Derrick Brashear Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Stephan Wiesand --- src/vol/ihandle.c | 17 +++++++++++++ src/vol/ihandle.h | 7 ++++++ src/vol/namei_ops.c | 58 ++++++++++++++++++++++++++++++++++++++++----- src/vol/namei_ops.h | 3 +++ 4 files changed, 79 insertions(+), 6 deletions(-) diff --git a/src/vol/ihandle.c b/src/vol/ihandle.c index ab7bbd67f..01426e050 100644 --- a/src/vol/ihandle.c +++ b/src/vol/ihandle.c @@ -1141,6 +1141,23 @@ ih_icreate(IHandle_t * ih, int dev, char *part, Inode nI, int p1, int p2, } #endif /* AFS_NAMEI_ENV */ +#if defined(AFS_NT40_ENV) || !defined(AFS_NAMEI_ENV) +/* Unix namei implements its own more efficient IH_CREATE_INIT; this wrapper + * is for everyone else */ +IHandle_t * +ih_icreate_init(IHandle_t *lh, int dev, char *part, Inode nearInode, + afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4) +{ + IHandle_t *ihP; + Inode ino = IH_CREATE(lh, dev, part, nearInode, p1, p2, p3, p4); + if (!VALID_INO(ino)) { + return NULL; + } + IH_INIT(ihP, dev, p1, ino); + return ihP; +} +#endif + afs_sfsize_t ih_size(FD_t fd) { diff --git a/src/vol/ihandle.h b/src/vol/ihandle.h index e7b9b7e7b..b59568552 100644 --- a/src/vol/ihandle.h +++ b/src/vol/ihandle.h @@ -425,6 +425,11 @@ extern int ih_isunlinked(FD_t fd); # define OS_DIRSEPC '/' #endif +#if defined(AFS_NT40_ENV) || !defined(AFS_NAMEI_ENV) +# define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \ + ih_icreate_init(H, D, P, N, P1, P2, P3, P4) +#endif + #ifdef AFS_NAMEI_ENV # ifdef AFS_NT40_ENV @@ -490,6 +495,8 @@ extern int OS_TRUNC(int FD, OFFT L); # endif /* !O_LARGEFILE */ # define OS_SYNC(FD) fsync(FD) +# define IH_CREATE_INIT(H, D, P, N, P1, P2, P3, P4) \ + namei_icreate_init(H, D, P, P1, P2, P3, P4) /*@=fcnmacros =macrofcndecl@*/ # endif /* AFS_NT40_ENV */ diff --git a/src/vol/namei_ops.c b/src/vol/namei_ops.c index c3e79afc7..1ac13f71a 100644 --- a/src/vol/namei_ops.c +++ b/src/vol/namei_ops.c @@ -1004,7 +1004,8 @@ bad: } #else /* !AFS_NT40_ENV */ Inode -namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4) +icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4, + FD_t *afd, Inode *ainode) { namei_t name; int fd = INVALID_FD; @@ -1094,10 +1095,6 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint } bad: - if (fd >= 0) - close(fd); - - if (code || (fd < 0)) { if (p2 != -1) { fdP = IH_OPEN(lh); @@ -1107,7 +1104,56 @@ namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint } } } - return (code || (fd < 0)) ? (Inode) - 1 : tmp.ih_ino; + + *afd = fd; + *ainode = tmp.ih_ino; + + return code; +} + +Inode +namei_icreate(IHandle_t * lh, char *part, + afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4) +{ + Inode ino = 0; + int fd = INVALID_FD; + int code; + + code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino); + if (fd >= 0) { + close(fd); + } + return (code || (fd < 0)) ? (Inode) - 1 : ino; +} + +IHandle_t * +namei_icreate_init(IHandle_t * lh, int dev, char *part, + afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4) +{ + Inode ino = 0; + int fd = INVALID_FD; + int code; + IHandle_t *ihP; + FdHandle_t *fdP; + + code = icreate(lh, part, p1, p2, p3, p4, &fd, &ino); + if (fd == INVALID_FD) { + return NULL; + } + if (code) { + close(fd); + return NULL; + } + + IH_INIT(ihP, dev, p1, ino); + fdP = ih_attachfd(ihP, fd); + if (!fdP) { + close(fd); + } else { + FDH_CLOSE(fdP); + } + + return ihP; } #endif diff --git a/src/vol/namei_ops.h b/src/vol/namei_ops.h index b42151278..cbdef2d9a 100644 --- a/src/vol/namei_ops.h +++ b/src/vol/namei_ops.h @@ -22,6 +22,9 @@ extern int namei_unlink(char *name); extern Inode namei_MakeSpecIno(int volid, int type); extern Inode namei_icreate(IHandle_t * lh, char *part, afs_uint32 p1, afs_uint32 p2, afs_uint32 p3, afs_uint32 p4); +extern IHandle_t *namei_icreate_init(IHandle_t *lh, int dev, char *part, + afs_uint32 p1, afs_uint32 p2, + afs_uint32 p3, afs_uint32 p4); extern FD_t namei_iopen(IHandle_t * h); extern int namei_irelease(IHandle_t * h); afs_sfsize_t namei_iread(IHandle_t * h, afs_foff_t offset, char *buf, -- 2.39.5