[Libsysio-commit] HEAD: libsysio/drivers/native fs_native.c
Brought to you by:
lward
From: Lee W. <lw...@us...> - 2004-09-21 16:27:11
|
Update of /cvsroot/libsysio/libsysio/drivers/native In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27545 Modified Files: fs_native.c Log Message: From Henry Pierce at Cray; A chdir() to a directory without `x' permission should not succeed but does. This required that inodes now carry the full attributes -- Not just the mode bits. That's a bug change. Driver writers; 1) _sysio_i_new is altered. It needs the full intnl_stat structure now. 2) Your lookup function should refresh the inode attributes. 3) We don't keep an inode dirty bit. Hopefully, you've been pushing changes at the time of the operation instead of waiting until the inode was flushed or somesuch. Maybe you keep an internal dirty bit? Index: fs_native.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v retrieving revision 1.48 retrieving revision 1.49 diff -u -w -b -B -p -r1.48 -r1.49 --- fs_native.c 10 Sep 2004 16:42:39 -0000 1.48 +++ fs_native.c 21 Sep 2004 16:26:59 -0000 1.49 @@ -210,7 +210,6 @@ struct native_inode { int ni_oflags; /* flags, from open */ unsigned ni_nopens; /* soft ref count */ _SYSIO_OFF_T ni_fpos; /* current pos */ - struct intnl_stat ni_stat; /* cached attrs */ }; /* @@ -329,52 +328,34 @@ static struct mount *native_internal_mou * stat -- by path. */ static int -native_stat(const char *path, struct native_inode *nino, struct intnl_stat *buf) +native_stat(const char *path, struct inode *ino, struct intnl_stat *buf) { + struct native_inode *nino; int err; struct __native_stat stbuf; - err = syscall(__SYS_STAT, path, &stbuf); - if (err) { - err = -errno; - goto out; - } - if (!nino) { - COPY_STAT(&stbuf, buf); - goto out; - } - COPY_STAT(&stbuf, &nino->ni_stat); - if (&nino->ni_stat != buf) - (void )memcpy(buf, &nino->ni_stat, sizeof(struct intnl_stat)); - -out: - return err; -} - -/* - * stat -- by fildes - */ -static int -native_fstat(int fd, struct native_inode *nino, struct intnl_stat *buf) -{ - int err; - struct __native_stat stbuf; + nino = ino ? I2NI(ino) : NULL; - err = syscall(__SYS_FSTAT, fd, &stbuf); - if (err) { - err = -errno; - goto out; + if (path) + err = syscall(__SYS_STAT, path, &stbuf); + else if (nino && nino->ni_fd >= 0) + err = syscall(__SYS_FSTAT, nino->ni_fd, &stbuf); + else + abort(); + if (err) + return -errno; + if (nino) { + COPY_STAT(&stbuf, &ino->i_stbuf); + if (buf) + (void )memcpy(buf, + &ino->i_stbuf, + sizeof(struct intnl_stat)); + return 0; } - if (!nino) { + if (!buf) + return 0; COPY_STAT(&stbuf, buf); - goto out; - } - COPY_STAT(&stbuf, &nino->ni_stat); - if (&nino->ni_stat != buf) - (void )memcpy(buf, &nino->ni_stat, sizeof(struct intnl_stat)); - -out: - return err; + return 0; } /* @@ -390,6 +371,7 @@ native_i_new(struct filesys *fs, struct if (!nino) return NULL; bzero(&nino->ni_ident, sizeof(nino->ni_ident)); + nino->ni_seekok = 0; nino->ni_ident.dev = buf->st_dev; nino->ni_ident.ino = buf->st_ino; #ifdef HAVE_GENERATION @@ -401,16 +383,10 @@ native_i_new(struct filesys *fs, struct nino->ni_oflags = 0; nino->ni_nopens = 0; nino->ni_fpos = 0; - (void )memcpy(&nino->ni_stat, buf, sizeof(struct intnl_stat)); ino = _sysio_i_new(fs, &nino->ni_fileid, -#ifndef AUTOMOUNT_FILE_NAME - buf->st_mode & S_IFMT, -#else - buf->st_mode, /* all of the bits! */ -#endif - buf->st_rdev, + buf, 0, &native_i_ops, nino); @@ -440,7 +416,7 @@ _sysio_native_init() * Create private, internal, view of the hosts name space. */ static int -create_internal_namespace() +create_internal_namespace(const void *data __IS_UNUSED) { int err; struct mount *mnt; @@ -462,6 +438,7 @@ create_internal_namespace() * have access to fully qualified path names in the various routines. * Initialize that name space now. */ + fs = NULL; mnt = NULL; rootino = NULL; rootpb = NULL; @@ -523,7 +500,7 @@ error: static int native_fsswop_mount(const char *source, unsigned flags, - const void *data __IS_UNUSED, + const void *data, struct pnode *tocover, struct mount **mntp) { @@ -539,10 +516,11 @@ native_fsswop_mount(const char *source, return -ENOENT; if (!native_internal_mount) { - err = create_internal_namespace(); + err = create_internal_namespace(data); if (err) return err; - } + } else if (data && *(char *)data) + return -EINVAL; /* * Lookup the source in the internally maintained name space. @@ -578,21 +556,22 @@ native_fsswop_mount(const char *source, } static int -native_i_invalid(struct inode *inop, struct intnl_stat stbuf) +native_i_invalid(struct inode *inop, struct intnl_stat *stat) { /* * Validate passed in inode against stat struct info */ struct native_inode *nino = I2NI(inop); - if ((nino->ni_ident.dev != stbuf.st_dev || - nino->ni_ident.ino != stbuf.st_ino || + if ((nino->ni_ident.dev != stat->st_dev || + nino->ni_ident.ino != stat->st_ino || #ifdef HAVE_GENERATION - nino->ni_ident.gen != stbuf.st_gen || + nino->ni_ident.gen != stat->st_gen || #endif - ((inop)->i_mode & S_IFMT) != (stbuf.st_mode & S_IFMT)) || - (((inop)->i_rdev != stbuf.st_rdev) && - (S_ISCHR((inop)->i_mode) || S_ISBLK((inop)->i_mode)))) + ((inop)->i_stbuf.st_mode & S_IFMT) != (stat->st_mode & S_IFMT)) || + (((inop)->i_stbuf.st_rdev != stat->st_rdev) && + (S_ISCHR((inop)->i_stbuf.st_mode) || + S_ISBLK((inop)->i_stbuf.st_mode)))) return 1; return 0; @@ -610,24 +589,24 @@ native_iget(struct filesys *fs, { int err; struct inode *ino; - struct intnl_stat stbuf; + struct intnl_stat ostbuf, stbuf; struct native_inode_identifier ident; struct file_identifier fileid; /* - * Get file status. + * Save old attributes and get current file status. */ - err = native_stat(path, *inop ? I2NI(*inop) : NULL, &stbuf); - if (err) { - *inop = NULL; + if (*inop) + ostbuf = (*inop)->i_stbuf; + err = native_stat(path, *inop, &stbuf); + if (err) return err; - } /* * Validate? */ if (*inop) { - if (!native_i_invalid(*inop, stbuf)) + if (!native_i_invalid(*inop, &ostbuf)) return 0; /* * Invalidate. @@ -648,11 +627,12 @@ native_iget(struct filesys *fs, fileid.fid_len = sizeof(ident); ino = _sysio_i_find(fs, &fileid); if (ino && - (forced || (ino->i_mode & S_IFMT) != (stbuf.st_mode & S_IFMT))) { + (forced || + (ino->i_stbuf.st_mode & S_IFMT) != (stbuf.st_mode & S_IFMT))) { /* * Insertion was forced or dup inum but it's already present! */ - if (native_i_invalid(ino, stbuf)) { + if (native_i_invalid(ino, &ostbuf)) { /* * Cached inode has stale attrs * make way for the new one @@ -733,7 +713,7 @@ native_inop_lookup(struct pnode *pno, static int native_inop_getattr(struct pnode *pno, struct inode *ino, - struct intnl_stat *stbuf) + struct intnl_stat *stat) { char *path; struct native_inode *nino; @@ -745,18 +725,18 @@ native_inop_getattr(struct pnode *pno, path = _sysio_pb_path(pno->p_base, '/'); if (!path) return -ENOMEM; - err = native_stat(path, nino, stbuf); + err = native_stat(path, ino, stat); free(path); } else if (nino->ni_fd >= 0) - err = native_fstat(nino->ni_fd, nino, stbuf); + err = native_stat(NULL, ino, stat); else { /* * Dev inodes don't open in this driver. We won't have * a file descriptor with which to do the deed then. Satisfy * the request from the cached copy of the attributes. */ - (void )memcpy(stbuf, - &nino->ni_stat, + (void )memcpy(stat, + &ino->i_stbuf, sizeof(struct intnl_stat)); err = 0; } @@ -768,22 +748,18 @@ static int native_inop_setattr(struct pnode *pno, struct inode *ino, unsigned mask, - struct intnl_stat *stbuf) + struct intnl_stat *stat) { char *path; struct native_inode *nino; int fd; - struct intnl_stat *stbp, _stbuf; int err; path = NULL; nino = ino ? I2NI(ino) : NULL; fd = -1; - stbp = &_stbuf; - if (nino) { + if (nino) fd = nino->ni_fd; - stbp = &nino->ni_stat; - } if (fd < 0 || mask & (SETATTR_MTIME|SETATTR_ATIME)) { if (!pno) return -EEXIST; @@ -795,10 +771,7 @@ native_inop_setattr(struct pnode *pno, /* * Get current status for undo. */ - err = - fd < 0 - ? native_stat(path, nino, stbp) - : native_fstat(fd, nino, stbp); + err = native_stat(path, ino, NULL); if (err) goto out; @@ -808,7 +781,7 @@ native_inop_setattr(struct pnode *pno, /* * Alter permissions attribute. */ - mode = stbuf->st_mode & 07777; + mode = stat->st_mode & 07777; err = fd < 0 ? syscall(SYS_chmod, path, mode) @@ -824,12 +797,12 @@ native_inop_setattr(struct pnode *pno, /* * Alter access and/or modify time attributes. */ - ut.actime = stbuf->st_atime; - ut.modtime = stbuf->st_mtime; + ut.actime = stat->st_atime; + ut.modtime = stat->st_mtime; if (mask & SETATTR_MTIME) - ut.modtime = stbuf->st_mtime; + ut.modtime = stat->st_mtime; if (mask & SETATTR_ATIME) - ut.actime = stbuf->st_atime; + ut.actime = stat->st_atime; err = syscall(__SYS_UTIME, path, &ut); if (err) err = -errno; @@ -846,18 +819,18 @@ native_inop_setattr(struct pnode *pno, ? syscall(SYS_chown, path, mask & SETATTR_UID - ? stbuf->st_uid + ? stat->st_uid : (uid_t )-1, mask & SETATTR_GID - ? stbuf->st_gid + ? stat->st_gid : (gid_t )-1) : syscall(SYS_fchown, fd, mask & SETATTR_UID - ? stbuf->st_uid + ? stat->st_uid : (uid_t )-1, mask & SETATTR_GID - ? stbuf->st_gid + ? stat->st_gid : (gid_t )-1); if (err) err = -errno; @@ -869,8 +842,8 @@ native_inop_setattr(struct pnode *pno, * Do the truncate last. It can't be undone. */ (void )(fd < 0 - ? syscall(__SYS_TRUNCATE, path, stbuf->st_size) - : syscall(__SYS_FTRUNCATE, fd, stbuf->st_size)); + ? syscall(__SYS_TRUNCATE, path, stat->st_size) + : syscall(__SYS_FTRUNCATE, fd, stat->st_size)); } if (!err) goto out; @@ -883,39 +856,37 @@ native_inop_setattr(struct pnode *pno, ? syscall(SYS_chown, path, mask & SETATTR_UID - ? stbp->st_uid + ? ino->i_stbuf.st_uid : (uid_t )-1, mask & SETATTR_GID - ? stbp->st_gid + ? ino->i_stbuf.st_gid : (gid_t )-1) : syscall(SYS_fchown, fd, mask & SETATTR_UID - ? stbp->st_uid + ? ino->i_stbuf.st_uid : (uid_t )-1, mask & SETATTR_GID - ? stbp->st_gid + ? ino->i_stbuf.st_gid : (gid_t )-1)); } if (mask & (SETATTR_MTIME|SETATTR_ATIME)) { struct utimbuf ut; - ut.actime = stbp->st_atime; - ut.modtime = stbp->st_mtime; + ut.actime = ino->i_stbuf.st_atime; + ut.modtime = ino->i_stbuf.st_mtime; (void )syscall(__SYS_UTIME, path, &ut); } if (mask & SETATTR_MODE) { fd < 0 - ? syscall(SYS_chmod, path, stbp->st_mode & 07777) - : syscall(SYS_fchmod, stbp->st_mode & 07777); + ? syscall(SYS_chmod, path, ino->i_stbuf.st_mode & 07777) + : syscall(SYS_fchmod, ino->i_stbuf.st_mode & 07777); } out: /* * We must refresh the cached attributes on success. */ - if (!err && (fd < 0 - ? native_stat(path, nino, stbp) - : native_fstat(fd, nino, stbp)) != 0) + if (!err && native_stat(path, ino, NULL) != 0) abort(); if (path) free(path); @@ -1804,6 +1775,7 @@ static void native_fsop_gone(struct filesys *fs __IS_UNUSED) { + free(fs->fs_private); /* * Do nothing. There is no private part maintained for the * native file interface. |