locks: protect most of the file_lock handling with i_lock

Dan Carpenter dan.carpenter at oracle.com
Tue Apr 5 23:47:44 PDT 2016


Hello Jeff Layton,

The patch 1c8c601a8c0d: "locks: protect most of the file_lock
handling with i_lock" from Jun 21, 2013, leads to the following
static checker warning:

	fs/afs/flock.c:353 afs_do_setlk()
	error: scheduling with locks held: 'spin_lock:i_lock'

fs/afs/flock.c
   250  /*
   251   * request a lock on a file on the server
   252   */
   253  static int afs_do_setlk(struct file *file, struct file_lock *fl)
   254  {
   255          struct inode *inode = file_inode(file);
   256          struct afs_vnode *vnode = AFS_FS_I(inode);
   257          afs_lock_type_t type;
   258          struct key *key = file->private_data;
   259          int ret;
   260  
   261          _enter("{%x:%u},%u", vnode->fid.vid, vnode->fid.vnode, fl->fl_type);
   262  
   263          /* only whole-file locks are supported */
   264          if (fl->fl_start != 0 || fl->fl_end != OFFSET_MAX)
   265                  return -EINVAL;
   266  
   267          ret = afs_init_lock_manager();
   268          if (ret < 0)
   269                  return ret;
   270  
   271          fl->fl_ops = &afs_lock_ops;
   272          INIT_LIST_HEAD(&fl->fl_u.afs.link);
   273          fl->fl_u.afs.state = AFS_LOCK_PENDING;
   274  
   275          type = (fl->fl_type == F_RDLCK) ? AFS_LOCK_READ : AFS_LOCK_WRITE;
   276  
   277          spin_lock(&inode->i_lock);
   278  
   279          /* make sure we've got a callback on this file and that our view of the
   280           * data version is up to date */
   281          ret = afs_vnode_fetch_status(vnode, NULL, key);
   282          if (ret < 0)
   283                  goto error;

[ snip ]

   350          /* now we need to sleep and wait for the lock manager thread to get the
   351           * lock from the server */
   352          _debug("sleep");
   353          ret = wait_event_interruptible(fl->fl_wait,
   354                                         fl->fl_u.afs.state <= AFS_LOCK_GRANTED);

Are we allowed to sleep holding this spinlock?  It's weird that I'm only
seeing this warning now three years later.

   355          if (fl->fl_u.afs.state <= AFS_LOCK_GRANTED) {
   356                  ret = fl->fl_u.afs.state;
   357                  if (ret < 0)
   358                          goto error;
   359                  spin_lock(&vnode->lock);
   360                  goto given_lock;
   361          }

regards,
dan carpenter



More information about the linux-afs mailing list