/***** Unlink a file */ static int msdos_unlink(struct inode *dir, struct dentry *dentry) { struct inode *inode = d_inode(dentry); struct super_block *sb = inode->i_sb; struct fat_slot_info sinfo; int err; mutex_lock(&MSDOS_SB(sb)->s_lock); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) goto out; err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; clear_nlink(inode); inode->i_ctime = current_time(inode); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); if (!err) err = fat_flush_inodes(sb, dir, inode); return err; }
static int msdos_unlink(struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; struct super_block *sb= inode->i_sb; struct fat_slot_info sinfo; int err; lock_super(sb); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) goto out; err = fat_remove_entries(dir, &sinfo); /* */ if (err) goto out; clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: unlock_super(sb); if (!err) err = fat_flush_inodes(sb, dir, inode); return err; }
/***** Get inode using directory and name */ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry) { struct super_block *sb = dir->i_sb; struct inode *inode = NULL; struct msdos_dir_entry *de; struct buffer_head *bh = NULL; int res; loff_t ino; PRINTK (("msdos_lookup\n")); dentry->d_op = &msdos_dentry_operations; res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &ino); if (res == -ENOENT) goto add; if (res < 0) goto out; inode = fat_build_inode(sb, de, ino, &res); if (res) goto out; add: d_add(dentry, inode); res = 0; out: if (bh) fat_brelse(sb, bh); return ERR_PTR(res); }
/***** Unlink a file */ int msdos_unlink( struct inode *dir, struct dentry *dentry) { struct super_block *sb = dir->i_sb; struct inode *inode = dentry->d_inode; int res; loff_t ino; struct buffer_head *bh; struct msdos_dir_entry *de; bh = NULL; res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &ino); if (res < 0) goto unlink_done; de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh); fat_detach(inode); fat_brelse(sb, bh); inode->i_nlink = 0; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); mark_inode_dirty(dir); res = 0; unlink_done: return res; }
/***** Get inode using directory and name */ struct dentry *msdos_lookup(struct inode *dir,struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct inode *inode = NULL; struct msdos_dir_entry *de; struct buffer_head *bh = NULL; loff_t i_pos; int res; dentry->d_op = &msdos_dentry_operations; lock_kernel(); res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &i_pos); if (res == -ENOENT) goto add; if (res < 0) goto out; inode = fat_build_inode(sb, de, i_pos, &res); if (res) goto out; add: res = 0; dentry = d_splice_alias(inode, dentry); if (dentry) dentry->d_op = &msdos_dentry_operations; out: brelse(bh); unlock_kernel(); if (!res) return dentry; return ERR_PTR(res); }
/***** Unlink a file */ int msdos_unlink( struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; loff_t i_pos; int res; struct buffer_head *bh; struct msdos_dir_entry *de; bh = NULL; lock_kernel(); res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &i_pos); if (res < 0) goto unlink_done; de->name[0] = DELETED_FLAG; mark_buffer_dirty(bh); fat_detach(inode); brelse(bh); inode->i_nlink = 0; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(inode); mark_inode_dirty(dir); res = 0; unlink_done: unlock_kernel(); return res; }
/***** Remove a directory */ int msdos_rmdir(struct inode *dir, struct dentry *dentry) { struct super_block *sb = dir->i_sb; struct inode *inode = dentry->d_inode; int res,ino; struct buffer_head *bh; struct msdos_dir_entry *de; bh = NULL; res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &ino); if (res < 0) goto rmdir_done; /* * Check whether the directory is not in use, then check * whether it is empty. */ res = fat_dir_empty(inode); if (res) goto rmdir_done; de->name[0] = DELETED_FLAG; fat_mark_buffer_dirty(sb, bh); fat_detach(inode); inode->i_nlink = 0; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; dir->i_nlink--; mark_inode_dirty(inode); mark_inode_dirty(dir); res = 0; rmdir_done: fat_brelse(sb, bh); return res; }
/***** Remove a directory */ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; struct fat_slot_info sinfo; int err; lock_kernel(); /* * Check whether the directory is not in use, then check * whether it is empty. */ err = fat_dir_empty(inode); if (err) goto out; err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) goto out; err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; drop_nlink(dir); clear_nlink(inode); inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: unlock_kernel(); if (!err) err = fat_flush_inodes(inode->i_sb, dir, inode); return err; }
int msdos_unlink(struct inode *dir,const char *name,int len) { int res,ino; struct buffer_head *bh; struct msdos_dir_entry *de; struct inode *inode; bh = NULL; inode = NULL; if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto unlink_done; if (!(inode = iget(dir->i_dev,ino))) { res = -ENOENT; goto unlink_done; } if (!S_ISREG(inode->i_mode)) { res = -EPERM; goto unlink_done; } inode->i_nlink = 0; MSDOS_I(inode)->i_busy = 1; inode->i_dirt = 1; de->name[0] = DELETED_FLAG; bh->b_dirt = 1; unlink_done: brelse(bh); iput(inode); iput(dir); return res; }
/***** Remove a directory */ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) { struct super_block *sb = dir->i_sb; struct inode *inode = d_inode(dentry); struct fat_slot_info sinfo; int err; mutex_lock(&MSDOS_SB(sb)->s_lock); /* * Check whether the directory is not in use, then check * whether it is empty. */ err = fat_dir_empty(inode); if (err) goto out; err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) goto out; err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; drop_nlink(dir); clear_nlink(inode); inode->i_ctime = current_time(inode); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); if (!err) err = fat_flush_inodes(sb, dir, inode); return err; }
/***** Get inode using directory and name */ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; struct inode *inode = NULL; int res; dentry->d_op = &msdos_dentry_operations; lock_kernel(); res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (res == -ENOENT) goto add; if (res < 0) goto out; inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); if (IS_ERR(inode)) { res = PTR_ERR(inode); goto out; } add: res = 0; dentry = d_splice_alias(inode, dentry); if (dentry) dentry->d_op = &msdos_dentry_operations; out: unlock_kernel(); if (!res) return dentry; return ERR_PTR(res); }
/***** Get inode using directory and name */ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; struct inode *inode; int err; lock_super(sb); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) { if (err == -ENOENT) { inode = NULL; goto out; } goto error; } inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto error; } out: unlock_super(sb); return d_splice_alias(inode, dentry); error: unlock_super(sb); return ERR_PTR(err); }
int msdos_lookup(struct inode *dir,const char *name,int len, struct inode **result) { int ino,res; struct msdos_dir_entry *de; struct buffer_head *bh; struct inode *next; *result = NULL; if (!dir) return -ENOENT; if (!S_ISDIR(dir->i_mode)) { iput(dir); return -ENOENT; } if (len == 1 && get_fs_byte(name) == '.') { *result = dir; return 0; } if (len == 2 && get_fs_byte(name) == '.' && get_fs_byte(name+1) == '.') { ino = msdos_parent_ino(dir,0); iput(dir); if (ino < 0) return ino; if (!(*result = iget(dir->i_dev,ino))) return -EACCES; return 0; } if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) { iput(dir); return res; } if (bh) brelse(bh); /* printk("lookup: ino=%d\r\n",ino); */ if (!(*result = iget(dir->i_dev,ino))) { iput(dir); return -EACCES; } if (MSDOS_I(*result)->i_busy) { /* mkdir in progress */ iput(*result); iput(dir); return -ENOENT; } while (MSDOS_I(*result)->i_old) { next = MSDOS_I(*result)->i_old; iput(*result); if (!(*result = iget(next->i_dev,next->i_ino))) panic("msdos_lookup: Can't happen"); } iput(dir); return 0; }
int msdos_rmdir(struct inode *dir,const char *name,int len) { int res,ino,pos; struct buffer_head *bh,*dbh; struct msdos_dir_entry *de,*dde; struct inode *inode; bh = NULL; inode = NULL; res = -EINVAL; if (get_fs_byte(name) == '.' && (len == 1 || (len == 2 && get_fs_byte(name+1) == '.'))) goto rmdir_done; if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto rmdir_done; res = -ENOENT; if (!(inode = iget(dir->i_dev,ino))) goto rmdir_done; res = -ENOTDIR; if (!S_ISDIR(inode->i_mode)) goto rmdir_done; res = -EBUSY; if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done; if (inode->i_count > 1) goto rmdir_done; if (MSDOS_I(inode)->i_start) { /* may be zero in mkdir */ res = -ENOTEMPTY; pos = 0; dbh = NULL; while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1) if (dde->name[0] && ((unsigned char *) dde->name)[0] != DELETED_FLAG && strncmp(dde->name,MSDOS_DOT, MSDOS_NAME) && strncmp(dde->name,MSDOS_DOTDOT, MSDOS_NAME)) goto rmdir_done; if (dbh) brelse(dbh); } inode->i_nlink = 0; dir->i_mtime = CURRENT_TIME; dir->i_nlink--; inode->i_dirt = dir->i_dirt = 1; de->name[0] = DELETED_FLAG; bh->b_dirt = 1; res = 0; rmdir_done: brelse(bh); iput(dir); iput(inode); return res; }
/***** Get inode using directory and name */ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; struct inode *inode; int err; char szBuffer[20]; int len = min((int)dentry->d_name.len, 19); memset(szBuffer, 0, 20); __memcpy(szBuffer, dentry->d_name.name, len); printk (KERN_INFO "myfat: msdos_lookup, dir is %s\n", szBuffer); lock_super(sb); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) { if (err == -ENOENT) { inode = NULL; goto out; } goto error; } inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); // by rzq: hold the reference count brelse(sinfo.bh); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto error; } out: unlock_super(sb); dentry->d_op = &msdos_dentry_operations; dentry = d_splice_alias(inode, dentry); if (dentry) dentry->d_op = &msdos_dentry_operations; return dentry; error: unlock_super(sb); return ERR_PTR(err); }
/***** Unlink a file */ static int msdos_unlink(struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; struct fat_slot_info sinfo; int err; lock_kernel(); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); if (err) goto out; err = fat_remove_entries(dir, &sinfo); /* and releases bh */ if (err) goto out; inode->i_nlink = 0; inode->i_ctime = CURRENT_TIME_SEC; fat_detach(inode); out: unlock_kernel(); return err; }
/***** Remove a directory */ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) { struct inode *inode = dentry->d_inode; loff_t i_pos; int res; struct buffer_head *bh; struct msdos_dir_entry *de; bh = NULL; lock_kernel(); res = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de, &i_pos); if (res < 0) goto rmdir_done; /* * Check whether the directory is not in use, then check * whether it is empty. */ res = fat_dir_empty(inode); if (res) goto rmdir_done; de->name[0] = DELETED_FLAG; mark_buffer_dirty(bh); fat_detach(inode); inode->i_nlink = 0; inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; dir->i_nlink--; mark_inode_dirty(inode); mark_inode_dirty(dir); res = 0; rmdir_done: brelse(bh); unlock_kernel(); return res; }
/***** Get inode using directory and name */ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; struct inode *inode; int err; mutex_lock(&MSDOS_SB(sb)->s_lock); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); switch (err) { case -ENOENT: inode = NULL; break; case 0: inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); break; default: inode = ERR_PTR(err); } mutex_unlock(&MSDOS_SB(sb)->s_lock); return d_splice_alias(inode, dentry); }
static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; struct inode *inode; int err; lock_super(sb); err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo); switch (err) { case -ENOENT: inode = NULL; break; case 0: inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos); brelse(sinfo.bh); break; default: inode = ERR_PTR(err); } unlock_super(sb); return d_splice_alias(inode, dentry); }