📄 proc.c
字号:
static intnfs_proc_unlink_done(struct dentry *dir, struct rpc_task *task){ struct rpc_message *msg = &task->tk_msg; if (msg->rpc_argp) kfree(msg->rpc_argp); return 0;}static intnfs_proc_rename(struct inode *old_dir, struct qstr *old_name, struct inode *new_dir, struct qstr *new_name){ struct nfs_renameargs arg = { .fromfh = NFS_FH(old_dir), .fromname = old_name->name, .fromlen = old_name->len, .tofh = NFS_FH(new_dir), .toname = new_name->name, .tolen = new_name->len }; int status; dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); status = rpc_call(NFS_CLIENT(old_dir), NFSPROC_RENAME, &arg, NULL, 0); dprintk("NFS reply rename: %d\n", status); return status;}static intnfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name){ struct nfs_linkargs arg = { .fromfh = NFS_FH(inode), .tofh = NFS_FH(dir), .toname = name->name, .tolen = name->len }; int status; dprintk("NFS call link %s\n", name->name); status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); dprintk("NFS reply link: %d\n", status); return status;}static intnfs_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path, struct iattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr){ struct nfs_symlinkargs arg = { .fromfh = NFS_FH(dir), .fromname = name->name, .fromlen = name->len, .topath = path->name, .tolen = path->len, .sattr = sattr }; int status; if (path->len > NFS2_MAXPATHLEN) return -ENAMETOOLONG; dprintk("NFS call symlink %s -> %s\n", name->name, path->name); fattr->valid = 0; fhandle->size = 0; status = rpc_call(NFS_CLIENT(dir), NFSPROC_SYMLINK, &arg, NULL, 0); dprintk("NFS reply symlink: %d\n", status); return status;}static intnfs_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr, struct nfs_fh *fhandle, struct nfs_fattr *fattr){ struct nfs_createargs arg = { .fh = NFS_FH(dir), .name = name->name, .len = name->len, .sattr = sattr }; struct nfs_diropok res = { .fh = fhandle, .fattr = fattr }; int status; dprintk("NFS call mkdir %s\n", name->name); fattr->valid = 0; status = rpc_call(NFS_CLIENT(dir), NFSPROC_MKDIR, &arg, &res, 0); dprintk("NFS reply mkdir: %d\n", status); return status;}static intnfs_proc_rmdir(struct inode *dir, struct qstr *name){ struct nfs_diropargs arg = { .fh = NFS_FH(dir), .name = name->name, .len = name->len }; int status; dprintk("NFS call rmdir %s\n", name->name); status = rpc_call(NFS_CLIENT(dir), NFSPROC_RMDIR, &arg, NULL, 0); dprintk("NFS reply rmdir: %d\n", status); return status;}/* * The READDIR implementation is somewhat hackish - we pass a temporary * buffer to the encode function, which installs it in the receive * the receive iovec. The decode function just parses the reply to make * sure it is syntactically correct; the entries itself are decoded * from nfs_readdir by calling the decode_entry function directly. */static intnfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, u64 cookie, struct page *page, unsigned int count, int plus){ struct inode *dir = dentry->d_inode; struct nfs_readdirargs arg = { .fh = NFS_FH(dir), .cookie = cookie, .count = count, .pages = &page }; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_READDIR], .rpc_argp = &arg, .rpc_resp = NULL, .rpc_cred = cred }; int status; lock_kernel(); dprintk("NFS call readdir %d\n", (unsigned int)cookie); status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); dprintk("NFS reply readdir: %d\n", status); unlock_kernel(); return status;}static intnfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *stat){ struct nfs2_fsstat fsinfo; int status; dprintk("NFS call statfs\n"); stat->fattr->valid = 0; status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0); dprintk("NFS reply statfs: %d\n", status); if (status) goto out; stat->tbytes = (u64)fsinfo.blocks * fsinfo.bsize; stat->fbytes = (u64)fsinfo.bfree * fsinfo.bsize; stat->abytes = (u64)fsinfo.bavail * fsinfo.bsize; stat->tfiles = 0; stat->ffiles = 0; stat->afiles = 0;out: return status;}static intnfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *info){ struct nfs2_fsstat fsinfo; int status; dprintk("NFS call fsinfo\n"); info->fattr->valid = 0; status = rpc_call(server->client, NFSPROC_STATFS, fhandle, &fsinfo, 0); dprintk("NFS reply fsinfo: %d\n", status); if (status) goto out; info->rtmax = NFS_MAXDATA; info->rtpref = fsinfo.tsize; info->rtmult = fsinfo.bsize; info->wtmax = NFS_MAXDATA; info->wtpref = fsinfo.tsize; info->wtmult = fsinfo.bsize; info->dtpref = fsinfo.tsize; info->maxfilesize = 0x7FFFFFFF; info->lease_time = 0;out: return status;}static intnfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_pathconf *info){ info->max_link = 0; info->max_namelen = NFS2_MAXNAMLEN; return 0;}extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);static voidnfs_read_done(struct rpc_task *task){ struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata; if (task->tk_status >= 0) { nfs_refresh_inode(data->inode, data->res.fattr); /* Emulate the eof flag, which isn't normally needed in NFSv2 * as it is guaranteed to always return the file attributes */ if (data->args.offset + data->args.count >= data->res.fattr->size) data->res.eof = 1; } nfs_readpage_result(task);}static voidnfs_proc_read_setup(struct nfs_read_data *data){ struct rpc_task *task = &data->task; struct inode *inode = data->inode; int flags; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_READ], .rpc_argp = &data->args, .rpc_resp = &data->res, .rpc_cred = data->cred, }; /* N.B. Do we need to test? Never called for swapfile inode */ flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags); rpc_call_setup(task, &msg, 0);}static voidnfs_write_done(struct rpc_task *task){ struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata; if (task->tk_status >= 0) nfs_refresh_inode(data->inode, data->res.fattr); nfs_writeback_done(task);}static voidnfs_proc_write_setup(struct nfs_write_data *data, int how){ struct rpc_task *task = &data->task; struct inode *inode = data->inode; int flags; struct rpc_message msg = { .rpc_proc = &nfs_procedures[NFSPROC_WRITE], .rpc_argp = &data->args, .rpc_resp = &data->res, .rpc_cred = data->cred, }; /* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ data->args.stable = NFS_FILE_SYNC; /* Set the initial flags for the task. */ flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC; /* Finalize the task. */ rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags); rpc_call_setup(task, &msg, 0);}static voidnfs_proc_commit_setup(struct nfs_write_data *data, int how){ BUG();}static intnfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl){ return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl);}struct nfs_rpc_ops nfs_v2_clientops = { .version = 2, /* protocol version */ .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs_dir_inode_operations, .getroot = nfs_proc_get_root, .getattr = nfs_proc_getattr, .setattr = nfs_proc_setattr, .lookup = nfs_proc_lookup, .access = NULL, /* access */ .readlink = nfs_proc_readlink, .read = nfs_proc_read, .write = nfs_proc_write, .commit = NULL, /* commit */ .create = nfs_proc_create, .remove = nfs_proc_remove, .unlink_setup = nfs_proc_unlink_setup, .unlink_done = nfs_proc_unlink_done, .rename = nfs_proc_rename, .link = nfs_proc_link, .symlink = nfs_proc_symlink, .mkdir = nfs_proc_mkdir, .rmdir = nfs_proc_rmdir, .readdir = nfs_proc_readdir, .mknod = nfs_proc_mknod, .statfs = nfs_proc_statfs, .fsinfo = nfs_proc_fsinfo, .pathconf = nfs_proc_pathconf, .decode_dirent = nfs_decode_dirent, .read_setup = nfs_proc_read_setup, .write_setup = nfs_proc_write_setup, .commit_setup = nfs_proc_commit_setup, .file_open = nfs_open, .file_release = nfs_release, .lock = nfs_proc_lock,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -