From: Joel Holdsworth joel@airwebreathe.org.uk
In order to implement FILE_DISPOSITION_POSIX_SEMANTICS, it will be necessary to add additional flags to closed_fd. In preparation for this, the unlink member variable has been replaced with disp_flags which directly reflects the flags defined in the FILE_DISPOSITION_INFORMATION_EX structure.
Signed-off-by: Joel Holdsworth joel@airwebreathe.org.uk --- server/fd.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/server/fd.c b/server/fd.c index dc35999c3f3..6ce3343fb6f 100644 --- a/server/fd.c +++ b/server/fd.c @@ -160,10 +160,10 @@ static inline int epoll_wait( int epfd, struct epoll_event *events, int maxevent /* closed_fd is used to keep track of the unix fd belonging to a closed fd object */ struct closed_fd { - struct list entry; /* entry in inode closed list */ - int unix_fd; /* the unix file descriptor */ - int unlink; /* whether to unlink on close: -1 - implicit FILE_DELETE_ON_CLOSE, 1 - explicit disposition */ - char *unix_name; /* name to unlink on close, points to parent fd unix_name */ + struct list entry; /* entry in inode closed list */ + int unix_fd; /* the unix file descriptor */ + unsigned int disp_flags; /* the disposition flags */ + char *unix_name; /* name to unlink on close, points to parent fd unix_name */ };
struct fd @@ -1122,7 +1122,9 @@ static void inode_close_pending( struct inode *inode, int keep_unlinks ) close( fd->unix_fd ); fd->unix_fd = -1; } - if (!keep_unlinks || !fd->unlink) /* get rid of it unless there's an unlink pending on that file */ + + /* get rid of it unless there's an unlink pending on that file */ + if (!keep_unlinks || !(fd->disp_flags & FILE_DISPOSITION_DELETE)) { list_remove( ptr ); free( fd->unix_name ); @@ -1155,7 +1157,7 @@ static void inode_destroy( struct object *obj ) struct closed_fd *fd = LIST_ENTRY( ptr, struct closed_fd, entry ); list_remove( ptr ); if (fd->unix_fd != -1) close( fd->unix_fd ); - if (fd->unlink) + if (fd->disp_flags & FILE_DISPOSITION_DELETE) { /* make sure it is still the same file */ struct stat st; @@ -1211,8 +1213,9 @@ static void inode_add_closed_fd( struct inode *inode, struct closed_fd *fd ) { list_add_head( &inode->closed, &fd->entry ); } - else if (fd->unlink) /* close the fd but keep the structure around for unlink */ + else if (fd->disp_flags & FILE_DISPOSITION_ON_CLOSE) { + /* close the fd but keep the structure around for unlink */ if (fd->unix_fd != -1) close( fd->unix_fd ); fd->unix_fd = -1; list_add_head( &inode->closed, &fd->entry ); @@ -1560,7 +1563,7 @@ static void fd_dump( struct object *obj, int verbose ) { struct fd *fd = (struct fd *)obj; fprintf( stderr, "Fd unix_fd=%d user=%p options=%08x", fd->unix_fd, fd->user, fd->options ); - if (fd->inode) fprintf( stderr, " inode=%p unlink=%d", fd->inode, fd->closed->unlink ); + if (fd->inode) fprintf( stderr, " inode=%p disp_flags=%x", fd->inode, fd->closed->disp_flags ); fprintf( stderr, "\n" ); }
@@ -1673,7 +1676,7 @@ static inline void unmount_fd( struct fd *fd ) fd->unix_fd = -1; fd->no_fd_status = STATUS_VOLUME_DISMOUNTED; fd->closed->unix_fd = -1; - fd->closed->unlink = 0; + fd->closed->disp_flags = 0;
/* stop using Unix locks on this fd (existing locks have been removed by close) */ fd->fs_locks = 0; @@ -1783,7 +1786,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha goto failed; } closed->unix_fd = fd->unix_fd; - closed->unlink = 0; + closed->disp_flags = 0; closed->unix_name = fd->unix_name; fd->closed = closed; fd->inode = (struct inode *)grab_object( orig->inode ); @@ -1977,7 +1980,7 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam }
closed_fd->unix_fd = fd->unix_fd; - closed_fd->unlink = 0; + closed_fd->disp_flags = 0; closed_fd->unix_name = fd->unix_name; fstat( fd->unix_fd, &st ); *mode = st.st_mode; @@ -2026,7 +2029,8 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam goto error; }
- fd->closed->unlink = (options & FILE_DELETE_ON_CLOSE) ? -1 : 0; + fd->closed->disp_flags = (options & FILE_DELETE_ON_CLOSE) ? + FILE_DISPOSITION_DELETE : 0; if (flags & O_TRUNC) { if (S_ISDIR(st.st_mode)) @@ -2528,9 +2532,8 @@ static void set_fd_disposition( struct fd *fd, unsigned int flags ) if (flags & FILE_DISPOSITION_ON_CLOSE) fd->options &= ~FILE_DELETE_ON_CLOSE;
- fd->closed->unlink = (flags & FILE_DISPOSITION_DELETE) ? 1 : 0; - if (fd->options & FILE_DELETE_ON_CLOSE) - fd->closed->unlink = -1; + fd->closed->disp_flags = (flags & FILE_DISPOSITION_DELETE) | + ((fd->options & FILE_DELETE_ON_CLOSE) ? FILE_DISPOSITION_DELETE : 0); }
/* set new name for the fd */