Loading fs/nfs/nfs4proc.c +97 −107 Original line number Diff line number Diff line Loading @@ -2079,47 +2079,81 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n return err; } struct nfs4_createdata { struct rpc_message msg; struct nfs4_create_arg arg; struct nfs4_create_res res; struct nfs_fh fh; struct nfs_fattr fattr; struct nfs_fattr dir_fattr; }; static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, struct qstr *name, struct iattr *sattr, u32 ftype) { struct nfs4_createdata *data; data = kzalloc(sizeof(*data), GFP_KERNEL); if (data != NULL) { struct nfs_server *server = NFS_SERVER(dir); data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; data->msg.rpc_argp = &data->arg; data->msg.rpc_resp = &data->res; data->arg.dir_fh = NFS_FH(dir); data->arg.server = server; data->arg.name = name; data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = server->attr_bitmask; data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; data->res.dir_fattr = &data->dir_fattr; nfs_fattr_init(data->res.fattr); nfs_fattr_init(data->res.dir_fattr); } return data; } static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) { int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); if (status == 0) { update_changeattr(dir, &data->res.dir_cinfo); nfs_post_op_update_inode(dir, data->res.dir_fattr); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); } return status; } static void nfs4_free_createdata(struct nfs4_createdata *data) { kfree(data); } static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, unsigned int len, struct iattr *sattr) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fhandle; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .ftype = NF4LNK, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fhandle, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int status = -ENAMETOOLONG; if (len > NFS4_MAXPATHLEN) return -ENAMETOOLONG; goto out; arg.u.symlink.pages = &page; arg.u.symlink.len = len; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); status = -ENOMEM; data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4LNK); if (data == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (!status) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fhandle, &fattr); } data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK]; data->arg.u.symlink.pages = &page; data->arg.u.symlink.len = len; status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading @@ -2140,39 +2174,17 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fhandle; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .ftype = NF4DIR, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fhandle, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int status = -ENOMEM; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR); if (data == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (!status) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fhandle, &fattr); } status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading Loading @@ -2242,56 +2254,34 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fh; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fh, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int mode = sattr->ia_mode; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); int status = -ENOMEM; BUG_ON(!(sattr->ia_valid & ATTR_MODE)); BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode)); data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK); if (data == NULL) goto out; if (S_ISFIFO(mode)) arg.ftype = NF4FIFO; data->arg.ftype = NF4FIFO; else if (S_ISBLK(mode)) { arg.ftype = NF4BLK; arg.u.device.specdata1 = MAJOR(rdev); arg.u.device.specdata2 = MINOR(rdev); data->arg.ftype = NF4BLK; data->arg.u.device.specdata1 = MAJOR(rdev); data->arg.u.device.specdata2 = MINOR(rdev); } else if (S_ISCHR(mode)) { arg.ftype = NF4CHR; arg.u.device.specdata1 = MAJOR(rdev); arg.u.device.specdata2 = MINOR(rdev); data->arg.ftype = NF4CHR; data->arg.u.device.specdata1 = MAJOR(rdev); data->arg.u.device.specdata2 = MINOR(rdev); } else arg.ftype = NF4SOCK; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (status == 0) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fh, &fattr); } status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading Loading
fs/nfs/nfs4proc.c +97 −107 Original line number Diff line number Diff line Loading @@ -2079,47 +2079,81 @@ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *n return err; } struct nfs4_createdata { struct rpc_message msg; struct nfs4_create_arg arg; struct nfs4_create_res res; struct nfs_fh fh; struct nfs_fattr fattr; struct nfs_fattr dir_fattr; }; static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, struct qstr *name, struct iattr *sattr, u32 ftype) { struct nfs4_createdata *data; data = kzalloc(sizeof(*data), GFP_KERNEL); if (data != NULL) { struct nfs_server *server = NFS_SERVER(dir); data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE]; data->msg.rpc_argp = &data->arg; data->msg.rpc_resp = &data->res; data->arg.dir_fh = NFS_FH(dir); data->arg.server = server; data->arg.name = name; data->arg.attrs = sattr; data->arg.ftype = ftype; data->arg.bitmask = server->attr_bitmask; data->res.server = server; data->res.fh = &data->fh; data->res.fattr = &data->fattr; data->res.dir_fattr = &data->dir_fattr; nfs_fattr_init(data->res.fattr); nfs_fattr_init(data->res.dir_fattr); } return data; } static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_createdata *data) { int status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); if (status == 0) { update_changeattr(dir, &data->res.dir_cinfo); nfs_post_op_update_inode(dir, data->res.dir_fattr); status = nfs_instantiate(dentry, data->res.fh, data->res.fattr); } return status; } static void nfs4_free_createdata(struct nfs4_createdata *data) { kfree(data); } static int _nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, unsigned int len, struct iattr *sattr) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fhandle; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .ftype = NF4LNK, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fhandle, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int status = -ENAMETOOLONG; if (len > NFS4_MAXPATHLEN) return -ENAMETOOLONG; goto out; arg.u.symlink.pages = &page; arg.u.symlink.len = len; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); status = -ENOMEM; data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4LNK); if (data == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (!status) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fhandle, &fattr); } data->msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SYMLINK]; data->arg.u.symlink.pages = &page; data->arg.u.symlink.len = len; status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading @@ -2140,39 +2174,17 @@ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, static int _nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fhandle; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .ftype = NF4DIR, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fhandle, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int status = -ENOMEM; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4DIR); if (data == NULL) goto out; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (!status) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fhandle, &fattr); } status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading Loading @@ -2242,56 +2254,34 @@ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, static int _nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, dev_t rdev) { struct nfs_server *server = NFS_SERVER(dir); struct nfs_fh fh; struct nfs_fattr fattr, dir_fattr; struct nfs4_create_arg arg = { .dir_fh = NFS_FH(dir), .server = server, .name = &dentry->d_name, .attrs = sattr, .bitmask = server->attr_bitmask, }; struct nfs4_create_res res = { .server = server, .fh = &fh, .fattr = &fattr, .dir_fattr = &dir_fattr, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CREATE], .rpc_argp = &arg, .rpc_resp = &res, }; int status; struct nfs4_createdata *data; int mode = sattr->ia_mode; nfs_fattr_init(&fattr); nfs_fattr_init(&dir_fattr); int status = -ENOMEM; BUG_ON(!(sattr->ia_valid & ATTR_MODE)); BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode)); data = nfs4_alloc_createdata(dir, &dentry->d_name, sattr, NF4SOCK); if (data == NULL) goto out; if (S_ISFIFO(mode)) arg.ftype = NF4FIFO; data->arg.ftype = NF4FIFO; else if (S_ISBLK(mode)) { arg.ftype = NF4BLK; arg.u.device.specdata1 = MAJOR(rdev); arg.u.device.specdata2 = MINOR(rdev); data->arg.ftype = NF4BLK; data->arg.u.device.specdata1 = MAJOR(rdev); data->arg.u.device.specdata2 = MINOR(rdev); } else if (S_ISCHR(mode)) { arg.ftype = NF4CHR; arg.u.device.specdata1 = MAJOR(rdev); arg.u.device.specdata2 = MINOR(rdev); data->arg.ftype = NF4CHR; data->arg.u.device.specdata1 = MAJOR(rdev); data->arg.u.device.specdata2 = MINOR(rdev); } else arg.ftype = NF4SOCK; status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); if (status == 0) { update_changeattr(dir, &res.dir_cinfo); nfs_post_op_update_inode(dir, res.dir_fattr); status = nfs_instantiate(dentry, &fh, &fattr); } status = nfs4_do_create(dir, dentry, data); nfs4_free_createdata(data); out: return status; } Loading