From mboxrd@z Thu Jan 1 00:00:00 1970 From: "William A.(Andy) Adamson" Subject: PATCH [6/10] lease interfaces for version 4 NFSD Date: Mon, 20 Sep 2004 16:23:00 -0400 Sender: linux-fsdevel-owner@vger.kernel.org Message-ID: <20040920202300.898BA1BBA3@citi.umich.edu> Mime-Version: 1.0 Content-Type: multipart/mixed ; boundary="==_Exmh_-2425963120" Cc: andros@citi.umich.edu Return-path: Received: from citi.umich.edu ([141.211.133.111]:48415 "EHLO citi.umich.edu") by vger.kernel.org with ESMTP id S267312AbUITUXC (ORCPT ); Mon, 20 Sep 2004 16:23:02 -0400 To: linux-fsdevel@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org This is a multipart MIME message. --==_Exmh_-2425963120 Content-Type: text/plain; charset=us-ascii VFS: nfsd will not have a file descriptor, nor an owner on the filp. nfsd also will not use signals. Seperate the lease processing code from fcntl_setlease() into a __setlease() call. Signed-off-by: Andy Adamson --==_Exmh_-2425963120 Content-Type: text/plain ; name="linux-2.6.9-rc2-06-fcntl_setlease.dif"; charset=us-ascii Content-Description: linux-2.6.9-rc2-06-fcntl_setlease.dif Content-Disposition: attachment; filename="linux-2.6.9-rc2-06-fcntl_setlease.dif" diff --recursive -puN old/fs/locks.c new/fs/locks.c --- old/fs/locks.c 2004-09-20 13:36:41.571386000 -0400 +++ new/fs/locks.c 2004-09-20 13:56:25.385316000 -0400 @@ -1252,37 +1252,29 @@ int fcntl_getlease(struct file *filp) } /** - * fcntl_setlease - sets a lease on an open file - * @fd: open file descriptor + * __setlease - sets a lease on an open file * @filp: file pointer * @arg: type of lease to obtain + * @flp: input - file_lock to use, output - file_lock inserted * - * Call this fcntl to establish a lease on the file. - * Note that you also need to call %F_SETSIG to - * receive a signal when the lease is broken. + * The (input) flp->fl_lmops->fl_break function is required + * by break_lease + * + * Called with kernel lock held. */ -int fcntl_setlease(unsigned int fd, struct file *filp, long arg) +int __setlease(struct file *filp, long arg, struct file_lock **flp) { struct file_lock *fl, **before, **my_before = NULL; - struct dentry *dentry; - struct inode *inode; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; int error, rdlease_count = 0, wrlease_count = 0; - dentry = filp->f_dentry; - inode = dentry->d_inode; - - if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) - return -EACCES; - if (!S_ISREG(inode->i_mode)) - return -EINVAL; - error = security_file_lock(filp, arg); - if (error) - return error; - - lock_kernel(); - time_out_leases(inode); + error = -EINVAL; + if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break) + goto out; + /* * FIXME: What about F_RDLCK and files open for writing? */ @@ -1290,7 +1282,7 @@ int fcntl_setlease(unsigned int fd, stru if ((arg == F_WRLCK) && ((atomic_read(&dentry->d_count) > 1) || (atomic_read(&inode->i_count) > 1))) - goto out_unlock; + goto out; /* * At this point, we know that if there is an exclusive @@ -1318,39 +1310,83 @@ int fcntl_setlease(unsigned int fd, stru if ((arg == F_RDLCK && (wrlease_count > 0)) || (arg == F_WRLCK && ((rdlease_count + wrlease_count) > 0))) - goto out_unlock; + goto out; if (my_before != NULL) { error = lease_modify(my_before, arg); - goto out_unlock; + goto out; } error = 0; if (arg == F_UNLCK) - goto out_unlock; + goto out; error = -EINVAL; if (!leases_enable) - goto out_unlock; + goto out; error = lease_alloc(filp, arg, &fl); if (error) - goto out_unlock; + goto out; - error = fasync_helper(fd, filp, 1, &fl->fl_fasync); - if (error < 0) { - locks_free_lock(fl); - goto out_unlock; - } + locks_copy_lock(fl, lease); locks_insert_lock(before, fl); +out: + return error; +} + +/** + * fcntl_setlease - sets a lease on an open file + * @fd: open file descriptor + * @filp: file pointer + * @arg: type of lease to obtain + * + * Call this fcntl to establish a lease on the file. + * Uses default fl_break function. + * Note that you also need to call %F_SETSIG to + * receive a signal when the lease is broken. + */ +int fcntl_setlease(unsigned int fd, struct file *filp, long arg) +{ + struct file_lock fl, *flp = &fl; + struct dentry *dentry = filp->f_dentry; + struct inode *inode = dentry->d_inode; + int error; + + if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) + return -EACCES; + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + error = security_file_lock(filp, arg); + if (error) + return error; + + locks_init_lock(&fl); + if ((error = lease_init(filp, arg, &fl))) + return error; + + lock_kernel(); + if((error = __setlease(filp, arg, &flp))) + goto out; + + error = fasync_helper(fd, filp, 1, &flp->fl_fasync); + if (error < 0) { + /* remove lease just inserted by __setlease */ + flp->fl_type = F_UNLCK | F_INPROGRESS; + flp->fl_break_time = jiffies - 10; + time_out_leases(inode); + goto out; + } + error = f_setown(filp, current->pid, 0); -out_unlock: +out: unlock_kernel(); return error; } + /** * flock_lock_file_wait - Apply a FLOCK-style lock to a file * @filp: The file to apply the lock to --==_Exmh_-2425963120--