From: braam Date: Wed, 23 Jan 2002 04:59:12 +0000 (+0000) Subject: It's been a good day: chmod/chown and friends now work for Lustre Light. X-Git-Tag: v1_7_100~6013 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4bca4a668d2b618a3746c2414296e43114226034;p=fs%2Flustre-release.git It's been a good day: chmod/chown and friends now work for Lustre Light. - most of the changes are in the packing. It will take a little bit more time before this completely settles I think, but we have a pretty efficient system now. - added initial infrastructure for MDS update records. - the MDS server has a new routine to change the attributes: the associated RPC call is MDS_REINT. - Lustre Light is simpler than OBDFS since it doesn't have to change inodes when it creates them: that's part of the MDS transactions we send over -- removed many "change inode" and "setattr" variants. --- diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 5b9b033..518c1c9 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -41,6 +41,7 @@ * - ioctl's */ + /* * OST requests: OBDO & OBD request records */ @@ -194,16 +195,10 @@ struct obd_bufref { #define MDS_TYPE_ERR 3 #define MDS_GETATTR 1 -#define MDS_SETATTR 2 +#define MDS_REINT 2 #define MDS_READPAGE 3 -#define MDS_CREATE 4 -#define MDS_LINK 5 -#define MDS_SYMLINK 6 -#define MDS_MKNOD 7 -#define MDS_MKDIR 8 -#define MDS_UNLINK 9 -#define MDS_RMDIR 10 -#define MDS_RENAME 11 + +#define REINT_SETATTR 1 struct mds_req_hdr { __u32 opc; @@ -212,7 +207,7 @@ struct mds_req_hdr { __u32 type; }; -struct lustre_fid { +struct ll_fid { __u64 id; __u32 generation; __u32 f_type; @@ -230,10 +225,11 @@ struct mds_rep_hdr { }; struct mds_req_packed { - struct lustre_fid fid1; - struct lustre_fid fid2; + struct ll_fid fid1; + struct ll_fid fid2; int namelen; int tgtlen; + __u32 opcode; __u32 valid; __u32 mode; __u32 uid; @@ -248,13 +244,11 @@ struct mds_req_packed { __u32 ino; __u32 nlink; __u32 generation; - __u32 name_offset; - __u32 tgt_offset; }; struct mds_rep_packed { - struct lustre_fid fid1; - struct lustre_fid fid2; + struct ll_fid fid1; + struct ll_fid fid2; int namelen; int tgtlen; __u32 valid; @@ -271,10 +265,42 @@ struct mds_rep_packed { __u32 ino; __u32 nlink; __u32 generation; - __u32 name_offset; - __u32 tgt_offset; }; + +struct mds_rec_setattr { + __u32 sa_len; + __u32 sa_opcode; + struct ll_fid sa_fid; + __u32 sa_valid; + __u32 sa_mode; + __u32 sa_uid; + __u32 sa_gid; + __u64 sa_size; + __u64 sa_atime; + __u64 sa_mtime; + __u64 sa_ctime; + __u32 sa_attr_flags; +}; + +#ifdef __KERNEL__ + +static inline void ll_ino2fid(struct ll_fid *fid, ino_t ino, __u32 generation, int type) +{ + fid->id = HTON__u64((__u64)ino); + fid->generation = HTON__u32(generation); + fid->f_type = HTON__u32(type); +} + +static inline void ll_inode2fid(struct ll_fid *fid, struct inode *inode) +{ + fid->id = HTON__u64((__u64)inode->i_ino); + fid->generation = HTON__u32(inode->i_generation); + fid->f_type = HTON__u32(inode->i_mode & S_IFMT); +} + +#endif + /* * OBD IOCTLS */ diff --git a/lustre/include/linux/lustre_mds.h b/lustre/include/linux/lustre_mds.h index 4891588..66ec13b 100644 --- a/lustre/include/linux/lustre_mds.h +++ b/lustre/include/linux/lustre_mds.h @@ -80,10 +80,11 @@ struct mds_request { /* more or less identical to the packed structure, except for the pointers */ struct mds_req { - struct lustre_fid fid1; - struct lustre_fid fid2; + struct ll_fid fid1; + struct ll_fid fid2; int namelen; int tgtlen; + __u32 opcode; __u32 valid; __u32 mode; __u32 uid; @@ -98,14 +99,12 @@ struct mds_req { __u32 ino; __u32 nlink; __u32 generation; - char *name; - char *tgt; }; /* more or less identical to the packed structure, except for the pointers */ struct mds_rep { - struct lustre_fid fid1; - struct lustre_fid fid2; + struct ll_fid fid1; + struct ll_fid fid2; int namelen; int tgtlen; __u32 valid; @@ -122,21 +121,32 @@ struct mds_rep { __u32 ino; __u32 nlink; __u32 generation; - char *name; - char *tgt; }; /* mds/mds_pack.c */ +void *mds_req_tgt(struct mds_req *req); int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen, struct mds_req_hdr **hdr, struct mds_req **req, int *len, char **buf); int mds_unpack_req(char *buf, int len, struct mds_req_hdr **hdr, struct mds_req **req); int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, struct mds_rep_hdr **hdr, struct mds_rep **rep, int *len, char **buf); int mds_unpack_rep(char *buf, int len, struct mds_rep_hdr **hdr, struct mds_rep **rep); +/* mds/mds_reint.c */ +int mds_reint_setattr(struct mds_request *req); + +/* lib/mds_updates.c */ +void mds_setattr_unpack(struct mds_rec_setattr *rec, struct iattr *attr); +void mds_setattr_pack(struct mds_rec_setattr *rec, struct inode *inode, struct iattr *iattr); + +/* mds/handler.c */ +struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt); + /* llight/request.c */ int mdc_getattr(ino_t ino, int type, int valid, struct mds_rep **mds_reply, struct mds_rep_hdr **hdr); +int mdc_setattr(struct inode *inode, struct iattr *iattr, + struct mds_rep **mds_reply, struct mds_rep_hdr **hdr); int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, struct mds_rep **rep, struct mds_rep_hdr **hdr); @@ -148,7 +158,8 @@ int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, #define IOC_REQUEST_GETATTR _IOWR('f', 30, long) #define IOC_REQUEST_READPAGE _IOWR('f', 31, long) -#define IOC_REQUEST_MAX_NR 31 +#define IOC_REQUEST_SETATTR _IOWR('f', 32, long) +#define IOC_REQUEST_MAX_NR 32 #endif diff --git a/lustre/lib/mds_pack.c b/lustre/lib/mds_pack.c index f13eaa4..af4ab68 100644 --- a/lustre/lib/mds_pack.c +++ b/lustre/lib/mds_pack.c @@ -78,13 +78,11 @@ int mds_pack_req(char *name, int namelen, char *tgt, int tgtlen, (*req)->namelen = NTOH__u32(namelen); if (name) { - preq->name_offset = (__u32)(ptr - (char *)preq); LOGL(name, namelen, ptr); } (*req)->tgtlen = NTOH__u32(tgtlen); if (tgt) { - preq->tgt_offset = (__u32)(ptr - (char *)preq); LOGL(tgt, tgtlen, ptr); } return 0; @@ -95,7 +93,6 @@ int mds_unpack_req(char *buf, int len, struct mds_req_hdr **hdr, struct mds_req **req) { struct mds_req_packed *preq; - __u32 off1, off2; char *name, *tgt; if (len < sizeof(**hdr) + sizeof(**req)) { @@ -105,8 +102,6 @@ int mds_unpack_req(char *buf, int len, *hdr = (struct mds_req_hdr *) (buf); preq = (struct mds_req_packed *) (buf + sizeof(**hdr)); - off1 = preq->name_offset; - off2 = preq->tgt_offset; *req = (struct mds_req *) (buf + sizeof(**hdr)); (*req)->namelen = NTOH__u32((*req)->namelen); @@ -119,23 +114,29 @@ int mds_unpack_req(char *buf, int len, } if ((*req)->namelen) { - name = buf + sizeof(**hdr) + off1; + name = buf + sizeof(**hdr) + sizeof(*preq); } else { name = NULL; } if ((*req)->tgtlen) { - tgt = buf + sizeof(**hdr) + off2; + tgt = buf + sizeof(**hdr) + sizeof(*preq) + + size_round((*req)->namelen); } else { tgt = NULL; } - (*req)->name = name; - (*req)->tgt = tgt; EXIT; return 0; } +void *mds_req_tgt(struct mds_req *req) +{ + if (!req->tgtlen) + return NULL; + return (void *)((char *)req + sizeof(*req) + size_round(req->namelen)); +} + int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, struct mds_rep_hdr **hdr, struct mds_rep **rep, int *len, char **buf) @@ -163,13 +164,11 @@ int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, (*rep)->namelen = NTOH__u32(namelen); if (name) { - prep->name_offset = (__u32)(ptr - (char *)prep); LOGL(name, namelen, ptr); } - (*rep)->tgtlen = NTOH__u32(tgtlen); + (*rep)->tgtlen = NTOH__u32(tgtlen); if (tgt) { - prep->tgt_offset = (__u32)(ptr - (char *)prep); LOGL(tgt, tgtlen, ptr); } return 0; @@ -180,17 +179,19 @@ int mds_unpack_rep(char *buf, int len, struct mds_rep_hdr **hdr, struct mds_rep **rep) { struct mds_rep_packed *prep; - __u32 off1, off2; + + if (len < sizeof(**hdr)) { + EXIT; + return -EINVAL; + } + *hdr = (struct mds_rep_hdr *) (buf); if (len < sizeof(**hdr) + sizeof(**rep)) { EXIT; return -EINVAL; } - *hdr = (struct mds_rep_hdr *) (buf); prep = (struct mds_rep_packed *) (buf + sizeof(**hdr)); - off1 = prep->name_offset; - off2 = prep->tgt_offset; *rep = (struct mds_rep *) (buf + sizeof(**hdr)); (*rep)->namelen = NTOH__u32((*rep)->namelen); @@ -202,23 +203,17 @@ int mds_unpack_rep(char *buf, int len, return -EINVAL; } - if ((*rep)->namelen) { - (*rep)->name = buf + sizeof(**hdr) + off1; - } else { - (*rep)->name = NULL; - } - - if ((*rep)->tgtlen) { - (*rep)->tgt = buf + sizeof(**hdr) + off2; - } else { - (*rep)->tgt = NULL; - } - - EXIT; return 0; } +void *mds_rep_tgt(struct mds_rep *rep) +{ + if (!rep->tgtlen) + return NULL; + return (void *)((char *)rep + sizeof(*rep) + size_round(rep->namelen)); +} + #if 0 int mds_pack_rep(char *name, int namelen, char *tgt, int tgtlen, struct mds_rep_hdr **hdr, struct mds_rep **rep, diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index f07a310..ebc68e9 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -488,8 +488,8 @@ got_it: err = ext2_commit_chunk(page, from, to); // change_inode happens with the commit_chunk - // ll_change_inode(dir); - /* OFFSET_CACHE */ + /* XXX OFFSET_CACHE */ + out_unlock: UnlockPage(page); out_page: diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 45f543d..9a4ce69 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -38,7 +38,6 @@ #include extern int ll_setattr(struct dentry *de, struct iattr *attr); -void ll_change_inode(struct inode *inode); static inline void ll_remove_suid(struct inode *inode) { @@ -52,7 +51,6 @@ static inline void ll_remove_suid(struct inode *inode) if (mode && !capable(CAP_FSETID)) { inode->i_mode &= ~mode; // XXX careful here - we cannot change the size - //ll_change_inode(inode); } } diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 15bd677..408ff33 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -55,15 +55,12 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, static inline void ext2_inc_count(struct inode *inode) { inode->i_nlink++; - ll_change_inode(inode); } /* postpone the disk update until the inode really goes away */ static inline void ext2_dec_count(struct inode *inode) { inode->i_nlink--; - if (inode->i_nlink > 0) - ll_change_inode(inode); } static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) @@ -217,7 +214,6 @@ static int ll_mknod (struct inode * dir, struct dentry *dentry, int mode, int rd int err = PTR_ERR(inode); if (!IS_ERR(inode)) { init_special_inode(inode, mode, rdev); - ll_change_inode(inode); err = ext2_add_nondir(dentry, inode); } return err; @@ -254,7 +250,6 @@ static int ll_symlink (struct inode * dir, struct dentry * dentry, memcpy(oinfo->lli_inline, symname, l); inode->i_size = l-1; } - ll_change_inode(inode); err = ext2_add_nondir(dentry, inode); out: diff --git a/lustre/llite/rw.c b/lustre/llite/rw.c index 46eaee8..e80dd7e 100644 --- a/lustre/llite/rw.c +++ b/lustre/llite/rw.c @@ -1,13 +1,7 @@ /* - * OBDFS Super operations + * Lustre Light I/O Page Cache * - * This code is issued under the GNU General Public License. - * See the file COPYING in this distribution - * - * Copyright (C) 1996, 1997, Olaf Kirch - * Copryright (C) 1999 Stelias Computing Inc, - * (author Peter J. Braam ) - * Copryright (C) 1999 Seagate Technology Inc. + * Copyright (C) 2002, Cluster File Systems, Inc. */ @@ -38,14 +32,6 @@ #include #include -void ll_change_inode(struct inode *inode); - -static int cache_writes = 0; - - -/* page cache support stuff */ - - /* * Add a page to the dirty page list. */ @@ -284,231 +270,6 @@ int ll_prepare_write(struct file *file, struct page *page, unsigned from, unsign } - - - - -static kmem_cache_t *ll_pgrq_cachep = NULL; - -int ll_init_pgrqcache(void) -{ - ENTRY; - if (ll_pgrq_cachep == NULL) { - CDEBUG(D_CACHE, "allocating ll_pgrq_cache\n"); - ll_pgrq_cachep = kmem_cache_create("ll_pgrq", - sizeof(struct ll_pgrq), - 0, SLAB_HWCACHE_ALIGN, - NULL, NULL); - if (ll_pgrq_cachep == NULL) { - EXIT; - return -ENOMEM; - } else { - CDEBUG(D_CACHE, "allocated cache at %p\n", - ll_pgrq_cachep); - } - } else { - CDEBUG(D_CACHE, "using existing cache at %p\n", - ll_pgrq_cachep); - } - EXIT; - return 0; -} /* ll_init_wreqcache */ - -inline void ll_pgrq_del(struct ll_pgrq *pgrq) -{ - --ll_cache_count; - CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n", - pgrq->rq_page, ll_cache_count); - list_del(&pgrq->rq_plist); - OBDClearCachePage(pgrq->rq_page); - kmem_cache_free(ll_pgrq_cachep, pgrq); -} - -void ll_cleanup_pgrqcache(void) -{ - ENTRY; - if (ll_pgrq_cachep != NULL) { - CDEBUG(D_CACHE, "destroying ll_pgrqcache at %p, count %ld\n", - ll_pgrq_cachep, ll_cache_count); - if (kmem_cache_destroy(ll_pgrq_cachep)) - printk(KERN_INFO __FUNCTION__ - ": unable to free all of cache\n"); - ll_pgrq_cachep = NULL; - } else - printk(KERN_INFO __FUNCTION__ ": called with NULL pointer\n"); - - EXIT; -} /* ll_cleanup_wreqcache */ - - -/* called with the list lock held */ -static struct page *ll_find_page_index(struct inode *inode, - unsigned long index) -{ - struct list_head *page_list = ll_iplist(inode); - struct list_head *tmp; - struct page *page; - - ENTRY; - - CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n", - inode->i_ino, index); - OIDEBUG(inode); - - if (list_empty(page_list)) { - EXIT; - return NULL; - } - tmp = page_list; - while ( (tmp = tmp->next) != page_list ) { - struct ll_pgrq *pgrq; - - pgrq = list_entry(tmp, struct ll_pgrq, rq_plist); - page = pgrq->rq_page; - if (index == page->index) { - CDEBUG(D_INFO, - "INDEX SEARCH found page %p, index %ld\n", - page, index); - EXIT; - return page; - } - } - - EXIT; - return NULL; -} /* ll_find_page_index */ - - -/* call and free pages from Linux page cache: called with io lock on inodes */ -int ll_do_vec_wr(struct inode **inodes, obd_count num_io, - obd_count num_obdos, struct obdo **obdos, - obd_count *oa_bufs, struct page **pages, char **bufs, - obd_size *counts, obd_off *offsets, obd_flag *flags) -{ - int err; - - ENTRY; - - CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n", - num_io, num_obdos); - if (obd_debug_level & D_INFO) { /* DEBUGGING */ - int i; - printk("OBDOS: "); - for (i = 0; i < num_obdos; i++) - printk("%ld:0x%p ", (long)obdos[i]->o_id, obdos[i]); - - printk("\nPAGES: "); - for (i = 0; i < num_io; i++) - printk("0x%p ", pages[i]); - printk("\n"); - } - - err = obd_brw(WRITE, IID(inodes[0]), num_obdos, obdos, - oa_bufs, pages, counts, offsets, flags); - - CDEBUG(D_INFO, "BRW done\n"); - /* release the pages from the page cache */ - while ( num_io > 0 ) { - --num_io; - CDEBUG(D_INFO, "calling put_page for %p, index %ld\n", - pages[num_io], pages[num_io]->index); - /* PDEBUG(pages[num_io], "do_vec_wr"); */ - put_page(pages[num_io]); - /* PDEBUG(pages[num_io], "do_vec_wr"); */ - } - CDEBUG(D_INFO, "put_page done\n"); - - while ( num_obdos > 0) { - --num_obdos; - CDEBUG(D_INFO, "free obdo %ld\n",(long)obdos[num_obdos]->o_id); - /* copy o_blocks to i_blocks */ - ll_set_size (inodes[num_obdos], obdos[num_obdos]->o_size); - //ll_to_inode(inodes[num_obdos], obdos[num_obdos]); - obdo_free(obdos[num_obdos]); - } - CDEBUG(D_INFO, "obdo_free done\n"); - EXIT; - return err; -} - - -/* - * Add a page to the write request cache list for later writing. - * ASYNCHRONOUS write method. - */ -static int ll_add_page_to_cache(struct inode *inode, struct page *page) -{ - int err = 0; - ENTRY; - - /* The PG_obdcache bit is cleared by ll_pgrq_del() BEFORE the page - * is written, so at worst we will write the page out twice. - * - * If the page has the PG_obdcache bit set, then the inode MUST be - * on the superblock dirty list so we don't need to check this. - * Dirty inodes are removed from the superblock list ONLY when they - * don't have any more cached pages. It is possible to have an inode - * with no dirty pages on the superblock list, but not possible to - * have an inode with dirty pages NOT on the superblock dirty list. - */ - if (!OBDAddCachePage(page)) { - struct ll_pgrq *pgrq; - pgrq = kmem_cache_alloc(ll_pgrq_cachep, SLAB_KERNEL); - if (!pgrq) { - OBDClearCachePage(page); - EXIT; - return -ENOMEM; - } - /* not really necessary since we set all pgrq fields here - memset(pgrq, 0, sizeof(*pgrq)); - */ - - pgrq->rq_page = page; - pgrq->rq_jiffies = jiffies; - get_page(pgrq->rq_page); - - obd_down(&ll_i2sbi(inode)->ll_list_mutex); - list_add(&pgrq->rq_plist, ll_iplist(inode)); - ll_cache_count++; - //printk("-- count %d\n", ll_cache_count); - - /* If inode isn't already on superblock inodes list, add it. - * - * We increment the reference count on the inode to keep it - * from being freed from memory. This _should_ be an iget() - * with an iput() in both flush_reqs() and put_inode(), but - * since put_inode() is called from iput() we can't call iput() - * again there. Instead we just increment/decrement i_count, - * which is mostly what iget/iput do for an inode in memory. - */ - if ( list_empty(ll_islist(inode)) ) { - atomic_inc(&inode->i_count); - CDEBUG(D_INFO, - "adding inode %ld to superblock list %p\n", - inode->i_ino, ll_slist(inode)); - list_add(ll_islist(inode), ll_slist(inode)); - } - obd_up(&ll_i2sbi(inode)->ll_list_mutex); - - } - - /* XXX For testing purposes, we can write out the page here. - err = ll_flush_reqs(ll_slist(inode), ~0UL); - */ - - EXIT; - return err; -} /* ll_add_page_to_cache */ - -void rebalance(void) -{ - if (ll_cache_count > 60000) { - printk("-- count %ld\n", ll_cache_count); - //ll_flush_dirty_pages(~0UL); - printk("-- count %ld\n", ll_cache_count); - } -} - /* select between SYNC and ASYNC I/O methods */ int ll_do_writepage(struct page *page, int sync) { @@ -517,14 +278,9 @@ int ll_do_writepage(struct page *page, int sync) ENTRY; /* PDEBUG(page, "WRITEPAGE"); */ - if ( sync ) - err = ll_brw(WRITE, inode, page, 1); - else { - err = ll_add_page_to_cache(inode, page); - CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n", - inode->i_ino, page, err, Page_Uptodate(page)); - } - + /* XXX everything is synchronous now */ + err = ll_brw(WRITE, inode, page, 1); + if ( !err ) { SetPageUptodate(page); set_page_clean(page); @@ -575,10 +331,7 @@ int ll_commit_write(struct file *file, struct page *page, unsigned from, unsigne CDEBUG(D_INODE, "commit write ino %ld (end at %Ld) from %d to %d ,ind %ld\n", inode->i_ino, len, from, to, page->index); - - if (cache_writes == 0) { - rc = ll_commit_page(page, 1, from, to); - } + rc = ll_commit_page(page, 1, from, to); if (len > inode->i_size) { ll_set_size(inode, len); @@ -674,14 +427,6 @@ struct page *ll_getpage(struct inode *inode, unsigned long offset, return page; } - -#ifdef EXT2_OBD_DEBUG - if ((obd_debug_level & D_INFO) && ll_find_page_index(inode, index)) { - CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n", - page, page->index); - } -#endif - err = ll_brw(READ, inode, page, create); if ( err ) { diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 43f3457..357be67 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -90,161 +90,100 @@ static struct super_block * ll_read_super(struct super_block *sb, { struct inode *root = 0; struct ll_sb_info *sbi = (struct ll_sb_info *)(&sb->u.generic_sbp); - struct obd_device *obddev; char *device = NULL; char *version = NULL; - int root_ino = 2; int connected = 0; int devno; int err; struct mds_rep *rep; struct mds_rep_hdr *hdr = NULL; - ENTRY; MOD_INC_USE_COUNT; + memset(sbi, 0, sizeof(*sbi)); - - CDEBUG(D_INFO, "\n"); + ll_options(data, &device, &version); if ( !device ) { printk(__FUNCTION__ ": no device\n"); - EXIT; + sb = NULL; goto ERR; } devno = simple_strtoul(device, NULL, 0); - CDEBUG(D_INFO, "\n"); if ( devno >= MAX_OBD_DEVICES ) { - printk(__FUNCTION__ ": device of %s too high (%d)\n", device, devno); - EXIT; + printk(__FUNCTION__ ": device of %s too high\n", device); + sb = NULL; goto ERR; } - CDEBUG(D_INFO, "\n"); - - obddev = &obd_dev[devno]; - sbi->ll_conn.oc_dev = obddev; - CDEBUG(D_INFO, "\n"); - + sbi->ll_conn.oc_dev = &obd_dev[devno]; err = obd_connect(&sbi->ll_conn); - CDEBUG(D_INFO, "\n"); if ( err ) { - printk("OBDFS: cannot connect to %s\n", device); - EXIT; + printk(__FUNCTION__ "cannot connect to %s\n", device); + sb = NULL; goto ERR; } connected = 1; - /* list of dirty inodes, and a mutex to hold while modifying it */ - INIT_LIST_HEAD(&sbi->ll_inodes); - init_MUTEX (&sbi->ll_list_mutex); - sbi->ll_super = sb; sbi->ll_rootino = 2; sb->s_maxbytes = 1LL << 36; - printk("Max bytes: %Lx\n", sb->s_maxbytes); sb->s_blocksize = PAGE_SIZE; sb->s_blocksize_bits = (unsigned char)PAGE_SHIFT; sb->s_magic = LL_SUPER_MAGIC; sb->s_op = &ll_super_operations; /* make root inode */ - err = mdc_getattr(root_ino, S_IFDIR, OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, - &rep, &hdr); + err = mdc_getattr(sbi->ll_rootino, S_IFDIR, + OBD_MD_FLNOTOBD|OBD_MD_FLBLOCKS, + &rep, &hdr); if (err) { - printk(__FUNCTION__ ": mds_getattr failed %d\n", err); - if (rep) - kfree(rep); - EXIT; + printk(__FUNCTION__ ": mds_getattr failed for root %d\n", err); + sb = NULL; goto ERR; } - root = iget4(sb, root_ino, NULL, rep); - kfree(hdr); - if (!root) { + root = iget4(sb, sbi->ll_rootino, NULL, rep); + if (root) { + sb->s_root = d_alloc_root(root); + } else { printk("lustre_light: bad iget4 for root\n"); - sb->s_dev = 0; - err = -ENOENT; - EXIT; + sb = NULL; goto ERR; } - sb->s_root = d_alloc_root(root); - OBD_FREE(device, strlen(device) + 1); - if (version) - OBD_FREE(version, strlen(version) + 1); - EXIT; - return sb; - ERR: - MOD_DEC_USE_COUNT; + if (hdr) + kfree(hdr); if (device) OBD_FREE(device, strlen(device) + 1); if (version) OBD_FREE(version, strlen(version) + 1); - if (connected) + if (!sb && connected) obd_disconnect(&sbi->ll_conn); - if (sbi) { - sbi->ll_super = NULL; - } - if (root) { + if (!sb && root) { iput(root); } - sb->s_dev = 0; - return NULL; -} /* ll_read_super */ + if (!sb) + MOD_DEC_USE_COUNT; + EXIT; + return sb; +} /* ll_read_super */ static void ll_put_super(struct super_block *sb) { - struct ll_sb_info *sbi; - ENTRY; - sb->s_dev = 0; - - sbi = (struct ll_sb_info *) &sb->u.generic_sbp; + obd_disconnect(ID(sb)); - - printk(KERN_INFO "OBDFS: Bye bye.\n"); MOD_DEC_USE_COUNT; EXIT; } /* ll_put_super */ -void ll_do_change_inode(struct inode *inode, int valid) -{ - struct obdo *oa; - int err; - - ENTRY; - - oa = obdo_alloc(); - if ( !oa ) { - printk(__FUNCTION__ ": obdo_alloc failed\n"); - EXIT; - return; - } - - oa->o_valid = OBD_MD_FLNOTOBD & (valid | OBD_MD_FLID); - ll_from_inode(oa, inode); - oa->o_mode = inode->i_mode; - err = obd_setattr(IID(inode), oa); - - if ( err ) - printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err); - - EXIT; - obdo_free(oa); -} /* ll_write_inode */ - -void ll_change_inode(struct inode *inode, int mask) -{ - return ll_do_change_inode(inode, OBD_MD_FLNLINK); -} - extern void write_inode_pages(struct inode *); /* This routine is called from iput() (for each unlink on the inode). @@ -265,50 +204,7 @@ static void ll_put_inode(struct inode *inode) EXIT; } /* ll_put_inode */ - -static void ll_delete_inode(struct inode *inode) -{ - ll_do_change_inode(inode, ~0); - clear_inode(inode); -} -#if 0 -{ - struct obdo *oa; - int err; - - ENTRY; - if (IOPS(inode, destroy) == NULL) { - printk(KERN_ERR __FUNCTION__ ": no destroy method!\n"); - EXIT; - return; - } - - oa = obdo_alloc(); - if ( !oa ) { - printk(__FUNCTION__ ": obdo_alloc failed\n"); - EXIT; - return; - } - oa->o_valid = OBD_MD_FLNOTOBD; - ll_from_inode(oa, inode); - - /* XXX how do we know that this inode is now clean? */ - printk("delete_inode ------> link %d\n", inode->i_nlink); - ODEBUG(oa); - err = IOPS(inode, destroy)(IID(inode), oa); - obdo_free(oa); - clear_inode(inode); - if (err) { - printk(__FUNCTION__ ": obd_destroy fails (%d)\n", err); - EXIT; - return; - } - - EXIT; -} /* ll_delete_inode */ -#endif - - +/* like inode_setattr, but doesn't mark the inode dirty */ static int ll_attr2inode(struct inode * inode, struct iattr * attr) { unsigned int ia_valid = attr->ia_valid; @@ -319,7 +215,6 @@ static int ll_attr2inode(struct inode * inode, struct iattr * attr) if (error) goto out; } - if (ia_valid & ATTR_UID) inode->i_uid = attr->ia_uid; if (ia_valid & ATTR_GID) @@ -342,28 +237,19 @@ out: int ll_setattr(struct dentry *de, struct iattr *attr) { struct inode *inode = de->d_inode; - struct obdo *oa; - int err; + struct mds_rep_hdr *hdr = NULL; + int err; ENTRY; - oa = obdo_alloc(); - if ( !oa ) { - printk(__FUNCTION__ ": obdo_alloc failed\n"); - return -ENOMEM; - } - + /* change incore inode */ ll_attr2inode(inode, attr); - oa->o_id = inode->i_ino; - oa->o_mode = inode->i_mode; - obdo_from_iattr(oa, attr); - err = obd_setattr(IID(inode), oa); + err = mdc_setattr(inode, attr, NULL, &hdr); if ( err ) - printk(__FUNCTION__ ": obd_setattr fails (%d)\n", err); + printk(__FUNCTION__ ": ll_setattr fails (%d)\n", err); EXIT; - obdo_free(oa); return err; } /* ll_setattr */ diff --git a/lustre/mdc/Makefile.am b/lustre/mdc/Makefile.am index 65234e6..6fffd8a 100644 --- a/lustre/mdc/Makefile.am +++ b/lustre/mdc/Makefile.am @@ -10,9 +10,11 @@ modulefs_DATA = mdc.o EXTRA_PROGRAMS = mdc -mdc_SOURCES = mds_pack.c mdc_request.c +mdc_SOURCES = mds_pack.c mdc_request.c mdc_reint.c mds_updates.c mds_pack.c: ln -s ../lib/mds_pack.c . +mds_updates.c: + ln -s ../lib/mds_updates.c . include $(top_srcdir)/Rules diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index ac1f6ac..4930ee9 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -35,7 +35,7 @@ extern int mds_queue_req(struct mds_request *); -struct mds_request *mds_prep_req(int size, int opcode, int namelen, char *name, int tgtlen, char *tgt) +struct mds_request *mds_prep_req(int opcode, int namelen, char *name, int tgtlen, char *tgt) { struct mds_request *request; int rc; @@ -54,6 +54,9 @@ struct mds_request *mds_prep_req(int size, int opcode, int namelen, char *name, printk("llight request: cannot pack request %d\n", rc); return NULL; } + printk("--> mds_prep_req: len %d, req %p, tgtlen %d\n", + request->rq_reqlen, request->rq_req, + request->rq_req->tgtlen); request->rq_reqhdr->opc = opcode; EXIT; @@ -83,8 +86,10 @@ static int mds_queue_wait(struct mds_request *req) mds_unpack_rep(req->rq_repbuf, req->rq_replen, &req->rq_rephdr, &req->rq_rep); - printk("-->mdc_queue_wait: buf %p len %d status %d\n", - req->rq_repbuf, req->rq_replen, req->rq_rephdr->status); + if ( req->rq_rephdr->status == 0 ) + printk("-->mdc_queue_wait: buf %p len %d status %d\n", + req->rq_repbuf, req->rq_replen, + req->rq_rephdr->status); EXIT; return req->rq_rephdr->status; @@ -101,15 +106,14 @@ int mdc_getattr(ino_t ino, int type, int valid, struct mds_request *request; int rc; - request = mds_prep_req(sizeof(*request), MDS_GETATTR, - 0, NULL, 0, NULL); + request = mds_prep_req(MDS_GETATTR, 0, NULL, 0, NULL); if (!request) { printk("llight request: cannot pack\n"); return -ENOMEM; } - request->rq_req->fid1.id = ino; - request->rq_req->fid1.f_type = type; + ll_ino2fid(&request->rq_req->fid1, ino, 0, type); + request->rq_req->valid = valid; rc = mds_queue_wait(request); @@ -143,8 +147,7 @@ int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, printk("mdc_readpage: inode: %ld\n", ino); - request = mds_prep_req(sizeof(*request), MDS_READPAGE, - 0, NULL, + request = mds_prep_req(MDS_READPAGE, 0, NULL, sizeof(struct niobuf), (char *)&niobuf); if (!request) { printk("mdc request: cannot pack\n"); @@ -176,6 +179,18 @@ int mdc_readpage(ino_t ino, int type, __u64 offset, char *addr, return rc; } +int mdc_reint(struct mds_request *request) +{ + int rc; + + rc = mds_queue_wait(request); + if (rc) { + printk("mdc request: error in handling %d\n", rc); + } + + return rc; +} + static int request_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -201,16 +216,17 @@ static int request_ioctl(struct inode *inode, struct file *file, switch (cmd) { case IOC_REQUEST_GETATTR: { - struct mds_rep_hdr *hdr; + struct mds_rep_hdr *hdr = NULL; printk("-- getting attr for ino 2\n"); err = mdc_getattr(2, S_IFDIR, ~0, NULL, &hdr); - kfree(hdr); + if (hdr) + kfree(hdr); printk("-- done err %d\n", err); break; } case IOC_REQUEST_READPAGE: { - struct mds_rep_hdr *hdr; + struct mds_rep_hdr *hdr = NULL; char *buf; buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) { @@ -223,11 +239,33 @@ static int request_ioctl(struct inode *inode, struct file *file, if (!err) { printk("-- status: %d\n", hdr->status); err = hdr->status; - kfree(hdr); + if (hdr) + kfree(hdr); } kfree(buf); break; } + + case IOC_REQUEST_SETATTR: { + struct inode inode; + struct mds_rep_hdr *hdr; + struct iattr iattr; + + inode.i_ino = 2; + iattr.ia_mode = 040777; + iattr.ia_atime = 0; + iattr.ia_valid = ATTR_MODE | ATTR_ATIME; + + err = mdc_setattr(&inode, &iattr, NULL, &hdr); + printk("-- done err %d\n", err); + if (!err) { + printk("-- status: %d\n", hdr->status); + err = hdr->status; + } + kfree(hdr); + break; + } + default: err = -EINVAL; EXIT; @@ -268,6 +306,7 @@ MODULE_LICENSE("GPL"); EXPORT_SYMBOL(mdc_getattr); EXPORT_SYMBOL(mdc_readpage); +EXPORT_SYMBOL(mdc_setattr); module_init(mds_request_init); module_exit(mds_request_exit); diff --git a/lustre/mds/Makefile.am b/lustre/mds/Makefile.am index f93103a..a78e8b8 100644 --- a/lustre/mds/Makefile.am +++ b/lustre/mds/Makefile.am @@ -11,8 +11,10 @@ EXTRA_PROGRAMS = mds mds_pack.c: ln -s ../lib/mds_pack.c . +mds_updates.c: + ln -s ../lib/mds_updates.c . -mds_SOURCES = mds_pack.c handler.c +mds_SOURCES = mds_pack.c handler.c mds_reint.c mds_updates.c include $(top_srcdir)/Rules diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 3a29163..3585f8c 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -131,7 +131,7 @@ int mds_error(struct mds_request *req) return mds_reply(req); } -static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid, struct vfsmount **mnt) +struct dentry *mds_fid2dentry(struct mds_obd *mds, struct ll_fid *fid, struct vfsmount **mnt) { /* iget isn't really right if the inode is currently unallocated!! @@ -145,7 +145,8 @@ static struct dentry *mds_fid2dentry(struct mds_obd *mds, struct lustre_fid *fid */ struct super_block *sb = mds->mds_sb; unsigned long ino = fid->id; - __u32 generation = fid->generation; + //__u32 generation = fid->generation; + __u32 generation = 0; struct inode *inode; struct list_head *lp; struct dentry *result; @@ -277,7 +278,7 @@ int mds_readpage(struct mds_request *req) return 0; } - niobuf = (struct niobuf *)req->rq_req->tgt; + niobuf = mds_req_tgt(req->rq_req); /* to make this asynchronous make sure that the handling function doesn't send a reply when this function completes. Instead a @@ -290,7 +291,20 @@ int mds_readpage(struct mds_request *req) return 0; } +int mds_reint(struct mds_request *req) +{ + int opc = NTOH__u32(req->rq_req->opcode); + + switch (opc) { + case REINT_SETATTR: + return mds_reint_setattr(req); + default: + printk(__FUNCTION__ "opcode %d not handled.\n", opc); + return -EINVAL; + } + return 0; +} //int mds_handle(struct mds_conn *conn, int len, char *buf) int mds_handle(struct mds_request *req) @@ -329,32 +343,10 @@ int mds_handle(struct mds_request *req) rc = mds_readpage(req); break; - case MDS_SETATTR: - return mds_getattr(req); - - case MDS_CREATE: - return mds_getattr(req); - - case MDS_MKDIR: - return mds_getattr(req); - - case MDS_RMDIR: - return mds_getattr(req); - - case MDS_SYMLINK: - return mds_getattr(req); - - case MDS_LINK: - return mds_getattr(req); - - case MDS_MKNOD: - return mds_getattr(req); - - case MDS_UNLINK: - return mds_getattr(req); - - case MDS_RENAME: - return mds_getattr(req); + case MDS_REINT: + CDEBUG(D_INODE, "reint\n"); + rc = mds_reint(req); + break; default: return mds_error(req); diff --git a/lustre/tests/testreq.c b/lustre/tests/testreq.c index 98886f4..00f7a6b 100644 --- a/lustre/tests/testreq.c +++ b/lustre/tests/testreq.c @@ -3,8 +3,10 @@ #include #include #include + #define IOC_REQUEST_GETATTR _IOWR('f', 30, long) #define IOC_REQUEST_READPAGE _IOWR('f', 31, long) +#define IOC_REQUEST_SETATTR _IOWR('f', 32, long) int main(int argc, char **argv) { @@ -27,5 +29,9 @@ int main(int argc, char **argv) printf("readpage test... "); rc = ioctl(fd, IOC_REQUEST_READPAGE, NULL); printf("result: %d\n", rc); + + printf("setattr test... "); + rc = ioctl(fd, IOC_REQUEST_SETATTR, NULL); + printf("result: %d\n", rc); return 0; }