Whamcloud - gitweb
landing smfs.
authoryury <yury>
Wed, 5 May 2004 11:40:01 +0000 (11:40 +0000)
committeryury <yury>
Wed, 5 May 2004 11:40:01 +0000 (11:40 +0000)
100 files changed:
lnet/include/linux/kp30.h
lnet/include/linux/libcfs.h
lnet/utils/debug.c
lustre/include/linux/Makefile.am
lustre/include/linux/lustre_fsfilt.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_lib.h
lustre/include/linux/lustre_log.h
lustre/include/linux/lustre_mds.h
lustre/include/linux/lustre_net.h
lustre/include/linux/lustre_smfs.h [new file with mode: 0644]
lustre/include/linux/lvfs.h
lustre/include/linux/lvfs_linux.h
lustre/include/linux/obd.h
lustre/include/linux/obd_class.h
lustre/kernel_patches/patches/linux-2.4.20-tmpfs-iopen.patch [deleted file]
lustre/kernel_patches/patches/linux-2.4.20-tmpfs-xattr.patch [deleted file]
lustre/kernel_patches/series/vanilla-2.4.20
lustre/ldlm/ldlm_lockd.c
lustre/lov/lov_log.c
lustre/lvfs/Makefile.in
lustre/lvfs/Makefile.mk
lustre/lvfs/autoMakefile.am
lustre/lvfs/fsfilt_ext3.c
lustre/lvfs/fsfilt_smfs.c [new file with mode: 0644]
lustre/lvfs/llog.c [moved from lustre/obdclass/llog.c with 65% similarity]
lustre/lvfs/llog_cat.c [moved from lustre/obdclass/llog_cat.c with 57% similarity]
lustre/lvfs/llog_lvfs.c [new file with mode: 0644]
lustre/lvfs/lvfs_common.c
lustre/lvfs/lvfs_internal.h
lustre/lvfs/lvfs_linux.c
lustre/lvfs/lvfs_reint.c [new file with mode: 0644]
lustre/lvfs/lvfs_undo.c [new file with mode: 0644]
lustre/lvfs/lvfs_userfs.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/mds/mds_fs.c
lustre/mds/mds_log.c
lustre/mds/mds_lov.c
lustre/mds/mds_open.c
lustre/mds/mds_reint.c
lustre/mds/mds_unlink_open.c
lustre/obdclass/Makefile.in
lustre/obdclass/Makefile.mk
lustre/obdclass/autoMakefile.am
lustre/obdclass/class_obd.c
lustre/obdclass/llog_internal.h [deleted file]
lustre/obdclass/llog_ioctl.c
lustre/obdclass/llog_lvfs.c [deleted file]
lustre/obdclass/llog_obd.c
lustre/obdclass/llog_test.c
lustre/obdclass/simple.c
lustre/obdfilter/filter.c
lustre/obdfilter/filter_io.c
lustre/obdfilter/filter_io_24.c
lustre/obdfilter/filter_io_26.c
lustre/obdfilter/filter_log.c
lustre/osc/osc_request.c
lustre/portals/include/linux/kp30.h
lustre/portals/include/linux/libcfs.h
lustre/portals/utils/debug.c
lustre/ptlrpc/llog_client.c
lustre/ptlrpc/llog_net.c
lustre/ptlrpc/llog_server.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpc_module.c
lustre/ptlrpc/recov_thread.c
lustre/smfs/Makefile.in
lustre/smfs/autoMakefile.am
lustre/smfs/cache.c
lustre/smfs/cache_space.c [new file with mode: 0644]
lustre/smfs/dir.c
lustre/smfs/file.c
lustre/smfs/inode.c
lustre/smfs/ioctl.c [new file with mode: 0644]
lustre/smfs/journal.c
lustre/smfs/journal_ext3.c [deleted file]
lustre/smfs/kml.c
lustre/smfs/kml_idl.h [deleted file]
lustre/smfs/options.c
lustre/smfs/reint.c [deleted file]
lustre/smfs/sm_fs.c
lustre/smfs/smfs_internal.h
lustre/smfs/smfs_llog.c
lustre/smfs/smfs_support.h [deleted file]
lustre/smfs/super.c
lustre/smfs/symlink.c
lustre/smfs/sysctl.c
lustre/snapfs/options.c
lustre/tests/cmknod.c
lustre/tests/llmount.sh
lustre/tests/local.sh
lustre/tests/lsmfs.sh [new file with mode: 0755]
lustre/tests/oos.sh
lustre/utils/lconf
lustre/utils/lctl.c
lustre/utils/lmc
lustre/utils/lustre_cfg.c
lustre/utils/obd.c
lustre/utils/wiretest.c

index 5a185d7..958889a 100644 (file)
@@ -694,11 +694,11 @@ typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
 # endif
 #endif
 
-#ifndef LP_POISON
+/*#ifndef LP_POISON
 # define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
 # define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
 # define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
-#endif
+#endif*/
 
 #if defined(__x86_64__)
 # define LPU64 "%Lu"
@@ -706,18 +706,33 @@ typedef int (*cfg_record_cb_t)(enum cfg_record_type, int len, void *data);
 # define LPX64 "%#Lx"
 # define LPSZ  "%lu"
 # define LPSSZ "%ld"
+#ifndef LP_POISON
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#endif
 #elif (BITS_PER_LONG == 32 || __WORDSIZE == 32)
 # define LPU64 "%Lu"
 # define LPD64 "%Ld"
 # define LPX64 "%#Lx"
 # define LPSZ  "%u"
 # define LPSSZ "%d"
+#ifndef LP_POISON
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a)
+#endif
 #elif (BITS_PER_LONG == 64 || __WORDSIZE == 64)
 # define LPU64 "%lu"
 # define LPD64 "%ld"
 # define LPX64 "%#lx"
 # define LPSZ  "%lu"
 # define LPSSZ "%ld"
+#ifndef LP_POISON
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LL_POISON ((long)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#endif
 #endif
 #ifndef LPU64
 # error "No word size defined"
index 5b1b8a5..1d27768 100644 (file)
@@ -79,6 +79,7 @@ extern unsigned int portal_cerror;
 #define S_PTLROUTER   0x00100000
 #define S_COBD        0x00200000
 #define S_IBNAL       0x00400000
+#define S_SM          0x00800000
 
 /* If you change these values, please keep portals/utils/debug.c
  * up to date! */
index ae2da55..b6bfec0 100644 (file)
@@ -538,6 +538,7 @@ static struct mod_paths {
         {"mds", "lustre/mds"},
         {"mdc", "lustre/mdc"},
         {"llite", "lustre/llite"},
+        {"smfs", "lustre/smfs"},
         {"obdecho", "lustre/obdecho"},
         {"ldlm", "lustre/ldlm"},
         {"obdfilter", "lustre/obdfilter"},
@@ -546,6 +547,7 @@ static struct mod_paths {
         {"fsfilt_ext3", "lustre/lvfs"},
         {"fsfilt_extN", "lustre/lvfs"},
         {"fsfilt_reiserfs", "lustre/lvfs"},
+        {"fsfilt_smfs", "lustre/lvfs"},
         {"mds_ext2", "lustre/mds"},
         {"mds_ext3", "lustre/mds"},
         {"mds_extN", "lustre/mds"},
index cb75fe5..b170c5c 100644 (file)
@@ -8,4 +8,4 @@ EXTRA_DIST = lprocfs_status.h lustre_debug.h lustre_ha.h lustre_lib.h \
   lustre_net.h obd_class.h obd_ost.h obd_support.h lustre_commit_confd.h \
   lustre_export.h lustre_log.h obd_echo.h obd_ptlbd.h obd_trace.h \
   lustre_compat25.h lustre_fsfilt.h lustre_import.h lustre_mds.h obd.h \
-  lvfs.h lvfs_linux.h lustre_cfg.h lustre_lite.h  lustre_idl.h
+  lvfs.h lvfs_linux.h lustre_cfg.h lustre_lite.h  lustre_idl.h lustre_smfs.h 
index 72f3817..ae8b544 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- *  Copyright (C) 2001 Cluster File Systems, Inc. <info@clusterfs.com>
+ *  Copyright (C) 2001-2004 Cluster File Systems, Inc. <info@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -28,6 +28,7 @@
 #ifdef __KERNEL__
 
 #include <linux/obd.h>
+#include <linux/lustre_log.h>
 #include <linux/obd_class.h>
 
 typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd,
@@ -58,10 +59,23 @@ struct fsfilt_operations {
         int     (* fs_set_md)(struct inode *inode, void *handle, void *md,
                               int size);
         int     (* fs_get_md)(struct inode *inode, void *md, int size);
+
+        /* this method is needed to make IO operation fsfilt nature depend. */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+        int     (* fs_send_bio)(struct inode *inode, struct bio *bio);
+#else
+        int     (* fs_send_bio)(struct inode *inode, struct kiobuf *bio);
+#endif
+
+        /* methods for getting page from backing fs and putting page there
+         * during IO. Used on OST. */
+        int (* fs_putpage)(struct inode *inode, struct page *page);
+        struct page *(* fs_getpage)(struct inode *inode, long int index);
+
         ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count,
                                 loff_t *offset);
-        int     (* fs_add_journal_cb)(struct obd_device *obd, __u64 last_rcvd,
-                                      void *handle, fsfilt_cb_t cb_func,
+        int     (* fs_add_journal_cb)(struct obd_device *obd, struct super_block *sb,
+                                      __u64 last_rcvd, void *handle, fsfilt_cb_t cb_func,
                                       void *cb_data);
         int     (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs);
         int     (* fs_sync)(struct super_block *sb);
@@ -74,6 +88,12 @@ struct fsfilt_operations {
                                     int force_sync);
         int     (* fs_read_record)(struct file *, void *, int size, loff_t *);
         int     (* fs_setup)(struct super_block *sb);
+
+        int     (* fs_set_xattr)(struct inode *inode, void *handle, char *name,
+                                 void *buffer, int buffer_size); 
+        int     (* fs_get_xattr)(struct inode *inode, char *name,
+                                 void *buffer, int buffer_size); 
+
         int     (* fs_get_op_len)(int, struct fsfilt_objinfo *, int);
 };
 
@@ -92,15 +112,46 @@ extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops);
 #define FSFILT_OP_SETATTR        8
 #define FSFILT_OP_LINK           9
 #define FSFILT_OP_CANCEL_UNLINK 10
-
-static inline void *fsfilt_start_log(struct obd_device *obd,
-                                     struct inode *inode, int op,
-                                     struct obd_trans_info *oti, int logs)
+#define FSFILT_OP_NOOP          15
+
+/* XXX BUG 3188 -- must return to one set of opcodes */
+#define KML_UNLINK              0x11
+#define KML_RMDIR               0x12
+#define KML_RENAME              0x13
+#define KML_CREATE              0x14
+#define KML_MKDIR               0x15
+#define KML_SYMLINK             0x16
+#define KML_MKNOD               0x17
+#define KML_LINK                0x19
+
+#define CACHE_UNLINK            0x21
+#define CACHE_RMDIR             0x22
+#define CACHE_RENAME            0x23
+#define CACHE_CREATE            0x24
+#define CACHE_MKDIR             0x25
+#define CACHE_SYMLINK           0x26
+#define CACHE_MKNOD             0x27
+#define CACHE_LINK              0x29
+#define CACHE_NOOP              0x2f
+
+#define KML_CACHE_UNLINK        0x31
+#define KML_CACHE_RMDIR         0x32
+#define KML_CACHE_RENAME        0x33
+#define KML_CACHE_CREATE        0x34
+#define KML_CACHE_MKDIR         0x35
+#define KML_CACHE_SYMLINK       0x36
+#define KML_CACHE_MKNOD         0x37
+#define KML_CACHE_LINK          0x39
+#define KML_CACHE_NOOP          0x3f
+
+static inline void *
+fsfilt_start_ops(struct fsfilt_operations *ops, struct inode *inode,
+                 int op, struct obd_trans_info *oti, int logs)
 {
         unsigned long now = jiffies;
         void *parent_handle = oti ? oti->oti_handle : NULL;
-        void *handle = obd->obd_fsops->fs_start(inode, op, parent_handle, logs);
-        CDEBUG(D_INFO, "started handle %p (%p)\n", handle, parent_handle);
+        void *handle = ops->fs_start(inode, op, parent_handle, logs);
+        CDEBUG(D_HA, "started handle %p (%p)\n", handle, parent_handle);
 
         if (oti != NULL) {
                 if (parent_handle == NULL) {
@@ -116,17 +167,60 @@ static inline void *fsfilt_start_log(struct obd_device *obd,
         return handle;
 }
 
-static inline void *fsfilt_start(struct obd_device *obd, struct inode *inode,
-                                 int op, struct obd_trans_info *oti)
+static inline void *
+fsfilt_start_log(struct obd_device *obd, struct inode *inode,
+                 int op, struct obd_trans_info *oti, int logs)
+{
+        return fsfilt_start_ops(obd->obd_fsops, inode, op, oti, logs);
+}
+
+static inline void *
+fsfilt_start(struct obd_device *obd, struct inode *inode,
+             int op, struct obd_trans_info *oti)
+{
+        return fsfilt_start_ops(obd->obd_fsops, inode, op, oti, 0);
+}
+
+static inline void *
+llog_fsfilt_start(struct llog_ctxt *ctxt, struct inode *inode,
+                  int op, struct obd_trans_info *oti)
+{
+        return fsfilt_start_ops(ctxt->loc_fsops, inode, op, oti, 1);
+}
+
+static inline int
+fsfilt_commit_ops(struct fsfilt_operations *ops, struct inode *inode,
+                  void *handle, int force_sync)
+{
+        unsigned long now = jiffies;
+        int rc = ops->fs_commit(inode, handle, force_sync);
+        CDEBUG(D_HA, "committing handle %p\n", handle);
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+
+        return rc;
+}
+
+static inline int
+fsfilt_commit(struct obd_device *obd, struct inode *inode,
+              void *handle, int force_sync)
+{
+        return fsfilt_commit_ops(obd->obd_fsops, inode, handle, force_sync);
+}
+
+static inline int 
+llog_fsfilt_commit(struct llog_ctxt *ctxt, struct inode *inode,
+                   void *handle, int force_sync)
 {
-        return fsfilt_start_log(obd, inode, op, oti, 0);
+        return fsfilt_commit_ops(ctxt->loc_fsops, inode, handle, force_sync);
 }
 
-static inline void *fsfilt_brw_start_log(struct obd_device *obd,
-                                         int objcount,
-                                         struct fsfilt_objinfo *fso,
-                                         int niocount, struct niobuf_local *nb,
-                                         struct obd_trans_info *oti, int logs)
+static inline void *
+fsfilt_brw_start_log(struct obd_device *obd, int objcount,
+                     struct fsfilt_objinfo *fso, int niocount,
+                     struct niobuf_local *nb, struct obd_trans_info *oti,
+                     int logs)
 {
         unsigned long now = jiffies;
         void *parent_handle = oti ? oti->oti_handle : NULL;
@@ -149,30 +243,17 @@ static inline void *fsfilt_brw_start_log(struct obd_device *obd,
         return handle;
 }
 
-static inline void *fsfilt_brw_start(struct obd_device *obd, int objcount,
-                                     struct fsfilt_objinfo *fso, int niocount,
-                                     struct niobuf_local *nb,
-                                     struct obd_trans_info *oti)
+static inline void *
+fsfilt_brw_start(struct obd_device *obd, int objcount,
+                 struct fsfilt_objinfo *fso, int niocount,
+                 struct niobuf_local *nb, struct obd_trans_info *oti)
 {
         return fsfilt_brw_start_log(obd, objcount, fso, niocount, nb, oti, 0);
 }
 
-static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode,
-                                void *handle, int force_sync)
-{
-        unsigned long now = jiffies;
-        int rc = obd->obd_fsops->fs_commit(inode, handle, force_sync);
-        CDEBUG(D_INFO, "committing handle %p\n", handle);
-
-        if (time_after(jiffies, now + 15 * HZ))
-                CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
-
-        return rc;
-}
-
-static inline int fsfilt_commit_async(struct obd_device *obd,
-                                      struct inode *inode, void *handle,
-                                      void **wait_handle)
+static inline int
+fsfilt_commit_async(struct obd_device *obd, struct inode *inode,
+                    void *handle, void **wait_handle)
 {
         unsigned long now = jiffies;
         int rc = obd->obd_fsops->fs_commit_async(inode, handle, wait_handle);
@@ -184,8 +265,8 @@ static inline int fsfilt_commit_async(struct obd_device *obd,
         return rc;
 }
 
-static inline int fsfilt_commit_wait(struct obd_device *obd,
-                                     struct inode *inode, void *handle)
+static inline int
+fsfilt_commit_wait(struct obd_device *obd, struct inode *inode, void *handle)
 {
         unsigned long now = jiffies;
         int rc = obd->obd_fsops->fs_commit_wait(inode, handle);
@@ -195,8 +276,9 @@ static inline int fsfilt_commit_wait(struct obd_device *obd,
         return rc;
 }
 
-static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry,
-                                 void *handle, struct iattr *iattr,int do_trunc)
+static inline int
+fsfilt_setattr(struct obd_device *obd, struct dentry *dentry,
+               void *handle, struct iattr *iattr, int do_trunc)
 {
         unsigned long now = jiffies;
         int rc;
@@ -206,43 +288,120 @@ static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry,
         return rc;
 }
 
-static inline int fsfilt_iocontrol(struct obd_device *obd, struct inode *inode,
-                                   struct file *file, unsigned int cmd,
-                                   unsigned long arg)
+static inline int
+fsfilt_iocontrol(struct obd_device *obd, struct inode *inode,
+                 struct file *file, unsigned int cmd,
+                 unsigned long arg)
 {
         return obd->obd_fsops->fs_iocontrol(inode, file, cmd, arg);
 }
 
-static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode,
-                                void *handle, void *md, int size)
+static inline int fsfilt_setup(struct obd_device *obd,
+                               struct super_block *fs)
+{
+        if (obd->obd_fsops->fs_setup)
+                return obd->obd_fsops->fs_setup(fs);
+        
+        return 0;
+}
+
+static inline int
+fsfilt_set_md(struct obd_device *obd, struct inode *inode,
+              void *handle, void *md, int size)
 {
         return obd->obd_fsops->fs_set_md(inode, handle, md, size);
 }
 
-static inline int fsfilt_get_md(struct obd_device *obd, struct inode *inode,
-                                void *md, int size)
+static inline int
+fsfilt_get_md(struct obd_device *obd, struct inode *inode,
+              void *md, int size)
 {
         return obd->obd_fsops->fs_get_md(inode, md, size);
 }
 
-static inline ssize_t fsfilt_readpage(struct obd_device *obd,
-                                      struct file *file, char *buf,
-                                      size_t count, loff_t *offset)
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+static inline int
+fsfilt_send_bio(struct obd_device *obd, struct inode *inode,
+                struct bio *bio)
+#else
+static inline int
+fsfilt_send_bio(struct obd_device *obd, struct inode *inode,
+                struct kiobuf *bio)
+#endif
+{
+        return obd->obd_fsops->fs_send_bio(inode, bio);
+}
+
+static inline int
+fsfilt_putpage(struct obd_device *obd, struct inode *inode,
+               struct page *page)
+{
+        int rc = 0;
+        struct filter_obd *filter;
+        unsigned long now = jiffies;
+
+        LASSERT(obd != NULL);
+        LASSERT(inode != NULL);
+        LASSERT(page != NULL);
+
+        filter = &obd->u.filter;
+        
+        if (!obd->obd_fsops->fs_putpage)
+                return -ENOSYS;
+
+        CDEBUG(D_INFO, "putpage %lx\n", page->index);
+        
+        rc = obd->obd_fsops->fs_putpage(inode, page);
+
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("long putpage time %lus\n", (jiffies - now) / HZ);
+
+        return rc;
+}
+
+static inline struct page *
+fsfilt_getpage(struct obd_device *obd, struct inode *inode,
+               unsigned long index)
+{
+        struct page *page;
+        unsigned long now = jiffies;
+
+        LASSERT(obd != NULL);
+        LASSERT(inode != NULL);
+
+        if (!obd->obd_fsops->fs_getpage)
+                return ERR_PTR(-ENOSYS);
+
+        CDEBUG(D_INFO, "getpage %lx\n", index);
+        
+        page = obd->obd_fsops->fs_getpage(inode, index);
+        
+        if (time_after(jiffies, now + 15 * HZ))
+                CERROR("long getpage time %lus\n", (jiffies - now) / HZ);
+
+        return page;
+}
+
+static inline ssize_t
+fsfilt_readpage(struct obd_device *obd, struct file *file, char *buf,
+                size_t count, loff_t *offset)
 {
         return obd->obd_fsops->fs_readpage(file, buf, count, offset);
 }
 
-static inline int fsfilt_add_journal_cb(struct obd_device *obd, __u64 last_rcvd,
-                                        void *handle, fsfilt_cb_t cb_func,
-                                        void *cb_data)
+static inline int
+fsfilt_add_journal_cb(struct obd_device *obd, struct super_block *sb,
+                      __u64 last_rcvd, void *handle, fsfilt_cb_t cb_func,
+                      void *cb_data)
 {
-        return obd->obd_fsops->fs_add_journal_cb(obd, last_rcvd,
-                                                 handle, cb_func, cb_data);
+        return obd->obd_fsops->fs_add_journal_cb(obd, sb, last_rcvd, handle,
+                                                 cb_func, cb_data);
 }
 
 /* very similar to obd_statfs(), but caller already holds obd_osfs_lock */
-static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *sb,
-                                unsigned long max_age)
+static inline int
+fsfilt_statfs(struct obd_device *obd, struct super_block *sb,
+              unsigned long max_age)
 {
         int rc = 0;
 
@@ -258,48 +417,58 @@ static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *sb,
         return rc;
 }
 
-static inline int fsfilt_sync(struct obd_device *obd, struct super_block *sb)
+static inline int
+fsfilt_sync(struct obd_device *obd, struct super_block *sb)
 {
         return obd->obd_fsops->fs_sync(sb);
 }
 
-static inline int fsfilt_map_inode_page(struct obd_device *obd,
-                                        struct inode *inode, struct page *page,
-                                        unsigned long *blocks, int *created,
-                                        int create)
+static inline int
+fsfilt_map_inode_page(struct obd_device *obd, struct inode *inode,
+                      struct page *page, unsigned long *blocks,
+                      int *created, int create)
 {
-        return obd->obd_fsops->fs_map_inode_page(inode, page, blocks, created,
-                                                 create);
+        return obd->obd_fsops->fs_map_inode_page(inode, page, blocks,
+                                                 created, create);
 }
 
-static inline int fs_prep_san_write(struct obd_device *obd,
-                                    struct inode *inode,
-                                    long *blocks,
-                                    int nblocks,
-                                    loff_t newsize)
+static inline int
+fs_prep_san_write(struct obd_device *obd, struct inode *inode,
+                  long *blocks, int nblocks, loff_t newsize)
 {
         return obd->obd_fsops->fs_prep_san_write(inode, blocks,
                                                  nblocks, newsize);
 }
 
-static inline int fsfilt_read_record(struct obd_device *obd, struct file *file,
-                                     void *buf, loff_t size, loff_t *offs)
+static inline int
+fsfilt_read_record(struct obd_device *obd, struct file *file,
+                   void *buf, loff_t size, loff_t *offs)
 {
         return obd->obd_fsops->fs_read_record(file, buf, size, offs);
 }
 
-static inline int fsfilt_write_record(struct obd_device *obd, struct file *file,
-                                      void *buf, loff_t size, loff_t *offs,
-                                      int force_sync)
+static inline int
+fsfilt_write_record(struct obd_device *obd, struct file *file,
+                    void *buf, loff_t size, loff_t *offs, int force_sync)
 {
-        return obd->obd_fsops->fs_write_record(file, buf, size,offs,force_sync);
+        return obd->obd_fsops->fs_write_record(file, buf, size, offs, 
+                                               force_sync);
 }
 
-static inline int fsfilt_setup(struct obd_device *obd, struct super_block *fs)
+static inline int
+llog_fsfilt_write_record(struct llog_ctxt *ctxt, struct file *file,
+                         void *buf, loff_t size, loff_t *offs,
+                         int force_sync)
 {
-        if (obd->obd_fsops->fs_setup)
-                return obd->obd_fsops->fs_setup(fs);
-        return 0;
+        return ctxt->loc_fsops->fs_write_record(file, buf, size, offs,
+                                                force_sync);
+}
+
+static inline int
+llog_fsfilt_read_record(struct llog_ctxt *ctxt, struct file *file,
+                        void *buf, loff_t size, loff_t *offs)
+{
+        return ctxt->loc_fsops->fs_read_record(file, buf, size, offs);
 }
 
 #endif /* __KERNEL__ */
index ef2ad2d..7479634 100644 (file)
@@ -54,7 +54,7 @@
 # include <linux/types.h>
 # include <linux/list.h>
 # include <linux/string.h> /* for strncpy, below */
-# include <linux/fs.h> /* to check for FMODE_EXEC, lest we redefine */
+# include <linux/fs.h>     /* to check for FMODE_EXEC, dev_t, lest we redefine */
 #else
 #ifdef __CYGWIN__
 # include <sys/types.h>
@@ -487,19 +487,22 @@ typedef enum {
         MDS_DONE_WRITING = 45,
         MDS_LAST_OPC
 } mds_cmd_t;
+
 #define MDS_FIRST_OPC    MDS_GETATTR
 
 /*
  * Do not exceed 63
  */
 
-#define REINT_SETATTR  1
-#define REINT_CREATE   2
-#define REINT_LINK     3
-#define REINT_UNLINK   4
-#define REINT_RENAME   5
-#define REINT_OPEN     6
-#define REINT_MAX      6
+#define REINT_SETATTR    1
+#define REINT_CREATE     2
+#define REINT_LINK       3
+#define REINT_UNLINK     4
+#define REINT_RENAME     5
+#define REINT_OPEN       6
+#define REINT_CLOSE      7
+#define REINT_WRITE      8
+#define REINT_MAX        8
 
 /* the disposition of the intent outlines what was executed */
 #define DISP_IT_EXECD   1
@@ -571,12 +574,6 @@ struct mds_body {
 extern void lustre_swab_mds_body (struct mds_body *b);
 
 
-/* MDS update records */
-
-//struct mds_update_record_hdr {
-//        __u32 ur_opcode;
-//};
-
 struct mds_rec_setattr {
         __u32           sa_opcode;
         __u32           sa_fsuid;
@@ -898,6 +895,8 @@ typedef enum {
         LLOG_GEN_REC     = 0x10640000,
         LLOG_HDR_MAGIC   = 0x10645539,
         LLOG_LOGID_MAGIC = 0x1064553b,
+        SMFS_UPDATE_REC  = 0x10650000,
+        CACHE_LRU_REC    = 0x10660000,
 } llog_op_type;
 
 /* Log record header - stored in little endian order.
@@ -959,13 +958,48 @@ struct llog_size_change_rec {
 struct llog_gen {
         __u64 mnt_cnt;
         __u64 conn_cnt;
-} __attribute__((packed));
+};
 
 struct llog_gen_rec {
         struct llog_rec_hdr     lgr_hdr;
         struct llog_gen         lgr_gen;
         struct llog_rec_tail    lgr_tail;
+} __attribute__((packed));
+
+struct llog_lru_rec {
+        struct llog_rec_hdr     llr_hdr;
+        struct ll_fid           llr_cfid;
+        struct ll_fid           llr_pfid;
+        struct llog_rec_tail    llr_tail;
+} __attribute__((packed));
+
+/* got from mds_update_record. FIXME: maybe some attribute in reint_record and
+   update_record will be changed later. */
+/* XXX BUG 3188 -- must return to one set of structures. */
+
+struct update_record {
+        __u32 ur_opcode;
+        __u32 ur_fsuid;
+        __u32 ur_fsgid;
+        dev_t ur_rdev;
+        struct iattr ur_iattr;
+        struct iattr ur_pattr; 
+        __u32 ur_flags;
+        __u32 ur_len;
 };
+struct reint_record {
+       struct update_record u_rec;
+       char *rec_data1;
+       int rec1_size;
+       char *rec_data2;
+       int rec2_size;
+};
+struct llog_smfs_rec {
+        struct llog_rec_hdr     lsr_hdr;
+        struct update_record    lsr_rec;
+        struct llog_rec_tail    lsr_tail;
+};
+
 /* On-disk header structure of each log object, stored in little endian order */
 #define LLOG_CHUNK_SIZE         8192
 #define LLOG_HEADER_SIZE        (96)
@@ -986,7 +1020,7 @@ struct llog_log_hdr {
         __u32                   llh_size;
         __u32                   llh_flags;
         __u32                   llh_cat_idx;
-        /* for a catlog the first plain slot is next to it */
+        /* for a catalog the first plain slot is next to it */
         struct obd_uuid         llh_tgtuuid;
         __u32                   llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32) - 23];
         __u32                   llh_bitmap[LLOG_BITMAP_BYTES/sizeof(__u32)];
@@ -1010,6 +1044,7 @@ enum llogd_rpc_ops {
         LLOG_ORIGIN_HANDLE_CLOSE        = 505,
         LLOG_ORIGIN_CONNECT             = 506,
         LLOG_CATINFO                    = 507,  /* for lfs catinfo */
+        LLOG_ORIGIN_HANDLE_PREV_BLOCK   = 508,
 };
 
 struct llogd_body {
index 0bb5f0b..b4a59d3 100644 (file)
 #include <linux/lustre_idl.h>
 #include <linux/lustre_cfg.h>
 
-#define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
-#define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#if BITS_PER_LONG > 32 && !defined(__x86_64__)
+#ifndef LP_POISON
+# define LI_POISON ((int)0x5a5a5a5a5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a5a5a5a5a)
+#endif
+#else
+#ifndef LP_POISON
+# define LI_POISON ((int)0x5a5a5a5a)
+# define LP_POISON ((void *)(long)0x5a5a5a5a)
+#endif
+#endif
 
 #ifndef LPU64
 /* x86_64 has 64bit longs and defines u64 as long long */
index 1d0ff9f..36ec2d6 100644 (file)
@@ -40,6 +40,7 @@
 
 #define LOG_NAME_LIMIT(logname, name)                   \
         snprintf(logname, sizeof(logname), "LOGS/%s", name)
+#define LLOG_EEMPTY 4711
 
 struct plain_handle_data {
         struct list_head    phd_entry;
@@ -67,18 +68,18 @@ struct llog_handle {
         } u;
 };
 
-#define LLOG_EEMPTY 4711
-
 /* llog.c  -  general API */
 typedef int (*llog_cb_t)(struct llog_handle *, struct llog_rec_hdr *, void *);
+struct llog_handle *llog_alloc_handle(void);
+void llog_free_handle(struct llog_handle *handle);
+int llog_cancel_rec(struct llog_handle *loghandle, int index);
 int llog_init_handle(struct llog_handle *handle, int flags,
                      struct obd_uuid *uuid);
+int llog_close(struct llog_handle *cathandle);
 int llog_process(struct llog_handle *loghandle, llog_cb_t cb,
                  void *data, void *catdata);
-extern struct llog_handle *llog_alloc_handle(void);
-extern void llog_free_handle(struct llog_handle *handle);
-extern int llog_close(struct llog_handle *cathandle);
-extern int llog_cancel_rec(struct llog_handle *loghandle, int index);
+int llog_reverse_process(struct llog_handle *loghandle, llog_cb_t cb,
+                         void *data, void *catdata);
 
 /* llog_cat.c   -  catalog api */
 struct llog_process_data {
@@ -89,37 +90,45 @@ struct llog_process_data {
 struct llog_process_cat_data {
         int     first_idx;
         int     last_idx;
-        /* to process catlog across zero record */
+        /* to process catalog across zero record */
 };
 
+int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res,
+                       struct llog_logid *logid);
 int llog_cat_put(struct llog_handle *cathandle);
 int llog_cat_add_rec(struct llog_handle *cathandle, struct llog_rec_hdr *rec,
                      struct llog_cookie *reccookie, void *buf);
 int llog_cat_cancel_records(struct llog_handle *cathandle, int count,
                             struct llog_cookie *cookies);
 int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data);
+int llog_cat_reverse_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data);
 int llog_cat_set_first_idx(struct llog_handle *cathandle, int index);
 
-/* llog_obd.c */
-int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
-               int count,  struct llog_logid *logid,struct llog_operations *op);
-int llog_cleanup(struct llog_ctxt *);
-int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp);
-int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
-             struct lov_stripe_md *lsm, struct llog_cookie *logcookies,
-             int numcookies);
-int llog_cancel(struct llog_ctxt *, struct lov_stripe_md *lsm,
-                int count, struct llog_cookie *cookies, int flags);
+int llog_catalog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
+                     void *buf, struct llog_cookie *reccookie, int, void *data);
+int llog_catalog_cancel(struct llog_ctxt *ctxt, int count, struct llog_cookie *,
+                        int flags, void *data);
+int llog_catalog_setup(struct llog_ctxt **res, char *name, struct lvfs_run_ctxt *,
+                       struct fsfilt_operations *fsops, struct dentry *logs_de,
+                       struct dentry *objects_de);
+int llog_catalog_cleanup(struct llog_ctxt *ctxt);
+int llog_cat_half_bottom(struct llog_cookie *, struct llog_handle *);
+
+/* llog_lvfs.c */
+int llog_get_cat_list(struct lvfs_run_ctxt *, struct fsfilt_operations *,
+                      char *name, int count, struct llog_catid *idarray);
+int llog_put_cat_list(struct lvfs_run_ctxt *, struct fsfilt_operations *, 
+                      char *name, int count, struct llog_catid *idarray);
+extern struct llog_operations llog_lvfs_ops;
 
+/* llog_obd.c - obd llog api */
+int obd_llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd,
+                   int count,  struct llog_logid *logid,struct llog_operations *op);
+int obd_llog_cleanup(struct llog_ctxt *);
 int llog_obd_origin_setup(struct obd_device *obd, int index,
                           struct obd_device *disk_obd, int count,
                           struct llog_logid *logid);
-int llog_obd_origin_cleanup(struct llog_ctxt *ctxt);
-int llog_obd_origin_add(struct llog_ctxt *ctxt,
-                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
-                        struct llog_cookie *logcookies, int numcookies);
-
-int llog_cat_initialize(struct obd_device *obd, int count);
+int obd_llog_cat_initialize(struct obd_device *obd, int count, char *name);
 int obd_llog_init(struct obd_device *obd, struct obd_device *disk_obd,
                   int count, struct llog_catid *logid);
 
@@ -127,7 +136,7 @@ int obd_llog_finish(struct obd_device *obd, int count);
 
 /* llog_ioctl.c */
 int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data);
-int llog_catlog_list(struct obd_device *obd, int count,
+int llog_catalog_list(struct obd_device *obd, int count,
                      struct obd_ioctl_data *data);
 
 /* llog_net.c */
@@ -139,60 +148,65 @@ int llog_origin_connect(struct llog_ctxt *ctxt, int count,
 int llog_handle_connect(struct ptlrpc_request *req);
 
 /* recov_thread.c */
-int llog_obd_repl_cancel(struct llog_ctxt *ctxt,
-                         struct lov_stripe_md *lsm, int count,
-                         struct llog_cookie *cookies, int flags);
+int llog_obd_repl_cancel(struct llog_ctxt *ctxt, int count,
+                         struct llog_cookie *cookies, int flags, void *data);
+                         
 int llog_obd_repl_sync(struct llog_ctxt *ctxt, struct obd_export *exp);
 int llog_repl_connect(struct llog_ctxt *ctxt, int count,
                       struct llog_logid *logid, struct llog_gen *gen,
                       struct obd_uuid *uuid);
 
 struct llog_operations {
+        int (*lop_setup)(struct obd_device *obd, int ctxt_idx,
+                         struct obd_device *disk_obd, int count,
+                         struct llog_logid *logid);
+        int (*lop_cleanup)(struct llog_ctxt *ctxt);
+        int (*lop_create)(struct llog_ctxt *ctxt, struct llog_handle **,
+                          struct llog_logid *logid, char *name);
+        int (*lop_destroy)(struct llog_handle *handle);
+        int (*lop_close)(struct llog_handle *handle);
+
+        int (*lop_read_header)(struct llog_handle *handle);
+        int (*lop_add)(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
+                       void *buf, struct llog_cookie *logcookies,
+                       int numcookies, void *data);
+        int (*lop_cancel)(struct llog_ctxt *ctxt, int count,
+                          struct llog_cookie *cookies, int flags, void *data);
         int (*lop_write_rec)(struct llog_handle *loghandle,
                              struct llog_rec_hdr *rec,
                              struct llog_cookie *logcookies, int numcookies,
                              void *, int idx);
-        int (*lop_destroy)(struct llog_handle *handle);
         int (*lop_next_block)(struct llog_handle *h, int *curr_idx,
                               int next_idx, __u64 *offset, void *buf, int len);
-        int (*lop_create)(struct llog_ctxt *ctxt, struct llog_handle **,
-                          struct llog_logid *logid, char *name);
-        int (*lop_close)(struct llog_handle *handle);
-        int (*lop_read_header)(struct llog_handle *handle);
+        int (*lop_prev_block)(struct llog_handle *h,
+                              int prev_idx, void *buf, int len);
 
-        int (*lop_setup)(struct obd_device *obd, int ctxt_idx,
-                         struct obd_device *disk_obd, int count,
-                         struct llog_logid *logid);
+        /* XXX add 2 more: commit callbacks and llog recovery functions */
         int (*lop_sync)(struct llog_ctxt *ctxt, struct obd_export *exp);
-        int (*lop_cleanup)(struct llog_ctxt *ctxt);
-        int (*lop_add)(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
-                       struct lov_stripe_md *lsm,
-                       struct llog_cookie *logcookies, int numcookies);
-        int (*lop_cancel)(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
-                          int count, struct llog_cookie *cookies, int flags);
         int (*lop_connect)(struct llog_ctxt *ctxt, int count,
                            struct llog_logid *logid, struct llog_gen *gen,
                            struct obd_uuid *uuid);
-        /* XXX add 2 more: commit callbacks and llog recovery functions */
 };
 
-/* llog_lvfs.c */
-extern struct llog_operations llog_lvfs_ops;
-int llog_get_cat_list(struct obd_device *obd, struct obd_device *disk_obd,
-                      char *name, int count, struct llog_catid *idarray);
-
 struct llog_ctxt {
-        int                      loc_idx; /* my index the obd array of ctxt's */
-        struct llog_gen          loc_gen;
+        /* needed for lvfs based log */
+        struct llog_handle      *loc_handle;
+        struct llog_operations  *loc_logops;
+        struct fsfilt_operations *loc_fsops;
+        struct dentry           *loc_logs_dir;
+        struct dentry           *loc_objects_dir;
+        struct lvfs_run_ctxt    *loc_lvfs_ctxt;
+
         struct obd_device       *loc_obd; /* points back to the containing obd*/
+        struct llog_gen          loc_gen;
+        int                      loc_idx; /* my index the obd array of ctxt's */
+
         struct obd_export       *loc_exp;
         struct obd_import       *loc_imp; /* to use in RPC's: can be backward
                                              pointing import */
-        struct llog_operations  *loc_logops;
-        struct llog_handle      *loc_handle;
         struct llog_canceld_ctxt *loc_llcd;
         struct semaphore         loc_sem; /* protects loc_llcd */
-        void                    *llog_proc_cb;
+        void                    *loc_proc_cb; /* cb for recovery */
 };
 
 static inline void llog_gen_init(struct llog_ctxt *ctxt)
@@ -219,10 +233,10 @@ static inline int llog_gen_lt(struct llog_gen a, struct llog_gen b)
 #define LLOG_GEN_INC(gen)  ((gen).conn_cnt) ++
 #define LLOG_PROC_BREAK 0x0001
 
-static inline int llog_obd2ops(struct llog_ctxt *ctxt,
+static inline int llog_ctxt2ops(struct llog_ctxt *ctxt,
                                struct llog_operations **lop)
 {
-       if (ctxt == NULL)
+        if (ctxt == NULL)
                 return -ENOTCONN;
 
         *lop = ctxt->loc_logops;
@@ -238,7 +252,7 @@ static inline int llog_handle2ops(struct llog_handle *loghandle,
         if (loghandle == NULL)
                 return -EINVAL;
 
-        return llog_obd2ops(loghandle->lgh_ctxt, lop);
+        return llog_ctxt2ops(loghandle->lgh_ctxt, lop);
 }
 
 static inline int llog_data_len(int len)
@@ -255,29 +269,36 @@ static inline struct llog_ctxt *llog_get_context(struct obd_device *obd,
         return obd->obd_llog_ctxt[index];
 }
 
-static inline int llog_write_rec(struct llog_handle *handle,
-                                 struct llog_rec_hdr *rec,
-                                 struct llog_cookie *logcookies,
-                                 int numcookies, void *buf, int idx)
+static inline int llog_create(struct llog_ctxt *ctxt, struct llog_handle **res,
+                              struct llog_logid *logid, char *name)
 {
         struct llog_operations *lop;
-        int rc, buflen;
+        int rc;
         ENTRY;
 
-        rc = llog_handle2ops(handle, &lop);
+        rc = llog_ctxt2ops(ctxt, &lop);
         if (rc)
                 RETURN(rc);
-        if (lop->lop_write_rec == NULL)
+        if (lop->lop_create == NULL)
                 RETURN(-EOPNOTSUPP);
 
-        if (buf)
-                buflen = rec->lrh_len + sizeof(struct llog_rec_hdr)
-                                + sizeof(struct llog_rec_tail);
-        else
-                buflen = rec->lrh_len;
-        LASSERT(size_round(buflen) == buflen);
+        rc = lop->lop_create(ctxt, res, logid, name);
+        RETURN(rc);
+}
 
-        rc = lop->lop_write_rec(handle, rec, logcookies, numcookies, buf, idx);
+static inline int llog_destroy(struct llog_handle *handle)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_handle2ops(handle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_destroy == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_destroy(handle);
         RETURN(rc);
 }
 
@@ -297,44 +318,69 @@ static inline int llog_read_header(struct llog_handle *handle)
         RETURN(rc);
 }
 
-static inline int llog_destroy(struct llog_handle *handle)
+static inline int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
+                           void *buf, struct llog_cookie *logcookies,
+                           int numcookies, void *data)
 {
         struct llog_operations *lop;
         int rc;
         ENTRY;
 
-        rc = llog_handle2ops(handle, &lop);
+        rc = llog_ctxt2ops(ctxt, &lop);
         if (rc)
                 RETURN(rc);
-        if (lop->lop_destroy == NULL)
+        if (lop->lop_add == NULL)
                 RETURN(-EOPNOTSUPP);
 
-        rc = lop->lop_destroy(handle);
+        rc = lop->lop_add(ctxt, rec, buf, logcookies, numcookies, data);
         RETURN(rc);
 }
 
-#if 0
-static inline int llog_cancel(struct obd_export *exp,
-                              struct lov_stripe_md *lsm, int count,
-                              struct llog_cookie *cookies, int flags)
+static inline int llog_cancel(struct llog_ctxt *ctxt, int count,
+                              struct llog_cookie *cookies, int flags, void *data)
 {
         struct llog_operations *lop;
         int rc;
         ENTRY;
 
-        rc = llog_handle2ops(loghandle, &lop);
+        rc = llog_ctxt2ops(ctxt, &lop);
         if (rc)
                 RETURN(rc);
         if (lop->lop_cancel == NULL)
                 RETURN(-EOPNOTSUPP);
 
-        rc = lop->lop_cancel(exp, lsm, count, cookies, flags);
+        rc = lop->lop_cancel(ctxt, count, cookies, flags, data);
+        RETURN(rc);
+}
+
+static inline int llog_write_rec(struct llog_handle *handle,
+                                 struct llog_rec_hdr *rec,
+                                 struct llog_cookie *logcookies,
+                                 int numcookies, void *buf, int idx)
+{
+        struct llog_operations *lop;
+        int rc, buflen;
+        ENTRY;
+
+        rc = llog_handle2ops(handle, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_write_rec == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        if (buf)
+                buflen = le32_to_cpu(rec->lrh_len) + sizeof(struct llog_rec_hdr)
+                                + sizeof(struct llog_rec_tail);
+        else
+                buflen = le32_to_cpu(rec->lrh_len);
+        LASSERT(size_round(buflen) == buflen);
+
+        rc = lop->lop_write_rec(handle, rec, logcookies, numcookies, buf, idx);
         RETURN(rc);
 }
-#endif
 
-static inline int llog_next_block(struct llog_handle *loghandle, int *cur_idx,
-                                  int next_idx, __u64 *cur_offset, void *buf,
+static inline int llog_next_block(struct llog_handle *loghandle, int *curr_idx,
+                                  int next_idx, __u64 *curr_offset, void *buf,
                                   int len)
 {
         struct llog_operations *lop;
@@ -347,25 +393,25 @@ static inline int llog_next_block(struct llog_handle *loghandle, int *cur_idx,
         if (lop->lop_next_block == NULL)
                 RETURN(-EOPNOTSUPP);
 
-        rc = lop->lop_next_block(loghandle, cur_idx, next_idx, cur_offset, buf,
+        rc = lop->lop_next_block(loghandle, curr_idx, next_idx, curr_offset, buf,
                                  len);
         RETURN(rc);
 }
 
-static inline int llog_create(struct llog_ctxt *ctxt, struct llog_handle **res,
-                              struct llog_logid *logid, char *name)
+static inline int llog_prev_block(struct llog_handle *loghandle,
+                                  int prev_idx, void *buf, int len)
 {
         struct llog_operations *lop;
         int rc;
         ENTRY;
 
-        rc = llog_obd2ops(ctxt, &lop);
+        rc = llog_handle2ops(loghandle, &lop);
         if (rc)
                 RETURN(rc);
-        if (lop->lop_create == NULL)
+        if (lop->lop_prev_block == NULL)
                 RETURN(-EOPNOTSUPP);
 
-        rc = lop->lop_create(ctxt, res, logid, name);
+        rc = lop->lop_prev_block(loghandle, prev_idx, buf, len);
         RETURN(rc);
 }
 
@@ -377,7 +423,7 @@ static inline int llog_connect(struct llog_ctxt *ctxt, int count,
         int rc;
         ENTRY;
 
-        rc = llog_obd2ops(ctxt, &lop);
+        rc = llog_ctxt2ops(ctxt, &lop);
         if (rc)
                 RETURN(rc);
         if (lop->lop_connect == NULL)
@@ -387,4 +433,20 @@ static inline int llog_connect(struct llog_ctxt *ctxt, int count,
         RETURN(rc);
 }
 
+static inline int llog_sync(struct llog_ctxt *ctxt, struct obd_export *exp)
+{
+        struct llog_operations *lop;
+        int rc;
+        ENTRY;
+
+        rc = llog_ctxt2ops(ctxt, &lop);
+        if (rc)
+                RETURN(rc);
+        if (lop->lop_sync == NULL)
+                RETURN(-EOPNOTSUPP);
+
+        rc = lop->lop_sync(ctxt, exp);
+        RETURN(rc);
+}
+
 #endif
index c602bb6..20e2771 100644 (file)
@@ -84,18 +84,18 @@ struct mds_update_record {
         int ur_cookielen;
         struct llog_cookie *ur_logcookies;
         struct iattr ur_iattr;
-        struct obd_ucred ur_uc;
+        struct lvfs_ucred ur_uc;
         __u64 ur_rdev;
         __u32 ur_mode;
         __u64 ur_time;
         __u32 ur_flags;
 };
 
-#define ur_fsuid    ur_uc.ouc_fsuid
-#define ur_fsgid    ur_uc.ouc_fsgid
-#define ur_cap      ur_uc.ouc_cap
-#define ur_suppgid1 ur_uc.ouc_suppgid1
-#define ur_suppgid2 ur_uc.ouc_suppgid2
+#define ur_fsuid    ur_uc.luc_fsuid
+#define ur_fsgid    ur_uc.luc_fsgid
+#define ur_cap      ur_uc.luc_cap
+#define ur_suppgid1 ur_uc.luc_suppgid1
+#define ur_suppgid2 ur_uc.luc_suppgid2
 
 /* i_attr_flags holds the open count in the inode in 2.4 */
 //XXX Alex implement on 2.4 with i_attr_flags and find soln for 2.5 please
index 3c75a8b..8abb4e4 100644 (file)
@@ -713,6 +713,7 @@ void ptlrpc_lprocfs_unregister_obd(struct obd_device *obddev);
 
 /* ptlrpc/llog_server.c */
 int llog_origin_handle_create(struct ptlrpc_request *req);
+int llog_origin_handle_prev_block(struct ptlrpc_request *req);
 int llog_origin_handle_next_block(struct ptlrpc_request *req);
 int llog_origin_handle_read_header(struct ptlrpc_request *req);
 int llog_origin_handle_close(struct ptlrpc_request *req);
diff --git a/lustre/include/linux/lustre_smfs.h b/lustre/include/linux/lustre_smfs.h
new file mode 100644 (file)
index 0000000..2cb6774
--- /dev/null
@@ -0,0 +1,274 @@
+#ifndef __LUSTRE_SMFS_H
+#define __LUSTRE_SMFS_H
+
+struct smfs_inode_info {
+       struct inode *smi_inode;
+       __u32  smi_flags;
+};
+
+struct journal_operations {
+        void *(*tr_start)(struct inode *, int op);
+        void (*tr_commit)(void *handle);
+};
+
+struct sm_operations {
+        /* operations on the file store */
+        struct super_operations sm_sb_ops;
+        struct inode_operations sm_dir_iops;
+        struct inode_operations sm_file_iops;
+        struct inode_operations sm_sym_iops;
+        struct file_operations sm_dir_fops;
+        struct file_operations sm_file_fops;
+        struct file_operations sm_sym_fops;
+        struct dentry_operations sm_dentry_ops;
+       struct journal_operations sm_journal_ops;
+};
+
+struct smfs_super_info {
+       struct super_block       *smsi_sb;
+        struct vfsmount         *smsi_mnt;         /* mount the cache kern with
+                                                    * kern_do_mount (like MDS) */
+       struct fsfilt_operations *sm_cache_fsfilt;  /* fsfilt operations */
+       struct fsfilt_operations *sm_fsfilt;        /* fsfilt operations */
+       struct sm_operations     *sm_ops;           /* cache ops for set cache
+                                                    * inode ops */
+
+       struct lvfs_run_ctxt     *smsi_ctxt;    
+       struct llog_ctxt         *smsi_rec_log;     /* smfs kml llog */ 
+       struct dentry            *smsi_logs_dir;
+       struct dentry            *smsi_objects_dir;
+       struct dentry            *smsi_delete_dir;  /* for delete inode dir */
+       char                     *cache_fs_type;    /* cache file system type */
+       char                     *fs_type;          /* file system type */
+       __u32                    flags;             /* flags */
+       __u32                    ops_check;
+};
+
+#define SMFS_FILE_TYPE "smfs"
+#define SMFS_FILE_MAGIC        0x19760218
+
+struct smfs_file_info {
+       struct file     *c_file;
+       int             magic;
+};
+
+struct smfs_record_extents {
+       size_t  sre_count;
+       loff_t  sre_off; 
+};
+
+#define I2SMI(inode)  ((struct smfs_inode_info *) (&(inode->u.generic_ip)))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define S2SMI(sb)   ((struct smfs_super_info *) (&(sb->u.generic_sbp)))
+#define S2CSB(sb)   (((struct smfs_super_info *) (&(sb->u.generic_sbp)))->smsi_sb)
+#else
+#define S2SMI(sb)   ((struct smfs_super_info *) (sb->s_fs_info))
+#define S2CSB(sb)   (((struct smfs_super_info *) (sb->s_fs_info))->smsi_sb)
+#endif
+
+#define I2CI(inode) (((struct smfs_inode_info*) (&(inode->u.generic_ip)))->smi_inode)
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define I2CSB(inode) ((struct smfs_super_info *) (&(inode->i_sb->u.generic_sbp)))
+#else
+#define I2CSB(inode) ((struct smfs_super_info *) (inode->i_sb->s_fs_info))
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#define I2FOPS(inode) (((struct smfs_super_info *) \
+                       (&(inode->i_sb->u.generic_sbp)))->sm_cache_fsfilt)
+#else
+#define I2FOPS(inode) (((struct smfs_super_info *) \
+                       (inode->i_sb->s_fs_info))->sm_cache_fsfilt)
+#endif
+
+#define F2SMFI(file) ((struct smfs_file_info *)((file->private_data)))
+#define F2CF(file) (((struct smfs_file_info *) ((file->private_data)))->c_file)
+
+#define SM_DO_REC              0x1
+#define SM_INIT_REC            0x2
+#define SM_CACHE_HOOK          0x4
+
+#define SMFS_DO_REC(smfs_info) (smfs_info->flags & SM_DO_REC)
+#define SMFS_SET_REC(smfs_info) (smfs_info->flags |= SM_DO_REC)
+#define SMFS_CLEAN_REC(smfs_info) (smfs_info->flags &= ~SM_DO_REC)
+
+#define SMFS_INIT_REC(smfs_info) (smfs_info->flags & SM_INIT_REC)
+#define SMFS_SET_INIT_REC(smfs_info) (smfs_info->flags |= SM_INIT_REC)
+#define SMFS_CLEAN_INIT_REC(smfs_info) (smfs_info->flags &= ~SM_INIT_REC)
+
+#define SMFS_SET_INODE_REC(inode) (I2SMI(inode)->smi_flags |= SM_DO_REC)
+#define SMFS_DO_INODE_REC(inode) (I2SMI(inode)->smi_flags & SM_DO_REC)
+#define SMFS_CLEAN_INODE_REC(inode) (I2SMI(inode)->smi_flags &= ~SM_DO_REC)
+
+#define SMFS_CACHE_HOOK(smfs_info) (smfs_info->flags & SM_CACHE_HOOK)
+#define SMFS_SET_CACHE_HOOK(smfs_info) (smfs_info->flags |= SM_CACHE_HOOK)
+#define SMFS_CLEAN_CACHE_HOOK(smfs_info) (smfs_info->flags &= ~SM_CACHE_HOOK)
+
+#define SMFS_INODE_CACHE_HOOK(inode) (I2SMI(inode)->smi_flags & SM_CACHE_HOOK)
+#define SMFS_SET_INODE_CACHE_HOOK(inode) (I2SMI(inode)->smi_flags |= SM_CACHE_HOOK)
+#define SMFS_CLEAN_INODE_CACHE_HOOK(inode) (I2SMI(inode)->smi_flags &= ~SM_CACHE_HOOK)
+
+#define LVFS_SMFS_BACK_ATTR "lvfs_back_attr"
+
+
+#define REC_COUNT_BIT 0
+#define REC_COUNT_MASK 0x01 /*0001*/
+#define REC_OP_BIT  1
+#define REC_OP_MASK 0x06 /*0110*/
+#define REC_WRITE_KML_BIT 3
+#define REC_WRITE_KML_MASK 0x08 /*1000*/
+#define REC_DEC_LINK_BIT    4
+#define REC_DEC_LINK_MASK   0x10 /*10000* different with unlink*/
+
+
+#define SET_REC_COUNT_FLAGS(flag, count_flag) \
+               (flag |= count_flag << REC_COUNT_BIT)
+#define GET_REC_COUNT_FLAGS(flag) \
+               ((flag & REC_COUNT_MASK) >> REC_COUNT_BIT)
+
+#define SET_REC_OP_FLAGS(flag, op_flag) \
+               (flag |= op_flag << REC_OP_BIT) 
+#define GET_REC_OP_FLAGS(flag) \
+               ((flag & REC_OP_MASK) >> REC_OP_BIT)
+
+#define SET_REC_WRITE_KML_FLAGS(flag, op_flag) \
+               (flag |= op_flag << REC_OP_BIT) 
+#define GET_REC_WRITE_KML_FLAGS(flag) \
+               ((flag & REC_WRITE_KML_MASK) >> REC_WRITE_KML_BIT)
+
+#define SET_REC_DEC_LINK_FLAGS(flag, op_flag) \
+               (flag |= op_flag << REC_DEC_LINK_BIT) 
+#define GET_REC_DEC_LINK_FLAGS(flag) \
+               ((flag & REC_DEC_LINK_MASK) >> REC_DEC_LINK_BIT)
+
+#define SMFS_REC_ALL           0x1
+#define SMFS_REC_BY_COUNT      0x0
+
+#define SMFS_REINT_REC         0x1
+#define SMFS_UNDO_REC          0x2
+
+#define SMFS_WRITE_KML         0x1
+
+#define SMFS_DEC_LINK          0x1
+
+#define SMFS_DO_REINT_REC(flag) \
+        (GET_REC_OP_FLAGS(flag) == SMFS_REINT_REC)
+#define SMFS_DO_UNDO_REC(flag) \
+        (GET_REC_OP_FLAGS(flag) == SMFS_UNDO_REC)
+#define SMFS_DO_REC_ALL(flag) \
+       (GET_REC_COUNT_FLAGS(flag) == SMFS_REC_ALL)
+#define SMFS_DO_REC_BY_COUNT(flag) \
+       (GET_REC_COUNT_FLAGS(flag) == SMFS_REC_BY_COUNT)
+#define SMFS_DO_WRITE_KML(flag) \
+       (GET_REC_WRITE_KML_FLAGS(flag) == SMFS_WRITE_KML)
+#define SMFS_DO_DEC_LINK(flag) \
+       (GET_REC_DEC_LINK_FLAGS(flag) == SMFS_DEC_LINK)
+
+static inline void duplicate_inode(struct inode *dst_inode, 
+                                  struct inode *src_inode) 
+{
+       dst_inode->i_mode = src_inode->i_mode;
+       dst_inode->i_uid = src_inode->i_uid;
+       dst_inode->i_gid = src_inode->i_gid;
+       dst_inode->i_nlink = src_inode->i_nlink;
+       dst_inode->i_size = src_inode->i_size;
+       dst_inode->i_atime = src_inode->i_atime;
+       dst_inode->i_ctime = src_inode->i_ctime;
+       dst_inode->i_mtime = src_inode->i_mtime;
+       dst_inode->i_blksize = src_inode->i_blksize;  
+       dst_inode->i_version = src_inode->i_version;
+       dst_inode->i_state = src_inode->i_state;
+       dst_inode->i_generation = src_inode->i_generation;
+
+       /* This is to make creating special files working. */
+       dst_inode->i_rdev = src_inode->i_rdev;
+}
+
+static inline void post_smfs_inode(struct inode *inode, 
+                                  struct inode *cache_inode)
+{
+       if (inode && cache_inode) {
+               duplicate_inode(inode, cache_inode);
+               /*Here we must release the cache_inode,
+                *Otherwise we will have no chance to
+                *do it
+                */
+               cache_inode->i_state &=~I_LOCK; 
+               inode->i_blocks = cache_inode->i_blocks;
+       }
+}
+
+static inline void pre_smfs_inode(struct inode *inode,
+                                 struct inode *cache_inode)
+{
+       if (inode && cache_inode)
+               duplicate_inode(cache_inode, inode);
+}
+
+/* instantiate a file handle to the cache file */
+static inline void duplicate_file(struct file *dst_file,
+                                 struct file *src_file) 
+{
+       dst_file->f_pos = src_file->f_pos;
+        dst_file->f_mode = src_file->f_mode;
+        dst_file->f_flags = src_file->f_flags;
+        dst_file->f_owner  = src_file->f_owner;
+       dst_file->f_vfsmnt = src_file->f_vfsmnt;
+       
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       dst_file->f_reada = src_file->f_reada;
+       dst_file->f_ramax = src_file->f_ramax;
+       dst_file->f_raend = src_file->f_raend;
+       dst_file->f_ralen = src_file->f_ralen;
+       dst_file->f_rawin = src_file->f_rawin;
+#else
+       dst_file->f_ra = src_file->f_ra;
+#endif
+}
+
+static inline void duplicate_sb(struct super_block *dst_sb, 
+                               struct super_block *src_sb)
+{
+       dst_sb->s_blocksize = src_sb->s_blocksize;
+       dst_sb->s_magic = src_sb->s_magic;
+       dst_sb->s_blocksize_bits = src_sb->s_blocksize_bits;
+       dst_sb->s_maxbytes = src_sb->s_maxbytes;
+}
+
+static inline void d_unalloc(struct dentry *dentry)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+       list_del(&dentry->d_hash);
+       INIT_LIST_HEAD(&dentry->d_hash);
+#else
+       hlist_del_init(&dentry->d_hash);
+#endif
+       dput(dentry); /* this will free the dentry memory */
+}
+
+static inline struct dentry *pre_smfs_dentry(struct dentry *parent_dentry, 
+                                            struct inode *cache_inode,
+                                            struct dentry *dentry)
+{
+       struct dentry *cache_dentry = NULL;
+
+       cache_dentry = d_alloc(parent_dentry, &dentry->d_name); 
+       if (!cache_dentry)
+               RETURN(NULL);
+       if (!parent_dentry)
+               cache_dentry->d_parent = cache_dentry;
+       if (cache_inode)
+               d_add(cache_dentry, cache_inode);
+       RETURN(cache_dentry);
+}
+
+static inline void post_smfs_dentry(struct dentry *cache_dentry)
+{
+       if (!cache_dentry)
+               return;
+       if (cache_dentry->d_inode)
+               igrab(cache_dentry->d_inode);
+       d_unalloc(cache_dentry);        
+}
+#endif /* _LUSTRE_SMFS_H */
index b18769f..f51cf73 100644 (file)
 #endif
 
 /* simple.c */
-struct obd_ucred {
-        __u32 ouc_fsuid;
-        __u32 ouc_fsgid;
-        __u32 ouc_cap;
-        __u32 ouc_suppgid1;
-        __u32 ouc_suppgid2;
+struct lvfs_ucred {
+        __u32 luc_fsuid;
+        __u32 luc_fsgid;
+        __u32 luc_cap;
+        __u32 luc_suppgid1;
+        __u32 luc_suppgid2;
 };
 
 struct lvfs_callback_ops {
@@ -28,11 +28,11 @@ struct lvfs_callback_ops {
 
 #define OBD_RUN_CTXT_MAGIC      0xC0FFEEAA
 #define OBD_CTXT_DEBUG          /* development-only debugging */
-struct obd_run_ctxt {
+struct lvfs_run_ctxt {
         struct vfsmount *pwdmnt;
         struct dentry   *pwd;
         mm_segment_t     fs;
-        struct obd_ucred ouc;
+        struct lvfs_ucred luc;
         int              ngroups;
         struct lvfs_callback_ops cb_ops;
 #ifdef OBD_CTXT_DEBUG
@@ -47,15 +47,16 @@ struct obd_run_ctxt {
 #endif
 
 /* lvfs_common.c */
-struct dentry *lvfs_fid2dentry(struct obd_run_ctxt *, __u64, __u32, __u64 ,void *data);
+struct dentry *lvfs_fid2dentry(struct lvfs_run_ctxt *, __u64, __u32, __u64 ,void *data);
 
-void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
-               struct obd_ucred *cred);
-void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
-              struct obd_ucred *cred);
+void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
+               struct lvfs_ucred *cred);
+void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
+              struct lvfs_ucred *cred);
 
 #ifdef __KERNEL__
-
+int lvfs_reint(struct super_block *sb, void *r_rec);
+int lvfs_undo(struct super_block *sb, void *r_rec);
 struct dentry *simple_mkdir(struct dentry *dir, char *name, int mode, int fix);
 struct dentry *simple_mknod(struct dentry *dir, char *name, int mode, int fix);
 int lustre_fread(struct file *file, void *buf, int len, loff_t *off);
index 71fc431..5e125a0 100644 (file)
@@ -20,8 +20,8 @@
 
 #define l_filp_open filp_open
 
-struct obd_run_ctxt;
-struct l_file *l_dentry_open(struct obd_run_ctxt *, struct l_dentry *,
+struct lvfs_run_ctxt;
+struct l_file *l_dentry_open(struct lvfs_run_ctxt *, struct l_dentry *,
                              int flags);
 
 struct l_linux_dirent {
index b3ccd51..8635862 100644 (file)
@@ -32,6 +32,7 @@
 # include <linux/mount.h>
 #endif
 
+#include <linux/lvfs.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_idl.h>
 #include <linux/lustre_export.h>
@@ -484,8 +485,9 @@ struct obd_device {
         spinlock_t              obd_osfs_lock;
         struct obd_statfs       obd_osfs;
         unsigned long           obd_osfs_age;
-        struct obd_run_ctxt     obd_ctxt;
+        struct lvfs_run_ctxt    obd_lvfs_ctxt;
         struct llog_ctxt        *obd_llog_ctxt[LLOG_MAX_CTXTS];
+
         struct obd_device       *obd_observer;
         struct obd_export       *obd_self_export;
 
index 941d9b5..cc508c3 100644 (file)
@@ -600,7 +600,7 @@ obd_lvfs_fid2dentry(struct obd_export *exp, __u64 id_ino, __u32 gen, __u64 gr)
 {
         LASSERT(exp->exp_obd);
 
-        return lvfs_fid2dentry(&exp->exp_obd->obd_ctxt, id_ino, gen, gr,
+        return lvfs_fid2dentry(&exp->exp_obd->obd_lvfs_ctxt, id_ino, gen, gr,
                                exp->exp_obd);
 }
 
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-tmpfs-iopen.patch b/lustre/kernel_patches/patches/linux-2.4.20-tmpfs-iopen.patch
deleted file mode 100644 (file)
index b3b75e3..0000000
+++ /dev/null
@@ -1,1287 +0,0 @@
-diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/mm.h linux-2.4.20/include/linux/mm.h
---- linux-2.4.20.orig/include/linux/mm.h       2004-02-10 11:43:10.000000000 +0200
-+++ linux-2.4.20/include/linux/mm.h    2004-03-01 13:44:45.000000000 +0200
-@@ -468,7 +468,8 @@ extern void clear_page_tables(struct mm_
- extern int fail_writepage(struct page *);
- struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused);
- struct file *shmem_file_setup(char * name, loff_t size);
--int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr);
-+struct page *shmem_getpage_locked(struct inode *inode, unsigned long idx);
-+struct page *shmem_getpage_unlocked(struct inode *inode, unsigned long idx);
- extern void shmem_lock(struct file * file, int lock);
- extern int shmem_zero_setup(struct vm_area_struct *);
-diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/shmem_fs.h linux-2.4.20/include/linux/shmem_fs.h
---- linux-2.4.20.orig/include/linux/shmem_fs.h 2004-02-10 18:39:17.000000000 +0200
-+++ linux-2.4.20/include/linux/shmem_fs.h      2004-02-23 12:40:28.000000000 +0200
-@@ -7,6 +7,9 @@
- #define SHMEM_NR_DIRECT 16
-+#define SHMEM_MOUNT_IOPEN       0x8000        /* Allow access via iopen */
-+#define SHMEM_MOUNT_IOPEN_NOPRIV  0x10000     /* Make iopen world-readable */
-+
- /*
-  * A swap entry has to fit into a "unsigned long", as
-  * the entry is hidden in the "index" field of the
-@@ -38,6 +41,9 @@ struct shmem_inode_info {
- };
- struct shmem_sb_info {
-+      struct dentry *iopen;
-+      unsigned long options;
-+      unsigned long root_ino;
-       unsigned long max_blocks;   /* How many blocks are allowed */
-       unsigned long free_blocks;  /* How many are left for allocation */
-       unsigned long max_inodes;   /* How many inodes are allowed */
-@@ -59,11 +65,9 @@ shmem_xattr_find(struct inode *inode, co
- extern ssize_t
- shmem_xattr_set(struct inode *inode, const char *name,
-               const void *value, u16 valuelen, int flags);
--              
- extern ssize_t
- shmem_xattr_get(struct inode *inode, const char *name,
-               void *value, size_t valuelen);
--              
- extern int
- shmem_xattr_delete(struct inode *inode, struct shmem_xattr *xattr);
-diff -rupN --exclude='ide*' linux-2.4.20.orig/mm/shmem.c linux-2.4.20/mm/shmem.c
---- linux-2.4.20.orig/mm/shmem.c       2004-02-10 18:44:05.000000000 +0200
-+++ linux-2.4.20/mm/shmem.c    2004-03-01 14:37:21.000000000 +0200
-@@ -36,29 +36,45 @@
- #define TMPFS_MAGIC   0x01021994
- #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
-+
- #define BLOCKS_PER_PAGE  (PAGE_CACHE_SIZE/512)
--#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
-+#define SHMEM_MAX_INDEX  (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE * \
-+                        (ENTRIES_PER_PAGE/2) * (ENTRIES_PER_PAGE+1))
-+
- #define SHMEM_MAX_BYTES  ((unsigned long long)SHMEM_MAX_INDEX << PAGE_CACHE_SHIFT)
- #define VM_ACCT(size)    (((size) + PAGE_CACHE_SIZE - 1) >> PAGE_SHIFT)
- /* Pretend that each entry is of this size in directory's i_size */
--#define BOGO_DIRENT_SIZE 20
--
-+#define BOGO_DIRENT_SIZE (20)
- #define SHMEM_SB(sb) (&sb->u.shmem_sb)
-+#define SHMEM_IOPEN_INO       2
-+#define SHMEM_IOPEN_NAME_LEN  32
-+
-+#define ASSERT(cond)                                                    \
-+do {                                                                  \
-+      if (!(cond)) {                                                  \
-+              printk (KERN_EMERG                                      \
-+                      "Assertion failure in %s() at %s:%d: \"%s\"\n", \
-+                      __FUNCTION__, __FILE__, __LINE__, # cond);      \
-+              BUG();                                                  \
-+      }                                                               \
-+} while (0)
-+
- static struct super_operations shmem_ops;
-+static struct vm_operations_struct shmem_vm_ops;
- static struct address_space_operations shmem_aops;
- static struct file_operations shmem_file_operations;
- static struct inode_operations shmem_inode_operations;
- static struct inode_operations shmem_dir_inode_operations;
--static struct vm_operations_struct shmem_vm_ops;
- LIST_HEAD (shmem_inodes);
- static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
- atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
--static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
-+struct page *shmem_getpage_locked(struct inode *inode, unsigned long idx);
-+struct page *shmem_getpage_unlocked(struct inode *inode, unsigned long idx);
- #ifdef CONFIG_TMPFS
- static struct inode_operations shmem_symlink_inode_operations;
-@@ -327,7 +343,7 @@ shmem_getxattr(struct dentry *dentry, co
-  * inode attributes list.*/
- static int
- shmem_setxattr(struct dentry *dentry, const char *name,
--               void *value, size_t valuelen, int flags)
-+               const void *value, size_t valuelen, int flags)
- {
-         int error;
-         struct inode *inode = dentry->d_inode;
-@@ -404,8 +420,8 @@ shmem_listxattr(struct dentry *dentry, c
-  * @inode: inode to recalc
-  * @swap:  additional swap pages freed externally
-  *
-- * We have to calculate the free blocks since the mm can drop pages
-- * behind our back
-+ * We have to calculate the free blocks since the mm can drop pages behind our
-+ * back
-  *
-  * But we know that normally
-  * inodes->i_blocks/BLOCKS_PER_PAGE == 
-@@ -441,24 +457,23 @@ static void shmem_recalc_inode(struct in
-  * @page:  optional page to add to the structure. Has to be preset to
-  *         all zeros
-  *
-- * If there is no space allocated yet it will return -ENOMEM when
-- * page == 0 else it will use the page for the needed block.
-+ * If there is no space allocated yet it will return -ENOMEM when page == 0 else
-+ * it will use the page for the needed block.
-  *
-  * returns -EFBIG if the index is too big.
-  *
-  *
-  * The swap vector is organized the following way:
-  *
-- * There are SHMEM_NR_DIRECT entries directly stored in the
-- * shmem_inode_info structure. So small files do not need an addional
-- * allocation.
-- *
-- * For pages with index > SHMEM_NR_DIRECT there is the pointer
-- * i_indirect which points to a page which holds in the first half
-- * doubly indirect blocks, in the second half triple indirect blocks:
-+ * There are SHMEM_NR_DIRECT entries directly stored in the shmem_inode_info
-+ * structure. So small files do not need an addional allocation.
-+ *
-+ * For pages with index > SHMEM_NR_DIRECT there is the pointer i_indirect which
-+ * points to a page which holds in the first half doubly indirect blocks, in the
-+ * second half triple indirect blocks:
-  *
-- * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the
-- * following layout (for SHMEM_NR_DIRECT == 16):
-+ * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the following
-+ * layout (for SHMEM_NR_DIRECT == 16):
-  *
-  * i_indirect -> dir --> 16-19
-  *          |      +-> 20-23
-@@ -473,7 +488,9 @@ static void shmem_recalc_inode(struct in
-  *                   +-> 48-51
-  *                   +-> 52-55
-  */
--static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long index, unsigned long page) 
-+static swp_entry_t *
-+shmem_swp_entry (struct shmem_inode_info *info, unsigned long index,
-+               unsigned long page) 
- {
-       unsigned long offset;
-       void **dir;
-@@ -520,7 +537,8 @@ static swp_entry_t * shmem_swp_entry (st
-  * @info:     info structure for the inode
-  * @index:    index of the page to find
-  */
--static inline swp_entry_t * shmem_alloc_entry (struct shmem_inode_info *info, unsigned long index)
-+static inline swp_entry_t *
-+shmem_alloc_entry(struct shmem_inode_info *info, unsigned long index)
- {
-       unsigned long page = 0;
-       swp_entry_t * res;
-@@ -545,7 +563,8 @@ static inline swp_entry_t * shmem_alloc_
-  * @dir:   pointer to the directory
-  * @count: number of entries to scan
-  */
--static int shmem_free_swp(swp_entry_t *dir, unsigned int count)
-+static int
-+shmem_free_swp(swp_entry_t *dir, unsigned int count)
- {
-       swp_entry_t *ptr, entry;
-       int freed = 0;
-@@ -573,7 +592,9 @@ static int shmem_free_swp(swp_entry_t *d
-  */
- static inline unsigned long 
--shmem_truncate_direct(swp_entry_t *** dir, unsigned long start, unsigned long len) {
-+shmem_truncate_direct(swp_entry_t ***dir, unsigned long start,
-+                    unsigned long len)
-+{
-       swp_entry_t **last, **ptr;
-       unsigned long off, freed = 0;
-  
-@@ -639,7 +660,8 @@ shmem_truncate_indirect(struct shmem_ino
-                       BUG();
-               baseidx = max & ~(ENTRIES_PER_PAGE*ENTRIES_PER_PAGE-1);
--              base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 + baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
-+              base = (swp_entry_t ***) info->i_indirect + ENTRIES_PER_PAGE/2 +
-+                      baseidx/ENTRIES_PER_PAGE/ENTRIES_PER_PAGE ;
-               len = max - baseidx + 1;
-               baseidx += ENTRIES_PER_PAGE*ENTRIES_PER_PAGE/2+SHMEM_NR_DIRECT;
-       }
-@@ -654,7 +676,8 @@ shmem_truncate_indirect(struct shmem_ino
-       return shmem_truncate_direct(base, start, len);
- }
--static void shmem_truncate (struct inode * inode)
-+static void
-+shmem_truncate(struct inode *inode)
- {
-       unsigned long index;
-       unsigned long partial;
-@@ -668,16 +691,16 @@ static void shmem_truncate (struct inode
-       partial = inode->i_size & ~PAGE_CACHE_MASK;
-       if (partial) {
--              swp_entry_t *entry = shmem_swp_entry(info, index-1, 0);
-               struct page *page;
--              /*
--               * This check is racy: it's faintly possible that page
--               * was assigned to swap during truncate_inode_pages,
--               * and now assigned to file; but better than nothing.
-+              swp_entry_t *entry = shmem_swp_entry(info, index - 1, 0);
-+              
-+              /* This check is racy: it's faintly possible that page was
-+               * assigned to swap during truncate_inode_pages, and now
-+               * assigned to file; but better than nothing.
-                */
-               if (!IS_ERR(entry) && entry->val) {
-                       spin_unlock(&info->lock);
--                      page = shmem_getpage_locked(info, inode, index-1);
-+                      page = shmem_getpage_locked(inode, index - 1);
-                       if (!IS_ERR(page)) {
-                               memclear_highpage_flush(page, partial,
-                                       PAGE_CACHE_SIZE - partial);
-@@ -697,8 +720,166 @@ static void shmem_truncate (struct inode
-       up(&info->sem);
- }
--static void shmem_delete_inode(struct inode * inode)
-+static struct inode *
-+shmem_find_inode(struct super_block *sb, long int ino)
-+{
-+      struct list_head *p;
-+      struct inode *inode = NULL;
-+      struct shmem_inode_info *info;
-+
-+      spin_lock (&shmem_ilock);
-+      list_for_each(p, &shmem_inodes) {
-+              info = list_entry(p, struct shmem_inode_info, list);
-+              
-+              if (info->inode->i_ino == ino && 
-+                  info->inode->i_sb == sb) 
-+              {
-+                      inode = info->inode;
-+                      break;
-+              }
-+      }
-+      
-+      spin_unlock (&shmem_ilock);
-+      
-+      if (inode)
-+              igrab(inode);
-+              
-+      return inode;
-+}
-+
-+#define switch_fields(x,y) do {   \
-+      __typeof__ (x) __tmp = x; \
-+      x = y; y = __tmp; } while (0)
-+
-+static inline void
-+switch_names(struct dentry *dentry, struct dentry *target)
-+{
-+      const unsigned char *old_name, *new_name;
-+
-+      memcpy(dentry->d_iname, target->d_iname, 
-+             DNAME_INLINE_LEN);
-+      
-+      old_name = target->d_name.name;
-+      new_name = dentry->d_name.name;
-+      
-+      if (old_name == target->d_iname)
-+              old_name = dentry->d_iname;
-+      
-+      if (new_name == dentry->d_iname)
-+              new_name = target->d_iname;
-+      
-+      target->d_name.name = new_name;
-+      dentry->d_name.name = old_name;
-+}
-+
-+static struct dentry *
-+shmem_iopen_lookup(struct inode *dir, 
-+                 struct dentry *dentry)
-+{
-+      struct inode *inode;
-+      unsigned long ino;
-+      struct list_head *lp;
-+      struct dentry *alternate;
-+      char buf[SHMEM_IOPEN_NAME_LEN];
-+      struct shmem_sb_info *sbinfo = SHMEM_SB(dir->i_sb);
-+
-+      if (dentry->d_name.len >= SHMEM_IOPEN_NAME_LEN)
-+              return ERR_PTR(-ENAMETOOLONG);
-+
-+      memcpy(buf, dentry->d_name.name, dentry->d_name.len);
-+      buf[dentry->d_name.len] = 0;
-+
-+      if (strcmp(buf, ".") == 0)
-+              ino = dir->i_ino;
-+      else if (strcmp(buf, "..") == 0)
-+              ino = sbinfo->root_ino;
-+      else
-+              ino = simple_strtoul(buf, 0, 0);
-+
-+      if (ino < sbinfo->root_ino)
-+              return ERR_PTR(-ENOENT);
-+
-+      if (!(inode = shmem_find_inode(dir->i_sb, ino)))
-+              return ERR_PTR(-ENOENT);
-+
-+      ASSERT(list_empty(&dentry->d_alias));
-+      ASSERT(list_empty(&dentry->d_hash));
-+
-+      /* preferrably return a connected dentry */
-+      spin_lock(&dcache_lock);
-+      list_for_each(lp, &inode->i_dentry) {
-+              alternate = list_entry(lp, struct dentry, d_alias);
-+              ASSERT(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED));
-+      }
-+
-+      if (!list_empty(&inode->i_dentry)) {
-+              alternate = list_entry(inode->i_dentry.next,
-+                                     struct dentry, d_alias);
-+              dget_locked(alternate);
-+              alternate->d_vfs_flags |= DCACHE_REFERENCED;
-+              iput(inode);
-+              spin_unlock(&dcache_lock);
-+              return alternate;
-+      }
-+      dentry->d_flags |= DCACHE_NFSD_DISCONNECTED;
-+
-+      /* d_add(), but don't drop dcache_lock before adding dentry to inode */
-+      list_add(&dentry->d_alias, &inode->i_dentry);
-+      dentry->d_inode = inode;
-+
-+      __d_rehash(dentry, 0);
-+      spin_unlock(&dcache_lock);
-+
-+      return NULL;
-+}
-+
-+struct dentry *
-+shmem_iopen_unalias(struct dentry *dentry, struct inode *inode)
-+{
-+      struct dentry *tmp, *goal = NULL;
-+      struct list_head *lp;
-+
-+      list_for_each(lp, &inode->i_dentry) {
-+              tmp = list_entry(lp, struct dentry, d_alias);
-+              if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) {
-+                      ASSERT(tmp->d_alias.next == &inode->i_dentry);
-+                      ASSERT(tmp->d_alias.prev == &inode->i_dentry);
-+                      goal = tmp;
-+                      dget_locked(goal);
-+                      break;
-+              }
-+      }
-+
-+      if (!goal)
-+              return NULL;
-+
-+      goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
-+      list_del_init(&goal->d_hash);
-+
-+      list_del(&goal->d_child);
-+      list_del(&dentry->d_child);
-+
-+      switch_names(goal, dentry);
-+      switch_fields(goal->d_parent, dentry->d_parent);
-+      switch_fields(goal->d_name.len, dentry->d_name.len);
-+      switch_fields(goal->d_name.hash, dentry->d_name.hash);
-+
-+      list_add(&goal->d_child, &goal->d_parent->d_subdirs);
-+      list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
-+      __d_rehash(goal, 0);
-+
-+      return goal;
-+}
-+
-+static struct inode_operations iopen_inode_operations = {
-+      lookup:         shmem_iopen_lookup,
-+};
-+
-+static void
-+shmem_delete_inode(struct inode *inode)
- {
-+      struct dentry *dentry;
-+      
- #ifdef CONFIG_TMPFS_XATTR
-       struct list_head *tmp, *p;
-       struct shmem_xattr *xattr;
-@@ -706,16 +887,30 @@ static void shmem_delete_inode(struct in
- #endif
-       struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
--      if (inode->i_op->truncate == shmem_truncate) {
-+      if (inode->i_ino != SHMEM_IOPEN_INO) {
-+              /* eliminating iopen alias */
-+              spin_lock(&dcache_lock);
-+              if (!list_empty(&inode->i_dentry)) {
-+                      dentry = list_entry(inode->i_dentry.next,
-+                                          struct dentry, d_alias);
-+                      shmem_iopen_unalias(dentry, inode);
-+              }
-+              spin_unlock(&dcache_lock);
-+
-               spin_lock (&shmem_ilock);
-               list_del (&SHMEM_I(inode)->list);
-               spin_unlock (&shmem_ilock);
--              inode->i_size = 0;
--              shmem_truncate (inode);
-+      
-+              if (inode->i_op->truncate == shmem_truncate) {
-+                      inode->i_size = 0;
-+                      shmem_truncate (inode);
-+              }
-+      
-+              spin_lock (&sbinfo->stat_lock);
-+              sbinfo->free_inodes++;
-+              spin_unlock (&sbinfo->stat_lock);
-       }
--      spin_lock (&sbinfo->stat_lock);
--      sbinfo->free_inodes++;
--      spin_unlock (&sbinfo->stat_lock);
-+      
- #ifdef CONFIG_TMPFS_XATTR
-         list_for_each_safe(p, tmp, &info->xattrs) {
-                 xattr = list_entry(p, struct shmem_xattr, list);
-@@ -725,7 +920,8 @@ static void shmem_delete_inode(struct in
-       clear_inode(inode);
- }
--static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
-+static inline int
-+shmem_find_swp(swp_entry_t entry, swp_entry_t *ptr, swp_entry_t *eptr)
- {
-       swp_entry_t *test;
-@@ -736,7 +932,9 @@ static inline int shmem_find_swp(swp_ent
-       return -1;
- }
--static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page)
-+static int
-+shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry,
-+                struct page *page)
- {
-       swp_entry_t *ptr;
-       unsigned long idx;
-@@ -875,9 +1073,11 @@ getswap:
-  * still need to guard against racing with shm_writepage(), which might
-  * be trying to move the page to the swap cache as we run.
-  */
--static struct page * shmem_getpage_locked(struct shmem_inode_info *info, struct inode * inode, unsigned long idx)
-+struct page *
-+shmem_getpage_locked(struct inode *inode, unsigned long idx)
- {
-       struct address_space * mapping = inode->i_mapping;
-+      struct shmem_inode_info *info = SHMEM_I(inode);
-       struct shmem_sb_info *sbinfo;
-       struct page * page;
-       swp_entry_t *entry;
-@@ -941,7 +1141,8 @@ repeat:
-               swap_free(*entry);
-               *entry = (swp_entry_t) {0};
-               delete_from_swap_cache(page);
--              flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) | (1 << PG_referenced) | (1 << PG_arch_1));
-+              flags = page->flags & ~((1 << PG_uptodate) | (1 << PG_error) |
-+                                      (1 << PG_referenced) | (1 << PG_arch_1));
-               page->flags = flags | (1 << PG_dirty);
-               add_to_page_cache_locked(page, mapping, idx);
-               info->swapped--;
-@@ -985,46 +1186,53 @@ wait_retry:
-       goto repeat;
- }
--int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
-+struct page *
-+shmem_getpage_unlocked(struct inode *inode, unsigned long idx)
- {
-+      struct page *page;
-       struct shmem_inode_info *info = SHMEM_I(inode);
--      int error;
--      down (&info->sem);
--      *ptr = ERR_PTR(-EFAULT);
--      if (inode->i_size <= (loff_t) idx * PAGE_CACHE_SIZE)
-+      down(&info->sem);
-+      page = ERR_PTR(-EFAULT);
-+      
-+      if (inode->i_size <= (loff_t)idx * PAGE_CACHE_SIZE)
-               goto failed;
--      *ptr = shmem_getpage_locked(info, inode, idx);
--      if (IS_ERR (*ptr))
-+      page = shmem_getpage_locked(inode, idx);
-+      
-+      if (IS_ERR(page))
-               goto failed;
--      UnlockPage(*ptr);
--      up (&info->sem);
--      return 0;
-+      UnlockPage(page);
-+      up(&info->sem);
-+      return page;
- failed:
--      up (&info->sem);
--      error = PTR_ERR(*ptr);
--      *ptr = NOPAGE_SIGBUS;
--      if (error == -ENOMEM)
--              *ptr = NOPAGE_OOM;
--      return error;
-+      up(&info->sem);
-+
-+      if (PTR_ERR(page) == -ENOMEM)
-+              return NOPAGE_OOM;
-+      
-+      return page;
- }
--struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused)
-+struct page *
-+shmem_nopage(struct vm_area_struct *vma, 
-+           unsigned long address, int unused)
- {
--      struct page * page;
-       unsigned int idx;
-+      struct page * page;
-       struct inode * inode = vma->vm_file->f_dentry->d_inode;
--      idx = (address - vma->vm_start) >> PAGE_CACHE_SHIFT;
--      idx += vma->vm_pgoff;
-+      idx = ((address - vma->vm_start) >> PAGE_CACHE_SHIFT) +
-+              vma->vm_pgoff;
--      if (shmem_getpage(inode, idx, &page))
-+      page = shmem_getpage_unlocked(inode, idx);
-+      
-+      if (IS_ERR(page))
-               return page;
-       flush_page_to_ram(page);
--      return(page);
-+      return page;
- }
- void shmem_lock(struct file * file, int lock)
-@@ -1037,7 +1245,8 @@ void shmem_lock(struct file * file, int 
-       up(&info->sem);
- }
--static int shmem_mmap(struct file * file, struct vm_area_struct * vma)
-+static int
-+shmem_mmap(struct file * file, struct vm_area_struct * vma)
- {
-       struct vm_operations_struct * ops;
-       struct inode *inode = file->f_dentry->d_inode;
-@@ -1050,39 +1259,53 @@ static int shmem_mmap(struct file * file
-       return 0;
- }
--struct inode *shmem_get_inode(struct super_block *sb, int mode, int dev)
-+static void
-+shmem_fill_inode(struct inode *inode, int mode, int dev)
- {
--      struct inode * inode;
-       struct shmem_inode_info *info;
--      struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-+      
-+      info = SHMEM_I(inode);
-+      info->inode = inode;
-+      spin_lock_init (&info->lock);
-+      sema_init (&info->sem, 1);
--      spin_lock (&sbinfo->stat_lock);
--      if (!sbinfo->free_inodes) {
--              spin_unlock (&sbinfo->stat_lock);
--              return NULL;
--      }
--      sbinfo->free_inodes--;
--      spin_unlock (&sbinfo->stat_lock);
-+#ifdef CONFIG_TMPFS_XATTR
-+      INIT_LIST_HEAD(&info->xattrs);
-+      info->xtail = &info->xattrs;
-+#endif
--      inode = new_inode(sb);
--      if (inode) {
-+      inode->i_blocks = 0;
-+      inode->i_rdev = NODEV;
-+      inode->i_atime = CURRENT_TIME;
-+      inode->i_ctime = CURRENT_TIME;
-+      inode->i_mtime = CURRENT_TIME;
-+      inode->i_blksize = PAGE_CACHE_SIZE;
-+      
-+      /* handling speciall iopen inode. */
-+      if (inode->i_ino == SHMEM_IOPEN_INO) {
-+              struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
-+              
-+              inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR;
-+      
-+              if (sbinfo->options & SHMEM_MOUNT_IOPEN_NOPRIV)
-+                      inode->i_mode |= 0777;
-+              
-+              inode->i_uid = 0;
-+              inode->i_gid = 0;
-+              inode->i_nlink = 1;
-+              inode->i_size = 2 * BOGO_DIRENT_SIZE;
-+              inode->i_version = 1;
-+              inode->i_generation = 0;
-+
-+              inode->i_op = &iopen_inode_operations;
-+              inode->i_fop = &dcache_dir_ops;
-+              inode->i_mapping->a_ops = 0;
-+      } else {
-               inode->i_mode = mode;
-               inode->i_uid = current->fsuid;
-               inode->i_gid = current->fsgid;
--              inode->i_blksize = PAGE_CACHE_SIZE;
--              inode->i_blocks = 0;
--              inode->i_rdev = NODEV;
-               inode->i_mapping->a_ops = &shmem_aops;
--              inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
--              info = SHMEM_I(inode);
--              info->inode = inode;
--              spin_lock_init (&info->lock);
--              sema_init (&info->sem, 1);
--#ifdef CONFIG_TMPFS_XATTR
--              INIT_LIST_HEAD(&info->xattrs);
--              info->xtail = &info->xattrs;
--#endif
-               switch (mode & S_IFMT) {
-               default:
-                       init_special_inode(inode, mode, dev);
-@@ -1090,9 +1313,6 @@ struct inode *shmem_get_inode(struct sup
-               case S_IFREG:
-                       inode->i_op = &shmem_inode_operations;
-                       inode->i_fop = &shmem_file_operations;
--                      spin_lock (&shmem_ilock);
--                      list_add_tail(&info->list, &shmem_inodes);
--                      spin_unlock (&shmem_ilock);
-                       break;
-               case S_IFDIR:
-                       inode->i_nlink++;
-@@ -1104,12 +1324,59 @@ struct inode *shmem_get_inode(struct sup
-               case S_IFLNK:
-                       break;
-               }
-+              
-+              spin_lock (&shmem_ilock);
-+              list_add_tail(&info->list, &shmem_inodes);
-+              spin_unlock (&shmem_ilock);
-+      }
-+}
-+
-+struct inode *
-+shmem_get_inode(struct super_block *sb, 
-+              int mode, int dev, int root)
-+{
-+      struct inode *inode;
-+      struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-+
-+      spin_lock (&sbinfo->stat_lock);
-+      if (!sbinfo->free_inodes) {
-+              spin_unlock (&sbinfo->stat_lock);
-+              return NULL;
-+      }
-+      sbinfo->free_inodes--;
-+      spin_unlock (&sbinfo->stat_lock);
-+
-+      if ((inode = new_inode(sb))) {
-+              shmem_fill_inode(inode, mode, dev);
-+              if (root)
-+                      sbinfo->root_ino = inode->i_ino;
-       }
-+      
-       return inode;
- }
--static int shmem_set_size(struct shmem_sb_info *info,
--                        unsigned long max_blocks, unsigned long max_inodes)
-+void shmem_read_inode(struct inode *inode)
-+{
-+      struct shmem_sb_info *sbinfo;
-+
-+      if (inode->i_ino != SHMEM_IOPEN_INO)
-+              return;
-+              
-+      sbinfo = SHMEM_SB(inode->i_sb);
-+      
-+      spin_lock (&sbinfo->stat_lock);
-+      if (!sbinfo->free_inodes) {
-+              spin_unlock (&sbinfo->stat_lock);
-+              return;
-+      }
-+      sbinfo->free_inodes--;
-+      spin_unlock (&sbinfo->stat_lock);
-+      shmem_fill_inode(inode, 0, 0);
-+}
-+
-+static int
-+shmem_set_size(struct shmem_sb_info *info, unsigned long max_blocks, 
-+             unsigned long max_inodes)
- {
-       int error;
-       unsigned long blocks, inodes;
-@@ -1192,7 +1459,6 @@ shmem_file_write(struct file *file,const
-       while (count) {
-               unsigned long bytes, index, offset;
--              char *kaddr;
-               /*
-                * Try to find the page in the cache. If it isn't there,
-@@ -1201,9 +1467,9 @@ shmem_file_write(struct file *file,const
-               offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
-               index = pos >> PAGE_CACHE_SHIFT;
-               bytes = PAGE_CACHE_SIZE - offset;
--              if (bytes > count) {
-+
-+              if (bytes > count)
-                       bytes = count;
--              }
-               /*
-                * Bring in the user page that we will copy from _first_.
-@@ -1218,7 +1484,7 @@ shmem_file_write(struct file *file,const
-               info = SHMEM_I(inode);
-               down (&info->sem);
--              page = shmem_getpage_locked(info, inode, index);
-+              page = shmem_getpage_locked(inode, index);
-               up (&info->sem);
-               status = PTR_ERR(page);
-@@ -1226,17 +1492,19 @@ shmem_file_write(struct file *file,const
-                       break;
-               /* We have exclusive IO access to the page.. */
--              if (!PageLocked(page)) {
-+              if (!PageLocked(page))
-                       PAGE_BUG(page);
--              }
--              kaddr = kmap(page);
--              status = copy_from_user(kaddr+offset, buf, bytes);
-+              status = copy_from_user(kmap(page) + offset,
-+                                      buf, bytes);
-+              
-               kunmap(page);
-+
-               if (status)
-                       goto fail_write;
-               flush_dcache_page(page);
-+              
-               if (bytes > 0) {
-                       SetPageDirty(page);
-                       written += bytes;
-@@ -1266,7 +1534,8 @@ fail_write:
-       goto unlock;
- }
--static void do_shmem_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc)
-+static void
-+do_shmem_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc)
- {
-       struct inode *inode = filp->f_dentry->d_inode;
-       struct address_space *mapping = inode->i_mapping;
-@@ -1292,15 +1561,18 @@ static void do_shmem_file_read(struct fi
-               nr = nr - offset;
--              if ((desc->error = shmem_getpage(inode, index, &page)))
-+              page = shmem_getpage_unlocked(inode, index);
-+
-+              if (IS_ERR(page)) {
-+                      desc->error = PTR_ERR(page);
-                       break;
-+              }
-               if (mapping->i_mmap_shared != NULL)
-                       flush_dcache_page(page);
--              /*
--               * Ok, we have the page, and it's up-to-date, so
--               * now we can copy it to user space...
-+              /* Ok, we have the page, and it's up-to-date, so now we can copy
-+               * it to user space...
-                *
-                * The actor routine returns how many bytes were actually used..
-                * NOTE! This may not be the same as how much of a user buffer
-@@ -1309,6 +1581,8 @@ static void do_shmem_file_read(struct fi
-                * pointers and the remaining count).
-                */
-               nr = file_read_actor(desc, page, offset, nr);
-+
-+              /* updating counters */
-               offset += nr;
-               index += offset >> PAGE_CACHE_SHIFT;
-               offset &= ~PAGE_CACHE_MASK;
-@@ -1320,7 +1594,8 @@ static void do_shmem_file_read(struct fi
-       UPDATE_ATIME(inode);
- }
--static ssize_t shmem_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
-+static ssize_t
-+shmem_file_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
- {
-       ssize_t retval;
-@@ -1345,7 +1620,8 @@ static ssize_t shmem_file_read(struct fi
-       return retval;
- }
--static int shmem_statfs(struct super_block *sb, struct statfs *buf)
-+static int
-+shmem_statfs(struct super_block *sb, struct statfs *buf)
- {
-       struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-@@ -1361,22 +1637,62 @@ static int shmem_statfs(struct super_blo
-       return 0;
- }
--/*
-- * Lookup the data. This is trivial - if the dentry didn't already
-- * exist, we know it is negative.
-- */
--static struct dentry * shmem_lookup(struct inode *dir, struct dentry *dentry)
-+static int
-+match_dentry(struct dentry *dentry, const char *name)
-+{
-+      int len = strlen(name);
-+      
-+      if (dentry->d_name.len != len)
-+              return 0;
-+              
-+      if (strncmp(dentry->d_name.name, name, len))
-+              return 0;
-+              
-+      return 1;
-+}
-+
-+static int
-+shmem_iopen_check(struct inode *dir, struct dentry *dentry)
-+{
-+      struct inode *inode;
-+      struct shmem_sb_info *sbinfo = SHMEM_SB(dir->i_sb);
-+
-+      if (dir->i_ino != sbinfo->root_ino ||
-+          !(sbinfo->options & SHMEM_MOUNT_IOPEN) ||
-+          !match_dentry(dentry, "__iopen__"))
-+      {
-+              return 0;
-+      }
-+
-+      if (!(inode = iget(dir->i_sb, SHMEM_IOPEN_INO)))
-+              return 0;
-+              
-+      d_add(dentry, inode);
-+      
-+      spin_lock (&sbinfo->stat_lock);
-+      sbinfo->iopen = dentry;
-+      spin_unlock (&sbinfo->stat_lock);
-+      
-+      dget(dentry);
-+      return 1;
-+}
-+
-+static struct dentry *
-+shmem_lookup(struct inode *dir, struct dentry *dentry)
- {
--      d_add(dentry, NULL);
-+      if (!shmem_iopen_check(dir, dentry))
-+              d_add(dentry, NULL);
-+      
-       return NULL;
- }
- /*
-  * File creation. Allocate an inode, and we're done..
-  */
--static int shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
-+static int
-+shmem_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
- {
--      struct inode * inode = shmem_get_inode(dir->i_sb, mode, dev);
-+      struct inode *inode = shmem_get_inode(dir->i_sb, mode, dev, 0);
-       int error = -ENOSPC;
-       if (inode) {
-@@ -1386,20 +1702,24 @@ static int shmem_mknod(struct inode *dir
-               dget(dentry); /* Extra count - pin the dentry in core */
-               error = 0;
-       }
-+      
-       return error;
- }
--static int shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
-+static int
-+shmem_mkdir(struct inode * dir, struct dentry * dentry, int mode)
- {
-       int error;
-       if ((error = shmem_mknod(dir, dentry, mode | S_IFDIR, 0)))
-               return error;
-+              
-       dir->i_nlink++;
-       return 0;
- }
--static int shmem_create(struct inode *dir, struct dentry *dentry, int mode)
-+static int
-+shmem_create(struct inode *dir, struct dentry *dentry, int mode)
- {
-       return shmem_mknod(dir, dentry, mode | S_IFREG, 0);
- }
-@@ -1407,7 +1727,8 @@ static int shmem_create(struct inode *di
- /*
-  * Link a file..
-  */
--static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
-+static int
-+shmem_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry)
- {
-       struct inode *inode = old_dentry->d_inode;
-@@ -1429,13 +1750,11 @@ static inline int shmem_positive(struct 
- }
- /*
-- * Check that a directory is empty (this works
-- * for regular files too, they'll just always be
-- * considered empty..).
-+ * Check that a directory is empty (this works for regular files too, they'll
-+ * just always be considered empty..).
-  *
-- * Note that an empty directory can still have
-- * children, they just all have to be negative..
-- */
-+ * Note that an empty directory can still have children, they just all have to
-+ * be negative.. */
- static int shmem_empty(struct dentry *dentry)
- {
-       struct list_head *list;
-@@ -1456,18 +1775,22 @@ static int shmem_empty(struct dentry *de
-       return 1;
- }
--static int shmem_unlink(struct inode * dir, struct dentry *dentry)
-+static int
-+shmem_unlink(struct inode *dir, struct dentry *dentry)
- {
-       struct inode *inode = dentry->d_inode;
-       dir->i_size -= BOGO_DIRENT_SIZE;
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       inode->i_nlink--;
--      dput(dentry);   /* Undo the count from "create" - this does all the work */
-+      
-+      /* undo the count from "create" - this does all the work. */
-+      dput(dentry);
-       return 0;
- }
--static int shmem_rmdir(struct inode * dir, struct dentry *dentry)
-+static int
-+shmem_rmdir(struct inode *dir, struct dentry *dentry)
- {
-       if (!shmem_empty(dentry))
-               return -ENOTEMPTY;
-@@ -1477,12 +1800,13 @@ static int shmem_rmdir(struct inode * di
- }
- /*
-- * The VFS layer already does all the dentry stuff for rename,
-- * we just have to decrement the usage count for the target if
-- * it exists so that the VFS layer correctly free's it when it
-- * gets overwritten.
-+ * The VFS layer already does all the dentry stuff for rename, we just have to
-+ * decrement the usage count for the target if it exists so that the VFS layer
-+ * correctly free's it when it gets overwritten.
-  */
--static int shmem_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry)
-+static int
-+shmem_rename(struct inode *old_dir, struct dentry *old_dentry,
-+           struct inode *new_dir, struct dentry *new_dentry)
- {
-       struct inode *inode = old_dentry->d_inode;
-       int they_are_dirs = S_ISDIR(inode->i_mode);
-@@ -1507,19 +1831,20 @@ static int shmem_rename(struct inode * o
-       return 0;
- }
--static int shmem_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
-+static int
-+shmem_symlink(struct inode *dir, struct dentry *dentry,
-+            const char *symname)
- {
-       int len;
--      struct inode *inode;
-       struct page *page;
--      char *kaddr;
--      struct shmem_inode_info * info;
-+      struct inode *inode;
-+      struct shmem_inode_info *info;
-       len = strlen(symname) + 1;
-       if (len > PAGE_CACHE_SIZE)
-               return -ENAMETOOLONG;
--      inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
-+      inode = shmem_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0, 0);
-       if (!inode)
-               return -ENOSPC;
-@@ -1531,7 +1856,7 @@ static int shmem_symlink(struct inode * 
-               inode->i_op = &shmem_symlink_inline_operations;
-       } else {
-               down(&info->sem);
--              page = shmem_getpage_locked(info, inode, 0);
-+              page = shmem_getpage_locked(inode, 0);
-               if (IS_ERR(page)) {
-                       up(&info->sem);
-                       iput(inode);
-@@ -1541,8 +1866,7 @@ static int shmem_symlink(struct inode * 
-               spin_lock (&shmem_ilock);
-               list_add_tail(&info->list, &shmem_inodes);
-               spin_unlock (&shmem_ilock);
--              kaddr = kmap(page);
--              memcpy(kaddr, symname, len);
-+              memcpy(kmap(page), symname, len);
-               kunmap(page);
-               SetPageDirty(page);
-               UnlockPage(page);
-@@ -1556,40 +1880,52 @@ static int shmem_symlink(struct inode * 
-       return 0;
- }
--static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
-+static int
-+shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
- {
--      return vfs_readlink(dentry,buffer,buflen, (const char *)SHMEM_I(dentry->d_inode));
-+      return vfs_readlink(dentry,buffer, buflen,
-+                          (const char *)SHMEM_I(dentry->d_inode));
- }
--static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
-+static int
-+shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
- {
-       return vfs_follow_link(nd, (const char *)SHMEM_I(dentry->d_inode));
- }
--static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
-+static int
-+shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
--      struct page * page;
--      int res = shmem_getpage(dentry->d_inode, 0, &page);
-+      int res;
-+      struct page *page;
-+
-+      page = shmem_getpage_unlocked(dentry->d_inode, 0);
--      if (res)
--              return res;
-+      if (IS_ERR(page))
-+              return PTR_ERR(page);
-       res = vfs_readlink(dentry,buffer,buflen, kmap(page));
-       kunmap(page);
-       page_cache_release(page);
-+      
-       return res;
- }
--static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
-+static int
-+shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
- {
-       struct page * page;
--      int res = shmem_getpage(dentry->d_inode, 0, &page);
--      if (res)
--              return res;
-+      int res;
-+
-+      page = shmem_getpage_unlocked(dentry->d_inode, 0);
-+
-+      if (IS_ERR(page))
-+              return PTR_ERR(page);
-       res = vfs_follow_link(nd, kmap(page));
-       kunmap(page);
-       page_cache_release(page);
-+
-       return res;
- }
-@@ -1610,7 +1946,10 @@ static struct inode_operations shmem_sym
- #endif
- };
--static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long * blocks, unsigned long *inodes)
-+static int
-+shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, 
-+                  unsigned long *blocks, unsigned long *inodes, 
-+                  unsigned long *opts)
- {
-       char *this_char, *value, *rest;
-@@ -1620,11 +1959,6 @@ static int shmem_parse_options(char *opt
-       for ( ; this_char; this_char = strtok(NULL,",")) {
-               if ((value = strchr(this_char,'=')) != NULL) {
-                       *value++ = 0;
--              } else {
--                      printk(KERN_ERR 
--                          "tmpfs: No value for mount option '%s'\n", 
--                          this_char);
--                      return 1;
-               }
-               if (!strcmp(this_char,"size")) {
-@@ -1659,6 +1993,17 @@ static int shmem_parse_options(char *opt
-                       *gid = simple_strtoul(value,&rest,0);
-                       if (*rest)
-                               goto bad_val;
-+              } else if (!strcmp(this_char, "iopen")) {
-+                      *opts |= SHMEM_MOUNT_IOPEN;
-+                      *opts &= ~SHMEM_MOUNT_IOPEN_NOPRIV;
-+              }
-+              else if (!strcmp(this_char, "noiopen")) {
-+                      *opts &= ~SHMEM_MOUNT_IOPEN;
-+                      *opts &= ~SHMEM_MOUNT_IOPEN_NOPRIV;
-+              }
-+              else if (!strcmp (this_char, "iopen_nopriv")) {
-+                      *opts |= SHMEM_MOUNT_IOPEN;
-+                      *opts |= SHMEM_MOUNT_IOPEN_NOPRIV;
-               } else {
-                       printk(KERN_ERR "tmpfs: Bad mount option %s\n",
-                              this_char);
-@@ -1674,14 +2019,19 @@ bad_val:
- }
--static int shmem_remount_fs (struct super_block *sb, int *flags, char *data)
-+static int
-+shmem_remount_fs(struct super_block *sb, int *flags, char *data)
- {
-       struct shmem_sb_info *sbinfo = &sb->u.shmem_sb;
-       unsigned long max_blocks = sbinfo->max_blocks;
-       unsigned long max_inodes = sbinfo->max_inodes;
--      if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, &max_inodes))
-+      if (shmem_parse_options (data, NULL, NULL, NULL, &max_blocks, 
-+                               &max_inodes, &sbinfo->options))
-+      {
-               return -EINVAL;
-+      }
-+              
-       return shmem_set_size(sbinfo, max_blocks, max_inodes);
- }
-@@ -1691,7 +2041,8 @@ int shmem_sync_file(struct file * file, 
- }
- #endif
--static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent)
-+static struct super_block *
-+shmem_read_super(struct super_block * sb, void * data, int silent)
- {
-       struct inode * inode;
-       struct dentry * root;
-@@ -1710,11 +2061,15 @@ static struct super_block *shmem_read_su
-       blocks = inodes = si.totalram / 2;
- #ifdef CONFIG_TMPFS
--      if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, &inodes))
-+      if (shmem_parse_options (data, &mode, &uid, &gid, &blocks, 
-+                               &inodes, &sbinfo->options))
-+      {
-               return NULL;
-+      }
- #endif
-       spin_lock_init (&sbinfo->stat_lock);
-+      sbinfo->iopen = NULL;
-       sbinfo->max_blocks = blocks;
-       sbinfo->free_blocks = blocks;
-       sbinfo->max_inodes = inodes;
-@@ -1724,7 +2079,7 @@ static struct super_block *shmem_read_su
-       sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-       sb->s_magic = TMPFS_MAGIC;
-       sb->s_op = &shmem_ops;
--      inode = shmem_get_inode(sb, S_IFDIR | mode, 0);
-+      inode = shmem_get_inode(sb, S_IFDIR | mode, 0, 1);
-       if (!inode)
-               return NULL;
-@@ -1739,7 +2094,19 @@ static struct super_block *shmem_read_su
-       return sb;
- }
-+void shmem_put_super(struct super_block *sb)
-+{
-+      struct dentry *iopen;
-+      struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
-+      spin_lock(&sbinfo->stat_lock);
-+      iopen = sbinfo->iopen;
-+      sbinfo->iopen = NULL;
-+      spin_unlock(&sbinfo->stat_lock);
-+
-+      if (iopen)
-+              dput(iopen);
-+}
- static struct address_space_operations shmem_aops = {
-       writepage:      shmem_writepage,
-@@ -1790,11 +2157,13 @@ static struct super_operations shmem_ops
-       remount_fs:     shmem_remount_fs,
- #endif
-       delete_inode:   shmem_delete_inode,
--      put_inode:      force_delete,   
-+      read_inode:     shmem_read_inode,
-+      put_inode:      force_delete,
-+      put_super:      shmem_put_super,
- };
- static struct vm_operations_struct shmem_vm_ops = {
--      nopage: shmem_nopage,
-+      nopage:         shmem_nopage,
- };
- #ifdef CONFIG_TMPFS
-@@ -1885,7 +2254,7 @@ struct file *shmem_file_setup(char * nam
-               goto put_dentry;
-       error = -ENOSPC;
--      inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
-+      inode = shmem_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0, 0);
-       if (!inode) 
-               goto close_file;
-@@ -1921,15 +2290,17 @@ int shmem_zero_setup(struct vm_area_stru
-       if (vma->vm_file)
-               fput (vma->vm_file);
-+      
-       vma->vm_file = file;
-       vma->vm_ops = &shmem_vm_ops;
-       return 0;
- }
- EXPORT_SYMBOL(shmem_file_setup);
--EXPORT_SYMBOL(shmem_getpage);
- EXPORT_SYMBOL(shmem_xattr_find);
- EXPORT_SYMBOL(shmem_xattr_set);
- EXPORT_SYMBOL(shmem_xattr_get);
- EXPORT_SYMBOL(shmem_xattr_delete);
- EXPORT_SYMBOL(shmem_xattr_remove);
-+EXPORT_SYMBOL(shmem_getpage_locked);
-+EXPORT_SYMBOL(shmem_getpage_unlocked);
diff --git a/lustre/kernel_patches/patches/linux-2.4.20-tmpfs-xattr.patch b/lustre/kernel_patches/patches/linux-2.4.20-tmpfs-xattr.patch
deleted file mode 100644 (file)
index a807ac7..0000000
+++ /dev/null
@@ -1,543 +0,0 @@
-diff -rupN --exclude='ide*' linux-2.4.20.orig/fs/Config.in linux-2.4.20/fs/Config.in
---- linux-2.4.20.orig/fs/Config.in     2002-11-29 01:53:15.000000000 +0200
-+++ linux-2.4.20/fs/Config.in  2004-02-08 21:37:47.000000000 +0200
-@@ -48,6 +48,9 @@ if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFI
- fi
- tristate 'Compressed ROM file system support' CONFIG_CRAMFS
- bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
-+if [ "$CONFIG_TMPFS" = "y" ]; then
-+   bool '  tmpfs Extended Attributes' CONFIG_TMPFS_XATTR
-+fi
- define_bool CONFIG_RAMFS y
- tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
-diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/mm.h linux-2.4.20/include/linux/mm.h
---- linux-2.4.20.orig/include/linux/mm.h       2002-08-03 03:39:45.000000000 +0300
-+++ linux-2.4.20/include/linux/mm.h    2004-02-10 11:43:10.000000000 +0200
-@@ -468,6 +468,7 @@ extern void clear_page_tables(struct mm_
- extern int fail_writepage(struct page *);
- struct page * shmem_nopage(struct vm_area_struct * vma, unsigned long address, int unused);
- struct file *shmem_file_setup(char * name, loff_t size);
-+int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr);
- extern void shmem_lock(struct file * file, int lock);
- extern int shmem_zero_setup(struct vm_area_struct *);
-diff -rupN --exclude='ide*' linux-2.4.20.orig/include/linux/shmem_fs.h linux-2.4.20/include/linux/shmem_fs.h
---- linux-2.4.20.orig/include/linux/shmem_fs.h 2001-12-21 19:42:03.000000000 +0200
-+++ linux-2.4.20/include/linux/shmem_fs.h      2004-02-10 18:39:17.000000000 +0200
-@@ -3,6 +3,8 @@
- /* inode in-kernel data */
-+#include <linux/config.h>
-+
- #define SHMEM_NR_DIRECT 16
- /*
-@@ -28,6 +30,10 @@ struct shmem_inode_info {
-       unsigned long           swapped;
-       int                     locked;     /* into memory */
-       struct list_head        list;
-+#ifdef CONFIG_TMPFS_XATTR
-+      struct list_head        xattrs;
-+      struct list_head        *xtail;
-+#endif
-       struct inode           *inode;
- };
-@@ -39,6 +45,32 @@ struct shmem_sb_info {
-       spinlock_t    stat_lock;
- };
-+#ifdef CONFIG_TMPFS_XATTR
-+struct shmem_xattr {
-+      u8 namelen;
-+      u16 valuelen;
-+      void *entity;
-+      struct list_head list;
-+};
-+
-+extern struct shmem_xattr *
-+shmem_xattr_find(struct inode *inode, const char *name);
-+
-+extern ssize_t
-+shmem_xattr_set(struct inode *inode, const char *name,
-+              const void *value, u16 valuelen, int flags);
-+              
-+extern ssize_t
-+shmem_xattr_get(struct inode *inode, const char *name,
-+              void *value, size_t valuelen);
-+              
-+extern int
-+shmem_xattr_delete(struct inode *inode, struct shmem_xattr *xattr);
-+
-+extern int
-+shmem_xattr_remove(struct inode *inode, const char *name);
-+#endif
-+
- #define SHMEM_I(inode)  (&inode->u.shmem_i)
- #endif
-diff -rupN --exclude='ide*' linux-2.4.20.orig/mm/shmem.c linux-2.4.20/mm/shmem.c
---- linux-2.4.20.orig/mm/shmem.c       2002-11-29 01:53:15.000000000 +0200
-+++ linux-2.4.20/mm/shmem.c    2004-02-10 18:44:05.000000000 +0200
-@@ -27,6 +27,8 @@
- #include <linux/string.h>
- #include <linux/locks.h>
- #include <linux/smp_lock.h>
-+#include <linux/slab.h>
-+#include <linux/xattr.h>
- #include <asm/uaccess.h>
-@@ -58,6 +60,344 @@ atomic_t shmem_nrpages = ATOMIC_INIT(0);
- static struct page *shmem_getpage_locked(struct shmem_inode_info *, struct inode *, unsigned long);
-+#ifdef CONFIG_TMPFS
-+static struct inode_operations shmem_symlink_inode_operations;
-+static struct inode_operations shmem_symlink_inline_operations;
-+#endif
-+
-+#ifdef CONFIG_TMPFS_XATTR
-+#define xattr_name(xattr)                     \
-+      ((char *)xattr->entity)
-+
-+#define xattr_value(xattr)                            \
-+      ((void *)xattr->entity + xattr->namelen + 1)
-+
-+/* allocates memory for new xattr with name length of @namelen and value size of
-+ * @valuelen. */
-+static struct shmem_xattr *
-+shmem_xattr_alloc(u8 namelen, u16 valuelen)
-+{
-+      u16 size;
-+        struct shmem_xattr *xattr;
-+                                                                                      
-+      size = namelen + 1 + valuelen;
-+
-+        if (!(xattr = kmalloc(sizeof(*xattr), GFP_KERNEL)))
-+                return NULL;
-+
-+      if (!(xattr->entity = kmalloc(size, GFP_KERNEL))) {
-+              kfree(xattr);
-+              return NULL;
-+      }
-+                                                                                      
-+        xattr->namelen = namelen;
-+        xattr->valuelen = valuelen;
-+        return xattr;
-+}
-+
-+/* reallocs passed @xattr with new @value. */
-+static int
-+shmem_xattr_realloc(struct shmem_xattr *xattr, u16 valuelen)
-+{
-+        if (xattr->valuelen != valuelen) {
-+              u16 new_size;
-+                void *entity;
-+
-+              /* allocating new entity. */
-+              new_size = xattr->namelen + 1 + valuelen;
-+                                                                                      
-+              if (!(entity = kmalloc(new_size, GFP_KERNEL)))
-+                        return -ENOMEM;
-+
-+              /* copying old name to new entity.*/
-+              memcpy(entity, xattr->entity, xattr->namelen);
-+              *((char *)(entity + xattr->namelen)) = '\0';
-+
-+              /* finishing the change.*/
-+                kfree(xattr->entity);
-+              xattr->entity = entity;
-+                xattr->valuelen = valuelen;
-+        }
-+
-+        return 0;
-+}
-+
-+/* assigns @name and @value to passed @xattr. */
-+static int
-+shmem_xattr_assign(struct shmem_xattr *xattr,
-+                 const char *name, const void *value)
-+{
-+      if (name) {
-+              if (xattr->namelen != strlen(name))
-+                      return -EINVAL;
-+              
-+              memcpy(xattr->entity, name, xattr->namelen);
-+              *((char *)(xattr->entity + xattr->namelen)) = '\0';
-+      }
-+
-+      if (value) {
-+              memcpy(xattr_value(xattr),
-+                     value, xattr->valuelen);
-+      }
-+
-+        return 0;
-+}
-+
-+/* frees passed @xattr. */
-+static void
-+shmem_xattr_free(struct shmem_xattr *xattr)
-+{
-+        kfree(xattr->entity);
-+        kfree(xattr);
-+}
-+
-+/* lookups passed @name inside @inode's xattr list. */
-+struct shmem_xattr *
-+shmem_xattr_find(struct inode *inode, const char *name)
-+{
-+      u8 namelen;
-+        struct list_head *p;
-+        struct shmem_xattr *xattr;
-+        struct shmem_inode_info *info;
-+
-+        info = SHMEM_I(inode);
-+      namelen = strlen(name);
-+
-+        list_for_each(p, &info->xattrs) {
-+                xattr = list_entry(p, struct shmem_xattr, list);
-+
-+                if (xattr->namelen == namelen &&
-+                    !memcmp(xattr->entity, name, namelen))
-+                {
-+                        return xattr;
-+                }
-+        }
-+
-+        return NULL;
-+}
-+
-+/* allocates new xattr and fills it with passed value, name, etc. */
-+ssize_t
-+shmem_xattr_set(struct inode *inode, const char *name,
-+              const void *value, u16 valuelen, int flags)
-+{
-+      ssize_t error;
-+        struct shmem_xattr *xattr;
-+      struct shmem_inode_info *info;
-+
-+        xattr = shmem_xattr_find(inode, name);
-+
-+        if (xattr) {
-+                if (flags & XATTR_CREATE)
-+                        return -EEXIST;
-+
-+                if ((error = shmem_xattr_realloc(xattr, valuelen)))
-+                        return error;
-+
-+              if ((error = shmem_xattr_assign(xattr, NULL, value)))
-+                      return error;
-+        } else {
-+                info = SHMEM_I(inode);
-+
-+              if (flags & XATTR_REPLACE)
-+                        return -ENODATA;
-+
-+              if (!(xattr = shmem_xattr_alloc(strlen(name), valuelen)))
-+                      return -ENOMEM;
-+
-+              if ((error = shmem_xattr_assign(xattr, name, value)))
-+                      return error;
-+              
-+                list_add(&xattr->list, info->xtail);
-+              info->xtail = &xattr->list;
-+        }
-+      
-+        return 0;
-+}
-+
-+/* fills passed @value by attribute value found by @name. */
-+ssize_t
-+shmem_xattr_get(struct inode *inode, const char *name,
-+              void *value, size_t valuelen)
-+{
-+        struct shmem_xattr *xattr;
-+
-+        if (!(xattr = shmem_xattr_find(inode, name)))
-+                return -ENODATA;
-+
-+        /* handling value size guess request */
-+        if (valuelen == 0 || value == NULL)
-+                return xattr->valuelen;
-+
-+        if (xattr->valuelen > valuelen)
-+                return -ERANGE;
-+
-+        memcpy(value, xattr_value(xattr),
-+             xattr->valuelen);
-+      
-+        return xattr->valuelen;
-+}
-+
-+/* deletes passed @xattr from inode xattr list and frees it. */
-+int
-+shmem_xattr_delete(struct inode *inode, struct shmem_xattr *xattr)
-+{
-+      struct shmem_inode_info *info;
-+
-+      info = SHMEM_I(inode);
-+      
-+      if (&xattr->list == info->xtail)
-+              info->xtail = xattr->list.prev;
-+      
-+      list_del(&xattr->list);
-+      shmem_xattr_free(xattr);
-+
-+      return 0;
-+}
-+
-+/* removes attribute found by passed @name. */
-+int
-+shmem_xattr_remove(struct inode *inode, const char *name)
-+{
-+        struct shmem_xattr *xattr;
-+
-+        if (!(xattr = shmem_xattr_find(inode, name)))
-+                return -ENODATA;
-+
-+      return shmem_xattr_delete(inode, xattr);
-+}
-+
-+static int
-+shmem_xattr_can_read(struct inode *inode, const char *name)
-+{
-+      /* check for inlined symlinks. They store path inside inode info and
-+       * thus, cannot be used for access xattrs. */
-+      if (S_ISLNK(inode->i_mode) &&
-+          inode->i_op == &shmem_symlink_inline_operations)
-+      {
-+                return -EPERM;
-+      }
-+      
-+      return permission(inode, MAY_READ);
-+}
-+                                                                                      
-+static int
-+shmem_xattr_can_write(struct inode *inode, const char *name)
-+{
-+        if (IS_RDONLY(inode))
-+                return -EROFS;
-+                                                                                      
-+        if (IS_IMMUTABLE(inode) || IS_APPEND(inode) ||
-+          S_ISLNK(inode->i_mode))
-+      {
-+                return -EPERM;
-+      }
-+                                                                                      
-+        if ((!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) ||
-+          inode->i_mode & S_ISVTX)
-+      {
-+                return -EPERM;
-+      }
-+                                                                                      
-+        return permission(inode, MAY_WRITE);
-+}
-+
-+/* fills passed @value with data of attribute @name from @dentry->d_inode
-+ * attribute list. */
-+static ssize_t
-+shmem_getxattr(struct dentry *dentry, const char *name,
-+               void *value, size_t valuelen)
-+{
-+        int error;
-+        struct inode *inode = dentry->d_inode;
-+
-+      if (name == NULL)
-+              return -EINVAL;
-+                                                                                      
-+        if ((error = shmem_xattr_can_read(inode, name)))
-+                return error;
-+
-+      return shmem_xattr_get(inode, name,
-+                             value, valuelen);
-+                                                                                      
-+}
-+
-+/* updates attribute with @name inside @dentry->d_inode attributes list (if
-+ * any), or creates new attribute with name @name and value @value and put it to
-+ * inode attributes list.*/
-+static int
-+shmem_setxattr(struct dentry *dentry, const char *name,
-+               void *value, size_t valuelen, int flags)
-+{
-+        int error;
-+        struct inode *inode = dentry->d_inode;
-+                                                                                      
-+      if (name == NULL)
-+              return -EINVAL;
-+      
-+        if ((error = shmem_xattr_can_write(inode, name)))
-+                return error;
-+                                                                                      
-+        if (value == NULL) {
-+                value = "";
-+                valuelen = 0;
-+        }
-+                                                                                      
-+        return shmem_xattr_set(inode, name, value,
-+                             valuelen, flags);
-+}
-+
-+/* removes attribute with passed @name from @dentry->d_inode attributes list. */
-+static int
-+shmem_removexattr(struct dentry *dentry, const char *name)
-+{
-+        int error;
-+        struct inode *inode = dentry->d_inode;
-+                                                                                      
-+      if (name == NULL)
-+              return -EINVAL;
-+
-+        if ((error = shmem_xattr_can_write(inode, name)))
-+                return error;
-+                                                                                      
-+        return shmem_xattr_remove(inode, name);
-+}
-+
-+/* fills passed @data with list of @dentry->d_inode attributes. Returns size of
-+ * actuall data put to @data. */
-+static ssize_t
-+shmem_listxattr(struct dentry *dentry, char *data, size_t buf_size)
-+{
-+        ssize_t size = 0;
-+        struct list_head *p;
-+        struct shmem_xattr *xattr;
-+        struct shmem_inode_info *info;
-+        struct inode *inode = dentry->d_inode;
-+
-+        info = SHMEM_I(inode);
-+
-+        list_for_each(p, &info->xattrs) {
-+                xattr = list_entry(p, struct shmem_xattr, list);
-+                size += xattr->namelen + 1;
-+        }
-+
-+        /* handling data size guess request. */
-+        if (buf_size == 0 || data == NULL)
-+                return size;
-+
-+        if (size > buf_size)
-+                return -ERANGE;
-+
-+        list_for_each(p, &info->xattrs) {
-+                xattr = list_entry(p, struct shmem_xattr, list);
-+                memcpy(data, xattr->entity, xattr->namelen + 1);
-+                data += xattr->namelen + 1;
-+        }
-+
-+        return size;
-+}
-+#endif
-+
- /*
-  * shmem_recalc_inode - recalculate the size of an inode
-  *
-@@ -359,6 +699,11 @@ static void shmem_truncate (struct inode
- static void shmem_delete_inode(struct inode * inode)
- {
-+#ifdef CONFIG_TMPFS_XATTR
-+      struct list_head *tmp, *p;
-+      struct shmem_xattr *xattr;
-+      struct shmem_inode_info * info = SHMEM_I(inode);
-+#endif
-       struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
-       if (inode->i_op->truncate == shmem_truncate) {
-@@ -371,6 +716,12 @@ static void shmem_delete_inode(struct in
-       spin_lock (&sbinfo->stat_lock);
-       sbinfo->free_inodes++;
-       spin_unlock (&sbinfo->stat_lock);
-+#ifdef CONFIG_TMPFS_XATTR
-+        list_for_each_safe(p, tmp, &info->xattrs) {
-+                xattr = list_entry(p, struct shmem_xattr, list);
-+              shmem_xattr_delete(inode, xattr);
-+        }
-+#endif
-       clear_inode(inode);
- }
-@@ -634,7 +985,7 @@ wait_retry:
-       goto repeat;
- }
--static int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
-+int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
- {
-       struct shmem_inode_info *info = SHMEM_I(inode);
-       int error;
-@@ -727,6 +1078,11 @@ struct inode *shmem_get_inode(struct sup
-               info->inode = inode;
-               spin_lock_init (&info->lock);
-               sema_init (&info->sem, 1);
-+
-+#ifdef CONFIG_TMPFS_XATTR
-+              INIT_LIST_HEAD(&info->xattrs);
-+              info->xtail = &info->xattrs;
-+#endif
-               switch (mode & S_IFMT) {
-               default:
-                       init_special_inode(inode, mode, dev);
-@@ -777,10 +1133,6 @@ out:
- }
- #ifdef CONFIG_TMPFS
--
--static struct inode_operations shmem_symlink_inode_operations;
--static struct inode_operations shmem_symlink_inline_operations;
--
- static ssize_t
- shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
- {
-@@ -1250,6 +1602,12 @@ static struct inode_operations shmem_sym
-       truncate:       shmem_truncate,
-       readlink:       shmem_readlink,
-       follow_link:    shmem_follow_link,
-+#ifdef CONFIG_TMPFS_XATTR
-+      setxattr:       shmem_setxattr,
-+      getxattr:       shmem_getxattr,
-+      listxattr:      shmem_listxattr,
-+      removexattr:    shmem_removexattr,
-+#endif
- };
- static int shmem_parse_options(char *options, int *mode, uid_t *uid, gid_t *gid, unsigned long * blocks, unsigned long *inodes)
-@@ -1398,6 +1756,12 @@ static struct file_operations shmem_file
- static struct inode_operations shmem_inode_operations = {
-       truncate:       shmem_truncate,
-+#ifdef CONFIG_TMPFS_XATTR
-+      setxattr:       shmem_setxattr,
-+      getxattr:       shmem_getxattr,
-+      listxattr:      shmem_listxattr,
-+      removexattr:    shmem_removexattr,
-+#endif
- };
- static struct inode_operations shmem_dir_inode_operations = {
-@@ -1411,6 +1775,12 @@ static struct inode_operations shmem_dir
-       rmdir:          shmem_rmdir,
-       mknod:          shmem_mknod,
-       rename:         shmem_rename,
-+#ifdef CONFIG_TMPFS_XATTR
-+      setxattr:       shmem_setxattr,
-+      getxattr:       shmem_getxattr,
-+      listxattr:      shmem_listxattr,
-+      removexattr:    shmem_removexattr,
-+#endif
- #endif
- };
-@@ -1557,3 +1927,9 @@ int shmem_zero_setup(struct vm_area_stru
- }
- EXPORT_SYMBOL(shmem_file_setup);
-+EXPORT_SYMBOL(shmem_getpage);
-+EXPORT_SYMBOL(shmem_xattr_find);
-+EXPORT_SYMBOL(shmem_xattr_set);
-+EXPORT_SYMBOL(shmem_xattr_get);
-+EXPORT_SYMBOL(shmem_xattr_delete);
-+EXPORT_SYMBOL(shmem_xattr_remove);
index ae838ca..d11bec0 100644 (file)
@@ -50,7 +50,5 @@ kernel_text_address-2.4.20-vanilla.patch
 ext3-xattr-ptr-arith-fix.patch
 gfp_memalloc-2.4.22.patch
 procfs-ndynamic-2.4.patch
-linux-2.4.20-tmpfs-xattr.patch
-linux-2.4.20-tmpfs-iopen.patch
 linux-2.4.20-filemap.patch
 ext3-truncate-buffer-head.patch
index 2a09a2e..37cca17 100644 (file)
@@ -1005,6 +1005,11 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                 rc = llog_origin_handle_next_block(req);
                 ldlm_callback_reply(req, rc);
                 RETURN(0);
+        case LLOG_ORIGIN_HANDLE_PREV_BLOCK:
+                OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
+                rc = llog_origin_handle_prev_block(req);
+                ldlm_callback_reply(req, rc);
+                RETURN(0);
         case LLOG_ORIGIN_HANDLE_READ_HEADER:
                 OBD_FAIL_RETURN(OBD_FAIL_OBD_LOGD_NET, 0);
                 rc = llog_origin_handle_read_header(req);
index 7809366..5931326 100644 (file)
  * we need to keep cookies in stripe order, even if some are NULL, so that
  * the right cookies are passed back to the right OSTs at the client side.
  * Unset cookies should be all-zero (which will never occur naturally). */
-static int lov_llog_origin_add(struct llog_ctxt *ctxt,
-                        struct llog_rec_hdr *rec, struct lov_stripe_md *lsm,
-                        struct llog_cookie *logcookies, int numcookies)
+static int lov_llog_origin_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
+                               void *buf, struct llog_cookie *logcookies, 
+                               int numcookies, void *data)
 {
         struct obd_device *obd = ctxt->loc_obd;
         struct lov_obd *lov = &obd->u.lov;
         struct lov_oinfo *loi;
         struct llog_unlink_rec *lur;
+        struct lov_stripe_md *lsm = (struct lov_stripe_md *)data;
         int i, rc = 0;
         ENTRY;
 
@@ -82,7 +83,7 @@ static int lov_llog_origin_add(struct llog_ctxt *ctxt,
                 lur->lur_oid = loi->loi_id;
                 lur->lur_ogen = loi->loi_gr;
                 rc += llog_add(cctxt, &lur->lur_hdr, NULL, logcookies + rc,
-                                numcookies - rc);
+                                numcookies - rc, NULL);
 
         }
         OBD_FREE(lur, sizeof(*lur));
@@ -119,9 +120,11 @@ static int lov_llog_origin_connect(struct llog_ctxt *ctxt, int count,
 }
 
 /* the replicators commit callback */
-static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm,
-                          int count, struct llog_cookie *cookies, int flags)
+static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, int count, 
+                                struct llog_cookie *cookies, int flags,
+                                void *data)
 {
+        struct lov_stripe_md *lsm = (struct lov_stripe_md *)data;
         struct lov_obd *lov;
         struct obd_device *obd = ctxt->loc_obd;
         struct lov_oinfo *loi;
@@ -138,7 +141,7 @@ static int lov_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *ls
                 struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx);
                 int err;
 
-                err = llog_cancel(cctxt, NULL, 1, cookies, flags);
+                err = llog_cancel(cctxt, 1, cookies, flags, NULL);
                 if (err && lov->tgts[loi->loi_ost_idx].active) {
                         CERROR("error: objid "LPX64" subobj "LPX64
                                " on OST idx %d: rc = %d\n", lsm->lsm_object_id,
@@ -159,21 +162,20 @@ static struct llog_operations lov_size_repl_logops = {
         lop_cancel: lov_llog_repl_cancel
 };
 
-
 int lov_llog_init(struct obd_device *obd, struct obd_device *tgt,
                   int count, struct llog_catid *logid)
 {
         struct lov_obd *lov = &obd->u.lov;
         int i, rc = 0;
         ENTRY;
-
-        rc = llog_setup(obd, LLOG_UNLINK_ORIG_CTXT, tgt, 0, NULL,
-                        &lov_unlink_orig_logops);
+        
+        rc = obd_llog_setup(obd, LLOG_UNLINK_ORIG_CTXT, tgt, 0, NULL,
+                            &lov_unlink_orig_logops);
         if (rc)
                 RETURN(rc);
 
-        rc = llog_setup(obd, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL,
-                        &lov_size_repl_logops);
+        rc = obd_llog_setup(obd, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, 
+                            &lov_size_repl_logops);
         if (rc)
                 RETURN(rc);
 
@@ -195,11 +197,11 @@ int lov_llog_finish(struct obd_device *obd, int count)
         int i, rc = 0;
         ENTRY;
         
-        rc = llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT));
+        rc = obd_llog_cleanup(llog_get_context(obd, LLOG_UNLINK_ORIG_CTXT));
         if (rc)
                 RETURN(rc);
 
-        rc = llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT));
+        rc = obd_llog_cleanup(llog_get_context(obd, LLOG_SIZE_REPL_CTXT));
         if (rc)
                 RETURN(rc);
 
index 791e48d..89c76dd 100644 (file)
@@ -1,6 +1,7 @@
-MODULES := lvfs fsfilt_@BACKINGFS@
+MODULES := lvfs fsfilt_@BACKINGFS@ fsfilt_smfs
 
-lvfs-objs := lvfs_common.o lvfs_linux.o fsfilt.o
+lvfs-objs := fsfilt.o lvfs_common.o llog_lvfs.o lvfs_linux.o 
+lvfs-objs += llog.o llog_cat.o lvfs_reint.o lvfs_undo.o
 
 ifeq ($(PATCHLEVEL),6)
 fsfilt_@BACKINGFS@-objs := fsfilt-@BACKINGFS@.o
@@ -9,6 +10,8 @@ $(obj)/fsfilt-%.c: $(obj)/fsfilt_%.c
        ln -s $< $@
 endif
 
+fsfilt_smfs-objs := fsfilt-smfs.o
+
 # for <ext3/xattr.h> on 2.6
 EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LUSTRE@ -I@LUSTRE@/ldiskfs
 
index 81c177a..bc1e6b2 100644 (file)
@@ -1,4 +1,5 @@
 include $(src)/../portals/Kernelenv
 
-obj-y += lvfs.o fsfilt_ext3.o 
-lvfs-objs := fsfilt.o  lvfs_common.o  lvfs_linux.o 
+obj-y += lvfs.o fsfilt_ext3.o fsfilt_smfs.o
+lvfs-objs := fsfilt.o lvfs_common.o llog_lvfs.o lvfs_linux.o 
+lvfs-objs += llog.o llog_cat.o lvfs_reint.o lvfs_undo.o
index 1261554..16a2658 100644 (file)
@@ -5,7 +5,7 @@
 
 if LIBLUSTRE
 noinst_LIBRARIES = liblvfs.a
-liblvfs_a_SOURCES = lvfs_userfs.c
+liblvfs_a_SOURCES = lvfs_userfs.c llog_lvfs.c llog_cat.c llog.c
 liblvfs_a_CFLAGS = $(LLCFLAGS)
 liblvfs_a_CPPFLAGS = $(LLCPPFLAGS)
 
@@ -16,14 +16,17 @@ endif
 
 if MODULES
 
-modulefs_DATA = lvfs$(KMODEXT) fsfilt_$(BACKINGFS)$(KMODEXT)
+modulefs_DATA = lvfs$(KMODEXT) fsfilt_$(BACKINGFS)$(KMODEXT) fsfilt_smfs$(KMODEXT)
 
-sources: fsfilt_$(BACKINGFS).c
+sources: fsfilt_$(BACKINGFS).c fsfilt_smfs.c
        touch sources
 
 fsfilt_extN.c: fsfilt_ext3.c
        sed -e "s/EXT3/EXTN/g" -e "s/ext3/extN/g" $< > $@
 
+fsfilt_smfs.c:
+       $< > $@
+
 ldiskfs_sed_flags = \
        -e "s/dx_hash_info/ext3_dx_hash_info/g" \
        -e "s/dir_private_info/ext3_dir_private_info/g" \
@@ -35,8 +38,9 @@ fsfilt_ldiskfs.c: fsfilt_ext3.c
 
 endif # MODULES
 
-DIST_SOURCES = fsfilt.c fsfilt_ext3.c fsfilt_reiserfs.c lvfs_common.c \
-       lvfs_internal.h lvfs_linux.c lvfs_userfs.c
+DIST_SOURCES = fsfilt.c fsfilt_ext3.c fsfilt_smfs.c fsfilt_reiserfs.c \
+       lvfs_common.c lvfs_internal.h lvfs_linux.c llog.c llog_cat.c \
+       llog_lvfs.c lvfs_reint.c lvfs_undo.c lvfs_userfs.c
 
 MOSTLYCLEANFILES = *.o *.ko *.mod.c
 CLEANFILES = fsfilt-*.c fsfilt_ldiskfs.c fsfilt_extN.c sources
index 5457625..1870988 100644 (file)
 #include <linux/lustre_fsfilt.h>
 #include <linux/obd.h>
 #include <linux/obd_class.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/module.h>
+#include <linux/iobuf.h>
+#endif
 
 static kmem_cache_t *fcb_cache;
 static atomic_t fcb_cache_count = ATOMIC_INIT(0);
@@ -82,6 +86,19 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private,
                 goto journal_start;
         }
 
+        /* XXX BUG 3188 -- must return to one set of opcodes */
+        /* FIXME - cache hook */
+        if (op & 0x20) {
+                nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS;
+                op = op & ~0x20;
+        }
+
+        /* FIXME - kml */
+        if (op & 0x10) {
+                nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS;
+                op = op & ~0x10;
+        }
+
         switch(op) {
         case FSFILT_OP_RMDIR:
         case FSFILT_OP_UNLINK:
@@ -123,8 +140,11 @@ static void *fsfilt_ext3_start(struct inode *inode, int op, void *desc_private,
                 nblocks = (LLOG_CHUNK_SIZE >> inode->i_blkbits) +
                         EXT3_DELETE_TRANS_BLOCKS * logs;
                 break;
+        case FSFILT_OP_NOOP:
+                nblocks += EXT3_INDEX_EXTRA_TRANS_BLOCKS+EXT3_DATA_TRANS_BLOCKS;
+                break;
         default: CERROR("unknown transaction start op %d\n", op);
-                 LBUG();
+                LBUG();
         }
 
         LASSERT(current->journal_info == desc_private);
@@ -350,7 +370,7 @@ static int fsfilt_ext3_commit_wait(struct inode *inode, void *h)
         tid_t tid = (tid_t)(long)h;
 
         CDEBUG(D_INODE, "commit wait: %lu\n", (unsigned long) tid);
-       if (is_journal_aborted(EXT3_JOURNAL(inode)))
+        if (is_journal_aborted(EXT3_JOURNAL(inode)))
                 return -EIO;
 
         log_wait_commit(EXT3_JOURNAL(inode), tid);
@@ -467,6 +487,57 @@ static int fsfilt_ext3_get_md(struct inode *inode, void *lmm, int lmm_size)
         return rc;
 }
 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+static int fsfilt_ext3_send_bio(struct inode *inode, struct bio *bio)
+{
+        submit_bio(WRITE, bio);
+        return 0;
+}
+#else
+static int fsfilt_ext3_send_bio(struct inode *inode, struct kiobuf *bio)
+{
+        int rc, blocks_per_page;
+
+        rc = brw_kiovec(WRITE, 1, &bio, inode->i_dev,
+                        bio->blocks, 1 << inode->i_blkbits);
+
+        blocks_per_page = PAGE_SIZE >> inode->i_blkbits;
+
+        if (rc != (1 << inode->i_blkbits) * bio->nr_pages *
+            blocks_per_page) {
+                CERROR("short write?  expected %d, wrote %d\n",
+                       (1 << inode->i_blkbits) * bio->nr_pages *
+                       blocks_per_page, rc);
+        }
+
+        return rc;
+}
+#endif
+
+/* FIXME-UMKA: This should be used in 2.6.x io code later. */
+static struct page *fsfilt_ext3_getpage(struct inode *inode, long int index)
+{
+        int rc;
+        struct page *page;
+
+        page = grab_cache_page(inode->i_mapping, index);
+        if (page == NULL)
+                return ERR_PTR(-ENOMEM);
+
+        if (PageUptodate(page)) {
+                unlock_page(page);
+                return page;
+        }
+
+        rc = inode->i_mapping->a_ops->readpage(NULL, page);
+        if (rc < 0) {
+                page_cache_release(page);
+                return ERR_PTR(rc);
+        }
+
+        return page;
+}
+
 static ssize_t fsfilt_ext3_readpage(struct file *file, char *buf, size_t count,
                                     loff_t *off)
 {
@@ -533,7 +604,9 @@ static void fsfilt_ext3_cb_func(struct journal_callback *jcb, int error)
         atomic_dec(&fcb_cache_count);
 }
 
-static int fsfilt_ext3_add_journal_cb(struct obd_device *obd, __u64 last_rcvd,
+static int fsfilt_ext3_add_journal_cb(struct obd_device *obd,
+                                      struct super_block *sb,
+                                      __u64 last_rcvd,
                                       void *handle, fsfilt_cb_t cb_func,
                                       void *cb_data)
 {
@@ -752,6 +825,44 @@ static int fsfilt_ext3_setup(struct super_block *sb)
         return 0;
 }
 
+static int fsfilt_ext3_set_xattr(struct inode * inode, void *handle, char *name,
+                                 void *buffer, int buffer_size)
+{
+        int rc = 0;
+
+        lock_kernel();
+
+        rc = ext3_xattr_set_handle(handle, inode, EXT3_XATTR_INDEX_TRUSTED,
+                                   name, buffer, buffer_size, 0);
+        unlock_kernel();
+        if (rc)
+                CERROR("set xattr %s from inode %lu: rc %d\n",
+                       name,  inode->i_ino, rc);
+        return rc;
+}
+
+static int fsfilt_ext3_get_xattr(struct inode *inode, char *name,
+                                 void *buffer, int buffer_size)
+{
+        int rc = 0;
+        lock_kernel();
+
+        rc = ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED,
+                            name, buffer, buffer_size);
+        unlock_kernel();
+
+        if (buffer == NULL)
+                return (rc == -ENODATA) ? 0 : rc;
+        if (rc < 0) {
+                CDEBUG(D_INFO, "error getting EA %s from inode %lu: rc %d\n",
+                       name,  inode->i_ino, rc);
+                memset(buffer, 0, buffer_size);
+                return (rc == -ENODATA) ? 0 : rc;
+        }
+
+        return rc;
+}
+
 /* If fso is NULL, op is FSFILT operation, otherwise op is number of fso
    objects. Logs is number of logfiles to update */
 static int fsfilt_ext3_get_op_len(int op, struct fsfilt_objinfo *fso, int logs)
@@ -804,6 +915,10 @@ static struct fsfilt_operations fsfilt_ext3_ops = {
         .fs_write_record        = fsfilt_ext3_write_record,
         .fs_read_record         = fsfilt_ext3_read_record,
         .fs_setup               = fsfilt_ext3_setup,
+        .fs_getpage             = fsfilt_ext3_getpage,
+        .fs_send_bio            = fsfilt_ext3_send_bio,
+        .fs_set_xattr           = fsfilt_ext3_set_xattr,
+        .fs_get_xattr           = fsfilt_ext3_get_xattr,
         .fs_get_op_len          = fsfilt_ext3_get_op_len,
 };
 
@@ -811,7 +926,6 @@ static int __init fsfilt_ext3_init(void)
 {
         int rc;
 
-        //rc = ext3_xattr_register();
         fcb_cache = kmem_cache_create("fsfilt_ext3_fcb",
                                       sizeof(struct fsfilt_cb_data), 0,
                                       0, NULL, NULL);
@@ -839,8 +953,6 @@ static void __exit fsfilt_ext3_exit(void)
                 CERROR("can't free fsfilt callback cache: count %d, rc = %d\n",
                        atomic_read(&fcb_cache_count), rc);
         }
-
-        //rc = ext3_xattr_unregister();
 }
 
 module_init(fsfilt_ext3_init);
diff --git a/lustre/lvfs/fsfilt_smfs.c b/lustre/lvfs/fsfilt_smfs.c
new file mode 100644 (file)
index 0000000..7dfee3c
--- /dev/null
@@ -0,0 +1,697 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  lustre/lib/fsfilt_smfs.c
+ *  Lustre filesystem abstraction routines
+ *
+ *  Copyright (C) 2002, 2003 Cluster File Systems, Inc.
+ *   Author: Wang Di <wangdi@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/fs.h>
+#include <linux/jbd.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/version.h>
+#include <linux/kp30.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_smfs.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/module.h>
+
+static void *fsfilt_smfs_start(struct inode *inode, int op, 
+                               void *desc_private, int logs)
+{
+       void *handle;
+        struct inode *cache_inode = I2CI(inode);
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+
+        if (cache_fsfilt == NULL)
+                return NULL;
+
+        if (!cache_fsfilt->fs_start)
+               return ERR_PTR(-ENOSYS);
+               
+        handle = cache_fsfilt->fs_start(cache_inode, op, 
+                                       desc_private, logs);
+        return handle;
+}
+
+static void *fsfilt_smfs_brw_start(int objcount, struct fsfilt_objinfo *fso,
+                                   int niocount, struct niobuf_local *nb,
+                                   void *desc_private, int logs)
+{
+       struct fsfilt_operations *cache_fsfilt;
+        struct dentry *cache_dentry = NULL;
+        struct inode *cache_inode = NULL;
+        struct fsfilt_objinfo cache_fso;
+        void   *rc = NULL;
+        
+        ENTRY; 
+        cache_fsfilt = I2FOPS(fso->fso_dentry->d_inode);
+        if (cache_fsfilt == NULL) 
+                return NULL;
+
+        cache_inode = I2CI(fso->fso_dentry->d_inode);
+       cache_dentry = pre_smfs_dentry(NULL, cache_inode, fso->fso_dentry);     
+    
+        if (!cache_dentry)
+                GOTO(exit, rc = ERR_PTR(-ENOMEM));
+    
+        cache_fso.fso_dentry = cache_dentry; 
+        cache_fso.fso_bufcnt = fso->fso_bufcnt;
+        if (!cache_fsfilt->fs_brw_start)
+               return ERR_PTR(-ENOSYS);
+               
+        rc = (cache_fsfilt->fs_brw_start(objcount, &cache_fso, 
+                                        niocount, nb, desc_private,
+                                         logs));
+exit:
+        post_smfs_dentry(cache_dentry); 
+        return rc; 
+}
+
+static int fsfilt_smfs_commit(struct inode *inode, void *h, 
+                              int force_sync)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;      
+        cache_inode = I2CI(inode);
+        if (cache_fsfilt == NULL)
+                RETURN(rc);
+       
+        if (!cache_fsfilt->fs_commit) 
+               RETURN(-ENOSYS);
+        
+       rc = cache_fsfilt->fs_commit(cache_inode, h, force_sync);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_commit_async(struct inode *inode, void *h,
+                                    void **wait_handle)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;      
+        cache_inode = I2CI(inode);
+        if (cache_fsfilt == NULL)
+               RETURN(-EINVAL);
+       
+        if (!cache_fsfilt->fs_commit_async)
+               RETURN(-ENOSYS);
+               
+        rc = cache_fsfilt->fs_commit_async(cache_inode, h, wait_handle);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_commit_wait(struct inode *inode, void *h)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;      
+        cache_inode = I2CI(inode);
+        if (cache_fsfilt == NULL)
+                RETURN(-EINVAL);
+       
+        if (!cache_fsfilt->fs_commit_wait) 
+               RETURN(-ENOSYS);
+        
+       rc = cache_fsfilt->fs_commit_wait(cache_inode, h);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_setattr(struct dentry *dentry, void *handle,
+                               struct iattr *iattr, int do_trunc)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(dentry->d_inode);
+        struct dentry *cache_dentry = NULL;
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;
+        if (!cache_fsfilt) 
+                RETURN(rc);
+        cache_inode = I2CI(dentry->d_inode); 
+       
+       cache_dentry = pre_smfs_dentry(NULL, cache_inode, dentry);      
+        if (!cache_dentry)
+                GOTO(exit, rc = -ENOMEM);
+  
+        pre_smfs_inode(dentry->d_inode, cache_inode);
+        
+        if (!cache_fsfilt->fs_setattr)
+               RETURN(-ENOSYS);
+               
+       rc = cache_fsfilt->fs_setattr(cache_dentry, handle, 
+                                      iattr, do_trunc);
+        
+        post_smfs_inode(dentry->d_inode, cache_inode);
+       
+exit:
+        post_smfs_dentry(cache_dentry);
+        RETURN(rc);                    
+}
+
+static int fsfilt_smfs_iocontrol(struct inode *inode, struct file *file,
+                                 unsigned int cmd, unsigned long arg)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+       struct smfs_file_info *sfi = NULL;
+        int    rc = -EIO;                                                                                                                                                                                                     
+        ENTRY;
+                                                                                                                                                                                                     
+        if (!cache_fsfilt) 
+                RETURN(rc);
+        
+        cache_inode = I2CI(inode);
+       
+        if (!cache_inode)
+                RETURN(rc);
+
+       if (file != NULL) {
+               sfi = F2SMFI(file);
+               
+               if (sfi->magic != SMFS_FILE_MAGIC) 
+                       BUG();
+       } else {
+               sfi = NULL;
+       }
+        
+        if (!cache_fsfilt->fs_iocontrol)
+               RETURN(-ENOSYS);
+    
+       if (sfi) {
+               rc = cache_fsfilt->fs_iocontrol(cache_inode,
+                                               sfi->c_file, 
+                                               cmd, arg);
+       } else {
+               rc = cache_fsfilt->fs_iocontrol(cache_inode,
+                                               NULL, cmd, arg);
+       }
+       
+       /* FIXME-UMKA: Should this be in duplicate_inode()? */
+       if (rc == 0 && cmd == EXT3_IOC_SETFLAGS)
+               inode->i_flags = cache_inode->i_flags;
+               
+       post_smfs_inode(inode, cache_inode); 
+
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
+                              void *lmm, int lmm_size)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;
+  
+        if (!cache_fsfilt) 
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(inode);
+       
+        if (!cache_inode)
+                RETURN(-ENOENT);
+       
+        pre_smfs_inode(inode, cache_inode); 
+        
+        if (!cache_fsfilt->fs_set_md)
+               RETURN(-ENOSYS);
+               
+       down(&cache_inode->i_sem);
+               
+        rc = cache_fsfilt->fs_set_md(cache_inode, handle,
+                                     lmm, lmm_size); 
+                                    
+       up(&cache_inode->i_sem);
+       
+        post_smfs_inode(inode, cache_inode); 
+        
+        RETURN(rc); 
+}
+
+/* Must be called with i_sem held */
+static int fsfilt_smfs_get_md(struct inode *inode, void *lmm, int lmm_size)
+{
+       struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;
+  
+        if (!cache_fsfilt) 
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(inode);
+       
+        if (!cache_inode)
+                RETURN(-ENOENT);
+       
+        pre_smfs_inode(inode, cache_inode); 
+        
+        if (!cache_fsfilt->fs_get_md)
+               RETURN(-ENOSYS);
+               
+       down(&cache_inode->i_sem);
+       
+       rc = cache_fsfilt->fs_get_md(cache_inode, lmm, 
+                                    lmm_size); 
+                                    
+       up(&cache_inode->i_sem);
+        
+        post_smfs_inode(inode, cache_inode); 
+       
+        RETURN(rc); 
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
+static int fsfilt_smfs_send_bio(struct inode *inode, 
+                               struct bio *bio)
+#else
+static int fsfilt_smfs_send_bio(struct inode *inode, 
+                               struct kiobuf *bio)
+#endif
+{
+        struct inode *cache_inode;
+       struct fsfilt_operations *cache_fsfilt;
+       
+        cache_fsfilt = I2FOPS(inode);
+        if (!cache_fsfilt) 
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(-EINVAL);
+        
+       if (!cache_fsfilt->fs_send_bio)
+               RETURN(-ENOSYS);
+               
+       return cache_fsfilt->fs_send_bio(cache_inode, bio);
+}
+
+static struct page *
+fsfilt_smfs_getpage(struct inode *inode, long int index)
+{
+       struct  fsfilt_operations *cache_fsfilt;
+        struct  inode *cache_inode;
+
+        cache_fsfilt = I2FOPS(inode);
+        if (!cache_fsfilt) 
+                RETURN(ERR_PTR(-EINVAL));
+        
+        cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(ERR_PTR(-EINVAL));
+        
+       if (!cache_fsfilt->fs_getpage)
+               RETURN(ERR_PTR(-ENOSYS));
+       
+        return cache_fsfilt->fs_getpage(cache_inode, index);
+}
+
+static ssize_t fsfilt_smfs_readpage(struct file *file, char *buf,
+                                    size_t count, loff_t *off)
+{
+       struct fsfilt_operations *cache_fsfilt;
+       struct smfs_file_info *sfi; 
+        struct inode *cache_inode;
+        loff_t tmp_ppos;
+        loff_t *cache_ppos;
+        ssize_t rc = -EIO;
+
+        ENTRY;
+
+        cache_fsfilt = I2FOPS(file->f_dentry->d_inode);
+        if (!cache_fsfilt) 
+                RETURN(rc);
+        
+        cache_inode = I2CI(file->f_dentry->d_inode);
+        if (!cache_inode)
+                RETURN(rc);
+
+       sfi = F2SMFI(file);
+       if (sfi->magic != SMFS_FILE_MAGIC)
+                BUG();
+        
+        if (off != &(file->f_pos)) {
+                cache_ppos = &tmp_ppos;
+        } else {
+                cache_ppos = &sfi->c_file->f_pos;
+        }
+        *cache_ppos = *off;
+        
+        pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        
+        if (cache_fsfilt->fs_readpage) 
+                rc = cache_fsfilt->fs_readpage(sfi->c_file, buf,
+                                               count, cache_ppos);
+        
+        *off = *cache_ppos;
+        post_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        duplicate_file(file, sfi->c_file);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_add_journal_cb(struct obd_device *obd,
+                                      struct super_block *sb,
+                                      __u64 last_rcvd, void *handle,
+                                      fsfilt_cb_t cb_func,
+                                      void *cb_data)
+{
+        struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
+        struct super_block *csb = S2CSB(sb);
+        int rc = -EIO;
+
+        if (!cache_fsfilt) 
+                 RETURN(rc);
+        if (cache_fsfilt->fs_add_journal_cb)
+                rc = cache_fsfilt->fs_add_journal_cb(obd, csb, last_rcvd,
+                                                     handle, cb_func, cb_data);
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_statfs(struct super_block *sb, struct obd_statfs *osfs)
+{
+       struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
+        struct super_block *csb = S2CSB(sb);
+        int rc = -EIO;
+
+        if (!cache_fsfilt)
+                RETURN(rc);
+        
+        if (!cache_fsfilt->fs_statfs)
+               RETURN(-ENOSYS);
+               
+        rc = cache_fsfilt->fs_statfs(csb, osfs);
+        duplicate_sb(csb, sb);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_sync(struct super_block *sb)
+{
+       struct fsfilt_operations *cache_fsfilt = S2SMI(sb)->sm_cache_fsfilt;
+        struct super_block *csb = S2CSB(sb);
+        int    rc = -EIO;
+        if(!cache_fsfilt)
+                RETURN(-EINVAL);
+        
+        if (!cache_fsfilt->fs_sync)
+               RETURN(-ENOSYS);
+        
+       rc = cache_fsfilt->fs_sync(csb);
+        
+        RETURN(rc); 
+}
+
+int fsfilt_smfs_map_inode_page(struct inode *inode, struct page *page,
+                               unsigned long *blocks, int *created, int create)
+{
+       struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct  inode *cache_inode = NULL;
+        int     rc = -EIO;
+         
+        if (!cache_fsfilt)
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(inode);
+       
+        if (!cache_inode)
+                RETURN(rc);
+
+        if (!cache_fsfilt->fs_map_inode_page) 
+               RETURN(-ENOSYS);
+       
+       down(&cache_inode->i_sem);
+        rc = cache_fsfilt->fs_map_inode_page(cache_inode, page, 
+                                             blocks, created, create);
+       up(&cache_inode->i_sem);
+       
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_prep_san_write(struct inode *inode, long *blocks,
+                                      int nblocks, loff_t newsize)
+{
+       struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct  inode *cache_inode = NULL;
+        int     rc = -EIO;
+         
+        if (!cache_fsfilt)
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(inode);
+       
+        if (!cache_inode)
+                RETURN(-EINVAL);
+
+        if (!cache_fsfilt->fs_prep_san_write)
+               RETURN(-ENOSYS);
+        
+       down(&cache_inode->i_sem);
+       rc = cache_fsfilt->fs_prep_san_write(cache_inode, blocks, 
+                                             nblocks, newsize);
+       up(&cache_inode->i_sem);
+        
+       RETURN(rc);
+}
+
+static int fsfilt_smfs_read_record(struct file * file, void *buf,
+                                   int size, loff_t *offs)
+{
+       struct  fsfilt_operations *cache_fsfilt;
+        struct  inode *cache_inode;
+       struct  smfs_file_info *sfi; 
+        loff_t  tmp_ppos;
+        loff_t  *cache_ppos;
+        ssize_t rc;
+        
+        ENTRY;
+        cache_fsfilt = I2FOPS(file->f_dentry->d_inode); 
+        if (!cache_fsfilt) 
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(file->f_dentry->d_inode);
+        
+        if (!cache_inode)
+                RETURN(-EINVAL);
+
+       sfi = F2SMFI(file);
+       if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+        
+        if (offs != &(file->f_pos)) {
+                cache_ppos = &tmp_ppos;
+        } else {
+                cache_ppos = &sfi->c_file->f_pos;
+        }
+        *cache_ppos = *offs;
+
+        pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
+
+        if (!cache_fsfilt->fs_read_record)
+               RETURN(-ENOSYS);
+               
+        rc = cache_fsfilt->fs_read_record(sfi->c_file, buf, 
+                                         size, cache_ppos);
+        
+        *offs = *cache_ppos;
+        post_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        duplicate_file(file, sfi->c_file); 
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_write_record(struct file *file, void *buf, int bufsize,
+                                    loff_t *offs, int force_sync)
+{
+       struct  fsfilt_operations *cache_fsfilt;
+        struct  inode *cache_inode;
+       struct  smfs_file_info *sfi; 
+        loff_t  tmp_ppos;
+        loff_t  *cache_ppos;
+        ssize_t rc = -EIO;
+
+        ENTRY;
+
+        cache_fsfilt = I2FOPS(file->f_dentry->d_inode); 
+        if (!cache_fsfilt) 
+                RETURN(-EINVAL);
+        
+        cache_inode = I2CI(file->f_dentry->d_inode);
+        
+        if (!cache_inode)
+                RETURN(-EINVAL);
+
+       sfi = F2SMFI(file);
+       if (sfi->magic != SMFS_FILE_MAGIC) BUG();
+        
+        if (offs != &(file->f_pos)) {
+                cache_ppos = &tmp_ppos;
+        } else {
+                cache_ppos = &sfi->c_file->f_pos;
+        }
+        *cache_ppos = *offs;
+       
+        pre_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        
+        if (!cache_fsfilt->fs_write_record)
+               RETURN(-ENOSYS);
+        
+       rc = cache_fsfilt->fs_write_record(sfi->c_file, buf, 
+                                           bufsize, cache_ppos, force_sync);
+        *offs = *cache_ppos; 
+        post_smfs_inode(file->f_dentry->d_inode, cache_inode);
+        duplicate_file(file, sfi->c_file); 
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_setup(struct super_block *sb)
+{
+       struct smfs_super_info *smfs_info = S2SMI(sb);
+        struct fsfilt_operations *cache_fsfilt;
+        struct super_block *csb;
+        int rc = 0;
+
+       /* It should be initialized olready by smfs_read_super(). */
+       if (!(cache_fsfilt = smfs_info->sm_cache_fsfilt))
+               cache_fsfilt = fsfilt_get_ops(smfs_info->cache_fs_type);
+
+        if (!cache_fsfilt)
+                RETURN(-ENOENT);
+        
+        csb = S2CSB(sb);
+
+        if (cache_fsfilt->fs_setup) 
+                rc = cache_fsfilt->fs_setup(csb);
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_set_xattr(struct inode *inode, void *handle,
+                                 char *name,  void *buffer, 
+                                 int buffer_size)
+{
+        struct  fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct  inode *cache_inode = NULL;
+        int     rc = -EIO;
+         
+        if (!cache_fsfilt)
+                RETURN(rc);
+        
+        cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(rc);
+        
+        pre_smfs_inode(inode, cache_inode); 
+       
+        if (cache_fsfilt->fs_set_xattr) 
+                rc = cache_fsfilt->fs_set_xattr(cache_inode, handle, name, 
+                                                buffer, buffer_size);
+        post_smfs_inode(inode, cache_inode); 
+        
+        RETURN(rc);
+}
+
+static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
+                                 void *buffer, int buffer_size)
+{
+        struct fsfilt_operations *cache_fsfilt = I2FOPS(inode);
+        struct inode *cache_inode = NULL;
+        int    rc = -EIO;
+
+         if (!cache_fsfilt)
+                RETURN(rc);
+        
+        cache_inode = I2CI(inode);
+        if (!cache_inode)
+                RETURN(rc);
+        
+        pre_smfs_inode(inode, cache_inode); 
+       
+        if (cache_fsfilt->fs_get_xattr) 
+                rc = cache_fsfilt->fs_get_xattr(cache_inode, name, 
+                                                buffer, buffer_size);
+        post_smfs_inode(inode, cache_inode); 
+        
+        RETURN(rc);
+}
+
+static struct fsfilt_operations fsfilt_smfs_ops = {
+        .fs_type                = "smfs",
+        .fs_owner               = THIS_MODULE,
+        .fs_start               = fsfilt_smfs_start,
+        .fs_brw_start           = fsfilt_smfs_brw_start,
+        .fs_commit              = fsfilt_smfs_commit,
+        .fs_commit_async        = fsfilt_smfs_commit_async,
+        .fs_commit_wait         = fsfilt_smfs_commit_wait,
+        .fs_setattr             = fsfilt_smfs_setattr,
+        .fs_iocontrol           = fsfilt_smfs_iocontrol,
+        .fs_set_md              = fsfilt_smfs_set_md,
+        .fs_get_md              = fsfilt_smfs_get_md,
+        .fs_readpage            = fsfilt_smfs_readpage,
+        .fs_getpage             = fsfilt_smfs_getpage,
+        .fs_add_journal_cb      = fsfilt_smfs_add_journal_cb,
+        .fs_statfs              = fsfilt_smfs_statfs,
+        .fs_sync                = fsfilt_smfs_sync,
+        .fs_map_inode_page      = fsfilt_smfs_map_inode_page,
+        .fs_prep_san_write      = fsfilt_smfs_prep_san_write,
+        .fs_write_record        = fsfilt_smfs_write_record,
+        .fs_read_record         = fsfilt_smfs_read_record,
+        .fs_setup               = fsfilt_smfs_setup,
+        .fs_send_bio            = fsfilt_smfs_send_bio,
+        .fs_set_xattr           = fsfilt_smfs_set_xattr,
+        .fs_get_xattr           = fsfilt_smfs_get_xattr,
+        
+        /* FIXME-UMKA: probably fsfilt_smfs_get_op_len() should be put here
+         * too. */
+};
+
+static int __init fsfilt_smfs_init(void)
+{
+        int rc;
+        
+        rc = fsfilt_register_ops(&fsfilt_smfs_ops);
+        return rc;
+}
+
+static void __exit fsfilt_smfs_exit(void)
+{
+        fsfilt_unregister_ops(&fsfilt_smfs_ops);
+}
+
+module_init(fsfilt_smfs_init);
+module_exit(fsfilt_smfs_exit);
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre SMFS Filesystem Helper v0.1");
+MODULE_LICENSE("GPL");
similarity index 65%
rename from lustre/obdclass/llog.c
rename to lustre/lvfs/llog.c
index 0ad595f..12da23b 100644 (file)
@@ -38,9 +38,7 @@
 #include <liblustre.h>
 #endif
 
-#include <linux/obd_class.h>
 #include <linux/lustre_log.h>
-#include <portals/list.h>
 
 /* Allocate a new log or catalog handle */
 struct llog_handle *llog_alloc_handle(void)
@@ -58,7 +56,6 @@ struct llog_handle *llog_alloc_handle(void)
 }
 EXPORT_SYMBOL(llog_alloc_handle);
 
-
 void llog_free_handle(struct llog_handle *loghandle)
 {
         if (!loghandle)
@@ -66,9 +63,9 @@ void llog_free_handle(struct llog_handle *loghandle)
 
         if (!loghandle->lgh_hdr)
                 goto out;
-        if (loghandle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN)
+        if (le32_to_cpu(loghandle->lgh_hdr->llh_flags) & LLOG_F_IS_PLAIN)
                 list_del_init(&loghandle->u.phd.phd_entry);
-        if (loghandle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
+        if (le32_to_cpu(loghandle->lgh_hdr->llh_flags) & LLOG_F_IS_CAT)
                 LASSERT(list_empty(&loghandle->u.chd.chd_head));
         OBD_FREE(loghandle->lgh_hdr, LLOG_CHUNK_SIZE);
 
@@ -97,10 +94,10 @@ int llog_cancel_rec(struct llog_handle *loghandle, int index)
                 RETURN(-EINVAL);
         }
 
-        llh->llh_count--;
+        llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) - 1);
 
-        if ((llh->llh_flags & LLOG_F_ZAP_WHEN_EMPTY) &&
-            (llh->llh_count == 1) &&
+        if ((le32_to_cpu(llh->llh_flags) & LLOG_F_ZAP_WHEN_EMPTY) &&
+            (le32_to_cpu(llh->llh_count) == 1) &&
             (loghandle->lgh_last_idx == (LLOG_BITMAP_BYTES * 8) - 1)) {
                 rc = llog_destroy(loghandle);
                 if (rc)
@@ -131,10 +128,10 @@ int llog_init_handle(struct llog_handle *handle, int flags,
                 RETURN(-ENOMEM);
         handle->lgh_hdr = llh;
         /* first assign flags to use llog_client_ops */
-        llh->llh_flags = flags;
+        llh->llh_flags = cpu_to_le32(flags);
         rc = llog_read_header(handle);
         if (rc == 0) {
-                flags = llh->llh_flags;
+                flags = le32_to_cpu(llh->llh_flags);
                 if (uuid)
                         LASSERT(obd_uuid_equals(uuid, &llh->llh_tgtuuid));
                 GOTO(out, rc);
@@ -146,20 +143,21 @@ int llog_init_handle(struct llog_handle *handle, int flags,
         rc = 0;
 
         handle->lgh_last_idx = 0; /* header is record with index 0 */
-        llh->llh_count = 1;         /* for the header record */
-        llh->llh_hdr.lrh_type = LLOG_HDR_MAGIC;
-        llh->llh_hdr.lrh_len = llh->llh_tail.lrt_len = LLOG_CHUNK_SIZE;
+        llh->llh_count = cpu_to_le32(1);         /* for the header record */
+        llh->llh_hdr.lrh_type = cpu_to_le32(LLOG_HDR_MAGIC);
+        llh->llh_hdr.lrh_len = llh->llh_tail.lrt_len =
+                cpu_to_le32(LLOG_CHUNK_SIZE);
         llh->llh_hdr.lrh_index = llh->llh_tail.lrt_index = 0;
-        llh->llh_timestamp = LTIME_S(CURRENT_TIME);
+        llh->llh_timestamp = cpu_to_le64(LTIME_S(CURRENT_TIME));
         if (uuid)
                 memcpy(&llh->llh_tgtuuid, uuid, sizeof(llh->llh_tgtuuid));
-        llh->llh_bitmap_offset = offsetof(typeof(*llh),llh_bitmap);
+        llh->llh_bitmap_offset = cpu_to_le32(offsetof(typeof(*llh),llh_bitmap));
         ext2_set_bit(0, llh->llh_bitmap);
 
 out:
         if (flags & LLOG_F_IS_CAT) {
                 INIT_LIST_HEAD(&handle->u.chd.chd_head);
-                llh->llh_size = sizeof(struct llog_logid_rec);
+                llh->llh_size = cpu_to_le32(sizeof(struct llog_logid_rec));
         }
         else if (flags & LLOG_F_IS_PLAIN)
                 INIT_LIST_HEAD(&handle->u.phd.phd_entry);
@@ -234,12 +232,11 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb,
                         GOTO(out, rc);
 
                 rec = buf;
-                idx = rec->lrh_index;
+                idx = le32_to_cpu(rec->lrh_index);
                 if (idx < index)
                         CDEBUG(D_HA, "index %u : idx %u\n", index, idx);
                 while (idx < index) {
-                        rec = (struct llog_rec_hdr *)
-                                ((char *)rec + rec->lrh_len);
+                        rec = ((void *)rec + le32_to_cpu(rec->lrh_len));
                         idx ++;
                 }
 
@@ -266,8 +263,7 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb,
                         ++index;
                         if (index > last_index)
                                 GOTO(out, rc = 0);
-                        rec = (struct llog_rec_hdr *)
-                                ((char *)rec + rec->lrh_len);
+                        rec = ((void *)rec + le32_to_cpu(rec->lrh_len));
                 }
         }
 
@@ -277,3 +273,86 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb,
         RETURN(rc);
 }
 EXPORT_SYMBOL(llog_process);
+
+int llog_reverse_process(struct llog_handle *loghandle, llog_cb_t cb,
+                         void *data, void *catdata)
+{
+        struct llog_log_hdr *llh = loghandle->lgh_hdr;
+        struct llog_process_cat_data *cd = catdata;
+        void *buf;
+        int rc = 0, first_index = 1, index, idx;
+        struct llog_rec_tail *tail;
+        ENTRY;
+
+        OBD_ALLOC(buf, LLOG_CHUNK_SIZE);
+        if (!buf)
+                RETURN(-ENOMEM);
+
+        if (cd != NULL)
+                first_index = cd->first_idx + 1;
+        if (cd != NULL && cd->last_idx)
+                index = cd->last_idx;
+        else
+                index = LLOG_BITMAP_BYTES * 8 - 1;
+
+        while (rc == 0) {
+                struct llog_rec_hdr *rec;
+
+                /* skip records not set in bitmap */
+                while (index >= first_index &&
+                       !ext2_test_bit(index, llh->llh_bitmap))
+                        --index;
+
+                LASSERT(index >= first_index - 1);
+                if (index == first_index - 1)
+                        break;
+
+                /* get the buf with our target record; avoid old garbage */
+                memset(buf, 0, LLOG_CHUNK_SIZE);
+                rc = llog_prev_block(loghandle, index, buf, LLOG_CHUNK_SIZE);
+                if (rc)
+                        GOTO(out, rc);
+
+                rec = buf;
+                idx = le32_to_cpu(rec->lrh_index);
+                if (idx < index)
+                        CDEBUG(D_HA, "index %u : idx %u\n", index, idx);
+                while (idx < index) {
+                        rec = ((void *)rec + le32_to_cpu(rec->lrh_len));
+                        idx ++;
+                }
+
+                /* process records in buffer, starting where we found one */
+                while ((void *)rec >= buf) {
+                        if (rec->lrh_index == 0)
+                                GOTO(out, 0); /* no more records */
+
+                        /* if set, process the callback on this record */
+                        if (ext2_test_bit(index, llh->llh_bitmap)) {
+                                rc = cb(loghandle, rec, data);
+                                if (rc == LLOG_PROC_BREAK) {
+                                        CWARN("recovery from log: "LPX64":%x"
+                                              " stopped\n",
+                                              loghandle->lgh_id.lgl_oid,
+                                              loghandle->lgh_id.lgl_ogen);
+                                        GOTO(out, rc);
+                                }
+                                if (rc)
+                                        GOTO(out, rc);
+                        }
+
+                        /* previous record, still in buffer? */
+                        --index;
+                        if (index < first_index)
+                                GOTO(out, rc = 0);
+                        tail = (void *)rec - sizeof(struct llog_rec_tail);
+                        rec = ((void *)rec - le32_to_cpu(tail->lrt_len));
+                }
+        }
+
+ out:
+        if (buf)
+                OBD_FREE(buf, LLOG_CHUNK_SIZE);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_reverse_process);
similarity index 57%
rename from lustre/obdclass/llog_cat.c
rename to lustre/lvfs/llog_cat.c
index d4fa370..67a6f80 100644 (file)
@@ -38,7 +38,6 @@
 #include <liblustre.h>
 #endif
 
-#include <linux/obd_class.h>
 #include <linux/lustre_log.h>
 #include <portals/list.h>
 
@@ -51,7 +50,7 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
 {
         struct llog_handle *loghandle;
         struct llog_log_hdr *llh;
-        struct llog_logid_rec rec = { { 0 }, };
+        struct llog_logid_rec rec;
         int rc, index, bitmap_size;
         ENTRY;
 
@@ -60,8 +59,8 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
 
         index = (cathandle->lgh_last_idx + 1) % bitmap_size;
 
-        /* maximum number of available slots in catlog is bitmap_size - 2 */
-        if (llh->llh_cat_idx == index) {
+        /* maximum number of available slots in catalog is bitmap_size - 2 */
+        if (llh->llh_cat_idx == cpu_to_le32(index)) {
                 CERROR("no free catalog slots for log...\n");
                 RETURN(ERR_PTR(-ENOSPC));
         } else {
@@ -73,8 +72,8 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
                         LBUG(); /* should never happen */
                 }
                 cathandle->lgh_last_idx = index;
-                llh->llh_count++;
-                llh->llh_tail.lrt_index = index;
+                llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) + 1);
+                llh->llh_tail.lrt_index = cpu_to_le32(index);
         }
 
         rc = llog_create(cathandle->lgh_ctxt, &loghandle, NULL, NULL);
@@ -91,12 +90,12 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
                LPX64"\n", loghandle->lgh_id.lgl_oid, loghandle->lgh_id.lgl_ogen,
                index, cathandle->lgh_id.lgl_oid);
         /* build the record for this log in the catalog */
-        rec.lid_hdr.lrh_len = sizeof(rec);
-        rec.lid_hdr.lrh_index = index;
-        rec.lid_hdr.lrh_type = LLOG_LOGID_MAGIC;
+        rec.lid_hdr.lrh_len = cpu_to_le32(sizeof(rec));
+        rec.lid_hdr.lrh_index = cpu_to_le32(index);
+        rec.lid_hdr.lrh_type = cpu_to_le32(LLOG_LOGID_MAGIC);
         rec.lid_id = loghandle->lgh_id;
-        rec.lid_tail.lrt_len = sizeof(rec);
-        rec.lid_tail.lrt_index = index;
+        rec.lid_tail.lrt_len = cpu_to_le32(sizeof(rec));
+        rec.lid_tail.lrt_index = cpu_to_le32(index);
 
         /* update the catalog: header and record */
         rc = llog_write_rec(cathandle, &rec.lid_hdr,
@@ -105,7 +104,7 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
                 GOTO(out_destroy, rc);
         }
 
-        loghandle->lgh_hdr->llh_cat_idx = index;
+        loghandle->lgh_hdr->llh_cat_idx = cpu_to_le32(index);
         cathandle->u.chd.chd_current_log = loghandle;
         LASSERT(list_empty(&loghandle->u.phd.phd_entry));
         list_add_tail(&loghandle->u.phd.phd_entry, &cathandle->u.chd.chd_head);
@@ -116,7 +115,6 @@ static struct llog_handle *llog_cat_new_log(struct llog_handle *cathandle)
 
         RETURN(loghandle);
 }
-EXPORT_SYMBOL(llog_cat_new_log);
 
 /* Open an existent log handle and add it to the open list.
  * This log handle will be closed when all of the records in it are removed.
@@ -125,7 +123,7 @@ EXPORT_SYMBOL(llog_cat_new_log);
  * We return a lock on the handle to ensure nobody yanks it from us.
  */
 int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res,
-                       struct llog_logid *logid)
+                              struct llog_logid *logid)
 {
         struct llog_handle *loghandle;
         int rc = 0;
@@ -163,14 +161,15 @@ int llog_cat_id2handle(struct llog_handle *cathandle, struct llog_handle **res,
         if (!rc) {
                 loghandle->u.phd.phd_cat_handle = cathandle;
                 loghandle->u.phd.phd_cookie.lgc_lgl = cathandle->lgh_id;
-                loghandle->u.phd.phd_cookie.lgc_index = 
-                        loghandle->lgh_hdr->llh_cat_idx;
+                loghandle->u.phd.phd_cookie.lgc_index =
+                        le32_to_cpu(loghandle->lgh_hdr->llh_cat_idx);
         }
 
 out:
         *res = loghandle;
         RETURN(rc);
 }
+EXPORT_SYMBOL(llog_cat_id2handle);
 
 int llog_cat_put(struct llog_handle *cathandle)
 {
@@ -257,21 +256,13 @@ int llog_cat_add_rec(struct llog_handle *cathandle, struct llog_rec_hdr *rec,
         int rc;
         ENTRY;
 
-        LASSERT(rec->lrh_len <= LLOG_CHUNK_SIZE);
+        LASSERT(le32_to_cpu(rec->lrh_len) <= LLOG_CHUNK_SIZE);
         loghandle = llog_cat_current_log(cathandle, 1);
         if (IS_ERR(loghandle))
                 RETURN(PTR_ERR(loghandle));
         /* loghandle is already locked by llog_cat_current_log() for us */
         rc = llog_write_rec(loghandle, rec, reccookie, 1, buf, -1);
         up_write(&loghandle->lgh_lock);
-        if (rc == -ENOSPC) {
-                /* to create a new plain log */
-                loghandle = llog_cat_current_log(cathandle, 1);
-                if (IS_ERR(loghandle))
-                        RETURN(PTR_ERR(loghandle));
-                rc = llog_write_rec(loghandle, rec, reccookie, 1, buf, -1);
-                up_write(&loghandle->lgh_lock);
-        }
 
         RETURN(rc);
 }
@@ -287,7 +278,7 @@ EXPORT_SYMBOL(llog_cat_add_rec);
  * Assumes caller has already pushed us into the kernel context.
  */
 int llog_cat_cancel_records(struct llog_handle *cathandle, int count,
-                        struct llog_cookie *cookies)
+                            struct llog_cookie *cookies)
 {
         int i, index, rc = 0;
         ENTRY;
@@ -328,21 +319,21 @@ int llog_cat_cancel_records(struct llog_handle *cathandle, int count,
 }
 EXPORT_SYMBOL(llog_cat_cancel_records);
 
-int llog_cat_process_cb(struct llog_handle *cat_llh, struct llog_rec_hdr *rec,
-                        void *data)
+static int llog_cat_process_cb(struct llog_handle *cat_llh, 
+                               struct llog_rec_hdr *rec, void *data)
 {
         struct llog_process_data *d = data;
         struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
         struct llog_handle *llh;
         int rc;
 
-        if (rec->lrh_type != LLOG_LOGID_MAGIC) {
+        if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
                 CERROR("invalid record in catalog\n");
                 RETURN(-EINVAL);
         }
         CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n",
                lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
-               rec->lrh_index, cat_llh->lgh_id.lgl_oid);
+               le32_to_cpu(rec->lrh_index), cat_llh->lgh_id.lgl_oid);
 
         rc = llog_cat_id2handle(cat_llh, &llh, &lir->lid_id);
         if (rc) {
@@ -363,15 +354,15 @@ int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data)
         int rc;
         ENTRY;
 
-        LASSERT(llh->llh_flags & LLOG_F_IS_CAT);
+        LASSERT(llh->llh_flags &cpu_to_le32(LLOG_F_IS_CAT));
         d.lpd_data = data;
         d.lpd_cb = cb;
 
         if (llh->llh_cat_idx > cat_llh->lgh_last_idx) {
-                CWARN("catlog "LPX64" crosses index zero\n",
+                CWARN("catalog "LPX64" crosses index zero\n",
                       cat_llh->lgh_id.lgl_oid);
 
-                cd.first_idx = llh->llh_cat_idx;
+                cd.first_idx = le32_to_cpu(llh->llh_cat_idx);
                 cd.last_idx = 0;
                 rc = llog_process(cat_llh, llog_cat_process_cb, &d, &cd);
                 if (rc != 0)
@@ -388,6 +379,70 @@ int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data)
 }
 EXPORT_SYMBOL(llog_cat_process);
 
+static int llog_cat_reverse_process_cb(struct llog_handle *cat_llh, 
+                                       struct llog_rec_hdr *rec, void *data)
+{
+        struct llog_process_data *d = data;
+        struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
+        struct llog_handle *llh;
+        int rc;
+
+        if (le32_to_cpu(rec->lrh_type) != LLOG_LOGID_MAGIC) {
+                CERROR("invalid record in catalog\n");
+                RETURN(-EINVAL);
+        }
+        CWARN("processing log "LPX64":%x at index %u of catalog "LPX64"\n",
+               lir->lid_id.lgl_oid, lir->lid_id.lgl_ogen,
+               le32_to_cpu(rec->lrh_index), cat_llh->lgh_id.lgl_oid);
+
+        rc = llog_cat_id2handle(cat_llh, &llh, &lir->lid_id);
+        if (rc) {
+                CERROR("Cannot find handle for log "LPX64"\n",
+                       lir->lid_id.lgl_oid);
+                RETURN(rc);
+        }
+
+        rc = llog_reverse_process(llh, d->lpd_cb, d->lpd_data, NULL);
+        RETURN(rc);
+}
+
+int llog_cat_reverse_process(struct llog_handle *cat_llh,
+                             llog_cb_t cb, void *data)
+{
+        struct llog_process_data d;
+        struct llog_process_cat_data cd;
+        struct llog_log_hdr *llh = cat_llh->lgh_hdr;
+        int rc;
+        ENTRY;
+
+        LASSERT(llh->llh_flags &cpu_to_le32(LLOG_F_IS_CAT));
+        d.lpd_data = data;
+        d.lpd_cb = cb;
+
+        if (llh->llh_cat_idx > cat_llh->lgh_last_idx) {
+                CWARN("catalog "LPX64" crosses index zero\n",
+                      cat_llh->lgh_id.lgl_oid);
+
+                cd.first_idx = 0;
+                cd.last_idx = cat_llh->lgh_last_idx;
+                rc = llog_reverse_process(cat_llh, llog_cat_reverse_process_cb,
+                                          &d, &cd);
+                if (rc != 0)
+                        RETURN(rc);
+
+                cd.first_idx = le32_to_cpu(llh->llh_cat_idx);
+                cd.last_idx = 0;
+                rc = llog_reverse_process(cat_llh, llog_cat_reverse_process_cb,
+                                          &d, &cd);
+        } else {
+                rc = llog_reverse_process(cat_llh, llog_cat_reverse_process_cb,
+                                          &d, NULL);
+        }
+
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_reverse_process);
+
 int llog_cat_set_first_idx(struct llog_handle *cathandle, int index)
 {
         struct llog_log_hdr *llh = cathandle->lgh_hdr;
@@ -395,17 +450,17 @@ int llog_cat_set_first_idx(struct llog_handle *cathandle, int index)
         ENTRY;
 
         bitmap_size = sizeof(llh->llh_bitmap) * 8;
-        if (llh->llh_cat_idx == (index - 1)) {
-                idx = llh->llh_cat_idx + 1;
-                llh->llh_cat_idx = idx;
+        if (llh->llh_cat_idx == cpu_to_le32(index - 1)) {
+                idx = le32_to_cpu(llh->llh_cat_idx) + 1;
+                llh->llh_cat_idx = cpu_to_le32(idx);
                 if (idx == cathandle->lgh_last_idx)
                         goto out;
                 for (i = (index + 1) % bitmap_size;
                      i != cathandle->lgh_last_idx;
                      i = (i + 1) % bitmap_size) {
                         if (!ext2_test_bit(i, llh->llh_bitmap)) {
-                                idx = llh->llh_cat_idx + 1;
-                                llh->llh_cat_idx = idx;
+                                idx = le32_to_cpu(llh->llh_cat_idx) + 1;
+                                llh->llh_cat_idx = cpu_to_le32(idx);
                         } else if (i == 0) {
                                 llh->llh_cat_idx = 0;
                         } else {
@@ -413,55 +468,166 @@ int llog_cat_set_first_idx(struct llog_handle *cathandle, int index)
                         }
                 }
 out:
-                CDEBUG(D_HA, "set catlog "LPX64" first idx %u\n",
-                       cathandle->lgh_id.lgl_oid, llh->llh_cat_idx);
+                CDEBUG(D_HA, "set catalog "LPX64" first idx %u\n",
+                       cathandle->lgh_id.lgl_oid,le32_to_cpu(llh->llh_cat_idx));
         }
 
         RETURN(0);
 }
+EXPORT_SYMBOL(llog_cat_set_first_idx);
 
-#if 0
-/* Assumes caller has already pushed us into the kernel context. */
-int llog_cat_init(struct llog_handle *cathandle, struct obd_uuid *tgtuuid)
+int llog_catalog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, 
+                     void *buf, struct llog_cookie *logcookies, 
+                     int numcookies, void *data)
 {
-        struct llog_log_hdr *llh;
-        loff_t offset = 0;
-        int rc = 0;
+        struct llog_handle *cathandle;
+        int rc;
         ENTRY;
+        
+        cathandle = ctxt->loc_handle;
+        LASSERT(cathandle != NULL);
+        
+        rc = llog_cat_add_rec(cathandle, rec, logcookies, buf);
+        if (rc != 1)
+                CERROR("write one catalog record failed: %d\n", rc);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_catalog_add);
 
-        LASSERT(sizeof(*llh) == LLOG_CHUNK_SIZE);
+int llog_catalog_cancel(struct llog_ctxt *ctxt, int count,
+                        struct llog_cookie *cookies, int flags, void *data)
+{
+        struct llog_handle *cathandle;
+        int rc;
+        ENTRY;
 
-        down(&cathandle->lgh_lock);
-        llh = cathandle->lgh_hdr;
+        if (cookies == NULL || count == 0)
+                RETURN(-EINVAL);
+        cathandle = ctxt->loc_handle;
+        LASSERT(cathandle != NULL);
+        rc = llog_cat_cancel_records(cathandle, count, cookies);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_catalog_cancel);
 
-        if (cathandle->lgh_file->f_dentry->d_inode->i_size == 0) {
-                llog_write_rec(cathandle, &llh->llh_hdr, NULL, 0, NULL, 0);
-
-write_hdr:
-                rc = lustre_fwrite(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
-                                   &offset);
-                if (rc != LLOG_CHUNK_SIZE) {
-                        CERROR("error writing catalog header: rc %d\n", rc);
-                        OBD_FREE(llh, sizeof(*llh));
-                        if (rc >= 0)
-                                rc = -ENOSPC;
-                } else
-                        rc = 0;
-        } else {
-                rc = lustre_fread(cathandle->lgh_file, llh, LLOG_CHUNK_SIZE,
-                                  &offset);
-                if (rc != LLOG_CHUNK_SIZE) {
-                        CERROR("error reading catalog header: rc %d\n", rc);
-                        /* Can we do much else if the header is bad? */
-                        goto write_hdr;
-                } else
-                        rc = 0;
+int llog_catalog_setup(struct llog_ctxt **res, char *name,
+                       struct lvfs_run_ctxt *lvfs_ctxt,
+                       struct fsfilt_operations *fsops,
+                       struct dentry *logs_de, 
+                       struct dentry *objects_de)
+{
+        struct llog_ctxt *ctxt;
+        struct llog_catid catid;
+        struct llog_handle *handle;
+        int rc;
+        
+        ENTRY;
+
+        OBD_ALLOC(ctxt, sizeof(*ctxt));
+        if (!ctxt)
+                RETURN(-ENOMEM);
+
+        *res = ctxt;
+
+        ctxt->loc_fsops = fsops;
+        ctxt->loc_lvfs_ctxt = lvfs_ctxt;
+        ctxt->loc_logs_dir = logs_de;
+        ctxt->loc_objects_dir = objects_de;
+        ctxt->loc_logops = &llog_lvfs_ops; 
+        ctxt->loc_logops->lop_add = llog_catalog_add;
+        ctxt->loc_logops->lop_cancel = llog_catalog_cancel;
+
+        memset(&catid, 0, sizeof(struct llog_catid));
+        rc = llog_get_cat_list(lvfs_ctxt, fsops, name, 1, &catid);
+        if (rc) {
+                CERROR("error llog_get_cat_list rc: %d\n", rc);
+                RETURN(rc);
+        }
+        if (catid.lci_logid.lgl_oid)
+                rc = llog_create(ctxt, &handle, &catid.lci_logid, 0);
+        else {
+                rc = llog_create(ctxt, &handle, NULL, NULL);
+                if (!rc)
+                        catid.lci_logid = handle->lgh_id;
         }
+        if (rc)
+                GOTO(out, rc);
 
-        cathandle->lgh_tgtuuid = &llh->llh_tgtuuid;
-        up(&cathandle->lgh_lock);
+        ctxt->loc_handle = handle;
+        rc = llog_init_handle(handle, LLOG_F_IS_CAT, NULL);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = llog_put_cat_list(lvfs_ctxt, fsops, name, 1, &catid);
+        if (rc)
+                CERROR("error llog_get_cat_list rc: %d\n", rc);
+out:
+        if (ctxt && rc)
+                OBD_FREE(ctxt, sizeof(*ctxt));
         RETURN(rc);
 }
-EXPORT_SYMBOL(llog_cat_init);
+EXPORT_SYMBOL(llog_catalog_setup);
 
-#endif
+int llog_catalog_cleanup(struct llog_ctxt *ctxt)
+{
+        struct llog_handle *cathandle, *n, *loghandle;
+        struct llog_log_hdr *llh;
+        int rc, index;
+        ENTRY;
+                                                                                                                             
+        if (!ctxt)
+                return 0;
+
+        cathandle = ctxt->loc_handle;
+        if (cathandle) {
+                list_for_each_entry_safe(loghandle, n,
+                                         &cathandle->u.chd.chd_head,
+                                         u.phd.phd_entry) {
+                        llh = loghandle->lgh_hdr;
+                        if ((le32_to_cpu(llh->llh_flags) &
+                                LLOG_F_ZAP_WHEN_EMPTY) &&
+                            (le32_to_cpu(llh->llh_count) == 1)) {
+                                rc = llog_destroy(loghandle);
+                                if (rc)
+                                        CERROR("failure destroying log during "
+                                               "cleanup: %d\n", rc);
+                                LASSERT(rc == 0);
+                                index = loghandle->u.phd.phd_cookie.lgc_index;
+                                llog_free_handle(loghandle);
+                                                                                                                             
+                                LASSERT(index);
+                                llog_cat_set_first_idx(cathandle, index);
+                                rc = llog_cancel_rec(cathandle, index);
+                                if (rc == 0)
+                                        CDEBUG(D_HA, "cancel plain log at index"
+                                               " %u of catalog "LPX64"\n",
+                                               index,cathandle->lgh_id.lgl_oid);
+                        }
+                }
+                llog_cat_put(ctxt->loc_handle);
+        }
+        OBD_FREE(ctxt, sizeof(*ctxt));
+        return 0;
+}
+EXPORT_SYMBOL(llog_catalog_cleanup);
+
+int llog_cat_half_bottom(struct llog_cookie *cookie, struct llog_handle *handle)
+{
+        struct llog_handle *loghandle;
+        struct llog_logid *lgl = &cookie->lgc_lgl;
+        int rc;
+                                                                                                                             
+        down_read(&handle->lgh_lock);
+        rc = llog_cat_id2handle(handle, &loghandle, lgl);
+        if (rc)
+                GOTO(out, rc);
+        if (2 * loghandle->lgh_hdr->llh_cat_idx <=
+            handle->lgh_last_idx + handle->lgh_hdr->llh_cat_idx + 1)
+                rc = 1;
+        else
+                rc = 0;
+out:
+        up_read(&handle->lgh_lock);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_cat_half_bottom);
diff --git a/lustre/lvfs/llog_lvfs.c b/lustre/lvfs/llog_lvfs.c
new file mode 100644 (file)
index 0000000..66e9686
--- /dev/null
@@ -0,0 +1,933 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
+ *   Author: Andreas Dilger <adilger@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * OST<->MDS recovery logging infrastructure.
+ *
+ * Invariants in implementation:
+ * - we do not share logs among different OST<->MDS connections, so that
+ *   if an OST or MDS fails it need only look at log(s) relevant to itself
+ */
+
+#define DEBUG_SUBSYSTEM S_LOG
+
+#ifndef EXPORT_SYMTAB
+#define EXPORT_SYMTAB
+#endif
+
+#ifdef __KERNEL__
+#include <linux/fs.h>
+#else
+#include <liblustre.h>
+#endif
+
+#include <linux/lvfs.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/lustre_log.h>
+
+#ifdef __KERNEL__
+
+static int llog_lvfs_pad(struct llog_ctxt *ctxt, struct l_file *file,
+                         int len, int index)
+{
+        struct llog_rec_hdr rec;
+        struct llog_rec_tail tail;
+        int rc;
+        ENTRY;
+
+        LASSERT(len >= LLOG_MIN_REC_SIZE && (len & 0x7) == 0);
+
+        tail.lrt_len = rec.lrh_len = cpu_to_le32(len);
+        tail.lrt_index = rec.lrh_index = cpu_to_le32(index);
+        rec.lrh_type = 0;
+
+        rc = llog_fsfilt_write_record(ctxt, file, &rec, sizeof(rec), 
+                                      &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing padding record: rc %d\n", rc);
+                goto out;
+        }
+
+        file->f_pos += len - sizeof(rec) - sizeof(tail);
+        rc = llog_fsfilt_write_record(ctxt, file, &tail, sizeof(tail),
+                                      &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing padding record: rc %d\n", rc);
+                goto out;
+        }
+
+ out:
+        RETURN(rc);
+}
+
+static int llog_lvfs_write_blob(struct llog_ctxt *ctxt, struct l_file *file,
+                                struct llog_rec_hdr *rec, void *buf, loff_t off)
+{
+        int rc;
+        struct llog_rec_tail end;
+        loff_t saved_off = file->f_pos;
+        int buflen = le32_to_cpu(rec->lrh_len);
+
+        ENTRY;
+        file->f_pos = off;
+
+        if (!buf) {
+                rc = llog_fsfilt_write_record(ctxt, file, rec, buflen,
+                                              &file->f_pos, 0);
+                if (rc) {
+                        CERROR("error writing log record: rc %d\n", rc);
+                        goto out;
+                }
+                GOTO(out, rc = 0);
+        }
+
+        /* the buf case */
+        rec->lrh_len = cpu_to_le32(sizeof(*rec) + buflen + sizeof(end));
+        rc = llog_fsfilt_write_record(ctxt, file, rec, sizeof(*rec), 
+                                      &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log hdr: rc %d\n", rc);
+                goto out;
+        }
+
+        rc = llog_fsfilt_write_record(ctxt, file, buf, buflen, 
+                                      &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log buffer: rc %d\n", rc);
+                goto out;
+        }
+
+        end.lrt_len = rec->lrh_len;
+        end.lrt_index = rec->lrh_index;
+        rc = llog_fsfilt_write_record(ctxt, file, &end, sizeof(end), 
+                                      &file->f_pos, 0);
+        if (rc) {
+                CERROR("error writing log tail: rc %d\n", rc);
+                goto out;
+        }
+
+        rc = 0;
+ out:
+        if (saved_off > file->f_pos)
+                file->f_pos = saved_off;
+        LASSERT(rc <= 0);
+        RETURN(rc);
+}
+
+static int llog_lvfs_read_blob(struct llog_ctxt *ctxt, struct l_file *file,
+                               void *buf, int size, loff_t off)
+{
+        loff_t offset = off;
+        int rc;
+        ENTRY;
+
+        rc = llog_fsfilt_read_record(ctxt, file, buf, size, &offset);
+        if (rc) {
+                CERROR("error reading log record: rc %d\n", rc);
+                RETURN(rc);
+        }
+        RETURN(0);
+}
+
+static int llog_lvfs_read_header(struct llog_handle *handle)
+{
+        struct llog_ctxt *ctxt = handle->lgh_ctxt;
+        int rc;
+        ENTRY;
+
+        LASSERT(sizeof(*handle->lgh_hdr) == LLOG_CHUNK_SIZE);
+        LASSERT(ctxt != NULL);
+
+        if (handle->lgh_file->f_dentry->d_inode->i_size == 0) {
+                CDEBUG(D_HA, "not reading header from 0-byte log\n");
+                RETURN(LLOG_EEMPTY);
+        }
+
+        rc = llog_lvfs_read_blob(ctxt, handle->lgh_file, handle->lgh_hdr,
+                                 LLOG_CHUNK_SIZE, 0);
+        if (rc)
+                CERROR("error reading log header\n");
+
+        handle->lgh_last_idx = le32_to_cpu(handle->lgh_hdr->llh_tail.lrt_index);
+        handle->lgh_file->f_pos = handle->lgh_file->f_dentry->d_inode->i_size;
+
+        RETURN(rc);
+}
+
+/* returns negative in on error; 0 if success && reccookie == 0; 1 otherwise */
+/* appends if idx == -1, otherwise overwrites record idx. */
+static int llog_lvfs_write_rec(struct llog_handle *loghandle,
+                               struct llog_rec_hdr *rec,
+                               struct llog_cookie *reccookie, 
+                               int cookiecount,
+                               void *buf, int idx)
+{
+        struct llog_log_hdr *llh;
+        int reclen = le32_to_cpu(rec->lrh_len), index, rc;
+        struct llog_rec_tail *lrt;
+        struct llog_ctxt *ctxt = loghandle->lgh_ctxt;
+        struct file *file;
+        loff_t offset;
+        size_t left;
+        ENTRY;
+
+        llh = loghandle->lgh_hdr;
+        file = loghandle->lgh_file;
+
+        /* record length should not bigger than LLOG_CHUNK_SIZE */
+        if (buf)
+                rc = (reclen > LLOG_CHUNK_SIZE - sizeof(struct llog_rec_hdr)
+                      - sizeof(struct llog_rec_tail)) ? -E2BIG : 0;
+        else
+                rc = (reclen > LLOG_CHUNK_SIZE) ? -E2BIG : 0;
+        if (rc)
+                RETURN(rc);
+
+        if (idx != -1) {
+                loff_t saved_offset;
+
+                /* no header: only allowed to insert record 1 */
+                if (idx != 1 && !file->f_dentry->d_inode->i_size) {
+                        CERROR("idx != -1 in empty log\n");
+                        LBUG();
+                }
+
+                if (idx && llh->llh_size && llh->llh_size != reclen)
+                        RETURN(-EINVAL);
+
+                rc = llog_lvfs_write_blob(ctxt, file, &llh->llh_hdr, NULL, 0);
+                /* we are done if we only write the header or on error */
+                if (rc || idx == 0)
+                        RETURN(rc);
+
+                saved_offset = sizeof(*llh) + (idx-1)*le32_to_cpu(rec->lrh_len);
+                rc = llog_lvfs_write_blob(ctxt, file, rec, buf, saved_offset);
+                if (rc == 0 && reccookie) {
+                        reccookie->lgc_lgl = loghandle->lgh_id;
+                        reccookie->lgc_index = idx;
+                        rc = 1;
+                }
+                RETURN(rc);
+        }
+
+        /* Make sure that records don't cross a chunk boundary, so we can
+         * process them page-at-a-time if needed.  If it will cross a chunk
+         * boundary, write in a fake (but referenced) entry to pad the chunk.
+         *
+         * We know that llog_current_log() will return a loghandle that is
+         * big enough to hold reclen, so all we care about is padding here.
+         */
+        left = LLOG_CHUNK_SIZE - (file->f_pos & (LLOG_CHUNK_SIZE - 1));
+        if (buf)
+                reclen = sizeof(*rec) + le32_to_cpu(rec->lrh_len) +
+                         sizeof(struct llog_rec_tail);
+
+        /* NOTE: padding is a record, but no bit is set */
+        if (left != 0 && left != reclen &&
+            left < (reclen + LLOG_MIN_REC_SIZE)) {
+                loghandle->lgh_last_idx++;
+                rc = llog_lvfs_pad(ctxt, file, left, loghandle->lgh_last_idx);
+                if (rc)
+                        RETURN(rc);
+        }
+
+        loghandle->lgh_last_idx++;
+        index = loghandle->lgh_last_idx;
+        rec->lrh_index = cpu_to_le32(index);
+        if (buf == NULL) {
+                lrt = (void *)rec + le32_to_cpu(rec->lrh_len) - sizeof(*lrt);
+                lrt->lrt_len = rec->lrh_len;
+                lrt->lrt_index = rec->lrh_index;
+        }
+        if (ext2_set_bit(index, llh->llh_bitmap)) {
+                CERROR("argh, index %u already set in log bitmap?\n", index);
+                LBUG(); /* should never happen */
+        }
+        llh->llh_count = cpu_to_le32(le32_to_cpu(llh->llh_count) + 1);
+        llh->llh_tail.lrt_index = cpu_to_le32(index);
+
+        offset = 0;
+        rc = llog_lvfs_write_blob(ctxt, file, &llh->llh_hdr, NULL, 0);
+        if (rc)
+                RETURN(rc);
+
+        rc = llog_lvfs_write_blob(ctxt, file, rec, buf, file->f_pos);
+        if (rc)
+                RETURN(rc);
+
+        CDEBUG(D_HA, "added record "LPX64": idx: %u, %u bytes\n",
+               loghandle->lgh_id.lgl_oid, index, le32_to_cpu(rec->lrh_len));
+        if (rc == 0 && reccookie) {
+                reccookie->lgc_lgl = loghandle->lgh_id;
+                reccookie->lgc_index = index;
+                if (le32_to_cpu(rec->lrh_type) == MDS_UNLINK_REC)
+                        reccookie->lgc_subsys = LLOG_UNLINK_ORIG_CTXT;
+                else if (le32_to_cpu(rec->lrh_type) == OST_SZ_REC)
+                        reccookie->lgc_subsys = LLOG_SIZE_ORIG_CTXT;
+                else if (le32_to_cpu(rec->lrh_type) == OST_RAID1_REC)
+                        reccookie->lgc_subsys = LLOG_RD1_ORIG_CTXT;
+                else
+                        reccookie->lgc_subsys = -1;
+                rc = 1;
+        }
+        if (rc == 0 && (le32_to_cpu(rec->lrh_type) == LLOG_GEN_REC ||
+            le32_to_cpu(rec->lrh_type) == SMFS_UPDATE_REC))
+                rc = 1;
+
+        RETURN(rc);
+}
+
+/* We can skip reading at least as many log blocks as the number of
+* minimum sized log records we are skipping.  If it turns out
+* that we are not far enough along the log (because the
+* actual records are larger than minimum size) we just skip
+* some more records. */
+
+static void llog_skip_over(__u64 *off, int curr, int goal)
+{
+        if (goal <= curr)
+                return;
+        *off = (*off + (goal-curr-1) * LLOG_MIN_REC_SIZE) &
+                ~(LLOG_CHUNK_SIZE - 1);
+}
+
+/* sets:
+ *  - curr_offset to the furthest point read in the log file
+ *  - curr_idx to the log index preceeding curr_offset
+ * returns -EIO/-EINVAL on error
+ */
+static int llog_lvfs_next_block(struct llog_handle *loghandle, int *curr_idx,
+                                int next_idx, __u64 *curr_offset, void *buf,
+                                int len)
+{
+        struct llog_ctxt *ctxt = loghandle->lgh_ctxt;
+        int rc;
+        ENTRY;
+
+        if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
+                RETURN(-EINVAL);
+
+        CDEBUG(D_OTHER, "looking for log index %u (cur idx %u off "LPU64")\n",
+               next_idx, *curr_idx, *curr_offset);
+
+        while (*curr_offset < loghandle->lgh_file->f_dentry->d_inode->i_size) {
+                struct llog_rec_hdr *rec;
+                struct llog_rec_tail *tail;
+                loff_t ppos;
+
+                llog_skip_over(curr_offset, *curr_idx, next_idx);
+
+                ppos = *curr_offset;
+                rc = llog_fsfilt_read_record(ctxt, loghandle->lgh_file,
+                                             buf, len, &ppos);
+
+                if (rc) {
+                        CERROR("Cant read llog block at log id "LPU64
+                               "/%u offset "LPU64"\n",
+                               loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen,
+                               *curr_offset);
+                        RETURN(rc);
+                }
+
+                /* put number of bytes read into rc to make code simpler */
+                rc = ppos - *curr_offset;
+                *curr_offset = ppos;
+
+                if (rc == 0) /* end of file, nothing to do */
+                        RETURN(0);
+
+                if (rc < sizeof(*tail)) {
+                        CERROR("Invalid llog block at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, *curr_offset);
+                        RETURN(-EINVAL);
+                }
+
+                tail = buf + rc - sizeof(struct llog_rec_tail);
+                *curr_idx = le32_to_cpu(tail->lrt_index);
+
+                /* this shouldn't happen */
+                if (tail->lrt_index == 0) {
+                        CERROR("Invalid llog tail at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, *curr_offset);
+                        RETURN(-EINVAL);
+                }
+                if (le32_to_cpu(tail->lrt_index) < next_idx)
+                        continue;
+
+                /* sanity check that the start of the new buffer is no farther
+                 * than the record that we wanted.  This shouldn't happen. */
+                rec = buf;
+                if (le32_to_cpu(rec->lrh_index) > next_idx) {
+                        CERROR("missed desired record? %u > %u\n",
+                               le32_to_cpu(rec->lrh_index), next_idx);
+                        RETURN(-ENOENT);
+                }
+                RETURN(0);
+        }
+        RETURN(-EIO);
+}
+
+static int llog_lvfs_prev_block(struct llog_handle *loghandle, 
+                                int prev_idx, void *buf, int len)
+{
+        struct llog_ctxt *ctxt = loghandle->lgh_ctxt;
+        __u64 curr_offset;
+        int rc;
+        ENTRY;
+
+        if (len == 0 || len & (LLOG_CHUNK_SIZE - 1))
+                RETURN(-EINVAL);
+
+        CDEBUG(D_OTHER, "looking for log index %u n", prev_idx);
+
+        curr_offset = LLOG_CHUNK_SIZE;
+        llog_skip_over(&curr_offset, 0, prev_idx);
+
+        while (curr_offset < loghandle->lgh_file->f_dentry->d_inode->i_size) {
+                struct llog_rec_hdr *rec;
+                struct llog_rec_tail *tail;
+                loff_t ppos;
+
+                ppos = curr_offset;
+                rc = llog_fsfilt_read_record(ctxt, loghandle->lgh_file,
+                                             buf, len, &ppos);
+
+                if (rc) {
+                        CERROR("Cant read llog block at log id "LPU64
+                               "/%u offset "LPU64"\n",
+                               loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen,
+                               curr_offset);
+                        RETURN(rc);
+                }
+
+                /* put number of bytes read into rc to make code simpler */
+                rc = ppos - curr_offset;
+                curr_offset = ppos;
+
+                if (rc == 0) /* end of file, nothing to do */
+                        RETURN(0);
+
+                if (rc < sizeof(*tail)) {
+                        CERROR("Invalid llog block at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, curr_offset);
+                        RETURN(-EINVAL);
+                }
+
+                tail = buf + rc - sizeof(struct llog_rec_tail);
+
+                /* this shouldn't happen */
+                if (tail->lrt_index == 0) {
+                        CERROR("Invalid llog tail at log id "LPU64"/%u offset "
+                               LPU64"\n", loghandle->lgh_id.lgl_oid,
+                               loghandle->lgh_id.lgl_ogen, curr_offset);
+                        RETURN(-EINVAL);
+                }
+                if (le32_to_cpu(tail->lrt_index) < prev_idx)
+                        continue;
+
+                /* sanity check that the start of the new buffer is no farther
+                 * than the record that we wanted.  This shouldn't happen. */
+                rec = buf;
+                if (le32_to_cpu(rec->lrh_index) > prev_idx) {
+                        CERROR("missed desired record? %u > %u\n",
+                               le32_to_cpu(rec->lrh_index), prev_idx);
+                        RETURN(-ENOENT);
+                }
+                RETURN(0);
+        }
+        RETURN(-EIO);
+}
+
+static struct file *llog_filp_open(char *name, int flags, int mode)
+{
+        char *logname;
+        struct file *filp;
+        int len;
+
+        OBD_ALLOC(logname, PATH_MAX);
+        if (logname == NULL)
+                return ERR_PTR(-ENOMEM);
+
+        len = snprintf(logname, PATH_MAX, "LOGS/%s", name);
+        if (len >= PATH_MAX - 1) {
+                filp = ERR_PTR(-ENAMETOOLONG);
+        } else {
+                filp = l_filp_open(logname, flags, mode);
+                if (IS_ERR(filp)) {
+                        CERROR("logfile creation %s: %ld\n", logname,
+                               PTR_ERR(filp));
+                }
+        }
+
+        OBD_FREE(logname, PATH_MAX);
+        return filp;
+}
+
+static struct file *llog_object_create(struct llog_ctxt *ctxt)
+{
+        unsigned int tmpname = ll_insecure_random_int();
+        char fidname[LL_FID_NAMELEN];
+        struct file *filp;
+        struct dentry *new_child, *parent;
+        void *handle;
+        int rc = 0, err, namelen;
+        ENTRY;
+
+        sprintf(fidname, "OBJECTS/%u", tmpname);
+        filp = filp_open(fidname, O_CREAT | O_EXCL, 0644);
+        if (IS_ERR(filp)) {
+                rc = PTR_ERR(filp);
+                if (rc == -EEXIST) {
+                        CERROR("impossible object name collision %u\n",
+                               tmpname);
+                        LBUG();
+                }
+                CERROR("error creating tmp object %u: rc %d\n", tmpname, rc);
+                RETURN(filp);
+        }
+
+        namelen = ll_fid2str(fidname, filp->f_dentry->d_inode->i_ino,
+                             filp->f_dentry->d_inode->i_generation);
+        parent = filp->f_dentry->d_parent;
+        down(&parent->d_inode->i_sem);
+        new_child = lookup_one_len(fidname, parent, namelen);
+        if (IS_ERR(new_child)) {
+                CERROR("getting neg dentry for obj rename: %d\n", rc);
+                GOTO(out_close, rc = PTR_ERR(new_child));
+        }
+        if (new_child->d_inode != NULL) {
+                CERROR("impossible non-negative obj dentry %lu:%u!\n",
+                       filp->f_dentry->d_inode->i_ino,
+                       filp->f_dentry->d_inode->i_generation);
+                LBUG();
+        }
+
+        handle = llog_fsfilt_start(ctxt, parent->d_inode, FSFILT_OP_RENAME, NULL);
+        if (IS_ERR(handle))
+                GOTO(out_dput, rc = PTR_ERR(handle));
+                                                                                                                             
+        lock_kernel();
+        rc = vfs_rename(parent->d_inode, filp->f_dentry,
+                        parent->d_inode, new_child);
+        unlock_kernel();
+        if (rc)
+                CERROR("error renaming new object %lu:%u: rc %d\n",
+                       filp->f_dentry->d_inode->i_ino, 
+                       filp->f_dentry->d_inode->i_generation, rc);
+
+        err = llog_fsfilt_commit(ctxt, parent->d_inode, handle, 0);
+        if (!rc)
+                rc = err;
+out_dput:
+        dput(new_child);
+out_close:
+        up(&parent->d_inode->i_sem);
+        if (rc) {
+                filp_close(filp, 0);
+                filp = (struct file *)rc; 
+        }
+
+        RETURN(filp); 
+}
+
+static int llog_add_link_object(struct llog_ctxt *ctxt, struct llog_logid logid,
+                                struct dentry *dentry)
+{
+        struct dentry *new_child;
+        char fidname[LL_FID_NAMELEN];
+        void *handle;
+        int namelen, rc = 0, err;
+        ENTRY;
+
+        namelen = ll_fid2str(fidname, logid.lgl_oid, logid.lgl_ogen);
+        down(&ctxt->loc_objects_dir->d_inode->i_sem);
+        new_child = lookup_one_len(fidname, ctxt->loc_objects_dir, namelen);
+        if (IS_ERR(new_child)) {
+                CERROR("getting neg dentry for obj rename: %d\n", rc);
+                GOTO(out, rc = PTR_ERR(new_child));
+        }
+        if (new_child->d_inode == dentry->d_inode)
+                GOTO(out_dput, rc);
+        if (new_child->d_inode != NULL) {
+                CERROR("impossible non-negative obj dentry "LPX64":%u!\n",
+                       logid.lgl_oid, logid.lgl_ogen);
+                LBUG();
+        }
+        handle = llog_fsfilt_start(ctxt, ctxt->loc_objects_dir->d_inode, 
+                                   FSFILT_OP_LINK, NULL);
+        if (IS_ERR(handle))
+                GOTO(out_dput, rc = PTR_ERR(handle));
+                                                                                                                             
+        lock_kernel();
+        rc = vfs_link(dentry, ctxt->loc_objects_dir->d_inode, new_child);
+        unlock_kernel();
+        if (rc)
+                CERROR("error link new object "LPX64":%u: rc %d\n",
+                       logid.lgl_oid, logid.lgl_ogen, rc);
+        err = llog_fsfilt_commit(ctxt, ctxt->loc_objects_dir->d_inode, handle, 0);
+out_dput:
+        l_dput(new_child);
+out:
+        up(&ctxt->loc_objects_dir->d_inode->i_sem);
+        RETURN(rc);
+}
+
+/* This is a callback from the llog_* functions.
+ * Assumes caller has already pushed us into the kernel context. */
+static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res,
+                            struct llog_logid *logid, char *name)
+{
+        struct llog_handle *handle;
+        struct lvfs_run_ctxt saved;
+        int rc = 0;
+        int open_flags = O_RDWR | O_CREAT | O_LARGEFILE;
+        ENTRY;
+
+        handle = llog_alloc_handle();
+        if (handle == NULL)
+                RETURN(-ENOMEM);
+        *res = handle;
+
+        LASSERT(ctxt);
+        if (ctxt->loc_lvfs_ctxt)
+                push_ctxt(&saved, ctxt->loc_lvfs_ctxt, NULL);
+
+        if (logid != NULL) {
+                char logname[LL_FID_NAMELEN + 10] = "OBJECTS/";
+                char fidname[LL_FID_NAMELEN];
+                ll_fid2str(fidname, logid->lgl_oid, logid->lgl_ogen);
+                strcat(logname, fidname);
+
+                handle->lgh_file = filp_open(logname, O_RDWR | O_LARGEFILE, 0644);
+                if (IS_ERR(handle->lgh_file)) {
+                        CERROR("cannot open %s file\n", logname);
+                        GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+                }
+                if (!S_ISREG(handle->lgh_file->f_dentry->d_inode->i_mode)) {
+                        CERROR("%s is not a regular file!: mode = %o\n", logname,
+                               handle->lgh_file->f_dentry->d_inode->i_mode);
+                        GOTO(cleanup, rc = -ENOENT);
+                }
+                LASSERT(handle->lgh_file->f_dentry->d_parent == ctxt->loc_objects_dir);
+                handle->lgh_id = *logid;
+        } else if (name) {
+                handle->lgh_file = llog_filp_open(name, open_flags, 0644);
+                if (IS_ERR(handle->lgh_file))
+                        GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+                LASSERT(handle->lgh_file->f_dentry->d_parent == ctxt->loc_logs_dir);
+
+                handle->lgh_id.lgl_oid = handle->lgh_file->f_dentry->d_inode->i_ino;
+                handle->lgh_id.lgl_ogen = handle->lgh_file->f_dentry->d_inode->i_generation;
+                rc = llog_add_link_object(ctxt, handle->lgh_id, handle->lgh_file->f_dentry);
+                if (rc)
+                        GOTO(cleanup, rc);
+        } else {
+                handle->lgh_file = llog_object_create(ctxt);
+                if (IS_ERR(handle->lgh_file))
+                        GOTO(cleanup, rc = PTR_ERR(handle->lgh_file));
+                LASSERT(handle->lgh_file->f_dentry->d_parent == ctxt->loc_objects_dir);
+                handle->lgh_id.lgl_oid = handle->lgh_file->f_dentry->d_inode->i_ino;
+                handle->lgh_id.lgl_ogen = handle->lgh_file->f_dentry->d_inode->i_generation;
+        }
+
+        handle->lgh_id.lgl_ogr = 1;
+        handle->lgh_ctxt = ctxt;
+ finish:
+        if (ctxt->loc_lvfs_ctxt)
+                pop_ctxt(&saved, ctxt->loc_lvfs_ctxt, NULL);
+        RETURN(rc);
+cleanup:
+        llog_free_handle(handle);
+        goto finish;
+}
+
+static int llog_lvfs_close(struct llog_handle *handle)
+{
+        int rc;
+        ENTRY;
+
+        rc = filp_close(handle->lgh_file, 0);
+        if (rc)
+                CERROR("error closing log: rc %d\n", rc);
+        RETURN(rc);
+}
+
+static int llog_lvfs_destroy(struct llog_handle *loghandle)
+{
+        struct llog_ctxt *ctxt = loghandle->lgh_ctxt;
+        struct lvfs_run_ctxt saved;
+        struct dentry *fdentry;
+        struct inode *parent_inode;
+        char fidname[LL_FID_NAMELEN];
+        void *handle;
+        int rc = -EINVAL, err, namelen;
+        ENTRY;
+                                                                                                                             
+        if (ctxt->loc_lvfs_ctxt)
+                push_ctxt(&saved, ctxt->loc_lvfs_ctxt, NULL);
+
+        fdentry = loghandle->lgh_file->f_dentry;
+        parent_inode = fdentry->d_parent->d_inode;
+
+        if (!strcmp(fdentry->d_parent->d_name.name, "LOGS")) {
+                LASSERT(parent_inode == ctxt->loc_logs_dir->d_inode);
+
+                namelen = ll_fid2str(fidname, fdentry->d_inode->i_ino,
+                                     fdentry->d_inode->i_generation);
+                dget(fdentry);
+                rc = llog_lvfs_close(loghandle);
+                if (rc) {
+                        dput(fdentry);
+                        GOTO(out, rc);
+                }
+
+                handle = llog_fsfilt_start(ctxt, parent_inode,
+                                           FSFILT_OP_UNLINK, NULL);
+                if (IS_ERR(handle)) {
+                        dput(fdentry);
+                        GOTO(out, rc = PTR_ERR(handle));
+                }
+
+                down(&parent_inode->i_sem);
+                rc = vfs_unlink(parent_inode, fdentry);
+                up(&parent_inode->i_sem);
+                dput(fdentry);
+
+                if (!rc) {
+                        down(&ctxt->loc_objects_dir->d_inode->i_sem);
+                        fdentry = lookup_one_len(fidname, ctxt->loc_objects_dir,
+                                                 namelen);
+                        if (fdentry == NULL || fdentry->d_inode == NULL) {
+                                CERROR("destroy non_existent object %s\n", fidname);
+                                GOTO(out_err, rc = IS_ERR(fdentry) ?
+                                     PTR_ERR(fdentry) : -ENOENT);
+                        }
+                        rc = vfs_unlink(ctxt->loc_objects_dir->d_inode, fdentry);
+                        l_dput(fdentry);
+out_err:
+                        up(&ctxt->loc_objects_dir->d_inode->i_sem);
+                }
+                err = llog_fsfilt_commit(ctxt, parent_inode, handle, 0);
+                if (err && !rc)
+                        err = rc;
+
+                GOTO(out, rc);
+        }
+                                                                                                                             
+        if (!strcmp(fdentry->d_parent->d_name.name, "OBJECTS")) {
+                LASSERT(parent_inode == ctxt->loc_objects_dir->d_inode);
+
+                dget(fdentry);
+                rc = llog_lvfs_close(loghandle);
+                if (rc == 0) {
+                        down(&parent_inode->i_sem);
+                        rc = vfs_unlink(parent_inode, fdentry);
+                        up(&parent_inode->i_sem);
+                }
+                dput(fdentry);
+        }
+out:
+        if (ctxt->loc_lvfs_ctxt)
+                pop_ctxt(&saved, ctxt->loc_lvfs_ctxt, NULL);
+        RETURN(rc);
+}
+
+/* reads the catalog list */
+int llog_get_cat_list(struct lvfs_run_ctxt *ctxt,
+                      struct fsfilt_operations *fsops, char *name, 
+                      int count, struct llog_catid *idarray)
+{
+        struct lvfs_run_ctxt saved;
+        struct l_file *file;
+        int size = sizeof(*idarray) * count;
+        loff_t off = 0;
+        int rc;
+
+        LASSERT(count);
+
+        if (ctxt)
+                push_ctxt(&saved, ctxt, NULL);
+        file = l_filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
+        if (!file || IS_ERR(file)) {
+                rc = PTR_ERR(file);
+                CERROR("OBD filter: cannot open/create %s: rc = %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+        if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+                CERROR("%s is not a regular file!: mode = %o\n", name,
+                       file->f_dentry->d_inode->i_mode);
+                GOTO(out, rc = -ENOENT);
+        }
+
+        rc = fsops->fs_read_record(file, idarray, size, &off);
+        if (rc) {
+                CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+ out:
+        if (file && !IS_ERR(file))
+                rc = filp_close(file, 0);
+        if (ctxt)
+                pop_ctxt(&saved, ctxt, NULL);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_get_cat_list);
+
+/* writes the cat list */
+int llog_put_cat_list(struct lvfs_run_ctxt *ctxt, 
+                      struct fsfilt_operations *fsops, char *name, 
+                      int count, struct llog_catid *idarray)
+{
+        struct lvfs_run_ctxt saved;
+        struct l_file *file;
+        int size = sizeof(*idarray) * count;
+        loff_t off = 0;
+        int rc;
+
+        LASSERT(count);
+
+        if (ctxt)
+                push_ctxt(&saved, ctxt, NULL);
+        file = filp_open(name, O_RDWR | O_CREAT | O_LARGEFILE, 0700);
+        if (!file || IS_ERR(file)) {
+                rc = PTR_ERR(file);
+                CERROR("OBD filter: cannot open/create %s: rc = %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+        if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
+                CERROR("%s is not a regular file!: mode = %o\n", name,
+                       file->f_dentry->d_inode->i_mode);
+                GOTO(out, rc = -ENOENT);
+        }
+
+        rc = fsops->fs_write_record(file, idarray, size, &off, 1);
+        if (rc) {
+                CDEBUG(D_INODE,"OBD filter: error reading %s: rc %d\n",
+                       name, rc);
+                GOTO(out, rc);
+        }
+
+ out:
+        if (file && !IS_ERR(file))
+                rc = filp_close(file, 0);
+        if (ctxt)
+                pop_ctxt(&saved, ctxt, NULL);
+        RETURN(rc);
+}
+EXPORT_SYMBOL(llog_put_cat_list);
+
+struct llog_operations llog_lvfs_ops = {
+        lop_create:      llog_lvfs_create,
+        lop_destroy:     llog_lvfs_destroy,
+        lop_close:       llog_lvfs_close,
+        lop_read_header: llog_lvfs_read_header,
+        lop_write_rec:   llog_lvfs_write_rec,
+        lop_next_block:  llog_lvfs_next_block,
+        lop_prev_block:  llog_lvfs_prev_block,
+};
+EXPORT_SYMBOL(llog_lvfs_ops);
+
+#else /* !__KERNEL__ */
+
+static int llog_lvfs_read_header(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+
+static int llog_lvfs_write_rec(struct llog_handle *loghandle,
+                               struct llog_rec_hdr *rec,
+                               struct llog_cookie *reccookie, int cookiecount,
+                               void *buf, int idx)
+{
+        LBUG();
+        return 0;
+}
+
+static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res,
+                            struct llog_logid *logid, char *name)
+{
+        LBUG();
+        return 0;
+}
+
+static int llog_lvfs_close(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+
+static int llog_lvfs_destroy(struct llog_handle *handle)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_get_cat_list(struct lvfs_run_ctxt *ctxt,
+                      struct fsfilt_operations *fsops, char *name, 
+                      int count, struct llog_catid *idarray)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_put_cat_list(struct lvfs_run_ctxt *ctxt, 
+                      struct fsfilt_operations *fsops, char *name, 
+                      int count, struct llog_catid *idarray)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_lvfs_prev_block(struct llog_handle *loghandle, 
+                         int prev_idx, void *buf, int len)
+{
+        LBUG();
+        return 0;
+}
+
+int llog_lvfs_next_block(struct llog_handle *loghandle, 
+                         int next_idx, void *buf, int len)
+{
+        LBUG();
+        return 0;
+}
+
+struct llog_operations llog_lvfs_ops = {
+        lop_create:      llog_lvfs_create,
+        lop_destroy:     llog_lvfs_destroy,
+        lop_close:       llog_lvfs_close,
+        lop_read_header: llog_lvfs_read_header,
+        lop_write_rec:   llog_lvfs_write_rec,
+        lop_next_block:  llog_lvfs_next_block,
+        lop_prev_block:  llog_lvfs_prev_block,
+};
+#endif
index c1a6640..d8ab4a3 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <linux/lvfs.h>
 
-struct dentry *lvfs_fid2dentry(struct obd_run_ctxt *ctxt, __u64 id,
+struct dentry *lvfs_fid2dentry(struct lvfs_run_ctxt *ctxt, __u64 id,
                                __u32 gen, __u64 gr, void *data)
 {
         return ctxt->cb_ops.l_fid2dentry(id, gen, gr, data);
index 4d68116..d74bafd 100644 (file)
@@ -6,3 +6,6 @@ void fsfilt_extN_exit(void);
 
 int  fsfilt_reiser_init(void);
 void fsfilt_reiser_exit(void);
+
+int lookup_by_path(char *path, int flags, struct nameidata *nd);
+struct dentry *lookup_create(struct nameidata *nd, int is_dir);
index 1e58081..657076c 100644 (file)
@@ -74,8 +74,8 @@ int obd_memmax;
 #endif
 
 /* push / pop to root of obd store */
-void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
-               struct obd_ucred *uc)
+void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
+               struct lvfs_ucred *uc)
 {
         //ASSERT_NOT_KERNEL_CTXT("already in kernel context!\n");
         ASSERT_CTXT_MAGIC(new_ctx->magic);
@@ -105,21 +105,21 @@ void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
         LASSERT(new_ctx->pwdmnt);
 
         if (uc) {
-                save->ouc.ouc_fsuid = current->fsuid;
-                save->ouc.ouc_fsgid = current->fsgid;
-                save->ouc.ouc_cap = current->cap_effective;
-                save->ouc.ouc_suppgid1 = current_groups[0];
-                save->ouc.ouc_suppgid2 = current_groups[1];
-
-                current->fsuid = uc->ouc_fsuid;
-                current->fsgid = uc->ouc_fsgid;
-                current->cap_effective = uc->ouc_cap;
+                save->luc.luc_fsuid = current->fsuid;
+                save->luc.luc_fsgid = current->fsgid;
+                save->luc.luc_cap = current->cap_effective;
+                save->luc.luc_suppgid1 = current_groups[0];
+                save->luc.luc_suppgid2 = current_groups[1];
+
+                current->fsuid = uc->luc_fsuid;
+                current->fsgid = uc->luc_fsgid;
+                current->cap_effective = uc->luc_cap;
                 current_ngroups = 0;
 
-                if (uc->ouc_suppgid1 != -1)
-                        current_groups[current_ngroups++] = uc->ouc_suppgid1;
-                if (uc->ouc_suppgid2 != -1)
-                        current_groups[current_ngroups++] = uc->ouc_suppgid2;
+                if (uc->luc_suppgid1 != -1)
+                        current_groups[current_ngroups++] = uc->luc_suppgid1;
+                if (uc->luc_suppgid2 != -1)
+                        current_groups[current_ngroups++] = uc->luc_suppgid2;
         }
         set_fs(new_ctx->fs);
         set_fs_pwd(current->fs, new_ctx->pwdmnt, new_ctx->pwd);
@@ -137,8 +137,8 @@ void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
 }
 EXPORT_SYMBOL(push_ctxt);
 
-void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
-              struct obd_ucred *uc)
+void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
+              struct lvfs_ucred *uc)
 {
         //printk("pc0");
         ASSERT_CTXT_MAGIC(saved->magic);
@@ -165,12 +165,12 @@ void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
         dput(saved->pwd);
         mntput(saved->pwdmnt);
         if (uc) {
-                current->fsuid = saved->ouc.ouc_fsuid;
-                current->fsgid = saved->ouc.ouc_fsgid;
-                current->cap_effective = saved->ouc.ouc_cap;
+                current->fsuid = saved->luc.luc_fsuid;
+                current->fsgid = saved->luc.luc_fsgid;
+                current->cap_effective = saved->luc.luc_cap;
                 current_ngroups = saved->ngroups;
-                current_groups[0] = saved->ouc.ouc_suppgid1;
-                current_groups[1] = saved->ouc.ouc_suppgid2;
+                current_groups[0] = saved->luc.luc_suppgid1;
+                current_groups[1] = saved->luc.luc_suppgid2;
         }
 
         /*
@@ -325,7 +325,7 @@ int lustre_fsync(struct file *file)
 }
 EXPORT_SYMBOL(lustre_fsync);
 
-struct l_file *l_dentry_open(struct obd_run_ctxt *ctxt, struct l_dentry *de,
+struct l_file *l_dentry_open(struct lvfs_run_ctxt *ctxt, struct l_dentry *de,
                              int flags)
 {
         mntget(ctxt->pwdmnt);
diff --git a/lustre/lvfs/lvfs_reint.c b/lustre/lvfs/lvfs_reint.c
new file mode 100644 (file)
index 0000000..2e4e211
--- /dev/null
@@ -0,0 +1,542 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <asm/unistd.h>
+#include <linux/jbd.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/version.h>
+#include <linux/kp30.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/lustre_compat25.h>
+#include <linux/lvfs.h>
+#include <linux/lustre_smfs.h>
+#include "lvfs_internal.h"
+
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+
+/* from namei.c*/
+struct dentry *lookup_create(struct nameidata *nd, int is_dir)
+{
+        struct dentry *dentry;
+                                                                                                                                                                                                     
+        dentry = ERR_PTR(-EEXIST);
+        if (nd->last_type != LAST_NORM)
+                goto fail;
+        dentry = lookup_hash(&nd->last, nd->dentry);
+        if (IS_ERR(dentry))
+                goto fail;
+        if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
+                goto enoent;
+        return dentry;
+enoent:
+        dput(dentry);
+        dentry = ERR_PTR(-ENOENT);
+fail:
+        return dentry;
+}
+
+int lookup_by_path(char *path, int flags, struct nameidata *nd)
+{
+       struct dentry *dentry = NULL;
+        int rc = 0;
+        
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+        if (path_init(path, flags, nd)) {
+#else
+        if (path_lookup(path, flags, nd)) {
+#endif
+               rc = path_walk(path, nd);
+               if (rc)
+                       RETURN(rc);
+       } else
+               RETURN(-EINVAL);
+
+       dentry = nd->dentry;
+
+       if (!dentry->d_inode || is_bad_inode(dentry->d_inode) || 
+           (!S_ISDIR(dentry->d_inode->i_mode))) { 
+               path_release(nd);
+               RETURN(-ENODEV);
+       }
+        RETURN(rc); 
+}  
+
+static int lvfs_reint_create(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char *path = r_rec->rec_data1;
+        int type = r_rec->u_rec.ur_iattr.ia_mode & S_IFMT;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0, created = 0, err = 0;
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry;
+        
+        down(&dparent->d_inode->i_sem);
+        /*create a new dentry*/
+        dentry = lookup_create(&nd, 0);
+        dir = dparent->d_inode;
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+        
+        switch(type) {  
+        case S_IFREG:
+                handle = fsfilt->fs_start(dir, FSFILT_OP_CREATE, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                rc = ll_vfs_create(dir, dentry, r_rec->u_rec.ur_iattr.ia_mode, 
+                                   NULL);
+                break;
+        case S_IFDIR:
+                handle = fsfilt->fs_start(dir, FSFILT_OP_MKDIR, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                rc = vfs_mkdir(dir, dentry, r_rec->u_rec.ur_iattr.ia_mode);
+                break;
+        case S_IFLNK: {
+                char *new_path = r_rec->rec_data2; 
+                handle = fsfilt->fs_start(dir, FSFILT_OP_SYMLINK, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                rc = vfs_symlink(dir, dentry, new_path);
+                break;
+        }
+        case S_IFCHR:
+        case S_IFBLK:
+        case S_IFIFO:
+        case S_IFSOCK: {
+                int rdev = r_rec->u_rec.ur_rdev;
+                handle = fsfilt->fs_start(dir, FSFILT_OP_MKNOD, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, (handle = NULL, rc = PTR_ERR(handle)));
+                rc = vfs_mknod(dir, dentry, r_rec->u_rec.ur_iattr.ia_mode, 
+                               rdev);
+                break;
+        }
+        default:
+                CERROR("Error type %d in create\n", type);
+                rc = -EINVAL;
+                break;
+        }  
+       
+        if (rc) {
+                CERROR("Error for creating mkdir %s\n", path);
+                GOTO(cleanup, 0); 
+        } else {
+                struct iattr iattr;
+                
+                created = 1;
+
+                LTIME_S(iattr.ia_atime) = LTIME_S(r_rec->u_rec.ur_iattr.ia_atime);
+                LTIME_S(iattr.ia_ctime) = LTIME_S(r_rec->u_rec.ur_iattr.ia_ctime);
+                LTIME_S(iattr.ia_mtime) = LTIME_S(r_rec->u_rec.ur_iattr.ia_mtime);
+
+                iattr.ia_uid = r_rec->u_rec.ur_fsuid;
+                if (dir->i_mode & S_ISGID)
+                        iattr.ia_gid = dir->i_gid;
+                else
+                        iattr.ia_gid = r_rec->u_rec.ur_fsgid;
+                iattr.ia_valid = ATTR_UID | ATTR_GID | ATTR_ATIME |
+                        ATTR_MTIME | ATTR_CTIME;
+               
+                rc = fsfilt->fs_setattr(dentry, handle, &iattr, 0);
+                if (rc) {
+                        CERROR("error on child setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }    
+   
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, &iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (rc && created) {
+                /* Destroy the file we just created.  This should not need
+                 * extra journal credits, as we have already modified all of
+                 * the blocks needed in order to create the file in the first
+                 * place.
+                 */
+                switch (type) {
+                case S_IFDIR:
+                        err = vfs_rmdir(dir, dentry);
+                        if (err)
+                                CERROR("rmdir in error path: %d\n", err);
+                        break;
+                default:
+                        err = vfs_unlink(dir, dentry);
+                        if (err)
+                                CERROR("unlink in error path: %d\n", err);
+                        break;
+                }
+        } else {
+                rc = err;
+        }
+        if (handle) 
+                rc = fsfilt->fs_commit(dentry->d_inode, handle, 0);
+       
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        up(&dparent->d_inode->i_sem);
+        path_release(&nd);
+        if (dentry)
+                l_dput(dentry);
+
+        RETURN(0);
+};
+
+static int lvfs_reint_link(struct super_block *sb, 
+                           struct reint_record *r_rec)
+{       
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char   *old_path = r_rec->rec_data1;
+        char   *new_path = r_rec->rec_data2;
+        struct nameidata old_nd;
+        struct nameidata new_nd;
+        struct dentry *old_dparent;
+        struct dentry *new_dparent;
+       struct dentry *old_dentry = NULL;
+       struct dentry *new_dentry = NULL;
+        void   *handle = NULL;
+        struct inode *dir = NULL;
+        int    rc = 0;
+        
+        /*get parent dentry*/  
+        rc = lookup_by_path(new_path, LOOKUP_PARENT, &new_nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        new_dparent = new_nd.dentry;
+        
+        dir = new_dparent->d_inode;
+
+        new_dentry = lookup_create(&new_nd, 0);
+        
+        rc = lookup_by_path(old_path, LOOKUP_PARENT, &old_nd);
+        if (rc) {
+                path_release(&new_nd); 
+                RETURN(rc);
+        }
+        old_dparent = old_nd.dentry;
+        old_dentry = lookup_one_len(old_nd.last.name, old_dparent, 
+                                    old_nd.last.len);    
+        
+        if (! old_dentry || !old_dentry->d_inode 
+            || is_bad_inode(old_dentry->d_inode)) {
+                GOTO(cleanup, rc = -ENODEV);
+        }       
+        if (dir->i_rdev != old_dentry->d_inode->i_rdev) {
+                GOTO(cleanup, rc = -EINVAL);
+        }
+        
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+      
+        handle = fsfilt->fs_start(dir, FSFILT_OP_LINK, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        
+        rc = vfs_link(old_dentry, dir, new_dentry);
+        if (rc) {
+                CERROR("replay error: vfs_link error rc=%d", rc);
+                GOTO(cleanup, rc); 
+        }
+cleanup:
+        if (handle) {
+                rc = fsfilt->fs_commit(dir, handle, 0);
+        }
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (old_dentry) 
+                l_dput(old_dentry); 
+        if (new_dentry)
+                l_dput(new_dentry);
+        path_release(&new_nd);
+        path_release(&old_nd);
+        RETURN(rc);
+};
+static int lvfs_reint_unlink(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        int type = r_rec->u_rec.ur_iattr.ia_mode & S_IFMT;
+        char *path = r_rec->rec_data1;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0;
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry;
+        
+        dir = dparent->d_inode;
+        
+        dentry = lookup_one_len(nd.last.name, dparent, 
+                                nd.last.len);
+        if (! dentry || !dentry->d_inode 
+            || is_bad_inode(dentry->d_inode)) {
+                GOTO(cleanup, rc = -ENODEV);
+        }   
+        
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+      
+        handle = fsfilt->fs_start(dir, FSFILT_OP_UNLINK, NULL, 0);
+        
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        
+        switch (type) {
+                case S_IFDIR:
+                        rc = vfs_rmdir(dir, dentry);
+                        if (rc)
+                                CERROR("rmdir in error path: %d\n", rc);
+                        break;
+                default:
+                        rc = vfs_unlink(dir, dentry);
+                        if (rc)
+                                CERROR("unlink in error path: %d\n", rc);
+                        break;
+        }
+        if (!rc) {
+                /*time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (handle) 
+                fsfilt->fs_commit(dir, handle, 0);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        path_release(&nd);
+        RETURN(rc);
+};
+
+static int lvfs_reint_rename(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char *path = r_rec->rec_data1;
+        char *new_path = r_rec->rec_data2;
+               struct nameidata nd;
+               struct nameidata new_nd;
+       struct dentry *dparent = NULL;
+       struct dentry *new_dparent = NULL;
+       struct dentry *dentry = NULL;
+       struct dentry *new_dentry = NULL;
+        struct inode *dir = NULL;
+        struct inode *new_dir = NULL;
+        void *handle = NULL;
+        int rc = 0;
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);
+        if (!dentry || !dentry->d_inode 
+            || is_bad_inode(dentry->d_inode)) {
+                path_release(&nd);
+                RETURN(rc);
+        }       
+        rc = lookup_by_path(new_path, LOOKUP_PARENT, &new_nd);
+        if (rc) {
+                path_release(&nd); 
+                path_release(&new_nd); 
+                RETURN(rc);
+        }
+        new_dparent = new_nd.dentry;
+        new_dir = new_dparent->d_inode;
+        new_dentry = lookup_create(&new_nd, 0);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags)) 
+                SMFS_CLEAN_INODE_REC(dir);
+      
+        handle = fsfilt->fs_start(dir, FSFILT_OP_RENAME, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        
+        rc = vfs_rename(dir, dentry, new_dir, new_dentry);
+        if (rc) {
+                CERROR("unlink in error path: %d\n", rc);
+                GOTO(cleanup, 0); 
+        } else {
+                /*restore time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+                rc = fsfilt->fs_setattr(new_dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (handle) 
+                rc = fsfilt->fs_commit(dir, handle, 0);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        if (new_dentry)
+                l_dput(new_dentry);
+        path_release(&nd);
+        path_release(&new_nd); 
+        RETURN(0);
+};
+
+static int lvfs_reint_setattr(struct super_block *sb, 
+                              struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char *path = r_rec->rec_data1;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0; 
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+        
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);
+        if (!dentry || !dentry->d_inode 
+            || is_bad_inode(dentry->d_inode)) {
+                path_release(&nd);
+                RETURN(rc);
+        }       
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags)) 
+                SMFS_CLEAN_INODE_REC(dir);
+        handle = fsfilt->fs_start(dir, FSFILT_OP_SETATTR, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        rc = fsfilt->fs_setattr(dentry, handle, &r_rec->u_rec.ur_pattr, 0);
+cleanup:
+        if (handle) 
+                fsfilt->fs_commit(dir, handle, 0); 
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        path_release(&nd);
+        RETURN(0);
+}; 
+static int lvfs_reint_close(struct super_block *sb, 
+                            struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char   *path = r_rec->rec_data1;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        struct iattr *iattr = &r_rec->u_rec.ur_iattr; 
+        int rc = 0; 
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+        
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);
+        if (!dentry || !dentry->d_inode 
+            || is_bad_inode(dentry->d_inode)) {
+                path_release(&nd);
+                RETURN(rc);
+        }       
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags)) 
+                SMFS_CLEAN_INODE_REC(dir);
+        handle = fsfilt->fs_start(dir, FSFILT_OP_CREATE, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        iattr->ia_valid = ATTR_MTIME | ATTR_CTIME | ATTR_SIZE;
+
+        rc = fsfilt->fs_setattr(dentry, handle, iattr, 0);
+        if (rc) {
+                CERROR("error on parent setattr: rc = %d\n", rc);
+                GOTO(cleanup, rc);
+        }
+cleanup:
+        if (handle) 
+                fsfilt->fs_commit(dir, handle, 0); 
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        path_release(&nd);
+        RETURN(0);
+}; 
+
+typedef int (*lvfs_reinter)(struct super_block *sb, struct reint_record *);
+static lvfs_reinter reinters[REINT_MAX + 1] = {
+        [REINT_SETATTR] lvfs_reint_setattr,
+        [REINT_CREATE] lvfs_reint_create,
+        [REINT_LINK] lvfs_reint_link,
+        [REINT_UNLINK] lvfs_reint_unlink,
+        [REINT_RENAME] lvfs_reint_rename,
+        [REINT_CLOSE] lvfs_reint_close,
+};
+int lvfs_reint(struct super_block *sb, 
+               void *r_rec)
+{
+        return  reinters[((struct reint_record*)r_rec)->u_rec.ur_opcode](sb, 
+                         (struct reint_record *)r_rec);     
+};
+
+EXPORT_SYMBOL(lvfs_reint);
diff --git a/lustre/lvfs/lvfs_undo.c b/lustre/lvfs/lvfs_undo.c
new file mode 100644 (file)
index 0000000..43e9dbf
--- /dev/null
@@ -0,0 +1,421 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_FILTER
+
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <asm/unistd.h>
+#include <linux/jbd.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/quotaops.h>
+#include <linux/version.h>
+#include <linux/kp30.h>
+#include <linux/lustre_fsfilt.h>
+#include <linux/obd.h>
+#include <linux/obd_class.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/lustre_compat25.h>
+#include <linux/lvfs.h>
+#include <linux/lustre_smfs.h>
+#include "lvfs_internal.h"
+
+#include <linux/obd.h>
+#include <linux/lustre_lib.h>
+
+static int lvfs_undo_create(struct super_block *sb, 
+                            struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char *path = r_rec->rec_data1;
+        int type = r_rec->u_rec.ur_iattr.ia_mode & S_IFMT;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0;
+
+       rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry; 
+        dir = dparent->d_inode;
+        
+        down(&dir->i_sem);
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);    
+        
+       if (!dentry->d_inode || is_bad_inode(dentry->d_inode)) {
+               up(&dir->i_sem);
+                if (dentry)
+                        l_dput(dentry);
+                path_release(&nd);
+               RETURN(-ENODEV);
+        } 
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+        
+        switch(type) {  
+        case S_IFREG:
+        case S_IFLNK:
+        case S_IFCHR:
+        case S_IFBLK:
+        case S_IFIFO:
+        case S_IFSOCK:
+                handle = fsfilt->fs_start(dir, FSFILT_OP_UNLINK, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                rc = vfs_unlink(dir, dentry);
+                if (rc)
+                        CERROR("unlink in error path: %d\n", rc);
+                break;
+        case S_IFDIR:
+                handle = fsfilt->fs_start(dir, FSFILT_OP_RMDIR, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup, rc = PTR_ERR(handle));
+                
+                rc = vfs_rmdir(dir, dentry);
+                if (rc)
+                        CERROR("rmdir in error path: %d\n", rc);
+                break;
+        default:
+                CERROR("Error type %d in create\n", type);
+                rc = -EINVAL;
+                break;
+        }  
+       
+        if (rc) {
+                CERROR("Error for undo node %s\n", path);
+                GOTO(cleanup, 0); 
+        } else {
+                /*restore time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (handle) 
+                rc = fsfilt->fs_commit(dparent->d_inode, handle, 0);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        up(&dir->i_sem);
+        path_release(&nd);
+        RETURN(0);
+};
+
+static int lvfs_undo_link(struct super_block *sb, 
+                          struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char   *new_path = r_rec->rec_data2;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0;
+
+       rc = lookup_by_path(new_path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry; 
+        dir = dparent->d_inode;
+        
+        down(&dir->i_sem);
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);    
+        
+       if (!dentry->d_inode || is_bad_inode(dentry->d_inode)) {
+               up(&dir->i_sem);
+                path_release(&nd);
+               RETURN(-ENODEV);
+        } 
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+        
+        handle = fsfilt->fs_start(dir, FSFILT_OP_UNLINK, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        rc = vfs_unlink(dir, dentry);
+        if (rc)
+                CERROR("unlink in error path: %d\n", rc);
+
+        if (rc) {
+                CERROR("Error for undo node %s\n", new_path);
+                GOTO(cleanup, 0); 
+        } else {
+                /*restore time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (handle) 
+                rc = fsfilt->fs_commit(dir, handle, 0);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        up(&dir->i_sem);
+        path_release(&nd);
+        RETURN(0);
+}       
+
+static int lvfs_undo_unlink(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char   *path = r_rec->rec_data1;
+        struct nameidata nd;
+        struct dentry *dparent;
+       struct dentry *dentry = NULL;
+        struct nameidata del_nd;
+        struct dentry *del_dparent = NULL;
+       struct dentry *del_dentry = NULL;
+        void   *handle = NULL;
+        struct inode *dir = NULL;
+        int    rc = 0;
+        
+        /*get parent dentry*/  
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        
+        dentry = lookup_create(&nd, 0);
+        
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(dir);
+        if (SMFS_DO_DEC_LINK(r_rec->u_rec.ur_flags)) {
+                ino_t ino = *((ino_t *)r_rec->rec_data2);
+                struct inode* inode = iget(dir->i_sb, ino);
+                if (!inode) 
+                        GOTO(cleanup1, rc = -EINVAL);        
+                handle = fsfilt->fs_start(dir, FSFILT_OP_LINK, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup1, rc = PTR_ERR(handle));
+                
+                del_dentry = pre_smfs_dentry(NULL, inode, dentry);
+                rc = vfs_link(del_dentry, dir, dentry); 
+cleanup1:
+                post_smfs_dentry(del_dentry);
+                iput(inode);
+        } else {
+                char   *del_path = r_rec->rec_data2;
+                             
+                rc = lookup_by_path(del_path, LOOKUP_PARENT, &del_nd);
+                if (rc) 
+                        GOTO(cleanup, rc = -ENODEV);
+                del_dparent = del_nd.dentry;
+                del_dentry = lookup_one_len(del_nd.last.name, del_dparent, 
+                                    del_nd.last.len);    
+
+                if (! del_dentry || !del_dentry->d_inode 
+                    || is_bad_inode(del_dentry->d_inode)) 
+                        GOTO(cleanup2, rc = -ENODEV);
+
+                handle = fsfilt->fs_start(dir, FSFILT_OP_RENAME, NULL, 0);
+                if (IS_ERR(handle))
+                        GOTO(cleanup2, rc = PTR_ERR(handle));
+
+                lock_kernel();
+                /*move the del dentry back to the original palace*/
+                rc = vfs_rename(del_dparent->d_inode, del_dentry, dir, dentry);
+                unlock_kernel();
+                if (!rc && S_ISDIR(del_dentry->d_inode->i_mode))
+                        del_dentry->d_inode->i_flags &=~S_DEAD;
+cleanup2:
+                if (del_dentry)
+                        l_dput(del_dentry);
+                path_release(&del_nd);
+        }
+        if (!rc) {
+               /*restore time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        } 
+cleanup:
+        if (handle) 
+                fsfilt->fs_commit(dir, handle, 0);
+        if (dentry);
+                l_dput(dentry);
+        path_release(&nd);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        RETURN(rc);
+}
+
+static int lvfs_undo_rename(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char   *path = r_rec->rec_data1;
+        char   *new_path = r_rec->rec_data2;
+        struct nameidata nd;
+        struct nameidata new_nd;
+        struct dentry *dparent;
+        struct dentry *new_dparent;
+       struct dentry *dentry = NULL;
+       struct dentry *new_dentry = NULL;
+        void   *handle = NULL;
+        struct inode *dir = NULL;
+        struct inode *new_dir = NULL;
+        int    rc = 0;
+        
+        /*get parent dentry*/  
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+       
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        dentry = lookup_create(&nd, 0);
+        
+        rc = lookup_by_path(new_path, LOOKUP_PARENT, &new_nd);
+        if (rc) {
+                path_release(&nd); 
+                RETURN(rc);
+        }
+        new_dparent = new_nd.dentry;
+        new_dir = new_dparent->d_inode;
+        new_dentry = lookup_one_len(new_nd.last.name, new_dparent, 
+                                    new_nd.last.len);    
+        
+        if (! new_dentry || !new_dentry->d_inode 
+            || is_bad_inode(new_dentry->d_inode)) {
+                GOTO(cleanup, rc = -ENODEV);
+        }       
+        
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_CLEAN_INODE_REC(new_dir);
+        
+        handle = fsfilt->fs_start(new_dir, FSFILT_OP_RENAME, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+
+        lock_kernel();
+        /*move the del dentry back to the original palace*/
+        rc = vfs_rename(new_dir, new_dentry, dir, dentry);
+        unlock_kernel();
+        if (rc) {
+                CERROR("Error for undo node %s\n", new_path);
+                GOTO(cleanup, 0); 
+        } else {
+                /*restore time attr of dir inode*/
+                struct iattr *iattr = &r_rec->u_rec.ur_pattr;
+                
+                iattr->ia_valid = ATTR_MTIME | ATTR_CTIME;
+                rc = fsfilt->fs_setattr(dparent, handle, iattr, 0);
+                if (rc) {
+                        CERROR("error on parent setattr: rc = %d\n", rc);
+                        GOTO(cleanup, rc);
+                }
+        }
+cleanup:
+        if (handle) 
+                rc = fsfilt->fs_commit(new_dir, handle, 0);
+        if (dentry);
+               l_dput(dentry);
+        if (new_dentry)
+                l_dput(new_dentry);
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(new_dir);
+        path_release(&nd);
+        path_release(&new_nd);
+        RETURN(rc);
+};
+
+static int lvfs_undo_setattr(struct super_block *sb, 
+                             struct reint_record *r_rec)
+{
+        struct fsfilt_operations *fsfilt = S2SMI(sb)->sm_fsfilt;
+        char *path = r_rec->rec_data1;
+               struct nameidata nd;
+       struct dentry *dparent = NULL;
+       struct dentry *dentry = NULL;
+        struct inode *dir = NULL;
+        void *handle = NULL;
+        int rc = 0;
+
+        rc = lookup_by_path(path, LOOKUP_PARENT, &nd); 
+        if (rc)
+                RETURN(rc); 
+        
+        dparent = nd.dentry;
+        dir = dparent->d_inode;
+        dentry = lookup_one_len(nd.last.name, dparent, nd.last.len);
+        if (!dentry || !dentry->d_inode 
+            || is_bad_inode(dentry->d_inode)) {
+                path_release(&nd);
+                RETURN(rc);
+        }       
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags)) 
+                SMFS_CLEAN_INODE_REC(dir);
+        handle = fsfilt->fs_start(dir, FSFILT_OP_SETATTR, NULL, 0);
+        if (IS_ERR(handle))
+                GOTO(cleanup, rc = PTR_ERR(handle));
+        
+        /*FIXME later, did not set parent attr*/
+        r_rec->u_rec.ur_iattr.ia_valid = r_rec->u_rec.ur_pattr.ia_valid;
+        rc = fsfilt->fs_setattr(dentry, handle, &r_rec->u_rec.ur_iattr, 0);
+cleanup:  
+        if (handle)
+                fsfilt->fs_commit(dir, handle, 0); 
+        if (!SMFS_DO_WRITE_KML(r_rec->u_rec.ur_flags))
+                SMFS_SET_INODE_REC(dir);
+        if (dentry)
+                l_dput(dentry);
+        path_release(&nd);
+        RETURN(0);
+       
+        RETURN(0);
+}; 
+
+
+typedef int (*lvfs_undoer)(struct super_block *sb, struct reint_record *);
+
+static lvfs_undoer undoers[REINT_MAX + 1] = {
+        [REINT_SETATTR] lvfs_undo_setattr,
+        [REINT_CREATE] lvfs_undo_create,
+        [REINT_LINK] lvfs_undo_link,
+        [REINT_UNLINK] lvfs_undo_unlink,
+        [REINT_RENAME] lvfs_undo_rename,
+};
+
+int lvfs_undo(struct super_block *sb, 
+              void *r_rec)
+{
+        return  undoers[((struct reint_record*)r_rec)->u_rec.ur_opcode](sb, 
+                         (struct reint_record *)r_rec);     
+};
+
+EXPORT_SYMBOL(lvfs_undo);
index 021a0a3..396ee30 100644 (file)
 
 #include <liblustre.h>
 #include <linux/lvfs.h>
-#include "lvfs_internal.h"
 
 #include <linux/obd.h>
 #include <linux/lustre_lib.h>
 
 /* XXX currently ctxt functions should not be used ?? */
-void push_ctxt(struct obd_run_ctxt *save, struct obd_run_ctxt *new_ctx,
-               struct obd_ucred *uc)
+void push_ctxt(struct lvfs_run_ctxt *save, struct lvfs_run_ctxt *new_ctx,
+               struct lvfs_ucred *uc)
 {
         LBUG();
 }
 
-void pop_ctxt(struct obd_run_ctxt *saved, struct obd_run_ctxt *new_ctx,
-              struct obd_ucred *uc)
+void pop_ctxt(struct lvfs_run_ctxt *saved, struct lvfs_run_ctxt *new_ctx,
+              struct lvfs_ucred *uc)
 {
         LBUG();
 }
index 2cb67a2..fbc448d 100644 (file)
@@ -980,8 +980,8 @@ static int mdc_llog_init(struct obd_device *obd, struct obd_device *tgt,
         int rc;
         ENTRY;
 
-        rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
-                        &llog_client_ops);
+        rc = obd_llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL,
+                            &llog_client_ops);
         if (rc == 0) {
                 ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT);
                 ctxt->loc_imp = obd->u.cli.cl_import;
@@ -995,7 +995,7 @@ static int mdc_llog_finish(struct obd_device *obd, int count)
         int rc;
         ENTRY;
 
-        rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT));
+        rc = obd_llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT));
         RETURN(rc);
 }
 
index 6ebbcad..b7e7aa6 100644 (file)
@@ -130,7 +130,7 @@ static int mds_sendpage(struct ptlrpc_request *req, struct file *file,
 
                 rc = -ETIMEDOUT; /* XXX should this be a different errno? */
         }
-        
+
         DEBUG_REQ(D_ERROR, req, "bulk failed: %s %d(%d), evicting %s@%s\n",
                   (rc == -ETIMEDOUT) ? "timeout" : "network error",
                   desc->bd_nob_transferred, count,
@@ -303,7 +303,7 @@ out:
         return rc;
 }
 
-static int mds_init_export(struct obd_export *exp) 
+static int mds_init_export(struct obd_export *exp)
 {
         struct mds_export_data *med = &exp->exp_mds_data;
 
@@ -316,7 +316,7 @@ static int mds_destroy_export(struct obd_export *export)
 {
         struct mds_export_data *med;
         struct obd_device *obd = export->exp_obd;
-        struct obd_run_ctxt saved;
+        struct lvfs_run_ctxt saved;
         int rc = 0;
         ENTRY;
 
@@ -326,7 +326,8 @@ static int mds_destroy_export(struct obd_export *export)
         if (obd_uuid_equals(&export->exp_client_uuid, &obd->obd_uuid))
                 GOTO(out, 0);
 
-        push_ctxt(&saved, &obd->obd_ctxt, NULL);
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
         /* Close any open files (which may also cause orphan unlinking). */
         spin_lock(&med->med_open_lock);
         while (!list_empty(&med->med_open_head)) {
@@ -345,7 +346,7 @@ static int mds_destroy_export(struct obd_export *export)
                        dentry->d_name.len, dentry->d_name.name,
                        ll_bdevname(dentry->d_inode->i_sb, btmp),
                        dentry->d_inode->i_ino);
-                rc = mds_mfd_close(NULL, obd, mfd, 
+                rc = mds_mfd_close(NULL, obd, mfd,
                                    !(export->exp_flags & OBD_OPT_FAILOVER));
 
                 if (rc)
@@ -353,7 +354,7 @@ static int mds_destroy_export(struct obd_export *export)
                 spin_lock(&med->med_open_lock);
         }
         spin_unlock(&med->med_open_lock);
-        pop_ctxt(&saved, &obd->obd_ctxt, NULL);
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
 out:
         mds_client_free(export, !(export->exp_flags & OBD_OPT_FAILOVER));
@@ -658,10 +659,10 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
 {
         struct obd_device *obd = req->rq_export->exp_obd;
         struct ldlm_reply *rep = NULL;
-        struct obd_run_ctxt saved;
+        struct lvfs_run_ctxt saved;
         struct mds_body *body;
         struct dentry *dparent = NULL, *dchild = NULL;
-        struct obd_ucred uc;
+        struct lvfs_ucred uc;
         struct lustre_handle parent_lockh;
         int namesize;
         int rc = 0, cleanup_phase = 0, resent_req = 0;
@@ -689,17 +690,17 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
 
         LASSERT (offset == 0 || offset == 2);
         /* if requests were at offset 2, the getattr reply goes back at 1 */
-        if (offset) { 
+        if (offset) {
                 rep = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*rep));
                 offset = 1;
         }
 
-        uc.ouc_fsuid = body->fsuid;
-        uc.ouc_fsgid = body->fsgid;
-        uc.ouc_cap = body->capability;
-        uc.ouc_suppgid1 = body->suppgid;
-        uc.ouc_suppgid2 = -1;
-        push_ctxt(&saved, &obd->obd_ctxt, &uc);
+        uc.luc_fsuid = body->fsuid;
+        uc.luc_fsgid = body->fsgid;
+        uc.luc_cap = body->capability;
+        uc.luc_suppgid1 = body->suppgid;
+        uc.luc_suppgid2 = -1;
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
         cleanup_phase = 1; /* kernel context */
         intent_set_disposition(rep, DISP_LOOKUP_EXECD);
 
@@ -789,7 +790,7 @@ static int mds_getattr_name(int offset, struct ptlrpc_request *req,
                 }
                 l_dput(dchild);
         case 1:
-                pop_ctxt(&saved, &obd->obd_ctxt, &uc);
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
         default: ;
         }
         return rc;
@@ -799,10 +800,10 @@ static int mds_getattr(int offset, struct ptlrpc_request *req)
 {
         struct mds_obd *mds = mds_req2mds(req);
         struct obd_device *obd = req->rq_export->exp_obd;
-        struct obd_run_ctxt saved;
+        struct lvfs_run_ctxt saved;
         struct dentry *de;
         struct mds_body *body;
-        struct obd_ucred uc;
+        struct lvfs_ucred uc;
         int rc = 0;
         ENTRY;
 
@@ -813,10 +814,10 @@ static int mds_getattr(int offset, struct ptlrpc_request *req)
                 RETURN (-EFAULT);
         }
 
-        uc.ouc_fsuid = body->fsuid;
-        uc.ouc_fsgid = body->fsgid;
-        uc.ouc_cap = body->capability;
-        push_ctxt(&saved, &obd->obd_ctxt, &uc);
+        uc.luc_fsuid = body->fsuid;
+        uc.luc_fsgid = body->fsgid;
+        uc.luc_cap = body->capability;
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
         de = mds_fid2dentry(mds, &body->fid1, NULL