/* * Lock a (portion of) a file */ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; int ret = -ENOLCK; dprintk("NFS: lock(%s/%s, t=%x, fl=%x, r=%lld:%lld)\n", filp->f_path.dentry->d_parent->d_name.name, filp->f_path.dentry->d_name.name, fl->fl_type, fl->fl_flags, (long long)fl->fl_start, (long long)fl->fl_end); nfs_inc_stats(inode, NFSIOS_VFSLOCK); /* No mandatory locks over NFS */ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) goto out_err; if (NFS_PROTO(inode)->lock_check_bounds != NULL) { ret = NFS_PROTO(inode)->lock_check_bounds(fl); if (ret < 0) goto out_err; } if (IS_GETLK(cmd)) ret = do_getlk(filp, cmd, fl); else if (fl->fl_type == F_UNLCK) ret = do_unlk(filp, cmd, fl); else ret = do_setlk(filp, cmd, fl); out_err: return ret; }
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) { struct inode *inode = filp->f_mapping->host; int status = 0; unsigned int saved_type = fl->fl_type; /* Try local locking first */ posix_test_lock(filp, fl); if (fl->fl_type != F_UNLCK) { /* found a conflict */ goto out; } fl->fl_type = saved_type; if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ)) goto out_noconflict; if (is_local) goto out_noconflict; status = NFS_PROTO(inode)->lock(filp, cmd, fl); out: return status; out_noconflict: fl->fl_type = F_UNLCK; goto out; }
/* * Remove a file after making sure there are no pending writes, * and after checking that the file has only one user. * * We invalidate the attribute cache and free the inode prior to the operation * to avoid possible races if the server reuses the inode. */ static int nfs_safe_remove(struct dentry *dentry) { struct inode *dir = dentry->d_parent->d_inode; struct inode *inode = dentry->d_inode; int error = -EBUSY; dfprintk(VFS, "NFS: safe_remove(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); /* If the dentry was sillyrenamed, we simply call d_delete() */ if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { error = 0; goto out; } nfs_begin_data_update(dir); if (inode != NULL) { nfs_begin_data_update(inode); error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); /* The VFS may want to delete this inode */ if (error == 0) inode->i_nlink--; nfs_end_data_update(inode); } else error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); nfs_end_data_update(dir); out: return error; }
/* * Lock a (portion of) a file */ int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; int ret = -ENOLCK; int is_local = 0; dprintk("NFS: lock(%pD2, t=%x, fl=%x, r=%lld:%lld)\n", filp, fl->fl_type, fl->fl_flags, (long long)fl->fl_start, (long long)fl->fl_end); nfs_inc_stats(inode, NFSIOS_VFSLOCK); /* No mandatory locks over NFS */ if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) goto out_err; if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FCNTL) is_local = 1; if (NFS_PROTO(inode)->lock_check_bounds != NULL) { ret = NFS_PROTO(inode)->lock_check_bounds(fl); if (ret < 0) goto out_err; } if (IS_GETLK(cmd)) ret = do_getlk(filp, cmd, fl, is_local); else if (fl->fl_type == F_UNLCK) ret = do_unlk(filp, cmd, fl, is_local); else ret = do_setlk(filp, cmd, fl, is_local); out_err: return ret; }
int nfs_permission(struct inode *inode, int mask) { int error = vfs_permission(inode, mask); if (!NFS_PROTO(inode)->access) goto out; if (error == -EROFS) goto out; /* * Trust UNIX mode bits except: * * 1) When override capabilities may have been invoked * 2) When root squashing may be involved * 3) When ACLs may overturn a negative answer */ if (!capable(CAP_DAC_OVERRIDE) && !capable(CAP_DAC_READ_SEARCH) && (current->fsuid != 0) && (current->fsgid != 0) && error != -EACCES) goto out; error = NFS_PROTO(inode)->access(inode, mask, 0); if (error == -EACCES && NFS_CLIENT(inode)->cl_droppriv && current->uid != 0 && current->gid != 0 && (current->fsuid != current->uid || current->fsgid != current->gid)) error = NFS_PROTO(inode)->access(inode, mask, 1); out: return error; }
static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct iattr attr; struct nfs_fattr sym_attr; struct nfs_fh sym_fh; struct qstr qsymname; int error; dfprintk(VFS, "NFS: symlink(%s/%ld, %s, %s)\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name, symname); error = -ENAMETOOLONG; switch (NFS_PROTO(dir)->version) { case 2: if (strlen(symname) > NFS2_MAXPATHLEN) goto out; break; case 3: if (strlen(symname) > NFS3_MAXPATHLEN) goto out; default: break; } #ifdef NFS_PARANOIA if (dentry->d_inode) printk("nfs_proc_symlink: %s/%s not negative!\n", dentry->d_parent->d_name.name, dentry->d_name.name); #endif /* * Fill in the sattr for the call. * Note: SunOS 4.1.2 crashes if the mode isn't initialized! */ attr.ia_valid = ATTR_MODE; attr.ia_mode = S_IFLNK | S_IRWXUGO; qsymname.name = symname; qsymname.len = strlen(symname); lock_kernel(); nfs_begin_data_update(dir); error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, &attr, &sym_fh, &sym_attr); nfs_end_data_update(dir); if (!error) { error = nfs_instantiate(dentry, &sym_fh, &sym_attr); } else { if (error == -EEXIST) printk("nfs_proc_symlink: %s/%s already exists??\n", dentry->d_parent->d_name.name, dentry->d_name.name); d_drop(dentry); } unlock_kernel(); out: return error; }
static inline int nfs_direct_write_rpc(struct file *file, struct nfs_writeargs *arg, struct nfs_writeverf *verf) { int result; struct inode *inode = file->f_dentry->d_inode; struct nfs_fattr fattr; struct rpc_message msg; struct nfs_writeres res = { &fattr, verf, 0 }; #ifdef CONFIG_NFS_V3 msg.rpc_proc = (NFS_PROTO(inode)->version == 3) ? NFS3PROC_WRITE : NFSPROC_WRITE; #else msg.rpc_proc = NFSPROC_WRITE; #endif msg.rpc_argp = arg; msg.rpc_resp = &res; lock_kernel(); msg.rpc_cred = get_rpccred(nfs_file_cred(file)); fattr.valid = 0; result = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); nfs_write_attributes(inode, &fattr); put_rpccred(msg.rpc_cred); unlock_kernel(); #ifdef CONFIG_NFS_V3 if (NFS_PROTO(inode)->version == 3) { if (result > 0) { if ((arg->stable == NFS_FILE_SYNC) && (verf->committed != NFS_FILE_SYNC)) { printk(KERN_ERR "%s: server didn't sync stable write request\n", __FUNCTION__); return -EIO; } if (result != arg->count) { printk(KERN_INFO "%s: short write, count=%u, result=%d\n", __FUNCTION__, arg->count, result); } } return result; } else { #endif verf->committed = NFS_FILE_SYNC; /* NFSv2 always syncs data */ if (result == 0) return arg->count; return result; #ifdef CONFIG_NFS_V3 } #endif }
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) { struct inode *inode = NULL; int error; struct nfs_fh fhandle; struct nfs_fattr fattr; dfprintk(VFS, "NFS: lookup(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -ENAMETOOLONG; if (dentry->d_name.len > NFS_SERVER(dir)->namelen) goto out; error = -ENOMEM; dentry->d_op = NFS_PROTO(dir)->dentry_ops; lock_kernel(); /* Revalidate parent directory attribute cache */ nfs_revalidate_inode(NFS_SERVER(dir), dir); /* If we're doing an exclusive create, optimize away the lookup */ if (nfs_is_exclusive_create(dir, nd)) goto no_entry; error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr); if (error != 0) { error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); if (error == -ENOENT) goto no_entry; if (error != 0) goto out_unlock; } error = -EACCES; inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr); if (!inode) goto out_unlock; no_entry: error = 0; d_add(dentry, inode); nfs_renew_times(dentry); nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); out_unlock: unlock_kernel(); out: BUG_ON(error > 0); return ERR_PTR(error); }
static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, struct qstr *name, struct nfs_fh *fh, struct nfs_fattr *fattr) { int err; if (NFS_PROTO(dir)->version == 4) return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr); err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr); if (err) return ERR_PTR(err); return rpc_clone_client(NFS_SERVER(dir)->client); }
static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct iattr attr; struct nfs_fattr sym_attr; struct nfs_fh sym_fh; struct qstr qsymname; unsigned int maxlen; int error; dfprintk(VFS, "NFS: symlink(%x/%ld, %s, %s)\n", dir->i_dev, dir->i_ino, dentry->d_name.name, symname); error = -ENAMETOOLONG; maxlen = (NFS_PROTO(dir)->version==2) ? NFS2_MAXPATHLEN : NFS3_MAXPATHLEN; if (strlen(symname) > maxlen) goto out; #ifdef NFS_PARANOIA if (dentry->d_inode) printk("nfs_proc_symlink: %s/%s not negative!\n", dentry->d_parent->d_name.name, dentry->d_name.name); #endif /* * Fill in the sattr for the call. * Note: SunOS 4.1.2 crashes if the mode isn't initialized! */ attr.ia_valid = ATTR_MODE; attr.ia_mode = S_IFLNK | S_IRWXUGO; qsymname.name = symname; qsymname.len = strlen(symname); nfs_zap_caches(dir); error = NFS_PROTO(dir)->symlink(dir, &dentry->d_name, &qsymname, &attr, &sym_fh, &sym_attr); if (!error) { error = nfs_instantiate(dentry, &sym_fh, &sym_attr); } else { if (error == -EEXIST) printk("nfs_proc_symlink: %s/%s already exists??\n", dentry->d_parent->d_name.name, dentry->d_name.name); d_drop(dentry); } out: return error; }
static inline int nfs_direct_read_rpc(struct file *file, struct nfs_readargs *arg) { int result; struct inode * inode = file->f_dentry->d_inode; struct nfs_fattr fattr; struct rpc_message msg; struct nfs_readres res = { &fattr, arg->count, 0 }; #ifdef CONFIG_NFS_V3 msg.rpc_proc = (NFS_PROTO(inode)->version == 3) ? NFS3PROC_READ : NFSPROC_READ; #else msg.rpc_proc = NFSPROC_READ; #endif msg.rpc_argp = arg; msg.rpc_resp = &res; lock_kernel(); msg.rpc_cred = nfs_file_cred(file); fattr.valid = 0; result = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); nfs_refresh_inode(inode, &fattr); unlock_kernel(); return result; }
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) { struct file_lock *cfl; struct inode *inode = filp->f_mapping->host; int status = 0; lock_kernel(); /* Try local locking first */ cfl = posix_test_lock(filp, fl); if (cfl != NULL) { locks_copy_lock(fl, cfl); goto out; } if (nfs_have_delegation(inode, FMODE_READ)) goto out_noconflict; if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) goto out_noconflict; status = NFS_PROTO(inode)->lock(filp, cmd, fl); out: unlock_kernel(); return status; out_noconflict: fl->fl_type = F_UNLCK; goto out; }
/* * See comments for nfs_proc_create regarding failed operations. */ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) { struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: mknod(%s/%ld, %s\n", dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); if (!new_valid_dev(rdev)) return -EINVAL; attr.ia_mode = mode; attr.ia_valid = ATTR_MODE; lock_kernel(); nfs_begin_data_update(dir); error = NFS_PROTO(dir)->mknod(dir, &dentry->d_name, &attr, rdev, &fhandle, &fattr); nfs_end_data_update(dir); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); else d_drop(dentry); unlock_kernel(); return error; }
/* * Code common to create, mkdir, and mknod. */ static int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct inode *inode; int error = -EACCES; /* We may have been initialized further down */ if (dentry->d_inode) return 0; if (fhandle->size == 0 || !(fattr->valid & NFS_ATTR_FATTR)) { struct inode *dir = dentry->d_parent->d_inode; error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr); if (error) goto out_err; } inode = nfs_fhget(dentry->d_sb, fhandle, fattr); if (inode) { d_instantiate(dentry, inode); nfs_renew_times(dentry); nfs_set_verifier(dentry, nfs_save_change_attribute(dentry->d_parent->d_inode)); return 0; } error = -ENOMEM; out_err: d_drop(dentry); return error; }
/* * Following a failed create operation, we drop the dentry rather * than retain a negative dentry. This avoids a problem in the event * that the operation succeeded on the server, but an error in the * reply path made it appear to have failed. */ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode) { struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: create(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); attr.ia_mode = mode; attr.ia_valid = ATTR_MODE; /* * The 0 argument passed into the create function should one day * contain the O_EXCL flag if requested. This allows NFSv3 to * select the appropriate create strategy. Currently open_namei * does not pass the create flags. */ nfs_zap_caches(dir); error = NFS_PROTO(dir)->create(dir, &dentry->d_name, &attr, 0, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); else d_drop(dentry); return error; }
/* * See comments for nfs_proc_create regarding failed operations. */ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) { struct iattr attr; struct nfs_fattr fattr; struct nfs_fh fhandle; int error; dfprintk(VFS, "NFS: mkdir(%x/%ld, %s\n", dir->i_dev, dir->i_ino, dentry->d_name.name); attr.ia_valid = ATTR_MODE; attr.ia_mode = mode | S_IFDIR; #if 0 /* * Always drop the dentry, we can't always depend on * the fattr returned by the server (AIX seems to be * broken). We're better off doing another lookup than * depending on potentially bogus information. */ d_drop(dentry); #endif nfs_zap_caches(dir); error = NFS_PROTO(dir)->mkdir(dir, &dentry->d_name, &attr, &fhandle, &fattr); if (!error) error = nfs_instantiate(dentry, &fhandle, &fattr); else d_drop(dentry); return error; }
/* * This is called every time the dcache has a lookup hit, * and we should check whether we can really trust that * lookup. * * NOTE! The hit can be a negative hit too, don't assume * we have an inode! * * If the parent directory is seen to have changed, we throw out the * cached dentry and do a new lookup. */ static int nfs_lookup_revalidate(struct dentry * dentry, int flags) { struct inode *dir; struct inode *inode; int error; struct nfs_fh fhandle; struct nfs_fattr fattr; lock_kernel(); dir = dentry->d_parent->d_inode; inode = dentry->d_inode; if (!inode) { if (nfs_neg_need_reval(dir, dentry)) goto out_bad; goto out_valid; } if (is_bad_inode(inode)) { dfprintk(VFS, "nfs_lookup_validate: %s/%s has dud inode\n", dentry->d_parent->d_name.name, dentry->d_name.name); goto out_bad; } /* Force a full look up iff the parent directory has changed */ if (nfs_check_verifier(dir, dentry)) { if (nfs_lookup_verify_inode(inode, flags)) goto out_bad; goto out_valid; } if (NFS_STALE(inode)) goto out_bad; error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); if (error) goto out_bad; if (memcmp(NFS_FH(inode), &fhandle, sizeof(struct nfs_fh))!= 0) goto out_bad; if ((error = nfs_refresh_inode(inode, &fattr)) != 0) goto out_bad; nfs_renew_times(dentry); out_valid: unlock_kernel(); return 1; out_bad: NFS_CACHEINV(dir); if (inode && S_ISDIR(inode->i_mode)) { /* Purge readdir caches. */ nfs_zap_caches(inode); /* If we have submounts, don't unhash ! */ if (have_submounts(dentry)) goto out_valid; shrink_dcache_parent(dentry); } d_drop(dentry); unlock_kernel(); return 0; }
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry) { struct inode *inode; int error; struct nfs_fh fhandle; struct nfs_fattr fattr; dfprintk(VFS, "NFS: lookup(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -ENAMETOOLONG; if (dentry->d_name.len > NFS_SERVER(dir)->namelen) goto out; error = -ENOMEM; dentry->d_op = &nfs_dentry_operations; error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr); inode = NULL; if (error == -ENOENT) goto no_entry; if (!error) { error = -EACCES; inode = nfs_fhget(dentry, &fhandle, &fattr); if (inode) { no_entry: d_add(dentry, inode); error = 0; } nfs_renew_times(dentry); } out: return ERR_PTR(error); }
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; int status = 0; /* Try local locking first */ posix_test_lock(filp, fl); if (fl->fl_type != F_UNLCK) { /* found a conflict */ goto out; } if (nfs_have_delegation(inode, FMODE_READ)) goto out_noconflict; if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) goto out_noconflict; status = NFS_PROTO(inode)->lock(filp, cmd, fl); out: return status; out_noconflict: fl->fl_type = F_UNLCK; goto out; }
static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; int status; /* * Flush all pending writes before doing anything * with locks.. */ status = nfs_sync_mapping(filp->f_mapping); if (status != 0) goto out; /* Use local locking if mounted with "-onolock" */ if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) status = NFS_PROTO(inode)->lock(filp, cmd, fl); else status = do_vfs_lock(filp, fl); if (status < 0) goto out; /* * Make sure we clear the cache whenever we try to get the lock. * This makes locking act as a cache coherency point. */ nfs_sync_mapping(filp->f_mapping); if (!nfs_have_delegation(inode, FMODE_READ)) nfs_zap_caches(inode); out: return status; }
static int do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) { struct inode *inode = filp->f_mapping->host; struct nfs_lock_context *l_ctx; int status; /* * Flush all pending writes before doing anything * with locks.. */ vfs_fsync(filp, 0); l_ctx = nfs_get_lock_context(nfs_file_open_context(filp)); if (!IS_ERR(l_ctx)) { status = nfs_iocounter_wait(&l_ctx->io_count); nfs_put_lock_context(l_ctx); if (status < 0) return status; } /* NOTE: special case * If we're signalled while cleaning up locks on process exit, we * still need to complete the unlock. */ /* * Use local locking if mounted with "-onolock" or with appropriate * "-olocal_lock=" */ if (!is_local) status = NFS_PROTO(inode)->lock(filp, cmd, fl); else status = do_vfs_lock(filp, fl); return status; }
static int do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) { struct inode *inode = filp->f_mapping->host; int status; /* * Flush all pending writes before doing anything * with locks.. */ nfs_sync_mapping(filp->f_mapping); /* NOTE: special case * If we're signalled while cleaning up locks on process exit, we * still need to complete the unlock. */ /* * Use local locking if mounted with "-onolock" or with appropriate * "-olocal_lock=" */ if (!is_local) status = NFS_PROTO(inode)->lock(filp, cmd, fl); else status = do_vfs_lock(filp, fl); return status; }
static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) { struct file_lock cfl; struct inode *inode = filp->f_mapping->host; int status = 0; lock_kernel(); /* Try local locking first */ if (posix_test_lock(filp, fl, &cfl)) { fl->fl_start = cfl.fl_start; fl->fl_end = cfl.fl_end; fl->fl_type = cfl.fl_type; fl->fl_pid = cfl.fl_pid; goto out; } if (nfs_have_delegation(inode, FMODE_READ)) goto out_noconflict; if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) goto out_noconflict; status = NFS_PROTO(inode)->lock(filp, cmd, fl); out: unlock_kernel(); return status; out_noconflict: fl->fl_type = F_UNLCK; goto out; }
static int nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) { struct inode *inode = old_dentry->d_inode; int error; dfprintk(VFS, "NFS: link(%s/%s -> %s/%s)\n", old_dentry->d_parent->d_name.name, old_dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name); /* * Drop the dentry in advance to force a new lookup. * Since nfs_proc_link doesn't return a file handle, * we can't use the existing dentry. */ lock_kernel(); d_drop(dentry); nfs_begin_data_update(dir); nfs_begin_data_update(inode); error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name); nfs_end_data_update(inode); nfs_end_data_update(dir); unlock_kernel(); return error; }
static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) { struct inode *inode = filp->f_mapping->host; sigset_t oldset; int status; rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); /* * Flush all pending writes before doing anything * with locks.. */ nfs_sync_mapping(filp->f_mapping); /* NOTE: special case * If we're signalled while cleaning up locks on process exit, we * still need to complete the unlock. */ lock_kernel(); /* Use local locking if mounted with "-onolock" */ if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) status = NFS_PROTO(inode)->lock(filp, cmd, fl); else status = do_vfs_lock(filp, fl); unlock_kernel(); rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); return status; }
static int nfs_negotiate_security(const struct dentry *parent, const struct dentry *dentry, rpc_authflavor_t *flavor) { struct page *page; struct nfs4_secinfo_flavors *flavors; int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); int ret = -EPERM; secinfo = NFS_PROTO(parent->d_inode)->secinfo; if (secinfo != NULL) { page = alloc_page(GFP_KERNEL); if (!page) { ret = -ENOMEM; goto out; } flavors = page_address(page); ret = secinfo(parent->d_inode, &dentry->d_name, flavors); *flavor = nfs_find_best_sec(flavors); put_page(page); } out: return ret; }
/** * nfs_pgio_prepare - Prepare pageio hdr to go over the wire * @task: The current task * @calldata: pageio header to prepare */ static void nfs_pgio_prepare(struct rpc_task *task, void *calldata) { struct nfs_pgio_header *hdr = calldata; int err; err = NFS_PROTO(hdr->inode)->pgio_rpc_prepare(task, hdr); if (err) rpc_exit(task, err); }
/** * nfs_async_unlink_done - Sillydelete post-processing * @task: rpc_task of the sillydelete * * Do the directory attribute update. */ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) { struct nfs_unlinkdata *data = calldata; struct inode *dir = data->dir; if (!NFS_PROTO(dir)->unlink_done(task, dir)) nfs_restart_rpc(task, NFS_SERVER(dir)->nfs_client); }
/** * nfs_async_unlink_done - Sillydelete post-processing * @task: rpc_task of the sillydelete * * Do the directory attribute update. */ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata) { struct nfs_unlinkdata *data = calldata; struct inode *dir = data->dir; if (!NFS_PROTO(dir)->unlink_done(task, dir)) rpc_restart_call_prepare(task); }
static int nfs_file_release(struct inode *inode, struct file *filp) { /* Ensure that dirty pages are flushed out with the right creds */ if (filp->f_mode & FMODE_WRITE) filemap_fdatawrite(filp->f_mapping); return NFS_PROTO(inode)->file_release(inode, filp); }