int (* fs_set_md)(struct inode *inode, void *handle, void *md,
int size);
int (* fs_get_md)(struct inode *inode, void *md, int size);
+ /* this method is needed to make IO operation fsfilt nature depend. */
+ int (* fs_send_bio)(int rw, struct inode *inode,struct kiobuf *bio);
ssize_t (* fs_readpage)(struct file *file, char *buf, size_t count,
loff_t *offset);
int (* fs_add_journal_cb)(struct obd_device *obd, __u64 last_rcvd,
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_map_inode_pages)(struct inode *inode, struct page **page,
+ int pages, unsigned long *blocks,
+ int *created, int create,
+ struct semaphore *sem);
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 *,
#define FSFILT_OP_LINK 9
#define FSFILT_OP_CANCEL_UNLINK 10
+#define fsfilt_check_slow(start, timeout, msg) \
+do { \
+ if (time_before(jiffies, start + 15 * HZ)) \
+ break; \
+ else if (time_before(jiffies, start + timeout / 2 * HZ)) \
+ CWARN("slow %s %lus\n", msg, (jiffies - start) / HZ); \
+ else \
+ CERROR("slow %s %lus\n", msg, (jiffies - start) / HZ); \
+} while (0)
+
static inline void *fsfilt_start_log(struct obd_device *obd,
struct inode *inode, int op,
struct obd_trans_info *oti, int logs)
LBUG();
}
}
- if (time_after(jiffies, now + 15 * HZ))
- CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+ fsfilt_check_slow(now, obd_timeout, "journal start");
return handle;
}
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);
+ CDEBUG(D_INFO, "started handle %p (%p)\n", handle, parent_handle);
if (oti != NULL) {
if (parent_handle == NULL) {
LBUG();
}
}
- if (time_after(jiffies, now + 15 * HZ))
- CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+ fsfilt_check_slow(now, obd_timeout, "journal start");
return handle;
}
int rc = obd->obd_fsops->fs_commit(inode, handle, force_sync);
CDEBUG(D_INFO, "committing handle %p\n", handle);
- if (time_after(jiffies, now + 15 * HZ))
- CERROR("long journal start time %lus\n", (jiffies - now) / HZ);
+ fsfilt_check_slow(now, obd_timeout, "journal start");
return rc;
}
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);
+ CDEBUG(D_INFO, "committing handle %p (async)\n", *wait_handle);
+ fsfilt_check_slow(now, obd_timeout, "journal start");
return rc;
}
{
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);
+ CDEBUG(D_INFO, "waiting for completion %p\n", handle);
+ fsfilt_check_slow(now, obd_timeout, "journal start");
return rc;
}
unsigned long now = jiffies;
int rc;
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);
+ fsfilt_check_slow(now, obd_timeout, "setattr");
return rc;
}
return obd->obd_fsops->fs_get_md(inode, md, size);
}
+static inline int fsfilt_send_bio(int rw, struct obd_device *obd,
+ struct inode *inode, void *bio)
+{
+ LASSERTF(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ, "%x\n", rw);
+
+ if (rw == OBD_BRW_READ)
+ return obd->obd_fsops->fs_send_bio(READ, inode, bio);
+ else
+ return obd->obd_fsops->fs_send_bio(WRITE, inode, bio);
+}
+
static inline ssize_t fsfilt_readpage(struct obd_device *obd,
struct file *file, char *buf,
size_t count, loff_t *offset)
return obd->obd_fsops->fs_sync(sb);
}
-static inline int fsfilt_map_inode_page(struct obd_device *obd,
- struct inode *inode, struct page *page,
- unsigned long *blocks, int *created,
- int create)
+static inline int fsfilt_map_inode_pages(struct obd_device *obd,
+ struct inode *inode,
+ struct page **page, int pages,
+ unsigned long *blocks, int *created,
+ int create, struct semaphore *sem)
{
- return obd->obd_fsops->fs_map_inode_page(inode, page, blocks, created,
- create);
+ return obd->obd_fsops->fs_map_inode_pages(inode, page, pages, blocks,
+ created, create, sem);
}
static inline int fs_prep_san_write(struct obd_device *obd,