static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { /* EXERCISE: Your code here. */ ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); ospfs_direntry_t *od; ospfs_inode_t *oi; uint32_t entry_ino = 0; if (dst_dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; if (find_direntry(dir_oi, dst_dentry->d_name.name, dst_dentry->d_name.len)) return -EEXIST; od = create_blank_direntry(dir_oi); if (IS_ERR(od)) return -ENOSPC; for (entry_ino = 2; entry_ino < ospfs_super->os_ninodes; entry_ino++) { oi = ospfs_inode(entry_ino); if (oi->oi_nlink == 0) break; } if (entry_ino == ospfs_super->os_ninodes) return -EIO; od->od_ino = src_dentry->d_inode->i_ino; strcpy(od->od_name, dst_dentry->d_name.name); oi = ospfs_inode(od->od_ino); oi->oi_nlink++; return 0; }
/* Setup up watchers, directory as well as initial files */ static HCDirEntry * setup_watchers(int fd) { HCFileInfo *conf = g_config; HCDirEntry *head_dir = NULL, *last_dir = NULL, *dir; char fname[MAX_PATH_LEN]; char *dname; while (conf) { conf->wd = inotify_add_watch(fd, conf->fname, IN_DELETE_SELF | IN_CLOSE_WRITE | IN_ATTRIB); TSDebug(PLUGIN_NAME, "Setting up a watcher for %s", conf->fname); strncpy(fname, conf->fname, MAX_PATH_LEN - 1); dname = dirname(fname); /* Make sure to only watch each directory once */ if (!(dir = find_direntry(dname, head_dir))) { TSDebug(PLUGIN_NAME, "Setting up a watcher for directory %s", dname); dir = TSmalloc(sizeof(HCDirEntry)); memset(dir, 0, sizeof(HCDirEntry)); strncpy(dir->dname, dname, MAX_PATH_LEN - 1); dir->wd = inotify_add_watch(fd, dname, IN_CREATE | IN_MOVED_FROM | IN_MOVED_TO | IN_ATTRIB); if (!head_dir) { head_dir = dir; } else { last_dir->_next = dir; } last_dir = dir; } conf->dir = dir; conf = conf->_next; } return head_dir; }
static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); ospfs_inode_t *src_oi = ospfs_inode(src_dentry->d_inode->i_ino); ospfs_direntry_t *entry; if (dst_dentry->d_name.len > OSPFS_MAXSYMLINKLEN) { return -ENAMETOOLONG; } if (find_direntry(dir_oi, dst_dentry->d_name.name, dst_dentry->d_name.len) != NULL) { return -EEXIST; } if (dir_oi == NULL || dir_oi->oi_nlink + 1 == 0) { return -EIO; } entry = create_blank_direntry(dir_oi); if (IS_ERR(entry)) { return PTR_ERR(entry); } else if(entry == NULL) { return -EIO; } entry->od_ino = src_dentry->d_inode->i_ino; memcpy(entry->od_name, dst_dentry->d_name.name, dst_dentry->d_name.len); entry->od_name[dst_dentry->d_name.len] = 0; src_oi->oi_nlink++; dir_oi->oi_nlink++; return 0; }
static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { ospfs_direntry_t* link; // check if name too long if (dst_dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; // check if directory entry already exists if (find_direntry(ospfs_inode(dir->i_ino), dst_dentry->d_name.name, dst_dentry->d_name.len)) return -EEXIST; // create new hardlinked file link = create_blank_direntry(ospfs_inode(dir->i_ino)); if (IS_ERR(link)) return PTR_ERR(link); // copy file information link->od_ino = src_dentry->d_inode->i_ino; memcpy(link->od_name, dst_dentry->d_name.name, dst_dentry->d_name.len); link->od_name[dst_dentry->d_name.len] = '\0'; // increment source file link count ospfs_inode(src_dentry->d_inode->i_ino)->oi_nlink++; return 0; }
/* Setup up watchers, directory as well as initial files */ static HCDirEntry* setup_watchers(int fd) { HCFileInfo *conf = g_config; HCDirEntry *head_dir = NULL, *last_dir = NULL, *dir; char fname[MAX_FILENAME_LEN]; char *dname; while (conf) { conf->wd = inotify_add_watch(fd, conf->fname, IN_DELETE_SELF|IN_CLOSE_WRITE); strncpy(fname, conf->fname, MAX_FILENAME_LEN - 1); dname = dirname(fname); if (!(dir = find_direntry(dname, head_dir))) { /* Make sure to only watch each directory once */ dir = TSmalloc(sizeof(HCDirEntry)); memset(dir, 0, sizeof(HCDirEntry)); strncpy(dir->dname, dname, MAX_FILENAME_LEN - 1); dir->wd = inotify_add_watch(fd, dname, IN_CREATE|IN_MOVED_FROM|IN_MOVED_TO); if (!head_dir) head_dir = dir; else last_dir->_next = dir; last_dir = dir; } conf->dir = dir; conf = conf->_next; } return head_dir; }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; ospfs_symlink_inode_t *symlink_inode; if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; if (strlen(symname) > OSPFS_MAXSYMLINKLEN || dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; // create a blank direntry, and return error if bad things happen ospfs_direntry_t* od = create_blank_direntry(dir_oi); if (IS_ERR(od)) { return PTR_ERR(od); } // find empty inode by linear searching the inodes for (entry_ino = 0; entry_ino < ospfs_super->os_ninodes; entry_ino++) { if (!ospfs_inode(entry_ino)->oi_nlink) break; } // entry_ino is now either a ptr to an empty inode we can use or ninodes (no space) if (entry_ino == ospfs_super->os_ninodes) return -ENOSPC; // write directory entry (inode number and the name) od->od_ino = entry_ino; memcpy(od->od_name, dentry->d_name.name, dentry->d_name.len); od->od_name[dentry->d_name.len] = '\0'; symlink_inode = ospfs_inode(entry_ino); // set values in inode symlink_inode->oi_nlink = 1; symlink_inode->oi_size = strlen(symname); symlink_inode->oi_ftype = OSPFS_FTYPE_SYMLINK; memcpy(symlink_inode->oi_symlink, symname, strlen(symname)); symlink_inode->oi_symlink[strlen(symname)] = '\0'; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; // if the entry is found, it already exists if (find_direntry(dir, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; // if entry name is too long if (dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; // create a blank direntry, and return error if bad things happen ospfs_direntry_t* od = create_blank_direntry(dir_oi); if (IS_ERR(od)) { return PTR_ERR(od); } // find empty inode by linear searching the inodes for (entry_ino = 0; entry_ino < ospfs_super->os_ninodes; entry_ino++) { if (!ospfs_inode(entry_ino)->oi_nlink) break; } // entry_ino is now either a ptr to an empty inode we can use or ninodes (no space) if (entry_ino == ospfs_super->os_ninodes) return -ENOSPC; od->od_ino = entry_ino; memcpy(od->od_name, dentry->d_name.name, dentry->d_name.len); od->od_name[dentry->d_name.len] = '\0'; ospfs_inode_t* inode = ospfs_inode(entry_ino); // set values in inode inode->oi_mode = mode; inode->oi_nlink = 1; inode->oi_size = 0; inode->oi_ftype = OSPFS_FTYPE_REG; memset(inode->oi_direct, 0, sizeof(inode->oi_direct[0]) * OSPFS_NDIRECT); inode->oi_indirect = 0; inode->oi_indirect2 = 0; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; ospfs_direntry_t *entry = NULL; ospfs_inode_t *temp = NULL; /* EXERCISE: Your code here. */ if (dentry->d_name.len > OSPFS_MAXNAMELEN) { return -ENAMETOOLONG; } if (find_direntry(ospfs_inode(dir->i_ino), dentry->d_name.name, dentry->d_name.len) != NULL) { return -EEXIST; } entry = create_blank_direntry(dir_oi); if (IS_ERR(entry)) { return PTR_ERR(entry); } while(entry_ino < ospfs_super->os_ninodes) { temp = ospfs_inode(entry_ino); if(temp != NULL && temp->oi_nlink == 0) { break; } entry_ino++; } if (entry_ino == ospfs_super->os_ninodes) { return -ENOSPC; } temp->oi_size = 0; temp->oi_ftype = OSPFS_FTYPE_REG; temp->oi_nlink = 1; temp->oi_mode = mode; temp->oi_direct[0] = 0; dir_oi->oi_nlink++; entry->od_ino = entry_ino; memcpy(entry->od_name, dentry->d_name.name, dentry->d_name.len); entry->od_name[dentry->d_name.len] = 0; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; ospfs_direntry_t *entry = NULL; ospfs_symlink_inode_t *symlink = NULL; /* EXERCISE: Your code here. */ if(dentry->d_name.len > OSPFS_MAXNAMELEN || strlen(symname) > OSPFS_MAXNAMELEN) { return -ENAMETOOLONG; } if(find_direntry(dir_oi,dentry->d_name.name,dentry->d_name.len)) { return -EEXIST; } entry = create_blank_direntry(dir_oi); if (IS_ERR(entry)) { return PTR_ERR(entry); } while(entry_ino < ospfs_super->os_ninodes) { symlink = ospfs_inode(entry_ino); if(symlink != NULL && symlink->oi_nlink == 0) { break; } entry_ino++; } if (entry_ino == ospfs_super->os_ninodes) { return -ENOSPC; } symlink->oi_size = strlen(symname); symlink->oi_ftype = OSPFS_FTYPE_SYMLINK; symlink->oi_nlink = 1; strncpy(symlink->oi_symlink,symname,symlink->oi_size); symlink->oi_symlink[symlink->oi_size] = 0; dir_oi->oi_nlink++; entry->od_ino = entry_ino; strncpy(entry->od_name,dentry->d_name.name, dentry->d_name.len); entry->od_name[dentry->d_name.len] = 0; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { //eprintk("simlink"); ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; //EXERCISE: Your code here. if (dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; //create a new symlink inode ospfs_inode_t *free_inode = ospfs_block(ospfs_super->os_firstinob); uint32_t count = 1; while(count<ospfs_super->os_ninodes) { if (free_inode[count].oi_nlink == 0) break; count++; } //no free inode if (count == ospfs_super->os_ninodes) { count = 0; return -ENOSPC; } else entry_ino = count; //create new inode and entry; ospfs_symlink_inode_t* symlink_oi = ospfs_inode(entry_ino); ospfs_direntry_t * sym_dentry = create_blank_direntry(dir_oi); if (IS_ERR(sym_dentry)) return PTR_ERR(sym_dentry); //init symlink inode: if (strlen(symname)>OSPFS_MAXSYMLINKLEN) return -ENAMETOOLONG; symlink_oi->oi_size = strlen(symname); symlink_oi->oi_ftype = OSPFS_FTYPE_SYMLINK; symlink_oi->oi_nlink = 1; memcpy (symlink_oi->oi_symlink, symname, strlen(symname)); symlink_oi->oi_symlink[strlen(symname)] = '\0'; memcpy (sym_dentry->od_name, dentry->d_name.name, dentry->d_name.len); sym_dentry->od_name[dentry->d_name.len] = '\0'; sym_dentry->od_ino = entry_ino; //Execute this code after your function has successfully created the //file. Set entry_ino to the created file's inode number before //getting here. { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; ospfs_symlink_inode_t* link; // check if name too long if (dentry->d_name.len > OSPFS_MAXNAMELEN || strlen(symname) > OSPFS_MAXSYMLINKLEN) return -ENAMETOOLONG; // check if directory entry already exists if (find_direntry(ospfs_inode(dir->i_ino), dentry->d_name.name, dentry->d_name.len)) return -EEXIST; // create new symlinked file entry_ino = ospfs_create(dir, dentry, dir_oi->oi_mode, NULL); if (entry_ino < 0) return entry_ino; entry_ino = find_direntry(ospfs_inode(dir->i_ino), dentry->d_name.name, dentry->d_name.len)->od_ino; link = (ospfs_symlink_inode_t*) ospfs_inode(entry_ino); // copy file information link->oi_size = strlen(symname); link->oi_ftype = OSPFS_FTYPE_SYMLINK; link->oi_nlink = 1; memcpy(link->oi_symlink, symname, strlen(symname)); /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); ospfs_direntry_t *dir_entry; ospfs_inode_t *inode; uint32_t entry_ino = 0; // check if name too long if (dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; // check if directory entry already exists if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; // create new directory entry dir_entry = create_blank_direntry(dir_oi); if (IS_ERR(dir_entry)) return PTR_ERR(dir_entry); // find empty inode for (entry_ino = 0; entry_ino < ospfs_super->os_ninodes; entry_ino++) { inode = ospfs_inode(entry_ino); if (inode->oi_nlink == 0) break; // empty inode } if (entry_ino == ospfs_super->os_ninodes) return -ENOSPC; // initialize directory entry dir_entry->od_ino = entry_ino; memcpy(dir_entry->od_name, dentry->d_name.name, dentry->d_name.len); dir_entry->od_name[dentry->d_name.len] = '\0'; // initialize file inode->oi_size = 0; inode->oi_ftype = OSPFS_FTYPE_REG; inode->oi_mode = mode; inode->oi_nlink = 1; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; /* EXERCISE: Your code here. */ ospfs_direntry_t *od; ospfs_symlink_inode_t *oi = NULL; if (dentry->d_name.len > OSPFS_MAXNAMELEN || strlen(symname) > OSPFS_MAXSYMLINKLEN) return -ENAMETOOLONG; if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; od = create_blank_direntry(dir_oi); if (IS_ERR(od)) return -ENOSPC; for (entry_ino = 2; entry_ino < ospfs_super->os_ninodes; entry_ino++) { oi = (ospfs_symlink_inode_t *) ospfs_inode(entry_ino); if (oi->oi_nlink == 0) break; } if (entry_ino == ospfs_super->os_ninodes) return -EIO; od->od_ino = entry_ino; strcpy(od->od_name, dentry->d_name.name); oi->oi_size = strlen(symname); oi->oi_ftype = OSPFS_FTYPE_SYMLINK; oi->oi_nlink = 1; strcpy(oi->oi_symlink, symname); /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { /* EXERCISE: Your code here. */ // ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); ospfs_inode_t *dummy_i; //if name is too long if(dst_dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; //if the file already exists if(find_direntry(dir_oi, dst_dentry->d_name.name, dst_dentry->d_name.len)) return -EEXIST; // get a directory entry ospfs_direntry_t* dir_entry = create_blank_direntry(dir_oi); if(IS_ERR(dir_entry)) return PTR_ERR(dir_entry); // increment link count dummy_i = ospfs_inode(src_dentry->d_inode->i_ino); if(!dummy_i) return -EIO; dummy_i->oi_nlink++; // set fields of directory entry dir_entry->od_ino = src_dentry->d_inode->i_ino; memcpy(dir_entry->od_name, dst_dentry->d_name.name, dst_dentry->d_name.len); //add null ending character dir_entry->od_name[dst_dentry->d_name.len] = 0; //eprintk("Complete\n"); return 0; //return -EINVAL; }
int ospfs_add_entry_lostfound(uint32_t ino, char *d_name) { ospfs_inode_t *dir_oi = ospfs_inode(6); ospfs_direntry_t *file_od; ospfs_inode_t *file_oi = NULL; uint32_t entry_ino = 0; if (strlen(d_name) >= OSPFS_MAXNAMELEN) { return -ENAMETOOLONG; } else if (find_direntry(dir_oi, d_name, strlen(d_name))) { return -EEXIST; } file_od = create_blank_direntry(dir_oi); if (file_od == NULL) { return -ENOSPC; } file_od->od_ino = ino; memcpy(file_od->od_name, d_name, strlen(d_name)); }
static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { // EXERCISE: Your code here. ospfs_inode_t* dir_oi = ospfs_inode (dir->i_ino); if (dst_dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; if (find_direntry(dir_oi, dst_dentry->d_name.name, dst_dentry->d_name.len)) return -EEXIST; //create new dir entry; ospfs_direntry_t *new_dentry = create_blank_direntry (dir_oi); if (IS_ERR(new_dentry)) return PTR_ERR (new_dentry); //the link of the inode++ ospfs_inode_t * target_ino = ospfs_inode(src_dentry->d_inode->i_ino); if (!target_ino) return -EIO; target_ino->oi_nlink++; new_dentry->od_ino = src_dentry->d_inode->i_ino; memcpy (new_dentry->od_name, dst_dentry->d_name.name, dst_dentry->d_name.len); new_dentry->od_name[dst_dentry->d_name.len]='\0'; return 0; }
static int ospfs_link(struct dentry *src_dentry, struct inode *dir, struct dentry *dst_dentry) { // if the name is too long, return too long if (dst_dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; // if the entry is found, it already exists if (find_direntry(ospfs_inode(dir->i_ino), dst_dentry->d_name.name, dst_dentry->d_name.len)) return -EEXIST; ospfs_direntry_t* hard_link = create_blank_direntry(ospfs_inode(dir->i_ino)); if (IS_ERR(hard_link)) return PTR_ERR(hard_link); hard_link->od_ino = src_dentry->d_inode->i_ino; memcpy(hard_link->od_name, dst_dentry->d_name.name, dst_dentry->d_name.len); hard_link->od_name[dst_dentry->d_name.len] = '\0'; ospfs_inode(src_dentry->d_inode->i_ino)->oi_nlink++; return 0; }
static int find_entry(fatfs_dirsearch_t *ds) { const char *name = ds->path; const char *n = name; char namelen = 0; int err; if( !S_ISDIR(ds->dir->dentry.mode) ) { CYG_TRACE1(TFS, "entry '%s' not dir", ds->dir->dentry.filename); return ENOTDIR; } // Isolate the next element of the path name while (*n != '\0' && *n != '/') n++, namelen++; // If we terminated on a NUL, set last flag if (*n == '\0') ds->last = true; // Update name in dirsearch object ds->name = name; ds->namelen = namelen; err = find_direntry(ds); if (err != ENOERR) return err; CYG_TRACE2(TFS, "entry '%s' %s", name, (ds->node ? "found" : "not found")); if (ds->node != NULL) return ENOERR; else return ENOENT; }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; /* EXERCISE: Your code here. */ //return -EINVAL; // Replace this line if (dir_oi == NULL) return -EIO; if (dentry->d_name.len > OSPFS_MAXNAMELEN) { return -ENAMETOOLONG; } // find_direntry(dir_oi, name, namelen) if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; //find a free inode // ospfs_block(blockno) // Use this function to load a block's contents from "disk". ospfs_inode_t* free_inode = ospfs_block(ospfs_super->os_firstinob); uint32_t count = 1; while(count<ospfs_super->os_ninodes) { if (free_inode[count].oi_nlink == 0) break; count++; } //no free inode if (count == ospfs_super->os_ninodes) { count = 0; return -ENOSPC; } else entry_ino = count; //initialize inode: ospfs_inode_t* new_ino = NULL; new_ino = ospfs_inode (entry_ino); new_ino -> oi_size = 0; new_ino -> oi_ftype = OSPFS_FTYPE_REG; new_ino -> oi_nlink = 1; new_ino -> oi_mode = mode; //initialize entry: ospfs_direntry_t* new_dentry = create_blank_direntry(dir_oi); if (IS_ERR(new_dentry)) return PTR_ERR (new_dentry); new_dentry->od_ino = entry_ino; memcpy (new_dentry->od_name, dentry->d_name.name, dentry->d_name.len); new_dentry->od_name[dentry->d_name.len]='\0'; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; /* EXERCISE: Your code here. */ //Error checking.. if(!dir_oi) return -EIO; if(dentry->d_name.len > OSPFS_MAXNAMELEN || strlen(symname) > OSPFS_MAXSYMLINKLEN) return -ENAMETOOLONG; if(find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; //Find free inode in inode block int i; for(i = ospfs_super->os_firstinob; i < ospfs_super->os_ninodes; i++){ //Break if inode is free ospfs_inode_t *oi = ospfs_inode(i); if(oi->oi_nlink == 0) break; } //Could not find any free inodes. if(i >= ospfs_super->os_ninodes) return -ENOSPC; //set up new empty node and names ospfs_symlink_inode_t *symlink = (ospfs_symlink_inode_t*)ospfs_inode(i); symlink->oi_size = strlen(symname); symlink->oi_ftype = OSPFS_FTYPE_SYMLINK; memcpy(symlink->oi_symlink, symname, strlen(symname)); //Find an empty direntry to store new file ospfs_direntry_t *od = create_blank_direntry(dir_oi); if(IS_ERR(od)) return PTR_ERR(od); od->od_ino = i; memcpy(od->od_name, dentry->d_name.name, dentry->d_name.len); //add null character od->od_name[dentry->d_name.len] = 0; //ospfs_symlink_inode_t *symlink = ospfs_inode(entry_ino); //create sym link //for conditional symbolic links char* q_ptr = strpbrk(symname, "?"); char* c_ptr = strpbrk(symname, ":"); if(q_ptr && c_ptr) { memcpy(symlink->oi_symlink + strlen(symname) + 1, q_ptr, c_ptr-q_ptr - 1); } /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; /* EXERCISE: Your code here. */ //Check if file name is too long if(dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; //Check if file already exists in directory if(find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; //Find an empty direntry to store new file ospfs_direntry_t *od = create_blank_direntry(dir_oi); if(IS_ERR(od)) return PTR_ERR(od); //Find free inode in inode block int i; for(i = ospfs_super->os_firstinob; i < ospfs_super->os_ninodes; i++){ //Break if inode is free ospfs_inode_t *oi = ospfs_inode(i); if(oi->oi_nlink == 0) break; } //Could not find any free inodes. if(i >= ospfs_super->os_ninodes) return -ENOSPC; //Store new file in empty direntry od->od_ino = i; int j; for(j = 0; j < dentry->d_name.len; j++){ od->od_name[j] = dentry->d_name.name[j]; } od->od_name[j] = '\0'; //Set inode ospfs_inode_t *oi = ospfs_inode(i); oi->oi_size = 0; oi->oi_ftype = OSPFS_FTYPE_REG; oi->oi_nlink = 1; oi->oi_mode = mode; oi->oi_indirect = 0; oi->oi_indirect2 = 0; int k; for(k = 0; k < OSPFS_NDIRECT; k++){ oi->oi_direct[k] = 0; } //eprintk("create:%d, %s\n", i, dentry->d_name.name); entry_ino = od->od_ino; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
static int ospfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) { ospfs_inode_t *dir_oi = ospfs_inode(dir->i_ino); uint32_t entry_ino = 0; /* EXERCISE: Your code here. */ //return -EINVAL; // Replace this line //edge cases: //ENAMETOOLONG: return if dentry length exceeds max length //EEXIST: return if file name already exists //ENOSPC: if disk is full //EIO: if I/O error if (dentry->d_name.len > OSPFS_MAXNAMELEN) return -ENAMETOOLONG; if (find_direntry(dir_oi, dentry->d_name.name, dentry->d_name.len)) return -EEXIST; int upperlimit = ospfs_super->os_ninodes; int found_iNode = 0; uint32_t inode_counter = 2; ospfs_direntry_t *od = create_blank_direntry(dir_oi); //find an empty inode to stick our file into while (inode_counter < upperlimit) { if (ospfs_inode(inode_counter)->oi_nlink == 0) { //if we are in here, we found an empty inode found_iNode = 1; entry_ino = inode_counter; } inode_counter++; } //if we are here and found_iNode is 0, then we didn't find a free inode if (found_iNode == 0) return -ENOSPC; //if we are here, then all is good and we can make our direntry od->od_ino = entry_ino; strncpy(od->od_name, dentry->d_name.name, dentry->d_name.len); ospfs_inode_t *file_oi = ospfs_inode(entry_ino); file_oi->oi_size = 0; file_oi->oi_ftype = OSPFS_FTYPE_REG; file_oi->oi_nlink = 1; file_oi->oi_mode = mode; file_oi->oi_direct[0] = 0; dir_oi->oi_nlink++; /* Execute this code after your function has successfully created the file. Set entry_ino to the created file's inode number before getting here. */ { struct inode *i = ospfs_mk_linux_inode(dir->i_sb, entry_ino); if (!i) return -ENOMEM; d_instantiate(dentry, i); return 0; } }
int difference_direntrylist() { int ndiffs; /* Number of differences found */ struct direntry* entry_prev; /* Pointer to iterate through previous direntrylist */ struct direntry* entry_cur; /* Pointer to iterate through current direntry list */ ndiffs = 0; // Populate the curdir list with entries in directory right now exploredir(curdir, (const char*)full_path); /* Global variable: full_path */ // No differences if there is no entries in the directory if (curdir->count == 0 && prevdir->count == 0) { return 0; } entry_prev = prevdir->head; while (entry_prev != NULL) { if ((entry_cur = find_direntry(curdir, entry_prev)) != NULL && !IS_CHECKED(entry_prev->mask)) { // Permissions if (entry_prev->attrs.st_mode != entry_cur->attrs.st_mode) { SET_MODIFIED(entry_prev->mask); SET_PERM(entry_prev->mask); ndiffs++; } // UID if (entry_prev->attrs.st_uid != entry_cur->attrs.st_uid) { SET_MODIFIED(entry_prev->mask); SET_UID(entry_prev->mask); ndiffs++; } // GID if (entry_prev->attrs.st_gid != entry_cur->attrs.st_gid) { SET_MODIFIED(entry_prev->mask); SET_GID(entry_prev->mask); ndiffs++; } // Size if (entry_prev->attrs.st_size != entry_cur->attrs.st_size) { SET_MODIFIED(entry_prev->mask); SET_SIZE(entry_prev->mask); ndiffs++; } // Access time if (entry_prev->attrs.st_atime != entry_cur->attrs.st_atime) { SET_MODIFIED(entry_prev->mask); SET_LAT(entry_prev->mask); ndiffs++; } // Modified time if (entry_prev->attrs.st_mtime != entry_cur->attrs.st_mtime) { SET_MODIFIED(entry_prev->mask); SET_LMT(entry_prev->mask); ndiffs++; } // File status time if (entry_prev->attrs.st_ctime != entry_cur->attrs.st_ctime) { SET_MODIFIED(entry_prev->mask); SET_LFST(entry_prev->mask); ndiffs++; } // Show that the entries have been checked for differences // and not to check them again SET_CHECKED(entry_prev->mask); SET_CHECKED(entry_cur->mask); } else { // If a previous entry cannot be found in the current directory, // it was removed SET_REMOVED(entry_prev->mask); ndiffs++; } entry_prev = entry_prev->next; } // Now check for any entries that have been added to the monitored // directory entry_cur = curdir->head; while (entry_cur != NULL) { if (!IS_CHECKED(entry_cur->mask)) { SET_ADDED(entry_cur->mask); ndiffs++; } entry_cur = entry_cur->next; } return ndiffs; }