~ubuntu-branches/ubuntu/maverick/transmission/maverick

« back to all changes in this revision

Viewing changes to libtransmission/fdlimit.c

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Klimonda
  • Date: 2009-05-22 21:57:30 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (2.1.18 sid) (1.3.8 upstream)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20090522215730-ly5kgv5aw9ig2u82
Tags: upstream-1.61
ImportĀ upstreamĀ versionĀ 1.61

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: fdlimit.c 7813 2009-01-29 18:18:24Z charles $
 
2
 * $Id: fdlimit.c 8350 2009-05-07 13:03:39Z charles $
3
3
 *
4
4
 * Copyright (c) 2005-2008 Transmission authors and contributors
5
5
 *
47
47
 #include <linux/falloc.h>
48
48
#endif
49
49
 
 
50
#ifdef HAVE_XFS_XFS_H
 
51
 #include <xfs/xfs.h>
 
52
#endif
 
53
 
50
54
#include <sys/types.h>
51
55
#include <sys/stat.h>
52
56
#ifdef HAVE_GETRLIMIT
79
83
{
80
84
    NOFILE_BUFFER = 512, /* the process' number of open files is
81
85
                            globalMaxPeers + NOFILE_BUFFER */
82
 
 
83
 
    SYNC_INTERVAL = 15   /* (arbitrary number) how many seconds to go
84
 
                            between fsync calls for files in heavy use */
85
86
};
86
87
 
87
88
struct tr_openfile
92
93
    char       filename[MAX_PATH_LENGTH];
93
94
    int        fd;
94
95
    uint64_t   date;
95
 
    time_t     syncAt;
96
96
};
97
97
 
98
98
struct tr_fd_s
158
158
    int fd = open( filename, flags, 0666 );
159
159
    if( fd >= 0 )
160
160
    {
161
 
        
 
161
# ifdef HAVE_XFS_XFS_H
 
162
        if( !success && platform_test_xfs_fd( fd ) )
 
163
        {
 
164
            xfs_flock64_t fl;
 
165
            fl.l_whence = 0;
 
166
            fl.l_start = 0;
 
167
            fl.l_len = length;
 
168
            success = !xfsctl( NULL, fd, XFS_IOC_RESVSP64, &fl );
 
169
        }
 
170
# endif
 
171
# ifdef SYS_DARWIN
 
172
        if( !success )
 
173
        {
 
174
            fstore_t fst;
 
175
            fst.fst_flags = F_ALLOCATECONTIG;
 
176
            fst.fst_posmode = F_PEOFPOSMODE;
 
177
            fst.fst_offset = 0;
 
178
            fst.fst_length = length;
 
179
            fst.fst_bytesalloc = 0;
 
180
            success = !fcntl( fd, F_PREALLOCATE, &fst );
 
181
        }
 
182
# endif
162
183
# ifdef HAVE_FALLOCATE
163
 
 
164
 
        success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
165
 
 
166
 
# elif defined(HAVE_POSIX_FALLOCATE)
167
 
 
168
 
        success = !posix_fallocate( fd, 0, length );
169
 
 
170
 
# elif defined(SYS_DARWIN) 
171
 
 
172
 
        fstore_t fst;
173
 
        fst.fst_flags = F_ALLOCATECONTIG;
174
 
        fst.fst_posmode = F_PEOFPOSMODE;
175
 
        fst.fst_offset = 0;
176
 
        fst.fst_length = length;
177
 
        fst.fst_bytesalloc = 0;
178
 
        success = !fcntl( fd, F_PREALLOCATE, &fst );
179
 
 
180
 
# else
181
 
 
182
 
        #warning no known method to preallocate files on this platform
183
 
        success = 0;
184
 
 
 
184
        if( !success )
 
185
        {
 
186
            success = !fallocate( fd, FALLOC_FL_KEEP_SIZE, 0, length );
 
187
        }
 
188
# endif
 
189
# ifdef HAVE_POSIX_FALLOCATE
 
190
        if( !success )
 
191
        {
 
192
            success = !posix_fallocate( fd, 0, length );
 
193
        }
185
194
# endif
186
195
 
187
196
        close( fd );
192
201
    return success;
193
202
}
194
203
 
 
204
int
 
205
tr_open_file_for_scanning( const char * filename )
 
206
{
 
207
    int fd;
 
208
    int flags;
 
209
 
 
210
    /* build the flags */
 
211
    flags = O_RDONLY;
 
212
#ifdef O_SEQUENTIAL
 
213
    flags |= O_SEQUENTIAL;
 
214
#endif
 
215
#ifdef O_BINARY
 
216
    flags |= O_BINARY;
 
217
#endif
 
218
#ifdef O_LARGEFILE
 
219
    flags |= O_LARGEFILE;
 
220
#endif
 
221
 
 
222
    /* open the file */
 
223
    fd = open( filename, flags, 0666 );
 
224
    if( fd >= 0 )
 
225
    {
 
226
        /* Set hints about the lookahead buffer and caching. It's okay
 
227
           for these to fail silently, so don't let them affect errno */
 
228
        const int err = errno;
 
229
#ifdef HAVE_POSIX_FADVISE
 
230
        posix_fadvise( fd, 0, 0, POSIX_FADV_SEQUENTIAL );
 
231
#endif
 
232
#ifdef SYS_DARWIN
 
233
        fcntl( fd, F_NOCACHE, 1 );
 
234
        fcntl( fd, F_RDAHEAD, 1 );
 
235
#endif
 
236
        errno = err;
 
237
    }
 
238
 
 
239
    return fd;
 
240
}
 
241
 
 
242
void
 
243
tr_close_file( int fd )
 
244
{
 
245
#if defined(HAVE_POSIX_FADVISE)
 
246
    /* Set hint about not caching this file.
 
247
       It's okay for this to fail silently, so don't let it affect errno */
 
248
    const int err = errno;
 
249
    posix_fadvise( fd, 0, 0, POSIX_FADV_DONTNEED );
 
250
    errno = err;
 
251
#endif
 
252
    close( fd );
 
253
}
 
254
 
195
255
/**
196
256
 * returns 0 on success, or an errno value on failure.
197
257
 * errno values include ENOENT if the parent folder doesn't exist,
262
322
    if( doWrite && !alreadyExisted && ( preallocationMode == TR_PREALLOCATE_SPARSE ) )
263
323
        preallocateFileSparse( file->fd, desiredFileSize );
264
324
 
265
 
#if defined( SYS_DARWIN )
266
 
    fcntl( file->fd, F_NOCACHE, 1 );
267
 
    fcntl( file->fd, F_RDAHEAD, 0 );
268
 
#elif defined( HAVE_POSIX_FADVISE )
 
325
#ifdef HAVE_POSIX_FADVISE
269
326
    posix_fadvise( file->fd, 0, 0, POSIX_FADV_RANDOM );
270
327
#endif
271
328
 
288
345
    assert( i < gFd->openFileLimit );
289
346
    assert( fileIsOpen( o ) );
290
347
 
291
 
    close( o->fd );
 
348
    tr_close_file( o->fd );
292
349
    o->fd = -1;
293
350
    o->isCheckedOut = 0;
294
351
}
413
470
                doWrite ? 'y' : 'n' );
414
471
        tr_strlcpy( o->filename, filename, sizeof( o->filename ) );
415
472
        o->isWritable = doWrite;
416
 
        o->syncAt = time( NULL ) + SYNC_INTERVAL;
417
473
    }
418
474
 
419
475
    dbgmsg( "checking out '%s' in slot %d", filename, winner );
441
497
        o->isCheckedOut = 0;
442
498
        if( o->closeWhenDone )
443
499
            TrCloseFile( i );
444
 
        else if( o->syncAt <= time( NULL ) ) {
445
 
            dbgmsg( "fsync()ing file '%s' in slot #%d", o->filename, i );
446
 
            fsync( o->fd );
447
 
#ifdef HAVE_POSIX_FADVISE
448
 
            /* TODO: test performance with and without this */
449
 
            posix_fadvise( o->fd, 0, 0, POSIX_FADV_DONTNEED );
450
 
#endif
451
 
            o->syncAt = time( NULL ) + SYNC_INTERVAL;
452
 
        }
453
500
 
454
501
        break;
455
502
    }