ext4: Fix time encoding with extra epoch bits
[linux-2.6-microblaze.git] / fs / cifs / file.c
index c34b7f8..fa7beac 100644 (file)
@@ -53,11 +53,9 @@ static inline struct cifsFileInfo *cifs_init_private(
        private_data->pInode = inode;
        private_data->invalidHandle = false;
        private_data->closePend = false;
-       /* we have to track num writers to the inode, since writepages
-       does not tell us which handle the write is for so there can
-       be a close (overlapping with write) of the filehandle that
-       cifs_writepages chose to use */
-       atomic_set(&private_data->wrtPending, 0);
+       /* Initialize reference count to one.  The private data is
+       freed on the release of the last reference */
+       atomic_set(&private_data->count, 1);
 
        return private_data;
 }
@@ -643,7 +641,7 @@ int cifs_close(struct inode *inode, struct file *file)
                        if (!pTcon->need_reconnect) {
                                write_unlock(&GlobalSMBSeslock);
                                timeout = 2;
-                               while ((atomic_read(&pSMBFile->wrtPending) != 0)
+                               while ((atomic_read(&pSMBFile->count) != 1)
                                        && (timeout <= 2048)) {
                                        /* Give write a better chance to get to
                                        server ahead of the close.  We do not
@@ -657,8 +655,6 @@ int cifs_close(struct inode *inode, struct file *file)
                                        msleep(timeout);
                                        timeout *= 4;
                                }
-                               if (atomic_read(&pSMBFile->wrtPending))
-                                       cERROR(1, ("close with pending write"));
                                if (!pTcon->need_reconnect &&
                                    !pSMBFile->invalidHandle)
                                        rc = CIFSSMBClose(xid, pTcon,
@@ -681,24 +677,7 @@ int cifs_close(struct inode *inode, struct file *file)
                list_del(&pSMBFile->flist);
                list_del(&pSMBFile->tlist);
                write_unlock(&GlobalSMBSeslock);
-               timeout = 10;
-               /* We waited above to give the SMBWrite a chance to issue
-                  on the wire (so we do not get SMBWrite returning EBADF
-                  if writepages is racing with close.  Note that writepages
-                  does not specify a file handle, so it is possible for a file
-                  to be opened twice, and the application close the "wrong"
-                  file handle - in these cases we delay long enough to allow
-                  the SMBWrite to get on the wire before the SMB Close.
-                  We allow total wait here over 45 seconds, more than
-                  oplock break time, and more than enough to allow any write
-                  to complete on the server, or to time out on the client */
-               while ((atomic_read(&pSMBFile->wrtPending) != 0)
-                               && (timeout <= 50000)) {
-                       cERROR(1, ("writes pending, delay free of handle"));
-                       msleep(timeout);
-                       timeout *= 8;
-               }
-               kfree(file->private_data);
+               cifsFileInfo_put(file->private_data);
                file->private_data = NULL;
        } else
                rc = -EBADF;
@@ -1236,7 +1215,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)
                        if (!open_file->invalidHandle) {
                                /* found a good file */
                                /* lock it so it will not be closed on us */
-                               atomic_inc(&open_file->wrtPending);
+                               cifsFileInfo_get(open_file);
                                read_unlock(&GlobalSMBSeslock);
                                return open_file;
                        } /* else might as well continue, and look for
@@ -1276,7 +1255,7 @@ refind_writable:
                if (open_file->pfile &&
                    ((open_file->pfile->f_flags & O_RDWR) ||
                     (open_file->pfile->f_flags & O_WRONLY))) {
-                       atomic_inc(&open_file->wrtPending);
+                       cifsFileInfo_get(open_file);
 
                        if (!open_file->invalidHandle) {
                                /* found a good writable file */
@@ -1293,7 +1272,7 @@ refind_writable:
                                else { /* start over in case this was deleted */
                                       /* since the list could be modified */
                                        read_lock(&GlobalSMBSeslock);
-                                       atomic_dec(&open_file->wrtPending);
+                                       cifsFileInfo_put(open_file);
                                        goto refind_writable;
                                }
                        }
@@ -1309,7 +1288,7 @@ refind_writable:
                        read_lock(&GlobalSMBSeslock);
                        /* can not use this handle, no write
                           pending on this one after all */
-                       atomic_dec(&open_file->wrtPending);
+                       cifsFileInfo_put(open_file);
 
                        if (open_file->closePend) /* list could have changed */
                                goto refind_writable;
@@ -1373,7 +1352,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
        if (open_file) {
                bytes_written = cifs_write(open_file->pfile, write_data,
                                           to-from, &offset);
-               atomic_dec(&open_file->wrtPending);
+               cifsFileInfo_put(open_file);
                /* Does mm or vfs already set times? */
                inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
                if ((bytes_written > 0) && (offset))
@@ -1562,7 +1541,7 @@ retry:
                                                   bytes_to_write, offset,
                                                   &bytes_written, iov, n_iov,
                                                   long_op);
-                               atomic_dec(&open_file->wrtPending);
+                               cifsFileInfo_put(open_file);
                                cifs_update_eof(cifsi, offset, bytes_written);
 
                                if (rc || bytes_written < bytes_to_write) {