1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * linux/fs/nfs/file.c 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * Copyright (C) 1992 Rick Sladkey 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Changes Copyright (C) 1994 by Florian La Roche 7*1da177e4SLinus Torvalds * - Do not copy data too often around in the kernel. 8*1da177e4SLinus Torvalds * - In nfs_file_read the return value of kmalloc wasn't checked. 9*1da177e4SLinus Torvalds * - Put in a better version of read look-ahead buffering. Original idea 10*1da177e4SLinus Torvalds * and implementation by Wai S Kok elekokws@ee.nus.sg. 11*1da177e4SLinus Torvalds * 12*1da177e4SLinus Torvalds * Expire cache on write to a file by Wai S Kok (Oct 1994). 13*1da177e4SLinus Torvalds * 14*1da177e4SLinus Torvalds * Total rewrite of read side for new NFS buffer cache.. Linus. 15*1da177e4SLinus Torvalds * 16*1da177e4SLinus Torvalds * nfs regular file handling functions 17*1da177e4SLinus Torvalds */ 18*1da177e4SLinus Torvalds 19*1da177e4SLinus Torvalds #include <linux/time.h> 20*1da177e4SLinus Torvalds #include <linux/kernel.h> 21*1da177e4SLinus Torvalds #include <linux/errno.h> 22*1da177e4SLinus Torvalds #include <linux/fcntl.h> 23*1da177e4SLinus Torvalds #include <linux/stat.h> 24*1da177e4SLinus Torvalds #include <linux/nfs_fs.h> 25*1da177e4SLinus Torvalds #include <linux/nfs_mount.h> 26*1da177e4SLinus Torvalds #include <linux/mm.h> 27*1da177e4SLinus Torvalds #include <linux/slab.h> 28*1da177e4SLinus Torvalds #include <linux/pagemap.h> 29*1da177e4SLinus Torvalds #include <linux/smp_lock.h> 30*1da177e4SLinus Torvalds 31*1da177e4SLinus Torvalds #include <asm/uaccess.h> 32*1da177e4SLinus Torvalds #include <asm/system.h> 33*1da177e4SLinus Torvalds 34*1da177e4SLinus Torvalds #include "delegation.h" 35*1da177e4SLinus Torvalds 36*1da177e4SLinus Torvalds #define NFSDBG_FACILITY NFSDBG_FILE 37*1da177e4SLinus Torvalds 38*1da177e4SLinus Torvalds static int nfs_file_open(struct inode *, struct file *); 39*1da177e4SLinus Torvalds static int nfs_file_release(struct inode *, struct file *); 40*1da177e4SLinus Torvalds static int nfs_file_mmap(struct file *, struct vm_area_struct *); 41*1da177e4SLinus Torvalds static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 42*1da177e4SLinus Torvalds static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); 43*1da177e4SLinus Torvalds static ssize_t nfs_file_write(struct kiocb *, const char __user *, size_t, loff_t); 44*1da177e4SLinus Torvalds static int nfs_file_flush(struct file *); 45*1da177e4SLinus Torvalds static int nfs_fsync(struct file *, struct dentry *dentry, int datasync); 46*1da177e4SLinus Torvalds static int nfs_check_flags(int flags); 47*1da177e4SLinus Torvalds static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); 48*1da177e4SLinus Torvalds static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 49*1da177e4SLinus Torvalds 50*1da177e4SLinus Torvalds struct file_operations nfs_file_operations = { 51*1da177e4SLinus Torvalds .llseek = remote_llseek, 52*1da177e4SLinus Torvalds .read = do_sync_read, 53*1da177e4SLinus Torvalds .write = do_sync_write, 54*1da177e4SLinus Torvalds .aio_read = nfs_file_read, 55*1da177e4SLinus Torvalds .aio_write = nfs_file_write, 56*1da177e4SLinus Torvalds .mmap = nfs_file_mmap, 57*1da177e4SLinus Torvalds .open = nfs_file_open, 58*1da177e4SLinus Torvalds .flush = nfs_file_flush, 59*1da177e4SLinus Torvalds .release = nfs_file_release, 60*1da177e4SLinus Torvalds .fsync = nfs_fsync, 61*1da177e4SLinus Torvalds .lock = nfs_lock, 62*1da177e4SLinus Torvalds .flock = nfs_flock, 63*1da177e4SLinus Torvalds .sendfile = nfs_file_sendfile, 64*1da177e4SLinus Torvalds .check_flags = nfs_check_flags, 65*1da177e4SLinus Torvalds }; 66*1da177e4SLinus Torvalds 67*1da177e4SLinus Torvalds struct inode_operations nfs_file_inode_operations = { 68*1da177e4SLinus Torvalds .permission = nfs_permission, 69*1da177e4SLinus Torvalds .getattr = nfs_getattr, 70*1da177e4SLinus Torvalds .setattr = nfs_setattr, 71*1da177e4SLinus Torvalds }; 72*1da177e4SLinus Torvalds 73*1da177e4SLinus Torvalds /* Hack for future NFS swap support */ 74*1da177e4SLinus Torvalds #ifndef IS_SWAPFILE 75*1da177e4SLinus Torvalds # define IS_SWAPFILE(inode) (0) 76*1da177e4SLinus Torvalds #endif 77*1da177e4SLinus Torvalds 78*1da177e4SLinus Torvalds static int nfs_check_flags(int flags) 79*1da177e4SLinus Torvalds { 80*1da177e4SLinus Torvalds if ((flags & (O_APPEND | O_DIRECT)) == (O_APPEND | O_DIRECT)) 81*1da177e4SLinus Torvalds return -EINVAL; 82*1da177e4SLinus Torvalds 83*1da177e4SLinus Torvalds return 0; 84*1da177e4SLinus Torvalds } 85*1da177e4SLinus Torvalds 86*1da177e4SLinus Torvalds /* 87*1da177e4SLinus Torvalds * Open file 88*1da177e4SLinus Torvalds */ 89*1da177e4SLinus Torvalds static int 90*1da177e4SLinus Torvalds nfs_file_open(struct inode *inode, struct file *filp) 91*1da177e4SLinus Torvalds { 92*1da177e4SLinus Torvalds struct nfs_server *server = NFS_SERVER(inode); 93*1da177e4SLinus Torvalds int (*open)(struct inode *, struct file *); 94*1da177e4SLinus Torvalds int res; 95*1da177e4SLinus Torvalds 96*1da177e4SLinus Torvalds res = nfs_check_flags(filp->f_flags); 97*1da177e4SLinus Torvalds if (res) 98*1da177e4SLinus Torvalds return res; 99*1da177e4SLinus Torvalds 100*1da177e4SLinus Torvalds lock_kernel(); 101*1da177e4SLinus Torvalds /* Do NFSv4 open() call */ 102*1da177e4SLinus Torvalds if ((open = server->rpc_ops->file_open) != NULL) 103*1da177e4SLinus Torvalds res = open(inode, filp); 104*1da177e4SLinus Torvalds unlock_kernel(); 105*1da177e4SLinus Torvalds return res; 106*1da177e4SLinus Torvalds } 107*1da177e4SLinus Torvalds 108*1da177e4SLinus Torvalds static int 109*1da177e4SLinus Torvalds nfs_file_release(struct inode *inode, struct file *filp) 110*1da177e4SLinus Torvalds { 111*1da177e4SLinus Torvalds /* Ensure that dirty pages are flushed out with the right creds */ 112*1da177e4SLinus Torvalds if (filp->f_mode & FMODE_WRITE) 113*1da177e4SLinus Torvalds filemap_fdatawrite(filp->f_mapping); 114*1da177e4SLinus Torvalds return NFS_PROTO(inode)->file_release(inode, filp); 115*1da177e4SLinus Torvalds } 116*1da177e4SLinus Torvalds 117*1da177e4SLinus Torvalds /* 118*1da177e4SLinus Torvalds * Flush all dirty pages, and check for write errors. 119*1da177e4SLinus Torvalds * 120*1da177e4SLinus Torvalds */ 121*1da177e4SLinus Torvalds static int 122*1da177e4SLinus Torvalds nfs_file_flush(struct file *file) 123*1da177e4SLinus Torvalds { 124*1da177e4SLinus Torvalds struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; 125*1da177e4SLinus Torvalds struct inode *inode = file->f_dentry->d_inode; 126*1da177e4SLinus Torvalds int status; 127*1da177e4SLinus Torvalds 128*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: flush(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); 129*1da177e4SLinus Torvalds 130*1da177e4SLinus Torvalds if ((file->f_mode & FMODE_WRITE) == 0) 131*1da177e4SLinus Torvalds return 0; 132*1da177e4SLinus Torvalds lock_kernel(); 133*1da177e4SLinus Torvalds /* Ensure that data+attribute caches are up to date after close() */ 134*1da177e4SLinus Torvalds status = nfs_wb_all(inode); 135*1da177e4SLinus Torvalds if (!status) { 136*1da177e4SLinus Torvalds status = ctx->error; 137*1da177e4SLinus Torvalds ctx->error = 0; 138*1da177e4SLinus Torvalds if (!status && !nfs_have_delegation(inode, FMODE_READ)) 139*1da177e4SLinus Torvalds __nfs_revalidate_inode(NFS_SERVER(inode), inode); 140*1da177e4SLinus Torvalds } 141*1da177e4SLinus Torvalds unlock_kernel(); 142*1da177e4SLinus Torvalds return status; 143*1da177e4SLinus Torvalds } 144*1da177e4SLinus Torvalds 145*1da177e4SLinus Torvalds static ssize_t 146*1da177e4SLinus Torvalds nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) 147*1da177e4SLinus Torvalds { 148*1da177e4SLinus Torvalds struct dentry * dentry = iocb->ki_filp->f_dentry; 149*1da177e4SLinus Torvalds struct inode * inode = dentry->d_inode; 150*1da177e4SLinus Torvalds ssize_t result; 151*1da177e4SLinus Torvalds 152*1da177e4SLinus Torvalds #ifdef CONFIG_NFS_DIRECTIO 153*1da177e4SLinus Torvalds if (iocb->ki_filp->f_flags & O_DIRECT) 154*1da177e4SLinus Torvalds return nfs_file_direct_read(iocb, buf, count, pos); 155*1da177e4SLinus Torvalds #endif 156*1da177e4SLinus Torvalds 157*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: read(%s/%s, %lu@%lu)\n", 158*1da177e4SLinus Torvalds dentry->d_parent->d_name.name, dentry->d_name.name, 159*1da177e4SLinus Torvalds (unsigned long) count, (unsigned long) pos); 160*1da177e4SLinus Torvalds 161*1da177e4SLinus Torvalds result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 162*1da177e4SLinus Torvalds if (!result) 163*1da177e4SLinus Torvalds result = generic_file_aio_read(iocb, buf, count, pos); 164*1da177e4SLinus Torvalds return result; 165*1da177e4SLinus Torvalds } 166*1da177e4SLinus Torvalds 167*1da177e4SLinus Torvalds static ssize_t 168*1da177e4SLinus Torvalds nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, 169*1da177e4SLinus Torvalds read_actor_t actor, void *target) 170*1da177e4SLinus Torvalds { 171*1da177e4SLinus Torvalds struct dentry *dentry = filp->f_dentry; 172*1da177e4SLinus Torvalds struct inode *inode = dentry->d_inode; 173*1da177e4SLinus Torvalds ssize_t res; 174*1da177e4SLinus Torvalds 175*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: sendfile(%s/%s, %lu@%Lu)\n", 176*1da177e4SLinus Torvalds dentry->d_parent->d_name.name, dentry->d_name.name, 177*1da177e4SLinus Torvalds (unsigned long) count, (unsigned long long) *ppos); 178*1da177e4SLinus Torvalds 179*1da177e4SLinus Torvalds res = nfs_revalidate_inode(NFS_SERVER(inode), inode); 180*1da177e4SLinus Torvalds if (!res) 181*1da177e4SLinus Torvalds res = generic_file_sendfile(filp, ppos, count, actor, target); 182*1da177e4SLinus Torvalds return res; 183*1da177e4SLinus Torvalds } 184*1da177e4SLinus Torvalds 185*1da177e4SLinus Torvalds static int 186*1da177e4SLinus Torvalds nfs_file_mmap(struct file * file, struct vm_area_struct * vma) 187*1da177e4SLinus Torvalds { 188*1da177e4SLinus Torvalds struct dentry *dentry = file->f_dentry; 189*1da177e4SLinus Torvalds struct inode *inode = dentry->d_inode; 190*1da177e4SLinus Torvalds int status; 191*1da177e4SLinus Torvalds 192*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: mmap(%s/%s)\n", 193*1da177e4SLinus Torvalds dentry->d_parent->d_name.name, dentry->d_name.name); 194*1da177e4SLinus Torvalds 195*1da177e4SLinus Torvalds status = nfs_revalidate_inode(NFS_SERVER(inode), inode); 196*1da177e4SLinus Torvalds if (!status) 197*1da177e4SLinus Torvalds status = generic_file_mmap(file, vma); 198*1da177e4SLinus Torvalds return status; 199*1da177e4SLinus Torvalds } 200*1da177e4SLinus Torvalds 201*1da177e4SLinus Torvalds /* 202*1da177e4SLinus Torvalds * Flush any dirty pages for this process, and check for write errors. 203*1da177e4SLinus Torvalds * The return status from this call provides a reliable indication of 204*1da177e4SLinus Torvalds * whether any write errors occurred for this process. 205*1da177e4SLinus Torvalds */ 206*1da177e4SLinus Torvalds static int 207*1da177e4SLinus Torvalds nfs_fsync(struct file *file, struct dentry *dentry, int datasync) 208*1da177e4SLinus Torvalds { 209*1da177e4SLinus Torvalds struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; 210*1da177e4SLinus Torvalds struct inode *inode = dentry->d_inode; 211*1da177e4SLinus Torvalds int status; 212*1da177e4SLinus Torvalds 213*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: fsync(%s/%ld)\n", inode->i_sb->s_id, inode->i_ino); 214*1da177e4SLinus Torvalds 215*1da177e4SLinus Torvalds lock_kernel(); 216*1da177e4SLinus Torvalds status = nfs_wb_all(inode); 217*1da177e4SLinus Torvalds if (!status) { 218*1da177e4SLinus Torvalds status = ctx->error; 219*1da177e4SLinus Torvalds ctx->error = 0; 220*1da177e4SLinus Torvalds } 221*1da177e4SLinus Torvalds unlock_kernel(); 222*1da177e4SLinus Torvalds return status; 223*1da177e4SLinus Torvalds } 224*1da177e4SLinus Torvalds 225*1da177e4SLinus Torvalds /* 226*1da177e4SLinus Torvalds * This does the "real" work of the write. The generic routine has 227*1da177e4SLinus Torvalds * allocated the page, locked it, done all the page alignment stuff 228*1da177e4SLinus Torvalds * calculations etc. Now we should just copy the data from user 229*1da177e4SLinus Torvalds * space and write it back to the real medium.. 230*1da177e4SLinus Torvalds * 231*1da177e4SLinus Torvalds * If the writer ends up delaying the write, the writer needs to 232*1da177e4SLinus Torvalds * increment the page use counts until he is done with the page. 233*1da177e4SLinus Torvalds */ 234*1da177e4SLinus Torvalds static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 235*1da177e4SLinus Torvalds { 236*1da177e4SLinus Torvalds return nfs_flush_incompatible(file, page); 237*1da177e4SLinus Torvalds } 238*1da177e4SLinus Torvalds 239*1da177e4SLinus Torvalds static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) 240*1da177e4SLinus Torvalds { 241*1da177e4SLinus Torvalds long status; 242*1da177e4SLinus Torvalds 243*1da177e4SLinus Torvalds lock_kernel(); 244*1da177e4SLinus Torvalds status = nfs_updatepage(file, page, offset, to-offset); 245*1da177e4SLinus Torvalds unlock_kernel(); 246*1da177e4SLinus Torvalds return status; 247*1da177e4SLinus Torvalds } 248*1da177e4SLinus Torvalds 249*1da177e4SLinus Torvalds struct address_space_operations nfs_file_aops = { 250*1da177e4SLinus Torvalds .readpage = nfs_readpage, 251*1da177e4SLinus Torvalds .readpages = nfs_readpages, 252*1da177e4SLinus Torvalds .set_page_dirty = __set_page_dirty_nobuffers, 253*1da177e4SLinus Torvalds .writepage = nfs_writepage, 254*1da177e4SLinus Torvalds .writepages = nfs_writepages, 255*1da177e4SLinus Torvalds .prepare_write = nfs_prepare_write, 256*1da177e4SLinus Torvalds .commit_write = nfs_commit_write, 257*1da177e4SLinus Torvalds #ifdef CONFIG_NFS_DIRECTIO 258*1da177e4SLinus Torvalds .direct_IO = nfs_direct_IO, 259*1da177e4SLinus Torvalds #endif 260*1da177e4SLinus Torvalds }; 261*1da177e4SLinus Torvalds 262*1da177e4SLinus Torvalds /* 263*1da177e4SLinus Torvalds * Write to a file (through the page cache). 264*1da177e4SLinus Torvalds */ 265*1da177e4SLinus Torvalds static ssize_t 266*1da177e4SLinus Torvalds nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) 267*1da177e4SLinus Torvalds { 268*1da177e4SLinus Torvalds struct dentry * dentry = iocb->ki_filp->f_dentry; 269*1da177e4SLinus Torvalds struct inode * inode = dentry->d_inode; 270*1da177e4SLinus Torvalds ssize_t result; 271*1da177e4SLinus Torvalds 272*1da177e4SLinus Torvalds #ifdef CONFIG_NFS_DIRECTIO 273*1da177e4SLinus Torvalds if (iocb->ki_filp->f_flags & O_DIRECT) 274*1da177e4SLinus Torvalds return nfs_file_direct_write(iocb, buf, count, pos); 275*1da177e4SLinus Torvalds #endif 276*1da177e4SLinus Torvalds 277*1da177e4SLinus Torvalds dfprintk(VFS, "nfs: write(%s/%s(%ld), %lu@%lu)\n", 278*1da177e4SLinus Torvalds dentry->d_parent->d_name.name, dentry->d_name.name, 279*1da177e4SLinus Torvalds inode->i_ino, (unsigned long) count, (unsigned long) pos); 280*1da177e4SLinus Torvalds 281*1da177e4SLinus Torvalds result = -EBUSY; 282*1da177e4SLinus Torvalds if (IS_SWAPFILE(inode)) 283*1da177e4SLinus Torvalds goto out_swapfile; 284*1da177e4SLinus Torvalds result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 285*1da177e4SLinus Torvalds if (result) 286*1da177e4SLinus Torvalds goto out; 287*1da177e4SLinus Torvalds 288*1da177e4SLinus Torvalds result = count; 289*1da177e4SLinus Torvalds if (!count) 290*1da177e4SLinus Torvalds goto out; 291*1da177e4SLinus Torvalds 292*1da177e4SLinus Torvalds result = generic_file_aio_write(iocb, buf, count, pos); 293*1da177e4SLinus Torvalds out: 294*1da177e4SLinus Torvalds return result; 295*1da177e4SLinus Torvalds 296*1da177e4SLinus Torvalds out_swapfile: 297*1da177e4SLinus Torvalds printk(KERN_INFO "NFS: attempt to write to active swap file!\n"); 298*1da177e4SLinus Torvalds goto out; 299*1da177e4SLinus Torvalds } 300*1da177e4SLinus Torvalds 301*1da177e4SLinus Torvalds static int do_getlk(struct file *filp, int cmd, struct file_lock *fl) 302*1da177e4SLinus Torvalds { 303*1da177e4SLinus Torvalds struct inode *inode = filp->f_mapping->host; 304*1da177e4SLinus Torvalds int status = 0; 305*1da177e4SLinus Torvalds 306*1da177e4SLinus Torvalds lock_kernel(); 307*1da177e4SLinus Torvalds /* Use local locking if mounted with "-onolock" */ 308*1da177e4SLinus Torvalds if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 309*1da177e4SLinus Torvalds status = NFS_PROTO(inode)->lock(filp, cmd, fl); 310*1da177e4SLinus Torvalds else { 311*1da177e4SLinus Torvalds struct file_lock *cfl = posix_test_lock(filp, fl); 312*1da177e4SLinus Torvalds 313*1da177e4SLinus Torvalds fl->fl_type = F_UNLCK; 314*1da177e4SLinus Torvalds if (cfl != NULL) 315*1da177e4SLinus Torvalds memcpy(fl, cfl, sizeof(*fl)); 316*1da177e4SLinus Torvalds } 317*1da177e4SLinus Torvalds unlock_kernel(); 318*1da177e4SLinus Torvalds return status; 319*1da177e4SLinus Torvalds } 320*1da177e4SLinus Torvalds 321*1da177e4SLinus Torvalds static int do_vfs_lock(struct file *file, struct file_lock *fl) 322*1da177e4SLinus Torvalds { 323*1da177e4SLinus Torvalds int res = 0; 324*1da177e4SLinus Torvalds switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { 325*1da177e4SLinus Torvalds case FL_POSIX: 326*1da177e4SLinus Torvalds res = posix_lock_file_wait(file, fl); 327*1da177e4SLinus Torvalds break; 328*1da177e4SLinus Torvalds case FL_FLOCK: 329*1da177e4SLinus Torvalds res = flock_lock_file_wait(file, fl); 330*1da177e4SLinus Torvalds break; 331*1da177e4SLinus Torvalds default: 332*1da177e4SLinus Torvalds BUG(); 333*1da177e4SLinus Torvalds } 334*1da177e4SLinus Torvalds if (res < 0) 335*1da177e4SLinus Torvalds printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", 336*1da177e4SLinus Torvalds __FUNCTION__); 337*1da177e4SLinus Torvalds return res; 338*1da177e4SLinus Torvalds } 339*1da177e4SLinus Torvalds 340*1da177e4SLinus Torvalds static int do_unlk(struct file *filp, int cmd, struct file_lock *fl) 341*1da177e4SLinus Torvalds { 342*1da177e4SLinus Torvalds struct inode *inode = filp->f_mapping->host; 343*1da177e4SLinus Torvalds sigset_t oldset; 344*1da177e4SLinus Torvalds int status; 345*1da177e4SLinus Torvalds 346*1da177e4SLinus Torvalds rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); 347*1da177e4SLinus Torvalds /* 348*1da177e4SLinus Torvalds * Flush all pending writes before doing anything 349*1da177e4SLinus Torvalds * with locks.. 350*1da177e4SLinus Torvalds */ 351*1da177e4SLinus Torvalds filemap_fdatawrite(filp->f_mapping); 352*1da177e4SLinus Torvalds down(&inode->i_sem); 353*1da177e4SLinus Torvalds nfs_wb_all(inode); 354*1da177e4SLinus Torvalds up(&inode->i_sem); 355*1da177e4SLinus Torvalds filemap_fdatawait(filp->f_mapping); 356*1da177e4SLinus Torvalds 357*1da177e4SLinus Torvalds /* NOTE: special case 358*1da177e4SLinus Torvalds * If we're signalled while cleaning up locks on process exit, we 359*1da177e4SLinus Torvalds * still need to complete the unlock. 360*1da177e4SLinus Torvalds */ 361*1da177e4SLinus Torvalds lock_kernel(); 362*1da177e4SLinus Torvalds /* Use local locking if mounted with "-onolock" */ 363*1da177e4SLinus Torvalds if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) 364*1da177e4SLinus Torvalds status = NFS_PROTO(inode)->lock(filp, cmd, fl); 365*1da177e4SLinus Torvalds else 366*1da177e4SLinus Torvalds status = do_vfs_lock(filp, fl); 367*1da177e4SLinus Torvalds unlock_kernel(); 368*1da177e4SLinus Torvalds rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); 369*1da177e4SLinus Torvalds return status; 370*1da177e4SLinus Torvalds } 371*1da177e4SLinus Torvalds 372*1da177e4SLinus Torvalds static int do_setlk(struct file *filp, int cmd, struct file_lock *fl) 373*1da177e4SLinus Torvalds { 374*1da177e4SLinus Torvalds struct inode *inode = filp->f_mapping->host; 375*1da177e4SLinus Torvalds sigset_t oldset; 376*1da177e4SLinus Torvalds int status; 377*1da177e4SLinus Torvalds 378*1da177e4SLinus Torvalds rpc_clnt_sigmask(NFS_CLIENT(inode), &oldset); 379*1da177e4SLinus Torvalds /* 380*1da177e4SLinus Torvalds * Flush all pending writes before doing anything 381*1da177e4SLinus Torvalds * with locks.. 382*1da177e4SLinus Torvalds */ 383*1da177e4SLinus Torvalds status = filemap_fdatawrite(filp->f_mapping); 384*1da177e4SLinus Torvalds if (status == 0) { 385*1da177e4SLinus Torvalds down(&inode->i_sem); 386*1da177e4SLinus Torvalds status = nfs_wb_all(inode); 387*1da177e4SLinus Torvalds up(&inode->i_sem); 388*1da177e4SLinus Torvalds if (status == 0) 389*1da177e4SLinus Torvalds status = filemap_fdatawait(filp->f_mapping); 390*1da177e4SLinus Torvalds } 391*1da177e4SLinus Torvalds if (status < 0) 392*1da177e4SLinus Torvalds goto out; 393*1da177e4SLinus Torvalds 394*1da177e4SLinus Torvalds lock_kernel(); 395*1da177e4SLinus Torvalds /* Use local locking if mounted with "-onolock" */ 396*1da177e4SLinus Torvalds if (!(NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)) { 397*1da177e4SLinus Torvalds status = NFS_PROTO(inode)->lock(filp, cmd, fl); 398*1da177e4SLinus Torvalds /* If we were signalled we still need to ensure that 399*1da177e4SLinus Torvalds * we clean up any state on the server. We therefore 400*1da177e4SLinus Torvalds * record the lock call as having succeeded in order to 401*1da177e4SLinus Torvalds * ensure that locks_remove_posix() cleans it out when 402*1da177e4SLinus Torvalds * the process exits. 403*1da177e4SLinus Torvalds */ 404*1da177e4SLinus Torvalds if (status == -EINTR || status == -ERESTARTSYS) 405*1da177e4SLinus Torvalds do_vfs_lock(filp, fl); 406*1da177e4SLinus Torvalds } else 407*1da177e4SLinus Torvalds status = do_vfs_lock(filp, fl); 408*1da177e4SLinus Torvalds unlock_kernel(); 409*1da177e4SLinus Torvalds if (status < 0) 410*1da177e4SLinus Torvalds goto out; 411*1da177e4SLinus Torvalds /* 412*1da177e4SLinus Torvalds * Make sure we clear the cache whenever we try to get the lock. 413*1da177e4SLinus Torvalds * This makes locking act as a cache coherency point. 414*1da177e4SLinus Torvalds */ 415*1da177e4SLinus Torvalds filemap_fdatawrite(filp->f_mapping); 416*1da177e4SLinus Torvalds down(&inode->i_sem); 417*1da177e4SLinus Torvalds nfs_wb_all(inode); /* we may have slept */ 418*1da177e4SLinus Torvalds up(&inode->i_sem); 419*1da177e4SLinus Torvalds filemap_fdatawait(filp->f_mapping); 420*1da177e4SLinus Torvalds nfs_zap_caches(inode); 421*1da177e4SLinus Torvalds out: 422*1da177e4SLinus Torvalds rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset); 423*1da177e4SLinus Torvalds return status; 424*1da177e4SLinus Torvalds } 425*1da177e4SLinus Torvalds 426*1da177e4SLinus Torvalds /* 427*1da177e4SLinus Torvalds * Lock a (portion of) a file 428*1da177e4SLinus Torvalds */ 429*1da177e4SLinus Torvalds static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) 430*1da177e4SLinus Torvalds { 431*1da177e4SLinus Torvalds struct inode * inode = filp->f_mapping->host; 432*1da177e4SLinus Torvalds 433*1da177e4SLinus Torvalds dprintk("NFS: nfs_lock(f=%s/%ld, t=%x, fl=%x, r=%Ld:%Ld)\n", 434*1da177e4SLinus Torvalds inode->i_sb->s_id, inode->i_ino, 435*1da177e4SLinus Torvalds fl->fl_type, fl->fl_flags, 436*1da177e4SLinus Torvalds (long long)fl->fl_start, (long long)fl->fl_end); 437*1da177e4SLinus Torvalds 438*1da177e4SLinus Torvalds if (!inode) 439*1da177e4SLinus Torvalds return -EINVAL; 440*1da177e4SLinus Torvalds 441*1da177e4SLinus Torvalds /* No mandatory locks over NFS */ 442*1da177e4SLinus Torvalds if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) 443*1da177e4SLinus Torvalds return -ENOLCK; 444*1da177e4SLinus Torvalds 445*1da177e4SLinus Torvalds if (IS_GETLK(cmd)) 446*1da177e4SLinus Torvalds return do_getlk(filp, cmd, fl); 447*1da177e4SLinus Torvalds if (fl->fl_type == F_UNLCK) 448*1da177e4SLinus Torvalds return do_unlk(filp, cmd, fl); 449*1da177e4SLinus Torvalds return do_setlk(filp, cmd, fl); 450*1da177e4SLinus Torvalds } 451*1da177e4SLinus Torvalds 452*1da177e4SLinus Torvalds /* 453*1da177e4SLinus Torvalds * Lock a (portion of) a file 454*1da177e4SLinus Torvalds */ 455*1da177e4SLinus Torvalds static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) 456*1da177e4SLinus Torvalds { 457*1da177e4SLinus Torvalds struct inode * inode = filp->f_mapping->host; 458*1da177e4SLinus Torvalds 459*1da177e4SLinus Torvalds dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", 460*1da177e4SLinus Torvalds inode->i_sb->s_id, inode->i_ino, 461*1da177e4SLinus Torvalds fl->fl_type, fl->fl_flags); 462*1da177e4SLinus Torvalds 463*1da177e4SLinus Torvalds if (!inode) 464*1da177e4SLinus Torvalds return -EINVAL; 465*1da177e4SLinus Torvalds 466*1da177e4SLinus Torvalds /* 467*1da177e4SLinus Torvalds * No BSD flocks over NFS allowed. 468*1da177e4SLinus Torvalds * Note: we could try to fake a POSIX lock request here by 469*1da177e4SLinus Torvalds * using ((u32) filp | 0x80000000) or some such as the pid. 470*1da177e4SLinus Torvalds * Not sure whether that would be unique, though, or whether 471*1da177e4SLinus Torvalds * that would break in other places. 472*1da177e4SLinus Torvalds */ 473*1da177e4SLinus Torvalds if (!(fl->fl_flags & FL_FLOCK)) 474*1da177e4SLinus Torvalds return -ENOLCK; 475*1da177e4SLinus Torvalds 476*1da177e4SLinus Torvalds /* We're simulating flock() locks using posix locks on the server */ 477*1da177e4SLinus Torvalds fl->fl_owner = (fl_owner_t)filp; 478*1da177e4SLinus Torvalds fl->fl_start = 0; 479*1da177e4SLinus Torvalds fl->fl_end = OFFSET_MAX; 480*1da177e4SLinus Torvalds 481*1da177e4SLinus Torvalds if (fl->fl_type == F_UNLCK) 482*1da177e4SLinus Torvalds return do_unlk(filp, cmd, fl); 483*1da177e4SLinus Torvalds return do_setlk(filp, cmd, fl); 484*1da177e4SLinus Torvalds } 485