X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Finclude%2Flinux%2Flustre_fsfilt.h;h=40e991415b52e4ab28b846a016a87825b50367a7;hb=c3ced3e86c18ab5e457c090f2d2320802f7eb002;hp=6b0cbfa6d53800a4b0e4b6739bdd7c8e74bd4d38;hpb=040033cef24c5aca2967daf2da7a862abcd074cf;p=fs%2Flustre-release.git diff --git a/lustre/include/linux/lustre_fsfilt.h b/lustre/include/linux/lustre_fsfilt.h index 6b0cbfa..40e9914 100644 --- a/lustre/include/linux/lustre_fsfilt.h +++ b/lustre/include/linux/lustre_fsfilt.h @@ -28,9 +28,10 @@ #ifdef __KERNEL__ #include -#include +#include -typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, int error); +typedef void (*fsfilt_cb_t)(struct obd_device *obd, __u64 last_rcvd, + void *data, int error); struct fsfilt_objinfo { struct dentry *fso_dentry; @@ -41,29 +42,44 @@ struct fsfilt_operations { struct list_head fs_list; struct module *fs_owner; char *fs_type; - void *(* fs_start)(struct inode *inode, int op); + void *(* fs_start)(struct inode *inode, int op, void *desc_private, + int logs); void *(* fs_brw_start)(int objcount, struct fsfilt_objinfo *fso, - int niocount, struct niobuf_remote *nb); - int (* fs_commit)(struct inode *inode, void *handle); + int niocount, struct niobuf_local *nb, + void *desc_private, int logs); + int (* fs_commit)(struct inode *inode, void *handle,int force_sync); + int (* fs_commit_async)(struct inode *inode, void *handle, + void **wait_handle); + int (* fs_commit_wait)(struct inode *inode, void *handle); int (* fs_setattr)(struct dentry *dentry, void *handle, - struct iattr *iattr); + struct iattr *iattr, int do_trunc); + int (* fs_iocontrol)(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); int (* fs_set_md)(struct inode *inode, void *handle, void *md, int size); int (* fs_get_md)(struct inode *inode, void *md, int size); ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count, loff_t *offset); - int (* fs_journal_data)(struct file *file); - int (* fs_set_last_rcvd)(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func); + int (* fs_add_journal_cb)(struct obd_device *obd, __u64 last_rcvd, + void *handle, fsfilt_cb_t cb_func, + void *cb_data); int (* fs_statfs)(struct super_block *sb, struct obd_statfs *osfs); int (* fs_sync)(struct super_block *sb); + int (* fs_map_inode_page)(struct inode *inode, struct page *page, + unsigned long *blocks, int *created, + int create); int (* fs_prep_san_write)(struct inode *inode, long *blocks, int nblocks, loff_t newsize); + int (* fs_write_record)(struct file *, void *, int size, loff_t *, + int force_sync); + int (* fs_read_record)(struct file *, void *, int size, loff_t *); + int (* fs_setup)(struct super_block *sb); + int (* fs_get_op_len)(int, struct fsfilt_objinfo *, int); }; extern int fsfilt_register_ops(struct fsfilt_operations *fs_ops); extern void fsfilt_unregister_ops(struct fsfilt_operations *fs_ops); -extern struct fsfilt_operations *fsfilt_get_ops(char *type); +extern struct fsfilt_operations *fsfilt_get_ops(const char *type); extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); #define FSFILT_OP_UNLINK 1 @@ -75,46 +91,128 @@ extern void fsfilt_put_ops(struct fsfilt_operations *fs_ops); #define FSFILT_OP_MKNOD 7 #define FSFILT_OP_SETATTR 8 #define FSFILT_OP_LINK 9 +#define FSFILT_OP_CANCEL_UNLINK 10 -static inline void *fsfilt_start(struct obd_device *obd, - struct inode *inode, int op) +static inline void *fsfilt_start_log(struct obd_device *obd, + struct inode *inode, int op, + struct obd_trans_info *oti, int logs) { - ENTRY; - return obd->obd_fsops->fs_start(inode, op); + unsigned long now = jiffies; + void *parent_handle = oti ? oti->oti_handle : NULL; + void *handle = obd->obd_fsops->fs_start(inode, op, parent_handle, logs); + CDEBUG(D_HA, "started handle %p (%p)\n", handle, parent_handle); + + if (oti != NULL) { + if (parent_handle == NULL) { + oti->oti_handle = handle; + } else if (handle != parent_handle) { + CERROR("mismatch: parent %p, handle %p, oti %p\n", + parent_handle, handle, oti); + LBUG(); + } + } + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long journal start time %lus\n", (jiffies - now) / HZ); + return handle; +} + +static inline void *fsfilt_start(struct obd_device *obd, struct inode *inode, + int op, struct obd_trans_info *oti) +{ + return fsfilt_start_log(obd, inode, op, oti, 0); +} + +static inline void *fsfilt_brw_start_log(struct obd_device *obd, + int objcount, + struct fsfilt_objinfo *fso, + int niocount, struct niobuf_local *nb, + struct obd_trans_info *oti, int logs) +{ + unsigned long now = jiffies; + void *parent_handle = oti ? oti->oti_handle : NULL; + void *handle = obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb, + parent_handle, logs); + CDEBUG(D_HA, "started handle %p (%p)\n", handle, parent_handle); + + if (oti != NULL) { + if (parent_handle == NULL) { + oti->oti_handle = handle; + } else if (handle != parent_handle) { + CERROR("mismatch: parent %p, handle %p, oti %p\n", + parent_handle, handle, oti); + LBUG(); + } + } + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long journal start time %lus\n", (jiffies - now) / HZ); + + return handle; } static inline void *fsfilt_brw_start(struct obd_device *obd, int objcount, struct fsfilt_objinfo *fso, int niocount, - struct niobuf_remote *nb) + struct niobuf_local *nb, + struct obd_trans_info *oti) { - return obd->obd_fsops->fs_brw_start(objcount, fso, niocount, nb); + return fsfilt_brw_start_log(obd, objcount, fso, niocount, nb, oti, 0); } static inline int fsfilt_commit(struct obd_device *obd, struct inode *inode, - void *handle) + void *handle, int force_sync) +{ + unsigned long now = jiffies; + int rc = obd->obd_fsops->fs_commit(inode, handle, force_sync); + CDEBUG(D_HA, "committing handle %p\n", handle); + + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long journal start time %lus\n", (jiffies - now) / HZ); + + return rc; +} + +static inline int fsfilt_commit_async(struct obd_device *obd, + struct inode *inode, void *handle, + void **wait_handle) { - return obd->obd_fsops->fs_commit(inode, handle); - EXIT; + unsigned long now = jiffies; + int rc = obd->obd_fsops->fs_commit_async(inode, handle, wait_handle); + + CDEBUG(D_HA, "committing handle %p (async)\n", *wait_handle); + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long journal start time %lus\n", (jiffies - now) / HZ); + + return rc; +} + +static inline int fsfilt_commit_wait(struct obd_device *obd, + struct inode *inode, void *handle) +{ + unsigned long now = jiffies; + int rc = obd->obd_fsops->fs_commit_wait(inode, handle); + CDEBUG(D_HA, "waiting for completion %p\n", handle); + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long journal start time %lus\n", (jiffies - now) / HZ); + return rc; } static inline int fsfilt_setattr(struct obd_device *obd, struct dentry *dentry, - void *handle, struct iattr *iattr) + void *handle, struct iattr *iattr,int do_trunc) { + unsigned long now = jiffies; int rc; - /* - * NOTE: we probably don't need to take i_sem here when changing - * ATTR_SIZE because the MDS never needs to truncate a file. - * The ext2/ext3 code never truncates a directory, and files - * stored on the MDS are entirely sparse (no data blocks). - * If we do need to get it, we can do it here. - */ - lock_kernel(); - rc = obd->obd_fsops->fs_setattr(dentry, handle, iattr); - unlock_kernel(); - + rc = obd->obd_fsops->fs_setattr(dentry, handle, iattr, do_trunc); + if (time_after(jiffies, now + 15 * HZ)) + CERROR("long setattr time %lus\n", (jiffies - now) / HZ); return rc; } +static inline int fsfilt_iocontrol(struct obd_device *obd, struct inode *inode, + struct file *file, unsigned int cmd, + unsigned long arg) +{ + return obd->obd_fsops->fs_iocontrol(inode, file, cmd, arg); +} + static inline int fsfilt_set_md(struct obd_device *obd, struct inode *inode, void *handle, void *md, int size) { @@ -134,26 +232,44 @@ static inline ssize_t fsfilt_readpage(struct obd_device *obd, return obd->obd_fsops->fs_readpage(file, buf, count, offset); } -static inline int fsfilt_journal_data(struct obd_device *obd, struct file *file) +static inline int fsfilt_add_journal_cb(struct obd_device *obd, __u64 last_rcvd, + void *handle, fsfilt_cb_t cb_func, + void *cb_data) { - return obd->obd_fsops->fs_journal_data(file); + return obd->obd_fsops->fs_add_journal_cb(obd, last_rcvd, + handle, cb_func, cb_data); } -static inline int fsfilt_set_last_rcvd(struct obd_device *obd, __u64 last_rcvd, - void *handle, fsfilt_cb_t cb_func) +/* very similar to obd_statfs(), but caller already holds obd_osfs_lock */ +static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *sb, + unsigned long max_age) { - return obd->obd_fsops->fs_set_last_rcvd(obd, last_rcvd,handle,cb_func); + int rc = 0; + + CDEBUG(D_SUPER, "osfs %lu, max_age %lu\n", obd->obd_osfs_age, max_age); + if (time_before(obd->obd_osfs_age, max_age)) { + rc = obd->obd_fsops->fs_statfs(sb, &obd->obd_osfs); + if (rc == 0) /* N.B. statfs can't really fail */ + obd->obd_osfs_age = jiffies; + } else { + CDEBUG(D_SUPER, "using cached obd_statfs data\n"); + } + + return rc; } -static inline int fsfilt_statfs(struct obd_device *obd, struct super_block *fs, - struct obd_statfs *osfs) +static inline int fsfilt_sync(struct obd_device *obd, struct super_block *sb) { - return obd->obd_fsops->fs_statfs(fs, osfs); + return obd->obd_fsops->fs_sync(sb); } -static inline int fsfilt_sync(struct obd_device *obd, struct super_block *fs) +static inline int fsfilt_map_inode_page(struct obd_device *obd, + struct inode *inode, struct page *page, + unsigned long *blocks, int *created, + int create) { - return obd->obd_fsops->fs_sync(fs); + return obd->obd_fsops->fs_map_inode_page(inode, page, blocks, created, + create); } static inline int fs_prep_san_write(struct obd_device *obd, @@ -165,6 +281,27 @@ static inline int fs_prep_san_write(struct obd_device *obd, return obd->obd_fsops->fs_prep_san_write(inode, blocks, nblocks, newsize); } + +static inline int fsfilt_read_record(struct obd_device *obd, struct file *file, + void *buf, loff_t size, loff_t *offs) +{ + return obd->obd_fsops->fs_read_record(file, buf, size, offs); +} + +static inline int fsfilt_write_record(struct obd_device *obd, struct file *file, + void *buf, loff_t size, loff_t *offs, + int force_sync) +{ + return obd->obd_fsops->fs_write_record(file, buf, size,offs,force_sync); +} + +static inline int fsfilt_setup(struct obd_device *obd, struct super_block *fs) +{ + if (obd->obd_fsops->fs_setup) + return obd->obd_fsops->fs_setup(fs); + return 0; +} + #endif /* __KERNEL__ */ #endif