void ocfs2_evict_inode(struct inode *inode) { if (!inode->i_nlink || (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) { ocfs2_delete_inode(inode); } else { truncate_inode_pages(&inode->i_data, 0); } ocfs2_clear_inode(inode); }
static int remove_quota_files_iterate(struct ocfs2_dir_entry *dirent, uint64_t blocknr, int offset, int blocksize, char *buf, void *priv_data) { struct remove_quota_files_ctxt *ctxt = priv_data; char dname[OCFS2_MAX_FILENAME_LEN]; char wname[OCFS2_MAX_FILENAME_LEN]; errcode_t ret; int tail, i; int ret_flags = 0; strncpy(dname, dirent->name, dirent->name_len); dname[dirent->name_len] = 0; /* Check whether entry is quota file of type we want - i.e. matching * aquota.user:[0-9][0-9][0-9][0-9] or aquota.user for type == USRQUOTA * and similarly for type == GRPQUOTA */ strcpy(wname, "aquota."); strcat(wname, type2name(ctxt->type)); tail = strlen(wname); if (strncmp(dname, wname, tail)) return 0; if (dname[tail] == ':') { /* May be local file? */ tail++; for (i = 0; i < 4; i++) if (dname[tail + i] < '0' || dname[tail + i] > '9') return 0; if (dname[tail + i]) return 0; } else if (dname[tail]) /* May be global file? */ return 0; verbosef(VL_APP, "Deleting quota file %s\n", dname); ret = ocfs2_truncate(ctxt->fs, dirent->inode, 0); if (ret) { tcom_err(ret, "while truncating quota file \"%s\"", dname); ret_flags |= OCFS2_DIRENT_ERROR; ctxt->err = ret; goto out; } ret = ocfs2_delete_inode(ctxt->fs, dirent->inode); if (ret) { tcom_err(ret, "while deleting quota file \"%s\"", dname); ret_flags |= OCFS2_DIRENT_ERROR; ctxt->err = ret; } else { dirent->inode = 0; ret_flags |= OCFS2_DIRENT_CHANGED; } out: return ret_flags; }
static int remove_slot_iterate(struct ocfs2_dir_entry *dirent, int offset, int blocksize, char *buf, void *priv_data) { struct remove_slot_ctxt *ctxt = (struct remove_slot_ctxt *)priv_data; int taillen, ret_flags = 0; errcode_t ret; char dname[OCFS2_MAX_FILENAME_LEN]; char tail[OCFS2_MAX_FILENAME_LEN]; sprintf(tail, ":%04d", ctxt->removed_slot); taillen = strlen(tail); strncpy(dname, dirent->name, dirent->name_len); dname[dirent->name_len] = '\0'; if (!strcmp(dname + (dirent->name_len - taillen), tail)) { verbosef(VL_APP, "Unlinking system file \"%s\"\n", dname); ret = ocfs2_delete_inode(ctxt->fs, dirent->inode); if (ret) { verbosef(VL_APP, "%s while unlinking system file \"%s\"\n", error_message(ret), dname); ret_flags |= OCFS2_DIRENT_ERROR; ctxt->errcode = ret; } else { verbosef(VL_APP, "Successfully unlinked system file " "\"%s\"\n", dname); dirent->inode = 0; ret_flags |= OCFS2_DIRENT_CHANGED; } } return ret_flags; }
static void check_root(o2fsck_state *ost) { struct ocfs2_super_block *sb = OCFS2_RAW_SB(ost->ost_fs->fs_super); errcode_t ret; uint64_t blkno, old_root; int was_set; if (o2fsck_test_inode_allocated(ost, ost->ost_fs->fs_root_blkno)) { ocfs2_bitmap_test(ost->ost_dir_inodes, ost->ost_fs->fs_root_blkno, &was_set); if (!was_set) printf("The root inode exists but isn't a " "directory.\n"); return; } if (!prompt(ost, PY, PR_ROOT_DIR_MISSING, "The super block claims that inode %"PRIu64" is the root " "directory but it isn't allocated. Create a new root " "directory and update the super block?", ost->ost_fs->fs_root_blkno)) return; ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR); if (ret) { com_err(whoami, ret, "while trying to allocate a new inode " "for the root directory\n"); return; } ret = ocfs2_init_dir(ost->ost_fs, blkno, blkno); if (ret) { com_err(whoami, ret, "while trying to expand a new root " "directory"); goto out; } o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 1); o2fsck_icount_set(ost->ost_icount_refs, blkno, 1); ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, ost->ost_fs->fs_root_blkno, ost->ost_fs->fs_root_blkno, 0); if (ret) { com_err(whoami, ret, "while recording a new root directory"); goto out; } old_root = sb->s_root_blkno; ost->ost_fs->fs_root_blkno = blkno; sb->s_root_blkno = blkno; ret = ocfs2_write_primary_super(ost->ost_fs); if (ret) { com_err(whoami, ret, "while writing the super block with a " "new root directory inode"); ost->ost_fs->fs_root_blkno = old_root; sb->s_root_blkno = old_root; goto out; } blkno = 0; out: if (blkno) { ret = ocfs2_delete_inode(ost->ost_fs, blkno); if (ret) { com_err(whoami, ret, "while trying to clean up an " "an allocated inode after linking /lost+found " "failed"); } } }
static void check_lostfound(o2fsck_state *ost) { char name[] = "lost+found"; int namelen = sizeof(name) - 1; uint64_t blkno; errcode_t ret; ret = ocfs2_lookup(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, namelen, NULL, &ost->ost_lostfound_ino); if (ret == 0) return; if (!prompt(ost, PY, PR_LOSTFOUND_MISSING, "/lost+found does not exist. Create it so " "that we can possibly fill it with orphaned inodes?")) return; ret = ocfs2_new_inode(ost->ost_fs, &blkno, 0755 | S_IFDIR); if (ret) { com_err(whoami, ret, "while trying to allocate a new inode " "for /lost+found"); return; } ret = ocfs2_init_dir(ost->ost_fs, blkno, ost->ost_fs->fs_root_blkno); if (ret) { com_err(whoami, ret, "while trying to expand a new " "/lost+found directory"); goto out; } ret = ocfs2_link(ost->ost_fs, ost->ost_fs->fs_root_blkno, name, blkno, OCFS2_FT_DIR); if (ret) { com_err(whoami, ret, "while linking inode %"PRIu64" as " "/lost+found", blkno); goto out; } /* XXX maybe this should be a helper to clean up the dir tracking * for any new dir. "2" for both the l+f dirent pointing to the * inode and the "." dirent in its dirblock */ o2fsck_icount_set(ost->ost_icount_in_inodes, blkno, 2); o2fsck_icount_set(ost->ost_icount_refs, blkno, 2); ret = o2fsck_add_dir_parent(&ost->ost_dir_parents, blkno, ost->ost_fs->fs_root_blkno, ost->ost_fs->fs_root_blkno, 0); if (ret) { com_err(whoami, ret, "while recording a new /lost+found " "directory"); goto out; } /* we've already iterated through the dirblocks in pass2 so there * is no need to register l+f's new dir block */ ost->ost_lostfound_ino = blkno; blkno = 0; out: if (blkno) { ret = ocfs2_delete_inode(ost->ost_fs, blkno); if (ret) { com_err(whoami, ret, "while trying to clean up an " "an allocated inode after linking /lost+found " "failed"); } } }