X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdfilter%2Ffilter.c;h=e2ceb0e793b8058dd3ab969a9fb26dd0d64608cc;hb=26f846563602a3275472079c2a360a88ac4db514;hp=22fa20a4c025497f3af319c5ed6e47dcdd0f8834;hpb=0237c8d4ba4864b598844f0bdab56e95e1ca7648;p=fs%2Flustre-release.git diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 22fa20a..e2ceb0e 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -19,6 +19,7 @@ #include #include #include +#include extern struct obd_device obd_dev[MAX_OBD_DEVICES]; long filter_memory; @@ -359,7 +360,6 @@ static int filter_connect(struct lustre_handle *conn, struct obd_device *obd) ENTRY; MOD_INC_USE_COUNT; rc = class_connect(conn, obd); - if (rc) MOD_DEC_USE_COUNT; RETURN(rc); @@ -483,27 +483,15 @@ static inline void filter_from_inode(struct obdo *oa, struct inode *inode) if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) { obd_rdev rdev = kdev_t_to_nr(inode->i_rdev); - CDEBUG(D_INODE, "copying device %x from inode to obdo\n", - rdev); - *((obd_rdev *)oa->o_inline) = rdev; - oa->o_obdflags |= OBD_FL_INLINEDATA; - oa->o_valid |= OBD_MD_FLINLINE; - } - -#if 0 - else if (filter_has_inline(inode)) { - CDEBUG(D_INFO, "copying inline from inode to obdo\n"); - memcpy(oa->o_inline, inode->u.ext2_i.i_data, - MIN(sizeof(inode->u.ext2_i.i_data),OBD_INLINESZ)); - oa->o_obdflags |= OBD_FL_INLINEDATA; - oa->o_valid |= OBD_MD_FLINLINE; + oa->o_rdev = rdev; + oa->o_valid |= OBD_MD_FLRDEV; } -#endif EXIT; } -static int filter_getattr(struct lustre_handle *conn, struct obdo *oa) +static int filter_getattr(struct lustre_handle *conn, struct obdo *oa, + struct lov_stripe_md *md) { struct obd_device *obddev = class_conn2obd(conn); struct dentry *dentry; @@ -527,7 +515,8 @@ static int filter_getattr(struct lustre_handle *conn, struct obdo *oa) RETURN(0); } -static int filter_setattr(struct lustre_handle *conn, struct obdo *oa) +static int filter_setattr(struct lustre_handle *conn, struct obdo *oa, + struct lov_stripe_md *md) { struct obd_run_ctxt saved; struct obd_device *obd = class_conn2obd(conn); @@ -537,15 +526,14 @@ static int filter_setattr(struct lustre_handle *conn, struct obdo *oa) int rc; ENTRY; - dentry = filter_fid2dentry(obd, filter_parent(obd, oa->o_mode), - oa->o_id, oa->o_mode); + iattr_from_obdo(&iattr, oa); + iattr.ia_mode = (iattr.ia_mode & ~S_IFMT) | S_IFREG; + dentry = filter_fid2dentry(obd, filter_parent(obd, iattr.ia_mode), + oa->o_id, iattr.ia_mode); if (IS_ERR(dentry)) RETURN(PTR_ERR(dentry)); inode = dentry->d_inode; - iattr_from_obdo(&iattr, oa); - iattr.ia_mode &= ~S_IFMT; - iattr.ia_mode |= S_IFREG; lock_kernel(); if (iattr.ia_mode & ATTR_SIZE) down(&inode->i_sem); @@ -568,7 +556,8 @@ static int filter_setattr(struct lustre_handle *conn, struct obdo *oa) RETURN(rc); } -static int filter_open(struct lustre_handle *conn, struct obdo *oa) +static int filter_open(struct lustre_handle *conn, struct obdo *oa, + struct lov_stripe_md *ea) { struct obd_device *obd; struct dentry *dentry; @@ -588,7 +577,8 @@ static int filter_open(struct lustre_handle *conn, struct obdo *oa) return 0; } /* filter_open */ -static int filter_close(struct lustre_handle *conn, struct obdo *oa) +static int filter_close(struct lustre_handle *conn, struct obdo *oa, + struct lov_stripe_md *ea) { struct obd_device *obd; struct dentry *dentry; @@ -614,7 +604,8 @@ static int filter_close(struct lustre_handle *conn, struct obdo *oa) return 0; } /* filter_close */ -static int filter_create(struct lustre_handle* conn, struct obdo *oa) +static int filter_create(struct lustre_handle* conn, struct obdo *oa, + struct lov_stripe_md **ea) { char name[64]; struct obd_run_ctxt saved; @@ -655,10 +646,12 @@ static int filter_create(struct lustre_handle* conn, struct obdo *oa) return 0; } -static int filter_destroy(struct lustre_handle *conn, struct obdo *oa) +static int filter_destroy(struct lustre_handle *conn, struct obdo *oa, + struct lov_stripe_md *ea) { - struct obd_run_ctxt saved; struct obd_device *obd; + struct filter_obd *filter; + struct obd_run_ctxt saved; struct obd_export *export; struct inode *inode; struct dentry *dir_dentry, *object_dentry; @@ -670,7 +663,7 @@ static int filter_destroy(struct lustre_handle *conn, struct obdo *oa) RETURN(-EINVAL); } - CDEBUG(D_INODE, "destroying object %Ld\n",oa->o_id); + CDEBUG(D_INODE, "destroying object %Ld\n", oa->o_id); obd = class_conn2obd(conn); dir_dentry = filter_parent(obd, oa->o_mode); @@ -682,13 +675,20 @@ static int filter_destroy(struct lustre_handle *conn, struct obdo *oa) GOTO(out, rc = -ENOENT); inode = object_dentry->d_inode; + if (inode == NULL) { + CERROR("trying to destroy negative inode %Ld!\n", oa->o_id); + GOTO(out, rc = -ENOENT); + } + if (inode->i_nlink != 1) { CERROR("destroying inode with nlink = %d\n", inode->i_nlink); + LBUG(); inode->i_nlink = 1; } inode->i_mode = S_IFREG; - push_ctxt(&saved, &obd->u.filter.fo_ctxt); + filter = &obd->u.filter; + push_ctxt(&saved, &filter->fo_ctxt); rc = vfs_unlink(dir_dentry->d_inode, object_dentry); pop_ctxt(&saved); @@ -704,31 +704,37 @@ out: /* NB count and offset are used for punch, but not truncate */ static int filter_truncate(struct lustre_handle *conn, struct obdo *oa, - obd_size count, obd_off offset) + struct lov_stripe_md *md, + obd_off start, obd_off end) { int error; ENTRY; - CDEBUG(D_INODE, "calling truncate for object #%Ld, valid = %x, " - "o_size = %Ld\n", oa->o_id, oa->o_valid, oa->o_size); - error = filter_setattr(conn, oa); + if ( end != 0xffffffffffffffff ) { + CERROR("PUNCH not supported, only truncate works\n"); + } + CDEBUG(D_INODE, "calling truncate for object #%Ld, valid = %x, " + "o_size = %Ld\n", oa->o_id, oa->o_valid, start); + oa->o_size = start; + error = filter_setattr(conn, oa, NULL); RETURN(error); } -static int filter_pgcache_brw(int cmd, struct lustre_handle *conn, obd_count num_oa, - struct obdo **oa, obd_count *oa_bufs, +static int filter_pgcache_brw(int cmd, struct lustre_handle *conn, + struct lov_stripe_md *md, obd_count oa_bufs, struct page **pages, obd_size *count, - obd_off *offset, obd_flag *flags, void *callback) + obd_off *offset, obd_flag *flags, + brw_callback_t callback, void *data) { struct obd_run_ctxt saved; struct super_block *sb; - int onum; /* index to oas */ int pnum; /* index to pages (bufs) */ unsigned long retval; int error; struct file *file; struct obd_device *obd = class_conn2obd(conn); + int pg; ENTRY; if (!class_conn2export(conn)) { @@ -739,53 +745,54 @@ static int filter_pgcache_brw(int cmd, struct lustre_handle *conn, obd_count num sb = obd->u.filter.fo_sb; push_ctxt(&saved, &obd->u.filter.fo_ctxt); pnum = 0; /* pnum indexes buf 0..num_pages */ - for (onum = 0; onum < num_oa; onum++) { - int pg; - - file = filter_obj_open(obd, oa[onum]->o_id, oa[onum]->o_mode); - if (IS_ERR(file)) - GOTO(out, retval = PTR_ERR(file)); - - /* count doubles as retval */ - for (pg = 0; pg < oa_bufs[onum]; pg++) { - CDEBUG(D_INODE, "OP %d obdo no/pno: (%d,%d) (%ld,%ld) " - "off count (%Ld,%Ld)\n", - cmd, onum, pnum, file->f_dentry->d_inode->i_ino, - (unsigned long)offset[pnum] >> PAGE_CACHE_SHIFT, - (unsigned long long)offset[pnum], - (unsigned long long)count[pnum]); - if (cmd & OBD_BRW_WRITE) { - loff_t off; - char *buffer; - off = offset[pnum]; - buffer = kmap(pages[pnum]); - retval = file->f_op->write(file, buffer, count[pnum], &off); - kunmap(pages[pnum]); - CDEBUG(D_INODE, "retval %ld\n", retval); + + file = filter_obj_open(obd, md->lmd_object_id, S_IFREG); + if (IS_ERR(file)) + GOTO(out, retval = PTR_ERR(file)); + + /* count doubles as retval */ + for (pg = 0; pg < oa_bufs; pg++) { + CDEBUG(D_INODE, "OP %d obdo pgno: (%d) (%ld,%ld) " + "off count (%Ld,%Ld)\n", + cmd, pnum, file->f_dentry->d_inode->i_ino, + (unsigned long)offset[pnum] >> PAGE_CACHE_SHIFT, + (unsigned long long)offset[pnum], + (unsigned long long)count[pnum]); + if (cmd & OBD_BRW_WRITE) { + loff_t off; + char *buffer; + off = offset[pnum]; + buffer = kmap(pages[pnum]); + retval = file->f_op->write(file, buffer, count[pnum], + &off); + kunmap(pages[pnum]); + CDEBUG(D_INODE, "retval %ld\n", retval); + } else { + loff_t off = offset[pnum]; + char *buffer = kmap(pages[pnum]); + + if (off >= file->f_dentry->d_inode->i_size) { + memset(buffer, 0, count[pnum]); + retval = count[pnum]; } else { - loff_t off = offset[pnum]; - char *buffer = kmap(pages[pnum]); - - if (off >= file->f_dentry->d_inode->i_size) { - memset(buffer, 0, count[pnum]); - retval = count[pnum]; - } else { - retval = file->f_op->read(file, buffer, count[pnum], &off); - } - kunmap(pages[pnum]); - - if (retval != count[pnum]) { - filp_close(file, 0); - GOTO(out, retval = -EIO); - } - CDEBUG(D_INODE, "retval %ld\n", retval); + retval = file->f_op->read(file, buffer, + count[pnum], &off); + } + kunmap(pages[pnum]); + + if (retval != count[pnum]) { + filp_close(file, 0); + GOTO(out, retval = -EIO); } - pnum++; + CDEBUG(D_INODE, "retval %ld\n", retval); } - /* sizes and blocks are set by generic_file_write */ - /* ctimes/mtimes will follow with a setattr call */ - filp_close(file, 0); + pnum++; } + /* sizes and blocks are set by generic_file_write */ + /* ctimes/mtimes will follow with a setattr call */ + filp_close(file, 0); + + /* XXX: do something with callback if it is set? */ EXIT; out: @@ -1284,23 +1291,13 @@ out_ctxt: RETURN(0); } -static int filter_statfs(struct lustre_handle *conn, struct statfs * statfs) +static int filter_statfs(struct lustre_handle *conn, struct statfs *statfs) { - struct super_block *sb; - int err; - ENTRY; - - if (!class_conn2export(conn)) { - CDEBUG(D_IOCTL, "invalid client %Lx\n", conn->addr); - RETURN(-EINVAL); - } - - sb = class_conn2obd(conn)->u.filter.fo_sb; - - err = sb->s_op->statfs(sb, statfs); - RETURN(err); -} /* filter_statfs */ + struct obd_device *obd = class_conn2obd(conn); + ENTRY; + RETURN(vfs_statfs(obd->u.filter.fo_sb, statfs)); +} static int filter_get_info(struct lustre_handle *conn, obd_count keylen, void *key, obd_count *vallen, void **val) @@ -1332,8 +1329,8 @@ static int filter_get_info(struct lustre_handle *conn, obd_count keylen, if ( keylen == strlen("root_ino") && memcmp(key, "root_ino", keylen) == 0 ){ - *vallen = sizeof(long); - *val = (void *)(long)FILTER_ROOTINO; + *vallen = sizeof(obd_id); + *val = (void *)(obd_id)FILTER_ROOTINO; RETURN(0); } @@ -1346,9 +1343,15 @@ int filter_copy_data(struct lustre_handle *dst_conn, struct obdo *dst, obd_size count, obd_off offset) { struct page *page; + struct lov_stripe_md srcmd, dstmd; unsigned long index = 0; int err = 0; + memset(&srcmd, 0, sizeof(srcmd)); + memset(&dstmd, 0, sizeof(dstmd)); + srcmd.lmd_object_id = src->o_id; + dstmd.lmd_object_id = dst->o_id; + ENTRY; CDEBUG(D_INFO, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n", (unsigned long long)src->o_id, (unsigned long long)src->o_blocks, @@ -1365,16 +1368,14 @@ int filter_copy_data(struct lustre_handle *dst_conn, struct obdo *dst, * and arrays to handle the request parameters. */ while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) { - obd_count num_oa = 1; - obd_count num_buf = 1; 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; - err = obd_brw(OBD_BRW_READ, src_conn, num_oa, &src, &num_buf, - &page, &brw_count, &brw_offset, &flagr, NULL); + err = obd_brw(OBD_BRW_READ, src_conn, &srcmd, 1, &page, + &brw_count, &brw_offset, &flagr, NULL, NULL); if ( err ) { EXIT; @@ -1382,8 +1383,8 @@ int filter_copy_data(struct lustre_handle *dst_conn, struct obdo *dst, } CDEBUG(D_INFO, "Read page %ld ...\n", page->index); - err = obd_brw(OBD_BRW_WRITE, dst_conn, num_oa, &dst, &num_buf, - &page, &brw_count, &brw_offset, &flagw, NULL); + err = obd_brw(OBD_BRW_WRITE, dst_conn, &dstmd, 1, &page, + &brw_count, &brw_offset, &flagw, NULL, NULL); /* XXX should handle dst->o_size, dst->o_blocks here */ if ( err ) { @@ -1433,7 +1434,7 @@ static struct obd_ops filter_obd_ops = { static int __init obdfilter_init(void) { - printk(KERN_INFO "Filtering OBD driver v0.001, braam@clusterfs.com\n"); + printk(KERN_INFO "Filtering OBD driver v0.001, info@clusterfs.com\n"); return class_register_type(&filter_obd_ops, OBD_FILTER_DEVICENAME); } @@ -1442,7 +1443,7 @@ static void __exit obdfilter_exit(void) class_unregister_type(OBD_FILTER_DEVICENAME); } -MODULE_AUTHOR("Peter J. Braam "); +MODULE_AUTHOR("Cluster File Systems, Inc. "); MODULE_DESCRIPTION("Lustre Filtering OBD driver v1.0"); MODULE_LICENSE("GPL");