Whamcloud - gitweb
- Add extN select-inum-for-allocation support, and use it to make recovery-time
authorshaver <shaver>
Mon, 30 Dec 2002 21:10:47 +0000 (21:10 +0000)
committershaver <shaver>
Mon, 30 Dec 2002 21:10:47 +0000 (21:10 +0000)
  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 [new file with mode: 0644]
lustre/extN/extN-wantedi.diff [new file with mode: 0644]
lustre/tests/wantedi.c [new file with mode: 0644]

diff --git a/lustre/conf/.cvsignore b/lustre/conf/.cvsignore
new file mode 100644 (file)
index 0000000..282522d
--- /dev/null
@@ -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 (file)
index 0000000..2e98856
--- /dev/null
@@ -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 (file)
index 0000000..73b0cca
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <time.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <linux/lustre_lib.h>
+#include <linux/obd.h>
+
+static int usage(char *prog, FILE *out)
+{
+        fprintf(out,
+               "Usage: %s <dir> <desired child ino>\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);
+       }
+}