~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/lib-storage/index/mbox/mbox-lock.c

  • Committer: Package Import Robot
  • Author(s): Jaldhar H. Vyas
  • Date: 2013-09-09 00:57:32 UTC
  • mfrom: (1.13.11)
  • mto: (4.8.5 experimental) (1.16.1)
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: package-import@ubuntu.com-20130909005732-dn1eell8srqbhh0e
Tags: upstream-2.2.5
ImportĀ upstreamĀ versionĀ 2.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "eacces-error.h"
86
86
        { 0, NULL, NULL }
87
87
};
88
88
 
89
 
static int mbox_lock_list(struct mbox_lock_context *ctx, int lock_type,
90
 
                          time_t max_wait_time, int idx);
91
 
static int mbox_unlock_files(struct mbox_lock_context *ctx);
 
89
static int ATTR_NOWARN_UNUSED_RESULT
 
90
mbox_lock_list(struct mbox_lock_context *ctx, int lock_type,
 
91
               time_t max_wait_time, int idx);
 
92
static int ATTR_NOWARN_UNUSED_RESULT
 
93
mbox_unlock_files(struct mbox_lock_context *ctx);
92
94
 
93
95
static void mbox_read_lock_methods(const char *str, const char *env,
94
96
                                   enum mbox_lock_type *locks)
228
230
                                ctx->dotlock_last_stale = TRUE;
229
231
                                return FALSE;
230
232
                        }
231
 
                        (void)mbox_lock_list(ctx, F_UNLCK, 0, i);
 
233
                        mbox_lock_list(ctx, F_UNLCK, 0, i);
232
234
                }
233
235
        }
234
236
        ctx->dotlock_last_stale = stale;
246
248
        return TRUE;
247
249
}
248
250
 
249
 
static int mbox_dotlock_privileged_op(struct mbox_mailbox *mbox,
250
 
                                      struct dotlock_settings *set,
251
 
                                      enum mbox_dotlock_op op)
 
251
static int ATTR_NULL(2) ATTR_NOWARN_UNUSED_RESULT
 
252
mbox_dotlock_privileged_op(struct mbox_mailbox *mbox,
 
253
                           struct dotlock_settings *set,
 
254
                           enum mbox_dotlock_op op)
252
255
{
253
256
        const char *box_path, *dir, *fname;
254
257
        int ret = -1, orig_dir_fd, orig_errno;
278
281
                if (chdir(dir) < 0) {
279
282
                        mail_storage_set_critical(&mbox->storage->storage,
280
283
                                "chdir(%s) failed: %m", dir);
281
 
                        (void)close(orig_dir_fd);
 
284
                        i_close_fd(&orig_dir_fd);
282
285
                        return -1;
283
286
                }
284
287
                fname++;
292
295
        }
293
296
 
294
297
        if (restrict_access_use_priv_gid() < 0) {
295
 
                (void)close(orig_dir_fd);
 
298
                i_close_fd(&orig_dir_fd);
296
299
                return -1;
297
300
        }
298
301
 
333
336
                mail_storage_set_critical(&mbox->storage->storage,
334
337
                        "fchdir() failed: %m");
335
338
        }
336
 
        (void)close(orig_dir_fd);
 
339
        i_close_fd(&orig_dir_fd);
337
340
        errno = orig_errno;
338
341
        return ret;
339
342
}
357
360
                mail_storage_set_critical(&mbox->storage->storage,
358
361
                        "%s (not INBOX -> no privileged locking)", errmsg);
359
362
        } else if (!mbox->mbox_privileged_locking) {
360
 
                dir = mailbox_list_get_path(mbox->box.list, NULL,
361
 
                                            MAILBOX_LIST_PATH_TYPE_DIR);
 
363
                dir = mailbox_list_get_root_forced(mbox->box.list,
 
364
                                                   MAILBOX_LIST_PATH_TYPE_DIR);
362
365
                mail_storage_set_critical(&mbox->storage->storage,
363
366
                        "%s (under root dir %s -> no privileged locking)",
364
367
                        errmsg, dir);
396
399
                        }
397
400
                } else {
398
401
                        ctx->using_privileges = TRUE;
399
 
                        (void)mbox_dotlock_privileged_op(mbox, NULL,
400
 
                                                         MBOX_DOTLOCK_OP_UNLOCK);
 
402
                        mbox_dotlock_privileged_op(mbox, NULL,
 
403
                                                   MBOX_DOTLOCK_OP_UNLOCK);
401
404
                        ctx->using_privileges = FALSE;
402
405
                }
403
406
                mbox->mbox_dotlocked = FALSE;
665
668
        return 1;
666
669
}
667
670
 
668
 
static int mbox_lock_list(struct mbox_lock_context *ctx, int lock_type,
669
 
                          time_t max_wait_time, int idx)
 
671
static int ATTR_NOWARN_UNUSED_RESULT
 
672
mbox_lock_list(struct mbox_lock_context *ctx, int lock_type,
 
673
               time_t max_wait_time, int idx)
670
674
{
671
675
        enum mbox_lock_type *lock_types;
672
676
        enum mbox_lock_type type;
741
745
        ret = mbox_lock_list(&ctx, lock_type, max_wait_time, 0);
742
746
        if (ret <= 0) {
743
747
                if (!drop_locks)
744
 
                        (void)mbox_unlock_files(&ctx);
 
748
                        mbox_unlock_files(&ctx);
745
749
                if (ret == 0) {
746
750
                        mail_storage_set_error(&mbox->storage->storage,
747
751
                                MAIL_ERROR_TEMP, MAIL_ERRSTR_LOCK_TIMEOUT);
764
768
                        ctx.lock_status[read_locks[i]] = 0;
765
769
 
766
770
                mbox->mbox_lock_type = F_WRLCK;
767
 
                (void)mbox_lock_list(&ctx, F_UNLCK, 0, 0);
 
771
                mbox_lock_list(&ctx, F_UNLCK, 0, 0);
768
772
                mbox->mbox_lock_type = F_RDLCK;
769
773
        }
770
774
 
780
784
        bool fcntl_locked;
781
785
        int ret;
782
786
 
 
787
        if (lock_type == F_RDLCK && mbox->external_transactions > 0 &&
 
788
            mbox->mbox_lock_type != F_RDLCK) {
 
789
                /* we have a transaction open that is going to save mails
 
790
                   and apparently also wants to read from the same mailbox
 
791
                   (copy, move, catenate). we need to write lock the mailbox,
 
792
                   since we can't later upgrade a read lock to write lock. */
 
793
                lock_type = F_WRLCK;
 
794
        }
 
795
 
783
796
        /* allow only unlock -> shared/exclusive or exclusive -> shared */
784
797
        i_assert(lock_type == F_RDLCK || lock_type == F_WRLCK);
785
798
        i_assert(lock_type == F_RDLCK || mbox->mbox_lock_type != F_RDLCK);
874
887
        return mbox_unlock_files(&ctx);
875
888
}
876
889
 
 
890
unsigned int mbox_get_cur_lock_id(struct mbox_mailbox *mbox)
 
891
{
 
892
        return mbox->mbox_lock_id +
 
893
                (mbox->mbox_excl_locks > 0 ? 1 : 0);
 
894
}
 
895
 
877
896
void mbox_dotlock_touch(struct mbox_mailbox *mbox)
878
897
{
879
898
        if (mbox->mbox_dotlock == NULL)
882
901
        if (!mbox->mbox_used_privileges)
883
902
                (void)file_dotlock_touch(mbox->mbox_dotlock);
884
903
        else {
885
 
                (void)mbox_dotlock_privileged_op(mbox, NULL,
 
904
                mbox_dotlock_privileged_op(mbox, NULL,
886
905
                                                 MBOX_DOTLOCK_OP_TOUCH);
887
906
        }
888
907
}