obdfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
ssize_t retval;
- CDEBUG(D_INODE, "Writing inode %ld, %d bytes, offset %ld\n", file->f_dentry->d_inode->i_ino, count, (long)*ppos);
+ CDEBUG(D_INFO, "Writing inode %ld, %d bytes, offset %ld\n", file->f_dentry->d_inode->i_ino, count, (long)*ppos);
retval = generic_file_write(file, buf, count,
ppos, obdfs_write_one_page);
- CDEBUG(D_INODE, "Wrote %d\n", retval);
+ CDEBUG(D_INFO, "Wrote %d\n", retval);
if (retval > 0) {
struct inode *inode = file->f_dentry->d_inode;
remove_suid(inode);
int interval; /* jiffies delay between pupdate flushes */
int age_buffer; /* Time for normal buffer to age before we flush it */
int age_super; /* Time for superblock to age before we flush it */
-} pupd_prm = {40, 500, 64, 256, 2*HZ, 30*HZ, 5*HZ };
+/* } pupd_prm = {40, 500, 64, 256, 2*HZ, 30*HZ, 5*HZ }; */
+} pupd_prm = {40, 500, 64, 256, 10*HZ, 30*HZ, 5*HZ };
/* Called with the superblock list lock */
static int obdfs_enqueue_pages(struct inode *inode, struct obdo **obdo,
int num = 0;
ENTRY;
- OIDEBUG(inode);
-
- *obdo = obdo_fromid(IID(inode), inode->i_ino, OBD_MD_FLNOTOBD);
- if ( IS_ERR(*obdo) ) {
- EXIT;
- return PTR_ERR(*obdo);
- }
-
- obdfs_from_inode(*obdo, inode); /* FIXME revisit fromid & from_inode */
- *flag = OBD_BRW_CREATE;
tmp = page_list;
- while ( ((tmp = tmp->next) != page_list) && (num < nr_slots) ) {
+ /* Traverse list in reverse order, so we do FIFO, not LIFO order */
+ while ( (tmp = tmp->prev) != page_list && num < nr_slots ) {
struct obdfs_pgrq *req;
struct page *page;
if (check_time &&
(jiffies - req->rq_jiffies) < pupd_prm.age_buffer)
- continue;
+ continue; /* FIXME break; (pages are in order) */
+
+ /* Only allocate the obdo if we will actually do I/O here */
+ if ( !*obdo ) {
+ OIDEBUG(inode);
+ *obdo = obdo_fromid(IID(inode), inode->i_ino,
+ OBD_MD_FLNOTOBD);
+ if ( IS_ERR(*obdo) ) {
+ int err = PTR_ERR(*obdo);
+ *obdo = NULL;
+
+ EXIT;
+ return err;
+ }
+
+ /* FIXME revisit fromid & from_inode */
+ obdfs_from_inode(*obdo, inode);
+ *flag = OBD_BRW_CREATE;
+ }
/* Remove request from list before write to avoid conflict.
* Note that obdfs_pgrq_del() also deletes the request.
*/
obdfs_pgrq_del(req);
if ( !page ) {
- CDEBUG(D_INODE, "no page \n");
+ CDEBUG(D_CACHE, "no page \n");
continue;
}
pages[num] = page;
counts[num] = PAGE_SIZE;
offsets[num] = ((obd_off)page->index) << PAGE_SHIFT;
- CDEBUG(D_INODE, "ENQ inode %ld, page %p addr %p to vector\n",
+ CDEBUG(D_INFO, "ENQ inode %ld, page %p addr %p to vector\n",
inode->i_ino, page, (char *)page_address(page));
num++;
}
if (!list_empty(page_list))
- CDEBUG(D_INODE, "inode %ld list not empty\n", inode->i_ino);
- CDEBUG(D_INODE, "added %d page(s) to vector\n", num);
+ CDEBUG(D_CACHE, "inode %ld list not empty\n", inode->i_ino);
+ CDEBUG(D_INFO, "added %d page(s) to vector\n", num);
EXIT;
return num;
{
struct list_head *tmp;
int total_io = 0;
- obd_count num_io = 0;
- obd_count num_obdos = 0;
+ obd_count num_io;
+ obd_count num_obdos;
struct inode *inodes[MAX_IOVEC]; /* write data back to these */
struct page *pages[MAX_IOVEC]; /* call put_page on these */
struct obdo *obdos[MAX_IOVEC];
sbi = list_entry(inode_list, struct obdfs_sb_info, osi_inodes);
obd_down(&sbi->osi_list_mutex);
- if ( list_empty(inode_list)) {
- CDEBUG(D_INODE, "list empty\n");
+ if ( list_empty(inode_list) ) {
+ CDEBUG(D_CACHE, "list empty\n");
obd_up(&sbi->osi_list_mutex);
EXIT;
return 0;
}
- /* add each inode's dirty pages to a write vector, and write it */
+ /* Add each inode's dirty pages to a write vector, and write it.
+ * Traverse list in reverse order, so we do FIFO, not LIFO order
+ */
again:
tmp = inode_list;
- while ( (tmp = tmp->next) != inode_list &&
- total_io < pupd_prm.ndirty) {
+ num_io = 0;
+ num_obdos = 0;
+ while ( (tmp = tmp->prev) != inode_list && total_io < pupd_prm.ndirty) {
struct obdfs_inode_info *ii;
struct inode *inode;
int res;
ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
inode = list_entry(ii, struct inode, u);
inodes[num_obdos] = inode;
- CDEBUG(D_INODE, "checking inode %ld pages\n", inode->i_ino);
+ obdos[num_obdos] = NULL;
+ CDEBUG(D_INFO, "checking inode %ld pages\n", inode->i_ino);
- res = 1;
-
- /* Loop on this inode until we can't get more pages from it
- * (either no more pages, or the pages aren't old enough).
- * Make sure we reference "inode" and not "inodes[num_obdos]",
+ /* Make sure we reference "inode" and not "inodes[num_obdos]",
* as num_obdos will change after the loop is run.
*/
- while (!list_empty(obdfs_iplist(inode)) && res &&
- total_io < pupd_prm.ndirty ) {
+ if (!list_empty(obdfs_iplist(inode))) {
res = obdfs_enqueue_pages(inode, &obdos[num_obdos],
MAX_IOVEC - num_io,
&pages[num_io], &bufs[num_io],
&offsets[num_io],
&flags[num_obdos],
check_time);
- CDEBUG(D_INODE, "FLUSHED inode %ld, pages flushed: %d\n",
+ CDEBUG(D_CACHE, "FLUSH inode %ld, pages flushed: %d\n",
inode->i_ino, res);
if ( res < 0 ) {
- obd_up(&sbi->osi_list_mutex);
err = res;
- goto ERR;
+ EXIT;
+ goto BREAK;
+ } else if (res) {
+ num_io += res;
+ total_io += res;
+ bufs_per_obdo[num_obdos] = res;
+ num_obdos++;
}
-
- num_io += res;
- total_io += res;
- bufs_per_obdo[num_obdos] = res;
- num_obdos++;
if ( num_io == MAX_IOVEC ) {
obd_up(&sbi->osi_list_mutex);
EXIT;
goto ERR;
}
- inodes[0] = inode;
- num_io = 0;
- num_obdos = 0;
obd_down(&sbi->osi_list_mutex);
goto again;
}
}
}
+BREAK:
obd_up(&sbi->osi_list_mutex);
/* flush any remaining I/Os */
err = obdfs_do_vec_wr(inodes, num_io, num_obdos, obdos,
bufs_per_obdo, pages, bufs, counts,
offsets, flags);
+ num_io = 0;
+ num_obdos = 0;
}
/* Remove inode from superblock dirty list when no more pages.
*/
obd_down(&sbi->osi_list_mutex);
tmp = inode_list;
- while ( (tmp = tmp->next) != inode_list ) {
+ while ( (tmp = tmp->prev) != inode_list ) {
struct obdfs_inode_info *ii;
struct inode *inode;
ii = list_entry(tmp, struct obdfs_inode_info, oi_inodes);
inode = list_entry(ii, struct inode, u);
- CDEBUG(D_INODE, "checking inode %ld empty\n", inode->i_ino);
+ CDEBUG(D_INFO, "checking inode %ld empty\n", inode->i_ino);
if (list_empty(obdfs_iplist(inode))) {
- CDEBUG(D_INODE, "remove inode %ld from dirty list\n",
+ CDEBUG(D_CACHE, "remove inode %ld from dirty list\n",
inode->i_ino);
- tmp = tmp->prev;
+ tmp = tmp->next;
list_del(obdfs_islist(inode));
/* decrement inode reference for page cache */
inode->i_count--;
}
obd_up(&sbi->osi_list_mutex);
- CDEBUG(D_INODE, "flushed %d pages in total\n", total_io);
+ CDEBUG(D_INFO, "flushed %d pages in total\n", total_io);
EXIT;
ERR:
return err;
ENTRY;
sl = &obdfs_super_list;
- while ( (sl = sl->next) != &obdfs_super_list ) {
+ while ( (sl = sl->prev) != &obdfs_super_list ) {
struct obdfs_sb_info *sbi =
list_entry(sl, struct obdfs_sb_info, osi_list);
unsigned long offset;
struct page * page;
ENTRY;
- CDEBUG(D_INODE, "find entry for %*s\n", namelen, name);
+ CDEBUG(D_INFO, "find entry for %*s\n", namelen, name);
*res_dir = NULL;
sb = dir->i_sb;
if (namelen > EXT2_NAME_LEN)
return NULL;
- CDEBUG(D_INODE, "dirsize is %Ld\n", dir->i_size);
+ CDEBUG(D_INFO, "dirsize is %Ld\n", dir->i_size);
page = 0;
offset = 0;
page = obdfs_getpage(dir, offset, 0, lock);
if ( !page ) {
- CDEBUG(D_INODE, "No page, offset %lx\n", offset);
+ CDEBUG(D_INFO, "No page, offset %lx\n", offset);
return NULL;
}
/* this code is executed quadratically often */
/* do minimal checking `by hand' */
int de_len;
- /* CDEBUG(D_INODE, "Entry %p len %d, page at %#lx - %#lx , offset %lx\n",
+ /* CDEBUG(D_INFO, "Entry %p len %d, page at %#lx - %#lx , offset %lx\n",
de, le16_to_cpu(de->rec_len), page_address(page),
page_address(page) + PAGE_SIZE, offset); */
offset += de_len;
de = (struct ext2_dir_entry_2 *)
((char *) de + de_len);
- /* CDEBUG(D_INODE, "Next while %lx\n", offset); */
+ /* CDEBUG(D_INFO, "Next while %lx\n", offset); */
}
if ( lock )
UnlockPage(page);
page_cache_release(page);
page = NULL;
- CDEBUG(D_INODE, "Next for %lx\n", offset);
+ CDEBUG(D_INFO, "Next for %lx\n", offset);
}
failure:
- CDEBUG(D_INODE, "Negative case, page %p, offset %ld\n", page, offset);
+ CDEBUG(D_INFO, "Negative case, page %p, offset %ld\n", page, offset);
if (page) {
if (lock)
UnlockPage(page);
&de, LOCKED);
inode = NULL;
if ( !page )
- CDEBUG(D_INODE, "No page - negative entry.\n");
+ CDEBUG(D_INFO, "No page - negative entry.\n");
if ( page && !de ) {
CDEBUG(D_INODE, "Danger: PAGE but de.\n");
return ERR_PTR(-ENOENT);
*err = -EINVAL;
*res_dir = NULL;
if (!dir || !dir->i_nlink) {
+ CDEBUG(D_INODE, "bad directory\n");
EXIT;
return NULL;
}
sb = dir->i_sb;
if (!namelen) {
+ CDEBUG(D_INODE, "bad directory\n");
EXIT;
return NULL;
}
return NULL;
}
rec_len = EXT2_DIR_REC_LEN(namelen);
- /* CDEBUG(D_INODE, "reclen: %d\n", rec_len); */
+ /* CDEBUG(D_INFO, "reclen: %d\n", rec_len); */
PDEBUG(page, "starting search");
offset = 0;
de = (struct ext2_dir_entry_2 *) page_address(page);
*err = -ENOSPC;
while (1) {
- /* CDEBUG(D_INODE,
+ /* CDEBUG(D_INFO,
"Entry at %p, (page at %#lx - %#lx), offset %ld\n",
de, page_address(page), page_address(page) + PAGE_SIZE,
offset); */
return NULL;
}
- CDEBUG(D_INODE, "creating next block\n");
+ CDEBUG(D_INFO, "creating next block\n");
de = (struct ext2_dir_entry_2 *) page_address(page);
de->inode = 0;
EXIT;
return NULL;
}
- CDEBUG(D_INODE, "\n");
+ CDEBUG(D_INFO, "\n");
if (ext2_match (namelen, name, de)) {
*err = -EEXIST;
UnlockPage(page);
EXIT;
return NULL;
}
- /* CDEBUG(D_INODE, "Testing for enough space at de %p\n", de);*/
+ /* CDEBUG(D_INFO, "Testing for enough space at de %p\n", de);*/
if ( (le32_to_cpu(de->inode) == 0 && le16_to_cpu(de->rec_len) >= rec_len) ||
(le16_to_cpu(de->rec_len) >= EXT2_DIR_REC_LEN(de->name_len) + rec_len)) {
offset += le16_to_cpu(de->rec_len);
- /* CDEBUG(D_INODE,
+ /* CDEBUG(D_INFO,
"Found enough space de %p, offset %#lx\n",
de, offset); */
if (le32_to_cpu(de->inode)) {
- /*CDEBUG(D_INODE, "Insert new in %p\n", de);*/
+ /*CDEBUG(D_INFO, "Insert new in %p\n", de);*/
de1 = (struct ext2_dir_entry_2 *) ((char *) de +
EXT2_DIR_REC_LEN(de->name_len));
- /*CDEBUG(D_INODE, "-- de1 at %p\n", de1);*/
+ /*CDEBUG(D_INFO, "-- de1 at %p\n", de1);*/
de1->rec_len = cpu_to_le16(le16_to_cpu(de->rec_len) -
EXT2_DIR_REC_LEN(de->name_len));
de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(de->name_len));
de = de1;
}
- /* CDEBUG(D_INODE,
+ /* CDEBUG(D_INFO,
"Reclen adjusted; copy %d bytes to %p, "
"page at %#lx EOP at %#lx\n",
namelen, de->name, page_address(page),
oinfo = obdfs_i2info(inode);
if (l >= sizeof(oinfo->oi_inline)) {
- CDEBUG(D_INODE, "l=%d, normal symlink\n", l);
+ CDEBUG(D_INFO, "l=%d, normal symlink\n", l);
name_page = obdfs_getpage(inode, 0, 1, LOCKED);
if (!name_page) {
link = oinfo->oi_inline;
oinfo->oi_flags |= OBD_FL_INLINEDATA;
- CDEBUG(D_INODE, "l=%d, fast symlink\n", l);
+ CDEBUG(D_INFO, "l=%d, fast symlink\n", l);
}
i = 0;
while (i < inode->i_sb->s_blocksize - 1 && (c = *(symname++)))
if ( old_page != new_page ) {
unsigned long index = old_page->index;
/* lock the old_page and release unlocked copy */
- CDEBUG(D_INODE, "old_page at %p\n", old_page);
+ CDEBUG(D_INFO, "old_page at %p\n", old_page);
page_cache_release(old_page);
old_page = obdfs_getpage(old_dir, index << PAGE_SHIFT, 0,
LOCKED);
- CDEBUG(D_INODE, "old_page at %p\n", old_page);
+ CDEBUG(D_INFO, "old_page at %p\n", old_page);
err = obdfs_do_writepage(old_dir, old_page, IS_SYNC(old_dir));
/* XXX handle err */
}
{
ENTRY;
if (obdfs_pgrq_cachep == NULL) {
- CDEBUG(D_INODE, "allocating obdfs_pgrq_cache\n");
+ CDEBUG(D_CACHE, "allocating obdfs_pgrq_cache\n");
obdfs_pgrq_cachep = kmem_cache_create("obdfs_pgrq",
sizeof(struct obdfs_pgrq),
0, SLAB_HWCACHE_ALIGN,
EXIT;
return -ENOMEM;
} else {
- CDEBUG(D_INODE, "allocated cache at %p\n",
+ CDEBUG(D_CACHE, "allocated cache at %p\n",
obdfs_pgrq_cachep);
}
} else {
- CDEBUG(D_INODE, "using existing cache at %p\n",
+ CDEBUG(D_CACHE, "using existing cache at %p\n",
obdfs_pgrq_cachep);
}
EXIT;
inline void obdfs_pgrq_del(struct obdfs_pgrq *pgrq)
{
obdfs_cache_count--;
- CDEBUG(D_INODE, "deleting page %p from list [count %d]\n",
+ CDEBUG(D_INFO, "deleting page %p from list [count %d]\n",
pgrq->rq_page, obdfs_cache_count);
list_del(&pgrq->rq_plist);
kmem_cache_free(obdfs_pgrq_cachep, pgrq);
{
ENTRY;
if (obdfs_pgrq_cachep != NULL) {
- CDEBUG(D_INODE, "destroying obdfs_pgrqcache at %p, count %d\n",
+ CDEBUG(D_CACHE, "destroying obdfs_pgrqcache at %p, count %d\n",
obdfs_pgrq_cachep, obdfs_cache_count);
if (kmem_cache_destroy(obdfs_pgrq_cachep))
printk(KERN_INFO __FUNCTION__
ENTRY;
- CDEBUG(D_INODE, "looking for inode %ld page %p\n", inode->i_ino, page);
+ CDEBUG(D_INFO, "looking for inode %ld page %p\n", inode->i_ino, page);
OIDEBUG(inode);
if (list_empty(page_list)) {
- CDEBUG(D_INODE, "empty list\n");
+ CDEBUG(D_INFO, "empty list\n");
EXIT;
return NULL;
}
pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
if (pgrq->rq_page == page) {
- CDEBUG(D_INODE, "found page %p in list\n", page);
+ CDEBUG(D_INFO, "found page %p in list\n", page);
EXIT;
return pgrq;
}
ENTRY;
- CDEBUG(D_INODE, "looking for inode %ld pageindex %ld\n",
+ CDEBUG(D_INFO, "looking for inode %ld pageindex %ld\n",
inode->i_ino, index);
OIDEBUG(inode);
pgrq = list_entry(tmp, struct obdfs_pgrq, rq_plist);
page = pgrq->rq_page;
if (index == page->index) {
- CDEBUG(D_INODE,
+ CDEBUG(D_INFO,
"INDEX SEARCH found page %p, index %ld\n",
page, index);
EXIT;
int err;
ENTRY;
- CDEBUG(D_INODE, "writing %d page(s), %d obdo(s) in vector\n",
+ CDEBUG(D_INFO, "writing %d page(s), %d obdo(s) in vector\n",
num_io, num_obdos);
err = OPS(sb, brw)(WRITE, &sbi->osi_conn, num_obdos, obdos, oa_bufs,
bufs, counts, offsets, flags);
/* release the pages from the page cache */
while ( num_io > 0 ) {
num_io--;
- CDEBUG(D_INODE, "calling put_page for %p, index %ld\n",
+ CDEBUG(D_INFO, "calling put_page for %p, index %ld\n",
pages[num_io], pages[num_io]->index);
put_page(pages[num_io]);
}
while ( num_obdos > 0) {
num_obdos--;
- CDEBUG(D_INODE, "copy/free obdo %ld\n",
+ CDEBUG(D_INFO, "copy/free obdo %ld\n",
(long)obdos[num_obdos]->o_id);
obdfs_to_inode(inodes[num_obdos], obdos[num_obdos]);
obdo_free(obdos[num_obdos]);
if ( !obdfs_find_in_page_list(inode, page) ) {
struct obdfs_pgrq *pgrq;
pgrq = kmem_cache_alloc(obdfs_pgrq_cachep, SLAB_KERNEL);
- CDEBUG(D_INODE, "adding inode %ld page %p, pgrq: %p, cache count [%d]\n",
- inode->i_ino, page, pgrq, obdfs_cache_count);
+ CDEBUG(D_INFO,
+ "adding inode %ld page %p, pgrq: %p, cache count [%d]\n",
+ inode->i_ino, page, pgrq, obdfs_cache_count + 1);
if (!pgrq) {
EXIT;
obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
memset(pgrq, 0, sizeof(*pgrq));
pgrq->rq_page = page;
+ pgrq->rq_jiffies = jiffies;
get_page(pgrq->rq_page);
list_add(&pgrq->rq_plist, obdfs_iplist(inode));
obdfs_cache_count++;
*/
if ( list_empty(obdfs_islist(inode)) ) {
inode->i_count++;
- CDEBUG(D_INODE, "adding inode %ld to superblock list %p\n",
+ CDEBUG(D_INFO, "adding inode %ld to superblock list %p\n",
inode->i_ino, obdfs_slist(inode));
list_add(obdfs_islist(inode), obdfs_slist(inode));
}
err = obdfs_brw(WRITE, inode, page, 1);
else {
err = obdfs_add_page_to_cache(inode, page);
- CDEBUG(D_IOCTL, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n", inode->i_ino, page, err, Page_Uptodate(page));
+ CDEBUG(D_INFO, "DO_WR ino: %ld, page %p, err %d, uptodate %d\n",
+ inode->i_ino, page, err, Page_Uptodate(page));
}
if ( !err )
ENTRY;
offset = offset & PAGE_CACHE_MASK;
- CDEBUG(D_INODE, "ino: %ld, offset %ld, create %d, locked %d\n",
+ CDEBUG(D_INFO, "ino: %ld, offset %ld, create %d, locked %d\n",
inode->i_ino, offset, create, locked);
index = offset >> PAGE_CACHE_SHIFT;
EXIT;
return NULL;
}
- CDEBUG(D_INODE, "page_cache %p\n", page_cache);
+ CDEBUG(D_INFO, "page_cache %p\n", page_cache);
hash = page_hash(&inode->i_data, index);
page = grab_cache_page(&inode->i_data, index);
if ( obdfs_find_page_index(inode, index) ) {
- CDEBUG(D_INODE, "OVERWRITE: found dirty page %p, index %ld\n",
+ CDEBUG(D_INFO, "OVERWRITE: found dirty page %p, index %ld\n",
page, page->index);
}
char *value;
char *retval;
- CDEBUG(D_SUPER, "option: %s, data %s\n", opt, data);
+ CDEBUG(D_INFO, "option: %s, data %s\n", opt, data);
if ( strncmp(opt, data, strlen(opt)) )
return NULL;
}
memcpy(retval, value, strlen(value)+1);
- CDEBUG(D_SUPER, "Assigned option: %s, value %s\n", opt, retval);
+ CDEBUG(D_INFO, "Assigned option: %s, value %s\n", opt, retval);
return retval;
}
for (this_char = strtok (options, ",");
this_char != NULL;
this_char = strtok (NULL, ",")) {
- CDEBUG(D_SUPER, "this_char %s\n", this_char);
+ CDEBUG(D_INFO, "this_char %s\n", this_char);
if ( (!*dev && (*dev = obdfs_read_opt("device", this_char)))||
(!*vers && (*vers = obdfs_read_opt("version", this_char))) )
continue;
goto ERR;
}
- CDEBUG(D_SUPER, "obdfs_read_super: sbdev %d, rootino: %ld, dev %s, "
+ CDEBUG(D_INFO, "obdfs_read_super: sbdev %d, rootino: %ld, dev %s, "
"minor: %d, blocksize: %ld, blocksize bits %ld\n",
sb->s_dev, root->i_ino, device, MINOR(devno),
blocksize, blocksize_bits);
obd_down(&obdfs_i2sbi(inode)->osi_list_mutex);
tmp = obdfs_islist(inode);
if ( list_empty(tmp) ) {
- CDEBUG(D_INODE, __FUNCTION__ ": no dirty pages for inode %ld\n",
- inode->i_ino);
+ CDEBUG(D_INFO, "no dirty pages for inode %ld\n", inode->i_ino);
obd_up(&obdfs_i2sbi(inode)->osi_list_mutex);
EXIT;
return;