From 7e2b7edbe95ef032f84c0d2f54669b8b6318c8a7 Mon Sep 17 00:00:00 2001 From: zab Date: Sun, 18 Jan 2004 23:08:15 +0000 Subject: [PATCH] - revert the b=1934 fix from 1/16 to stop llmount from hanging --- lustre/include/linux/lvfs.h | 5 +- lustre/include/linux/lvfs_linux.h | 18 +++---- lustre/lvfs/lvfs_linux.c | 48 ++++++++++-------- lustre/mds/mds_unlink_open.c | 100 ++++++++++++++++++-------------------- 4 files changed, 84 insertions(+), 87 deletions(-) diff --git a/lustre/include/linux/lvfs.h b/lustre/include/linux/lvfs.h index bf27a40..6f48bcc 100644 --- a/lustre/include/linux/lvfs.h +++ b/lustre/include/linux/lvfs.h @@ -3,8 +3,6 @@ #include -#define LL_FID_NAMELEN (16 + 1 + 8 + 1) - #if defined __KERNEL__ #include #endif @@ -61,7 +59,7 @@ struct dentry *simple_mknod(struct dentry *dir, char *name, int mode); int lustre_fread(struct file *file, void *buf, int len, loff_t *off); int lustre_fwrite(struct file *file, const void *buf, int len, loff_t *off); int lustre_fsync(struct file *file); -long l_readdir(struct file * file, struct list_head *dentry_list); +long l_readdir(struct file * file, void * dirent, unsigned int count); static inline void l_dput(struct dentry *de) { @@ -98,6 +96,7 @@ static inline void ll_sleep(int t) } #endif +#define LL_FID_NAMELEN (16 + 1 + 8 + 1) static inline int ll_fid2str(char *str, __u64 id, __u32 generation) { return sprintf(str, "%llx:%08x", (unsigned long long)id, generation); diff --git a/lustre/include/linux/lvfs_linux.h b/lustre/include/linux/lvfs_linux.h index 71fc431..b38d6f0 100644 --- a/lustre/include/linux/lvfs_linux.h +++ b/lustre/include/linux/lvfs_linux.h @@ -1,6 +1,3 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - */ #ifndef __LVFS_LINUX_H__ #define __LVFS_LINUX_H__ @@ -25,14 +22,17 @@ struct l_file *l_dentry_open(struct obd_run_ctxt *, struct l_dentry *, int flags); struct l_linux_dirent { - struct list_head lld_list; - ino_t lld_ino; - unsigned long lld_off; - char lld_name[LL_FID_NAMELEN]; + ino_t d_ino; + unsigned long d_off; + unsigned short d_reclen; + char d_name[1]; }; + struct l_readdir_callback { - struct l_linux_dirent *lrc_dirent; - struct list_head *lrc_list; + struct l_linux_dirent *current_dir; + struct l_linux_dirent *previous; + int count; + int error; }; #endif diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c index b7fb933..61cd57c 100644 --- a/lustre/lvfs/lvfs_linux.c +++ b/lustre/lvfs/lvfs_linux.c @@ -308,41 +308,47 @@ static int l_filldir(void *__buf, const char *name, int namlen, loff_t offset, { struct l_linux_dirent *dirent; struct l_readdir_callback *buf = (struct l_readdir_callback *)__buf; + int reclen = size_round(offsetof(struct l_linux_dirent, d_name) + namlen + 1); - dirent = buf->lrc_dirent; + buf->error = -EINVAL; + if (reclen > buf->count) + return -EINVAL; + dirent = buf->previous; if (dirent) - dirent->lld_off = offset; - - PORTAL_ALLOC(dirent, sizeof(*dirent)); - - list_add_tail(&dirent->lld_list, buf->lrc_list); - - buf->lrc_dirent = dirent; - dirent->lld_ino = ino; - LASSERT(sizeof(dirent->lld_name) >= strlen(name) + 1); - memcpy(dirent->lld_name, name, strlen(name)); - + dirent->d_off = offset; + dirent = buf->current_dir; + buf->previous = dirent; + dirent->d_ino = ino; + dirent->d_reclen = reclen; + memcpy(dirent->d_name, name, namlen); + ((char *)dirent) += reclen; + buf->current_dir = dirent; + buf->count -= reclen; return 0; } -long l_readdir(struct file *file, struct list_head *dentry_list) +long l_readdir(struct file * file, void * dirent, unsigned int count) { - struct l_linux_dirent *lastdirent; + struct l_linux_dirent * lastdirent; struct l_readdir_callback buf; int error; - buf.lrc_dirent = NULL; - buf.lrc_list = dentry_list; + buf.current_dir = (struct l_linux_dirent *)dirent; + buf.previous = NULL; + buf.count = count; + buf.error = 0; error = vfs_readdir(file, l_filldir, &buf); if (error < 0) return error; + error = buf.error; + lastdirent = buf.previous; - lastdirent = buf.lrc_dirent; - if (lastdirent) - lastdirent->lld_off = file->f_pos; - - return 0; + if (lastdirent) { + lastdirent->d_off = file->f_pos; + error = count - buf.count; + } + return error; } EXPORT_SYMBOL(l_readdir); diff --git a/lustre/mds/mds_unlink_open.c b/lustre/mds/mds_unlink_open.c index 5e6bb75..330ef32 100644 --- a/lustre/mds/mds_unlink_open.c +++ b/lustre/mds/mds_unlink_open.c @@ -238,95 +238,87 @@ int mds_cleanup_orphans(struct obd_device *obd) struct mds_obd *mds = &obd->u.mds; struct obd_run_ctxt saved; struct file *file; - struct dentry *dchild, *dentry; - struct vfsmount *mnt; + struct dentry *dchild; struct inode *child_inode, *pending_dir = mds->mds_pending_dir->d_inode; - struct l_linux_dirent *dirent, *n; - struct list_head dentry_list; - char d_name[LL_FID_NAMELEN]; - __u64 i = 0; - int rc = 0, item = 0, namlen; + struct l_linux_dirent *dirent, *ptr; + unsigned int count = pending_dir->i_size; + int rc = 0, rc2 = 0, item = 0; ENTRY; push_ctxt(&saved, &obd->obd_ctxt, NULL); - dentry = dget(mds->mds_pending_dir); - if (IS_ERR(dentry)) - GOTO(err_pop, rc = PTR_ERR(dentry)); - mnt = mntget(mds->mds_vfsmnt); - if (IS_ERR(mnt)) - GOTO(err_mntget, rc = PTR_ERR(mnt)); - + dget(mds->mds_pending_dir); + mntget(mds->mds_vfsmnt); file = dentry_open(mds->mds_pending_dir, mds->mds_vfsmnt, O_RDONLY | O_LARGEFILE); if (IS_ERR(file)) - GOTO(err_pop, rc = PTR_ERR(file)); + GOTO(err_open, rc2 = PTR_ERR(file)); + + OBD_ALLOC(dirent, count); + if (dirent == NULL) + GOTO(err_alloc_dirent, rc2 = -ENOMEM); - INIT_LIST_HEAD(&dentry_list); - rc = l_readdir(file, &dentry_list); + rc = l_readdir(file, dirent, count); filp_close(file, 0); if (rc < 0) - GOTO(err_out, rc); - - list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { - i ++; - list_del(&dirent->lld_list); - - namlen = strlen(dirent->lld_name); - LASSERT(sizeof(d_name) >= namlen + 1); - memcpy(d_name, dirent->lld_name, namlen); - PORTAL_FREE(dirent, sizeof(*dirent)); - - CDEBUG(D_INODE, "entry "LPU64" of PENDING DIR: %s\n", - i, d_name); - - if (((namlen == 1) && !strcmp(d_name, ".")) || - ((namlen == 2) && !strcmp(d_name, ".."))) { + GOTO(err_out, rc2 = rc); + + for (ptr = dirent; (char *)ptr < (char *)dirent + rc; + (char *)ptr += ptr->d_reclen) { + int namlen = strlen(ptr->d_name); + + if (((namlen == 1) && !strcmp(ptr->d_name, ".")) || + ((namlen == 2) && !strcmp(ptr->d_name, ".."))) continue; - } down(&pending_dir->i_sem); - dchild = lookup_one_len(d_name, mds->mds_pending_dir, namlen); + dchild = lookup_one_len(ptr->d_name, mds->mds_pending_dir, + namlen); if (IS_ERR(dchild)) { up(&pending_dir->i_sem); - GOTO(err_out, rc = PTR_ERR(dchild)); + GOTO(err_out, rc2 = PTR_ERR(dchild)); } if (!dchild->d_inode) { - CERROR("orphan %s has been removed\n", d_name); - GOTO(next, rc = 0); + CDEBUG(D_ERROR, "orphan %s has been removed\n", + ptr->d_name); + GOTO(next, rc2 = 0); } child_inode = dchild->d_inode; if (mds_inode_is_orphan(child_inode) && mds_open_orphan_count(child_inode)) { - CWARN("orphan %s was re-opened during recovery\n", d_name); - GOTO(next, rc = 0); + CWARN("orphan %s was re-opened during recovery\n", + ptr->d_name); + GOTO(next, rc2 = 0); } - rc = mds_unlink_orphan(obd, dchild, child_inode, pending_dir); - if (rc == 0) { + rc2 = mds_unlink_orphan(obd, dchild, child_inode, pending_dir); + if (rc2 == 0) { item ++; - CWARN("removed orphan %s from MDS and OST\n", d_name); + CWARN("removed orphan %s from MDS and OST\n", + ptr->d_name); } else { - CERROR("removed orphan %s from MDS and OST failed," - " rc = %d\n", d_name, rc); - rc = 0; + l_dput(dchild); + up(&pending_dir->i_sem); + GOTO(err_out, rc2); } next: l_dput(dchild); up(&pending_dir->i_sem); } err_out: - list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { - list_del(&dirent->lld_list); - PORTAL_FREE(dirent, sizeof(*dirent)); - } + OBD_FREE(dirent, count); err_pop: pop_ctxt(&saved, &obd->obd_ctxt, NULL); - if (rc == 0) - rc = item; - RETURN(rc); + if (rc2 == 0) + rc2 = item; + + RETURN(rc2); -err_mntget: +err_open: + mntput(mds->mds_vfsmnt); l_dput(mds->mds_pending_dir); goto err_pop; +err_alloc_dirent: + filp_close(file, 0); + goto err_pop; } -- 1.8.3.1