Whamcloud - gitweb
LU-921 llite: warning in case of discarding dirty pages
[fs/lustre-release.git] / lustre / llite / llite_lib.c
index 08936e2..f1aa2af 100644 (file)
@@ -73,8 +73,9 @@ extern struct address_space_operations_ext ll_aops;
 
 static struct ll_sb_info *ll_init_sbi(void)
 {
-        struct ll_sb_info *sbi = NULL;
-        unsigned long pages;
+       struct ll_sb_info *sbi = NULL;
+       unsigned long pages;
+       unsigned long lru_page_max;
         struct sysinfo si;
         class_uuid_t uuid;
         int i;
@@ -94,13 +95,20 @@ static struct ll_sb_info *ll_init_sbi(void)
         pages = si.totalram - si.totalhigh;
         if (pages >> (20 - CFS_PAGE_SHIFT) < 512) {
 #ifdef HAVE_BGL_SUPPORT
-                sbi->ll_async_page_max = pages / 4;
+               lru_page_max = pages / 4;
 #else
-                sbi->ll_async_page_max = pages / 2;
+               lru_page_max = pages / 2;
 #endif
-        } else {
-                sbi->ll_async_page_max = (pages / 4) * 3;
-        }
+       } else {
+               lru_page_max = (pages / 4) * 3;
+       }
+
+       /* initialize lru data */
+       cfs_atomic_set(&sbi->ll_lru.ccl_users, 0);
+       sbi->ll_lru.ccl_page_max = lru_page_max;
+       cfs_atomic_set(&sbi->ll_lru.ccl_page_left, lru_page_max);
+       cfs_spin_lock_init(&sbi->ll_lru.ccl_lock);
+       CFS_INIT_LIST_HEAD(&sbi->ll_lru.ccl_list);
 
         sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32,
                                            SBI_DEFAULT_READAHEAD_MAX);
@@ -543,7 +551,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                                  NULL);
         cl_sb_init(sb);
 
-        sb->s_root = d_alloc_root(root);
+       err = obd_set_info_async(NULL, sbi->ll_dt_exp, sizeof(KEY_LRU_SET),
+                                KEY_LRU_SET, sizeof(sbi->ll_lru),
+                                &sbi->ll_lru, NULL);
+
+       sb->s_root = d_alloc_root(root);
 #ifdef HAVE_DCACHE_LOCK
        sb->s_root->d_op = &ll_d_root_ops;
 #else
@@ -1394,8 +1406,10 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr)
         int rc = 0, rc1 = 0;
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu valid %x\n", inode->i_ino,
-               attr->ia_valid);
+       CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu (%p) to %llu, valid %x\n",
+               inode->i_ino,
+               inode,i_size_read(inode),
+               attr->ia_valid);
 
         if (ia_valid & ATTR_SIZE) {
                 /* Check new size against VFS/VM file size limit and rlimit */
@@ -1848,8 +1862,8 @@ void ll_read_inode2(struct inode *inode, void *opaque)
         } else {
                 inode->i_op = &ll_special_inode_operations;
 
-                init_special_inode(inode, inode->i_mode,
-                                   kdev_t_to_nr(inode->i_rdev));
+               init_special_inode(inode, inode->i_mode,
+                                  inode->i_rdev);
 
                 EXIT;
         }
@@ -1952,17 +1966,17 @@ int ll_iocontrol(struct inode *inode, struct file *file,
                if (rc)
                        RETURN(rc);
 
-               OBDO_ALLOC(oinfo.oi_oa);
-               if (!oinfo.oi_oa)
-                       RETURN(-ENOMEM);
+               inode->i_flags = ll_ext_to_inode_flags(flags);
 
                lsm = ccc_inode_lsm_get(inode);
-               if (lsm == NULL) {
-                       inode->i_flags = ll_ext_to_inode_flags(flags);
-                       OBDO_FREE(oinfo.oi_oa);
+               if (lsm == NULL)
                        RETURN(0);
-               }
 
+               OBDO_ALLOC(oinfo.oi_oa);
+               if (!oinfo.oi_oa) {
+                       ccc_inode_lsm_put(inode, lsm);
+                       RETURN(-ENOMEM);
+               }
                oinfo.oi_md = lsm;
                 oinfo.oi_oa->o_id = lsm->lsm_object_id;
                 oinfo.oi_oa->o_seq = lsm->lsm_object_seq;
@@ -2393,3 +2407,48 @@ char *ll_get_fsname(struct super_block *sb, char *buf, int buflen)
 
        return buf;
 }
+
+static char* ll_d_path(struct dentry *dentry, char *buf, int bufsize)
+{
+       char *path = NULL;
+
+#ifdef HAVE_FS_STRUCT_USE_PATH
+       struct path p;
+
+       p.dentry = dentry;
+       p.mnt = current->fs->root.mnt;
+       path_get(&p);
+       path = d_path(&p, buf, bufsize);
+       path_put(&p);
+#else
+       path = d_path(dentry, current->fs->rootmnt, buf, bufsize);
+#endif
+
+       return path;
+}
+
+void ll_dirty_page_discard_warn(cfs_page_t *page, int ioret)
+{
+       char *buf, *path = NULL;
+       struct dentry *dentry = NULL;
+       struct ccc_object *obj = cl_inode2ccc(page->mapping->host);
+
+       buf = (char *)__get_free_page(GFP_KERNEL);
+       if (buf != NULL) {
+               dentry = d_find_alias(page->mapping->host);
+               if (dentry != NULL)
+                       path = ll_d_path(dentry, buf, PAGE_SIZE);
+       }
+
+       CWARN("%s: dirty page discard: %s/fid: "DFID"/%s may get corrupted "
+             "(rc %d)\n", ll_get_fsname(page->mapping->host->i_sb, NULL, 0),
+             s2lsi(page->mapping->host->i_sb)->lsi_lmd->lmd_dev,
+             PFID(&obj->cob_header.coh_lu.loh_fid),
+             (path && !IS_ERR(path)) ? path : "", ioret);
+
+       if (dentry != NULL)
+               dput(dentry);
+
+       if (buf != NULL)
+               free_page((unsigned long)buf);
+}