📄 dir.c
字号:
memcpy(name,__name,len);
name[len] = '\0';
if (len == 1 && name[0] == '.') { /* cheat for "." */
*result = dir;
return 0;
}
if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
|| !nfs_lookup_cache_lookup(dir, name, &fhandle, &fattr)) {
if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
name, &fhandle, &fattr))) {
iput(dir);
return error;
}
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
}
if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
iput(dir);
return -EACCES;
}
iput(dir);
return 0;
}
static int nfs_create(struct inode *dir, const char *name, int len, int mode,
struct inode **result)
{
struct nfs_sattr sattr;
struct nfs_fattr fattr;
struct nfs_fh fhandle;
int error;
*result = NULL;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_create: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
sattr.mode = mode;
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
name, &sattr, &fhandle, &fattr))) {
iput(dir);
return error;
}
if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
iput(dir);
return -EACCES;
}
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
iput(dir);
return 0;
}
static int nfs_mknod(struct inode *dir, const char *name, int len,
int mode, int rdev)
{
struct nfs_sattr sattr;
struct nfs_fattr fattr;
struct nfs_fh fhandle;
int error;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_mknod: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
sattr.mode = mode;
sattr.uid = sattr.gid = (unsigned) -1;
if (S_ISCHR(mode) || S_ISBLK(mode))
sattr.size = rdev; /* get out your barf bag */
else
sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
name, &sattr, &fhandle, &fattr);
if (!error)
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
iput(dir);
return error;
}
static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
{
struct nfs_sattr sattr;
struct nfs_fattr fattr;
struct nfs_fh fhandle;
int error;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_mkdir: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
sattr.mode = mode;
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
name, &sattr, &fhandle, &fattr);
if (!error)
nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
iput(dir);
return error;
}
static int nfs_rmdir(struct inode *dir, const char *name, int len)
{
int error;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_rmdir: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), name);
if (!error)
nfs_lookup_cache_remove(dir, NULL, name);
iput(dir);
return error;
}
static int nfs_unlink(struct inode *dir, const char *name, int len)
{
int error;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_unlink: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), name);
if (!error)
nfs_lookup_cache_remove(dir, NULL, name);
iput(dir);
return error;
}
static int nfs_symlink(struct inode *dir, const char *name, int len,
const char *symname)
{
struct nfs_sattr sattr;
int error;
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_symlink: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(dir);
return -ENAMETOOLONG;
}
if (strlen(symname) > NFS_MAXPATHLEN) {
iput(dir);
return -ENAMETOOLONG;
}
sattr.mode = S_IFLNK | S_IRWXUGO; /* SunOS 4.1.2 crashes without this! */
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
name, symname, &sattr);
iput(dir);
return error;
}
static int nfs_link(struct inode *oldinode, struct inode *dir,
const char *name, int len)
{
int error;
if (!oldinode) {
printk("nfs_link: old inode is NULL\n");
iput(oldinode);
iput(dir);
return -ENOENT;
}
if (!dir || !S_ISDIR(dir->i_mode)) {
printk("nfs_link: dir is NULL or not a directory\n");
iput(oldinode);
iput(dir);
return -ENOENT;
}
if (len > NFS_MAXNAMLEN) {
iput(oldinode);
iput(dir);
return -ENAMETOOLONG;
}
error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
NFS_FH(dir), name);
if (!error)
nfs_lookup_cache_remove(dir, oldinode, NULL);
iput(oldinode);
iput(dir);
return error;
}
static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
struct inode *new_dir, const char *new_name, int new_len)
{
int error;
if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
printk("nfs_rename: old inode is NULL or not a directory\n");
iput(old_dir);
iput(new_dir);
return -ENOENT;
}
if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
printk("nfs_rename: new inode is NULL or not a directory\n");
iput(old_dir);
iput(new_dir);
return -ENOENT;
}
if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
iput(old_dir);
iput(new_dir);
return -ENAMETOOLONG;
}
error = nfs_proc_rename(NFS_SERVER(old_dir),
NFS_FH(old_dir), old_name,
NFS_FH(new_dir), new_name);
if (!error) {
nfs_lookup_cache_remove(old_dir, NULL, old_name);
nfs_lookup_cache_remove(new_dir, NULL, new_name);
}
iput(old_dir);
iput(new_dir);
return error;
}
/*
* Many nfs protocol calls return the new file attributes after
* an operation. Here we update the inode to reflect the state
* of the server's inode.
*/
void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
{
int was_empty;
if (!inode || !fattr) {
printk("nfs_refresh_inode: inode or fattr is NULL\n");
return;
}
if (inode->i_ino != fattr->fileid) {
printk("nfs_refresh_inode: inode number mismatch\n");
return;
}
was_empty = inode->i_mode == 0;
inode->i_mode = fattr->mode;
inode->i_nlink = fattr->nlink;
inode->i_uid = fattr->uid;
inode->i_gid = fattr->gid;
inode->i_size = fattr->size;
inode->i_blksize = fattr->blocksize;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
inode->i_rdev = fattr->rdev;
else
inode->i_rdev = 0;
inode->i_blocks = fattr->blocks;
inode->i_atime = fattr->atime.seconds;
inode->i_mtime = fattr->mtime.seconds;
inode->i_ctime = fattr->ctime.seconds;
if (was_empty) {
if (S_ISREG(inode->i_mode))
inode->i_op = &nfs_file_inode_operations;
else if (S_ISDIR(inode->i_mode))
inode->i_op = &nfs_dir_inode_operations;
else if (S_ISLNK(inode->i_mode))
inode->i_op = &nfs_symlink_inode_operations;
else if (S_ISCHR(inode->i_mode))
inode->i_op = &chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &blkdev_inode_operations;
else if (S_ISFIFO(inode->i_mode))
init_fifo(inode);
else
inode->i_op = NULL;
}
nfs_lookup_cache_refresh(inode, fattr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -