From 37b7de1e7e692510cf04378eb614049d156da81b Mon Sep 17 00:00:00 2001 From: adilger Date: Tue, 11 Jan 2000 08:36:16 +0000 Subject: [PATCH] Updated snapshot files for new obdo methods. No testing yet. --- lustre/demos/baseclean.sh | 1 - lustre/include/linux/obd_class.h | 57 ++++++++++++++---------- lustre/include/linux/obd_snap.h | 54 +---------------------- lustre/include/linux/obd_snap_support.h | 66 ++++++++++++++++++++++++++-- lustre/include/linux/obdfs.h | 37 +++++++--------- lustre/obdclass/genops.c | 39 ++++++++++++----- lustre/obdfs/flushd.c | 13 +++--- lustre/obdfs/namei.c | 21 +++++---- lustre/obdfs/rw.c | 78 +++++++++++++++++++++------------ lustre/obdfs/super.c | 13 ++---- lustre/obdfs/symlink.c | 65 +++++++++++++-------------- 11 files changed, 245 insertions(+), 199 deletions(-) diff --git a/lustre/demos/baseclean.sh b/lustre/demos/baseclean.sh index 0daf84b..abe4d73 100755 --- a/lustre/demos/baseclean.sh +++ b/lustre/demos/baseclean.sh @@ -27,7 +27,6 @@ fi rmmod loop > /dev/null 2>&1 if [ "$TMPFILE" -a -f "$TMPFILE" ]; then - echo -n "Remove $TMPFILE [N/y]? " rm -i $TMPFILE fi diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 2cd4c29..804d66a 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -216,6 +216,7 @@ static __inline__ struct obdo *obdo_fromid(struct obd_conn *conn, obd_id id) } memset(res, 0, sizeof(*res)); res->o_id = id; + res->o_valid = ~OBD_MD_FLOBDMD; if (OBP(conn->oc_dev, getattr)(conn, res)) { OBD_FREE(res, sizeof(*res)); EXIT; @@ -363,29 +364,41 @@ static __inline__ void obdo_to_inode(struct inode *dst, struct obdo *src) dst->i_generation = src->o_generation; } -static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src) +static __inline__ int obdo_cmp_md(struct obdo *dst, struct obdo *src, + obd_flag compare) { - int res = 1; - - if ( src->o_valid & OBD_MD_FLMODE ) - res = (res && (dst->o_mode == src->o_mode)); - if ( src->o_valid & OBD_MD_FLUID ) - res = (res && (dst->o_uid == src->o_uid)); - if ( src->o_valid & OBD_MD_FLGID ) - res = (res && (dst->o_gid == src->o_gid)); - if ( src->o_valid & OBD_MD_FLSIZE ) - res = (res && (dst->o_size == src->o_size)); - if ( src->o_valid & OBD_MD_FLATIME ) - res = (res && (dst->o_atime == src->o_atime)); - if ( src->o_valid & OBD_MD_FLMTIME ) - res = (res && (dst->o_mtime == src->o_mtime)); - if ( src->o_valid & OBD_MD_FLCTIME ) - res = (res && (dst->o_ctime == src->o_ctime)); - if ( src->o_valid & OBD_MD_FLFLAGS ) - res = (res && (dst->o_flags == src->o_flags)); - /* allocation of space */ - if ( src->o_valid & OBD_MD_FLBLOCKS ) - res = (res && (dst->o_blocks == src->o_blocks)); + int res = 0; + + if ( compare & OBD_MD_FLATIME ) + res = (res || (dst->o_atime != src->o_atime)); + if ( compare & OBD_MD_FLMTIME ) + res = (res || (dst->o_mtime != src->o_mtime)); + if ( compare & OBD_MD_FLCTIME ) + res = (res || (dst->o_ctime != src->o_ctime)); + if ( compare & OBD_MD_FLSIZE ) + res = (res || (dst->o_size != src->o_size)); + if ( compare & OBD_MD_FLBLOCKS ) /* allocation of space */ + res = (res || (dst->o_blocks != src->o_blocks)); + if ( compare & OBD_MD_FLBLKSZ ) + res = (res || (dst->o_blksize != src->o_blksize)); + if ( compare & OBD_MD_FLMODE ) + res = (res || (dst->o_mode != src->o_mode)); + if ( compare & OBD_MD_FLUID ) + 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_FLFLAGS ) + res = (res || (dst->o_flags != src->o_flags)); + if ( compare & OBD_MD_FLNLINK ) + res = (res || (dst->o_nlink != src->o_nlink)); + if ( compare & OBD_MD_FLGENER ) + res = (res || (dst->o_generation != src->o_generation)); + /* XXX Don't know if thses should be included here + if ( compare & OBD_MD_FLINLINE ) + res = (res || memcmp(dst->o_inline, src->o_inline)); + if ( compare & OBD_MD_FLOBDMD ) + res = (res || memcmp(dst->o_obdmd, src->o_obdmd)); + */ return res; } diff --git a/lustre/include/linux/obd_snap.h b/lustre/include/linux/obd_snap.h index e2b79d2..9d1ba8c 100644 --- a/lustre/include/linux/obd_snap.h +++ b/lustre/include/linux/obd_snap.h @@ -3,72 +3,20 @@ #define OBD_SNAP_MAGIC 0xfffffff3 /* an unlikely block number */ -/* maximum number of snapshot tables we maintain in the kernel */ -#define SNAP_MAX_TABLES 8 - - -/* maximum number of snapshots per device - must fit in "u" area of struct inode */ -#define SNAP_MAX (EXT2_N_BLOCKS-1) - - /* ioctls for manipulating snapshots 40 - 60 */ #define OBD_SNAP_SETTABLE _IOWR('f', 40, long) #define OBD_SNAP_PRINTTABLE _IOWR('f', 41, long) #define OBD_SNAP_DELETE _IOWR('f', 42, long) #define OBD_SNAP_RESTORE _IOWR('f', 43, long) - - -/* if time is 0 this designates the "current" snapshot, i.e. - the head of the tree -*/ -struct snap { - time_t time; - int index; -}; - -/* snap ioctl data for attach: current always in first slot of this array */ -struct snap_obd_data { - int snap_dev; /* which device contains the data */ - unsigned int snap_index;/* which snapshot is ours */ - unsigned int snap_table;/* which table do we use */ -}; - - -/* snap ioctl data for table fiddling */ -struct snap_table_data { - int tblcmd_no; /* which table */ - unsigned int tblcmd_count; /* how many snaps */ - struct snap tblcmd_snaps[SNAP_MAX]; /* sorted times! */ -}; - - -struct snap_table { - spinlock_t tbl_lock; - unsigned int tbl_count; /* how many snapshots exist in this table*/ - int tbl_used; /* bitmap of snaps in use by a device */ - time_t tbl_times[SNAP_MAX]; - int tbl_index[SNAP_MAX]; -}; - - /* this is the obd device descriptor: - - current snapshot ends up in first slot of this array + * - current snapshot ends up in first slot of this array */ struct snap_obd { unsigned int snap_index; /* which snapshot index are we accessing */ int snap_tableno; }; - -/* stored as inline data in the objects */ -struct snap_object_data { - int od_magic; - /* id of snaps of object; slot 0 has the current data */ - unsigned long od_ids[SNAP_MAX]; -}; - void snap_use(int table_no, int snap_index) ; void snap_unuse(int table_no, int snap_index) ; int snap_is_used(int table_no, int snap_index) ; diff --git a/lustre/include/linux/obd_snap_support.h b/lustre/include/linux/obd_snap_support.h index ca4e615..ff8fc9a 100644 --- a/lustre/include/linux/obd_snap_support.h +++ b/lustre/include/linux/obd_snap_support.h @@ -1,6 +1,58 @@ #ifndef __OBD_SNAP_SUPP_H #define __OBD_SNAP_SUPP_H +/* What we use to point to IDs in the obdmd data for snapshots. If we use + * obd_id (8 bytes) instead of ino_t (4 bytes), we halve the number of + * available snapshot slots (14 in 56 bytes vs. 7 in 56 bytes until we + * increase the size of OBD_OBDMDSZ). + */ +typedef ino_t snap_id; + +/* maximum number of snapshot tables we maintain in the kernel */ +#define SNAP_MAX_TABLES 8 + +/* maximum number of snapshots per device + must fit in "o_obdmd" area of struct obdo */ +#define SNAP_MAX ((OBD_OBDMDSZ - sizeof(uint32_t))/sizeof(snap_id)) + +struct snap_md { + uint32_t m_magic; + snap_id m_ids[SNAP_MAX]; /* id of snaps; slot 0 has current id */ +}; + + +/* if time is 0 this designates the "current" snapshot, i.e. + the head of the tree +*/ +struct snap { + time_t time; + int index; +}; + +/* snap ioctl data for attach: current always in first slot of this array */ +struct snap_obd_data { + int snap_dev; /* which device contains the data */ + unsigned int snap_index;/* which snapshot is ours */ + unsigned int snap_table;/* which table do we use */ +}; + + +/* snap ioctl data for table fiddling */ +struct snap_table_data { + int tblcmd_no; /* which table */ + unsigned int tblcmd_count; /* how many snaps */ + struct snap tblcmd_snaps[SNAP_MAX]; /* sorted times! */ +}; + + +struct snap_table { + spinlock_t tbl_lock; + unsigned int tbl_count; /* how many snapshots exist in this table*/ + int tbl_used; /* bitmap of snaps in use by a device */ + time_t tbl_times[SNAP_MAX]; + int tbl_index[SNAP_MAX]; +}; + struct snap_iterdata { struct obd_conn *conn; struct obd_conn *ch_conn; @@ -11,11 +63,17 @@ struct snap_iterdata { time_t prevtime; }; - inline struct obd_conn *child_conn(struct obd_conn *conn); -int snap_deleteobj(obd_id id, void *data); -int snap_restoreobj(obd_id id, void *data); -int snap_printobj(obd_id id, void *data); +int snap_deleteobj(obd_id id, obd_gr group, void *data); +int snap_restoreobj(obd_id id, obd_gr group, void *data); +int snap_printobj(obd_id id, obd_gr group, void *data); int snap_iocontrol(int cmd, struct obd_conn *conn, int len, void *karg, void *uarg); +/* In the future, this function may have to deal with offsets into the obdmd. + * Currently, we assume we have the whole obdmd struct. + */ +static __inline__ struct snap_md *snap_obdmd(struct obdo *oa) +{ + return ((struct snap_md *)(&oa->o_obdmd)); +} #endif diff --git a/lustre/include/linux/obdfs.h b/lustre/include/linux/obdfs.h index cad8f07..405bdb2 100644 --- a/lustre/include/linux/obdfs.h +++ b/lustre/include/linux/obdfs.h @@ -58,8 +58,8 @@ struct obdfs_super_info { /* list of all OBDFS super blocks */ struct list_head obdfs_super_list; struct obdfs_super_entry { - struct list_head sl_chain; - struct obdfs_super_info *sl_sbi; + struct list_head sl_chain; + struct obdfs_super_info *sl_sbi; }; struct obdfs_pgrq { @@ -70,25 +70,25 @@ struct obdfs_pgrq { }; struct obdfs_sb_info { - struct obd_conn osi_conn; - struct super_block *osi_super; - struct obd_device *osi_obd; - struct obd_ops *osi_ops; - ino_t osi_rootino; /* which root inode */ - int osi_minor; /* minor of /dev/obdX */ - struct list_head osi_list; /* linked list of inodes to write */ + struct obd_conn osi_conn; + struct super_block *osi_super; + struct obd_device *osi_obd; + struct obd_ops *osi_ops; + ino_t osi_rootino; /* which root inode */ + int osi_minor; /* minor of /dev/obdX */ + struct list_head osi_list; /* linked list of inodes to write */ }; struct obdfs_inode_info { int oi_flags; struct list_head oi_pages; - char *oi_inline; + char oi_inline[OBD_INLINESZ]; }; -#define OBD_LIST(inode) (((struct obdfs_inode_info *)(&(inode)->u.generic_ip))->oi_pages) -#define WREQ(entry) (list_entry(entry, struct obdfs_pgrq, rq_list)) -#define OBD_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip)) +#define OBDFS_LIST(inode) (((struct obdfs_inode_info *)(&(inode)->u.generic_ip))->oi_pages) +#define WREQ(entry) (list_entry(entry, struct obdfs_pgrq, rq_list)) +#define OBDFS_INFO(inode) ((struct obdfs_inode_info *)(&(inode)->u.generic_ip)) void obdfs_sysctl_init(void); void obdfs_sysctl_clean(void); @@ -98,16 +98,9 @@ extern struct inode_operations obdfs_file_inode_operations; extern struct inode_operations obdfs_dir_inode_operations; extern struct inode_operations obdfs_symlink_inode_operations; -static inline struct obd_ops *iops(struct inode *i) +static inline int obdfs_has_inline(struct inode *inode) { - struct obdfs_sb_info *sbi = (struct obdfs_sb_info *) &i->i_sb->u.generic_sbp; - return sbi->osi_ops; -} - -static inline struct obd_conn *iid(struct inode *i) -{ - struct obdfs_sb_info *sbi = (struct obdfs_sb_info *) &i->i_sb->u.generic_sbp; - return &sbi->osi_conn; + return (OBDFS_INFO(inode)->oi_flags & OBD_FL_INLINEDATA); } #define NOLOCK 0 diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 10a69dc..fc79194 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -38,6 +38,7 @@ int obd_init_obdo_cache(void) { ENTRY; if (obdo_cachep == NULL) { + CDEBUG(D_INODE, "allocating obdo_cache\n"); obdo_cachep = kmem_cache_create("obdo_cache", sizeof(struct obdo), 0, SLAB_HWCACHE_ALIGN, @@ -45,7 +46,11 @@ int obd_init_obdo_cache(void) if (obdo_cachep == NULL) { EXIT; return -ENOMEM; + } else { + CDEBUG(D_INODE, "allocated cache at %p\n", obdo_cachep); } + } else { + CDEBUG(D_INODE, "using existing cache at %p\n", obdo_cachep); } EXIT; return 0; @@ -55,8 +60,11 @@ void obd_cleanup_obdo_cache(void) { ENTRY; if (obdo_cachep != NULL) { + /* + CDEBUG(D_INODE, "shrinking obdo_cache at %p\n", obdo_cachep); if (kmem_cache_shrink(obdo_cachep)) printk(KERN_INFO "obd_cleanup_obdo_cache: unable to free all of cache\n"); + */ } else printk(KERN_INFO "obd_cleanup_obdo_cache: called with NULL cache pointer\n"); @@ -239,16 +247,15 @@ void lck_page(struct page *page) ___wait_on_page(page); } -/* XXX this should return errors correctly, so should migrate!!! */ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst, struct obd_conn *src_conn, struct obdo *src, obd_size count, obd_off offset) { struct page *page; unsigned long index = 0; - int rc; - ENTRY; + int err = 0; + ENTRY; CDEBUG(D_INODE, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n", src->o_id, src->o_blocks, src->o_size, dst->o_id); page = alloc_page(GFP_USER); @@ -260,26 +267,34 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst, lck_page(page); while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) { - obd_size count = PAGE_SIZE; + obd_size brw_count; + brw_count = PAGE_SIZE; + page->index = index; - rc = OBP(src_conn->oc_dev, brw) + err = OBP(src_conn->oc_dev, brw) (READ, src_conn, src, (char *)page_address(page), - &count, (page->index) << PAGE_SHIFT, 0); + &brw_count, (page->index) << PAGE_SHIFT, 0); - if ( rc != 0 ) + if ( err ) { + EXIT; break; + } CDEBUG(D_INODE, "Read page %ld ...\n", page->index); - rc = OBP(dst_conn->oc_dev, brw) + err = OBP(dst_conn->oc_dev, brw) (WRITE, dst_conn, dst, (char *)page_address(page), - &count, (page->index) << PAGE_SHIFT, 1); - if ( rc != 0) + &brw_count, (page->index) << PAGE_SHIFT, 1); + + /* XXX should handle dst->o_size, dst->o_blocks here */ + if ( err ) { + EXIT; break; + } CDEBUG(D_INODE, "Wrote page %ld ...\n", page->index); - index ++; + index++; } dst->o_size = src->o_size; dst->o_blocks = src->o_blocks; @@ -288,5 +303,5 @@ int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst, __free_page(page); EXIT; - return 0; + return err; } diff --git a/lustre/obdfs/flushd.c b/lustre/obdfs/flushd.c index e94b6bf..8a3eaf4 100644 --- a/lustre/obdfs/flushd.c +++ b/lustre/obdfs/flushd.c @@ -1,7 +1,7 @@ /* * OBDFS Super operations - also used for Lustre file system * - * + * * Copyright (C) 1991, 1992 Linus Torvalds * Copryright (C) 1999 Stelias Computing Inc. * Copryright (C) 1999 Seagate Technology Inc. @@ -82,7 +82,7 @@ static void obdfs_flush_dirty_pages(int check_time) while ( (sl = sl->next) != &obdfs_super_list ) { struct obdfs_super_entry *entry = list_entry(sl, struct obdfs_super_entry, sl_chain); - struct obdfs_super_info *sbi = entry->sl_sbi; + sbi = entry->sl_sbi; /* walk write requests here */ obdfs_flush_reqs(sbi, jiffies); @@ -96,6 +96,7 @@ static void obdfs_flush_dirty_pages(int check_time) sbi = entry->sl_sbi; /* walk write requests here */ + /* XXX should jiffies be 0 here? */ obdfs_flush_reqs(sbi, jiffies); } } @@ -107,15 +108,17 @@ static int pupdate(void *unused) struct task_struct * tsk = current; int interval; - pupdated = current; tsk->session = 1; tsk->pgrp = 1; strcpy(tsk->comm, "pupdate"); + pupdated = current; + + printk("pupdate() activated...\n"); /* sigstop and sigcont will stop and wakeup kupdate */ spin_lock_irq(&tsk->sigmask_lock); sigfillset(&tsk->blocked); - siginitsetinv(¤t->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); + siginitsetinv(&tsk->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP)); recalc_sigpending(tsk); spin_unlock_irq(&tsk->sigmask_lock); @@ -130,6 +133,7 @@ static int pupdate(void *unused) else { stop_pupdate: + printk("pupdate() stopped...\n"); tsk->state = TASK_STOPPED; MOD_DEC_USE_COUNT; schedule(); /* wait for SIGCONT */ @@ -149,7 +153,6 @@ static int pupdate(void *unused) if (stopped) goto stop_pupdate; } - printk("pupdate() activated...\n"); /* flush_inodes(); */ obdfs_flush_dirty_pages(1); } diff --git a/lustre/obdfs/namei.c b/lustre/obdfs/namei.c index 22fdde1..4c8419f 100644 --- a/lustre/obdfs/namei.c +++ b/lustre/obdfs/namei.c @@ -485,7 +485,9 @@ struct inode *obdfs_new_inode(struct inode *dir) return ERR_PTR(-EIO); } + INIT_LIST_HEAD(&OBDFS_LIST(inode)); obdo_free(oa); + EXIT; return inode; } /* obdfs_new_inode */ @@ -622,12 +624,12 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) strcpy (de->name, ".."); ext2_set_de_type(dir->i_sb, de, S_IFDIR); + /* XXX handle err */ err = obdfs_do_writepage(inode, inode_page, IS_SYNC(inode)); inode->i_blocks = PAGE_SIZE/inode->i_sb->s_blocksize; inode->i_size = PAGE_SIZE; UnlockPage(inode_page); page_cache_release(inode_page); - /* XXX handle err */ inode->i_nlink = 2; inode->i_mode = S_IFDIR | mode; @@ -649,12 +651,12 @@ int obdfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) dir->u.ext2_i.i_flags &= ~EXT2_BTREE_FL; mark_inode_dirty(dir); err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); + /* XXX handle err? */ UnlockPage(page); page_cache_release(page); d_instantiate(dentry, inode); - err = 0; out: EXIT; return err; @@ -766,6 +768,7 @@ int obdfs_rmdir (struct inode * dir, struct dentry *dentry) if (retval) goto end_rmdir; err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); + /* XXX handle err? */ UnlockPage(page); if (inode->i_nlink != 2) @@ -822,6 +825,7 @@ int obdfs_unlink(struct inode * dir, struct dentry *dentry) goto end_unlink; dir->i_version = ++event; err = obdfs_do_writepage(dir, page, IS_SYNC(dir)); + /* XXX handle err? */ UnlockPage(page); dir->i_ctime = dir->i_mtime = CURRENT_TIME; @@ -840,7 +844,8 @@ end_unlink: return retval; } /* obdfs_unlink */ -int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symname) +int obdfs_symlink (struct inode * dir, struct dentry *dentry, + const char * symname) { struct ext2_dir_entry_2 * de; struct inode * inode; @@ -852,7 +857,7 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna ENTRY; inode = obdfs_new_inode(dir); - oinfo = OBD_INFO(inode); + oinfo = OBDFS_INFO(inode); if ( IS_ERR(inode) ) { EXIT; return PTR_ERR(inode); @@ -860,11 +865,10 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_op = &obdfs_symlink_inode_operations; - for (l = 0; l < inode->i_sb->s_blocksize - 1 && - symname [l]; l++) + for (l = 0; l < inode->i_sb->s_blocksize - 1 && symname [l]; l++) ; - if (l >= sizeof (oinfo->oi_inline)) { + if (l >= sizeof(OBDFS_INFO(inode)->oi_inline)) { CDEBUG(D_INODE, "l=%d, normal symlink\n", l); name_page = obdfs_getpage(inode, 0, 1, LOCKED); @@ -888,7 +892,8 @@ int obdfs_symlink (struct inode * dir, struct dentry *dentry, const char * symna link[i++] = c; link[i] = 0; if (name_page) { - obdfs_do_writepage(inode, name_page, IS_SYNC(inode)); + err = obdfs_do_writepage(inode, name_page, IS_SYNC(inode)); + /* XXX handle err */ PDEBUG(name_page, "symlink"); UnlockPage(name_page); page_cache_release(name_page); diff --git a/lustre/obdfs/rw.c b/lustre/obdfs/rw.c index f58704b..e72d1b8 100644 --- a/lustre/obdfs/rw.c +++ b/lustre/obdfs/rw.c @@ -54,7 +54,9 @@ static int obdfs_brw(int rw, struct inode *inode, struct page *page, int create) err = IOPS(inode, brw)(rw, IID(inode), obdo, (char *)page_address(page), &count, (page->index) >> PAGE_SHIFT, create); - obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */ + if ( !err ) + obdo_to_inode(inode, obdo); /* copy o_blocks to i_blocks */ + obdo_free(obdo); EXIT; @@ -79,29 +81,45 @@ int obdfs_readpage(struct dentry *dentry, struct page *page) return rc; } /* obdfs_readpage */ -static kmem_cache_t *obdfs_pgrq_cachep; +static kmem_cache_t *obdfs_pgrq_cachep = NULL; int obdfs_init_pgrqcache(void) { ENTRY; - obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq", - sizeof(struct obdfs_pgrq), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); if (obdfs_pgrq_cachep == NULL) { - EXIT; - return -ENOMEM; + CDEBUG(D_INODE, "allocating obdfs_pgrq_cache\n"); + obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq", + sizeof(struct obdfs_pgrq), + 0, SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (obdfs_pgrq_cachep == NULL) { + EXIT; + return -ENOMEM; + } else { + CDEBUG(D_INODE, "allocated cache at %p\n", + obdfs_pgrq_cachep); + } + } else { + CDEBUG(D_INODE, "using existing cache at %p\n", + obdfs_pgrq_cachep); } - EXIT; return 0; } /* obdfs_init_wreqcache */ void obdfs_cleanup_pgrqcache(void) { - if (obdfs_pgrq_cachep != NULL) - kmem_cache_destroy(obdfs_pgrq_cachep); - obdfs_pgrq_cachep = NULL; + ENTRY; + if (obdfs_pgrq_cachep != NULL) { + /* + CDEBUG(D_INODE, "shrinking obdfs_pgrqcache at %p\n", + obdfs_pgrq_cachep); + if (kmem_cache_shrink(obdfs_pgrq_cachep)) + printk(KERN_INFO "obd_cleanup_pgrqcache: unable to free all of cache\n"); + */ + } else + printk(KERN_INFO "obd_cleanup_pgrqcache: called with NULL cache pointer\n"); + EXIT; } /* obdfs_cleanup_wreqcache */ @@ -113,7 +131,7 @@ void obdfs_cleanup_pgrqcache(void) static struct obdfs_pgrq * obdfs_find_in_page_cache(struct inode *inode, struct page *page) { - struct list_head *page_list = &OBD_LIST(inode); + struct list_head *page_list = &OBDFS_LIST(inode); struct list_head *tmp; struct obdfs_pgrq *pgrq; @@ -148,25 +166,29 @@ obdfs_remove_from_page_cache(struct obdfs_pgrq *pgrq) { struct inode *inode = pgrq->rq_inode; struct page *page = pgrq->rq_page; - int rc; + int err; ENTRY; CDEBUG(D_INODE, "removing inode %ld page %p, pgrq: %p\n", inode->i_ino, page, pgrq); - rc = obdfs_brw(WRITE, inode, page, 1); + OIDEBUG(inode); + PDEBUG(page, "REM_CACHE"); + err = obdfs_brw(WRITE, inode, page, 1); /* XXX probably should handle error here somehow. I think that * ext2 also does the same thing - discard write even if error? */ put_page(page); list_del(&pgrq->rq_list); kmem_cache_free(obdfs_pgrq_cachep, pgrq); + OIDEBUG(inode); EXIT; - return rc; + return err; } /* obdfs_remove_from_page_cache */ /* * Add a page to the write request cache list for later writing + * ASYNCHRONOUS write method. */ static int obdfs_add_to_page_cache(struct inode *inode, struct page *page) { @@ -186,7 +208,7 @@ static int obdfs_add_to_page_cache(struct inode *inode, struct page *page) pgrq->rq_inode = inode; get_page(pgrq->rq_page); - list_add(&pgrq->rq_list, &OBD_LIST(inode)); + list_add(&pgrq->rq_list, &OBDFS_LIST(inode)); /* For testing purposes, we write out the page here. * In the future, a flush daemon will write out the page. @@ -203,6 +225,7 @@ static int obdfs_add_to_page_cache(struct inode *inode, struct page *page) } /* obdfs_add_to_page_cache */ +/* select between SYNC and ASYNC I/O methods */ int obdfs_do_writepage(struct inode *inode, struct page *page, int sync) { int err; @@ -234,10 +257,12 @@ int obdfs_writepage(struct dentry *dentry, struct page *page) * * If the writer ends up delaying the write, the writer needs to * increment the page use counts until he is done with the page. + * + * Return value is the number of bytes written. */ int obdfs_write_one_page(struct file *file, struct page *page, - unsigned long offset, unsigned long bytes, - const char * buf) + unsigned long offset, unsigned long bytes, + const char * buf) { struct inode *inode = file->f_dentry->d_inode; int err; @@ -250,16 +275,15 @@ int obdfs_write_one_page(struct file *file, struct page *page, else return err; } - bytes -= copy_from_user((u8*)page_address(page) + offset, buf, bytes); - err = -EFAULT; - if (bytes) { - lock_kernel(); - err = obdfs_writepage(file->f_dentry, page); - unlock_kernel(); - } + if (copy_from_user((u8*)page_address(page) + offset, buf, bytes)) + return -EFAULT; - return err; + lock_kernel(); + err = obdfs_writepage(file->f_dentry, page); + unlock_kernel(); + + return (err < 0 ? err : bytes); } /* obdfs_write_one_page */ /* diff --git a/lustre/obdfs/super.c b/lustre/obdfs/super.c index daaf8cb..6e61ea7 100644 --- a/lustre/obdfs/super.c +++ b/lustre/obdfs/super.c @@ -292,18 +292,11 @@ static void obdfs_put_super(struct super_block *sb) EXIT; } -inline int obdfs_has_inline(struct inode *inode) -{ - struct obdfs_inode_info *oinfo = OBD_INFO(inode); - - return (oinfo->oi_flags & OBD_FL_INLINEDATA); -} - void inline obdfs_from_inode(struct obdo *oa, struct inode *inode) { obdo_from_inode(oa, inode); if (obdfs_has_inline(inode)) { - struct obdfs_inode_info *oinfo = OBD_INFO(inode); + struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); memcpy(oa->o_inline, oinfo->oi_inline, OBD_INLINESZ); oa->o_flags |= OBD_FL_INLINEDATA; @@ -314,7 +307,7 @@ void inline obdfs_to_inode(struct inode *inode, struct obdo *oa) { obdo_to_inode(inode, oa); if (obdo_has_inline(oa)) { - struct obdfs_inode_info *oinfo = OBD_INFO(inode); + struct obdfs_inode_info *oinfo = OBDFS_INFO(inode); memcpy(oinfo->oi_inline, oa->o_inline, OBD_INLINESZ); oinfo->oi_flags |= OBD_FL_INLINEDATA; @@ -351,7 +344,7 @@ void obdfs_read_inode(struct inode *inode) ODEBUG(oa); obdfs_to_inode(inode, oa); - INIT_LIST_HEAD(&OBD_LIST(inode)); + INIT_LIST_HEAD(&OBDFS_LIST(inode)); obdo_free(oa); OIDEBUG(inode); diff --git a/lustre/obdfs/symlink.c b/lustre/obdfs/symlink.c index 767f469..dc567b8 100644 --- a/lustre/obdfs/symlink.c +++ b/lustre/obdfs/symlink.c @@ -30,38 +30,8 @@ #include /* for ENTRY and EXIT only */ #include -/* -static int obdfs_readlink (struct dentry *, char *, int); -static struct dentry *obdfs_follow_link(struct dentry *, struct dentry *, unsigned int); -*/ - -/* - * symlinks can't do much... - */ -struct inode_operations obdfs_symlink_inode_operations = { - NULL, /* no file-operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - obdfs_readlink, /* readlink */ - obdfs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL /* revalidate */ -}; - /* static */ -struct dentry * obdfs_follow_link(struct dentry * dentry, - struct dentry *base, +struct dentry * obdfs_follow_link(struct dentry * dentry, struct dentry *base, unsigned int follow) { struct inode *inode = dentry->d_inode; @@ -69,8 +39,8 @@ struct dentry * obdfs_follow_link(struct dentry * dentry, char * link; ENTRY; - link = (char *) inode->u.ext2_i.i_data; - if (inode->i_blocks) { + link = OBDFS_INFO(inode)->oi_inline; + if (!obdfs_has_inline(inode)) { OIDEBUG(inode); page = obdfs_getpage(inode, 0, 0, 0); PDEBUG(page, "follow_link"); @@ -102,8 +72,8 @@ int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen) if (buflen > inode->i_sb->s_blocksize - 1) buflen = inode->i_sb->s_blocksize - 1; - link = (char *) inode->u.ext2_i.i_data; - if (inode->i_blocks) { + link = OBDFS_INFO(inode)->oi_inline; + if (!obdfs_has_inline(inode)) { OIDEBUG(inode); page = obdfs_getpage(inode, 0, 0, 0); PDEBUG(page, "readlink"); @@ -125,3 +95,28 @@ int obdfs_readlink (struct dentry * dentry, char * buffer, int buflen) EXIT; return i; } /* obdfs_readlink */ + +/* + * symlinks can't do much... + */ +struct inode_operations obdfs_symlink_inode_operations = { + NULL, /* no file-operations */ + NULL, /* create */ + NULL, /* lookup */ + NULL, /* link */ + NULL, /* unlink */ + NULL, /* symlink */ + NULL, /* mkdir */ + NULL, /* rmdir */ + NULL, /* mknod */ + NULL, /* rename */ + obdfs_readlink, /* readlink */ + obdfs_follow_link, /* follow_link */ + NULL, /* get_block */ + NULL, /* readpage */ + NULL, /* writepage */ + NULL, /* truncate */ + NULL, /* permission */ + NULL /* revalidate */ +}; + -- 1.8.3.1