From df93d6b832fdf0c8c51a4e3d9230ea5c95f2af1f Mon Sep 17 00:00:00 2001 From: tianying Date: Sat, 17 Jan 2004 04:02:05 +0000 Subject: [PATCH] * b:1934 - fix mds_cleanup_orphans * r: Robert allocate dirent dynamicly --- 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, 87 insertions(+), 84 deletions(-) diff --git a/lustre/include/linux/lvfs.h b/lustre/include/linux/lvfs.h index 6f48bcc..bf27a40 100644 --- a/lustre/include/linux/lvfs.h +++ b/lustre/include/linux/lvfs.h @@ -3,6 +3,8 @@ #include +#define LL_FID_NAMELEN (16 + 1 + 8 + 1) + #if defined __KERNEL__ #include #endif @@ -59,7 +61,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, void * dirent, unsigned int count); +long l_readdir(struct file * file, struct list_head *dentry_list); static inline void l_dput(struct dentry *de) { @@ -96,7 +98,6 @@ 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 b38d6f0..71fc431 100644 --- a/lustre/include/linux/lvfs_linux.h +++ b/lustre/include/linux/lvfs_linux.h @@ -1,3 +1,6 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + */ #ifndef __LVFS_LINUX_H__ #define __LVFS_LINUX_H__ @@ -22,17 +25,14 @@ struct l_file *l_dentry_open(struct obd_run_ctxt *, struct l_dentry *, int flags); struct l_linux_dirent { - ino_t d_ino; - unsigned long d_off; - unsigned short d_reclen; - char d_name[1]; + struct list_head lld_list; + ino_t lld_ino; + unsigned long lld_off; + char lld_name[LL_FID_NAMELEN]; }; - struct l_readdir_callback { - struct l_linux_dirent *current_dir; - struct l_linux_dirent *previous; - int count; - int error; + struct l_linux_dirent *lrc_dirent; + struct list_head *lrc_list; }; #endif diff --git a/lustre/lvfs/lvfs_linux.c b/lustre/lvfs/lvfs_linux.c index 61cd57c..b7fb933 100644 --- a/lustre/lvfs/lvfs_linux.c +++ b/lustre/lvfs/lvfs_linux.c @@ -308,47 +308,41 @@ 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); - buf->error = -EINVAL; - if (reclen > buf->count) - return -EINVAL; - dirent = buf->previous; + dirent = buf->lrc_dirent; if (dirent) - 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; + 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)); + return 0; } -long l_readdir(struct file * file, void * dirent, unsigned int count) +long l_readdir(struct file *file, struct list_head *dentry_list) { - struct l_linux_dirent * lastdirent; + struct l_linux_dirent *lastdirent; struct l_readdir_callback buf; int error; - buf.current_dir = (struct l_linux_dirent *)dirent; - buf.previous = NULL; - buf.count = count; - buf.error = 0; + buf.lrc_dirent = NULL; + buf.lrc_list = dentry_list; error = vfs_readdir(file, l_filldir, &buf); if (error < 0) return error; - error = buf.error; - lastdirent = buf.previous; - if (lastdirent) { - lastdirent->d_off = file->f_pos; - error = count - buf.count; - } - return error; + lastdirent = buf.lrc_dirent; + if (lastdirent) + lastdirent->lld_off = file->f_pos; + + return 0; } EXPORT_SYMBOL(l_readdir); diff --git a/lustre/mds/mds_unlink_open.c b/lustre/mds/mds_unlink_open.c index 330ef32..5e6bb75 100644 --- a/lustre/mds/mds_unlink_open.c +++ b/lustre/mds/mds_unlink_open.c @@ -238,87 +238,95 @@ 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; + struct dentry *dchild, *dentry; + struct vfsmount *mnt; struct inode *child_inode, *pending_dir = mds->mds_pending_dir->d_inode; - struct l_linux_dirent *dirent, *ptr; - unsigned int count = pending_dir->i_size; - int rc = 0, rc2 = 0, item = 0; + 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; ENTRY; push_ctxt(&saved, &obd->obd_ctxt, NULL); - dget(mds->mds_pending_dir); - mntget(mds->mds_vfsmnt); + 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)); + file = dentry_open(mds->mds_pending_dir, mds->mds_vfsmnt, O_RDONLY | O_LARGEFILE); if (IS_ERR(file)) - GOTO(err_open, rc2 = PTR_ERR(file)); - - OBD_ALLOC(dirent, count); - if (dirent == NULL) - GOTO(err_alloc_dirent, rc2 = -ENOMEM); + GOTO(err_pop, rc = PTR_ERR(file)); - rc = l_readdir(file, dirent, count); + INIT_LIST_HEAD(&dentry_list); + rc = l_readdir(file, &dentry_list); filp_close(file, 0); if (rc < 0) - 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, ".."))) + 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, ".."))) { continue; + } down(&pending_dir->i_sem); - dchild = lookup_one_len(ptr->d_name, mds->mds_pending_dir, - namlen); + dchild = lookup_one_len(d_name, mds->mds_pending_dir, namlen); if (IS_ERR(dchild)) { up(&pending_dir->i_sem); - GOTO(err_out, rc2 = PTR_ERR(dchild)); + GOTO(err_out, rc = PTR_ERR(dchild)); } if (!dchild->d_inode) { - CDEBUG(D_ERROR, "orphan %s has been removed\n", - ptr->d_name); - GOTO(next, rc2 = 0); + CERROR("orphan %s has been removed\n", d_name); + GOTO(next, rc = 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", - ptr->d_name); - GOTO(next, rc2 = 0); + CWARN("orphan %s was re-opened during recovery\n", d_name); + GOTO(next, rc = 0); } - rc2 = mds_unlink_orphan(obd, dchild, child_inode, pending_dir); - if (rc2 == 0) { + rc = mds_unlink_orphan(obd, dchild, child_inode, pending_dir); + if (rc == 0) { item ++; - CWARN("removed orphan %s from MDS and OST\n", - ptr->d_name); + CWARN("removed orphan %s from MDS and OST\n", d_name); } else { - l_dput(dchild); - up(&pending_dir->i_sem); - GOTO(err_out, rc2); + CERROR("removed orphan %s from MDS and OST failed," + " rc = %d\n", d_name, rc); + rc = 0; } next: l_dput(dchild); up(&pending_dir->i_sem); } err_out: - OBD_FREE(dirent, count); + list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) { + list_del(&dirent->lld_list); + PORTAL_FREE(dirent, sizeof(*dirent)); + } err_pop: pop_ctxt(&saved, &obd->obd_ctxt, NULL); - if (rc2 == 0) - rc2 = item; - - RETURN(rc2); + if (rc == 0) + rc = item; + RETURN(rc); -err_open: - mntput(mds->mds_vfsmnt); +err_mntget: l_dput(mds->mds_pending_dir); goto err_pop; -err_alloc_dirent: - filp_close(file, 0); - goto err_pop; } -- 1.8.3.1