📄 dir.c
字号:
*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); /* The parent dir inode count may have changed ! */ nfs_lookup_cache_remove( NULL, dir, NULL); } 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) { if (fattr.fileid == dir->i_ino) printk("Sony NewsOS 4.1R buggy nfs server?\n"); else nfs_lookup_cache_add(dir, name, &fhandle, &fattr); } iput(dir); /* The parent dir link count may have changed */ nfs_lookup_cache_remove( NULL, dir, NULL); 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); nfs_lookup_cache_remove(dir, NULL, name); iput(dir); return error;}static int nfs_sillyrename(struct inode *dir, const char *name, int len){ struct inode *inode; char silly[16]; int slen, ret; dir->i_count++; if (nfs_lookup(dir, name, len, &inode) < 0) return -EIO; /* arbitrary */ if (inode->i_count == 1 || NFS_RENAMED_DIR(inode)) { iput(inode); return -EIO; } slen = sprintf(silly, ".nfs%ld", inode->i_ino); if (len == slen && !strncmp(name, silly, len)) { iput(inode); return -EIO; /* DWIM */ } ret = nfs_proc_rename(NFS_SERVER(dir), NFS_FH(dir), name, NFS_FH(dir), silly, 0); if (ret >= 0) { nfs_lookup_cache_remove(dir, NULL, name); nfs_lookup_cache_remove(dir, NULL, silly); NFS_RENAMED_DIR(inode) = dir; dir->i_count++; } iput(inode); return ret;}void nfs_sillyrename_cleanup(struct inode *inode){ struct inode *dir = NFS_RENAMED_DIR(inode); char silly[14]; int error, slen; slen = sprintf(silly, ".nfs%ld", inode->i_ino); if ((error = nfs_unlink(dir, silly, slen)) < 0) { printk("NFS silly_rename cleanup failed (err = %d)\n", -error); } NFS_RENAMED_DIR(inode) = NULL;}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; } if ((error = nfs_sillyrename(dir, name, len)) < 0) { error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), name); 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); nfs_lookup_cache_remove(dir, oldinode, NULL); NFS_CACHEINV(oldinode); 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 must_be_dir){ 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, must_be_dir); 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); /* * Some (broken?) NFS servers return 0 as the file type. * We'll assume that 0 means the file type has not changed. */ if(!(fattr->mode & S_IFMT)){ inode->i_mode = (inode->i_mode & S_IFMT) | (fattr->mode & ~S_IFMT); }else{ inode->i_mode = fattr->mode; } inode->i_nlink = fattr->nlink; inode->i_uid = fattr->uid; inode->i_gid = fattr->gid; /* Size changed from outside: invalidate caches on next read */ if (inode->i_size != fattr->size) NFS_CACHEINV(inode); if (NFS_OLDMTIME(inode) != fattr->mtime.seconds) NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); inode->i_size = fattr->size; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_rdev = to_kdev_t(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 (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)) { if (was_empty) init_fifo(inode); } else inode->i_op = NULL; nfs_lookup_cache_refresh(inode, fattr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -