Whamcloud - gitweb
ext2 page cache updates
authorbraam <braam>
Mon, 15 Oct 2001 05:33:22 +0000 (05:33 +0000)
committerbraam <braam>
Mon, 15 Oct 2001 05:33:22 +0000 (05:33 +0000)
lustre/demos/basesetup.sh
lustre/demos/config.sh
lustre/include/linux/obd_class.h
lustre/obdclass/genops.c
lustre/obdfs/Makefile.am
lustre/obdfs/Makefile.in
lustre/obdfs/dir.c
lustre/obdfs/file.c
lustre/obdfs/namei.c
lustre/obdfs/rw.c
lustre/obdfs/super.c

index f2cf372..7d1beb3 100755 (executable)
@@ -10,6 +10,10 @@ OBDDIR="`dirname $0`/.."
 # source config info
 . $OBDDIR/demos/config.sh
 
+insmod obdclass
+insmod obdext2
+insmod obdfs
+
 # module configuration
 if [ "$MODCONF" -a -f $MODCONF ]; then
     if [ -z "`grep -i "alias  *char-major-$OBDMAJ  *obdclass" $MODCONF`" ]; then
index 5a5140d..4d19a29 100644 (file)
@@ -25,8 +25,8 @@ OBDMAJ=186
 
 # If LOOPDEV is empty, then it is assumed that BASEDEV is a real block device
 # that doesn't mind being overwritten - don't use a partition with data on it!!
-LOOPDEV=""
-BASEDEV="/dev/hda5"
+LOOPDEV="/dev/loop0"
+BASEDEV="/dev/loop0"
 
 # The following are mount points for the filesystems during the test.
 MNTOBD="/mnt/obd"
index 1ea91e7..6926875 100644 (file)
@@ -33,6 +33,7 @@ typedef uint32_t        obd_blksize;
 typedef uint32_t        obd_mode;
 typedef uint32_t        obd_uid;
 typedef uint32_t        obd_gid;
+typedef uint16_t        obd_rdev;
 typedef uint32_t        obd_flag;
 typedef uint32_t        obd_count;
 
@@ -54,6 +55,7 @@ struct obdo {
         obd_mode                o_mode;
         obd_uid                 o_uid;
         obd_gid                 o_gid;
+       obd_rdev                o_rdev;
         obd_flag                o_flags;
         obd_flag                o_obdflags;
         obd_count               o_nlink;
@@ -82,6 +84,7 @@ struct obdo {
 #define OBD_MD_FLGENER  (0x00002000UL)
 #define OBD_MD_FLINLINE (0x00004000UL)
 #define OBD_MD_FLOBDMD  (0x00008000UL)
+#define OBD_MD_FLRDEV   (0x00010000UL)
 #define OBD_MD_FLNOTOBD (~(OBD_MD_FLOBDMD | OBD_MD_FLOBDFLG | OBD_MD_FLBLOCKS))
 
 /*
@@ -322,6 +325,8 @@ static __inline__ void obdo_cpy_md(struct obdo *dst, struct obdo *src)
                 dst->o_gid = src->o_gid;
         if ( src->o_valid & OBD_MD_FLFLAGS ) 
                 dst->o_flags = src->o_flags;
+        if ( src->o_valid & OBD_MD_FLRDEV ) 
+                dst->o_rdev = src->o_rdev;
         /*
         if ( src->o_valid & OBD_MD_FLOBDFLG ) 
                 dst->o_obdflags = src->o_obdflags;
@@ -366,6 +371,8 @@ static __inline__ void obdo_from_inode(struct obdo *dst, struct inode *src)
                 dst->o_uid = src->i_uid;
         if ( dst->o_valid & OBD_MD_FLGID )
                 dst->o_gid = src->i_gid;
+        if ( dst->o_valid & OBD_MD_FLRDEV )
+                dst->o_rdev = src->i_rdev;
         if ( dst->o_valid & OBD_MD_FLFLAGS )
                 dst->o_flags = src->i_flags;
         if ( dst->o_valid & OBD_MD_FLNLINK )
@@ -397,6 +404,8 @@ static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src)
                 dst->i_uid = src->o_uid;
         if ( src->o_valid & OBD_MD_FLGID ) 
                 dst->i_gid = src->o_gid;
+        if ( src->o_valid & OBD_MD_FLRDEV ) 
+                dst->i_rdev = src->o_rdev;
         if ( src->o_valid & OBD_MD_FLFLAGS ) 
                 dst->i_flags = src->o_flags;
         if ( src->o_valid & OBD_MD_FLNLINK )
@@ -429,6 +438,8 @@ static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src,
                 res = (res || (dst->o_uid != src->o_uid));
         if ( compare & OBD_MD_FLGID )
                 res = (res || (dst->o_gid != src->o_gid));
+        if ( compare & OBD_MD_FLRDEV )
+                res = (res || (dst->o_rdev != src->o_rdev));
         if ( compare & OBD_MD_FLFLAGS ) 
                 res = (res || (dst->o_flags != src->o_flags));
         if ( compare & OBD_MD_FLNLINK )
index a261dd8..545b0c7 100644 (file)
@@ -270,16 +270,14 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
         while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
                 obd_count        num_oa = 1;
                 obd_count        num_buf = 1;
-                char            *buf;
                 obd_size         brw_count = PAGE_SIZE;
                 obd_off          brw_offset = (page->index) << PAGE_SHIFT;
                 obd_flag         flagr = 0;
                 obd_flag         flagw = OBD_BRW_CREATE;
                 
                 page->index = index;
-                buf = (char *)page_address(page); 
                 err = OBP(src_conn->oc_dev, brw)(READ, src_conn, num_oa, &src,
-                                                 &num_buf, &buf, &brw_count,
+                                                 &num_buf, &page, &brw_count,
                                                  &brw_offset, &flagr);
 
                 if ( err ) {
@@ -289,7 +287,7 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
                 CDEBUG(D_INFO, "Read page %ld ...\n", page->index);
 
                 err = OBP(dst_conn->oc_dev, brw)(WRITE, dst_conn, num_oa, &dst,
-                                                 &num_buf, &buf, &brw_count,
+                                                 &num_buf, &page, &brw_count,
                                                  &brw_offset, &flagw);
 
                 /* XXX should handle dst->o_size, dst->o_blocks here */
index 1432ae7..62e0606 100644 (file)
@@ -6,6 +6,6 @@
 MODULE = obdfs
 modulefs_DATA = obdfs.o
 EXTRA_PROGRAMS = obdfs
-obdfs_SOURCES = flushd.c rw.c file.c dir.c sysctl.c super.c namei.c symlink.c
+obdfs_SOURCES = dirdata.c flushd.c rw.c file.c dir.c sysctl.c super.c namei.c symlink.c
 
 include $(top_srcdir)/Rules
index fd9838f..262ea31 100644 (file)
@@ -93,7 +93,7 @@ modulefsdir = @modulefsdir@
 MODULE = obdfs
 modulefs_DATA = obdfs.o
 EXTRA_PROGRAMS = obdfs
-obdfs_SOURCES = flushd.c rw.c file.c dir.c sysctl.c super.c namei.c symlink.c
+obdfs_SOURCES = dirdata.c flushd.c rw.c file.c dir.c sysctl.c super.c namei.c symlink.c
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_CLEAN_FILES = 
 
@@ -101,8 +101,8 @@ DEFS = @DEFS@ -I. -I$(srcdir)
 CPPFLAGS = @CPPFLAGS@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
-obdfs_OBJECTS =  flushd.o rw.o file.o dir.o sysctl.o super.o namei.o \
-symlink.o
+obdfs_OBJECTS =  dirdata.o flushd.o rw.o file.o dir.o sysctl.o super.o \
+namei.o symlink.o
 obdfs_LDADD = $(LDADD)
 obdfs_DEPENDENCIES = 
 obdfs_LDFLAGS = 
@@ -119,8 +119,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = gtar
 GZIP_ENV = --best
-DEP_FILES =  .deps/dir.P .deps/file.P .deps/flushd.P .deps/namei.P \
-.deps/rw.P .deps/super.P .deps/symlink.P .deps/sysctl.P
+DEP_FILES =  .deps/dir.P .deps/dirdata.P .deps/file.P .deps/flushd.P \
+.deps/namei.P .deps/rw.P .deps/super.P .deps/symlink.P .deps/sysctl.P
 SOURCES = $(obdfs_SOURCES)
 OBJECTS = $(obdfs_OBJECTS)
 
index 1462f30..af115d9 100644 (file)
@@ -48,15 +48,17 @@ static ssize_t obdfs_dir_read (struct file * filp, char * buf,
 }
 
 static int obdfs_readdir(struct file *, void *, filldir_t);
+extern int new_obdfs_readdir(struct file *, void *, filldir_t);
 
 struct file_operations obdfs_dir_operations = {
         read: obdfs_dir_read,
-        readdir: obdfs_readdir
+        readdir: new_obdfs_readdir
 };
 
+extern struct dentry *new_obdfs_lookup(struct inode * dir, struct dentry *dentry);
 struct inode_operations obdfs_dir_inode_operations = {
         create: obdfs_create,
-        lookup: obdfs_lookup,
+        lookup: new_obdfs_lookup,
         link: obdfs_link,
         unlink: obdfs_unlink,
         symlink: obdfs_symlink,
index ff07ce3..f58c057 100644 (file)
@@ -83,7 +83,7 @@ struct file_operations obdfs_file_operations = {
 extern int obdfs_notify_change(struct dentry *de, struct iattr *attr);
 struct inode_operations obdfs_file_inode_operations = {
         create: obdfs_create,
-        lookup: obdfs_lookup,
+        lookup: NULL,
         link: obdfs_link,
         unlink: obdfs_unlink,
         symlink: obdfs_symlink,
index e899303..9ea0c1c 100644 (file)
@@ -22,6 +22,8 @@
  * 
  *  Changes for use in OBDFS
  *  Copyright (c) 1999, Seagate Technology Inc.
+ *  Copyright (C) 2001, Cluster File Systems, Inc.
+ *                       Rewritten based on recent ext2 page cache use.
  * 
  */
 
 #include <linux/quotaops.h>
 #include <linux/obd_support.h>
 #include <linux/obdfs.h>
-
-
+extern struct address_space_operations obdfs_aops;
 /*
- * define how far ahead to read directories while searching them.
+ * Couple of helper functions - make the code slightly cleaner.
  */
-#define NAMEI_RA_CHUNKS  2
-#define NAMEI_RA_BLOCKS  4
-#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
+extern int ext2_add_link (struct dentry *dentry, struct inode *inode);
+extern ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry);
+int ext2_make_empty(struct inode *inode, struct inode *parent);
+struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
+                  struct dentry *dentry, struct page ** res_page);
+int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page );
+
+
+static inline void ext2_inc_count(struct inode *inode)
+{
+       inode->i_nlink++;
+       mark_inode_dirty(inode);
+}
+
+static inline void ext2_dec_count(struct inode *inode)
+{
+       inode->i_nlink--;
+       mark_inode_dirty(inode);
+}
+
+static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
+{
+       int err = ext2_add_link(dentry, inode);
+       if (!err) {
+               d_instantiate(dentry, inode);
+               return 0;
+       }
+       ext2_dec_count(inode);
+       iput(inode);
+       return err;
+}
+
+/* methods */
+struct dentry *new_obdfs_lookup(struct inode * dir, struct dentry *dentry)
+{
+       struct inode * inode;
+       ino_t ino;
+       
+       if (dentry->d_name.len > EXT2_NAME_LEN)
+               return ERR_PTR(-ENAMETOOLONG);
+
+       ino = ext2_inode_by_name(dir, dentry);
+       inode = NULL;
+       if (ino) {
+               inode = iget(dir->i_sb, ino);
+               if (!inode) 
+                       return ERR_PTR(-EACCES);
+       }
+       d_add(dentry, inode);
+       return NULL;
+}
 
 
 /*
@@ -58,6 +106,7 @@ static inline int ext2_match (int len, const char * const name,
         return !memcmp(name, de->name, len);
 }
 
+
 /*
  *      obdfs_find_entry()
  *
@@ -147,42 +196,6 @@ failure:
         return NULL;
 } /* obdfs_find_entry */
 
-struct dentry *obdfs_lookup(struct inode *dir, struct dentry *dentry)
-{
-        struct inode * inode;
-        struct ext2_dir_entry_2 * de;
-        struct page *page;
-        ENTRY;
-
-        if (dentry->d_name.len > EXT2_NAME_LEN)
-                return ERR_PTR(-ENAMETOOLONG);
-
-        page = obdfs_find_entry(dir, dentry->d_name.name, dentry->d_name.len,
-                                &de, LOCKED);
-        inode = NULL;
-        if ( !page ) 
-                CDEBUG(D_INFO, "No page - negative entry.\n");
-        if ( page && !de ) {
-                CDEBUG(D_INODE, "Danger: PAGE but de.\n");
-                return ERR_PTR(-ENOENT);
-        }
-        if (page) {
-                unsigned long ino = le32_to_cpu(de->inode);
-                page_cache_release(page);
-                obd_unlock_page(page);
-                inode = iget(dir->i_sb, ino);
-
-                if (!inode) { 
-                        CDEBUG(D_INODE, "No inode.\n");
-                        EXIT;
-                        return ERR_PTR(-EACCES);
-                }
-        }
-        d_add(dentry, inode);
-        EXIT;
-        return NULL;
-} /* obdfs_lookup */
-
 /*
  *      obdfs_add_entry()
  *
@@ -342,7 +355,7 @@ static struct page *obdfs_add_entry (struct inode * dir,
                         dir->i_version = ++event;
                         *res_dir = de;
                         *err = 0;
-                        PDEBUG(page, "add_entry");
+                       //                        PDEBUG(page, "add_entry");
                         /* XXX unlock page here */
                         EXIT;
                         return page;
@@ -519,174 +532,158 @@ static struct inode *obdfs_new_inode(struct inode *dir, int mode)
  */
 int obdfs_create (struct inode * dir, struct dentry * dentry, int mode)
 {
-        struct inode * inode;
-        struct page *page;
-        struct ext2_dir_entry_2 * de;
-        int err = -EIO;
-
-        ENTRY;
-        inode = obdfs_new_inode(dir, mode);
-        if ( IS_ERR(inode) ) {
-                EXIT;
-                return PTR_ERR(inode);
-        }
-
-        inode->i_op = &obdfs_file_inode_operations;
-        mark_inode_dirty(inode);
-        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-        if (!page) {
-                inode->i_nlink--;
-                mark_inode_dirty(inode);
-                iput (inode);
-                EXIT;
-                return err;
-        }
-        de->inode = cpu_to_le32(inode->i_ino);
-        ext2_set_de_type(dir->i_sb, de, S_IFREG);
-        dir->i_version = ++event;
-
-        err = obdfs_do_writepage(page, IS_SYNC(dir));
-        obd_unlock_page(page);
-        page_cache_release(page);
-        d_instantiate(dentry, inode);
-        EXIT;
-        return err;
+       struct inode * inode = obdfs_new_inode (dir, mode);
+       int err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               inode->i_op = &obdfs_file_inode_operations;
+               inode->i_fop = &obdfs_file_operations;
+               inode->i_mapping->a_ops = &obdfs_aops;
+               mark_inode_dirty(inode);
+               err = ext2_add_nondir(dentry, inode);
+       }
+       return err;
 } /* obdfs_create */
 
+
 int obdfs_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
-        struct inode * inode;
-        struct page *page;
-        struct ext2_dir_entry_2 * de;
-        struct obdfs_inode_info *oinfo;
-        int err;
-
-        ENTRY;
-        inode = obdfs_new_inode(dir, mode);
-        if ( IS_ERR(inode) ) {
-                EXIT;
-                return PTR_ERR(inode);
-        }
+       struct inode * inode = obdfs_new_inode (dir, mode);
+       int err = PTR_ERR(inode);
+       if (!IS_ERR(inode)) {
+               init_special_inode(inode, mode, rdev);
+               mark_inode_dirty(inode);
+               err = ext2_add_nondir(dentry, inode);
+       }
+       return err;
+}
 
-        inode->i_uid = current->fsuid;
-        init_special_inode(inode, mode, rdev);
+int obdfs_symlink (struct inode * dir, struct dentry * dentry,
+       const char * symname)
+{
+       struct super_block * sb = dir->i_sb;
+       int err = -ENAMETOOLONG;
+       unsigned l = strlen(symname)+1;
+       struct inode * inode;
+        struct obdfs_inode_info *oinfo;
         oinfo = obdfs_i2info(inode);
-        ((obd_count *)oinfo->oi_inline)[0] = rdev;
-        oinfo->oi_flags |= OBD_FL_INLINEDATA;
 
-        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-        if (!page)
-                goto out_no_entry;
-        de->inode = cpu_to_le32(inode->i_ino);
-        dir->i_version = ++event;
-        ext2_set_de_type(dir->i_sb, de, inode->i_mode);
-        mark_inode_dirty(inode);
+       if (l > sb->s_blocksize)
+               goto out;
 
-        err = obdfs_do_writepage(page, IS_SYNC(dir));
-        obd_unlock_page(page);
+       inode = obdfs_new_inode (dir, S_IFLNK | S_IRWXUGO);
+       err = PTR_ERR(inode);
+       if (IS_ERR(inode))
+               goto out;
 
-        d_instantiate(dentry, inode);
-        page_cache_release(page);
-        err = 0;
+        if (l >= sizeof(oinfo->oi_inline)) {
+               /* slow symlink */
+               inode->i_op = &obdfs_symlink_inode_operations;
+               inode->i_mapping->a_ops = &obdfs_aops;
+               err = block_symlink(inode, symname, l);
+               if (err)
+                       goto out_fail;
+       } else {
+               /* fast symlink */
+               inode->i_op = &obdfs_fast_symlink_inode_operations;
+               memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
+               inode->i_size = l-1;
+       }
+       mark_inode_dirty(inode);
+
+       err = ext2_add_nondir(dentry, inode);
 out:
-        return err;
+       return err;
 
-out_no_entry:
-        inode->i_nlink--;
-        mark_inode_dirty(inode);
-        iput(inode);
-        goto out;
-} /* obdfs_mknod */
+out_fail:
+       ext2_dec_count(inode);
+       iput (inode);
+       goto out;
+}
 
-int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+
+
+int obdfs_link (struct dentry * old_dentry, struct inode * dir,
+       struct dentry *dentry)
 {
-        struct inode * inode;
-        struct page *page, *inode_page;
-        struct ext2_dir_entry_2 * de;
-        int err;
+       struct inode *inode = old_dentry->d_inode;
 
-        ENTRY;
+       if (S_ISDIR(inode->i_mode))
+               return -EPERM;
 
-        err = -EMLINK;
-        if (dir->i_nlink >= EXT2_LINK_MAX)
-                goto out;
+       if (inode->i_nlink >= EXT2_LINK_MAX)
+               return -EMLINK;
 
-        mode |= S_IFDIR;
-        if (dir->i_mode & S_ISGID)
-                mode |= S_ISGID;
+       inode->i_ctime = CURRENT_TIME;
+       ext2_inc_count(inode);
+       atomic_inc(&inode->i_count);
 
-        inode = obdfs_new_inode(dir, mode);
-        if ( IS_ERR(inode) ) {
-                EXIT;
-                return PTR_ERR(inode);
-        }
+       return ext2_add_nondir(dentry, inode);
+}
 
-        inode->i_op = &obdfs_dir_inode_operations;
-        inode->i_blocks = 0;    
-        inode_page = obdfs_getpage(inode, 0, 1, LOCKED);
-        if (!inode_page) {
-                inode->i_nlink--; /* is this nlink == 0? */
-                mark_inode_dirty(inode);
-                iput (inode);
-                return -EIO;
-        }
-        de = (struct ext2_dir_entry_2 *) page_address(inode_page);
-
-        /* create . and .. */
-        de->inode = cpu_to_le32(inode->i_ino);
-        de->name_len = 1;
-        de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
-        strcpy (de->name, ".");
-        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-        de = (struct ext2_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
-        de->inode = cpu_to_le32(dir->i_ino);
-        de->rec_len = cpu_to_le16(PAGE_SIZE - EXT2_DIR_REC_LEN(1));
-        de->name_len = 2;
-        strcpy (de->name, "..");
-        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-        inode->i_nlink = 2;
-        
-        err = obdfs_do_writepage(inode_page, IS_SYNC(inode));
-        inode->i_blocks = PAGE_SIZE/inode->i_sb->s_blocksize;
-        inode->i_size = PAGE_SIZE;
-        obd_unlock_page(inode_page);
-        page_cache_release(inode_page);
-        mark_inode_dirty(inode);
-        if (err) {
-                EXIT;
-                goto out_no_entry;
-        }
 
-        /* now deal with the parent */
-        page = obdfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-        if (!page) {
-                EXIT;
-                goto out_no_entry;
-        }
+int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+       struct inode * inode;
+       int err = -EMLINK;
 
-        de->inode = cpu_to_le32(inode->i_ino);
-        ext2_set_de_type(dir->i_sb, de, S_IFDIR);
-        dir->i_version = ++event;
+       if (dir->i_nlink >= EXT2_LINK_MAX)
+               goto out;
 
-        dir->i_nlink++;
-        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-        mark_inode_dirty(dir);
-        err = obdfs_do_writepage(page, IS_SYNC(dir));
+       ext2_inc_count(dir);
 
-        obd_unlock_page(page);
+       inode = obdfs_new_inode (dir, S_IFDIR | mode);
+       err = PTR_ERR(inode);
+       if (IS_ERR(inode))
+               goto out_dir;
 
-        page_cache_release(page);
-        d_instantiate(dentry, inode);
-        EXIT;
+       inode->i_op = &obdfs_dir_inode_operations;
+       inode->i_fop = &obdfs_dir_operations;
+       inode->i_mapping->a_ops = &obdfs_aops;
+
+       ext2_inc_count(inode);
+
+       err = ext2_make_empty(inode, dir);
+       if (err)
+               goto out_fail;
+
+       err = ext2_add_link(dentry, inode);
+       if (err)
+               goto out_fail;
+
+       d_instantiate(dentry, inode);
 out:
-        return err;
+       return err;
+
+out_fail:
+       ext2_dec_count(inode);
+       ext2_dec_count(inode);
+       iput(inode);
+out_dir:
+       ext2_dec_count(dir);
+       goto out;
+}
 
-out_no_entry:
-        inode->i_nlink = 0;
-        mark_inode_dirty(inode);
-        iput (inode);
-        goto out;
-} /* obdfs_mkdir */
+int obdfs_unlink(struct inode * dir, struct dentry *dentry)
+{
+       struct inode * inode = dentry->d_inode;
+       struct ext2_dir_entry_2 * de;
+       struct page * page;
+       int err = -ENOENT;
+
+       de = ext2_find_entry (dir, dentry, &page);
+       if (!de)
+               goto out;
+
+       err = ext2_delete_entry (de, page);
+       if (err)
+               goto out;
+
+       inode->i_ctime = dir->i_ctime;
+       ext2_dec_count(inode);
+       err = 0;
+out:
+       return err;
+}
 
 
 /*
@@ -810,171 +807,7 @@ end_rmdir:
         return retval;
 } /* obdfs_rmdir */
 
-int obdfs_unlink(struct inode * dir, struct dentry *dentry)
-{
-        int retval;
-        struct inode * inode;
-        struct page *page;
-        struct ext2_dir_entry_2 * de;
-
-        ENTRY;
-
-        retval = -ENOENT;
-        page = obdfs_find_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, LOCKED);
-        if (!page)
-                goto end_unlink;
-
-        inode = dentry->d_inode;
-        DQUOT_INIT(inode);
-
-        retval = -EIO;
-        if (le32_to_cpu(de->inode) != inode->i_ino)
-                goto end_unlink;
-        
-        if (!inode->i_nlink) {
-                ext2_warning (inode->i_sb, "ext2_unlink",
-                              "Deleting nonexistent file (%lu), %d",
-                              inode->i_ino, inode->i_nlink);
-                inode->i_nlink = 1;
-        }
-        retval = obdfs_delete_entry (de, page);
-        if (retval)
-                goto end_unlink;
-        dir->i_version = ++event;
-        retval = obdfs_do_writepage(page, IS_SYNC(dir));
-        /* XXX handle err? */
-        obd_unlock_page(page);
-
-        dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-        dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL;
-        mark_inode_dirty(dir);
-        inode->i_nlink--;
-        mark_inode_dirty(inode);
-        inode->i_ctime = dir->i_ctime;
-        d_delete(dentry);       /* This also frees the inode */
-
-end_unlink:
-        if (page)
-                page_cache_release(page);
-        EXIT;
-        return retval;
-} /* obdfs_unlink */
-
-int obdfs_symlink (struct inode * dir, struct dentry *dentry,
-                   const char * symname)
-{
-        struct inode * inode;
-        struct ext2_dir_entry_2 * de;
-        struct obdfs_inode_info *oinfo;
-        struct page* page = NULL, * name_page = NULL;
-        char * link;
-        int l, err;
-
-        ENTRY;
-        err = -ENAMETOOLONG;
-        l = strlen(symname)+1;
-        if (l > PAGE_SIZE) {
-                EXIT;
-                goto out;
-        }
-
-        inode = obdfs_new_inode(dir, S_IFLNK);
-        if ( IS_ERR(inode) ) {
-                EXIT;
-                goto out;
-        }
-
-        inode->i_mode = S_IFLNK | S_IRWXUGO;
-        oinfo = obdfs_i2info(inode);
-
-        if (l >= sizeof(oinfo->oi_inline)) {
-                CDEBUG(D_INFO, "l=%d, normal symlink\n", l);
-                inode->i_op = &obdfs_symlink_inode_operations;
-
-                name_page = obdfs_getpage(inode, 0, 1, LOCKED);
-                if (!name_page) {
-                        EXIT;
-                        err = -ENOMEM;
-                        goto out_no_entry;
-                }
-                link = (char *)page_address(name_page);
-        } else {
-                CDEBUG(D_INFO, "l=%d, fast symlink\n", l);
-                inode->i_op = &obdfs_fast_symlink_inode_operations;
-                link = oinfo->oi_inline;
-                oinfo->oi_flags |= OBD_FL_INLINEDATA;
-        }
-        memcpy(link, symname, l);
-        if (name_page) {
-                err = obdfs_do_writepage(name_page, IS_SYNC(inode));
-                /* PDEBUG(name_page, "symlink"); */
-                obd_unlock_page(name_page);
-                page_cache_release(name_page);
-                if (err) {
-                        EXIT;
-                        goto out_no_entry;
-                }
-        }
-        inode->i_size = l-1;
-        mark_inode_dirty(inode);
-
-        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len,
-                                &de, &err);
-        if (!page)
-                goto out_no_entry;
-        de->inode = cpu_to_le32(inode->i_ino);
-        ext2_set_de_type(dir->i_sb, de, S_IFLNK);
-        dir->i_version = ++event;
-        err = obdfs_do_writepage(page, IS_SYNC(dir));
-        obd_unlock_page(page);
-
-        d_instantiate(dentry, inode);
-out:
-        EXIT;
-        return err;
-
-out_no_entry:
-        inode->i_nlink--;
-        mark_inode_dirty(inode);
-        iput (inode);
-        goto out;
-} /* obdfs_symlink */
-
-int obdfs_link (struct dentry * old_dentry,
-                struct inode * dir, struct dentry *dentry)
-{
-        struct inode *inode = old_dentry->d_inode;
-        struct ext2_dir_entry_2 * de;
-        struct page *page;
-        int err;
-
-        ENTRY;
-
-        if (S_ISDIR(inode->i_mode))
-                return -EPERM;
-
-        if (inode->i_nlink >= EXT2_LINK_MAX)
-                return -EMLINK;
-
-        page = obdfs_add_entry (dir, dentry->d_name.name, dentry->d_name.len, &de, &err);
-        if (!page)
-                return err;
-
-        de->inode = cpu_to_le32(inode->i_ino);
-        ext2_set_de_type(dir->i_sb, de, inode->i_mode);
-        dir->i_version = ++event;
-
-        err = obdfs_do_writepage(page, IS_SYNC(dir));
-        obd_unlock_page(page);
 
-        page_cache_release(page);
-        inode->i_nlink++;
-        inode->i_ctime = CURRENT_TIME;
-        mark_inode_dirty(inode);
-        atomic_inc(&inode->i_count);
-        d_instantiate(dentry, inode);
-        return err;
-} /* obdfs_link */
 
 #define PARENT_INO(buffer) \
         ((struct ext2_dir_entry_2 *) ((char *) buffer + \
index 347ba2a..313ebd3 100644 (file)
@@ -77,8 +77,7 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create)
 /* returns the page unlocked, but with a reference */
 int obdfs_readpage(struct file *file, struct page *page)
 {
-        struct dentry *dentry = file->f_dentry;
-        struct inode *inode = dentry->d_inode;
+       struct inode *inode = page->mapping->host;
         int rc;
 
         ENTRY;
index 1fb0444..9af4896 100644 (file)
@@ -324,6 +324,7 @@ static void obdfs_read_inode(struct inode *inode)
         } else if (S_ISDIR(inode->i_mode)) {
                 inode->i_op = &obdfs_dir_inode_operations;
                 inode->i_fop = &obdfs_dir_operations; 
+                inode->i_mapping->a_ops = &obdfs_aops;
                 EXIT;
         } else if (S_ISLNK(inode->i_mode)) {
                 if (inode->i_blocks) {