From 0d623db5f7effc9a7a27826296bc97149889a3d4 Mon Sep 17 00:00:00 2001 From: shaver Date: Mon, 30 Dec 2002 21:10:47 +0000 Subject: [PATCH] - Add extN select-inum-for-allocation support, and use it to make recovery-time inode creation more deterministic. - Test program and ioctl for the aforementioned wantedi support. - Don't send MSG_LAST_REPLAY with the last-replayed lock. Really. I mean it this time. - Some transno-reintegration CERROR removal, because the 9600bps conman on dev cramps the style of 300-transaction replays something fierce. - Sync after every integrated transaction, so that we make forward progress in case of interrupted recovery. (This will be replaced by the handle->h_sync fix foreshadowed in fsfilt_extN_commit.) - Reuse reply_md.start instead of the likely-NULL rq_repmsg when resending reqs. - Requests without transnos should be ERESTARTed _never_, not _always_. --- lustre/conf/.cvsignore | 2 + lustre/extN/extN-wantedi.diff | 160 ++++++++++++++++++++++++++++++++++++++++++ lustre/tests/wantedi.c | 46 ++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 lustre/conf/.cvsignore create mode 100644 lustre/extN/extN-wantedi.diff create mode 100644 lustre/tests/wantedi.c diff --git a/lustre/conf/.cvsignore b/lustre/conf/.cvsignore new file mode 100644 index 0000000..282522d --- /dev/null +++ b/lustre/conf/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/lustre/extN/extN-wantedi.diff b/lustre/extN/extN-wantedi.diff new file mode 100644 index 0000000..2e98856 --- /dev/null +++ b/lustre/extN/extN-wantedi.diff @@ -0,0 +1,160 @@ +--- lustre/extN-clean/namei.c 2002-12-30 05:56:09.000000000 -0500 ++++ lustre/extN/namei.c 2002-12-30 06:29:39.000000000 -0500 +@@ -1224,7 +1224,7 @@ + if (IS_SYNC(dir)) + handle->h_sync = 1; + +- inode = extN_new_inode (handle, dir, mode); ++ inode = extN_new_inode (handle, dir, mode, (int)dentry->d_fsdata); + err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + inode->i_op = &extN_file_inode_operations; +@@ -1254,7 +1254,7 @@ + if (IS_SYNC(dir)) + handle->h_sync = 1; + +- inode = extN_new_inode (handle, dir, mode); ++ inode = extN_new_inode (handle, dir, mode, (int)dentry->d_fsdata); + err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + init_special_inode(inode, mode, rdev); +@@ -1286,7 +1286,8 @@ + if (IS_SYNC(dir)) + handle->h_sync = 1; + +- inode = extN_new_inode (handle, dir, S_IFDIR | mode); ++ inode = extN_new_inode (handle, dir, S_IFDIR | mode, ++ (int)dentry->d_fsdata); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_stop; +@@ -1680,7 +1681,8 @@ + if (IS_SYNC(dir)) + handle->h_sync = 1; + +- inode = extN_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); ++ inode = extN_new_inode (handle, dir, S_IFLNK|S_IRWXUGO, ++ (int)dentry->d_fsdata); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_stop; +--- lustre/extN-clean/ialloc.c 2002-12-28 23:56:42.000000000 -0500 ++++ lustre/extN/ialloc.c 2002-12-30 06:29:39.000000000 -0500 +@@ -330,7 +330,8 @@ + * group to find a free inode. + */ + struct inode * extN_new_inode (handle_t *handle, +- const struct inode * dir, int mode) ++ const struct inode * dir, int mode, ++ int wantedi) + { + struct super_block * sb; + struct buffer_head * bh; +@@ -360,6 +361,40 @@ + + lock_super (sb); + es = sbi->s_es; ++ ++ if (wantedi) { ++ i = (wantedi - 1) / EXTN_INODES_PER_GROUP(sb); ++ j = (wantedi - 1) % EXTN_INODES_PER_GROUP(sb); ++ gdp = extN_get_group_desc(sb, i, &bh2); ++ ++ bitmap_nr = load_inode_bitmap (sb, i); ++ if (bitmap_nr < 0) ++ goto fail; ++ ++ bh = sbi->s_inode_bitmap[bitmap_nr]; ++ ++ BUFFER_TRACE(bh, "get_write_access"); ++ err = extN_journal_get_write_access(handle, bh); ++ if (err) goto fail; ++ ++ if (extN_set_bit(j, bh->b_data)) { ++ printk(KERN_ERR "wantedi %d not available", ++ wantedi); ++ /* Oh well, we tried. */ ++ wantedi = 0; ++ goto repeat; ++ } ++ ++ BUFFER_TRACE(bh, "call extN_journal_dirty_metadata"); ++ err = extN_journal_dirty_metadata(handle, bh); ++ if (err) goto fail; ++ ++ /* We've shortcircuited the allocation system successfully, ++ * now finish filling in the inode. ++ */ ++ goto have_bit_and_group; ++ } ++ + repeat: + gdp = NULL; + i = 0; +@@ -474,6 +509,7 @@ + } + goto repeat; + } ++have_bit_and_group: + j += i * sbi->s_inodes_per_group + 1; + if (j < sbi->s_first_ino || j > le32_to_cpu(es->s_inodes_count)) { + extN_error (sb, "extN_new_inode", +--- lustre/extN-clean/ioctl.c 2002-12-28 23:56:42.000000000 -0500 ++++ lustre/extN/ioctl.c 2002-12-30 06:29:39.000000000 -0500 +@@ -24,7 +24,28 @@ + extN_debug ("cmd = %u, arg = %lu\n", cmd, arg); + + switch (cmd) { +- case EXTN_IOC_GETFLAGS: ++ case EXTN_IOC_CREATE_INUM: { ++ char name[32]; ++ struct dentry *dchild, *dparent; ++ struct inode *ichild; ++ int rc = 0; ++ ++ dparent = list_entry(inode->i_dentry.next, struct dentry, ++ d_alias); ++ snprintf(name, sizeof name, "%d", (int)arg); ++ dchild = lookup_one_len(name, dparent, strlen(name)); ++ dchild->d_fsdata = (void *)(int)arg; ++ rc = vfs_create(inode, dchild, 0644); ++ if (rc) { ++ printk(KERN_ERR "vfs_create: %d\n", rc); ++ } else if (dchild->d_inode->i_ino != (int)arg) { ++ rc = -EEXIST; ++ } ++ iput(ichild); ++ dput(dchild); ++ return rc; ++ } ++ case EXTN_IOC_GETFLAGS: + flags = ei->i_flags & EXTN_FL_USER_VISIBLE; + return put_user(flags, (int *) arg); + case EXTN_IOC_SETFLAGS: { +--- lustre/include/linux/extN_fs.h~ 2002-12-30 06:01:43.000000000 -0500 ++++ lustre/include/linux/extN_fs.h 2002-12-30 06:02:51.000000000 -0500 +@@ -200,6 +200,7 @@ + #define EXTN_IOC_SETFLAGS _IOW('f', 2, long) + #define EXTN_IOC_GETVERSION _IOR('f', 3, long) + #define EXTN_IOC_SETVERSION _IOW('f', 4, long) ++/* EXTN_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */ + #define EXTN_IOC_GETVERSION_OLD _IOR('v', 1, long) + #define EXTN_IOC_SETVERSION_OLD _IOW('v', 2, long) + #ifdef CONFIG_JBD_DEBUG +@@ -632,7 +633,8 @@ + extern int extN_sync_file (struct file *, struct dentry *, int); + + /* ialloc.c */ +-extern struct inode * extN_new_inode (handle_t *, const struct inode *, int); ++extern struct inode * extN_new_inode (handle_t *, const struct inode *, int, ++ int); + extern void extN_free_inode (handle_t *, struct inode *); + extern struct inode * extN_orphan_get (struct super_block *, ino_t); + extern unsigned long extN_count_free_inodes (struct super_block *); +@@ -714,4 +716,6 @@ + + #endif /* __KERNEL__ */ + ++#define EXTN_IOC_CREATE_INUM _IOW('f', 5, long) ++ + #endif /* _LINUX_EXTN_FS_H */ diff --git a/lustre/tests/wantedi.c b/lustre/tests/wantedi.c new file mode 100644 index 0000000..73b0cca --- /dev/null +++ b/lustre/tests/wantedi.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int usage(char *prog, FILE *out) +{ + fprintf(out, + "Usage: %s \n", prog); + exit(out == stderr); +} + +#define EXTN_IOC_CREATE_INUM _IOW('f', 5, long) + +int main(int argc, char ** argv) +{ + int dirfd, wantedi, rc; + + if (argc < 2 || argc > 3) + usage(argv[0], stderr); + + dirfd = open(argv[1], O_RDONLY); + if (dirfd < 0) { + perror("open"); + exit(1); + } + + wantedi = atoi(argv[2]); + printf("Creating %s/%d with ino %d\n", argv[1], wantedi, wantedi); + + rc = ioctl(dirfd, EXTN_IOC_CREATE_INUM, wantedi); + if (rc < 0) { + perror("ioctl(EXTN_IOC_CREATE_INUM)"); + exit(2); + } +} -- 1.8.3.1