[Libsysio-commit] b_lustre: libsysio/drivers/incore fs_incore.c
Brought to you by:
lward
From: Mei <me...@us...> - 2003-11-01 03:08:24
|
Update of /cvsroot/libsysio/libsysio/drivers/incore In directory sc8-pr-cvs1:/tmp/cvs-serv28091/drivers/incore Modified Files: Tag: b_lustre fs_incore.c Log Message: merge HEAD into b_lustre, some fixes Index: fs_incore.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/drivers/incore/fs_incore.c,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -w -b -B -p -r1.4.2.1 -r1.4.2.2 --- fs_incore.c 15 Aug 2003 07:43:15 -0000 1.4.2.1 +++ fs_incore.c 1 Nov 2003 03:08:21 -0000 1.4.2.2 @@ -56,7 +56,9 @@ #include <sys/types.h> #include <dirent.h> #include <sys/stat.h> +#ifdef _HAVE_STATVFS #include <sys/statvfs.h> +#endif #include <sys/queue.h> #include "sysio.h" @@ -132,18 +134,18 @@ static int _sysio_incore_inop_setattr(st static ssize_t _sysio_incore_dirop_getdirentries(struct inode *ino, char *buf, size_t nbytes, - off64_t *basep); + _SYSIO_OFF_T *basep); static int _sysio_incore_dirop_mkdir(struct pnode *pno, mode_t mode); static int _sysio_incore_dirop_rmdir(struct pnode *pno); static int _sysio_incore_inop_open(struct pnode *pno, int flags, mode_t mode); static int _sysio_incore_inop_close(struct inode *ino); +static int _sysio_incore_dirop_link(struct pnode *old, struct pnode *new); static int _sysio_incore_dirop_unlink(struct pnode *pno); +static int _sysio_incore_dirop_rename(struct pnode *old, struct pnode *new); static int _sysio_incore_filop_ipreadv(struct inode *ino, - struct io_arguments *ioargs, - struct ioctx **ioctxp); + struct ioctx *ioctx); static int _sysio_incore_filop_ipwritev(struct inode *ino, - struct io_arguments *ioargs, - struct ioctx **ioctxp); + struct ioctx *ioctx); static int _sysio_incore_filop_iodone(struct ioctx *ioctx); static int _sysio_incore_filop_fcntl(struct inode *ino, int cmd, va_list ap); static int _sysio_incore_inop_sync(struct inode *ino); @@ -151,12 +153,13 @@ static int _sysio_incore_filop_ioctl(str unsigned long int request, va_list ap); static int _sysio_incore_dirop_mknod(struct pnode *pno, mode_t mode, dev_t dev); +#ifdef _HAVE_STATVFS static int _sysio_incore_inop_statvfs(struct pnode *pno, struct inode *ino, struct intnl_statvfs *buf); +#endif static void _sysio_incore_inop_gone(struct inode *ino); static int _sysio_incore_e_isdir(void); -static int _sysio_incore_e_notdir(void); static int _sysio_incore_e_inval(void); static int _sysio_incore_e_nosys(void); static void _sysio_incore_illop(void); @@ -167,12 +170,10 @@ static void _sysio_incore_illop(void); (int (*)(struct pnode *, char *, size_t))_sysio_incore_e_inval #define _sysio_incore_dirop_ipreadv \ (int (*)(struct inode *, \ - struct io_arguments *, \ - struct ioctx **))_sysio_incore_e_isdir + struct ioctx *))_sysio_incore_e_isdir #define _sysio_incore_dirop_ipwritev \ (int (*)(struct inode *, \ - struct io_arguments *, \ - struct ioctx **))_sysio_incore_e_isdir + struct ioctx *))_sysio_incore_e_isdir #define _sysio_incore_dirop_iodone \ (int (*)(struct ioctx *))_sysio_incore_illop #define _sysio_incore_dirop_fcntl \ @@ -193,7 +194,9 @@ static struct inode_ops _sysio_incore_di _sysio_incore_dirop_readlink, _sysio_incore_inop_open, _sysio_incore_inop_close, + _sysio_incore_dirop_link, _sysio_incore_dirop_unlink, + _sysio_incore_dirop_rename, _sysio_incore_dirop_ipreadv, _sysio_incore_dirop_ipwritev, _sysio_incore_dirop_iodone, @@ -202,7 +205,9 @@ static struct inode_ops _sysio_incore_di _sysio_incore_inop_sync, _sysio_incore_dirop_ioctl, _sysio_incore_dirop_mknod, +#ifdef _HAVE_STATVFS _sysio_incore_inop_statvfs, +#endif _sysio_incore_inop_gone }; @@ -210,24 +215,28 @@ static struct inode_ops _sysio_incore_di (int (*)(struct pnode *, \ struct inode **, \ struct intent *, \ - const char *))_sysio_incore_e_notdir + const char *))_sysio_incore_illop #define _sysio_incore_filop_getdirentries \ (ssize_t (*)(struct inode *, \ char *, \ size_t, \ - off64_t *))_sysio_incore_e_notdir + _SYSIO_OFF_T *))_sysio_incore_illop #define _sysio_incore_filop_mkdir \ - (int (*)(struct pnode *, mode_t))_sysio_incore_e_notdir + (int (*)(struct pnode *, mode_t))_sysio_incore_illop #define _sysio_incore_filop_rmdir \ - (int (*)(struct pnode *))_sysio_incore_e_notdir + (int (*)(struct pnode *))_sysio_incore_illop #define _sysio_incore_filop_symlink \ (int (*)(struct pnode *, const char *))_sysio_incore_illop #define _sysio_incore_symlinkop_readlink \ (int (*)(struct pnode *, char *, size_t))_sysio_incore_illop +#define _sysio_incore_filop_link \ + (int (*)(struct pnode *old, struct pnode *new))_sysio_incore_illop #define _sysio_incore_filop_unlink \ - (int (*)(struct pnode *pno))_sysio_incore_e_notdir + (int (*)(struct pnode *pno))_sysio_incore_illop +#define _sysio_incore_filop_rename \ + (int (*)(struct pnode *old, struct pnode *new))_sysio_incore_illop #define _sysio_incore_filop_mknod \ - (int (*)(struct pnode *pno, mode_t, dev_t))_sysio_incore_e_notdir + (int (*)(struct pnode *pno, mode_t, dev_t))_sysio_incore_illop static struct inode_ops _sysio_incore_file_ops = { _sysio_incore_filop_lookup, @@ -240,7 +249,9 @@ static struct inode_ops _sysio_incore_fi _sysio_incore_symlinkop_readlink, _sysio_incore_inop_open, _sysio_incore_inop_close, + _sysio_incore_filop_link, _sysio_incore_filop_unlink, + _sysio_incore_filop_rename, _sysio_incore_filop_ipreadv, _sysio_incore_filop_ipwritev, _sysio_incore_filop_iodone, @@ -249,7 +260,9 @@ static struct inode_ops _sysio_incore_fi _sysio_incore_inop_sync, _sysio_incore_filop_ioctl, _sysio_incore_filop_mknod, +#ifdef _HAVE_STATVFS _sysio_incore_inop_statvfs, +#endif _sysio_incore_inop_gone }; @@ -264,7 +277,9 @@ static struct inode_ops _sysio_incore_de _sysio_incore_symlinkop_readlink, _sysio_nodev_inop_open, _sysio_nodev_inop_close, + _sysio_incore_filop_link, _sysio_incore_filop_unlink, + _sysio_incore_filop_rename, _sysio_nodev_inop_ipreadv, _sysio_nodev_inop_ipwritev, _sysio_nodev_inop_iodone, @@ -273,7 +288,9 @@ static struct inode_ops _sysio_incore_de _sysio_nodev_inop_sync, _sysio_nodev_inop_ioctl, _sysio_incore_filop_mknod, +#ifdef _HAVE_STATVFS _sysio_incore_inop_statvfs, +#endif _sysio_incore_inop_gone }; @@ -309,7 +326,7 @@ struct lookup_data { */ #define INCORE_D_RECLEN(namlen) \ (((size_t )&((struct intnl_dirent *)0)->d_name + \ - (namlen) + sizeof(void *)) & \ + (namlen) + 1 + sizeof(void *)) & \ ~(sizeof(void *) - 1)) /* @@ -350,14 +367,30 @@ _sysio_incore_init() * Fill in the directory template. */ de = (struct intnl_dirent *)incore_dir_template; - de->d_off = off = de->d_reclen = INCORE_D_RECLEN(1); +#ifdef _DIRENT_HAVE_D_OFF + de->d_off = +#endif + off = de->d_reclen = INCORE_D_RECLEN(1); de->d_type = INCORE_D_TYPEOF(S_IFDIR); de->d_name[0] = '.'; - de = (void *)de + de->d_off; +#ifdef _DIRENT_HAVE_D_NAMLEN + de->d_namlen = 1; +#endif + /* + * Move to entry for `..' + */ + de = (void *)de + off; de->d_reclen = INCORE_D_RECLEN(2); - de->d_off = off += de->d_reclen; +#ifdef _DIRENT_HAVE_D_NAMLEN + de->d_namlen = 2; +#endif +#ifdef _DIRENT_HAVE_D_OFF + de->d_off = +#endif + off += de->d_reclen; de->d_type = INCORE_D_TYPEOF(S_IFDIR); de->d_name[0] = de->d_name[1] = '.'; + de->d_name[2] = ' '; return _sysio_fssw_register("incore", &incore_fssw_ops); } @@ -394,9 +427,9 @@ incore_i_alloc(struct incore_filesys *ic } static int -incore_trunc(struct incore_inode *icino, off64_t size, int clear) +incore_trunc(struct incore_inode *icino, _SYSIO_OFF_T size, int clear) { - off64_t n; + _SYSIO_OFF_T n; void *p; if (size < 0) @@ -464,7 +497,12 @@ incore_directory_new(struct incore_files sizeof(incore_dir_template)); de = icino->ici_data; de->d_ino = st->st_ino; - (void *)de += de->d_off; + (void *)de += +#ifdef _DIRENT_HAVE_D_OFF + de->d_off; +#else + de->d_reclen; +#endif de->d_ino = parent->ici_st.st_ino; /* @@ -587,7 +625,6 @@ _sysio_incore_fsswop_mount(const char *s */ rooti = _sysio_i_new(fs, - icino->ici_st.st_ino, &icino->ici_fileid, icino->ici_st.st_mode, 0, @@ -682,7 +719,11 @@ _sysio_incore_fsop_gone(struct filesys * static void * incore_directory_probe(void *data, size_t siz, - off64_t origin, + _SYSIO_OFF_T origin +#ifndef _DIRENT_HAVE_D_OFF + __IS_UNUSED +#endif + , probe_ty entry, probe_ty hole, void *arg) @@ -693,15 +734,21 @@ incore_directory_probe(void *data, de = data; for (;;) { +#ifdef _DIRENT_HAVE_D_OFF assert(de->d_off); +#else + assert(de->d_reclen); +#endif if (entry && (p = (*entry)(de, de->d_reclen, arg))) return p; - n = de->d_off - origin; - if (hole && n > de->d_reclen) { - p = - (*hole)((void *)de + de->d_reclen, - n - de->d_reclen, - arg); + n = +#ifdef _DIRENT_HAVE_D_OFF + de->d_off - origin; +#else + ((void *)de - data) + de->d_reclen; +#endif + if (hole) { + p = (*hole)((void *)de, de->d_reclen, arg); if (p) return p; } @@ -719,7 +766,15 @@ incore_directory_match(struct intnl_dire struct lookup_data *ld) { - if (strncmp(de->d_name, ld->name->name, ld->name->len) == 0) +#if defined(BSD) || defined(REDSTORM) + if (IFTODT(de->d_type) == DT_WHT) + return NULL; +#endif + if ( +#ifdef _DIRENT_HAVE_D_NAMLEN + ld->name->len == de->d_namlen && +#endif + strncmp(de->d_name, ld->name->name, ld->name->len) == 0) return de; ld->de = de; return NULL; @@ -771,7 +826,7 @@ _sysio_incore_dirop_lookup(struct pnode fileid.fid_data = &de->d_ino; fileid.fid_len = sizeof(de->d_ino); ino = - _sysio_i_find(ino->i_fs, de->d_ino, &fileid); + _sysio_i_find(ino->i_fs, &fileid); #ifdef notdef if (ino) goto out; @@ -792,7 +847,6 @@ _sysio_incore_dirop_lookup(struct pnode abort(); ino = _sysio_i_new(ino->i_fs, - icino->ici_st.st_ino, &icino->ici_fileid, icino->ici_st.st_mode, 0, @@ -879,6 +933,13 @@ struct copy_info { size_t nbytes; }; +/* + * Eumeration callback. + * + * Note: + * On those systems supporting white-out entries, they are returned. On + * systems without, they are not. + */ static void * incore_directory_enumerate(struct intnl_dirent *de, size_t reclen, @@ -896,7 +957,7 @@ static ssize_t _sysio_incore_dirop_getdirentries(struct inode *ino, char *buf, size_t nbytes, - off64_t *basep) + _SYSIO_OFF_T *basep) { struct incore_inode *icino = I2IC(ino); off_t off; @@ -960,7 +1021,9 @@ incore_directory_insert(struct incore_in size_t reclen; struct lookup_data lookup_data; struct intnl_dirent *de; + size_t xt; size_t n; + size_t r; reclen = INCORE_D_RECLEN(name->len); INCORE_LD_INIT(&lookup_data, reclen, name); @@ -974,38 +1037,74 @@ incore_directory_insert(struct incore_in if (de) return -EEXIST; de = lookup_data.de; - n = de->d_off; - if (n >= (size_t )parent->ici_st.st_size) { + xt = (void *)lookup_data.de - parent->ici_data; + n = +#ifdef _DIRENT_HAVE_D_OFF + de->d_off; +#else + xt + de->d_reclen; +#endif + r = +#ifdef _DIRENT_HAVE_D_OFF + de->d_reclen; +#else + INCORE_D_RECLEN(de->d_namlen); +#endif + if (!parent->ici_st.st_size || + xt + r + reclen > (size_t )parent->ici_st.st_size) { int err; - size_t xt; - xt = (void *)lookup_data.de - parent->ici_data; - err = - incore_trunc(parent, - ((size_t )((void *)de - parent->ici_data) + - de->d_reclen + - reclen), - 1); + err = incore_trunc(parent, xt + r + reclen, 1); if (err) return err; de = parent->ici_data + xt; n = parent->ici_st.st_size; } +#ifdef _DIRENT_HAVE_D_OFF + de->d_off = xt + r; /* trim */ +#else + de->d_reclen = r; +#endif + (void *)de += r; /* reposition */ + xt += r; + +#ifndef _DIRENT_HAVE_D_OFF /* - * Fix previous entry. + * Will we split this hole or use all of it? */ - de->d_off = (void *)de - parent->ici_data + de->d_reclen; + if (lookup_data.hole.len - reclen && + lookup_data.hole.len - reclen <= INCORE_D_RECLEN(1)) + reclen = lookup_data.hole.len; +#endif /* * Insert new. */ - (void *)de += de->d_reclen; de->d_ino = inum; +#ifdef _DIRENT_HAVE_D_OFF de->d_off = n; +#endif de->d_reclen = reclen; de->d_type = type; (void )memcpy(de->d_name, name->name, name->len); +#ifdef _DIRENT_HAVE_D_NAMLEN + de->d_namlen = name->len; +#endif + +#ifndef _DIRENT_HAVE_D_OFF + xt += reclen; + if (n - xt) { + /* + * White-out remaining part of the hole. + */ + (void *)de += reclen; + de->d_ino = 0; + de->d_reclen = n - xt; + de->d_type = DT_WHT; + de->d_namlen = 0; + } +#endif /* * Update attributes to reflect the new entry. @@ -1057,7 +1156,6 @@ _sysio_incore_dirop_mkdir(struct pnode * */ ino = _sysio_i_new(pno->p_parent->p_base->pb_ino->i_fs, - stat.st_ino, &icino->ici_fileid, stat.st_mode, 0, @@ -1095,6 +1193,10 @@ incore_unlink_entry(struct incore_inode { struct lookup_data lookup_data; struct intnl_dirent *de; + size_t reclen; +#ifdef _DIRENT_HAVE_D_OFF + size_t off; +#endif if (!S_ISDIR(icino->ici_st.st_mode)) return -ENOTDIR; @@ -1111,8 +1213,25 @@ incore_unlink_entry(struct incore_inode return -ENOENT; assert((size_t )((void *)de - icino->ici_data) >= sizeof(incore_dir_template)); - lookup_data.de->d_off = de->d_off; /* unlink */ - (void )memset(de, 0, de->d_reclen); /* clear */ +#ifndef _DIRENT_HAVE_D_OFF + reclen = de->d_reclen; +#else + off = de->d_off; + reclen = off - ((void *)de - icino->ici_data); +#endif + (void )memset(de, 0, reclen); +#ifndef _DIRENT_HAVE_D_OFF + de->d_type = (__uint8_t )DTTOIF(DT_WHT); + de->d_reclen = reclen; +#else + lookup_data.de->d_off = off; +#endif + + /* + * Adjust link count. + */ + assert(icino->ici_st.st_nlink > 2); + icino->ici_st.st_nlink--; return 0; } @@ -1145,6 +1264,12 @@ _sysio_incore_dirop_rmdir(struct pnode * return err; I_RELE(ino); + /* + * Adjust link count. + */ + assert(icino->ici_st.st_nlink > 2); + icino->ici_st.st_nlink--; + return 0; } @@ -1167,7 +1292,6 @@ incore_create(struct pnode *pno, struct */ ino = _sysio_i_new(dino->i_fs, - st->st_ino, &icino->ici_fileid, st->st_mode, st->st_rdev, @@ -1242,6 +1366,94 @@ _sysio_incore_inop_close(struct inode *i } static int +_sysio_incore_dirop_link(struct pnode *old, struct pnode *new) +{ + struct incore_inode *icino = I2IC(old->p_base->pb_ino); + int err; + + assert(!new->p_base->pb_ino); + assert(!S_ISDIR(old->p_base->pb_ino->i_mode)); + + /* + * Can bump the link count? + */ + if (!(icino->ici_st.st_nlink + 1)) + return -EMLINK; + /* + * Insert into parent. + */ + err = + incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino), + &new->p_base->pb_name, + icino->ici_st.st_ino, + INCORE_D_TYPEOF(icino->ici_st.st_mode)); + if (err) + return err; + /* + * Bump the link count. + */ + icino->ici_st.st_nlink++; + + return 0; +} + +static int +_sysio_incore_dirop_rename(struct pnode *old, struct pnode *new) +{ + int err; + struct incore_inode *icino = I2IC(old->p_base->pb_ino); + + if (new->p_base->pb_ino) { + /* + * Have to kill off the target first. + */ + if (S_ISDIR(I2IC(new->p_base->pb_ino)->ici_st.st_mode) && + I2IC(new->p_base->pb_ino)->ici_st.st_nlink > 2) + return -ENOTEMPTY; + err = + incore_unlink_entry(I2IC(new->p_parent->p_base->pb_ino), + &new->p_base->pb_name); + if (err) + return err; + I_RELE(new->p_base->pb_ino); + _sysio_i_gone(new->p_base->pb_ino); + new->p_base->pb_ino = NULL; + } + + /* + * Insert into new parent. + */ + err = + incore_directory_insert(I2IC(new->p_parent->p_base->pb_ino), + &new->p_base->pb_name, + icino->ici_st.st_ino, + INCORE_D_TYPEOF(icino->ici_st.st_mode)); + if (err) + abort(); + /* + * Remove from the old parent. + */ + err = + incore_unlink_entry(I2IC(old->p_parent->p_base->pb_ino), + &old->p_base->pb_name); + if (err) + abort(); + + if (S_ISDIR(icino->ici_st.st_mode)) { + struct intnl_dirent *de; + + /* + * We moved a directory. The entry for `..' must be corrected. + */ + de = icino->ici_data; + de++; + assert(strcmp(de->d_name, "..") == 0); + de->d_ino = I2IC(new->p_parent->p_base->pb_ino)->ici_st.st_ino; + } + return 0; +} + +static int _sysio_incore_dirop_unlink(struct pnode *pno) { struct inode *ino = pno->p_base->pb_ino; @@ -1251,7 +1463,6 @@ _sysio_incore_dirop_unlink(struct pnode if (S_ISDIR(icino->ici_st.st_mode)) return -EISDIR; - pno->p_base->pb_ino = NULL; err = incore_unlink_entry(I2IC(pno->p_parent->p_base->pb_ino), &pno->p_base->pb_name); @@ -1265,18 +1476,12 @@ _sysio_incore_dirop_unlink(struct pnode static int incore_doio(ssize_t (*f)(struct incore_inode *, off_t, char *, size_t), struct inode *ino, - struct io_arguments *ioargs, - struct ioctx **ioctxp) + struct ioctx *ioctx) { - struct ioctx *ioctx; const struct iovec *iov; size_t n; ssize_t cc = 0; - ioctx = _sysio_ioctx_new(ino, ioargs); - if (!ioctx) - return -ENOMEM; - iov = ioctx->ioctx_iovec; for (n = ioctx->ioctx_iovlen, iov = ioctx->ioctx_iovec; n--; @@ -1297,18 +1502,19 @@ incore_doio(ssize_t (*f)(struct incore_i ioctx->ioctx_errno = -cc; } - *ioctxp = ioctx; + ioctx->ioctx_done = 1; + return 0; } static ssize_t incore_read(struct incore_inode *icino, off_t off, char *buf, size_t nbytes) { - off64_t n; + _SYSIO_OFF_T n; if (!nbytes || off > icino->ici_st.st_size) return 0; - n = (off64_t )nbytes; + n = (_SYSIO_OFF_T )nbytes; if (!(n > 0 && (size_t )n == nbytes)) return -EINVAL; if (n > icino->ici_st.st_size - off) @@ -1320,11 +1526,10 @@ incore_read(struct incore_inode *icino, static int _sysio_incore_filop_ipreadv(struct inode *ino, - struct io_arguments *ioargs, - struct ioctx **ioctxp) + struct ioctx *ioctx) { - return incore_doio(incore_read, ino, ioargs, ioctxp); + return incore_doio(incore_read, ino, ioctx); } static ssize_t @@ -1334,11 +1539,11 @@ incore_write(struct incore_inode *icino, size_t nbytes) { int err; - off64_t n; + _SYSIO_OFF_T n; if (!nbytes) return 0; - n = (off64_t )nbytes; + n = (_SYSIO_OFF_T )nbytes; if (!(n > 0 && (size_t )n == nbytes)) return -EINVAL; if (off + n > icino->ici_st.st_size) { @@ -1353,8 +1558,7 @@ incore_write(struct incore_inode *icino, static int _sysio_incore_filop_ipwritev(struct inode *ino, - struct io_arguments *ioargs, - struct ioctx **ioctxp) + struct ioctx *ioctx) { return incore_doio((ssize_t (*)(struct incore_inode *, @@ -1362,8 +1566,7 @@ _sysio_incore_filop_ipwritev(struct inod char *, size_t))incore_write, ino, - ioargs, - ioctxp); + ioctx); } static int @@ -1430,7 +1633,7 @@ _sysio_incore_dirop_mknod(struct pnode * return -EINVAL; /* - * Must create a new, regular, file. + * Initialize attributes. */ (void )memset(&stat, 0, sizeof(stat)); stat.st_dev = pno->p_parent->p_base->pb_ino->i_fs->fs_dev; @@ -1452,6 +1655,7 @@ _sysio_incore_dirop_mknod(struct pnode * return incore_create(pno, &stat); } +#ifdef _HAVE_STATVFS static int _sysio_incore_inop_statvfs(struct pnode *pno, struct inode *ino, @@ -1472,7 +1676,8 @@ _sysio_incore_inop_statvfs(struct pnode */ buf->f_bsize = fs->fs_bsize; buf->f_frsize = buf->f_bsize; - buf->f_blocks = (0xffffffffffffffff - 1) / buf->f_bsize; + buf->f_blocks = ~0; + buf->f_blocks /= buf->f_bsize; buf->f_bfree = buf->f_blocks - 1; buf->f_bavail = buf->f_bfree; buf->f_files = buf->f_blocks; @@ -1484,6 +1689,7 @@ _sysio_incore_inop_statvfs(struct pnode return 0; } +#endif void _sysio_incore_inop_gone(struct inode *ino) @@ -1498,13 +1704,6 @@ _sysio_incore_e_isdir(void) { return -EISDIR; -} - -static int -_sysio_incore_e_notdir(void) -{ - - return -ENOTDIR; } static int |